diff --git a/[refs] b/[refs] index 3e5293918c52..1bc441046df1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4f032ac4122a77dbabf7a24b2739b2790448180f +refs/heads/master: eeb5f5c9b3c8bee5ab4794323c1d23d100a9db59 diff --git a/trunk/CREDITS b/trunk/CREDITS index 9a93e3e26d70..e8b7d36611e5 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -495,11 +495,6 @@ S: Kopmansg 2 S: 411 13 Goteborg S: Sweden -N: Paul Bristow -E: paul@paulbristow.net -W: http://paulbristow.net/linux/idefloppy.html -D: Maintainer of IDE/ATAPI floppy driver - N: Dominik Brodowski E: linux@brodo.de W: http://www.brodo.de/ @@ -2647,10 +2642,6 @@ S: C/ Mieses 20, 9-B S: Valladolid 47009 S: Spain -N: Gadi Oxman -E: gadio@netvision.net.il -D: Original author and maintainer of IDE/ATAPI floppy/tape drivers - N: Greg Page E: gpage@sovereign.org D: IPX development and support diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-pci b/trunk/Documentation/ABI/testing/sysfs-bus-pci index 97ad190e13af..e638e15a8895 100644 --- a/trunk/Documentation/ABI/testing/sysfs-bus-pci +++ b/trunk/Documentation/ABI/testing/sysfs-bus-pci @@ -41,49 +41,6 @@ Description: for the device and attempt to bind to it. For example: # echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id -What: /sys/bus/pci/drivers/.../remove_id -Date: February 2009 -Contact: Chris Wright -Description: - Writing a device ID to this file will remove an ID - that was dynamically added via the new_id sysfs entry. - The format for the device ID is: - VVVV DDDD SVVV SDDD CCCC MMMM. That is Vendor ID, Device - ID, Subsystem Vendor ID, Subsystem Device ID, Class, - and Class Mask. The Vendor ID and Device ID fields are - required, the rest are optional. After successfully - removing an ID, the driver will no longer support the - device. This is useful to ensure auto probing won't - match the driver to the device. For example: - # echo "8086 10f5" > /sys/bus/pci/drivers/foo/remove_id - -What: /sys/bus/pci/rescan -Date: January 2009 -Contact: Linux PCI developers -Description: - Writing a non-zero value to this attribute will - force a rescan of all PCI buses in the system, and - re-discover previously removed devices. - Depends on CONFIG_HOTPLUG. - -What: /sys/bus/pci/devices/.../remove -Date: January 2009 -Contact: Linux PCI developers -Description: - Writing a non-zero value to this attribute will - hot-remove the PCI device and any of its children. - Depends on CONFIG_HOTPLUG. - -What: /sys/bus/pci/devices/.../rescan -Date: January 2009 -Contact: Linux PCI developers -Description: - Writing a non-zero value to this attribute will - force a rescan of the device's parent bus and all - child buses, and re-discover devices removed earlier - from this part of the device tree. - Depends on CONFIG_HOTPLUG. - What: /sys/bus/pci/devices/.../vpd Date: February 2008 Contact: Ben Hutchings @@ -95,30 +52,3 @@ Description: that some devices may have malformatted data. If the underlying VPD has a writable section then the corresponding section of this file will be writable. - -What: /sys/bus/pci/devices/.../virtfnN -Date: March 2009 -Contact: Yu Zhao -Description: - This symbolic link appears when hardware supports the SR-IOV - capability and the Physical Function driver has enabled it. - The symbolic link points to the PCI device sysfs entry of the - Virtual Function whose index is N (0...MaxVFs-1). - -What: /sys/bus/pci/devices/.../dep_link -Date: March 2009 -Contact: Yu Zhao -Description: - This symbolic link appears when hardware supports the SR-IOV - capability and the Physical Function driver has enabled it, - and this device has vendor specific dependencies with others. - The symbolic link points to the PCI device sysfs entry of - Physical Function this device depends on. - -What: /sys/bus/pci/devices/.../physfn -Date: March 2009 -Contact: Yu Zhao -Description: - This symbolic link appears when a device is a Virtual Function. - The symbolic link points to the PCI device sysfs entry of the - Physical Function this device associates with. diff --git a/trunk/Documentation/ABI/testing/sysfs-fs-ext4 b/trunk/Documentation/ABI/testing/sysfs-fs-ext4 deleted file mode 100644 index 4e79074de282..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-fs-ext4 +++ /dev/null @@ -1,81 +0,0 @@ -What: /sys/fs/ext4//mb_stats -Date: March 2008 -Contact: "Theodore Ts'o" -Description: - Controls whether the multiblock allocator should - collect statistics, which are shown during the unmount. - 1 means to collect statistics, 0 means not to collect - statistics - -What: /sys/fs/ext4//mb_group_prealloc -Date: March 2008 -Contact: "Theodore Ts'o" -Description: - The multiblock allocator will round up allocation - requests to a multiple of this tuning parameter if the - stripe size is not set in the ext4 superblock - -What: /sys/fs/ext4//mb_max_to_scan -Date: March 2008 -Contact: "Theodore Ts'o" -Description: - The maximum number of extents the multiblock allocator - will search to find the best extent - -What: /sys/fs/ext4//mb_min_to_scan -Date: March 2008 -Contact: "Theodore Ts'o" -Description: - The minimum number of extents the multiblock allocator - will search to find the best extent - -What: /sys/fs/ext4//mb_order2_req -Date: March 2008 -Contact: "Theodore Ts'o" -Description: - Tuning parameter which controls the minimum size for - requests (as a power of 2) where the buddy cache is - used - -What: /sys/fs/ext4//mb_stream_req -Date: March 2008 -Contact: "Theodore Ts'o" -Description: - Files which have fewer blocks than this tunable - parameter will have their blocks allocated out of a - block group specific preallocation pool, so that small - files are packed closely together. Each large file - will have its blocks allocated out of its own unique - preallocation pool. - -What: /sys/fs/ext4//inode_readahead -Date: March 2008 -Contact: "Theodore Ts'o" -Description: - Tuning parameter which controls the maximum number of - inode table blocks that ext4's inode table readahead - algorithm will pre-read into the buffer cache - -What: /sys/fs/ext4//delayed_allocation_blocks -Date: March 2008 -Contact: "Theodore Ts'o" -Description: - This file is read-only and shows the number of blocks - that are dirty in the page cache, but which do not - have their location in the filesystem allocated yet. - -What: /sys/fs/ext4//lifetime_write_kbytes -Date: March 2008 -Contact: "Theodore Ts'o" -Description: - This file is read-only and shows the number of kilobytes - of data that have been written to this filesystem since it was - created. - -What: /sys/fs/ext4//session_write_kbytes -Date: March 2008 -Contact: "Theodore Ts'o" -Description: - This file is read-only and shows the number of - kilobytes of data that have been written to this - filesystem since it was mounted. diff --git a/trunk/Documentation/DMA-API.txt b/trunk/Documentation/DMA-API.txt index d9aa43d78bcc..2a3fcc55e981 100644 --- a/trunk/Documentation/DMA-API.txt +++ b/trunk/Documentation/DMA-API.txt @@ -609,109 +609,3 @@ size is the size (and should be a page-sized multiple). The return value will be either a pointer to the processor virtual address of the memory, or an error (via PTR_ERR()) if any part of the region is occupied. - -Part III - Debug drivers use of the DMA-API -------------------------------------------- - -The DMA-API as described above as some constraints. DMA addresses must be -released with the corresponding function with the same size for example. With -the advent of hardware IOMMUs it becomes more and more important that drivers -do not violate those constraints. In the worst case such a violation can -result in data corruption up to destroyed filesystems. - -To debug drivers and find bugs in the usage of the DMA-API checking code can -be compiled into the kernel which will tell the developer about those -violations. If your architecture supports it you can select the "Enable -debugging of DMA-API usage" option in your kernel configuration. Enabling this -option has a performance impact. Do not enable it in production kernels. - -If you boot the resulting kernel will contain code which does some bookkeeping -about what DMA memory was allocated for which device. If this code detects an -error it prints a warning message with some details into your kernel log. An -example warning message may look like this: - -------------[ cut here ]------------ -WARNING: at /data2/repos/linux-2.6-iommu/lib/dma-debug.c:448 - check_unmap+0x203/0x490() -Hardware name: -forcedeth 0000:00:08.0: DMA-API: device driver frees DMA memory with wrong - function [device address=0x00000000640444be] [size=66 bytes] [mapped as -single] [unmapped as page] -Modules linked in: nfsd exportfs bridge stp llc r8169 -Pid: 0, comm: swapper Tainted: G W 2.6.28-dmatest-09289-g8bb99c0 #1 -Call Trace: - [] warn_slowpath+0xf2/0x130 - [] _spin_unlock+0x10/0x30 - [] usb_hcd_link_urb_to_ep+0x75/0xc0 - [] _spin_unlock_irqrestore+0x12/0x40 - [] ohci_urb_enqueue+0x19f/0x7c0 - [] queue_work+0x56/0x60 - [] enqueue_task_fair+0x20/0x50 - [] usb_hcd_submit_urb+0x379/0xbc0 - [] cpumask_next_and+0x23/0x40 - [] find_busiest_group+0x207/0x8a0 - [] _spin_lock_irqsave+0x1f/0x50 - [] check_unmap+0x203/0x490 - [] debug_dma_unmap_page+0x49/0x50 - [] nv_tx_done_optimized+0xc6/0x2c0 - [] nv_nic_irq_optimized+0x73/0x2b0 - [] handle_IRQ_event+0x34/0x70 - [] handle_edge_irq+0xc9/0x150 - [] do_IRQ+0xcb/0x1c0 - [] ret_from_intr+0x0/0xa - <4>---[ end trace f6435a98e2a38c0e ]--- - -The driver developer can find the driver and the device including a stacktrace -of the DMA-API call which caused this warning. - -Per default only the first error will result in a warning message. All other -errors will only silently counted. This limitation exist to prevent the code -from flooding your kernel log. To support debugging a device driver this can -be disabled via debugfs. See the debugfs interface documentation below for -details. - -The debugfs directory for the DMA-API debugging code is called dma-api/. In -this directory the following files can currently be found: - - dma-api/all_errors This file contains a numeric value. If this - value is not equal to zero the debugging code - will print a warning for every error it finds - into the kernel log. Be carefull with this - option. It can easily flood your logs. - - dma-api/disabled This read-only file contains the character 'Y' - if the debugging code is disabled. This can - happen when it runs out of memory or if it was - disabled at boot time - - dma-api/error_count This file is read-only and shows the total - numbers of errors found. - - dma-api/num_errors The number in this file shows how many - warnings will be printed to the kernel log - before it stops. This number is initialized to - one at system boot and be set by writing into - this file - - dma-api/min_free_entries - This read-only file can be read to get the - minimum number of free dma_debug_entries the - allocator has ever seen. If this value goes - down to zero the code will disable itself - because it is not longer reliable. - - dma-api/num_free_entries - The current number of free dma_debug_entries - in the allocator. - -If you have this code compiled into your kernel it will be enabled by default. -If you want to boot without the bookkeeping anyway you can provide -'dma_debug=off' as a boot parameter. This will disable DMA-API debugging. -Notice that you can not enable it again at runtime. You have to reboot to do -so. - -When the code disables itself at runtime this is most likely because it ran -out of dma_debug_entries. These entries are preallocated at boot. The number -of preallocated entries is defined per architecture. If it is too low for you -boot with 'dma_debug_entries=' to overwrite the -architectural default. diff --git a/trunk/Documentation/DocBook/.gitignore b/trunk/Documentation/DocBook/.gitignore index c6def352fe39..c102c02ecf89 100644 --- a/trunk/Documentation/DocBook/.gitignore +++ b/trunk/Documentation/DocBook/.gitignore @@ -4,7 +4,3 @@ *.html *.9.gz *.9 -*.aux -*.dvi -*.log -*.out diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl index 58c194572c76..bc962cda6504 100644 --- a/trunk/Documentation/DocBook/kernel-api.tmpl +++ b/trunk/Documentation/DocBook/kernel-api.tmpl @@ -199,7 +199,6 @@ X!Edrivers/pci/hotplug.c --> !Edrivers/pci/probe.c !Edrivers/pci/rom.c -!Edrivers/pci/iov.c PCI Hotplug Support Library !Edrivers/pci/hotplug/pci_hotplug_core.c diff --git a/trunk/Documentation/DocBook/procfs_example.c b/trunk/Documentation/DocBook/procfs_example.c index a5b11793b1e0..8c6396e4bf31 100644 --- a/trunk/Documentation/DocBook/procfs_example.c +++ b/trunk/Documentation/DocBook/procfs_example.c @@ -117,6 +117,9 @@ static int __init init_procfs_example(void) rv = -ENOMEM; goto out; } + + example_dir->owner = THIS_MODULE; + /* create jiffies using convenience function */ jiffies_file = create_proc_read_entry("jiffies", 0444, example_dir, @@ -127,6 +130,8 @@ static int __init init_procfs_example(void) goto no_jiffies; } + jiffies_file->owner = THIS_MODULE; + /* create foo and bar files using same callback * functions */ @@ -141,6 +146,7 @@ static int __init init_procfs_example(void) foo_file->data = &foo_data; foo_file->read_proc = proc_read_foobar; foo_file->write_proc = proc_write_foobar; + foo_file->owner = THIS_MODULE; bar_file = create_proc_entry("bar", 0644, example_dir); if(bar_file == NULL) { @@ -153,6 +159,7 @@ static int __init init_procfs_example(void) bar_file->data = &bar_data; bar_file->read_proc = proc_read_foobar; bar_file->write_proc = proc_write_foobar; + bar_file->owner = THIS_MODULE; /* create symlink */ symlink = proc_symlink("jiffies_too", example_dir, @@ -162,6 +169,8 @@ static int __init init_procfs_example(void) goto no_symlink; } + symlink->owner = THIS_MODULE; + /* everything OK */ printk(KERN_INFO "%s %s initialised\n", MODULE_NAME, MODULE_VERS); diff --git a/trunk/Documentation/PCI/MSI-HOWTO.txt b/trunk/Documentation/PCI/MSI-HOWTO.txt index dcf7acc720e1..256defd7e174 100644 --- a/trunk/Documentation/PCI/MSI-HOWTO.txt +++ b/trunk/Documentation/PCI/MSI-HOWTO.txt @@ -4,356 +4,506 @@ Revised Feb 12, 2004 by Martine Silbermann email: Martine.Silbermann@hp.com Revised Jun 25, 2004 by Tom L Nguyen - Revised Jul 9, 2008 by Matthew Wilcox - Copyright 2003, 2008 Intel Corporation 1. About this guide -This guide describes the basics of Message Signaled Interrupts (MSIs), -the advantages of using MSI over traditional interrupt mechanisms, how -to change your driver to use MSI or MSI-X and some basic diagnostics to -try if a device doesn't support MSIs. - - -2. What are MSIs? - -A Message Signaled Interrupt is a write from the device to a special -address which causes an interrupt to be received by the CPU. - -The MSI capability was first specified in PCI 2.2 and was later enhanced -in PCI 3.0 to allow each interrupt to be masked individually. The MSI-X -capability was also introduced with PCI 3.0. It supports more interrupts -per device than MSI and allows interrupts to be independently configured. - -Devices may support both MSI and MSI-X, but only one can be enabled at -a time. - - -3. Why use MSIs? - -There are three reasons why using MSIs can give an advantage over -traditional pin-based interrupts. - -Pin-based PCI interrupts are often shared amongst several devices. -To support this, the kernel must call each interrupt handler associated -with an interrupt, which leads to reduced performance for the system as -a whole. MSIs are never shared, so this problem cannot arise. - -When a device writes data to memory, then raises a pin-based interrupt, -it is possible that the interrupt may arrive before all the data has -arrived in memory (this becomes more likely with devices behind PCI-PCI -bridges). In order to ensure that all the data has arrived in memory, -the interrupt handler must read a register on the device which raised -the interrupt. PCI transaction ordering rules require that all the data -arrives in memory before the value can be returned from the register. -Using MSIs avoids this problem as the interrupt-generating write cannot -pass the data writes, so by the time the interrupt is raised, the driver -knows that all the data has arrived in memory. - -PCI devices can only support a single pin-based interrupt per function. -Often drivers have to query the device to find out what event has -occurred, slowing down interrupt handling for the common case. With -MSIs, a device can support more interrupts, allowing each interrupt -to be specialised to a different purpose. One possible design gives -infrequent conditions (such as errors) their own interrupt which allows -the driver to handle the normal interrupt handling path more efficiently. -Other possible designs include giving one interrupt to each packet queue -in a network card or each port in a storage controller. - - -4. How to use MSIs - -PCI devices are initialised to use pin-based interrupts. The device -driver has to set up the device to use MSI or MSI-X. Not all machines -support MSIs correctly, and for those machines, the APIs described below -will simply fail and the device will continue to use pin-based interrupts. - -4.1 Include kernel support for MSIs - -To support MSI or MSI-X, the kernel must be built with the CONFIG_PCI_MSI -option enabled. This option is only available on some architectures, -and it may depend on some other options also being set. For example, -on x86, you must also enable X86_UP_APIC or SMP in order to see the -CONFIG_PCI_MSI option. - -4.2 Using MSI - -Most of the hard work is done for the driver in the PCI layer. It simply -has to request that the PCI layer set up the MSI capability for this -device. - -4.2.1 pci_enable_msi +This guide describes the basics of Message Signaled Interrupts (MSI), +the advantages of using MSI over traditional interrupt mechanisms, +and how to enable your driver to use MSI or MSI-X. Also included is +a Frequently Asked Questions (FAQ) section. + +1.1 Terminology + +PCI devices can be single-function or multi-function. In either case, +when this text talks about enabling or disabling MSI on a "device +function," it is referring to one specific PCI device and function and +not to all functions on a PCI device (unless the PCI device has only +one function). + +2. Copyright 2003 Intel Corporation + +3. What is MSI/MSI-X? + +Message Signaled Interrupt (MSI), as described in the PCI Local Bus +Specification Revision 2.3 or later, is an optional feature, and a +required feature for PCI Express devices. MSI enables a device function +to request service by sending an Inbound Memory Write on its PCI bus to +the FSB as a Message Signal Interrupt transaction. Because MSI is +generated in the form of a Memory Write, all transaction conditions, +such as a Retry, Master-Abort, Target-Abort or normal completion, are +supported. + +A PCI device that supports MSI must also support pin IRQ assertion +interrupt mechanism to provide backward compatibility for systems that +do not support MSI. In systems which support MSI, the bus driver is +responsible for initializing the message address and message data of +the device function's MSI/MSI-X capability structure during device +initial configuration. + +An MSI capable device function indicates MSI support by implementing +the MSI/MSI-X capability structure in its PCI capability list. The +device function may implement both the MSI capability structure and +the MSI-X capability structure; however, the bus driver should not +enable both. + +The MSI capability structure contains Message Control register, +Message Address register and Message Data register. These registers +provide the bus driver control over MSI. The Message Control register +indicates the MSI capability supported by the device. The Message +Address register specifies the target address and the Message Data +register specifies the characteristics of the message. To request +service, the device function writes the content of the Message Data +register to the target address. The device and its software driver +are prohibited from writing to these registers. + +The MSI-X capability structure is an optional extension to MSI. It +uses an independent and separate capability structure. There are +some key advantages to implementing the MSI-X capability structure +over the MSI capability structure as described below. + + - Support a larger maximum number of vectors per function. + + - Provide the ability for system software to configure + each vector with an independent message address and message + data, specified by a table that resides in Memory Space. + + - MSI and MSI-X both support per-vector masking. Per-vector + masking is an optional extension of MSI but a required + feature for MSI-X. Per-vector masking provides the kernel the + ability to mask/unmask a single MSI while running its + interrupt service routine. If per-vector masking is + not supported, then the device driver should provide the + hardware/software synchronization to ensure that the device + generates MSI when the driver wants it to do so. + +4. Why use MSI? + +As a benefit to the simplification of board design, MSI allows board +designers to remove out-of-band interrupt routing. MSI is another +step towards a legacy-free environment. + +Due to increasing pressure on chipset and processor packages to +reduce pin count, the need for interrupt pins is expected to +diminish over time. Devices, due to pin constraints, may implement +messages to increase performance. + +PCI Express endpoints uses INTx emulation (in-band messages) instead +of IRQ pin assertion. Using INTx emulation requires interrupt +sharing among devices connected to the same node (PCI bridge) while +MSI is unique (non-shared) and does not require BIOS configuration +support. As a result, the PCI Express technology requires MSI +support for better interrupt performance. + +Using MSI enables the device functions to support two or more +vectors, which can be configured to target different CPUs to +increase scalability. + +5. Configuring a driver to use MSI/MSI-X + +By default, the kernel will not enable MSI/MSI-X on all devices that +support this capability. The CONFIG_PCI_MSI kernel option +must be selected to enable MSI/MSI-X support. + +5.1 Including MSI/MSI-X support into the kernel + +To allow MSI/MSI-X capable device drivers to selectively enable +MSI/MSI-X (using pci_enable_msi()/pci_enable_msix() as described +below), the VECTOR based scheme needs to be enabled by setting +CONFIG_PCI_MSI during kernel config. + +Since the target of the inbound message is the local APIC, providing +CONFIG_X86_LOCAL_APIC must be enabled as well as CONFIG_PCI_MSI. + +5.2 Configuring for MSI support + +Due to the non-contiguous fashion in vector assignment of the +existing Linux kernel, this version does not support multiple +messages regardless of a device function is capable of supporting +more than one vector. To enable MSI on a device function's MSI +capability structure requires a device driver to call the function +pci_enable_msi() explicitly. + +5.2.1 API pci_enable_msi int pci_enable_msi(struct pci_dev *dev) -A successful call will allocate ONE interrupt to the device, regardless -of how many MSIs the device supports. The device will be switched from -pin-based interrupt mode to MSI mode. The dev->irq number is changed -to a new number which represents the message signaled interrupt. -This function should be called before the driver calls request_irq() -since enabling MSIs disables the pin-based IRQ and the driver will not -receive interrupts on the old interrupt. - -4.2.2 pci_enable_msi_block - -int pci_enable_msi_block(struct pci_dev *dev, int count) - -This variation on the above call allows a device driver to request multiple -MSIs. The MSI specification only allows interrupts to be allocated in -powers of two, up to a maximum of 2^5 (32). - -If this function returns 0, it has succeeded in allocating at least as many -interrupts as the driver requested (it may have allocated more in order -to satisfy the power-of-two requirement). In this case, the function -enables MSI on this device and updates dev->irq to be the lowest of -the new interrupts assigned to it. The other interrupts assigned to -the device are in the range dev->irq to dev->irq + count - 1. - -If this function returns a negative number, it indicates an error and -the driver should not attempt to request any more MSI interrupts for -this device. If this function returns a positive number, it will be -less than 'count' and indicate the number of interrupts that could have -been allocated. In neither case will the irq value have been -updated, nor will the device have been switched into MSI mode. - -The device driver must decide what action to take if -pci_enable_msi_block() returns a value less than the number asked for. -Some devices can make use of fewer interrupts than the maximum they -request; in this case the driver should call pci_enable_msi_block() -again. Note that it is not guaranteed to succeed, even when the -'count' has been reduced to the value returned from a previous call to -pci_enable_msi_block(). This is because there are multiple constraints -on the number of vectors that can be allocated; pci_enable_msi_block() -will return as soon as it finds any constraint that doesn't allow the -call to succeed. - -4.2.3 pci_disable_msi +With this new API, a device driver that wants to have MSI +enabled on its device function must call this API to enable MSI. +A successful call will initialize the MSI capability structure +with ONE vector, regardless of whether a device function is +capable of supporting multiple messages. This vector replaces the +pre-assigned dev->irq with a new MSI vector. To avoid a conflict +of the new assigned vector with existing pre-assigned vector requires +a device driver to call this API before calling request_irq(). + +5.2.2 API pci_disable_msi void pci_disable_msi(struct pci_dev *dev) -This function should be used to undo the effect of pci_enable_msi() or -pci_enable_msi_block(). Calling it restores dev->irq to the pin-based -interrupt number and frees the previously allocated message signaled -interrupt(s). The interrupt may subsequently be assigned to another -device, so drivers should not cache the value of dev->irq. +This API should always be used to undo the effect of pci_enable_msi() +when a device driver is unloading. This API restores dev->irq with +the pre-assigned IOAPIC vector and switches a device's interrupt +mode to PCI pin-irq assertion/INTx emulation mode. + +Note that a device driver should always call free_irq() on the MSI vector +that it has done request_irq() on before calling this API. Failure to do +so results in a BUG_ON() and a device will be left with MSI enabled and +leaks its vector. + +5.2.3 MSI mode vs. legacy mode diagram + +The below diagram shows the events which switch the interrupt +mode on the MSI-capable device function between MSI mode and +PIN-IRQ assertion mode. + + ------------ pci_enable_msi ------------------------ + | | <=============== | | + | MSI MODE | | PIN-IRQ ASSERTION MODE | + | | ===============> | | + ------------ pci_disable_msi ------------------------ + + +Figure 1. MSI Mode vs. Legacy Mode + +In Figure 1, a device operates by default in legacy mode. Legacy +in this context means PCI pin-irq assertion or PCI-Express INTx +emulation. A successful MSI request (using pci_enable_msi()) switches +a device's interrupt mode to MSI mode. A pre-assigned IOAPIC vector +stored in dev->irq will be saved by the PCI subsystem and a new +assigned MSI vector will replace dev->irq. + +To return back to its default mode, a device driver should always call +pci_disable_msi() to undo the effect of pci_enable_msi(). Note that a +device driver should always call free_irq() on the MSI vector it has +done request_irq() on before calling pci_disable_msi(). Failure to do +so results in a BUG_ON() and a device will be left with MSI enabled and +leaks its vector. Otherwise, the PCI subsystem restores a device's +dev->irq with a pre-assigned IOAPIC vector and marks the released +MSI vector as unused. + +Once being marked as unused, there is no guarantee that the PCI +subsystem will reserve this MSI vector for a device. Depending on +the availability of current PCI vector resources and the number of +MSI/MSI-X requests from other drivers, this MSI may be re-assigned. + +For the case where the PCI subsystem re-assigns this MSI vector to +another driver, a request to switch back to MSI mode may result +in being assigned a different MSI vector or a failure if no more +vectors are available. + +5.3 Configuring for MSI-X support + +Due to the ability of the system software to configure each vector of +the MSI-X capability structure with an independent message address +and message data, the non-contiguous fashion in vector assignment of +the existing Linux kernel has no impact on supporting multiple +messages on an MSI-X capable device functions. To enable MSI-X on +a device function's MSI-X capability structure requires its device +driver to call the function pci_enable_msix() explicitly. + +The function pci_enable_msix(), once invoked, enables either +all or nothing, depending on the current availability of PCI vector +resources. If the PCI vector resources are available for the number +of vectors requested by a device driver, this function will configure +the MSI-X table of the MSI-X capability structure of a device with +requested messages. To emphasize this reason, for example, a device +may be capable for supporting the maximum of 32 vectors while its +software driver usually may request 4 vectors. It is recommended +that the device driver should call this function once during the +initialization phase of the device driver. + +Unlike the function pci_enable_msi(), the function pci_enable_msix() +does not replace the pre-assigned IOAPIC dev->irq with a new MSI +vector because the PCI subsystem writes the 1:1 vector-to-entry mapping +into the field vector of each element contained in a second argument. +Note that the pre-assigned IOAPIC dev->irq is valid only if the device +operates in PIN-IRQ assertion mode. In MSI-X mode, any attempt at +using dev->irq by the device driver to request for interrupt service +may result in unpredictable behavior. + +For each MSI-X vector granted, a device driver is responsible for calling +other functions like request_irq(), enable_irq(), etc. to enable +this vector with its corresponding interrupt service handler. It is +a device driver's choice to assign all vectors with the same +interrupt service handler or each vector with a unique interrupt +service handler. + +5.3.1 Handling MMIO address space of MSI-X Table + +The PCI 3.0 specification has implementation notes that MMIO address +space for a device's MSI-X structure should be isolated so that the +software system can set different pages for controlling accesses to the +MSI-X structure. The implementation of MSI support requires the PCI +subsystem, not a device driver, to maintain full control of the MSI-X +table/MSI-X PBA (Pending Bit Array) and MMIO address space of the MSI-X +table/MSI-X PBA. A device driver should not access the MMIO address +space of the MSI-X table/MSI-X PBA. + +5.3.2 API pci_enable_msix -A device driver must always call free_irq() on the interrupt(s) -for which it has called request_irq() before calling this function. -Failure to do so will result in a BUG_ON(), the device will be left with -MSI enabled and will leak its vector. +int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) + +This API enables a device driver to request the PCI subsystem +to enable MSI-X messages on its hardware device. Depending on +the availability of PCI vectors resources, the PCI subsystem enables +either all or none of the requested vectors. -4.3 Using MSI-X +Argument 'dev' points to the device (pci_dev) structure. -The MSI-X capability is much more flexible than the MSI capability. -It supports up to 2048 interrupts, each of which can be controlled -independently. To support this flexibility, drivers must use an array of -`struct msix_entry': +Argument 'entries' is a pointer to an array of msix_entry structs. +The number of entries is indicated in argument 'nvec'. +struct msix_entry is defined in /driver/pci/msi.h: struct msix_entry { u16 vector; /* kernel uses to write alloc vector */ u16 entry; /* driver uses to specify entry */ }; -This allows for the device to use these interrupts in a sparse fashion; -for example it could use interrupts 3 and 1027 and allocate only a -two-element array. The driver is expected to fill in the 'entry' value -in each element of the array to indicate which entries it wants the kernel -to assign interrupts for. It is invalid to fill in two entries with the -same number. - -4.3.1 pci_enable_msix - -int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) - -Calling this function asks the PCI subsystem to allocate 'nvec' MSIs. -The 'entries' argument is a pointer to an array of msix_entry structs -which should be at least 'nvec' entries in size. On success, the -function will return 0 and the device will have been switched into -MSI-X interrupt mode. The 'vector' elements in each entry will have -been filled in with the interrupt number. The driver should then call -request_irq() for each 'vector' that it decides to use. - -If this function returns a negative number, it indicates an error and -the driver should not attempt to allocate any more MSI-X interrupts for -this device. If it returns a positive number, it indicates the maximum -number of interrupt vectors that could have been allocated. See example -below. - -This function, in contrast with pci_enable_msi(), does not adjust -dev->irq. The device will not generate interrupts for this interrupt -number once MSI-X is enabled. The device driver is responsible for -keeping track of the interrupts assigned to the MSI-X vectors so it can -free them again later. - -Device drivers should normally call this function once per device -during the initialization phase. - -It is ideal if drivers can cope with a variable number of MSI-X interrupts, -there are many reasons why the platform may not be able to provide the -exact number a driver asks for. - -A request loop to achieve that might look like: - -static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) -{ - while (nvec >= FOO_DRIVER_MINIMUM_NVEC) { - rc = pci_enable_msix(adapter->pdev, - adapter->msix_entries, nvec); - if (rc > 0) - nvec = rc; - else - return rc; - } - - return -ENOSPC; -} - -4.3.2 pci_disable_msix +A device driver is responsible for initializing the field 'entry' of +each element with a unique entry supported by MSI-X table. Otherwise, +-EINVAL will be returned as a result. A successful return of zero +indicates the PCI subsystem completed initializing each of the requested +entries of the MSI-X table with message address and message data. +Last but not least, the PCI subsystem will write the 1:1 +vector-to-entry mapping into the field 'vector' of each element. A +device driver is responsible for keeping track of allocated MSI-X +vectors in its internal data structure. + +A return of zero indicates that the number of MSI-X vectors was +successfully allocated. A return of greater than zero indicates +MSI-X vector shortage. Or a return of less than zero indicates +a failure. This failure may be a result of duplicate entries +specified in second argument, or a result of no available vector, +or a result of failing to initialize MSI-X table entries. + +5.3.3 API pci_disable_msix void pci_disable_msix(struct pci_dev *dev) -This API should be used to undo the effect of pci_enable_msix(). It frees -the previously allocated message signaled interrupts. The interrupts may -subsequently be assigned to another device, so drivers should not cache -the value of the 'vector' elements over a call to pci_disable_msix(). - -A device driver must always call free_irq() on the interrupt(s) -for which it has called request_irq() before calling this function. -Failure to do so will result in a BUG_ON(), the device will be left with -MSI enabled and will leak its vector. - -4.3.3 The MSI-X Table - -The MSI-X capability specifies a BAR and offset within that BAR for the -MSI-X Table. This address is mapped by the PCI subsystem, and should not -be accessed directly by the device driver. If the driver wishes to -mask or unmask an interrupt, it should call disable_irq() / enable_irq(). - -4.4 Handling devices implementing both MSI and MSI-X capabilities - -If a device implements both MSI and MSI-X capabilities, it can -run in either MSI mode or MSI-X mode but not both simultaneously. -This is a requirement of the PCI spec, and it is enforced by the -PCI layer. Calling pci_enable_msi() when MSI-X is already enabled or -pci_enable_msix() when MSI is already enabled will result in an error. -If a device driver wishes to switch between MSI and MSI-X at runtime, -it must first quiesce the device, then switch it back to pin-interrupt -mode, before calling pci_enable_msi() or pci_enable_msix() and resuming -operation. This is not expected to be a common operation but may be -useful for debugging or testing during development. - -4.5 Considerations when using MSIs - -4.5.1 Choosing between MSI-X and MSI - -If your device supports both MSI-X and MSI capabilities, you should use -the MSI-X facilities in preference to the MSI facilities. As mentioned -above, MSI-X supports any number of interrupts between 1 and 2048. -In constrast, MSI is restricted to a maximum of 32 interrupts (and -must be a power of two). In addition, the MSI interrupt vectors must -be allocated consecutively, so the system may not be able to allocate -as many vectors for MSI as it could for MSI-X. On some platforms, MSI -interrupts must all be targetted at the same set of CPUs whereas MSI-X -interrupts can all be targetted at different CPUs. - -4.5.2 Spinlocks - -Most device drivers have a per-device spinlock which is taken in the -interrupt handler. With pin-based interrupts or a single MSI, it is not -necessary to disable interrupts (Linux guarantees the same interrupt will -not be re-entered). If a device uses multiple interrupts, the driver -must disable interrupts while the lock is held. If the device sends -a different interrupt, the driver will deadlock trying to recursively -acquire the spinlock. - -There are two solutions. The first is to take the lock with -spin_lock_irqsave() or spin_lock_irq() (see -Documentation/DocBook/kernel-locking). The second is to specify -IRQF_DISABLED to request_irq() so that the kernel runs the entire -interrupt routine with interrupts disabled. - -If your MSI interrupt routine does not hold the lock for the whole time -it is running, the first solution may be best. The second solution is -normally preferred as it avoids making two transitions from interrupt -disabled to enabled and back again. - -4.6 How to tell whether MSI/MSI-X is enabled on a device - -Using 'lspci -v' (as root) may show some devices with "MSI", "Message -Signalled Interrupts" or "MSI-X" capabilities. Each of these capabilities -has an 'Enable' flag which will be followed with either "+" (enabled) -or "-" (disabled). - - -5. MSI quirks - -Several PCI chipsets or devices are known not to support MSIs. -The PCI stack provides three ways to disable MSIs: - -1. globally -2. on all devices behind a specific bridge -3. on a single device - -5.1. Disabling MSIs globally - -Some host chipsets simply don't support MSIs properly. If we're -lucky, the manufacturer knows this and has indicated it in the ACPI -FADT table. In this case, Linux will automatically disable MSIs. -Some boards don't include this information in the table and so we have -to detect them ourselves. The complete list of these is found near the -quirk_disable_all_msi() function in drivers/pci/quirks.c. - -If you have a board which has problems with MSIs, you can pass pci=nomsi -on the kernel command line to disable MSIs on all devices. It would be -in your best interests to report the problem to linux-pci@vger.kernel.org -including a full 'lspci -v' so we can add the quirks to the kernel. - -5.2. Disabling MSIs below a bridge - -Some PCI bridges are not able to route MSIs between busses properly. -In this case, MSIs must be disabled on all devices behind the bridge. - -Some bridges allow you to enable MSIs by changing some bits in their -PCI configuration space (especially the Hypertransport chipsets such -as the nVidia nForce and Serverworks HT2000). As with host chipsets, -Linux mostly knows about them and automatically enables MSIs if it can. -If you have a bridge which Linux doesn't yet know about, you can enable -MSIs in configuration space using whatever method you know works, then -enable MSIs on that bridge by doing: - - echo 1 > /sys/bus/pci/devices/$bridge/msi_bus - -where $bridge is the PCI address of the bridge you've enabled (eg -0000:00:0e.0). - -To disable MSIs, echo 0 instead of 1. Changing this value should be -done with caution as it can break interrupt handling for all devices -below this bridge. - -Again, please notify linux-pci@vger.kernel.org of any bridges that need -special handling. - -5.3. Disabling MSIs on a single device - -Some devices are known to have faulty MSI implementations. Usually this -is handled in the individual device driver but occasionally it's necessary -to handle this with a quirk. Some drivers have an option to disable use -of MSI. While this is a convenient workaround for the driver author, -it is not good practise, and should not be emulated. - -5.4. Finding why MSIs are disabled on a device - -From the above three sections, you can see that there are many reasons -why MSIs may not be enabled for a given device. Your first step should -be to examine your dmesg carefully to determine whether MSIs are enabled -for your machine. You should also check your .config to be sure you -have enabled CONFIG_PCI_MSI. - -Then, 'lspci -t' gives the list of bridges above a device. Reading -/sys/bus/pci/devices/*/msi_bus will tell you whether MSI are enabled (1) -or disabled (0). If 0 is found in any of the msi_bus files belonging -to bridges between the PCI root and the device, MSIs are disabled. - -It is also worth checking the device driver to see whether it supports MSIs. -For example, it may contain calls to pci_enable_msi(), pci_enable_msix() or -pci_enable_msi_block(). +This API should always be used to undo the effect of pci_enable_msix() +when a device driver is unloading. Note that a device driver should +always call free_irq() on all MSI-X vectors it has done request_irq() +on before calling this API. Failure to do so results in a BUG_ON() and +a device will be left with MSI-X enabled and leaks its vectors. + +5.3.4 MSI-X mode vs. legacy mode diagram + +The below diagram shows the events which switch the interrupt +mode on the MSI-X capable device function between MSI-X mode and +PIN-IRQ assertion mode (legacy). + + ------------ pci_enable_msix(,,n) ------------------------ + | | <=============== | | + | MSI-X MODE | | PIN-IRQ ASSERTION MODE | + | | ===============> | | + ------------ pci_disable_msix ------------------------ + +Figure 2. MSI-X Mode vs. Legacy Mode + +In Figure 2, a device operates by default in legacy mode. A +successful MSI-X request (using pci_enable_msix()) switches a +device's interrupt mode to MSI-X mode. A pre-assigned IOAPIC vector +stored in dev->irq will be saved by the PCI subsystem; however, +unlike MSI mode, the PCI subsystem will not replace dev->irq with +assigned MSI-X vector because the PCI subsystem already writes the 1:1 +vector-to-entry mapping into the field 'vector' of each element +specified in second argument. + +To return back to its default mode, a device driver should always call +pci_disable_msix() to undo the effect of pci_enable_msix(). Note that +a device driver should always call free_irq() on all MSI-X vectors it +has done request_irq() on before calling pci_disable_msix(). Failure +to do so results in a BUG_ON() and a device will be left with MSI-X +enabled and leaks its vectors. Otherwise, the PCI subsystem switches a +device function's interrupt mode from MSI-X mode to legacy mode and +marks all allocated MSI-X vectors as unused. + +Once being marked as unused, there is no guarantee that the PCI +subsystem will reserve these MSI-X vectors for a device. Depending on +the availability of current PCI vector resources and the number of +MSI/MSI-X requests from other drivers, these MSI-X vectors may be +re-assigned. + +For the case where the PCI subsystem re-assigned these MSI-X vectors +to other drivers, a request to switch back to MSI-X mode may result +being assigned with another set of MSI-X vectors or a failure if no +more vectors are available. + +5.4 Handling function implementing both MSI and MSI-X capabilities + +For the case where a function implements both MSI and MSI-X +capabilities, the PCI subsystem enables a device to run either in MSI +mode or MSI-X mode but not both. A device driver determines whether it +wants MSI or MSI-X enabled on its hardware device. Once a device +driver requests for MSI, for example, it is prohibited from requesting +MSI-X; in other words, a device driver is not permitted to ping-pong +between MSI mod MSI-X mode during a run-time. + +5.5 Hardware requirements for MSI/MSI-X support + +MSI/MSI-X support requires support from both system hardware and +individual hardware device functions. + +5.5.1 Required x86 hardware support + +Since the target of MSI address is the local APIC CPU, enabling +MSI/MSI-X support in the Linux kernel is dependent on whether existing +system hardware supports local APIC. Users should verify that their +system supports local APIC operation by testing that it runs when +CONFIG_X86_LOCAL_APIC=y. + +In SMP environment, CONFIG_X86_LOCAL_APIC is automatically set; +however, in UP environment, users must manually set +CONFIG_X86_LOCAL_APIC. Once CONFIG_X86_LOCAL_APIC=y, setting +CONFIG_PCI_MSI enables the VECTOR based scheme and the option for +MSI-capable device drivers to selectively enable MSI/MSI-X. + +Note that CONFIG_X86_IO_APIC setting is irrelevant because MSI/MSI-X +vector is allocated new during runtime and MSI/MSI-X support does not +depend on BIOS support. This key independency enables MSI/MSI-X +support on future IOxAPIC free platforms. + +5.5.2 Device hardware support + +The hardware device function supports MSI by indicating the +MSI/MSI-X capability structure on its PCI capability list. By +default, this capability structure will not be initialized by +the kernel to enable MSI during the system boot. In other words, +the device function is running on its default pin assertion mode. +Note that in many cases the hardware supporting MSI have bugs, +which may result in system hangs. The software driver of specific +MSI-capable hardware is responsible for deciding whether to call +pci_enable_msi or not. A return of zero indicates the kernel +successfully initialized the MSI/MSI-X capability structure of the +device function. The device function is now running on MSI/MSI-X mode. + +5.6 How to tell whether MSI/MSI-X is enabled on device function + +At the driver level, a return of zero from the function call of +pci_enable_msi()/pci_enable_msix() indicates to a device driver that +its device function is initialized successfully and ready to run in +MSI/MSI-X mode. + +At the user level, users can use the command 'cat /proc/interrupts' +to display the vectors allocated for devices and their interrupt +MSI/MSI-X modes ("PCI-MSI"/"PCI-MSI-X"). Below shows MSI mode is +enabled on a SCSI Adaptec 39320D Ultra320 controller. + + CPU0 CPU1 + 0: 324639 0 IO-APIC-edge timer + 1: 1186 0 IO-APIC-edge i8042 + 2: 0 0 XT-PIC cascade + 12: 2797 0 IO-APIC-edge i8042 + 14: 6543 0 IO-APIC-edge ide0 + 15: 1 0 IO-APIC-edge ide1 +169: 0 0 IO-APIC-level uhci-hcd +185: 0 0 IO-APIC-level uhci-hcd +193: 138 10 PCI-MSI aic79xx +201: 30 0 PCI-MSI aic79xx +225: 30 0 IO-APIC-level aic7xxx +233: 30 0 IO-APIC-level aic7xxx +NMI: 0 0 +LOC: 324553 325068 +ERR: 0 +MIS: 0 + +6. MSI quirks + +Several PCI chipsets or devices are known to not support MSI. +The PCI stack provides 3 possible levels of MSI disabling: +* on a single device +* on all devices behind a specific bridge +* globally + +6.1. Disabling MSI on a single device + +Under some circumstances it might be required to disable MSI on a +single device. This may be achieved by either not calling pci_enable_msi() +or all, or setting the pci_dev->no_msi flag before (most of the time +in a quirk). + +6.2. Disabling MSI below a bridge + +The vast majority of MSI quirks are required by PCI bridges not +being able to route MSI between busses. In this case, MSI have to be +disabled on all devices behind this bridge. It is achieves by setting +the PCI_BUS_FLAGS_NO_MSI flag in the pci_bus->bus_flags of the bridge +subordinate bus. There is no need to set the same flag on bridges that +are below the broken bridge. When pci_enable_msi() is called to enable +MSI on a device, pci_msi_supported() takes care of checking the NO_MSI +flag in all parent busses of the device. + +Some bridges actually support dynamic MSI support enabling/disabling +by changing some bits in their PCI configuration space (especially +the Hypertransport chipsets such as the nVidia nForce and Serverworks +HT2000). It may then be required to update the NO_MSI flag on the +corresponding devices in the sysfs hierarchy. To enable MSI support +on device "0000:00:0e", do: + + echo 1 > /sys/bus/pci/devices/0000:00:0e/msi_bus + +To disable MSI support, echo 0 instead of 1. Note that it should be +used with caution since changing this value might break interrupts. + +6.3. Disabling MSI globally + +Some extreme cases may require to disable MSI globally on the system. +For now, the only known case is a Serverworks PCI-X chipsets (MSI are +not supported on several busses that are not all connected to the +chipset in the Linux PCI hierarchy). In the vast majority of other +cases, disabling only behind a specific bridge is enough. + +For debugging purpose, the user may also pass pci=nomsi on the kernel +command-line to explicitly disable MSI globally. But, once the appro- +priate quirks are added to the kernel, this option should not be +required anymore. + +6.4. Finding why MSI cannot be enabled on a device + +Assuming that MSI are not enabled on a device, you should look at +dmesg to find messages that quirks may output when disabling MSI +on some devices, some bridges or even globally. +Then, lspci -t gives the list of bridges above a device. Reading +/sys/bus/pci/devices/0000:00:0e/msi_bus will tell you whether MSI +are enabled (1) or disabled (0). In 0 is found in a single bridge +msi_bus file above the device, MSI cannot be enabled. + +7. FAQ + +Q1. Are there any limitations on using the MSI? + +A1. If the PCI device supports MSI and conforms to the +specification and the platform supports the APIC local bus, +then using MSI should work. + +Q2. Will it work on all the Pentium processors (P3, P4, Xeon, +AMD processors)? In P3 IPI's are transmitted on the APIC local +bus and in P4 and Xeon they are transmitted on the system +bus. Are there any implications with this? + +A2. MSI support enables a PCI device sending an inbound +memory write (0xfeexxxxx as target address) on its PCI bus +directly to the FSB. Since the message address has a +redirection hint bit cleared, it should work. + +Q3. The target address 0xfeexxxxx will be translated by the +Host Bridge into an interrupt message. Are there any +limitations on the chipsets such as Intel 8xx, Intel e7xxx, +or VIA? + +A3. If these chipsets support an inbound memory write with +target address set as 0xfeexxxxx, as conformed to PCI +specification 2.3 or latest, then it should work. + +Q4. From the driver point of view, if the MSI is lost because +of errors occurring during inbound memory write, then it may +wait forever. Is there a mechanism for it to recover? + +A4. Since the target of the transaction is an inbound memory +write, all transaction termination conditions (Retry, +Master-Abort, Target-Abort, or normal completion) are +supported. A device sending an MSI must abide by all the PCI +rules and conditions regarding that inbound memory write. So, +if a retry is signaled it must retry, etc... We believe that +the recommendation for Abort is also a retry (refer to PCI +specification 2.3 or latest). diff --git a/trunk/Documentation/PCI/pci-iov-howto.txt b/trunk/Documentation/PCI/pci-iov-howto.txt deleted file mode 100644 index fc73ef5d65b8..000000000000 --- a/trunk/Documentation/PCI/pci-iov-howto.txt +++ /dev/null @@ -1,99 +0,0 @@ - PCI Express I/O Virtualization Howto - Copyright (C) 2009 Intel Corporation - Yu Zhao - - -1. Overview - -1.1 What is SR-IOV - -Single Root I/O Virtualization (SR-IOV) is a PCI Express Extended -capability which makes one physical device appear as multiple virtual -devices. The physical device is referred to as Physical Function (PF) -while the virtual devices are referred to as Virtual Functions (VF). -Allocation of the VF can be dynamically controlled by the PF via -registers encapsulated in the capability. By default, this feature is -not enabled and the PF behaves as traditional PCIe device. Once it's -turned on, each VF's PCI configuration space can be accessed by its own -Bus, Device and Function Number (Routing ID). And each VF also has PCI -Memory Space, which is used to map its register set. VF device driver -operates on the register set so it can be functional and appear as a -real existing PCI device. - -2. User Guide - -2.1 How can I enable SR-IOV capability - -The device driver (PF driver) will control the enabling and disabling -of the capability via API provided by SR-IOV core. If the hardware -has SR-IOV capability, loading its PF driver would enable it and all -VFs associated with the PF. - -2.2 How can I use the Virtual Functions - -The VF is treated as hot-plugged PCI devices in the kernel, so they -should be able to work in the same way as real PCI devices. The VF -requires device driver that is same as a normal PCI device's. - -3. Developer Guide - -3.1 SR-IOV API - -To enable SR-IOV capability: - int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); - 'nr_virtfn' is number of VFs to be enabled. - -To disable SR-IOV capability: - void pci_disable_sriov(struct pci_dev *dev); - -To notify SR-IOV core of Virtual Function Migration: - irqreturn_t pci_sriov_migration(struct pci_dev *dev); - -3.2 Usage example - -Following piece of code illustrates the usage of the SR-IOV API. - -static int __devinit dev_probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - pci_enable_sriov(dev, NR_VIRTFN); - - ... - - return 0; -} - -static void __devexit dev_remove(struct pci_dev *dev) -{ - pci_disable_sriov(dev); - - ... -} - -static int dev_suspend(struct pci_dev *dev, pm_message_t state) -{ - ... - - return 0; -} - -static int dev_resume(struct pci_dev *dev) -{ - ... - - return 0; -} - -static void dev_shutdown(struct pci_dev *dev) -{ - ... -} - -static struct pci_driver dev_driver = { - .name = "SR-IOV Physical Function driver", - .id_table = dev_id_table, - .probe = dev_probe, - .remove = __devexit_p(dev_remove), - .suspend = dev_suspend, - .resume = dev_resume, - .shutdown = dev_shutdown, -}; diff --git a/trunk/Documentation/Smack.txt b/trunk/Documentation/Smack.txt index 629c92e99783..989c2fcd8111 100644 --- a/trunk/Documentation/Smack.txt +++ b/trunk/Documentation/Smack.txt @@ -184,16 +184,14 @@ length. Single character labels using special characters, that being anything other than a letter or digit, are reserved for use by the Smack development team. Smack labels are unstructured, case sensitive, and the only operation ever performed on them is comparison for equality. Smack labels cannot -contain unprintable characters or the "/" (slash) character. Smack labels -cannot begin with a '-', which is reserved for special options. +contain unprintable characters or the "/" (slash) character. There are some predefined labels: - _ Pronounced "floor", a single underscore character. - ^ Pronounced "hat", a single circumflex character. - * Pronounced "star", a single asterisk character. - ? Pronounced "huh", a single question mark character. - @ Pronounced "Internet", a single at sign character. + _ Pronounced "floor", a single underscore character. + ^ Pronounced "hat", a single circumflex character. + * Pronounced "star", a single asterisk character. + ? Pronounced "huh", a single question mark character. Every task on a Smack system is assigned a label. System tasks, such as init(8) and systems daemons, are run with the floor ("_") label. User tasks @@ -414,36 +412,6 @@ sockets. A privileged program may set this to match the label of another task with which it hopes to communicate. -Smack Netlabel Exceptions - -You will often find that your labeled application has to talk to the outside, -unlabeled world. To do this there's a special file /smack/netlabel where you can -add some exceptions in the form of : -@IP1 LABEL1 or -@IP2/MASK LABEL2 - -It means that your application will have unlabeled access to @IP1 if it has -write access on LABEL1, and access to the subnet @IP2/MASK if it has write -access on LABEL2. - -Entries in the /smack/netlabel file are matched by longest mask first, like in -classless IPv4 routing. - -A special label '@' and an option '-CIPSO' can be used there : -@ means Internet, any application with any label has access to it --CIPSO means standard CIPSO networking - -If you don't know what CIPSO is and don't plan to use it, you can just do : -echo 127.0.0.1 -CIPSO > /smack/netlabel -echo 0.0.0.0/0 @ > /smack/netlabel - -If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled -Internet access, you can have : -echo 127.0.0.1 -CIPSO > /smack/netlabel -echo 192.168.0.0/16 -CIPSO > /smack/netlabel -echo 0.0.0.0/0 @ > /smack/netlabel - - Writing Applications for Smack There are three sorts of applications that will run on a Smack system. How an diff --git a/trunk/Documentation/cgroups/cgroups.txt b/trunk/Documentation/cgroups/cgroups.txt index 4ea852345a47..93feb8444489 100644 --- a/trunk/Documentation/cgroups/cgroups.txt +++ b/trunk/Documentation/cgroups/cgroups.txt @@ -333,23 +333,12 @@ The "xxx" is not interpreted by the cgroup code, but will appear in To mount a cgroup hierarchy with just the cpuset and numtasks subsystems, type: -# mount -t cgroup -o cpuset,memory hier1 /dev/cgroup +# mount -t cgroup -o cpuset,numtasks hier1 /dev/cgroup To change the set of subsystems bound to a mounted hierarchy, just remount with different options: -# mount -o remount,cpuset,ns hier1 /dev/cgroup -Now memory is removed from the hierarchy and ns is added. - -Note this will add ns to the hierarchy but won't remove memory or -cpuset, because the new options are appended to the old ones: -# mount -o remount,ns /dev/cgroup - -To Specify a hierarchy's release_agent: -# mount -t cgroup -o cpuset,release_agent="/sbin/cpuset_release_agent" \ - xxx /dev/cgroup - -Note that specifying 'release_agent' more than once will return failure. +# mount -o remount,cpuset,ns /dev/cgroup Note that changing the set of subsystems is currently only supported when the hierarchy consists of a single (root) cgroup. Supporting @@ -360,11 +349,6 @@ Then under /dev/cgroup you can find a tree that corresponds to the tree of the cgroups in the system. For instance, /dev/cgroup is the cgroup that holds the whole system. -If you want to change the value of release_agent: -# echo "/sbin/new_release_agent" > /dev/cgroup/release_agent - -It can also be changed via remount. - If you want to create a new cgroup under /dev/cgroup: # cd /dev/cgroup # mkdir my_cgroup @@ -492,13 +476,11 @@ cgroup->parent is still valid. (Note - can also be called for a newly-created cgroup if an error occurs after this subsystem's create() method has been called for the new cgroup). -int pre_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp); +void pre_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp); Called before checking the reference count on each subsystem. This may be useful for subsystems which have some extra references even if -there are not tasks in the cgroup. If pre_destroy() returns error code, -rmdir() will fail with it. From this behavior, pre_destroy() can be -called multiple times against a cgroup. +there are not tasks in the cgroup. int can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, struct task_struct *task) diff --git a/trunk/Documentation/cgroups/memcg_test.txt b/trunk/Documentation/cgroups/memcg_test.txt index 8a11caf417a0..523a9c16c400 100644 --- a/trunk/Documentation/cgroups/memcg_test.txt +++ b/trunk/Documentation/cgroups/memcg_test.txt @@ -1,5 +1,5 @@ Memory Resource Controller(Memcg) Implementation Memo. -Last Updated: 2009/1/20 +Last Updated: 2009/1/19 Base Kernel Version: based on 2.6.29-rc2. Because VM is getting complex (one of reasons is memcg...), memcg's behavior @@ -360,21 +360,3 @@ Under below explanation, we assume CONFIG_MEM_RES_CTRL_SWAP=y. # kill malloc task. Of course, tmpfs v.s. swapoff test should be tested, too. - - 9.8 OOM-Killer - Out-of-memory caused by memcg's limit will kill tasks under - the memcg. When hierarchy is used, a task under hierarchy - will be killed by the kernel. - In this case, panic_on_oom shouldn't be invoked and tasks - in other groups shouldn't be killed. - - It's not difficult to cause OOM under memcg as following. - Case A) when you can swapoff - #swapoff -a - #echo 50M > /memory.limit_in_bytes - run 51M of malloc - - Case B) when you use mem+swap limitation. - #echo 50M > memory.limit_in_bytes - #echo 50M > memory.memsw.limit_in_bytes - run 51M of malloc diff --git a/trunk/Documentation/dvb/get_dvb_firmware b/trunk/Documentation/dvb/get_dvb_firmware index 2f21ecd4c205..f2e908d7f90d 100644 --- a/trunk/Documentation/dvb/get_dvb_firmware +++ b/trunk/Documentation/dvb/get_dvb_firmware @@ -25,7 +25,7 @@ use IO::Handle; "tda10046lifeview", "av7110", "dec2000t", "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004", "or51211", "or51132_qam", "or51132_vsb", "bluebird", - "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2" ); + "opera1"); # Check args syntax() if (scalar(@ARGV) != 1); @@ -37,8 +37,8 @@ for ($i=0; $i < scalar(@components); $i++) { $outfile = eval($cid); die $@ if $@; print STDERR < '588f081b562f5c653a3db1ad8f65939a', - 'v4l-cx23418-cpu.fw' => 'b6c7ed64bc44b1a6e0840adaeac39d79', - 'v4l-cx23418-dig.fw' => '95bc688d3e7599fd5800161e9971cc55', - ); - - checkstandard(); - - my $allfiles; - foreach my $fwfile (keys %files) { - wgetfile($fwfile, "$url/$fwfile"); - verify($fwfile, $files{$fwfile}); - $allfiles .= " $fwfile"; - } - - $allfiles =~ s/^\s//; - - $allfiles; -} - -sub cx23885 { - my $url = "http://linuxtv.org/downloads/firmware/"; - - my %files = ( - 'v4l-cx23885-avcore-01.fw' => 'a9f8f5d901a7fb42f552e1ee6384f3bb', - 'v4l-cx23885-enc.fw' => 'a9f8f5d901a7fb42f552e1ee6384f3bb', - ); - - checkstandard(); - - my $allfiles; - foreach my $fwfile (keys %files) { - wgetfile($fwfile, "$url/$fwfile"); - verify($fwfile, $files{$fwfile}); - $allfiles .= " $fwfile"; - } - - $allfiles =~ s/^\s//; - - $allfiles; -} - -sub pvrusb2 { - my $url = "http://linuxtv.org/downloads/firmware/"; - - my %files = ( - 'v4l-cx25840.fw' => 'dadb79e9904fc8af96e8111d9cb59320', - ); - - checkstandard(); - - my $allfiles; - foreach my $fwfile (keys %files) { - wgetfile($fwfile, "$url/$fwfile"); - verify($fwfile, $files{$fwfile}); - $allfiles .= " $fwfile"; - } - - $allfiles =~ s/^\s//; - - $allfiles; -} - sub or51132_qam { my $fwfile = "dvb-fe-or51132-qam.fw"; my $url = "http://linuxtv.org/downloads/firmware/$fwfile"; diff --git a/trunk/Documentation/fb/00-INDEX b/trunk/Documentation/fb/00-INDEX index a618fd99c9f0..caabbd395e61 100644 --- a/trunk/Documentation/fb/00-INDEX +++ b/trunk/Documentation/fb/00-INDEX @@ -11,6 +11,8 @@ aty128fb.txt - info on the ATI Rage128 frame buffer driver. cirrusfb.txt - info on the driver for Cirrus Logic chipsets. +cyblafb/ + - directory with documentation files related to the cyblafb driver. deferred_io.txt - an introduction to deferred IO. fbcon.txt diff --git a/trunk/Documentation/fb/cyblafb/bugs b/trunk/Documentation/fb/cyblafb/bugs new file mode 100644 index 000000000000..9443a6d72cdd --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/bugs @@ -0,0 +1,13 @@ +Bugs +==== + +I currently don't know of any bug. Please do send reports to: + - linux-fbdev-devel@lists.sourceforge.net + - Knut_Petersen@t-online.de. + + +Untested features +================= + +All LCD stuff is untested. If it worked in tridentfb, it should work in +cyblafb. Please test and report the results to Knut_Petersen@t-online.de. diff --git a/trunk/Documentation/fb/cyblafb/credits b/trunk/Documentation/fb/cyblafb/credits new file mode 100644 index 000000000000..0eb3b443dc2b --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/credits @@ -0,0 +1,7 @@ +Thanks to +========= + * Alan Hourihane, for writing the X trident driver + * Jani Monoses, for writing the tridentfb driver + * Antonino A. Daplas, for review of the first published + version of cyblafb and some code + * Jochen Hein, for testing and a helpfull bug report diff --git a/trunk/Documentation/fb/cyblafb/documentation b/trunk/Documentation/fb/cyblafb/documentation new file mode 100644 index 000000000000..bb1aac048425 --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/documentation @@ -0,0 +1,17 @@ +Available Documentation +======================= + +Apollo PLE 133 Chipset VT8601A North Bridge Datasheet, Rev. 1.82, October 22, +2001, available from VIA: + + http://www.viavpsd.com/product/6/15/DS8601A182.pdf + +The datasheet is incomplete, some registers that need to be programmed are not +explained at all and important bits are listed as "reserved". But you really +need the datasheet to understand the code. "p. xxx" comments refer to page +numbers of this document. + +XFree/XOrg drivers are available and of good quality, looking at the code +there is a good idea if the datasheet does not provide enough information +or if the datasheet seems to be wrong. + diff --git a/trunk/Documentation/fb/cyblafb/fb.modes b/trunk/Documentation/fb/cyblafb/fb.modes new file mode 100644 index 000000000000..fe0e5223ba86 --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/fb.modes @@ -0,0 +1,154 @@ +# +# Sample fb.modes file +# +# Provides an incomplete list of working modes for +# the cyberblade/i1 graphics core. +# +# The value 4294967256 is used instead of -40. Of course, -40 is not +# a really reasonable value, but chip design does not always follow +# logic. Believe me, it's ok, and it's the way the BIOS does it. +# +# fbset requires 4294967256 in fb.modes and -40 as an argument to +# the -t parameter. That's also not too reasonable, and it might change +# in the future or might even be differt for your current version. +# + +mode "640x480-50" + geometry 640 480 2048 4096 8 + timings 47619 4294967256 24 17 0 216 3 +endmode + +mode "640x480-60" + geometry 640 480 2048 4096 8 + timings 39682 4294967256 24 17 0 216 3 +endmode + +mode "640x480-70" + geometry 640 480 2048 4096 8 + timings 34013 4294967256 24 17 0 216 3 +endmode + +mode "640x480-72" + geometry 640 480 2048 4096 8 + timings 33068 4294967256 24 17 0 216 3 +endmode + +mode "640x480-75" + geometry 640 480 2048 4096 8 + timings 31746 4294967256 24 17 0 216 3 +endmode + +mode "640x480-80" + geometry 640 480 2048 4096 8 + timings 29761 4294967256 24 17 0 216 3 +endmode + +mode "640x480-85" + geometry 640 480 2048 4096 8 + timings 28011 4294967256 24 17 0 216 3 +endmode + +mode "800x600-50" + geometry 800 600 2048 4096 8 + timings 30303 96 24 14 0 136 11 +endmode + +mode "800x600-60" + geometry 800 600 2048 4096 8 + timings 25252 96 24 14 0 136 11 +endmode + +mode "800x600-70" + geometry 800 600 2048 4096 8 + timings 21645 96 24 14 0 136 11 +endmode + +mode "800x600-72" + geometry 800 600 2048 4096 8 + timings 21043 96 24 14 0 136 11 +endmode + +mode "800x600-75" + geometry 800 600 2048 4096 8 + timings 20202 96 24 14 0 136 11 +endmode + +mode "800x600-80" + geometry 800 600 2048 4096 8 + timings 18939 96 24 14 0 136 11 +endmode + +mode "800x600-85" + geometry 800 600 2048 4096 8 + timings 17825 96 24 14 0 136 11 +endmode + +mode "1024x768-50" + geometry 1024 768 2048 4096 8 + timings 19054 144 24 29 0 120 3 +endmode + +mode "1024x768-60" + geometry 1024 768 2048 4096 8 + timings 15880 144 24 29 0 120 3 +endmode + +mode "1024x768-70" + geometry 1024 768 2048 4096 8 + timings 13610 144 24 29 0 120 3 +endmode + +mode "1024x768-72" + geometry 1024 768 2048 4096 8 + timings 13232 144 24 29 0 120 3 +endmode + +mode "1024x768-75" + geometry 1024 768 2048 4096 8 + timings 12703 144 24 29 0 120 3 +endmode + +mode "1024x768-80" + geometry 1024 768 2048 4096 8 + timings 11910 144 24 29 0 120 3 +endmode + +mode "1024x768-85" + geometry 1024 768 2048 4096 8 + timings 11209 144 24 29 0 120 3 +endmode + +mode "1280x1024-50" + geometry 1280 1024 2048 4096 8 + timings 11114 232 16 39 0 160 3 +endmode + +mode "1280x1024-60" + geometry 1280 1024 2048 4096 8 + timings 9262 232 16 39 0 160 3 +endmode + +mode "1280x1024-70" + geometry 1280 1024 2048 4096 8 + timings 7939 232 16 39 0 160 3 +endmode + +mode "1280x1024-72" + geometry 1280 1024 2048 4096 8 + timings 7719 232 16 39 0 160 3 +endmode + +mode "1280x1024-75" + geometry 1280 1024 2048 4096 8 + timings 7410 232 16 39 0 160 3 +endmode + +mode "1280x1024-80" + geometry 1280 1024 2048 4096 8 + timings 6946 232 16 39 0 160 3 +endmode + +mode "1280x1024-85" + geometry 1280 1024 2048 4096 8 + timings 6538 232 16 39 0 160 3 +endmode diff --git a/trunk/Documentation/fb/cyblafb/performance b/trunk/Documentation/fb/cyblafb/performance new file mode 100644 index 000000000000..8d15d5dfc6b3 --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/performance @@ -0,0 +1,79 @@ +Speed +===== + +CyBlaFB is much faster than tridentfb and vesafb. Compare the performance data +for mode 1280x1024-[8,16,32]@61 Hz. + +Test 1: Cat a file with 2000 lines of 0 characters. +Test 2: Cat a file with 2000 lines of 80 characters. +Test 3: Cat a file with 2000 lines of 160 characters. + +All values show system time use in seconds, kernel 2.6.12 was used for +the measurements. 2.6.13 is a bit slower, 2.6.14 hopefully will include a +patch that speeds up kernel bitblitting a lot ( > 20%). + ++-----------+-----------------------------------------------------+ +| | not accelerated | +| TRIDENTFB +-----------------+-----------------+-----------------+ +| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp | +| | noypan | ypan | noypan | ypan | noypan | ypan | ++-----------+--------+--------+--------+--------+--------+--------+ +| Test 1 | 4.31 | 4.33 | 6.05 | 12.81 | ---- | ---- | +| Test 2 | 67.94 | 5.44 | 123.16 | 14.79 | ---- | ---- | +| Test 3 | 131.36 | 6.55 | 240.12 | 16.76 | ---- | ---- | ++-----------+--------+--------+--------+--------+--------+--------+ +| Comments | | | completely bro- | +| | | | ken, monitor | +| | | | switches off | ++-----------+-----------------+-----------------+-----------------+ + + ++-----------+-----------------------------------------------------+ +| | accelerated | +| TRIDENTFB +-----------------+-----------------+-----------------+ +| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp | +| | noypan | ypan | noypan | ypan | noypan | ypan | ++-----------+--------+--------+--------+--------+--------+--------+ +| Test 1 | ---- | ---- | 20.62 | 1.22 | ---- | ---- | +| Test 2 | ---- | ---- | 22.61 | 3.19 | ---- | ---- | +| Test 3 | ---- | ---- | 24.59 | 5.16 | ---- | ---- | ++-----------+--------+--------+--------+--------+--------+--------+ +| Comments | broken, writing | broken, ok only | completely bro- | +| | to wrong places | if bgcolor is | ken, monitor | +| | on screen + bug | black, bug in | switches off | +| | in fillrect() | fillrect() | | ++-----------+-----------------+-----------------+-----------------+ + + ++-----------+-----------------------------------------------------+ +| | not accelerated | +| VESAFB +-----------------+-----------------+-----------------+ +| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp | +| | noypan | ypan | noypan | ypan | noypan | ypan | ++-----------+--------+--------+--------+--------+--------+--------+ +| Test 1 | 4.26 | 3.76 | 5.99 | 7.23 | ---- | ---- | +| Test 2 | 65.65 | 4.89 | 120.88 | 9.08 | ---- | ---- | +| Test 3 | 126.91 | 5.94 | 235.77 | 11.03 | ---- | ---- | ++-----------+--------+--------+--------+--------+--------+--------+ +| Comments | vga=0x307 | vga=0x31a | vga=0x31b not | +| | fh=80kHz | fh=80kHz | supported by | +| | fv=75kHz | fv=75kHz | video BIOS and | +| | | | hardware | ++-----------+-----------------+-----------------+-----------------+ + + ++-----------+-----------------------------------------------------+ +| | accelerated | +| CYBLAFB +-----------------+-----------------+-----------------+ +| | 8 bpp | 16 bpp | 32 bpp | +| | noypan | ypan | noypan | ypan | noypan | ypan | ++-----------+--------+--------+--------+--------+--------+--------+ +| Test 1 | 8.02 | 0.23 | 19.04 | 0.61 | 57.12 | 2.74 | +| Test 2 | 8.38 | 0.55 | 19.39 | 0.92 | 57.54 | 3.13 | +| Test 3 | 8.73 | 0.86 | 19.74 | 1.24 | 57.95 | 3.51 | ++-----------+--------+--------+--------+--------+--------+--------+ +| Comments | | | | +| | | | | +| | | | | +| | | | | ++-----------+-----------------+-----------------+-----------------+ diff --git a/trunk/Documentation/fb/cyblafb/todo b/trunk/Documentation/fb/cyblafb/todo new file mode 100644 index 000000000000..c5f6d0eae545 --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/todo @@ -0,0 +1,31 @@ +TODO / Missing features +======================= + +Verify LCD stuff "stretch" and "center" options are + completely untested ... this code needs to be + verified. As I don't have access to such + hardware, please contact me if you are + willing run some tests. + +Interlaced video modes The reason that interleaved + modes are disabled is that I do not know + the meaning of the vertical interlace + parameter. Also the datasheet mentions a + bit d8 of a horizontal interlace parameter, + but nowhere the lower 8 bits. Please help + if you can. + +low-res double scan modes Who needs it? + +accelerated color blitting Who needs it? The console driver does use color + blitting for nothing but drawing the penguine, + everything else is done using color expanding + blitting of 1bpp character bitmaps. + +ioctls Who needs it? + +TV-out Will be done later. Use "vga= " at boot time + to set a suitable video mode. + +??? Feel free to contact me if you have any + feature requests diff --git a/trunk/Documentation/fb/cyblafb/usage b/trunk/Documentation/fb/cyblafb/usage new file mode 100644 index 000000000000..a39bb3d402a2 --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/usage @@ -0,0 +1,217 @@ +CyBlaFB is a framebuffer driver for the Cyberblade/i1 graphics core integrated +into the VIA Apollo PLE133 (aka vt8601) south bridge. It is developed and +tested using a VIA EPIA 5000 board. + +Cyblafb - compiled into the kernel or as a module? +================================================== + +You might compile cyblafb either as a module or compile it permanently into the +kernel. + +Unless you have a real reason to do so you should not compile both vesafb and +cyblafb permanently into the kernel. It's possible and it helps during the +developement cycle, but it's useless and will at least block some otherwise +usefull memory for ordinary users. + +Selecting Modes +=============== + + Startup Mode + ============ + + First of all, you might use the "vga=???" boot parameter as it is + documented in vesafb.txt and svga.txt. Cyblafb will detect the video + mode selected and will use the geometry and timings found by + inspecting the hardware registers. + + video=cyblafb vga=0x317 + + Alternatively you might use a combination of the mode, ref and bpp + parameters. If you compiled the driver into the kernel, add something + like this to the kernel command line: + + video=cyblafb:1280x1024,bpp=16,ref=50 ... + + If you compiled the driver as a module, the same mode would be + selected by the following command: + + modprobe cyblafb mode=1280x1024 bpp=16 ref=50 ... + + None of the modes possible to select as startup modes are affected by + the problems described at the end of the next subsection. + + For all startup modes cyblafb chooses a virtual x resolution of 2048, + the only exception is mode 1280x1024 in combination with 32 bpp. This + allows ywrap scrolling for all those modes if rotation is 0 or 2, and + also fast scrolling if rotation is 1 or 3. The default virtual y reso- + lution is 4096 for bpp == 8, 2048 for bpp==16 and 1024 for bpp == 32, + again with the only exception of 1280x1024 at 32 bpp. + + Please do set your video memory size to 8 Mb in the Bios setup. Other + values will work, but performace is decreased for a lot of modes. + + Mode changes using fbset + ======================== + + You might use fbset to change the video mode, see "man fbset". Cyblafb + generally does assume that you know what you are doing. But it does + some checks, especially those that are needed to prevent you from + damaging your hardware. + + - only 8, 16, 24 and 32 bpp video modes are accepted + - interlaced video modes are not accepted + - double scan video modes are not accepted + - if a flat panel is found, cyblafb does not allow you + to program a resolution higher than the physical + resolution of the flat panel monitor + - cyblafb does not allow vclk to exceed 230 MHz. As 32 bpp + and (currently) 24 bit modes use a doubled vclk internally, + the dotclock limit as seen by fbset is 115 MHz for those + modes and 230 MHz for 8 and 16 bpp modes. + - cyblafb will allow you to select very high resolutions as + long as the hardware can be programmed to these modes. The + documented limit 1600x1200 is not enforced, but don't expect + perfect signal quality. + + Any request that violates the rules given above will be either changed + to something the hardware supports or an error value will be returned. + + If you program a virtual y resolution higher than the hardware limit, + cyblafb will silently decrease that value to the highest possible + value. The same is true for a virtual x resolution that is not + supported by the hardware. Cyblafb tries to adapt vyres first because + vxres decides if ywrap scrolling is possible or not. + + Attempts to disable acceleration are ignored, I believe that this is + safe. + + Some video modes that should work do not work as expected. If you use + the standard fb.modes, fbset 640x480-60 will program that mode, but + you will see a vertical area, about two characters wide, with only + much darker characters than the other characters on the screen. + Cyblafb does allow that mode to be set, as it does not violate the + official specifications. It would need a lot of code to reliably sort + out all invalid modes, playing around with the margin values will + give a valid mode quickly. And if cyblafb would detect such an invalid + mode, should it silently alter the requested values or should it + report an error? Both options have some pros and cons. As stated + above, none of the startup modes are affected, and if you set + verbosity to 1 or higher, cyblafb will print the fbset command that + would be needed to program that mode using fbset. + + +Other Parameters +================ + + +crt don't autodetect, assume monitor connected to + standard VGA connector + +fp don't autodetect, assume flat panel display + connected to flat panel monitor interface + +nativex inform driver about native x resolution of + flat panel monitor connected to special + interface (should be autodetected) + +stretch stretch image to adapt low resolution modes to + higer resolutions of flat panel monitors + connected to special interface + +center center image to adapt low resolution modes to + higer resolutions of flat panel monitors + connected to special interface + +memsize use if autodetected memsize is wrong ... + should never be necessary + +nopcirr disable PCI read retry +nopciwr disable PCI write retry +nopcirb disable PCI read bursts +nopciwb disable PCI write bursts + +bpp bpp for specified modes + valid values: 8 || 16 || 24 || 32 + +ref refresh rate for specified mode + valid values: 50 <= ref <= 85 + +mode 640x480 or 800x600 or 1024x768 or 1280x1024 + if not specified, the startup mode will be detected + and used, so you might also use the vga=??? parameter + described in vesafb.txt. If you do not specify a mode, + bpp and ref parameters are ignored. + +verbosity 0 is the default, increase to at least 2 for every + bug report! + +Development hints +================= + +It's much faster do compile a module and to load the new version after +unloading the old module than to compile a new kernel and to reboot. So if you +try to work on cyblafb, it might be a good idea to use cyblafb as a module. +In real life, fast often means dangerous, and that's also the case here. If +you introduce a serious bug when cyblafb is compiled into the kernel, the +kernel will lock or oops with a high probability before the file system is +mounted, and the danger for your data is low. If you load a broken own version +of cyblafb on a running system, the danger for the integrity of the file +system is much higher as you might need a hard reset afterwards. Decide +yourself. + +Module unloading, the vfb method +================================ + +If you want to unload/reload cyblafb using the virtual framebuffer, you need +to enable vfb support in the kernel first. After that, load the modules as +shown below: + + modprobe vfb vfb_enable=1 + modprobe fbcon + modprobe cyblafb + fbset -fb /dev/fb1 1280x1024-60 -vyres 2662 + con2fb /dev/fb1 /dev/tty1 + ... + +If you now made some changes to cyblafb and want to reload it, you might do it +as show below: + + con2fb /dev/fb0 /dev/tty1 + ... + rmmod cyblafb + modprobe cyblafb + con2fb /dev/fb1 /dev/tty1 + ... + +Of course, you might choose another mode, and most certainly you also want to +map some other /dev/tty* to the real framebuffer device. You might also choose +to compile fbcon as a kernel module or place it permanently in the kernel. + +I do not know of any way to unload fbcon, and fbcon will prevent the +framebuffer device loaded first from unloading. [If there is a way, then +please add a description here!] + +Module unloading, the vesafb method +=================================== + +Configure the kernel: + + <*> Support for frame buffer devices + [*] VESA VGA graphics support + Cyberblade/i1 support + +Add e.g. "video=vesafb:ypan vga=0x307" to the kernel parameters. The ypan +parameter is important, choose any vga parameter you like as long as it is +a graphics mode. + +After booting, load cyblafb without any mode and bpp parameter and assign +cyblafb to individual ttys using con2fb, e.g.: + + modprobe cyblafb + con2fb /dev/fb1 /dev/tty1 + +Unloading cyblafb works without problems after you assign vesafb to all +ttys again, e.g.: + + con2fb /dev/fb0 /dev/tty1 + rmmod cyblafb diff --git a/trunk/Documentation/fb/cyblafb/whatsnew b/trunk/Documentation/fb/cyblafb/whatsnew new file mode 100644 index 000000000000..76c07a26e044 --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/whatsnew @@ -0,0 +1,29 @@ +0.62 +==== + + - the vesafb parameter has been removed as I decided to allow the + feature without any special parameter. + + - Cyblafb does not use the vga style of panning any longer, now the + "right view" register in the graphics engine IO space is used. Without + that change it was impossible to use all available memory, and without + access to all available memory it is impossible to ywrap. + + - The imageblit function now uses hardware acceleration for all font + widths. Hardware blitting across pixel column 2048 is broken in the + cyberblade/i1 graphics core, but we work around that hardware bug. + + - modes with vxres != xres are supported now. + + - ywrap scrolling is supported now and the default. This is a big + performance gain. + + - default video modes use vyres > yres and vxres > xres to allow + almost optimal scrolling speed for normal and rotated screens + + - some features mainly usefull for debugging the upper layers of the + framebuffer system have been added, have a look at the code + + - fixed: Oops after unloading cyblafb when reading /proc/io* + + - we work around some bugs of the higher framebuffer layers. diff --git a/trunk/Documentation/fb/cyblafb/whycyblafb b/trunk/Documentation/fb/cyblafb/whycyblafb new file mode 100644 index 000000000000..a123bc11e698 --- /dev/null +++ b/trunk/Documentation/fb/cyblafb/whycyblafb @@ -0,0 +1,85 @@ +I tried the following framebuffer drivers: + + - TRIDENTFB is full of bugs. Acceleration is broken for Blade3D + graphics cores like the cyberblade/i1. It claims to support a great + number of devices, but documentation for most of these devices is + unfortunately not available. There is _no_ reason to use tridentfb + for cyberblade/i1 + CRT users. VESAFB is faster, and the one + advantage, mode switching, is broken in tridentfb. + + - VESAFB is used by many distributions as a standard. Vesafb does + not support mode switching. VESAFB is a bit faster than the working + configurations of TRIDENTFB, but it is still too slow, even if you + use ypan. + + - EPIAFB (you'll find it on sourceforge) supports the Cyberblade/i1 + graphics core, but it still has serious bugs and developement seems + to have stopped. This is the one driver with TV-out support. If you + do need this feature, try epiafb. + +None of these drivers was a real option for me. + +I believe that is unreasonable to change code that announces to support 20 +devices if I only have more or less sufficient documentation for exactly one +of these. The risk of breaking device foo while fixing device bar is too high. + +So I decided to start CyBlaFB as a stripped down tridentfb. + +All code specific to other Trident chips has been removed. After that there +were a lot of cosmetic changes to increase the readability of the code. All +register names were changed to those mnemonics used in the datasheet. Function +and macro names were changed if they hindered easy understanding of the code. + +After that I debugged the code and implemented some new features. I'll try to +give a little summary of the main changes: + + - calculation of vertical and horizontal timings was fixed + + - video signal quality has been improved dramatically + + - acceleration: + + - fillrect and copyarea were fixed and reenabled + + - color expanding imageblit was newly implemented, color + imageblit (only used to draw the penguine) still uses the + generic code. + + - init of the acceleration engine was improved and moved to a + place where it really works ... + + - sync function has a timeout now and tries to reset and + reinit the accel engine if necessary + + - fewer slow copyarea calls when doing ypan scrolling by using + undocumented bit d21 of screen start address stored in + CR2B[5]. BIOS does use it also, so this should be safe. + + - cyblafb rejects any attempt to set modes that would cause vclk + values above reasonable 230 MHz. 32bit modes use a clock + multiplicator of 2, so fbset does show the correct values for + pixclock but not for vclk in this case. The fbset limit is 115 MHz + for 32 bpp modes. + + - cyblafb rejects modes known to be broken or unimplemented (all + interlaced modes, all doublescan modes for now) + + - cyblafb now works independant of the video mode in effect at startup + time (tridentfb does not init all needed registers to reasonable + values) + + - switching between video modes does work reliably now + + - the first video mode now is the one selected on startup using the + vga=???? mechanism or any of + - 640x480, 800x600, 1024x768, 1280x1024 + - 8, 16, 24 or 32 bpp + - refresh between 50 Hz and 85 Hz, 1 Hz steps (1280x1024-32 + is limited to 63Hz) + + - pci retry and pci burst mode are settable (try to disable if you + experience latency problems) + + - built as a module cyblafb might be unloaded and reloaded using + the vfb module and con2vt or might be used together with vesafb + diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index a23361e80c64..7907586c6e08 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -64,10 +64,10 @@ Who: Pavel Machek --------------------------- -What: Video4Linux API 1 ioctls and from Video devices. -When: July 2009 -Files: include/linux/videodev.h -Check: include/linux/videodev.h +What: Video4Linux API 1 ioctls and video_decoder.h from Video devices. +When: December 2008 +Files: include/linux/video_decoder.h include/linux/videodev.h +Check: include/linux/video_decoder.h include/linux/videodev.h Why: V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6 series. The old API have lots of drawbacks and don't provide enough means to work with all video and audio standards. The newer API is @@ -255,16 +255,6 @@ Who: Jan Engelhardt --------------------------- -What: GPIO autorequest on gpio_direction_{input,output}() in gpiolib -When: February 2010 -Why: All callers should use explicit gpio_request()/gpio_free(). - The autorequest mechanism in gpiolib was provided mostly as a - migration aid for legacy GPIO interfaces (for SOC based GPIOs). - Those users have now largely migrated. Platforms implementing - the GPIO interfaces without using gpiolib will see no changes. -Who: David Brownell ---------------------------- - What: b43 support for firmware revision < 410 When: The schedule was July 2008, but it was decided that we are going to keep the code as long as there are no major maintanance headaches. @@ -321,18 +311,6 @@ Who: Vlad Yasevich --------------------------- -What: Ability for non root users to shm_get hugetlb pages based on mlock - resource limits -When: 2.6.31 -Why: Non root users need to be part of /proc/sys/vm/hugetlb_shm_group or - have CAP_IPC_LOCK to be able to allocate shm segments backed by - huge pages. The mlock based rlimit check to allow shm hugetlb is - inconsistent with mmap based allocations. Hence it is being - deprecated. -Who: Ravikiran Thirumalai - ---------------------------- - What: CONFIG_THERMAL_HWMON When: January 2009 Why: This option was introduced just to allow older lm-sensors userspace @@ -378,6 +356,17 @@ Who: Hans de Goede --------------------------- +What: SELinux "compat_net" functionality +When: 2.6.30 at the earliest +Why: In 2.6.18 the Secmark concept was introduced to replace the "compat_net" + network access control functionality of SELinux. Secmark offers both + better performance and greater flexibility than the "compat_net" + mechanism. Now that the major Linux distributions have moved to + Secmark, it is time to deprecate the older mechanism and start the + process of removing the old code. +Who: Paul Moore +--------------------------- + What: sysfs ui for changing p4-clockmod parameters When: September 2009 Why: See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and @@ -402,35 +391,3 @@ Why: The defines and typedefs (hw_interrupt_type, no_irq_type, irq_desc_t) have been kept around for migration reasons. After more than two years it's time to remove them finally Who: Thomas Gleixner - ---------------------------- - -What: fakephp and associated sysfs files in /sys/bus/pci/slots/ -When: 2011 -Why: In 2.6.27, the semantics of /sys/bus/pci/slots was redefined to - represent a machine's physical PCI slots. The change in semantics - had userspace implications, as the hotplug core no longer allowed - drivers to create multiple sysfs files per physical slot (required - for multi-function devices, e.g.). fakephp was seen as a developer's - tool only, and its interface changed. Too late, we learned that - there were some users of the fakephp interface. - - In 2.6.30, the original fakephp interface was restored. At the same - time, the PCI core gained the ability that fakephp provided, namely - function-level hot-remove and hot-add. - - Since the PCI core now provides the same functionality, exposed in: - - /sys/bus/pci/rescan - /sys/bus/pci/devices/.../remove - /sys/bus/pci/devices/.../rescan - - there is no functional reason to maintain fakephp as well. - - We will keep the existing module so that 'modprobe fakephp' will - present the old /sys/bus/pci/slots/... interface for compatibility, - but users are urged to migrate their applications to the API above. - - After a reasonable transition period, we will remove the legacy - fakephp interface. -Who: Alex Chiang diff --git a/trunk/Documentation/filesystems/Locking b/trunk/Documentation/filesystems/Locking index 76efe5b71d7d..4e78ce677843 100644 --- a/trunk/Documentation/filesystems/Locking +++ b/trunk/Documentation/filesystems/Locking @@ -505,7 +505,7 @@ prototypes: void (*open)(struct vm_area_struct*); void (*close)(struct vm_area_struct*); int (*fault)(struct vm_area_struct*, struct vm_fault *); - int (*page_mkwrite)(struct vm_area_struct *, struct vm_fault *); + int (*page_mkwrite)(struct vm_area_struct *, struct page *); int (*access)(struct vm_area_struct *, unsigned long, void*, int, int); locking rules: diff --git a/trunk/Documentation/filesystems/ext4.txt b/trunk/Documentation/filesystems/ext4.txt index 97882df04865..cec829bc7291 100644 --- a/trunk/Documentation/filesystems/ext4.txt +++ b/trunk/Documentation/filesystems/ext4.txt @@ -85,7 +85,7 @@ Note: More extensive information for getting started with ext4 can be * extent format more robust in face of on-disk corruption due to magics, * internal redundancy in tree * improved file allocation (multi-block alloc) -* lift 32000 subdirectory limit imposed by i_links_count[1] +* fix 32000 subdirectory limit * nsec timestamps for mtime, atime, ctime, create time * inode version field on disk (NFSv4, Lustre) * reduced e2fsck time via uninit_bg feature @@ -100,9 +100,6 @@ Note: More extensive information for getting started with ext4 can be * efficent new ordered mode in JBD2 and ext4(avoid using buffer head to force the ordering) -[1] Filesystems with a block size of 1k may see a limit imposed by the -directory hash tree having a maximum depth of two. - 2.2 Candidate features for future inclusion * Online defrag (patches available but not well tested) @@ -183,8 +180,8 @@ commit=nrsec (*) Ext4 can be told to sync all its data and metadata performance. barrier=<0|1(*)> This enables/disables the use of write barriers in -barrier(*) the jbd code. barrier=0 disables, barrier=1 enables. -nobarrier This also requires an IO stack which can support + the jbd code. barrier=0 disables, barrier=1 enables. + This also requires an IO stack which can support barriers, and if jbd gets an error on a barrier write, it will disable again with a warning. Write barriers enforce proper on-disk ordering @@ -192,9 +189,6 @@ nobarrier This also requires an IO stack which can support safe to use, at some performance penalty. If your disks are battery-backed in one way or another, disabling barriers may safely improve performance. - The mount options "barrier" and "nobarrier" can - also be used to enable or disable barriers, for - consistency with other ext4 mount options. inode_readahead=n This tuning parameter controls the maximum number of inode table blocks that ext4's inode @@ -316,24 +310,6 @@ journal_ioprio=prio The I/O priority (from 0 to 7, where 0 is the a slightly higher priority than the default I/O priority. -auto_da_alloc(*) Many broken applications don't use fsync() when -noauto_da_alloc replacing existing files via patterns such as - fd = open("foo.new")/write(fd,..)/close(fd)/ - rename("foo.new", "foo"), or worse yet, - fd = open("foo", O_TRUNC)/write(fd,..)/close(fd). - If auto_da_alloc is enabled, ext4 will detect - the replace-via-rename and replace-via-truncate - patterns and force that any delayed allocation - blocks are allocated such that at the next - journal commit, in the default data=ordered - mode, the data blocks of the new file are forced - to disk before the rename() operation is - commited. This provides roughly the same level - of guarantees as ext3, and avoids the - "zero-length" problem that can happen when a - system crashes before the delayed allocation - blocks are forced to disk. - Data Mode ========= There are 3 different data modes: diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt index ce84cfc9eae0..830bad7cce0f 100644 --- a/trunk/Documentation/filesystems/proc.txt +++ b/trunk/Documentation/filesystems/proc.txt @@ -5,7 +5,6 @@ Bodo Bauer 2.4.x update Jorge Nerin November 14 2000 -move /proc/sys Shen Feng April 1 2009 ------------------------------------------------------------------------------ Version 1.3 Kernel version 2.2.12 Kernel version 2.4.0-test11-pre4 @@ -27,17 +26,25 @@ Table of Contents 1.6 Parallel port info in /proc/parport 1.7 TTY info in /proc/tty 1.8 Miscellaneous kernel statistics in /proc/stat - 1.9 Ext4 file system parameters 2 Modifying System Parameters - - 3 Per-Process Parameters - 3.1 /proc//oom_adj - Adjust the oom-killer score - 3.2 /proc//oom_score - Display current oom-killer score - 3.3 /proc//io - Display the IO accounting fields - 3.4 /proc//coredump_filter - Core dump filtering settings - 3.5 /proc//mountinfo - Information about mounts - + 2.1 /proc/sys/fs - File system data + 2.2 /proc/sys/fs/binfmt_misc - Miscellaneous binary formats + 2.3 /proc/sys/kernel - general kernel parameters + 2.4 /proc/sys/vm - The virtual memory subsystem + 2.5 /proc/sys/dev - Device specific parameters + 2.6 /proc/sys/sunrpc - Remote procedure calls + 2.7 /proc/sys/net - Networking stuff + 2.8 /proc/sys/net/ipv4 - IPV4 settings + 2.9 Appletalk + 2.10 IPX + 2.11 /proc/sys/fs/mqueue - POSIX message queues filesystem + 2.12 /proc//oom_adj - Adjust the oom-killer score + 2.13 /proc//oom_score - Display current oom-killer score + 2.14 /proc//io - Display the IO accounting fields + 2.15 /proc//coredump_filter - Core dump filtering settings + 2.16 /proc//mountinfo - Information about mounts + 2.17 /proc/sys/fs/epoll - Configuration options for the epoll interface ------------------------------------------------------------------------------ Preface @@ -933,6 +940,27 @@ Table 1-10: Files in /proc/fs/ext4/ File Content mb_groups details of multiblock allocator buddy cache of free blocks mb_history multiblock allocation history + stats controls whether the multiblock allocator should start + collecting statistics, which are shown during the unmount + group_prealloc the multiblock allocator will round up allocation + requests to a multiple of this tuning parameter if the + stripe size is not set in the ext4 superblock + max_to_scan The maximum number of extents the multiblock allocator + will search to find the best extent + min_to_scan The minimum number of extents the multiblock allocator + will search to find the best extent + order2_req Tuning parameter which controls the minimum size for + requests (as a power of 2) where the buddy cache is + used + stream_req Files which have fewer blocks than this tunable + parameter will have their blocks allocated out of a + block group specific preallocation pool, so that small + files are packed closely together. Each large file + will have its blocks allocated out of its own unique + preallocation pool. +inode_readahead Tuning parameter which controls the maximum number of + inode table blocks that ext4's inode table readahead + algorithm will pre-read into the buffer cache .............................................................................. @@ -983,24 +1011,1021 @@ review the kernel documentation in the directory /usr/src/linux/Documentation. This chapter is heavily based on the documentation included in the pre 2.2 kernels, and became part of it in version 2.2.1 of the Linux kernel. -Please see: Documentation/sysctls/ directory for descriptions of these +2.1 /proc/sys/fs - File system data +----------------------------------- + +This subdirectory contains specific file system, file handle, inode, dentry +and quota information. + +Currently, these files are in /proc/sys/fs: + +dentry-state +------------ + +Status of the directory cache. Since directory entries are dynamically +allocated and deallocated, this file indicates the current status. It holds +six values, in which the last two are not used and are always zero. The others +are listed in table 2-1. + + +Table 2-1: Status files of the directory cache +.............................................................................. + File Content + nr_dentry Almost always zero + nr_unused Number of unused cache entries + age_limit + in seconds after the entry may be reclaimed, when memory is short + want_pages internally +.............................................................................. + +dquot-nr and dquot-max +---------------------- + +The file dquot-max shows the maximum number of cached disk quota entries. + +The file dquot-nr shows the number of allocated disk quota entries and the +number of free disk quota entries. + +If the number of available cached disk quotas is very low and you have a large +number of simultaneous system users, you might want to raise the limit. + +file-nr and file-max +-------------------- + +The kernel allocates file handles dynamically, but doesn't free them again at +this time. + +The value in file-max denotes the maximum number of file handles that the +Linux kernel will allocate. When you get a lot of error messages about running +out of file handles, you might want to raise this limit. The default value is +10% of RAM in kilobytes. To change it, just write the new number into the +file: + + # cat /proc/sys/fs/file-max + 4096 + # echo 8192 > /proc/sys/fs/file-max + # cat /proc/sys/fs/file-max + 8192 + + +This method of revision is useful for all customizable parameters of the +kernel - simply echo the new value to the corresponding file. + +Historically, the three values in file-nr denoted the number of allocated file +handles, the number of allocated but unused file handles, and the maximum +number of file handles. Linux 2.6 always reports 0 as the number of free file +handles -- this is not an error, it just means that the number of allocated +file handles exactly matches the number of used file handles. + +Attempts to allocate more file descriptors than file-max are reported with +printk, look for "VFS: file-max limit reached". + +inode-state and inode-nr +------------------------ + +The file inode-nr contains the first two items from inode-state, so we'll skip +to that file... + +inode-state contains two actual numbers and five dummy values. The numbers +are nr_inodes and nr_free_inodes (in order of appearance). + +nr_inodes +~~~~~~~~~ + +Denotes the number of inodes the system has allocated. This number will +grow and shrink dynamically. + +nr_open +------- + +Denotes the maximum number of file-handles a process can +allocate. Default value is 1024*1024 (1048576) which should be +enough for most machines. Actual limit depends on RLIMIT_NOFILE +resource limit. + +nr_free_inodes +-------------- + +Represents the number of free inodes. Ie. The number of inuse inodes is +(nr_inodes - nr_free_inodes). + +aio-nr and aio-max-nr +--------------------- + +aio-nr is the running total of the number of events specified on the +io_setup system call for all currently active aio contexts. If aio-nr +reaches aio-max-nr then io_setup will fail with EAGAIN. Note that +raising aio-max-nr does not result in the pre-allocation or re-sizing +of any kernel data structures. + +2.2 /proc/sys/fs/binfmt_misc - Miscellaneous binary formats +----------------------------------------------------------- + +Besides these files, there is the subdirectory /proc/sys/fs/binfmt_misc. This +handles the kernel support for miscellaneous binary formats. + +Binfmt_misc provides the ability to register additional binary formats to the +Kernel without compiling an additional module/kernel. Therefore, binfmt_misc +needs to know magic numbers at the beginning or the filename extension of the +binary. + +It works by maintaining a linked list of structs that contain a description of +a binary format, including a magic with size (or the filename extension), +offset and mask, and the interpreter name. On request it invokes the given +interpreter with the original program as argument, as binfmt_java and +binfmt_em86 and binfmt_mz do. Since binfmt_misc does not define any default +binary-formats, you have to register an additional binary-format. + +There are two general files in binfmt_misc and one file per registered format. +The two general files are register and status. + +Registering a new binary format +------------------------------- + +To register a new binary format you have to issue the command + + echo :name:type:offset:magic:mask:interpreter: > /proc/sys/fs/binfmt_misc/register + + + +with appropriate name (the name for the /proc-dir entry), offset (defaults to +0, if omitted), magic, mask (which can be omitted, defaults to all 0xff) and +last but not least, the interpreter that is to be invoked (for example and +testing /bin/echo). Type can be M for usual magic matching or E for filename +extension matching (give extension in place of magic). + +Check or reset the status of the binary format handler +------------------------------------------------------ + +If you do a cat on the file /proc/sys/fs/binfmt_misc/status, you will get the +current status (enabled/disabled) of binfmt_misc. Change the status by echoing +0 (disables) or 1 (enables) or -1 (caution: this clears all previously +registered binary formats) to status. For example echo 0 > status to disable +binfmt_misc (temporarily). + +Status of a single handler +-------------------------- + +Each registered handler has an entry in /proc/sys/fs/binfmt_misc. These files +perform the same function as status, but their scope is limited to the actual +binary format. By cating this file, you also receive all related information +about the interpreter/magic of the binfmt. + +Example usage of binfmt_misc (emulate binfmt_java) +-------------------------------------------------- + + cd /proc/sys/fs/binfmt_misc + echo ':Java:M::\xca\xfe\xba\xbe::/usr/local/java/bin/javawrapper:' > register + echo ':HTML:E::html::/usr/local/java/bin/appletviewer:' > register + echo ':Applet:M:: [USB debug key] <-------> [client/console] - -1. There are three specific hardware requirements: - - a.) Host/target system needs to have USB debug port capability. - - You can check this capability by looking at a 'Debug port' bit in - the lspci -vvv output: - - # lspci -vvv - ... - 00:1d.7 USB Controller: Intel Corporation 82801H (ICH8 Family) USB2 EHCI Controller #1 (rev 03) (prog-if 20 [EHCI]) - Subsystem: Lenovo ThinkPad T61 - Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx- - Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- SERR- /proc/sysrq-trigger - - On the host/target system you should see this help line in "dmesg" output: - - SysRq : HELP : loglevel(0-9) reBoot Crashdump terminate-all-tasks(E) memory-full-oom-kill(F) kill-all-tasks(I) saK show-backtrace-all-active-cpus(L) show-memory-usage(M) nice-all-RT-tasks(N) powerOff show-registers(P) show-all-timers(Q) unRaw Sync show-task-states(T) Unmount show-blocked-tasks(W) dump-ftrace-buffer(Z) - - On the client/console system do: - - cat /dev/ttyUSB0 - - And you should see the help line above displayed shortly after you've - provoked it on the host system. - -If it does not work then please ask about it on the linux-kernel@vger.kernel.org -mailing list or contact the x86 maintainers. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index b5e278f9fb23..01243ce6d998 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -357,7 +357,6 @@ S: Odd Fixes for 2.4; Maintained for 2.6. P: Ivan Kokshaysky M: ink@jurassic.park.msu.ru S: Maintained for 2.4; PCI support for 2.6. -L: linux-alpha@vger.kernel.org AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER P: Thomas Dahlmann @@ -1064,6 +1063,7 @@ BTTV VIDEO4LINUX DRIVER P: Mauro Carvalho Chehab M: mchehab@infradead.org L: linux-media@vger.kernel.org +L: video4linux-list@redhat.com W: http://linuxtv.org T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git S: Maintained @@ -1945,12 +1945,6 @@ L: lm-sensors@lm-sensors.org W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/ S: Maintained -HYPERVISOR VIRTUAL CONSOLE DRIVER -L: linuxppc-dev@ozlabs.org -L: linux-kernel@vger.kernel.org -S: Odd Fixes -F: drivers/char/hvc_* - GSPCA FINEPIX SUBDRIVER P: Frank Zago M: frank@zago.net @@ -2208,12 +2202,25 @@ L: linux-ide@vger.kernel.org T: quilt kernel.org/pub/linux/kernel/people/bart/pata-2.6/ S: Maintained -IDE/ATAPI DRIVERS +IDE/ATAPI CDROM DRIVER P: Borislav Petkov M: petkovbb@gmail.com L: linux-ide@vger.kernel.org S: Maintained +IDE/ATAPI FLOPPY DRIVERS +P: Paul Bristow +M: Paul Bristow +W: http://paulbristow.net/linux/idefloppy.html +L: linux-kernel@vger.kernel.org +S: Maintained + +IDE/ATAPI TAPE DRIVERS +P: Gadi Oxman +M: Gadi Oxman +L: linux-kernel@vger.kernel.org +S: Maintained + IDLE-I7300 P: Andy Henroid M: andrew.d.henroid@intel.com @@ -4828,6 +4835,7 @@ VIDEO FOR LINUX (V4L) P: Mauro Carvalho Chehab M: mchehab@infradead.org L: linux-media@vger.kernel.org +L: video4linux-list@redhat.com W: http://linuxtv.org T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git S: Maintained diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig index 830c16a2b801..550dab22daa1 100644 --- a/trunk/arch/Kconfig +++ b/trunk/arch/Kconfig @@ -106,5 +106,3 @@ config HAVE_CLK The calls support software clock gating and thus are a key power management tool on many systems. -config HAVE_DMA_API_DEBUG - bool diff --git a/trunk/arch/alpha/include/asm/machvec.h b/trunk/arch/alpha/include/asm/machvec.h index 13cd42743810..fea4ea75b79d 100644 --- a/trunk/arch/alpha/include/asm/machvec.h +++ b/trunk/arch/alpha/include/asm/machvec.h @@ -80,7 +80,7 @@ struct alpha_machine_vector void (*update_irq_hw)(unsigned long, unsigned long, int); void (*ack_irq)(unsigned long); void (*device_interrupt)(unsigned long vector); - void (*machine_check)(unsigned long vector, unsigned long la); + void (*machine_check)(u64 vector, u64 la); void (*smp_callin)(void); void (*init_arch)(void); diff --git a/trunk/arch/alpha/include/asm/pci.h b/trunk/arch/alpha/include/asm/pci.h index cb04eaa6ba33..2a14302c17a3 100644 --- a/trunk/arch/alpha/include/asm/pci.h +++ b/trunk/arch/alpha/include/asm/pci.h @@ -273,18 +273,4 @@ struct pci_dev *alpha_gendev_to_pci(struct device *dev); extern struct pci_dev *isa_bridge; -extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, - size_t count); -extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, - size_t count); -extern int pci_mmap_legacy_page_range(struct pci_bus *bus, - struct vm_area_struct *vma, - enum pci_mmap_state mmap_state); -extern void pci_adjust_legacy_attr(struct pci_bus *bus, - enum pci_mmap_state mmap_type); -#define HAVE_PCI_LEGACY 1 - -extern int pci_create_resource_files(struct pci_dev *dev); -extern void pci_remove_resource_files(struct pci_dev *dev); - #endif /* __ALPHA_PCI_H */ diff --git a/trunk/arch/alpha/include/asm/spinlock.h b/trunk/arch/alpha/include/asm/spinlock.h index e38fb95cb335..aeeb125f6851 100644 --- a/trunk/arch/alpha/include/asm/spinlock.h +++ b/trunk/arch/alpha/include/asm/spinlock.h @@ -166,9 +166,6 @@ static inline void __raw_write_unlock(raw_rwlock_t * lock) lock->lock = 0; } -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) - #define _raw_spin_relax(lock) cpu_relax() #define _raw_read_relax(lock) cpu_relax() #define _raw_write_relax(lock) cpu_relax() diff --git a/trunk/arch/alpha/include/asm/system.h b/trunk/arch/alpha/include/asm/system.h index 5aa40cca4f23..afe20fa58c99 100644 --- a/trunk/arch/alpha/include/asm/system.h +++ b/trunk/arch/alpha/include/asm/system.h @@ -309,72 +309,519 @@ extern int __min_ipl; #define tbia() __tbi(-2, /* no second argument */) /* - * Atomic exchange routines. + * Atomic exchange. + * Since it can be used to implement critical sections + * it must clobber "memory" (also for interrupts in UP). */ -#define __ASM__MB -#define ____xchg(type, args...) __xchg ## type ## _local(args) -#define ____cmpxchg(type, args...) __cmpxchg ## type ## _local(args) -#include +static inline unsigned long +__xchg_u8(volatile char *m, unsigned long val) +{ + unsigned long ret, tmp, addr64; + + __asm__ __volatile__( + " andnot %4,7,%3\n" + " insbl %1,%4,%1\n" + "1: ldq_l %2,0(%3)\n" + " extbl %2,%4,%0\n" + " mskbl %2,%4,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%3)\n" + " beq %2,2f\n" +#ifdef CONFIG_SMP + " mb\n" +#endif + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64) + : "r" ((long)m), "1" (val) : "memory"); -#define xchg_local(ptr,x) \ - ({ \ - __typeof__(*(ptr)) _x_ = (x); \ - (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \ - sizeof(*(ptr))); \ - }) + return ret; +} -#define cmpxchg_local(ptr, o, n) \ - ({ \ - __typeof__(*(ptr)) _o_ = (o); \ - __typeof__(*(ptr)) _n_ = (n); \ - (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \ - (unsigned long)_n_, \ - sizeof(*(ptr))); \ - }) +static inline unsigned long +__xchg_u16(volatile short *m, unsigned long val) +{ + unsigned long ret, tmp, addr64; + + __asm__ __volatile__( + " andnot %4,7,%3\n" + " inswl %1,%4,%1\n" + "1: ldq_l %2,0(%3)\n" + " extwl %2,%4,%0\n" + " mskwl %2,%4,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%3)\n" + " beq %2,2f\n" +#ifdef CONFIG_SMP + " mb\n" +#endif + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64) + : "r" ((long)m), "1" (val) : "memory"); -#define cmpxchg64_local(ptr, o, n) \ - ({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ - cmpxchg_local((ptr), (o), (n)); \ - }) + return ret; +} +static inline unsigned long +__xchg_u32(volatile int *m, unsigned long val) +{ + unsigned long dummy; + + __asm__ __volatile__( + "1: ldl_l %0,%4\n" + " bis $31,%3,%1\n" + " stl_c %1,%2\n" + " beq %1,2f\n" #ifdef CONFIG_SMP -#undef __ASM__MB -#define __ASM__MB "\tmb\n" + " mb\n" #endif -#undef ____xchg -#undef ____cmpxchg -#define ____xchg(type, args...) __xchg ##type(args) -#define ____cmpxchg(type, args...) __cmpxchg ##type(args) -#include - -#define xchg(ptr,x) \ - ({ \ - __typeof__(*(ptr)) _x_ = (x); \ - (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \ - sizeof(*(ptr))); \ - }) + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (val), "=&r" (dummy), "=m" (*m) + : "rI" (val), "m" (*m) : "memory"); + + return val; +} + +static inline unsigned long +__xchg_u64(volatile long *m, unsigned long val) +{ + unsigned long dummy; + + __asm__ __volatile__( + "1: ldq_l %0,%4\n" + " bis $31,%3,%1\n" + " stq_c %1,%2\n" + " beq %1,2f\n" +#ifdef CONFIG_SMP + " mb\n" +#endif + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (val), "=&r" (dummy), "=m" (*m) + : "rI" (val), "m" (*m) : "memory"); -#define cmpxchg(ptr, o, n) \ - ({ \ - __typeof__(*(ptr)) _o_ = (o); \ - __typeof__(*(ptr)) _n_ = (n); \ - (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ - (unsigned long)_n_, sizeof(*(ptr)));\ + return val; +} + +/* This function doesn't exist, so you'll get a linker error + if something tries to do an invalid xchg(). */ +extern void __xchg_called_with_bad_pointer(void); + +#define __xchg(ptr, x, size) \ +({ \ + unsigned long __xchg__res; \ + volatile void *__xchg__ptr = (ptr); \ + switch (size) { \ + case 1: __xchg__res = __xchg_u8(__xchg__ptr, x); break; \ + case 2: __xchg__res = __xchg_u16(__xchg__ptr, x); break; \ + case 4: __xchg__res = __xchg_u32(__xchg__ptr, x); break; \ + case 8: __xchg__res = __xchg_u64(__xchg__ptr, x); break; \ + default: __xchg_called_with_bad_pointer(); __xchg__res = x; \ + } \ + __xchg__res; \ +}) + +#define xchg(ptr,x) \ + ({ \ + __typeof__(*(ptr)) _x_ = (x); \ + (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \ }) -#define cmpxchg64(ptr, o, n) \ - ({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ - cmpxchg((ptr), (o), (n)); \ +static inline unsigned long +__xchg_u8_local(volatile char *m, unsigned long val) +{ + unsigned long ret, tmp, addr64; + + __asm__ __volatile__( + " andnot %4,7,%3\n" + " insbl %1,%4,%1\n" + "1: ldq_l %2,0(%3)\n" + " extbl %2,%4,%0\n" + " mskbl %2,%4,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%3)\n" + " beq %2,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64) + : "r" ((long)m), "1" (val) : "memory"); + + return ret; +} + +static inline unsigned long +__xchg_u16_local(volatile short *m, unsigned long val) +{ + unsigned long ret, tmp, addr64; + + __asm__ __volatile__( + " andnot %4,7,%3\n" + " inswl %1,%4,%1\n" + "1: ldq_l %2,0(%3)\n" + " extwl %2,%4,%0\n" + " mskwl %2,%4,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%3)\n" + " beq %2,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64) + : "r" ((long)m), "1" (val) : "memory"); + + return ret; +} + +static inline unsigned long +__xchg_u32_local(volatile int *m, unsigned long val) +{ + unsigned long dummy; + + __asm__ __volatile__( + "1: ldl_l %0,%4\n" + " bis $31,%3,%1\n" + " stl_c %1,%2\n" + " beq %1,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (val), "=&r" (dummy), "=m" (*m) + : "rI" (val), "m" (*m) : "memory"); + + return val; +} + +static inline unsigned long +__xchg_u64_local(volatile long *m, unsigned long val) +{ + unsigned long dummy; + + __asm__ __volatile__( + "1: ldq_l %0,%4\n" + " bis $31,%3,%1\n" + " stq_c %1,%2\n" + " beq %1,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + : "=&r" (val), "=&r" (dummy), "=m" (*m) + : "rI" (val), "m" (*m) : "memory"); + + return val; +} + +#define __xchg_local(ptr, x, size) \ +({ \ + unsigned long __xchg__res; \ + volatile void *__xchg__ptr = (ptr); \ + switch (size) { \ + case 1: __xchg__res = __xchg_u8_local(__xchg__ptr, x); break; \ + case 2: __xchg__res = __xchg_u16_local(__xchg__ptr, x); break; \ + case 4: __xchg__res = __xchg_u32_local(__xchg__ptr, x); break; \ + case 8: __xchg__res = __xchg_u64_local(__xchg__ptr, x); break; \ + default: __xchg_called_with_bad_pointer(); __xchg__res = x; \ + } \ + __xchg__res; \ +}) + +#define xchg_local(ptr,x) \ + ({ \ + __typeof__(*(ptr)) _x_ = (x); \ + (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \ + sizeof(*(ptr))); \ }) -#undef __ASM__MB -#undef ____cmpxchg +/* + * Atomic compare and exchange. Compare OLD with MEM, if identical, + * store NEW in MEM. Return the initial value in MEM. Success is + * indicated by comparing RETURN with OLD. + * + * The memory barrier should be placed in SMP only when we actually + * make the change. If we don't change anything (so if the returned + * prev is equal to old) then we aren't acquiring anything new and + * we don't need any memory barrier as far I can tell. + */ #define __HAVE_ARCH_CMPXCHG 1 +static inline unsigned long +__cmpxchg_u8(volatile char *m, long old, long new) +{ + unsigned long prev, tmp, cmp, addr64; + + __asm__ __volatile__( + " andnot %5,7,%4\n" + " insbl %1,%5,%1\n" + "1: ldq_l %2,0(%4)\n" + " extbl %2,%5,%0\n" + " cmpeq %0,%6,%3\n" + " beq %3,2f\n" + " mskbl %2,%5,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%4)\n" + " beq %2,3f\n" +#ifdef CONFIG_SMP + " mb\n" +#endif + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64) + : "r" ((long)m), "Ir" (old), "1" (new) : "memory"); + + return prev; +} + +static inline unsigned long +__cmpxchg_u16(volatile short *m, long old, long new) +{ + unsigned long prev, tmp, cmp, addr64; + + __asm__ __volatile__( + " andnot %5,7,%4\n" + " inswl %1,%5,%1\n" + "1: ldq_l %2,0(%4)\n" + " extwl %2,%5,%0\n" + " cmpeq %0,%6,%3\n" + " beq %3,2f\n" + " mskwl %2,%5,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%4)\n" + " beq %2,3f\n" +#ifdef CONFIG_SMP + " mb\n" +#endif + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64) + : "r" ((long)m), "Ir" (old), "1" (new) : "memory"); + + return prev; +} + +static inline unsigned long +__cmpxchg_u32(volatile int *m, int old, int new) +{ + unsigned long prev, cmp; + + __asm__ __volatile__( + "1: ldl_l %0,%5\n" + " cmpeq %0,%3,%1\n" + " beq %1,2f\n" + " mov %4,%1\n" + " stl_c %1,%2\n" + " beq %1,3f\n" +#ifdef CONFIG_SMP + " mb\n" +#endif + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r"(prev), "=&r"(cmp), "=m"(*m) + : "r"((long) old), "r"(new), "m"(*m) : "memory"); + + return prev; +} + +static inline unsigned long +__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new) +{ + unsigned long prev, cmp; + + __asm__ __volatile__( + "1: ldq_l %0,%5\n" + " cmpeq %0,%3,%1\n" + " beq %1,2f\n" + " mov %4,%1\n" + " stq_c %1,%2\n" + " beq %1,3f\n" +#ifdef CONFIG_SMP + " mb\n" +#endif + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r"(prev), "=&r"(cmp), "=m"(*m) + : "r"((long) old), "r"(new), "m"(*m) : "memory"); + + return prev; +} + +/* This function doesn't exist, so you'll get a linker error + if something tries to do an invalid cmpxchg(). */ +extern void __cmpxchg_called_with_bad_pointer(void); + +static __always_inline unsigned long +__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) +{ + switch (size) { + case 1: + return __cmpxchg_u8(ptr, old, new); + case 2: + return __cmpxchg_u16(ptr, old, new); + case 4: + return __cmpxchg_u32(ptr, old, new); + case 8: + return __cmpxchg_u64(ptr, old, new); + } + __cmpxchg_called_with_bad_pointer(); + return old; +} + +#define cmpxchg(ptr, o, n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr))); \ + }) +#define cmpxchg64(ptr, o, n) \ + ({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ + cmpxchg((ptr), (o), (n)); \ + }) + +static inline unsigned long +__cmpxchg_u8_local(volatile char *m, long old, long new) +{ + unsigned long prev, tmp, cmp, addr64; + + __asm__ __volatile__( + " andnot %5,7,%4\n" + " insbl %1,%5,%1\n" + "1: ldq_l %2,0(%4)\n" + " extbl %2,%5,%0\n" + " cmpeq %0,%6,%3\n" + " beq %3,2f\n" + " mskbl %2,%5,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%4)\n" + " beq %2,3f\n" + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64) + : "r" ((long)m), "Ir" (old), "1" (new) : "memory"); + + return prev; +} + +static inline unsigned long +__cmpxchg_u16_local(volatile short *m, long old, long new) +{ + unsigned long prev, tmp, cmp, addr64; + + __asm__ __volatile__( + " andnot %5,7,%4\n" + " inswl %1,%5,%1\n" + "1: ldq_l %2,0(%4)\n" + " extwl %2,%5,%0\n" + " cmpeq %0,%6,%3\n" + " beq %3,2f\n" + " mskwl %2,%5,%2\n" + " or %1,%2,%2\n" + " stq_c %2,0(%4)\n" + " beq %2,3f\n" + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64) + : "r" ((long)m), "Ir" (old), "1" (new) : "memory"); + + return prev; +} + +static inline unsigned long +__cmpxchg_u32_local(volatile int *m, int old, int new) +{ + unsigned long prev, cmp; + + __asm__ __volatile__( + "1: ldl_l %0,%5\n" + " cmpeq %0,%3,%1\n" + " beq %1,2f\n" + " mov %4,%1\n" + " stl_c %1,%2\n" + " beq %1,3f\n" + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r"(prev), "=&r"(cmp), "=m"(*m) + : "r"((long) old), "r"(new), "m"(*m) : "memory"); + + return prev; +} + +static inline unsigned long +__cmpxchg_u64_local(volatile long *m, unsigned long old, unsigned long new) +{ + unsigned long prev, cmp; + + __asm__ __volatile__( + "1: ldq_l %0,%5\n" + " cmpeq %0,%3,%1\n" + " beq %1,2f\n" + " mov %4,%1\n" + " stq_c %1,%2\n" + " beq %1,3f\n" + "2:\n" + ".subsection 2\n" + "3: br 1b\n" + ".previous" + : "=&r"(prev), "=&r"(cmp), "=m"(*m) + : "r"((long) old), "r"(new), "m"(*m) : "memory"); + + return prev; +} + +static __always_inline unsigned long +__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new, + int size) +{ + switch (size) { + case 1: + return __cmpxchg_u8_local(ptr, old, new); + case 2: + return __cmpxchg_u16_local(ptr, old, new); + case 4: + return __cmpxchg_u32_local(ptr, old, new); + case 8: + return __cmpxchg_u64_local(ptr, old, new); + } + __cmpxchg_called_with_bad_pointer(); + return old; +} + +#define cmpxchg_local(ptr, o, n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr))); \ + }) +#define cmpxchg64_local(ptr, o, n) \ + ({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ + cmpxchg_local((ptr), (o), (n)); \ + }) + + #endif /* __ASSEMBLY__ */ #define arch_align_stack(x) (x) diff --git a/trunk/arch/alpha/include/asm/types.h b/trunk/arch/alpha/include/asm/types.h index f072f344497e..c1541353ccef 100644 --- a/trunk/arch/alpha/include/asm/types.h +++ b/trunk/arch/alpha/include/asm/types.h @@ -8,12 +8,7 @@ * not a major issue. However, for interoperability, libraries still * need to be careful to avoid a name clashes. */ - -#ifdef __KERNEL__ -#include -#else #include -#endif #ifndef __ASSEMBLY__ diff --git a/trunk/arch/alpha/include/asm/uaccess.h b/trunk/arch/alpha/include/asm/uaccess.h index 163f3053001c..22de3b434a22 100644 --- a/trunk/arch/alpha/include/asm/uaccess.h +++ b/trunk/arch/alpha/include/asm/uaccess.h @@ -498,13 +498,13 @@ struct exception_table_entry }; /* Returns the new pc */ -#define fixup_exception(map_reg, _fixup, pc) \ +#define fixup_exception(map_reg, fixup, pc) \ ({ \ - if ((_fixup)->fixup.bits.valreg != 31) \ - map_reg((_fixup)->fixup.bits.valreg) = 0; \ - if ((_fixup)->fixup.bits.errreg != 31) \ - map_reg((_fixup)->fixup.bits.errreg) = -EFAULT; \ - (pc) + (_fixup)->fixup.bits.nextinsn; \ + if ((fixup)->fixup.bits.valreg != 31) \ + map_reg((fixup)->fixup.bits.valreg) = 0; \ + if ((fixup)->fixup.bits.errreg != 31) \ + map_reg((fixup)->fixup.bits.errreg) = -EFAULT; \ + (pc) + (fixup)->fixup.bits.nextinsn; \ }) diff --git a/trunk/arch/alpha/include/asm/xchg.h b/trunk/arch/alpha/include/asm/xchg.h deleted file mode 100644 index beba1b803e0d..000000000000 --- a/trunk/arch/alpha/include/asm/xchg.h +++ /dev/null @@ -1,258 +0,0 @@ -#ifndef __ALPHA_SYSTEM_H -#error Do not include xchg.h directly! -#else -/* - * xchg/xchg_local and cmpxchg/cmpxchg_local share the same code - * except that local version do not have the expensive memory barrier. - * So this file is included twice from asm/system.h. - */ - -/* - * Atomic exchange. - * Since it can be used to implement critical sections - * it must clobber "memory" (also for interrupts in UP). - */ - -static inline unsigned long -____xchg(_u8, volatile char *m, unsigned long val) -{ - unsigned long ret, tmp, addr64; - - __asm__ __volatile__( - " andnot %4,7,%3\n" - " insbl %1,%4,%1\n" - "1: ldq_l %2,0(%3)\n" - " extbl %2,%4,%0\n" - " mskbl %2,%4,%2\n" - " or %1,%2,%2\n" - " stq_c %2,0(%3)\n" - " beq %2,2f\n" - __ASM__MB - ".subsection 2\n" - "2: br 1b\n" - ".previous" - : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64) - : "r" ((long)m), "1" (val) : "memory"); - - return ret; -} - -static inline unsigned long -____xchg(_u16, volatile short *m, unsigned long val) -{ - unsigned long ret, tmp, addr64; - - __asm__ __volatile__( - " andnot %4,7,%3\n" - " inswl %1,%4,%1\n" - "1: ldq_l %2,0(%3)\n" - " extwl %2,%4,%0\n" - " mskwl %2,%4,%2\n" - " or %1,%2,%2\n" - " stq_c %2,0(%3)\n" - " beq %2,2f\n" - __ASM__MB - ".subsection 2\n" - "2: br 1b\n" - ".previous" - : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64) - : "r" ((long)m), "1" (val) : "memory"); - - return ret; -} - -static inline unsigned long -____xchg(_u32, volatile int *m, unsigned long val) -{ - unsigned long dummy; - - __asm__ __volatile__( - "1: ldl_l %0,%4\n" - " bis $31,%3,%1\n" - " stl_c %1,%2\n" - " beq %1,2f\n" - __ASM__MB - ".subsection 2\n" - "2: br 1b\n" - ".previous" - : "=&r" (val), "=&r" (dummy), "=m" (*m) - : "rI" (val), "m" (*m) : "memory"); - - return val; -} - -static inline unsigned long -____xchg(_u64, volatile long *m, unsigned long val) -{ - unsigned long dummy; - - __asm__ __volatile__( - "1: ldq_l %0,%4\n" - " bis $31,%3,%1\n" - " stq_c %1,%2\n" - " beq %1,2f\n" - __ASM__MB - ".subsection 2\n" - "2: br 1b\n" - ".previous" - : "=&r" (val), "=&r" (dummy), "=m" (*m) - : "rI" (val), "m" (*m) : "memory"); - - return val; -} - -/* This function doesn't exist, so you'll get a linker error - if something tries to do an invalid xchg(). */ -extern void __xchg_called_with_bad_pointer(void); - -static __always_inline unsigned long -____xchg(, volatile void *ptr, unsigned long x, int size) -{ - switch (size) { - case 1: - return ____xchg(_u8, ptr, x); - case 2: - return ____xchg(_u16, ptr, x); - case 4: - return ____xchg(_u32, ptr, x); - case 8: - return ____xchg(_u64, ptr, x); - } - __xchg_called_with_bad_pointer(); - return x; -} - -/* - * Atomic compare and exchange. Compare OLD with MEM, if identical, - * store NEW in MEM. Return the initial value in MEM. Success is - * indicated by comparing RETURN with OLD. - * - * The memory barrier should be placed in SMP only when we actually - * make the change. If we don't change anything (so if the returned - * prev is equal to old) then we aren't acquiring anything new and - * we don't need any memory barrier as far I can tell. - */ - -static inline unsigned long -____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new) -{ - unsigned long prev, tmp, cmp, addr64; - - __asm__ __volatile__( - " andnot %5,7,%4\n" - " insbl %1,%5,%1\n" - "1: ldq_l %2,0(%4)\n" - " extbl %2,%5,%0\n" - " cmpeq %0,%6,%3\n" - " beq %3,2f\n" - " mskbl %2,%5,%2\n" - " or %1,%2,%2\n" - " stq_c %2,0(%4)\n" - " beq %2,3f\n" - __ASM__MB - "2:\n" - ".subsection 2\n" - "3: br 1b\n" - ".previous" - : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64) - : "r" ((long)m), "Ir" (old), "1" (new) : "memory"); - - return prev; -} - -static inline unsigned long -____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new) -{ - unsigned long prev, tmp, cmp, addr64; - - __asm__ __volatile__( - " andnot %5,7,%4\n" - " inswl %1,%5,%1\n" - "1: ldq_l %2,0(%4)\n" - " extwl %2,%5,%0\n" - " cmpeq %0,%6,%3\n" - " beq %3,2f\n" - " mskwl %2,%5,%2\n" - " or %1,%2,%2\n" - " stq_c %2,0(%4)\n" - " beq %2,3f\n" - __ASM__MB - "2:\n" - ".subsection 2\n" - "3: br 1b\n" - ".previous" - : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64) - : "r" ((long)m), "Ir" (old), "1" (new) : "memory"); - - return prev; -} - -static inline unsigned long -____cmpxchg(_u32, volatile int *m, int old, int new) -{ - unsigned long prev, cmp; - - __asm__ __volatile__( - "1: ldl_l %0,%5\n" - " cmpeq %0,%3,%1\n" - " beq %1,2f\n" - " mov %4,%1\n" - " stl_c %1,%2\n" - " beq %1,3f\n" - __ASM__MB - "2:\n" - ".subsection 2\n" - "3: br 1b\n" - ".previous" - : "=&r"(prev), "=&r"(cmp), "=m"(*m) - : "r"((long) old), "r"(new), "m"(*m) : "memory"); - - return prev; -} - -static inline unsigned long -____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new) -{ - unsigned long prev, cmp; - - __asm__ __volatile__( - "1: ldq_l %0,%5\n" - " cmpeq %0,%3,%1\n" - " beq %1,2f\n" - " mov %4,%1\n" - " stq_c %1,%2\n" - " beq %1,3f\n" - __ASM__MB - "2:\n" - ".subsection 2\n" - "3: br 1b\n" - ".previous" - : "=&r"(prev), "=&r"(cmp), "=m"(*m) - : "r"((long) old), "r"(new), "m"(*m) : "memory"); - - return prev; -} - -/* This function doesn't exist, so you'll get a linker error - if something tries to do an invalid cmpxchg(). */ -extern void __cmpxchg_called_with_bad_pointer(void); - -static __always_inline unsigned long -____cmpxchg(, volatile void *ptr, unsigned long old, unsigned long new, - int size) -{ - switch (size) { - case 1: - return ____cmpxchg(_u8, ptr, old, new); - case 2: - return ____cmpxchg(_u16, ptr, old, new); - case 4: - return ____cmpxchg(_u32, ptr, old, new); - case 8: - return ____cmpxchg(_u64, ptr, old, new); - } - __cmpxchg_called_with_bad_pointer(); - return old; -} - -#endif diff --git a/trunk/arch/alpha/kernel/Makefile b/trunk/arch/alpha/kernel/Makefile index a427538252f8..b4697759a123 100644 --- a/trunk/arch/alpha/kernel/Makefile +++ b/trunk/arch/alpha/kernel/Makefile @@ -12,7 +12,7 @@ obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \ obj-$(CONFIG_VGA_HOSE) += console.o obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_PCI) += pci.o pci_iommu.o pci-sysfs.o +obj-$(CONFIG_PCI) += pci.o pci_iommu.o obj-$(CONFIG_SRM_ENV) += srm_env.o obj-$(CONFIG_MODULES) += module.o diff --git a/trunk/arch/alpha/kernel/err_ev6.c b/trunk/arch/alpha/kernel/err_ev6.c index 985e5c1681ac..11aee012a8ae 100644 --- a/trunk/arch/alpha/kernel/err_ev6.c +++ b/trunk/arch/alpha/kernel/err_ev6.c @@ -157,8 +157,8 @@ ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn, err_print_prefix, streamname[stream], bitsname[bits], sourcename[source]); - printk("%s Address: 0x%016llx\n" - " Syndrome[upper.lower]: %02llx.%02llx\n", + printk("%s Address: 0x%016lx\n" + " Syndrome[upper.lower]: %02lx.%02lx\n", err_print_prefix, c_addr, c2_syn, c1_syn); diff --git a/trunk/arch/alpha/kernel/err_ev7.c b/trunk/arch/alpha/kernel/err_ev7.c index 73770c6ca013..68cd493f54c5 100644 --- a/trunk/arch/alpha/kernel/err_ev7.c +++ b/trunk/arch/alpha/kernel/err_ev7.c @@ -246,13 +246,13 @@ ev7_process_pal_subpacket(struct el_subpacket *header) switch(header->type) { case EL_TYPE__PAL__LOGOUT_FRAME: - printk("%s*** MCHK occurred on LPID %ld (RBOX %llx)\n", + printk("%s*** MCHK occurred on LPID %ld (RBOX %lx)\n", err_print_prefix, packet->by_type.logout.whami, packet->by_type.logout.rbox_whami); el_print_timestamp(&packet->by_type.logout.timestamp); - printk("%s EXC_ADDR: %016llx\n" - " HALT_CODE: %llx\n", + printk("%s EXC_ADDR: %016lx\n" + " HALT_CODE: %lx\n", err_print_prefix, packet->by_type.logout.exc_addr, packet->by_type.logout.halt_code); diff --git a/trunk/arch/alpha/kernel/err_marvel.c b/trunk/arch/alpha/kernel/err_marvel.c index 6bfd243efba3..413bf37eb094 100644 --- a/trunk/arch/alpha/kernel/err_marvel.c +++ b/trunk/arch/alpha/kernel/err_marvel.c @@ -129,7 +129,7 @@ marvel_print_po7_crrct_sym(u64 crrct_sym) printk("%s Correctable Error Symptoms:\n" - "%s Syndrome: 0x%llx\n", + "%s Syndrome: 0x%lx\n", err_print_prefix, err_print_prefix, EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__SYN)); marvel_print_err_cyc(EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__ERR_CYC)); @@ -186,7 +186,7 @@ marvel_print_po7_uncrr_sym(u64 uncrr_sym, u64 valid_mask) uncrr_sym &= valid_mask; if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__SYN)) - printk("%s Syndrome: 0x%llx\n", + printk("%s Syndrome: 0x%lx\n", err_print_prefix, EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__SYN)); @@ -307,7 +307,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym) sprintf(opcode_str, "BlkIO"); break; default: - sprintf(opcode_str, "0x%llx\n", + sprintf(opcode_str, "0x%lx\n", EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE)); break; } @@ -321,7 +321,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym) opcode_str); if (0xC5 != EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE)) - printk("%s Packet Offset 0x%08llx\n", + printk("%s Packet Offset 0x%08lx\n", err_print_prefix, EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_PKT_OFF)); } @@ -480,8 +480,8 @@ marvel_print_po7_err_sum(struct ev7_pal_io_subpacket *io) printk("%s Lost Error\n", err_print_prefix); printk("%s Failing Packet:\n" - "%s Cycle 1: %016llx\n" - "%s Cycle 2: %016llx\n", + "%s Cycle 1: %016lx\n" + "%s Cycle 2: %016lx\n", err_print_prefix, err_print_prefix, io->po7_err_pkt0, err_print_prefix, io->po7_err_pkt1); @@ -515,9 +515,9 @@ marvel_print_pox_tlb_err(u64 tlb_err) if (!(tlb_err & IO7__POX_TLBERR__ERR_VALID)) return; - printk("%s TLB Error on index 0x%llx:\n" + printk("%s TLB Error on index 0x%lx:\n" "%s - %s\n" - "%s - Addr: 0x%016llx\n", + "%s - Addr: 0x%016lx\n", err_print_prefix, EXTRACT(tlb_err, IO7__POX_TLBERR__ERR_TLB_PTR), err_print_prefix, @@ -579,7 +579,7 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt) sprintf(message, "Uncorrectable Split Write Data Error"); break; default: - sprintf(message, "%08llx\n", + sprintf(message, "%08lx\n", EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MESSAGE)); break; } @@ -620,9 +620,9 @@ marvel_print_pox_trans_sum(u64 trans_sum) return; printk("%s Transaction Summary:\n" - "%s Command: 0x%llx - %s\n" - "%s Address: 0x%016llx%s\n" - "%s PCI-X Master Slot: 0x%llx\n", + "%s Command: 0x%lx - %s\n" + "%s Address: 0x%016lx%s\n" + "%s PCI-X Master Slot: 0x%lx\n", err_print_prefix, err_print_prefix, EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD), @@ -964,12 +964,12 @@ marvel_process_io_error(struct ev7_lf_subpackets *lf_subpackets, int print) #if 0 printk("%s PORT 7 ERROR:\n" - "%s PO7_ERROR_SUM: %016llx\n" - "%s PO7_UNCRR_SYM: %016llx\n" - "%s PO7_CRRCT_SYM: %016llx\n" - "%s PO7_UGBGE_SYM: %016llx\n" - "%s PO7_ERR_PKT0: %016llx\n" - "%s PO7_ERR_PKT1: %016llx\n", + "%s PO7_ERROR_SUM: %016lx\n" + "%s PO7_UNCRR_SYM: %016lx\n" + "%s PO7_CRRCT_SYM: %016lx\n" + "%s PO7_UGBGE_SYM: %016lx\n" + "%s PO7_ERR_PKT0: %016lx\n" + "%s PO7_ERR_PKT1: %016lx\n", err_print_prefix, err_print_prefix, io->po7_error_sum, err_print_prefix, io->po7_uncrr_sym, @@ -987,12 +987,12 @@ marvel_process_io_error(struct ev7_lf_subpackets *lf_subpackets, int print) if (!MARVEL_IO_ERR_VALID(io->ports[i].pox_err_sum)) continue; - printk("%s PID %u PORT %d POx_ERR_SUM: %016llx\n", + printk("%s PID %u PORT %d POx_ERR_SUM: %016lx\n", err_print_prefix, lf_subpackets->io_pid, i, io->ports[i].pox_err_sum); marvel_print_pox_err(io->ports[i].pox_err_sum, &io->ports[i]); - printk("%s [ POx_FIRST_ERR: %016llx ]\n", + printk("%s [ POx_FIRST_ERR: %016lx ]\n", err_print_prefix, io->ports[i].pox_first_err); marvel_print_pox_err(io->ports[i].pox_first_err, &io->ports[i]); diff --git a/trunk/arch/alpha/kernel/err_titan.c b/trunk/arch/alpha/kernel/err_titan.c index c7e28a88d6e3..257449ed15ef 100644 --- a/trunk/arch/alpha/kernel/err_titan.c +++ b/trunk/arch/alpha/kernel/err_titan.c @@ -107,12 +107,12 @@ titan_parse_p_serror(int which, u64 serror, int print) if (!print) return status; - printk("%s PChip %d SERROR: %016llx\n", + printk("%s PChip %d SERROR: %016lx\n", err_print_prefix, which, serror); if (serror & TITAN__PCHIP_SERROR__ECCMASK) { printk("%s %sorrectable ECC Error:\n" " Source: %-6s Command: %-8s Syndrome: 0x%08x\n" - " Address: 0x%llx\n", + " Address: 0x%lx\n", err_print_prefix, (serror & TITAN__PCHIP_SERROR__UECC) ? "Unc" : "C", serror_src[EXTRACT(serror, TITAN__PCHIP_SERROR__SRC)], @@ -223,7 +223,7 @@ titan_parse_p_perror(int which, int port, u64 perror, int print) if (!print) return status; - printk("%s PChip %d %cPERROR: %016llx\n", + printk("%s PChip %d %cPERROR: %016lx\n", err_print_prefix, which, port ? 'A' : 'G', perror); if (perror & TITAN__PCHIP_PERROR__IPTPW) @@ -316,7 +316,7 @@ titan_parse_p_agperror(int which, u64 agperror, int print) addr = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__ADDR) << 3; len = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__LEN); - printk("%s PChip %d AGPERROR: %016llx\n", err_print_prefix, + printk("%s PChip %d AGPERROR: %016lx\n", err_print_prefix, which, agperror); if (agperror & TITAN__PCHIP_AGPERROR__NOWINDOW) printk("%s No Window\n", err_print_prefix); @@ -597,16 +597,16 @@ privateer_process_680_frame(struct el_common *mchk_header, int print) return status; /* TODO - decode instead of just dumping... */ - printk("%s Summary Flags: %016llx\n" - " CChip DIRx: %016llx\n" - " System Management IR: %016llx\n" - " CPU IR: %016llx\n" - " Power Supply IR: %016llx\n" - " LM78 Fault Status: %016llx\n" - " System Doors: %016llx\n" - " Temperature Warning: %016llx\n" - " Fan Control: %016llx\n" - " Fatal Power Down Code: %016llx\n", + printk("%s Summary Flags: %016lx\n" + " CChip DIRx: %016lx\n" + " System Management IR: %016lx\n" + " CPU IR: %016lx\n" + " Power Supply IR: %016lx\n" + " LM78 Fault Status: %016lx\n" + " System Doors: %016lx\n" + " Temperature Warning: %016lx\n" + " Fan Control: %016lx\n" + " Fatal Power Down Code: %016lx\n", err_print_prefix, emchk->summary, emchk->c_dirx, diff --git a/trunk/arch/alpha/kernel/pci-sysfs.c b/trunk/arch/alpha/kernel/pci-sysfs.c deleted file mode 100644 index 6ea822e7f724..000000000000 --- a/trunk/arch/alpha/kernel/pci-sysfs.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * arch/alpha/kernel/pci-sysfs.c - * - * Copyright (C) 2009 Ivan Kokshaysky - * - * Alpha PCI resource files. - * - * Loosely based on generic HAVE_PCI_MMAP implementation in - * drivers/pci/pci-sysfs.c - */ - -#include -#include - -static int hose_mmap_page_range(struct pci_controller *hose, - struct vm_area_struct *vma, - enum pci_mmap_state mmap_type, int sparse) -{ - unsigned long base; - - if (mmap_type == pci_mmap_mem) - base = sparse ? hose->sparse_mem_base : hose->dense_mem_base; - else - base = sparse ? hose->sparse_io_base : hose->dense_io_base; - - vma->vm_pgoff += base >> PAGE_SHIFT; - vma->vm_flags |= (VM_IO | VM_RESERVED); - - return io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot); -} - -static int __pci_mmap_fits(struct pci_dev *pdev, int num, - struct vm_area_struct *vma, int sparse) -{ - unsigned long nr, start, size; - int shift = sparse ? 5 : 0; - - nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; - start = vma->vm_pgoff; - size = ((pci_resource_len(pdev, num) - 1) >> (PAGE_SHIFT - shift)) + 1; - - if (start < size && size - start >= nr) - return 1; - WARN(1, "process \"%s\" tried to map%s 0x%08lx-0x%08lx on %s BAR %d " - "(size 0x%08lx)\n", - current->comm, sparse ? " sparse" : "", start, start + nr, - pci_name(pdev), num, size); - return 0; -} - -/** - * pci_mmap_resource - map a PCI resource into user memory space - * @kobj: kobject for mapping - * @attr: struct bin_attribute for the file being mapped - * @vma: struct vm_area_struct passed into the mmap - * @sparse: address space type - * - * Use the bus mapping routines to map a PCI resource into userspace. - */ -static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, - struct vm_area_struct *vma, int sparse) -{ - struct pci_dev *pdev = to_pci_dev(container_of(kobj, - struct device, kobj)); - struct resource *res = (struct resource *)attr->private; - enum pci_mmap_state mmap_type; - struct pci_bus_region bar; - int i; - - for (i = 0; i < PCI_ROM_RESOURCE; i++) - if (res == &pdev->resource[i]) - break; - if (i >= PCI_ROM_RESOURCE) - return -ENODEV; - - if (!__pci_mmap_fits(pdev, i, vma, sparse)) - return -EINVAL; - - if (iomem_is_exclusive(res->start)) - return -EINVAL; - - pcibios_resource_to_bus(pdev, &bar, res); - vma->vm_pgoff += bar.start >> (PAGE_SHIFT - (sparse ? 5 : 0)); - mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; - - return hose_mmap_page_range(pdev->sysdata, vma, mmap_type, sparse); -} - -static int pci_mmap_resource_sparse(struct kobject *kobj, - struct bin_attribute *attr, - struct vm_area_struct *vma) -{ - return pci_mmap_resource(kobj, attr, vma, 1); -} - -static int pci_mmap_resource_dense(struct kobject *kobj, - struct bin_attribute *attr, - struct vm_area_struct *vma) -{ - return pci_mmap_resource(kobj, attr, vma, 0); -} - -/** - * pci_remove_resource_files - cleanup resource files - * @dev: dev to cleanup - * - * If we created resource files for @dev, remove them from sysfs and - * free their resources. - */ -void pci_remove_resource_files(struct pci_dev *pdev) -{ - int i; - - for (i = 0; i < PCI_ROM_RESOURCE; i++) { - struct bin_attribute *res_attr; - - res_attr = pdev->res_attr[i]; - if (res_attr) { - sysfs_remove_bin_file(&pdev->dev.kobj, res_attr); - kfree(res_attr); - } - - res_attr = pdev->res_attr_wc[i]; - if (res_attr) { - sysfs_remove_bin_file(&pdev->dev.kobj, res_attr); - kfree(res_attr); - } - } -} - -static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num) -{ - struct pci_bus_region bar; - struct pci_controller *hose = pdev->sysdata; - long dense_offset; - unsigned long sparse_size; - - pcibios_resource_to_bus(pdev, &bar, &pdev->resource[num]); - - /* All core logic chips have 4G sparse address space, except - CIA which has 16G (see xxx_SPARSE_MEM and xxx_DENSE_MEM - definitions in asm/core_xxx.h files). This corresponds - to 128M or 512M of the bus space. */ - dense_offset = (long)(hose->dense_mem_base - hose->sparse_mem_base); - sparse_size = dense_offset >= 0x400000000UL ? 0x20000000 : 0x8000000; - - return bar.end < sparse_size; -} - -static int pci_create_one_attr(struct pci_dev *pdev, int num, char *name, - char *suffix, struct bin_attribute *res_attr, - unsigned long sparse) -{ - size_t size = pci_resource_len(pdev, num); - - sprintf(name, "resource%d%s", num, suffix); - res_attr->mmap = sparse ? pci_mmap_resource_sparse : - pci_mmap_resource_dense; - res_attr->attr.name = name; - res_attr->attr.mode = S_IRUSR | S_IWUSR; - res_attr->size = sparse ? size << 5 : size; - res_attr->private = &pdev->resource[num]; - return sysfs_create_bin_file(&pdev->dev.kobj, res_attr); -} - -static int pci_create_attr(struct pci_dev *pdev, int num) -{ - /* allocate attribute structure, piggyback attribute name */ - int retval, nlen1, nlen2 = 0, res_count = 1; - unsigned long sparse_base, dense_base; - struct bin_attribute *attr; - struct pci_controller *hose = pdev->sysdata; - char *suffix, *attr_name; - - suffix = ""; /* Assume bwx machine, normal resourceN files. */ - nlen1 = 10; - - if (pdev->resource[num].flags & IORESOURCE_MEM) { - sparse_base = hose->sparse_mem_base; - dense_base = hose->dense_mem_base; - if (sparse_base && !sparse_mem_mmap_fits(pdev, num)) { - sparse_base = 0; - suffix = "_dense"; - nlen1 = 16; /* resourceN_dense */ - } - } else { - sparse_base = hose->sparse_io_base; - dense_base = hose->dense_io_base; - } - - if (sparse_base) { - suffix = "_sparse"; - nlen1 = 17; - if (dense_base) { - nlen2 = 16; /* resourceN_dense */ - res_count = 2; - } - } - - attr = kzalloc(sizeof(*attr) * res_count + nlen1 + nlen2, GFP_ATOMIC); - if (!attr) - return -ENOMEM; - - /* Create bwx, sparse or single dense file */ - attr_name = (char *)(attr + res_count); - pdev->res_attr[num] = attr; - retval = pci_create_one_attr(pdev, num, attr_name, suffix, attr, - sparse_base); - if (retval || res_count == 1) - return retval; - - /* Create dense file */ - attr_name += nlen1; - attr++; - pdev->res_attr_wc[num] = attr; - return pci_create_one_attr(pdev, num, attr_name, "_dense", attr, 0); -} - -/** - * pci_create_resource_files - create resource files in sysfs for @dev - * @dev: dev in question - * - * Walk the resources in @dev creating files for each resource available. - */ -int pci_create_resource_files(struct pci_dev *pdev) -{ - int i; - int retval; - - /* Expose the PCI resources from this device as files */ - for (i = 0; i < PCI_ROM_RESOURCE; i++) { - - /* skip empty resources */ - if (!pci_resource_len(pdev, i)) - continue; - - retval = pci_create_attr(pdev, i); - if (retval) { - pci_remove_resource_files(pdev); - return retval; - } - } - return 0; -} - -/* Legacy I/O bus mapping stuff. */ - -static int __legacy_mmap_fits(struct pci_controller *hose, - struct vm_area_struct *vma, - unsigned long res_size, int sparse) -{ - unsigned long nr, start, size; - - nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; - start = vma->vm_pgoff; - size = ((res_size - 1) >> PAGE_SHIFT) + 1; - - if (start < size && size - start >= nr) - return 1; - WARN(1, "process \"%s\" tried to map%s 0x%08lx-0x%08lx on hose %d " - "(size 0x%08lx)\n", - current->comm, sparse ? " sparse" : "", start, start + nr, - hose->index, size); - return 0; -} - -static inline int has_sparse(struct pci_controller *hose, - enum pci_mmap_state mmap_type) -{ - unsigned long base; - - base = (mmap_type == pci_mmap_mem) ? hose->sparse_mem_base : - hose->sparse_io_base; - - return base != 0; -} - -int pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma, - enum pci_mmap_state mmap_type) -{ - struct pci_controller *hose = bus->sysdata; - int sparse = has_sparse(hose, mmap_type); - unsigned long res_size; - - res_size = (mmap_type == pci_mmap_mem) ? bus->legacy_mem->size : - bus->legacy_io->size; - if (!__legacy_mmap_fits(hose, vma, res_size, sparse)) - return -EINVAL; - - return hose_mmap_page_range(hose, vma, mmap_type, sparse); -} - -/** - * pci_adjust_legacy_attr - adjustment of legacy file attributes - * @b: bus to create files under - * @mmap_type: I/O port or memory - * - * Adjust file name and size for sparse mappings. - */ -void pci_adjust_legacy_attr(struct pci_bus *bus, enum pci_mmap_state mmap_type) -{ - struct pci_controller *hose = bus->sysdata; - - if (!has_sparse(hose, mmap_type)) - return; - - if (mmap_type == pci_mmap_mem) { - bus->legacy_mem->attr.name = "legacy_mem_sparse"; - bus->legacy_mem->size <<= 5; - } else { - bus->legacy_io->attr.name = "legacy_io_sparse"; - bus->legacy_io->size <<= 5; - } - return; -} - -/* Legacy I/O bus read/write functions */ -int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size) -{ - struct pci_controller *hose = bus->sysdata; - - port += hose->io_space->start; - - switch(size) { - case 1: - *((u8 *)val) = inb(port); - return 1; - case 2: - if (port & 1) - return -EINVAL; - *((u16 *)val) = inw(port); - return 2; - case 4: - if (port & 3) - return -EINVAL; - *((u32 *)val) = inl(port); - return 4; - } - return -EINVAL; -} - -int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size) -{ - struct pci_controller *hose = bus->sysdata; - - port += hose->io_space->start; - - switch(size) { - case 1: - outb(port, val); - return 1; - case 2: - if (port & 1) - return -EINVAL; - outw(port, val); - return 2; - case 4: - if (port & 3) - return -EINVAL; - outl(port, val); - return 4; - } - return -EINVAL; -} diff --git a/trunk/arch/alpha/kernel/pci.c b/trunk/arch/alpha/kernel/pci.c index a91ba28999b5..a3b938811400 100644 --- a/trunk/arch/alpha/kernel/pci.c +++ b/trunk/arch/alpha/kernel/pci.c @@ -168,7 +168,7 @@ pcibios_align_resource(void *data, struct resource *res, */ /* Align to multiple of size of minimum base. */ - alignto = max_t(resource_size_t, 0x1000, align); + alignto = max(0x1000UL, align); start = ALIGN(start, alignto); if (hose->sparse_mem_base && size <= 7 * 16*MB) { if (((start / (16*MB)) & 0x7) == 0) { diff --git a/trunk/arch/alpha/kernel/pci_iommu.c b/trunk/arch/alpha/kernel/pci_iommu.c index bfb880af959d..b9094da05d7a 100644 --- a/trunk/arch/alpha/kernel/pci_iommu.c +++ b/trunk/arch/alpha/kernel/pci_iommu.c @@ -247,7 +247,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, && paddr + size <= __direct_map_size) { ret = paddr + __direct_map_base; - DBGA2("pci_map_single: [%p,%zx] -> direct %llx from %p\n", + DBGA2("pci_map_single: [%p,%lx] -> direct %lx from %p\n", cpu_addr, size, ret, __builtin_return_address(0)); return ret; @@ -258,7 +258,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, if (dac_allowed) { ret = paddr + alpha_mv.pci_dac_offset; - DBGA2("pci_map_single: [%p,%zx] -> DAC %llx from %p\n", + DBGA2("pci_map_single: [%p,%lx] -> DAC %lx from %p\n", cpu_addr, size, ret, __builtin_return_address(0)); return ret; @@ -299,7 +299,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, ret = arena->dma_base + dma_ofs * PAGE_SIZE; ret += (unsigned long)cpu_addr & ~PAGE_MASK; - DBGA2("pci_map_single: [%p,%zx] np %ld -> sg %llx from %p\n", + DBGA2("pci_map_single: [%p,%lx] np %ld -> sg %lx from %p\n", cpu_addr, size, npages, ret, __builtin_return_address(0)); return ret; @@ -355,14 +355,14 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size, && dma_addr < __direct_map_base + __direct_map_size) { /* Nothing to do. */ - DBGA2("pci_unmap_single: direct [%llx,%zx] from %p\n", + DBGA2("pci_unmap_single: direct [%lx,%lx] from %p\n", dma_addr, size, __builtin_return_address(0)); return; } if (dma_addr > 0xffffffff) { - DBGA2("pci64_unmap_single: DAC [%llx,%zx] from %p\n", + DBGA2("pci64_unmap_single: DAC [%lx,%lx] from %p\n", dma_addr, size, __builtin_return_address(0)); return; } @@ -373,9 +373,9 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size, dma_ofs = (dma_addr - arena->dma_base) >> PAGE_SHIFT; if (dma_ofs * PAGE_SIZE >= arena->size) { - printk(KERN_ERR "Bogus pci_unmap_single: dma_addr %llx " - " base %llx size %x\n", - dma_addr, arena->dma_base, arena->size); + printk(KERN_ERR "Bogus pci_unmap_single: dma_addr %lx " + " base %lx size %x\n", dma_addr, arena->dma_base, + arena->size); return; BUG(); } @@ -394,7 +394,7 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size, spin_unlock_irqrestore(&arena->lock, flags); - DBGA2("pci_unmap_single: sg [%llx,%zx] np %ld from %p\n", + DBGA2("pci_unmap_single: sg [%lx,%lx] np %ld from %p\n", dma_addr, size, npages, __builtin_return_address(0)); } EXPORT_SYMBOL(pci_unmap_single); @@ -444,7 +444,7 @@ __pci_alloc_consistent(struct pci_dev *pdev, size_t size, goto try_again; } - DBGA2("pci_alloc_consistent: %zx -> [%p,%llx] from %p\n", + DBGA2("pci_alloc_consistent: %lx -> [%p,%x] from %p\n", size, cpu_addr, *dma_addrp, __builtin_return_address(0)); return cpu_addr; @@ -464,7 +464,7 @@ pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr, pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL); free_pages((unsigned long)cpu_addr, get_order(size)); - DBGA2("pci_free_consistent: [%llx,%zx] from %p\n", + DBGA2("pci_free_consistent: [%x,%lx] from %p\n", dma_addr, size, __builtin_return_address(0)); } EXPORT_SYMBOL(pci_free_consistent); @@ -551,7 +551,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end, out->dma_address = paddr + __direct_map_base; out->dma_length = size; - DBGA(" sg_fill: [%p,%lx] -> direct %llx\n", + DBGA(" sg_fill: [%p,%lx] -> direct %lx\n", __va(paddr), size, out->dma_address); return 0; @@ -563,7 +563,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end, out->dma_address = paddr + alpha_mv.pci_dac_offset; out->dma_length = size; - DBGA(" sg_fill: [%p,%lx] -> DAC %llx\n", + DBGA(" sg_fill: [%p,%lx] -> DAC %lx\n", __va(paddr), size, out->dma_address); return 0; @@ -589,7 +589,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end, out->dma_address = arena->dma_base + dma_ofs*PAGE_SIZE + paddr; out->dma_length = size; - DBGA(" sg_fill: [%p,%lx] -> sg %llx np %ld\n", + DBGA(" sg_fill: [%p,%lx] -> sg %lx np %ld\n", __va(paddr), size, out->dma_address, npages); /* All virtually contiguous. We need to find the length of each @@ -752,7 +752,7 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, if (addr > 0xffffffff) { /* It's a DAC address -- nothing to do. */ - DBGA(" (%ld) DAC [%llx,%zx]\n", + DBGA(" (%ld) DAC [%lx,%lx]\n", sg - end + nents, addr, size); continue; } @@ -760,12 +760,12 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents, if (addr >= __direct_map_base && addr < __direct_map_base + __direct_map_size) { /* Nothing to do. */ - DBGA(" (%ld) direct [%llx,%zx]\n", + DBGA(" (%ld) direct [%lx,%lx]\n", sg - end + nents, addr, size); continue; } - DBGA(" (%ld) sg [%llx,%zx]\n", + DBGA(" (%ld) sg [%lx,%lx]\n", sg - end + nents, addr, size); npages = iommu_num_pages(addr, size, PAGE_SIZE); diff --git a/trunk/arch/alpha/kernel/process.c b/trunk/arch/alpha/kernel/process.c index 3a2fb7a02db4..8d0097f10208 100644 --- a/trunk/arch/alpha/kernel/process.c +++ b/trunk/arch/alpha/kernel/process.c @@ -272,7 +272,7 @@ alpha_vfork(struct pt_regs *regs) */ int -copy_thread(unsigned long clone_flags, unsigned long usp, +copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct * p, struct pt_regs * regs) { diff --git a/trunk/arch/alpha/kernel/proto.h b/trunk/arch/alpha/kernel/proto.h index 567f2598d090..fe14c6747cd6 100644 --- a/trunk/arch/alpha/kernel/proto.h +++ b/trunk/arch/alpha/kernel/proto.h @@ -20,7 +20,7 @@ struct pci_controller; extern struct pci_ops apecs_pci_ops; extern void apecs_init_arch(void); extern void apecs_pci_clr_err(void); -extern void apecs_machine_check(unsigned long vector, unsigned long la_ptr); +extern void apecs_machine_check(u64, u64); extern void apecs_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_cia.c */ @@ -29,7 +29,7 @@ extern void cia_init_pci(void); extern void cia_init_arch(void); extern void pyxis_init_arch(void); extern void cia_kill_arch(int); -extern void cia_machine_check(unsigned long vector, unsigned long la_ptr); +extern void cia_machine_check(u64, u64); extern void cia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_irongate.c */ @@ -42,7 +42,7 @@ extern void irongate_machine_check(u64, u64); /* core_lca.c */ extern struct pci_ops lca_pci_ops; extern void lca_init_arch(void); -extern void lca_machine_check(unsigned long vector, unsigned long la_ptr); +extern void lca_machine_check(u64, u64); extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_marvel.c */ @@ -64,7 +64,7 @@ void io7_clear_errors(struct io7 *io7); extern struct pci_ops mcpcia_pci_ops; extern void mcpcia_init_arch(void); extern void mcpcia_init_hoses(void); -extern void mcpcia_machine_check(unsigned long vector, unsigned long la_ptr); +extern void mcpcia_machine_check(u64, u64); extern void mcpcia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_polaris.c */ @@ -72,14 +72,14 @@ extern struct pci_ops polaris_pci_ops; extern int polaris_read_config_dword(struct pci_dev *, int, u32 *); extern int polaris_write_config_dword(struct pci_dev *, int, u32); extern void polaris_init_arch(void); -extern void polaris_machine_check(unsigned long vector, unsigned long la_ptr); +extern void polaris_machine_check(u64, u64); #define polaris_pci_tbi ((void *)0) /* core_t2.c */ extern struct pci_ops t2_pci_ops; extern void t2_init_arch(void); extern void t2_kill_arch(int); -extern void t2_machine_check(unsigned long vector, unsigned long la_ptr); +extern void t2_machine_check(u64, u64); extern void t2_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_titan.c */ @@ -94,14 +94,14 @@ extern struct _alpha_agp_info *titan_agp_info(void); extern struct pci_ops tsunami_pci_ops; extern void tsunami_init_arch(void); extern void tsunami_kill_arch(int); -extern void tsunami_machine_check(unsigned long vector, unsigned long la_ptr); +extern void tsunami_machine_check(u64, u64); extern void tsunami_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); /* core_wildfire.c */ extern struct pci_ops wildfire_pci_ops; extern void wildfire_init_arch(void); extern void wildfire_kill_arch(int); -extern void wildfire_machine_check(unsigned long vector, unsigned long la_ptr); +extern void wildfire_machine_check(u64, u64); extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); extern int wildfire_pa_to_nid(unsigned long); extern int wildfire_cpuid_to_nid(int); diff --git a/trunk/arch/alpha/kernel/setup.c b/trunk/arch/alpha/kernel/setup.c index 80df86cd746b..02bee6983ce2 100644 --- a/trunk/arch/alpha/kernel/setup.c +++ b/trunk/arch/alpha/kernel/setup.c @@ -1255,7 +1255,7 @@ show_cpuinfo(struct seq_file *f, void *slot) platform_string(), nr_processors); #ifdef CONFIG_SMP - seq_printf(f, "cpus active\t\t: %u\n" + seq_printf(f, "cpus active\t\t: %d\n" "cpu active mask\t\t: %016lx\n", num_online_cpus(), cpus_addr(cpu_possible_map)[0]); #endif diff --git a/trunk/arch/alpha/kernel/smc37c669.c b/trunk/arch/alpha/kernel/smc37c669.c index bca5bda90cde..fd467b207f0f 100644 --- a/trunk/arch/alpha/kernel/smc37c669.c +++ b/trunk/arch/alpha/kernel/smc37c669.c @@ -2542,8 +2542,8 @@ void __init SMC669_Init ( int index ) SMC37c669_display_device_info( ); #endif local_irq_restore(flags); - printk( "SMC37c669 Super I/O Controller found @ 0x%p\n", - SMC_base ); + printk( "SMC37c669 Super I/O Controller found @ 0x%lx\n", + (unsigned long) SMC_base ); } else { local_irq_restore(flags); diff --git a/trunk/arch/alpha/kernel/srm_env.c b/trunk/arch/alpha/kernel/srm_env.c index d12af472e1c0..78ad7cd1bbd6 100644 --- a/trunk/arch/alpha/kernel/srm_env.c +++ b/trunk/arch/alpha/kernel/srm_env.c @@ -218,6 +218,7 @@ srm_env_init(void) BASE_DIR); goto cleanup; } + base_dir->owner = THIS_MODULE; /* * Create per-name subdirectory @@ -228,6 +229,7 @@ srm_env_init(void) BASE_DIR, NAMED_DIR); goto cleanup; } + named_dir->owner = THIS_MODULE; /* * Create per-number subdirectory @@ -239,6 +241,7 @@ srm_env_init(void) goto cleanup; } + numbered_dir->owner = THIS_MODULE; /* * Create all named nodes @@ -251,6 +254,7 @@ srm_env_init(void) goto cleanup; entry->proc_entry->data = (void *) entry; + entry->proc_entry->owner = THIS_MODULE; entry->proc_entry->read_proc = srm_env_read; entry->proc_entry->write_proc = srm_env_write; @@ -271,6 +275,7 @@ srm_env_init(void) entry->id = var_num; entry->proc_entry->data = (void *) entry; + entry->proc_entry->owner = THIS_MODULE; entry->proc_entry->read_proc = srm_env_read; entry->proc_entry->write_proc = srm_env_write; } diff --git a/trunk/arch/alpha/kernel/sys_jensen.c b/trunk/arch/alpha/kernel/sys_jensen.c index 2b5caf3d9b15..e2516f9a8967 100644 --- a/trunk/arch/alpha/kernel/sys_jensen.c +++ b/trunk/arch/alpha/kernel/sys_jensen.c @@ -244,11 +244,12 @@ jensen_init_arch(void) } static void -jensen_machine_check(unsigned long vector, unsigned long la) +jensen_machine_check (u64 vector, u64 la) { printk(KERN_CRIT "Machine check\n"); } + /* * The System Vector */ diff --git a/trunk/arch/alpha/kernel/sys_sable.c b/trunk/arch/alpha/kernel/sys_sable.c index 9e263256a42d..d232e42be018 100644 --- a/trunk/arch/alpha/kernel/sys_sable.c +++ b/trunk/arch/alpha/kernel/sys_sable.c @@ -453,7 +453,7 @@ sable_lynx_enable_irq(unsigned int irq) sable_lynx_irq_swizzle->update_irq_hw(bit, mask); spin_unlock(&sable_lynx_irq_lock); #if 0 - printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n", + printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n", __func__, mask, bit, irq); #endif } @@ -469,7 +469,7 @@ sable_lynx_disable_irq(unsigned int irq) sable_lynx_irq_swizzle->update_irq_hw(bit, mask); spin_unlock(&sable_lynx_irq_lock); #if 0 - printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n", + printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n", __func__, mask, bit, irq); #endif } diff --git a/trunk/arch/alpha/kernel/traps.c b/trunk/arch/alpha/kernel/traps.c index 6ee7655b7568..cefc5a355ef9 100644 --- a/trunk/arch/alpha/kernel/traps.c +++ b/trunk/arch/alpha/kernel/traps.c @@ -623,7 +623,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, } lock_kernel(); - printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n", + printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n", pc, va, opcode, reg); do_exit(SIGSEGV); diff --git a/trunk/arch/arm/include/asm/spinlock.h b/trunk/arch/arm/include/asm/spinlock.h index c13681ac1ede..2b41ebbfa7ff 100644 --- a/trunk/arch/arm/include/asm/spinlock.h +++ b/trunk/arch/arm/include/asm/spinlock.h @@ -217,9 +217,6 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw) /* read_can_lock - would read_trylock() succeed? */ #define __raw_read_can_lock(x) ((x)->lock < 0x80000000) -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) - #define _raw_spin_relax(lock) cpu_relax() #define _raw_read_relax(lock) cpu_relax() #define _raw_write_relax(lock) cpu_relax() diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index c3265a2e7cd4..2de14e2afdc5 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -301,7 +301,7 @@ void release_thread(struct task_struct *dead_task) asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); int -copy_thread(unsigned long clone_flags, unsigned long stack_start, +copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start, unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs) { struct thread_info *thread = task_thread_info(p); diff --git a/trunk/arch/arm/mach-pxa/pcm990-baseboard.c b/trunk/arch/arm/mach-pxa/pcm990-baseboard.c index 6112740b4ae9..f46698e20c1f 100644 --- a/trunk/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/trunk/arch/arm/mach-pxa/pcm990-baseboard.c @@ -380,49 +380,14 @@ static struct pca953x_platform_data pca9536_data = { .gpio_base = NR_BUILTIN_GPIO + 1, }; -static int gpio_bus_switch; - -static int pcm990_camera_set_bus_param(struct soc_camera_link *link, - unsigned long flags) -{ - if (gpio_bus_switch <= 0) { - if (flags == SOCAM_DATAWIDTH_10) - return 0; - else - return -EINVAL; - } - - if (flags & SOCAM_DATAWIDTH_8) - gpio_set_value(gpio_bus_switch, 1); - else - gpio_set_value(gpio_bus_switch, 0); - - return 0; -} - -static unsigned long pcm990_camera_query_bus_param(struct soc_camera_link *link) -{ - int ret; - - if (!gpio_bus_switch) { - ret = gpio_request(NR_BUILTIN_GPIO + 1, "camera"); - if (!ret) { - gpio_bus_switch = NR_BUILTIN_GPIO + 1; - gpio_direction_output(gpio_bus_switch, 0); - } else - gpio_bus_switch = -EINVAL; +static struct soc_camera_link iclink[] = { + { + .bus_id = 0, /* Must match with the camera ID above */ + .gpio = NR_BUILTIN_GPIO + 1, + }, { + .bus_id = 0, /* Must match with the camera ID above */ + .gpio = -ENXIO, } - - if (gpio_bus_switch > 0) - return SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_10; - else - return SOCAM_DATAWIDTH_10; -} - -static struct soc_camera_link iclink = { - .bus_id = 0, /* Must match with the camera ID above */ - .query_bus_param = pcm990_camera_query_bus_param, - .set_bus_param = pcm990_camera_set_bus_param, }; /* Board I2C devices. */ @@ -433,10 +398,10 @@ static struct i2c_board_info __initdata pcm990_i2c_devices[] = { .platform_data = &pca9536_data, }, { I2C_BOARD_INFO("mt9v022", 0x48), - .platform_data = &iclink, /* With extender */ + .platform_data = &iclink[0], /* With extender */ }, { I2C_BOARD_INFO("mt9m001", 0x5d), - .platform_data = &iclink, /* With extender */ + .platform_data = &iclink[0], /* With extender */ }, }; #endif /* CONFIG_VIDEO_PXA27x ||CONFIG_VIDEO_PXA27x_MODULE */ diff --git a/trunk/arch/arm/plat-mxc/include/mach/mx3_camera.h b/trunk/arch/arm/plat-mxc/include/mach/mx3_camera.h deleted file mode 100644 index 36d7ff27b5e2..000000000000 --- a/trunk/arch/arm/plat-mxc/include/mach/mx3_camera.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * mx3_camera.h - i.MX3x camera driver header file - * - * Copyright (C) 2008, Guennadi Liakhovetski, DENX Software Engineering, - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _MX3_CAMERA_H_ -#define _MX3_CAMERA_H_ - -#include - -#define MX3_CAMERA_CLK_SRC 1 -#define MX3_CAMERA_EXT_VSYNC 2 -#define MX3_CAMERA_DP 4 -#define MX3_CAMERA_PCP 8 -#define MX3_CAMERA_HSP 0x10 -#define MX3_CAMERA_VSP 0x20 -#define MX3_CAMERA_DATAWIDTH_4 0x40 -#define MX3_CAMERA_DATAWIDTH_8 0x80 -#define MX3_CAMERA_DATAWIDTH_10 0x100 -#define MX3_CAMERA_DATAWIDTH_15 0x200 - -#define MX3_CAMERA_DATAWIDTH_MASK (MX3_CAMERA_DATAWIDTH_4 | MX3_CAMERA_DATAWIDTH_8 | \ - MX3_CAMERA_DATAWIDTH_10 | MX3_CAMERA_DATAWIDTH_15) - -/** - * struct mx3_camera_pdata - i.MX3x camera platform data - * @flags: MX3_CAMERA_* flags - * @mclk_10khz: master clock frequency in 10kHz units - * @dma_dev: IPU DMA device to match against in channel allocation - */ -struct mx3_camera_pdata { - unsigned long flags; - unsigned long mclk_10khz; - struct device *dma_dev; -}; - -#endif diff --git a/trunk/arch/avr32/kernel/process.c b/trunk/arch/avr32/kernel/process.c index 1bbe1da54869..43ae555ecb33 100644 --- a/trunk/arch/avr32/kernel/process.c +++ b/trunk/arch/avr32/kernel/process.c @@ -332,7 +332,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) asmlinkage void ret_from_fork(void); -int copy_thread(unsigned long clone_flags, unsigned long usp, +int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { diff --git a/trunk/arch/avr32/mm/fault.c b/trunk/arch/avr32/mm/fault.c index 62d4abbaa654..ce4e4296b954 100644 --- a/trunk/arch/avr32/mm/fault.c +++ b/trunk/arch/avr32/mm/fault.c @@ -250,3 +250,21 @@ asmlinkage void do_bus_error(unsigned long addr, int write_access, dump_dtlb(); die("Bus Error", regs, SIGKILL); } + +/* + * This functionality is currently not possible to implement because + * we're using segmentation to ensure a fixed mapping of the kernel + * virtual address space. + * + * It would be possible to implement this, but it would require us to + * disable segmentation at startup and load the kernel mappings into + * the TLB like any other pages. There will be lots of trickery to + * avoid recursive invocation of the TLB miss handler, though... + */ +#ifdef CONFIG_DEBUG_PAGEALLOC +void kernel_map_pages(struct page *page, int numpages, int enable) +{ + +} +EXPORT_SYMBOL(kernel_map_pages); +#endif diff --git a/trunk/arch/blackfin/kernel/process.c b/trunk/arch/blackfin/kernel/process.c index f49427293ca1..33e2e8993f7f 100644 --- a/trunk/arch/blackfin/kernel/process.c +++ b/trunk/arch/blackfin/kernel/process.c @@ -193,7 +193,7 @@ asmlinkage int bfin_clone(struct pt_regs *regs) } int -copy_thread(unsigned long clone_flags, +copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long topstk, struct task_struct *p, struct pt_regs *regs) { diff --git a/trunk/arch/blackfin/mm/sram-alloc.c b/trunk/arch/blackfin/mm/sram-alloc.c index 530d1393a232..834cab7438a8 100644 --- a/trunk/arch/blackfin/mm/sram-alloc.c +++ b/trunk/arch/blackfin/mm/sram-alloc.c @@ -854,6 +854,7 @@ static int __init sram_proc_init(void) printk(KERN_WARNING "unable to create /proc/sram\n"); return -1; } + ptr->owner = THIS_MODULE; ptr->read_proc = sram_proc_read; return 0; } diff --git a/trunk/arch/cris/arch-v10/kernel/process.c b/trunk/arch/cris/arch-v10/kernel/process.c index c4c69cf721e5..bd9b3ff63f6c 100644 --- a/trunk/arch/cris/arch-v10/kernel/process.c +++ b/trunk/arch/cris/arch-v10/kernel/process.c @@ -115,7 +115,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) */ asmlinkage void ret_from_fork(void); -int copy_thread(unsigned long clone_flags, unsigned long usp, +int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { diff --git a/trunk/arch/cris/arch-v10/kernel/time.c b/trunk/arch/cris/arch-v10/kernel/time.c index 2b73c7a5b649..c685ba4c3387 100644 --- a/trunk/arch/cris/arch-v10/kernel/time.c +++ b/trunk/arch/cris/arch-v10/kernel/time.c @@ -261,6 +261,7 @@ timer_interrupt(int irq, void *dev_id) static struct irqaction irq2 = { .handler = timer_interrupt, .flags = IRQF_SHARED | IRQF_DISABLED, + .mask = CPU_MASK_NONE, .name = "timer", }; diff --git a/trunk/arch/cris/arch-v32/kernel/process.c b/trunk/arch/cris/arch-v32/kernel/process.c index 120e7f796fea..ced5b725d9bd 100644 --- a/trunk/arch/cris/arch-v32/kernel/process.c +++ b/trunk/arch/cris/arch-v32/kernel/process.c @@ -131,7 +131,7 @@ kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) extern asmlinkage void ret_from_fork(void); int -copy_thread(unsigned long clone_flags, unsigned long usp, +copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { diff --git a/trunk/arch/cris/arch-v32/kernel/smp.c b/trunk/arch/cris/arch-v32/kernel/smp.c index f59a973c97ee..9dac17334640 100644 --- a/trunk/arch/cris/arch-v32/kernel/smp.c +++ b/trunk/arch/cris/arch-v32/kernel/smp.c @@ -65,6 +65,7 @@ static int send_ipi(int vector, int wait, cpumask_t cpu_mask); static struct irqaction irq_ipi = { .handler = crisv32_ipi_interrupt, .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, .name = "ipi", }; diff --git a/trunk/arch/cris/arch-v32/kernel/time.c b/trunk/arch/cris/arch-v32/kernel/time.c index 65633d0dab86..3a13dd6e0a9a 100644 --- a/trunk/arch/cris/arch-v32/kernel/time.c +++ b/trunk/arch/cris/arch-v32/kernel/time.c @@ -267,6 +267,7 @@ timer_interrupt(int irq, void *dev_id) static struct irqaction irq_timer = { .handler = timer_interrupt, .flags = IRQF_SHARED | IRQF_DISABLED, + .mask = CPU_MASK_NONE, .name = "timer" }; diff --git a/trunk/arch/cris/include/arch-v32/arch/spinlock.h b/trunk/arch/cris/include/arch-v32/arch/spinlock.h index 129756b96661..0d5709b983a1 100644 --- a/trunk/arch/cris/include/arch-v32/arch/spinlock.h +++ b/trunk/arch/cris/include/arch-v32/arch/spinlock.h @@ -121,8 +121,6 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) return 1; } -#define _raw_read_lock_flags(lock, flags) _raw_read_lock(lock) -#define _raw_write_lock_flags(lock, flags) _raw_write_lock(lock) #define _raw_spin_relax(lock) cpu_relax() #define _raw_read_relax(lock) cpu_relax() diff --git a/trunk/arch/frv/kernel/irq-mb93091.c b/trunk/arch/frv/kernel/irq-mb93091.c index 4dd9adaf115a..9e38f99bbab8 100644 --- a/trunk/arch/frv/kernel/irq-mb93091.c +++ b/trunk/arch/frv/kernel/irq-mb93091.c @@ -109,24 +109,28 @@ static struct irqaction fpga_irq[4] = { [0] = { .handler = fpga_interrupt, .flags = IRQF_DISABLED | IRQF_SHARED, + .mask = CPU_MASK_NONE, .name = "fpga.0", .dev_id = (void *) 0x0028UL, }, [1] = { .handler = fpga_interrupt, .flags = IRQF_DISABLED | IRQF_SHARED, + .mask = CPU_MASK_NONE, .name = "fpga.1", .dev_id = (void *) 0x0050UL, }, [2] = { .handler = fpga_interrupt, .flags = IRQF_DISABLED | IRQF_SHARED, + .mask = CPU_MASK_NONE, .name = "fpga.2", .dev_id = (void *) 0x1c00UL, }, [3] = { .handler = fpga_interrupt, .flags = IRQF_DISABLED | IRQF_SHARED, + .mask = CPU_MASK_NONE, .name = "fpga.3", .dev_id = (void *) 0x6386UL, } diff --git a/trunk/arch/frv/kernel/irq-mb93093.c b/trunk/arch/frv/kernel/irq-mb93093.c index e45209031873..3c2752ca9775 100644 --- a/trunk/arch/frv/kernel/irq-mb93093.c +++ b/trunk/arch/frv/kernel/irq-mb93093.c @@ -108,6 +108,7 @@ static struct irqaction fpga_irq[1] = { [0] = { .handler = fpga_interrupt, .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, .name = "fpga.0", .dev_id = (void *) 0x0700UL, } diff --git a/trunk/arch/frv/kernel/irq-mb93493.c b/trunk/arch/frv/kernel/irq-mb93493.c index ba55ecdfb245..7754c7338e4b 100644 --- a/trunk/arch/frv/kernel/irq-mb93493.c +++ b/trunk/arch/frv/kernel/irq-mb93493.c @@ -120,12 +120,14 @@ static struct irqaction mb93493_irq[2] = { [0] = { .handler = mb93493_interrupt, .flags = IRQF_DISABLED | IRQF_SHARED, + .mask = CPU_MASK_NONE, .name = "mb93493.0", .dev_id = (void *) __addr_MB93493_IQSR(0), }, [1] = { .handler = mb93493_interrupt, .flags = IRQF_DISABLED | IRQF_SHARED, + .mask = CPU_MASK_NONE, .name = "mb93493.1", .dev_id = (void *) __addr_MB93493_IQSR(1), } diff --git a/trunk/arch/frv/kernel/process.c b/trunk/arch/frv/kernel/process.c index 0de50df74970..9583a338e9d6 100644 --- a/trunk/arch/frv/kernel/process.c +++ b/trunk/arch/frv/kernel/process.c @@ -204,7 +204,7 @@ void prepare_to_copy(struct task_struct *tsk) /* * set up the kernel stack and exception frames for a new process */ -int copy_thread(unsigned long clone_flags, +int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long topstk, struct task_struct *p, struct pt_regs *regs) { diff --git a/trunk/arch/frv/kernel/time.c b/trunk/arch/frv/kernel/time.c index fb0ce7577225..69f6a4ef5d61 100644 --- a/trunk/arch/frv/kernel/time.c +++ b/trunk/arch/frv/kernel/time.c @@ -45,6 +45,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy); static struct irqaction timer_irq = { .handler = timer_interrupt, .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, .name = "timer", }; diff --git a/trunk/arch/h8300/kernel/process.c b/trunk/arch/h8300/kernel/process.c index e2f33d0f9969..a8ef654a5a0b 100644 --- a/trunk/arch/h8300/kernel/process.c +++ b/trunk/arch/h8300/kernel/process.c @@ -191,7 +191,7 @@ asmlinkage int h8300_clone(struct pt_regs *regs) } -int copy_thread(unsigned long clone_flags, +int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long topstk, struct task_struct * p, struct pt_regs * regs) { diff --git a/trunk/arch/h8300/kernel/timer/itu.c b/trunk/arch/h8300/kernel/timer/itu.c index 4883ba7103a8..d1c926596b08 100644 --- a/trunk/arch/h8300/kernel/timer/itu.c +++ b/trunk/arch/h8300/kernel/timer/itu.c @@ -60,6 +60,7 @@ static struct irqaction itu_irq = { .name = "itu", .handler = timer_interrupt, .flags = IRQF_DISABLED | IRQF_TIMER, + .mask = CPU_MASK_NONE, }; static const int __initdata divide_rate[] = {1, 2, 4, 8}; diff --git a/trunk/arch/h8300/kernel/timer/timer16.c b/trunk/arch/h8300/kernel/timer/timer16.c index 042dbb53f3fb..e14271b72119 100644 --- a/trunk/arch/h8300/kernel/timer/timer16.c +++ b/trunk/arch/h8300/kernel/timer/timer16.c @@ -55,6 +55,7 @@ static struct irqaction timer16_irq = { .name = "timer-16", .handler = timer_interrupt, .flags = IRQF_DISABLED | IRQF_TIMER, + .mask = CPU_MASK_NONE, }; static const int __initdata divide_rate[] = {1, 2, 4, 8}; diff --git a/trunk/arch/h8300/kernel/timer/timer8.c b/trunk/arch/h8300/kernel/timer/timer8.c index 38be0cabef0d..0556d7c7bea6 100644 --- a/trunk/arch/h8300/kernel/timer/timer8.c +++ b/trunk/arch/h8300/kernel/timer/timer8.c @@ -75,6 +75,7 @@ static struct irqaction timer8_irq = { .name = "timer-8", .handler = timer_interrupt, .flags = IRQF_DISABLED | IRQF_TIMER, + .mask = CPU_MASK_NONE, }; static const int __initdata divide_rate[] = {8, 64, 8192}; diff --git a/trunk/arch/h8300/kernel/timer/tpu.c b/trunk/arch/h8300/kernel/timer/tpu.c index ad383caae196..df7f453a9673 100644 --- a/trunk/arch/h8300/kernel/timer/tpu.c +++ b/trunk/arch/h8300/kernel/timer/tpu.c @@ -65,6 +65,7 @@ static struct irqaction tpu_irq = { .name = "tpu", .handler = timer_interrupt, .flags = IRQF_DISABLED | IRQF_TIMER, + .mask = CPU_MASK_NONE, }; const static int __initdata divide_rate[] = { diff --git a/trunk/arch/ia64/configs/generic_defconfig b/trunk/arch/ia64/configs/generic_defconfig index 75645495c2dd..a109db30ce55 100644 --- a/trunk/arch/ia64/configs/generic_defconfig +++ b/trunk/arch/ia64/configs/generic_defconfig @@ -193,6 +193,7 @@ CONFIG_BOUNCE=y CONFIG_NR_QUICK=1 CONFIG_VIRT_TO_BUS=y CONFIG_UNEVICTABLE_LRU=y +CONFIG_MMU_NOTIFIER=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_DISCONTIGMEM_ENABLE=y CONFIG_ARCH_FLATMEM_ENABLE=y @@ -415,6 +416,8 @@ CONFIG_SGI_IOC4=y # CONFIG_ENCLOSURE_SERVICES is not set CONFIG_SGI_XP=m # CONFIG_HP_ILO is not set +CONFIG_SGI_GRU=m +# CONFIG_SGI_GRU_DEBUG is not set # CONFIG_C2PORT is not set CONFIG_HAVE_IDE=y CONFIG_IDE=y diff --git a/trunk/arch/ia64/dig/Makefile b/trunk/arch/ia64/dig/Makefile index 2f7caddf093e..5c0283830bd6 100644 --- a/trunk/arch/ia64/dig/Makefile +++ b/trunk/arch/ia64/dig/Makefile @@ -7,8 +7,8 @@ obj-y := setup.o ifeq ($(CONFIG_DMAR), y) -obj-$(CONFIG_IA64_GENERIC) += machvec.o machvec_vtd.o +obj-$(CONFIG_IA64_GENERIC) += machvec.o machvec_vtd.o dig_vtd_iommu.o else obj-$(CONFIG_IA64_GENERIC) += machvec.o endif - +obj-$(CONFIG_IA64_DIG_VTD) += dig_vtd_iommu.o diff --git a/trunk/arch/ia64/dig/dig_vtd_iommu.c b/trunk/arch/ia64/dig/dig_vtd_iommu.c new file mode 100644 index 000000000000..1c8a079017a3 --- /dev/null +++ b/trunk/arch/ia64/dig/dig_vtd_iommu.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include + +void * +vtd_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, + gfp_t flags) +{ + return intel_alloc_coherent(dev, size, dma_handle, flags); +} +EXPORT_SYMBOL_GPL(vtd_alloc_coherent); + +void +vtd_free_coherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle) +{ + intel_free_coherent(dev, size, vaddr, dma_handle); +} +EXPORT_SYMBOL_GPL(vtd_free_coherent); + +dma_addr_t +vtd_map_single_attrs(struct device *dev, void *addr, size_t size, + int dir, struct dma_attrs *attrs) +{ + return intel_map_single(dev, (phys_addr_t)addr, size, dir); +} +EXPORT_SYMBOL_GPL(vtd_map_single_attrs); + +void +vtd_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, + int dir, struct dma_attrs *attrs) +{ + intel_unmap_single(dev, iova, size, dir); +} +EXPORT_SYMBOL_GPL(vtd_unmap_single_attrs); + +int +vtd_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, + int dir, struct dma_attrs *attrs) +{ + return intel_map_sg(dev, sglist, nents, dir); +} +EXPORT_SYMBOL_GPL(vtd_map_sg_attrs); + +void +vtd_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, + int nents, int dir, struct dma_attrs *attrs) +{ + intel_unmap_sg(dev, sglist, nents, dir); +} +EXPORT_SYMBOL_GPL(vtd_unmap_sg_attrs); + +int +vtd_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return 0; +} +EXPORT_SYMBOL_GPL(vtd_dma_mapping_error); diff --git a/trunk/arch/ia64/hp/common/hwsw_iommu.c b/trunk/arch/ia64/hp/common/hwsw_iommu.c index e4a80d82e3d8..2769dbfd03bf 100644 --- a/trunk/arch/ia64/hp/common/hwsw_iommu.c +++ b/trunk/arch/ia64/hp/common/hwsw_iommu.c @@ -13,34 +13,49 @@ */ #include -#include #include -#include -extern struct dma_map_ops sba_dma_ops, swiotlb_dma_ops; +#include /* swiotlb declarations & definitions: */ extern int swiotlb_late_init_with_default_size (size_t size); +/* hwiommu declarations & definitions: */ + +extern ia64_mv_dma_alloc_coherent sba_alloc_coherent; +extern ia64_mv_dma_free_coherent sba_free_coherent; +extern ia64_mv_dma_map_single_attrs sba_map_single_attrs; +extern ia64_mv_dma_unmap_single_attrs sba_unmap_single_attrs; +extern ia64_mv_dma_map_sg_attrs sba_map_sg_attrs; +extern ia64_mv_dma_unmap_sg_attrs sba_unmap_sg_attrs; +extern ia64_mv_dma_supported sba_dma_supported; +extern ia64_mv_dma_mapping_error sba_dma_mapping_error; + +#define hwiommu_alloc_coherent sba_alloc_coherent +#define hwiommu_free_coherent sba_free_coherent +#define hwiommu_map_single_attrs sba_map_single_attrs +#define hwiommu_unmap_single_attrs sba_unmap_single_attrs +#define hwiommu_map_sg_attrs sba_map_sg_attrs +#define hwiommu_unmap_sg_attrs sba_unmap_sg_attrs +#define hwiommu_dma_supported sba_dma_supported +#define hwiommu_dma_mapping_error sba_dma_mapping_error +#define hwiommu_sync_single_for_cpu machvec_dma_sync_single +#define hwiommu_sync_sg_for_cpu machvec_dma_sync_sg +#define hwiommu_sync_single_for_device machvec_dma_sync_single +#define hwiommu_sync_sg_for_device machvec_dma_sync_sg + + /* * Note: we need to make the determination of whether or not to use * the sw I/O TLB based purely on the device structure. Anything else * would be unreliable or would be too intrusive. */ -static inline int use_swiotlb(struct device *dev) +static inline int +use_swiotlb (struct device *dev) { - return dev && dev->dma_mask && - !sba_dma_ops.dma_supported(dev, *dev->dma_mask); + return dev && dev->dma_mask && !hwiommu_dma_supported(dev, *dev->dma_mask); } -struct dma_map_ops *hwsw_dma_get_ops(struct device *dev) -{ - if (use_swiotlb(dev)) - return &swiotlb_dma_ops; - return &sba_dma_ops; -} -EXPORT_SYMBOL(hwsw_dma_get_ops); - void __init hwsw_init (void) { @@ -56,3 +71,125 @@ hwsw_init (void) #endif } } + +void * +hwsw_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags) +{ + if (use_swiotlb(dev)) + return swiotlb_alloc_coherent(dev, size, dma_handle, flags); + else + return hwiommu_alloc_coherent(dev, size, dma_handle, flags); +} + +void +hwsw_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) +{ + if (use_swiotlb(dev)) + swiotlb_free_coherent(dev, size, vaddr, dma_handle); + else + hwiommu_free_coherent(dev, size, vaddr, dma_handle); +} + +dma_addr_t +hwsw_map_single_attrs(struct device *dev, void *addr, size_t size, int dir, + struct dma_attrs *attrs) +{ + if (use_swiotlb(dev)) + return swiotlb_map_single_attrs(dev, addr, size, dir, attrs); + else + return hwiommu_map_single_attrs(dev, addr, size, dir, attrs); +} +EXPORT_SYMBOL(hwsw_map_single_attrs); + +void +hwsw_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, + int dir, struct dma_attrs *attrs) +{ + if (use_swiotlb(dev)) + return swiotlb_unmap_single_attrs(dev, iova, size, dir, attrs); + else + return hwiommu_unmap_single_attrs(dev, iova, size, dir, attrs); +} +EXPORT_SYMBOL(hwsw_unmap_single_attrs); + +int +hwsw_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, + int dir, struct dma_attrs *attrs) +{ + if (use_swiotlb(dev)) + return swiotlb_map_sg_attrs(dev, sglist, nents, dir, attrs); + else + return hwiommu_map_sg_attrs(dev, sglist, nents, dir, attrs); +} +EXPORT_SYMBOL(hwsw_map_sg_attrs); + +void +hwsw_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, + int dir, struct dma_attrs *attrs) +{ + if (use_swiotlb(dev)) + return swiotlb_unmap_sg_attrs(dev, sglist, nents, dir, attrs); + else + return hwiommu_unmap_sg_attrs(dev, sglist, nents, dir, attrs); +} +EXPORT_SYMBOL(hwsw_unmap_sg_attrs); + +void +hwsw_sync_single_for_cpu (struct device *dev, dma_addr_t addr, size_t size, int dir) +{ + if (use_swiotlb(dev)) + swiotlb_sync_single_for_cpu(dev, addr, size, dir); + else + hwiommu_sync_single_for_cpu(dev, addr, size, dir); +} + +void +hwsw_sync_sg_for_cpu (struct device *dev, struct scatterlist *sg, int nelems, int dir) +{ + if (use_swiotlb(dev)) + swiotlb_sync_sg_for_cpu(dev, sg, nelems, dir); + else + hwiommu_sync_sg_for_cpu(dev, sg, nelems, dir); +} + +void +hwsw_sync_single_for_device (struct device *dev, dma_addr_t addr, size_t size, int dir) +{ + if (use_swiotlb(dev)) + swiotlb_sync_single_for_device(dev, addr, size, dir); + else + hwiommu_sync_single_for_device(dev, addr, size, dir); +} + +void +hwsw_sync_sg_for_device (struct device *dev, struct scatterlist *sg, int nelems, int dir) +{ + if (use_swiotlb(dev)) + swiotlb_sync_sg_for_device(dev, sg, nelems, dir); + else + hwiommu_sync_sg_for_device(dev, sg, nelems, dir); +} + +int +hwsw_dma_supported (struct device *dev, u64 mask) +{ + if (hwiommu_dma_supported(dev, mask)) + return 1; + return swiotlb_dma_supported(dev, mask); +} + +int +hwsw_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return hwiommu_dma_mapping_error(dev, dma_addr) || + swiotlb_dma_mapping_error(dev, dma_addr); +} + +EXPORT_SYMBOL(hwsw_dma_mapping_error); +EXPORT_SYMBOL(hwsw_dma_supported); +EXPORT_SYMBOL(hwsw_alloc_coherent); +EXPORT_SYMBOL(hwsw_free_coherent); +EXPORT_SYMBOL(hwsw_sync_single_for_cpu); +EXPORT_SYMBOL(hwsw_sync_single_for_device); +EXPORT_SYMBOL(hwsw_sync_sg_for_cpu); +EXPORT_SYMBOL(hwsw_sync_sg_for_device); diff --git a/trunk/arch/ia64/hp/common/sba_iommu.c b/trunk/arch/ia64/hp/common/sba_iommu.c index 56ceb68eb99d..6d5e6c5630e3 100644 --- a/trunk/arch/ia64/hp/common/sba_iommu.c +++ b/trunk/arch/ia64/hp/common/sba_iommu.c @@ -36,7 +36,6 @@ #include /* hweight64() */ #include #include -#include #include /* ia64_get_itc() */ #include @@ -909,13 +908,11 @@ sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt) * * See Documentation/PCI/PCI-DMA-mapping.txt */ -static dma_addr_t sba_map_page(struct device *dev, struct page *page, - unsigned long poff, size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) +dma_addr_t +sba_map_single_attrs(struct device *dev, void *addr, size_t size, int dir, + struct dma_attrs *attrs) { struct ioc *ioc; - void *addr = page_address(page) + poff; dma_addr_t iovp; dma_addr_t offset; u64 *pdir_start; @@ -993,14 +990,7 @@ static dma_addr_t sba_map_page(struct device *dev, struct page *page, #endif return SBA_IOVA(ioc, iovp, offset); } - -static dma_addr_t sba_map_single_attrs(struct device *dev, void *addr, - size_t size, enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - return sba_map_page(dev, virt_to_page(addr), - (unsigned long)addr & ~PAGE_MASK, size, dir, attrs); -} +EXPORT_SYMBOL(sba_map_single_attrs); #ifdef ENABLE_MARK_CLEAN static SBA_INLINE void @@ -1036,8 +1026,8 @@ sba_mark_clean(struct ioc *ioc, dma_addr_t iova, size_t size) * * See Documentation/PCI/PCI-DMA-mapping.txt */ -static void sba_unmap_page(struct device *dev, dma_addr_t iova, size_t size, - enum dma_data_direction dir, struct dma_attrs *attrs) +void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, + int dir, struct dma_attrs *attrs) { struct ioc *ioc; #if DELAYED_RESOURCE_CNT > 0 @@ -1104,12 +1094,7 @@ static void sba_unmap_page(struct device *dev, dma_addr_t iova, size_t size, spin_unlock_irqrestore(&ioc->res_lock, flags); #endif /* DELAYED_RESOURCE_CNT == 0 */ } - -void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, - enum dma_data_direction dir, struct dma_attrs *attrs) -{ - sba_unmap_page(dev, iova, size, dir, attrs); -} +EXPORT_SYMBOL(sba_unmap_single_attrs); /** * sba_alloc_coherent - allocate/map shared mem for DMA @@ -1119,7 +1104,7 @@ void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, * * See Documentation/PCI/PCI-DMA-mapping.txt */ -static void * +void * sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags) { struct ioc *ioc; @@ -1182,8 +1167,7 @@ sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp * * See Documentation/PCI/PCI-DMA-mapping.txt */ -static void sba_free_coherent (struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_handle) +void sba_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) { sba_unmap_single_attrs(dev, dma_handle, size, 0, NULL); free_pages((unsigned long) vaddr, get_order(size)); @@ -1438,9 +1422,8 @@ sba_coalesce_chunks(struct ioc *ioc, struct device *dev, * * See Documentation/PCI/PCI-DMA-mapping.txt */ -static int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, - int nents, enum dma_data_direction dir, - struct dma_attrs *attrs) +int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, + int dir, struct dma_attrs *attrs) { struct ioc *ioc; int coalesced, filled = 0; @@ -1519,6 +1502,7 @@ static int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, return filled; } +EXPORT_SYMBOL(sba_map_sg_attrs); /** * sba_unmap_sg_attrs - unmap Scatter/Gather list @@ -1530,9 +1514,8 @@ static int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, * * See Documentation/PCI/PCI-DMA-mapping.txt */ -static void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, - int nents, enum dma_data_direction dir, - struct dma_attrs *attrs) +void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, + int nents, int dir, struct dma_attrs *attrs) { #ifdef ASSERT_PDIR_SANITY struct ioc *ioc; @@ -1568,6 +1551,7 @@ static void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, #endif } +EXPORT_SYMBOL(sba_unmap_sg_attrs); /************************************************************** * @@ -2080,8 +2064,6 @@ static struct acpi_driver acpi_sba_ioc_driver = { }, }; -extern struct dma_map_ops swiotlb_dma_ops; - static int __init sba_init(void) { @@ -2095,7 +2077,6 @@ sba_init(void) * a successful kdump kernel boot is to use the swiotlb. */ if (is_kdump_kernel()) { - dma_ops = &swiotlb_dma_ops; if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0) panic("Unable to initialize software I/O TLB:" " Try machvec=dig boot option"); @@ -2111,7 +2092,6 @@ sba_init(void) * If we didn't find something sba_iommu can claim, we * need to setup the swiotlb and switch to the dig machvec. */ - dma_ops = &swiotlb_dma_ops; if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0) panic("Unable to find SBA IOMMU or initialize " "software I/O TLB: Try machvec=dig boot option"); @@ -2158,13 +2138,15 @@ nosbagart(char *str) return 1; } -static int sba_dma_supported (struct device *dev, u64 mask) +int +sba_dma_supported (struct device *dev, u64 mask) { /* make sure it's at least 32bit capable */ return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL); } -static int sba_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +int +sba_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } @@ -2194,22 +2176,7 @@ sba_page_override(char *str) __setup("sbapagesize=",sba_page_override); -struct dma_map_ops sba_dma_ops = { - .alloc_coherent = sba_alloc_coherent, - .free_coherent = sba_free_coherent, - .map_page = sba_map_page, - .unmap_page = sba_unmap_page, - .map_sg = sba_map_sg_attrs, - .unmap_sg = sba_unmap_sg_attrs, - .sync_single_for_cpu = machvec_dma_sync_single, - .sync_sg_for_cpu = machvec_dma_sync_sg, - .sync_single_for_device = machvec_dma_sync_single, - .sync_sg_for_device = machvec_dma_sync_sg, - .dma_supported = sba_dma_supported, - .mapping_error = sba_dma_mapping_error, -}; - -void sba_dma_init(void) -{ - dma_ops = &sba_dma_ops; -} +EXPORT_SYMBOL(sba_dma_mapping_error); +EXPORT_SYMBOL(sba_dma_supported); +EXPORT_SYMBOL(sba_alloc_coherent); +EXPORT_SYMBOL(sba_free_coherent); diff --git a/trunk/arch/ia64/hp/sim/simserial.c b/trunk/arch/ia64/hp/sim/simserial.c index 2bef5261d96d..24b1ad5334cb 100644 --- a/trunk/arch/ia64/hp/sim/simserial.c +++ b/trunk/arch/ia64/hp/sim/simserial.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -849,36 +848,38 @@ static int rs_open(struct tty_struct *tty, struct file * filp) * /proc fs routines.... */ -static inline void line_info(struct seq_file *m, struct serial_state *state) +static inline int line_info(char *buf, struct serial_state *state) { - seq_printf(m, "%d: uart:%s port:%lX irq:%d\n", + return sprintf(buf, "%d: uart:%s port:%lX irq:%d\n", state->line, uart_config[state->type].name, state->port, state->irq); } -static int rs_proc_show(struct seq_file *m, void *v) +static int rs_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { - int i; - - seq_printf(m, "simserinfo:1.0 driver:%s\n", serial_version); - for (i = 0; i < NR_PORTS; i++) - line_info(m, &rs_table[i]); - return 0; -} - -static int rs_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, rs_proc_show, NULL); + int i, len = 0, l; + off_t begin = 0; + + len += sprintf(page, "simserinfo:1.0 driver:%s\n", serial_version); + for (i = 0; i < NR_PORTS && len < 4000; i++) { + l = line_info(page + len, &rs_table[i]); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } + } + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (begin-off); + return ((count < begin+len-off) ? count : begin+len-off); } -static const struct file_operations rs_proc_fops = { - .owner = THIS_MODULE, - .open = rs_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /* * --------------------------------------------------------------------- * rs_init() and friends @@ -916,7 +917,7 @@ static const struct tty_operations hp_ops = { .start = rs_start, .hangup = rs_hangup, .wait_until_sent = rs_wait_until_sent, - .proc_fops = &rs_proc_fops, + .read_proc = rs_read_proc, }; /* diff --git a/trunk/arch/ia64/include/asm/dma-mapping.h b/trunk/arch/ia64/include/asm/dma-mapping.h index 36c0009dbece..1f912d927585 100644 --- a/trunk/arch/ia64/include/asm/dma-mapping.h +++ b/trunk/arch/ia64/include/asm/dma-mapping.h @@ -11,128 +11,99 @@ #define ARCH_HAS_DMA_GET_REQUIRED_MASK -extern struct dma_map_ops *dma_ops; +struct dma_mapping_ops { + int (*mapping_error)(struct device *dev, + dma_addr_t dma_addr); + void* (*alloc_coherent)(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp); + void (*free_coherent)(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle); + dma_addr_t (*map_single)(struct device *hwdev, unsigned long ptr, + size_t size, int direction); + void (*unmap_single)(struct device *dev, dma_addr_t addr, + size_t size, int direction); + void (*sync_single_for_cpu)(struct device *hwdev, + dma_addr_t dma_handle, size_t size, + int direction); + void (*sync_single_for_device)(struct device *hwdev, + dma_addr_t dma_handle, size_t size, + int direction); + void (*sync_single_range_for_cpu)(struct device *hwdev, + dma_addr_t dma_handle, unsigned long offset, + size_t size, int direction); + void (*sync_single_range_for_device)(struct device *hwdev, + dma_addr_t dma_handle, unsigned long offset, + size_t size, int direction); + void (*sync_sg_for_cpu)(struct device *hwdev, + struct scatterlist *sg, int nelems, + int direction); + void (*sync_sg_for_device)(struct device *hwdev, + struct scatterlist *sg, int nelems, + int direction); + int (*map_sg)(struct device *hwdev, struct scatterlist *sg, + int nents, int direction); + void (*unmap_sg)(struct device *hwdev, + struct scatterlist *sg, int nents, + int direction); + int (*dma_supported_op)(struct device *hwdev, u64 mask); + int is_phys; +}; + +extern struct dma_mapping_ops *dma_ops; extern struct ia64_machine_vector ia64_mv; extern void set_iommu_machvec(void); -extern void machvec_dma_sync_single(struct device *, dma_addr_t, size_t, - enum dma_data_direction); -extern void machvec_dma_sync_sg(struct device *, struct scatterlist *, int, - enum dma_data_direction); +#define dma_alloc_coherent(dev, size, handle, gfp) \ + platform_dma_alloc_coherent(dev, size, handle, (gfp) | GFP_DMA) -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *daddr, gfp_t gfp) +/* coherent mem. is cheap */ +static inline void * +dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle, + gfp_t flag) { - struct dma_map_ops *ops = platform_dma_get_ops(dev); - return ops->alloc_coherent(dev, size, daddr, gfp); + return dma_alloc_coherent(dev, size, dma_handle, flag); } - -static inline void dma_free_coherent(struct device *dev, size_t size, - void *caddr, dma_addr_t daddr) -{ - struct dma_map_ops *ops = platform_dma_get_ops(dev); - ops->free_coherent(dev, size, caddr, daddr); -} - -#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) -#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) - -static inline dma_addr_t dma_map_single_attrs(struct device *dev, - void *caddr, size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - struct dma_map_ops *ops = platform_dma_get_ops(dev); - return ops->map_page(dev, virt_to_page(caddr), - (unsigned long)caddr & ~PAGE_MASK, size, - dir, attrs); -} - -static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t daddr, - size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - struct dma_map_ops *ops = platform_dma_get_ops(dev); - ops->unmap_page(dev, daddr, size, dir, attrs); -} - -#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL) -#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL) - -static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl, - int nents, enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - struct dma_map_ops *ops = platform_dma_get_ops(dev); - return ops->map_sg(dev, sgl, nents, dir, attrs); -} - -static inline void dma_unmap_sg_attrs(struct device *dev, - struct scatterlist *sgl, int nents, - enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - struct dma_map_ops *ops = platform_dma_get_ops(dev); - ops->unmap_sg(dev, sgl, nents, dir, attrs); -} - -#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL) -#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL) - -static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t daddr, - size_t size, - enum dma_data_direction dir) +#define dma_free_coherent platform_dma_free_coherent +static inline void +dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr, + dma_addr_t dma_handle) { - struct dma_map_ops *ops = platform_dma_get_ops(dev); - ops->sync_single_for_cpu(dev, daddr, size, dir); + dma_free_coherent(dev, size, cpu_addr, dma_handle); } - -static inline void dma_sync_sg_for_cpu(struct device *dev, - struct scatterlist *sgl, - int nents, enum dma_data_direction dir) +#define dma_map_single_attrs platform_dma_map_single_attrs +static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, + size_t size, int dir) { - struct dma_map_ops *ops = platform_dma_get_ops(dev); - ops->sync_sg_for_cpu(dev, sgl, nents, dir); + return dma_map_single_attrs(dev, cpu_addr, size, dir, NULL); } - -static inline void dma_sync_single_for_device(struct device *dev, - dma_addr_t daddr, - size_t size, - enum dma_data_direction dir) +#define dma_map_sg_attrs platform_dma_map_sg_attrs +static inline int dma_map_sg(struct device *dev, struct scatterlist *sgl, + int nents, int dir) { - struct dma_map_ops *ops = platform_dma_get_ops(dev); - ops->sync_single_for_device(dev, daddr, size, dir); + return dma_map_sg_attrs(dev, sgl, nents, dir, NULL); } - -static inline void dma_sync_sg_for_device(struct device *dev, - struct scatterlist *sgl, - int nents, - enum dma_data_direction dir) +#define dma_unmap_single_attrs platform_dma_unmap_single_attrs +static inline void dma_unmap_single(struct device *dev, dma_addr_t cpu_addr, + size_t size, int dir) { - struct dma_map_ops *ops = platform_dma_get_ops(dev); - ops->sync_sg_for_device(dev, sgl, nents, dir); + return dma_unmap_single_attrs(dev, cpu_addr, size, dir, NULL); } - -static inline int dma_mapping_error(struct device *dev, dma_addr_t daddr) -{ - struct dma_map_ops *ops = platform_dma_get_ops(dev); - return ops->mapping_error(dev, daddr); -} - -static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, - size_t offset, size_t size, - enum dma_data_direction dir) +#define dma_unmap_sg_attrs platform_dma_unmap_sg_attrs +static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sgl, + int nents, int dir) { - struct dma_map_ops *ops = platform_dma_get_ops(dev); - return ops->map_page(dev, page, offset, size, dir, NULL); + return dma_unmap_sg_attrs(dev, sgl, nents, dir, NULL); } +#define dma_sync_single_for_cpu platform_dma_sync_single_for_cpu +#define dma_sync_sg_for_cpu platform_dma_sync_sg_for_cpu +#define dma_sync_single_for_device platform_dma_sync_single_for_device +#define dma_sync_sg_for_device platform_dma_sync_sg_for_device +#define dma_mapping_error platform_dma_mapping_error -static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, - size_t size, enum dma_data_direction dir) -{ - dma_unmap_single(dev, addr, size, dir); -} +#define dma_map_page(dev, pg, off, size, dir) \ + dma_map_single(dev, page_address(pg) + (off), (size), (dir)) +#define dma_unmap_page(dev, dma_addr, size, dir) \ + dma_unmap_single(dev, dma_addr, size, dir) /* * Rest of this file is part of the "Advanced DMA API". Use at your own risk. @@ -144,11 +115,7 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, #define dma_sync_single_range_for_device(dev, dma_handle, offset, size, dir) \ dma_sync_single_for_device(dev, dma_handle, size, dir) -static inline int dma_supported(struct device *dev, u64 mask) -{ - struct dma_map_ops *ops = platform_dma_get_ops(dev); - return ops->dma_supported(dev, mask); -} +#define dma_supported platform_dma_supported static inline int dma_set_mask (struct device *dev, u64 mask) @@ -174,4 +141,11 @@ dma_cache_sync (struct device *dev, void *vaddr, size_t size, #define dma_is_consistent(d, h) (1) /* all we do is coherent memory... */ +static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) +{ + return dma_ops; +} + + + #endif /* _ASM_IA64_DMA_MAPPING_H */ diff --git a/trunk/arch/ia64/include/asm/intrinsics.h b/trunk/arch/ia64/include/asm/intrinsics.h index 111ed5222892..c47830e26cb7 100644 --- a/trunk/arch/ia64/include/asm/intrinsics.h +++ b/trunk/arch/ia64/include/asm/intrinsics.h @@ -202,11 +202,7 @@ extern long ia64_cmpxchg_called_with_bad_pointer (void); #ifndef __ASSEMBLY__ #if defined(CONFIG_PARAVIRT) && defined(__KERNEL__) -#ifdef ASM_SUPPORTED -# define IA64_INTRINSIC_API(name) paravirt_ ## name -#else -# define IA64_INTRINSIC_API(name) pv_cpu_ops.name -#endif +#define IA64_INTRINSIC_API(name) pv_cpu_ops.name #define IA64_INTRINSIC_MACRO(name) paravirt_ ## name #else #define IA64_INTRINSIC_API(name) ia64_native_ ## name diff --git a/trunk/arch/ia64/include/asm/machvec.h b/trunk/arch/ia64/include/asm/machvec.h index 367d299d9938..fe87b2121707 100644 --- a/trunk/arch/ia64/include/asm/machvec.h +++ b/trunk/arch/ia64/include/asm/machvec.h @@ -11,6 +11,7 @@ #define _ASM_IA64_MACHVEC_H #include +#include /* forward declarations: */ struct device; @@ -44,8 +45,24 @@ typedef void ia64_mv_kernel_launch_event_t(void); /* DMA-mapping interface: */ typedef void ia64_mv_dma_init (void); +typedef void *ia64_mv_dma_alloc_coherent (struct device *, size_t, dma_addr_t *, gfp_t); +typedef void ia64_mv_dma_free_coherent (struct device *, size_t, void *, dma_addr_t); +typedef dma_addr_t ia64_mv_dma_map_single (struct device *, void *, size_t, int); +typedef void ia64_mv_dma_unmap_single (struct device *, dma_addr_t, size_t, int); +typedef int ia64_mv_dma_map_sg (struct device *, struct scatterlist *, int, int); +typedef void ia64_mv_dma_unmap_sg (struct device *, struct scatterlist *, int, int); +typedef void ia64_mv_dma_sync_single_for_cpu (struct device *, dma_addr_t, size_t, int); +typedef void ia64_mv_dma_sync_sg_for_cpu (struct device *, struct scatterlist *, int, int); +typedef void ia64_mv_dma_sync_single_for_device (struct device *, dma_addr_t, size_t, int); +typedef void ia64_mv_dma_sync_sg_for_device (struct device *, struct scatterlist *, int, int); +typedef int ia64_mv_dma_mapping_error(struct device *, dma_addr_t dma_addr); +typedef int ia64_mv_dma_supported (struct device *, u64); + +typedef dma_addr_t ia64_mv_dma_map_single_attrs (struct device *, void *, size_t, int, struct dma_attrs *); +typedef void ia64_mv_dma_unmap_single_attrs (struct device *, dma_addr_t, size_t, int, struct dma_attrs *); +typedef int ia64_mv_dma_map_sg_attrs (struct device *, struct scatterlist *, int, int, struct dma_attrs *); +typedef void ia64_mv_dma_unmap_sg_attrs (struct device *, struct scatterlist *, int, int, struct dma_attrs *); typedef u64 ia64_mv_dma_get_required_mask (struct device *); -typedef struct dma_map_ops *ia64_mv_dma_get_ops(struct device *); /* * WARNING: The legacy I/O space is _architected_. Platforms are @@ -97,6 +114,8 @@ machvec_noop_bus (struct pci_bus *bus) extern void machvec_setup (char **); extern void machvec_timer_interrupt (int, void *); +extern void machvec_dma_sync_single (struct device *, dma_addr_t, size_t, int); +extern void machvec_dma_sync_sg (struct device *, struct scatterlist *, int, int); extern void machvec_tlb_migrate_finish (struct mm_struct *); # if defined (CONFIG_IA64_HP_SIM) @@ -129,8 +148,19 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *); # define platform_global_tlb_purge ia64_mv.global_tlb_purge # define platform_tlb_migrate_finish ia64_mv.tlb_migrate_finish # define platform_dma_init ia64_mv.dma_init +# define platform_dma_alloc_coherent ia64_mv.dma_alloc_coherent +# define platform_dma_free_coherent ia64_mv.dma_free_coherent +# define platform_dma_map_single_attrs ia64_mv.dma_map_single_attrs +# define platform_dma_unmap_single_attrs ia64_mv.dma_unmap_single_attrs +# define platform_dma_map_sg_attrs ia64_mv.dma_map_sg_attrs +# define platform_dma_unmap_sg_attrs ia64_mv.dma_unmap_sg_attrs +# define platform_dma_sync_single_for_cpu ia64_mv.dma_sync_single_for_cpu +# define platform_dma_sync_sg_for_cpu ia64_mv.dma_sync_sg_for_cpu +# define platform_dma_sync_single_for_device ia64_mv.dma_sync_single_for_device +# define platform_dma_sync_sg_for_device ia64_mv.dma_sync_sg_for_device +# define platform_dma_mapping_error ia64_mv.dma_mapping_error +# define platform_dma_supported ia64_mv.dma_supported # define platform_dma_get_required_mask ia64_mv.dma_get_required_mask -# define platform_dma_get_ops ia64_mv.dma_get_ops # define platform_irq_to_vector ia64_mv.irq_to_vector # define platform_local_vector_to_irq ia64_mv.local_vector_to_irq # define platform_pci_get_legacy_mem ia64_mv.pci_get_legacy_mem @@ -173,8 +203,19 @@ struct ia64_machine_vector { ia64_mv_global_tlb_purge_t *global_tlb_purge; ia64_mv_tlb_migrate_finish_t *tlb_migrate_finish; ia64_mv_dma_init *dma_init; + ia64_mv_dma_alloc_coherent *dma_alloc_coherent; + ia64_mv_dma_free_coherent *dma_free_coherent; + ia64_mv_dma_map_single_attrs *dma_map_single_attrs; + ia64_mv_dma_unmap_single_attrs *dma_unmap_single_attrs; + ia64_mv_dma_map_sg_attrs *dma_map_sg_attrs; + ia64_mv_dma_unmap_sg_attrs *dma_unmap_sg_attrs; + ia64_mv_dma_sync_single_for_cpu *dma_sync_single_for_cpu; + ia64_mv_dma_sync_sg_for_cpu *dma_sync_sg_for_cpu; + ia64_mv_dma_sync_single_for_device *dma_sync_single_for_device; + ia64_mv_dma_sync_sg_for_device *dma_sync_sg_for_device; + ia64_mv_dma_mapping_error *dma_mapping_error; + ia64_mv_dma_supported *dma_supported; ia64_mv_dma_get_required_mask *dma_get_required_mask; - ia64_mv_dma_get_ops *dma_get_ops; ia64_mv_irq_to_vector *irq_to_vector; ia64_mv_local_vector_to_irq *local_vector_to_irq; ia64_mv_pci_get_legacy_mem_t *pci_get_legacy_mem; @@ -213,8 +254,19 @@ struct ia64_machine_vector { platform_global_tlb_purge, \ platform_tlb_migrate_finish, \ platform_dma_init, \ + platform_dma_alloc_coherent, \ + platform_dma_free_coherent, \ + platform_dma_map_single_attrs, \ + platform_dma_unmap_single_attrs, \ + platform_dma_map_sg_attrs, \ + platform_dma_unmap_sg_attrs, \ + platform_dma_sync_single_for_cpu, \ + platform_dma_sync_sg_for_cpu, \ + platform_dma_sync_single_for_device, \ + platform_dma_sync_sg_for_device, \ + platform_dma_mapping_error, \ + platform_dma_supported, \ platform_dma_get_required_mask, \ - platform_dma_get_ops, \ platform_irq_to_vector, \ platform_local_vector_to_irq, \ platform_pci_get_legacy_mem, \ @@ -250,9 +302,6 @@ extern void machvec_init_from_cmdline(const char *cmdline); # error Unknown configuration. Update arch/ia64/include/asm/machvec.h. # endif /* CONFIG_IA64_GENERIC */ -extern void swiotlb_dma_init(void); -extern struct dma_map_ops *dma_get_ops(struct device *); - /* * Define default versions so we can extend machvec for new platforms without having * to update the machvec files for all existing platforms. @@ -283,10 +332,43 @@ extern struct dma_map_ops *dma_get_ops(struct device *); # define platform_kernel_launch_event machvec_noop #endif #ifndef platform_dma_init -# define platform_dma_init swiotlb_dma_init +# define platform_dma_init swiotlb_init +#endif +#ifndef platform_dma_alloc_coherent +# define platform_dma_alloc_coherent swiotlb_alloc_coherent +#endif +#ifndef platform_dma_free_coherent +# define platform_dma_free_coherent swiotlb_free_coherent +#endif +#ifndef platform_dma_map_single_attrs +# define platform_dma_map_single_attrs swiotlb_map_single_attrs +#endif +#ifndef platform_dma_unmap_single_attrs +# define platform_dma_unmap_single_attrs swiotlb_unmap_single_attrs +#endif +#ifndef platform_dma_map_sg_attrs +# define platform_dma_map_sg_attrs swiotlb_map_sg_attrs +#endif +#ifndef platform_dma_unmap_sg_attrs +# define platform_dma_unmap_sg_attrs swiotlb_unmap_sg_attrs +#endif +#ifndef platform_dma_sync_single_for_cpu +# define platform_dma_sync_single_for_cpu swiotlb_sync_single_for_cpu +#endif +#ifndef platform_dma_sync_sg_for_cpu +# define platform_dma_sync_sg_for_cpu swiotlb_sync_sg_for_cpu +#endif +#ifndef platform_dma_sync_single_for_device +# define platform_dma_sync_single_for_device swiotlb_sync_single_for_device +#endif +#ifndef platform_dma_sync_sg_for_device +# define platform_dma_sync_sg_for_device swiotlb_sync_sg_for_device +#endif +#ifndef platform_dma_mapping_error +# define platform_dma_mapping_error swiotlb_dma_mapping_error #endif -#ifndef platform_dma_get_ops -# define platform_dma_get_ops dma_get_ops +#ifndef platform_dma_supported +# define platform_dma_supported swiotlb_dma_supported #endif #ifndef platform_dma_get_required_mask # define platform_dma_get_required_mask ia64_dma_get_required_mask diff --git a/trunk/arch/ia64/include/asm/machvec_dig_vtd.h b/trunk/arch/ia64/include/asm/machvec_dig_vtd.h index 6ab1de5c45ef..3400b561e711 100644 --- a/trunk/arch/ia64/include/asm/machvec_dig_vtd.h +++ b/trunk/arch/ia64/include/asm/machvec_dig_vtd.h @@ -2,6 +2,14 @@ #define _ASM_IA64_MACHVEC_DIG_VTD_h extern ia64_mv_setup_t dig_setup; +extern ia64_mv_dma_alloc_coherent vtd_alloc_coherent; +extern ia64_mv_dma_free_coherent vtd_free_coherent; +extern ia64_mv_dma_map_single_attrs vtd_map_single_attrs; +extern ia64_mv_dma_unmap_single_attrs vtd_unmap_single_attrs; +extern ia64_mv_dma_map_sg_attrs vtd_map_sg_attrs; +extern ia64_mv_dma_unmap_sg_attrs vtd_unmap_sg_attrs; +extern ia64_mv_dma_supported iommu_dma_supported; +extern ia64_mv_dma_mapping_error vtd_dma_mapping_error; extern ia64_mv_dma_init pci_iommu_alloc; /* @@ -14,5 +22,17 @@ extern ia64_mv_dma_init pci_iommu_alloc; #define platform_name "dig_vtd" #define platform_setup dig_setup #define platform_dma_init pci_iommu_alloc +#define platform_dma_alloc_coherent vtd_alloc_coherent +#define platform_dma_free_coherent vtd_free_coherent +#define platform_dma_map_single_attrs vtd_map_single_attrs +#define platform_dma_unmap_single_attrs vtd_unmap_single_attrs +#define platform_dma_map_sg_attrs vtd_map_sg_attrs +#define platform_dma_unmap_sg_attrs vtd_unmap_sg_attrs +#define platform_dma_sync_single_for_cpu machvec_dma_sync_single +#define platform_dma_sync_sg_for_cpu machvec_dma_sync_sg +#define platform_dma_sync_single_for_device machvec_dma_sync_single +#define platform_dma_sync_sg_for_device machvec_dma_sync_sg +#define platform_dma_supported iommu_dma_supported +#define platform_dma_mapping_error vtd_dma_mapping_error #endif /* _ASM_IA64_MACHVEC_DIG_VTD_h */ diff --git a/trunk/arch/ia64/include/asm/machvec_hpzx1.h b/trunk/arch/ia64/include/asm/machvec_hpzx1.h index 3bd83d78a412..2f57f5144b9f 100644 --- a/trunk/arch/ia64/include/asm/machvec_hpzx1.h +++ b/trunk/arch/ia64/include/asm/machvec_hpzx1.h @@ -2,7 +2,14 @@ #define _ASM_IA64_MACHVEC_HPZX1_h extern ia64_mv_setup_t dig_setup; -extern ia64_mv_dma_init sba_dma_init; +extern ia64_mv_dma_alloc_coherent sba_alloc_coherent; +extern ia64_mv_dma_free_coherent sba_free_coherent; +extern ia64_mv_dma_map_single_attrs sba_map_single_attrs; +extern ia64_mv_dma_unmap_single_attrs sba_unmap_single_attrs; +extern ia64_mv_dma_map_sg_attrs sba_map_sg_attrs; +extern ia64_mv_dma_unmap_sg_attrs sba_unmap_sg_attrs; +extern ia64_mv_dma_supported sba_dma_supported; +extern ia64_mv_dma_mapping_error sba_dma_mapping_error; /* * This stuff has dual use! @@ -13,6 +20,18 @@ extern ia64_mv_dma_init sba_dma_init; */ #define platform_name "hpzx1" #define platform_setup dig_setup -#define platform_dma_init sba_dma_init +#define platform_dma_init machvec_noop +#define platform_dma_alloc_coherent sba_alloc_coherent +#define platform_dma_free_coherent sba_free_coherent +#define platform_dma_map_single_attrs sba_map_single_attrs +#define platform_dma_unmap_single_attrs sba_unmap_single_attrs +#define platform_dma_map_sg_attrs sba_map_sg_attrs +#define platform_dma_unmap_sg_attrs sba_unmap_sg_attrs +#define platform_dma_sync_single_for_cpu machvec_dma_sync_single +#define platform_dma_sync_sg_for_cpu machvec_dma_sync_sg +#define platform_dma_sync_single_for_device machvec_dma_sync_single +#define platform_dma_sync_sg_for_device machvec_dma_sync_sg +#define platform_dma_supported sba_dma_supported +#define platform_dma_mapping_error sba_dma_mapping_error #endif /* _ASM_IA64_MACHVEC_HPZX1_h */ diff --git a/trunk/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h b/trunk/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h index 1091ac39740c..a842cdda827b 100644 --- a/trunk/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h +++ b/trunk/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h @@ -2,7 +2,18 @@ #define _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h extern ia64_mv_setup_t dig_setup; -extern ia64_mv_dma_get_ops hwsw_dma_get_ops; +extern ia64_mv_dma_alloc_coherent hwsw_alloc_coherent; +extern ia64_mv_dma_free_coherent hwsw_free_coherent; +extern ia64_mv_dma_map_single_attrs hwsw_map_single_attrs; +extern ia64_mv_dma_unmap_single_attrs hwsw_unmap_single_attrs; +extern ia64_mv_dma_map_sg_attrs hwsw_map_sg_attrs; +extern ia64_mv_dma_unmap_sg_attrs hwsw_unmap_sg_attrs; +extern ia64_mv_dma_supported hwsw_dma_supported; +extern ia64_mv_dma_mapping_error hwsw_dma_mapping_error; +extern ia64_mv_dma_sync_single_for_cpu hwsw_sync_single_for_cpu; +extern ia64_mv_dma_sync_sg_for_cpu hwsw_sync_sg_for_cpu; +extern ia64_mv_dma_sync_single_for_device hwsw_sync_single_for_device; +extern ia64_mv_dma_sync_sg_for_device hwsw_sync_sg_for_device; /* * This stuff has dual use! @@ -12,8 +23,20 @@ extern ia64_mv_dma_get_ops hwsw_dma_get_ops; * the macros are used directly. */ #define platform_name "hpzx1_swiotlb" + #define platform_setup dig_setup #define platform_dma_init machvec_noop -#define platform_dma_get_ops hwsw_dma_get_ops +#define platform_dma_alloc_coherent hwsw_alloc_coherent +#define platform_dma_free_coherent hwsw_free_coherent +#define platform_dma_map_single_attrs hwsw_map_single_attrs +#define platform_dma_unmap_single_attrs hwsw_unmap_single_attrs +#define platform_dma_map_sg_attrs hwsw_map_sg_attrs +#define platform_dma_unmap_sg_attrs hwsw_unmap_sg_attrs +#define platform_dma_supported hwsw_dma_supported +#define platform_dma_mapping_error hwsw_dma_mapping_error +#define platform_dma_sync_single_for_cpu hwsw_sync_single_for_cpu +#define platform_dma_sync_sg_for_cpu hwsw_sync_sg_for_cpu +#define platform_dma_sync_single_for_device hwsw_sync_single_for_device +#define platform_dma_sync_sg_for_device hwsw_sync_sg_for_device #endif /* _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h */ diff --git a/trunk/arch/ia64/include/asm/machvec_sn2.h b/trunk/arch/ia64/include/asm/machvec_sn2.h index f061a30aac42..f1a6e0d6dfa5 100644 --- a/trunk/arch/ia64/include/asm/machvec_sn2.h +++ b/trunk/arch/ia64/include/asm/machvec_sn2.h @@ -55,8 +55,19 @@ extern ia64_mv_readb_t __sn_readb_relaxed; extern ia64_mv_readw_t __sn_readw_relaxed; extern ia64_mv_readl_t __sn_readl_relaxed; extern ia64_mv_readq_t __sn_readq_relaxed; +extern ia64_mv_dma_alloc_coherent sn_dma_alloc_coherent; +extern ia64_mv_dma_free_coherent sn_dma_free_coherent; +extern ia64_mv_dma_map_single_attrs sn_dma_map_single_attrs; +extern ia64_mv_dma_unmap_single_attrs sn_dma_unmap_single_attrs; +extern ia64_mv_dma_map_sg_attrs sn_dma_map_sg_attrs; +extern ia64_mv_dma_unmap_sg_attrs sn_dma_unmap_sg_attrs; +extern ia64_mv_dma_sync_single_for_cpu sn_dma_sync_single_for_cpu; +extern ia64_mv_dma_sync_sg_for_cpu sn_dma_sync_sg_for_cpu; +extern ia64_mv_dma_sync_single_for_device sn_dma_sync_single_for_device; +extern ia64_mv_dma_sync_sg_for_device sn_dma_sync_sg_for_device; +extern ia64_mv_dma_mapping_error sn_dma_mapping_error; +extern ia64_mv_dma_supported sn_dma_supported; extern ia64_mv_dma_get_required_mask sn_dma_get_required_mask; -extern ia64_mv_dma_init sn_dma_init; extern ia64_mv_migrate_t sn_migrate; extern ia64_mv_kernel_launch_event_t sn_kernel_launch_event; extern ia64_mv_setup_msi_irq_t sn_setup_msi_irq; @@ -100,8 +111,20 @@ extern ia64_mv_pci_fixup_bus_t sn_pci_fixup_bus; #define platform_pci_get_legacy_mem sn_pci_get_legacy_mem #define platform_pci_legacy_read sn_pci_legacy_read #define platform_pci_legacy_write sn_pci_legacy_write +#define platform_dma_init machvec_noop +#define platform_dma_alloc_coherent sn_dma_alloc_coherent +#define platform_dma_free_coherent sn_dma_free_coherent +#define platform_dma_map_single_attrs sn_dma_map_single_attrs +#define platform_dma_unmap_single_attrs sn_dma_unmap_single_attrs +#define platform_dma_map_sg_attrs sn_dma_map_sg_attrs +#define platform_dma_unmap_sg_attrs sn_dma_unmap_sg_attrs +#define platform_dma_sync_single_for_cpu sn_dma_sync_single_for_cpu +#define platform_dma_sync_sg_for_cpu sn_dma_sync_sg_for_cpu +#define platform_dma_sync_single_for_device sn_dma_sync_single_for_device +#define platform_dma_sync_sg_for_device sn_dma_sync_sg_for_device +#define platform_dma_mapping_error sn_dma_mapping_error +#define platform_dma_supported sn_dma_supported #define platform_dma_get_required_mask sn_dma_get_required_mask -#define platform_dma_init sn_dma_init #define platform_migrate sn_migrate #define platform_kernel_launch_event sn_kernel_launch_event #ifdef CONFIG_PCI_MSI diff --git a/trunk/arch/ia64/include/asm/mmu_context.h b/trunk/arch/ia64/include/asm/mmu_context.h index 7f2a456603cb..040bc87db930 100644 --- a/trunk/arch/ia64/include/asm/mmu_context.h +++ b/trunk/arch/ia64/include/asm/mmu_context.h @@ -87,7 +87,7 @@ get_mmu_context (struct mm_struct *mm) /* re-check, now that we've got the lock: */ context = mm->context; if (context == 0) { - cpumask_clear(mm_cpumask(mm)); + cpus_clear(mm->cpu_vm_mask); if (ia64_ctx.next >= ia64_ctx.limit) { ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap, ia64_ctx.max_ctx, ia64_ctx.next); @@ -166,8 +166,8 @@ activate_context (struct mm_struct *mm) do { context = get_mmu_context(mm); - if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) - cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); + if (!cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) + cpu_set(smp_processor_id(), mm->cpu_vm_mask); reload_context(context); /* * in the unlikely event of a TLB-flush by another thread, diff --git a/trunk/arch/ia64/include/asm/module.h b/trunk/arch/ia64/include/asm/module.h index 908eaef42a08..d2da61e4c49b 100644 --- a/trunk/arch/ia64/include/asm/module.h +++ b/trunk/arch/ia64/include/asm/module.h @@ -16,12 +16,6 @@ struct mod_arch_specific { struct elf64_shdr *got; /* global offset table */ struct elf64_shdr *opd; /* official procedure descriptors */ struct elf64_shdr *unwind; /* unwind-table section */ -#ifdef CONFIG_PARAVIRT - struct elf64_shdr *paravirt_bundles; - /* paravirt_alt_bundle_patch table */ - struct elf64_shdr *paravirt_insts; - /* paravirt_alt_inst_patch table */ -#endif unsigned long gp; /* global-pointer for module */ void *core_unw_table; /* core unwind-table cookie returned by unwinder */ diff --git a/trunk/arch/ia64/include/asm/native/inst.h b/trunk/arch/ia64/include/asm/native/inst.h index d2d46efb3e6e..0a1026cca4fa 100644 --- a/trunk/arch/ia64/include/asm/native/inst.h +++ b/trunk/arch/ia64/include/asm/native/inst.h @@ -30,9 +30,6 @@ #define __paravirt_work_processed_syscall_target \ ia64_work_processed_syscall -#define paravirt_fsyscall_table ia64_native_fsyscall_table -#define paravirt_fsys_bubble_down ia64_native_fsys_bubble_down - #ifdef CONFIG_PARAVIRT_GUEST_ASM_CLOBBER_CHECK # define PARAVIRT_POISON 0xdeadbeefbaadf00d # define CLOBBER(clob) \ @@ -77,11 +74,6 @@ (pred) mov reg = psr \ CLOBBER(clob) -#define MOV_FROM_ITC(pred, pred_clob, reg, clob) \ -(pred) mov reg = ar.itc \ - CLOBBER(clob) \ - CLOBBER_PRED(pred_clob) - #define MOV_TO_IFA(reg, clob) \ mov cr.ifa = reg \ CLOBBER(clob) @@ -166,11 +158,6 @@ #define RSM_PSR_DT \ rsm psr.dt -#define RSM_PSR_BE_I(clob0, clob1) \ - rsm psr.be | psr.i \ - CLOBBER(clob0) \ - CLOBBER(clob1) - #define SSM_PSR_DT_AND_SRLZ_I \ ssm psr.dt \ ;; \ diff --git a/trunk/arch/ia64/include/asm/native/patchlist.h b/trunk/arch/ia64/include/asm/native/patchlist.h deleted file mode 100644 index be16ca9311bf..000000000000 --- a/trunk/arch/ia64/include/asm/native/patchlist.h +++ /dev/null @@ -1,38 +0,0 @@ -/****************************************************************************** - * arch/ia64/include/asm/native/inst.h - * - * Copyright (c) 2008 Isaku Yamahata - * VA Linux Systems Japan K.K. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define __paravirt_start_gate_fsyscall_patchlist \ - __ia64_native_start_gate_fsyscall_patchlist -#define __paravirt_end_gate_fsyscall_patchlist \ - __ia64_native_end_gate_fsyscall_patchlist -#define __paravirt_start_gate_brl_fsys_bubble_down_patchlist \ - __ia64_native_start_gate_brl_fsys_bubble_down_patchlist -#define __paravirt_end_gate_brl_fsys_bubble_down_patchlist \ - __ia64_native_end_gate_brl_fsys_bubble_down_patchlist -#define __paravirt_start_gate_vtop_patchlist \ - __ia64_native_start_gate_vtop_patchlist -#define __paravirt_end_gate_vtop_patchlist \ - __ia64_native_end_gate_vtop_patchlist -#define __paravirt_start_gate_mckinley_e9_patchlist \ - __ia64_native_start_gate_mckinley_e9_patchlist -#define __paravirt_end_gate_mckinley_e9_patchlist \ - __ia64_native_end_gate_mckinley_e9_patchlist diff --git a/trunk/arch/ia64/include/asm/native/pvchk_inst.h b/trunk/arch/ia64/include/asm/native/pvchk_inst.h index 8d72962ec838..b8e6eb1090d7 100644 --- a/trunk/arch/ia64/include/asm/native/pvchk_inst.h +++ b/trunk/arch/ia64/include/asm/native/pvchk_inst.h @@ -180,11 +180,6 @@ IS_PRED_IN(pred) \ IS_RREG_OUT(reg) \ IS_RREG_CLOB(clob) -#define MOV_FROM_ITC(pred, pred_clob, reg, clob) \ - IS_PRED_IN(pred) \ - IS_PRED_CLOB(pred_clob) \ - IS_RREG_OUT(reg) \ - IS_RREG_CLOB(clob) #define MOV_TO_IFA(reg, clob) \ IS_RREG_IN(reg) \ IS_RREG_CLOB(clob) @@ -251,9 +246,6 @@ IS_RREG_CLOB(clob2) #define RSM_PSR_DT \ nop 0 -#define RSM_PSR_BE_I(clob0, clob1) \ - IS_RREG_CLOB(clob0) \ - IS_RREG_CLOB(clob1) #define SSM_PSR_DT_AND_SRLZ_I \ nop 0 #define BSW_0(clob0, clob1, clob2) \ diff --git a/trunk/arch/ia64/include/asm/paravirt.h b/trunk/arch/ia64/include/asm/paravirt.h index 2eb0a981a09a..2bf3636473fe 100644 --- a/trunk/arch/ia64/include/asm/paravirt.h +++ b/trunk/arch/ia64/include/asm/paravirt.h @@ -22,56 +22,6 @@ #ifndef __ASM_PARAVIRT_H #define __ASM_PARAVIRT_H -#ifndef __ASSEMBLY__ -/****************************************************************************** - * fsys related addresses - */ -struct pv_fsys_data { - unsigned long *fsyscall_table; - void *fsys_bubble_down; -}; - -extern struct pv_fsys_data pv_fsys_data; - -unsigned long *paravirt_get_fsyscall_table(void); -char *paravirt_get_fsys_bubble_down(void); - -/****************************************************************************** - * patchlist addresses for gate page - */ -enum pv_gate_patchlist { - PV_GATE_START_FSYSCALL, - PV_GATE_END_FSYSCALL, - - PV_GATE_START_BRL_FSYS_BUBBLE_DOWN, - PV_GATE_END_BRL_FSYS_BUBBLE_DOWN, - - PV_GATE_START_VTOP, - PV_GATE_END_VTOP, - - PV_GATE_START_MCKINLEY_E9, - PV_GATE_END_MCKINLEY_E9, -}; - -struct pv_patchdata { - unsigned long start_fsyscall_patchlist; - unsigned long end_fsyscall_patchlist; - unsigned long start_brl_fsys_bubble_down_patchlist; - unsigned long end_brl_fsys_bubble_down_patchlist; - unsigned long start_vtop_patchlist; - unsigned long end_vtop_patchlist; - unsigned long start_mckinley_e9_patchlist; - unsigned long end_mckinley_e9_patchlist; - - void *gate_section; -}; - -extern struct pv_patchdata pv_patchdata; - -unsigned long paravirt_get_gate_patchlist(enum pv_gate_patchlist type); -void *paravirt_get_gate_section(void); -#endif - #ifdef CONFIG_PARAVIRT_GUEST #define PARAVIRT_HYPERVISOR_TYPE_DEFAULT 0 @@ -118,14 +68,6 @@ struct pv_init_ops { int (*arch_setup_nomca)(void); void (*post_smp_prepare_boot_cpu)(void); - -#ifdef ASM_SUPPORTED - unsigned long (*patch_bundle)(void *sbundle, void *ebundle, - unsigned long type); - unsigned long (*patch_inst)(unsigned long stag, unsigned long etag, - unsigned long type); -#endif - void (*patch_branch)(unsigned long tag, unsigned long type); }; extern struct pv_init_ops pv_init_ops; @@ -268,8 +210,6 @@ struct pv_time_ops { int (*do_steal_accounting)(unsigned long *new_itm); void (*clocksource_resume)(void); - - unsigned long long (*sched_clock)(void); }; extern struct pv_time_ops pv_time_ops; @@ -287,11 +227,6 @@ paravirt_do_steal_accounting(unsigned long *new_itm) return pv_time_ops.do_steal_accounting(new_itm); } -static inline unsigned long long paravirt_sched_clock(void) -{ - return pv_time_ops.sched_clock(); -} - #endif /* !__ASSEMBLY__ */ #else diff --git a/trunk/arch/ia64/include/asm/paravirt_patch.h b/trunk/arch/ia64/include/asm/paravirt_patch.h deleted file mode 100644 index 128ff5db6e67..000000000000 --- a/trunk/arch/ia64/include/asm/paravirt_patch.h +++ /dev/null @@ -1,143 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2008 Isaku Yamahata - * VA Linux Systems Japan K.K. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ASM_PARAVIRT_PATCH_H -#define __ASM_PARAVIRT_PATCH_H - -#ifdef __ASSEMBLY__ - - .section .paravirt_branches, "a" - .previous -#define PARAVIRT_PATCH_SITE_BR(type) \ - { \ - [1:] ; \ - br.cond.sptk.many 2f ; \ - nop.b 0 ; \ - nop.b 0;; ; \ - } ; \ - 2: \ - .xdata8 ".paravirt_branches", 1b, type - -#else - -#include -#include - -/* for binary patch */ -struct paravirt_patch_site_bundle { - void *sbundle; - void *ebundle; - unsigned long type; -}; - -/* label means the beginning of new bundle */ -#define paravirt_alt_bundle(instr, privop) \ - "\t998:\n" \ - "\t" instr "\n" \ - "\t999:\n" \ - "\t.pushsection .paravirt_bundles, \"a\"\n" \ - "\t.popsection\n" \ - "\t.xdata8 \".paravirt_bundles\", 998b, 999b, " \ - __stringify(privop) "\n" - - -struct paravirt_patch_bundle_elem { - const void *sbundle; - const void *ebundle; - unsigned long type; -}; - - -struct paravirt_patch_site_inst { - unsigned long stag; - unsigned long etag; - unsigned long type; -}; - -#define paravirt_alt_inst(instr, privop) \ - "\t[998:]\n" \ - "\t" instr "\n" \ - "\t[999:]\n" \ - "\t.pushsection .paravirt_insts, \"a\"\n" \ - "\t.popsection\n" \ - "\t.xdata8 \".paravirt_insts\", 998b, 999b, " \ - __stringify(privop) "\n" - -struct paravirt_patch_site_branch { - unsigned long tag; - unsigned long type; -}; - -struct paravirt_patch_branch_target { - const void *entry; - unsigned long type; -}; - -void -__paravirt_patch_apply_branch( - unsigned long tag, unsigned long type, - const struct paravirt_patch_branch_target *entries, - unsigned int nr_entries); - -void -paravirt_patch_reloc_br(unsigned long tag, const void *target); - -void -paravirt_patch_reloc_brl(unsigned long tag, const void *target); - - -#if defined(ASM_SUPPORTED) && defined(CONFIG_PARAVIRT) -unsigned long -ia64_native_patch_bundle(void *sbundle, void *ebundle, unsigned long type); - -unsigned long -__paravirt_patch_apply_bundle(void *sbundle, void *ebundle, unsigned long type, - const struct paravirt_patch_bundle_elem *elems, - unsigned long nelems, - const struct paravirt_patch_bundle_elem **found); - -void -paravirt_patch_apply_bundle(const struct paravirt_patch_site_bundle *start, - const struct paravirt_patch_site_bundle *end); - -void -paravirt_patch_apply_inst(const struct paravirt_patch_site_inst *start, - const struct paravirt_patch_site_inst *end); - -void paravirt_patch_apply(void); -#else -#define paravirt_patch_apply_bundle(start, end) do { } while (0) -#define paravirt_patch_apply_inst(start, end) do { } while (0) -#define paravirt_patch_apply() do { } while (0) -#endif - -#endif /* !__ASSEMBLEY__ */ - -#endif /* __ASM_PARAVIRT_PATCH_H */ - -/* - * Local variables: - * mode: C - * c-set-style: "linux" - * c-basic-offset: 8 - * tab-width: 8 - * indent-tabs-mode: t - * End: - */ diff --git a/trunk/arch/ia64/include/asm/paravirt_privop.h b/trunk/arch/ia64/include/asm/paravirt_privop.h index 3d2951130b5f..33c8e55f5775 100644 --- a/trunk/arch/ia64/include/asm/paravirt_privop.h +++ b/trunk/arch/ia64/include/asm/paravirt_privop.h @@ -33,7 +33,7 @@ */ struct pv_cpu_ops { - void (*fc)(void *addr); + void (*fc)(unsigned long addr); unsigned long (*thash)(unsigned long addr); unsigned long (*get_cpuid)(int index); unsigned long (*get_pmd)(int index); @@ -60,18 +60,12 @@ extern unsigned long ia64_native_getreg_func(int regnum); /* Instructions paravirtualized for performance */ /************************************************/ -#ifndef ASM_SUPPORTED -#define paravirt_ssm_i() pv_cpu_ops.ssm_i() -#define paravirt_rsm_i() pv_cpu_ops.rsm_i() -#define __paravirt_getreg() pv_cpu_ops.getreg() -#endif - /* mask for ia64_native_ssm/rsm() must be constant.("i" constraing). * static inline function doesn't satisfy it. */ #define paravirt_ssm(mask) \ do { \ if ((mask) == IA64_PSR_I) \ - paravirt_ssm_i(); \ + pv_cpu_ops.ssm_i(); \ else \ ia64_native_ssm(mask); \ } while (0) @@ -79,7 +73,7 @@ extern unsigned long ia64_native_getreg_func(int regnum); #define paravirt_rsm(mask) \ do { \ if ((mask) == IA64_PSR_I) \ - paravirt_rsm_i(); \ + pv_cpu_ops.rsm_i(); \ else \ ia64_native_rsm(mask); \ } while (0) @@ -92,7 +86,7 @@ extern unsigned long ia64_native_getreg_func(int regnum); if ((reg) == _IA64_REG_IP) \ res = ia64_native_getreg(_IA64_REG_IP); \ else \ - res = __paravirt_getreg(reg); \ + res = pv_cpu_ops.getreg(reg); \ res; \ }) @@ -118,12 +112,6 @@ void paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch); #endif /* CONFIG_PARAVIRT */ -#if defined(CONFIG_PARAVIRT) && defined(ASM_SUPPORTED) -#define paravirt_dv_serialize_data() ia64_dv_serialize_data() -#else -#define paravirt_dv_serialize_data() /* nothing */ -#endif - /* these routines utilize privilege-sensitive or performance-sensitive * privileged instructions so the code must be replaced with * paravirtualized versions */ @@ -133,349 +121,4 @@ void paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch); IA64_PARAVIRT_ASM_FUNC(work_processed_syscall) #define ia64_leave_kernel IA64_PARAVIRT_ASM_FUNC(leave_kernel) - -#if defined(CONFIG_PARAVIRT) -/****************************************************************************** - * binary patching infrastructure - */ -#define PARAVIRT_PATCH_TYPE_FC 1 -#define PARAVIRT_PATCH_TYPE_THASH 2 -#define PARAVIRT_PATCH_TYPE_GET_CPUID 3 -#define PARAVIRT_PATCH_TYPE_GET_PMD 4 -#define PARAVIRT_PATCH_TYPE_PTCGA 5 -#define PARAVIRT_PATCH_TYPE_GET_RR 6 -#define PARAVIRT_PATCH_TYPE_SET_RR 7 -#define PARAVIRT_PATCH_TYPE_SET_RR0_TO_RR4 8 -#define PARAVIRT_PATCH_TYPE_SSM_I 9 -#define PARAVIRT_PATCH_TYPE_RSM_I 10 -#define PARAVIRT_PATCH_TYPE_GET_PSR_I 11 -#define PARAVIRT_PATCH_TYPE_INTRIN_LOCAL_IRQ_RESTORE 12 - -/* PARAVIRT_PATY_TYPE_[GS]ETREG + _IA64_REG_xxx */ -#define PARAVIRT_PATCH_TYPE_GETREG 0x10000000 -#define PARAVIRT_PATCH_TYPE_SETREG 0x20000000 - -/* - * struct task_struct* (*ia64_switch_to)(void* next_task); - * void *ia64_leave_syscall; - * void *ia64_work_processed_syscall - * void *ia64_leave_kernel; - */ - -#define PARAVIRT_PATCH_TYPE_BR_START 0x30000000 -#define PARAVIRT_PATCH_TYPE_BR_SWITCH_TO \ - (PARAVIRT_PATCH_TYPE_BR_START + 0) -#define PARAVIRT_PATCH_TYPE_BR_LEAVE_SYSCALL \ - (PARAVIRT_PATCH_TYPE_BR_START + 1) -#define PARAVIRT_PATCH_TYPE_BR_WORK_PROCESSED_SYSCALL \ - (PARAVIRT_PATCH_TYPE_BR_START + 2) -#define PARAVIRT_PATCH_TYPE_BR_LEAVE_KERNEL \ - (PARAVIRT_PATCH_TYPE_BR_START + 3) - -#ifdef ASM_SUPPORTED -#include - -/* - * pv_cpu_ops calling stub. - * normal function call convension can't be written by gcc - * inline assembly. - * - * from the caller's point of view, - * the following registers will be clobbered. - * r2, r3 - * r8-r15 - * r16, r17 - * b6, b7 - * p6-p15 - * ar.ccv - * - * from the callee's point of view , - * the following registers can be used. - * r2, r3: scratch - * r8: scratch, input argument0 and return value - * r0-r15: scratch, input argument1-5 - * b6: return pointer - * b7: scratch - * p6-p15: scratch - * ar.ccv: scratch - * - * other registers must not be changed. especially - * b0: rp: preserved. gcc ignores b0 in clobbered register. - * r16: saved gp - */ -/* 5 bundles */ -#define __PARAVIRT_BR \ - ";;\n" \ - "{ .mlx\n" \ - "nop 0\n" \ - "movl r2 = %[op_addr]\n"/* get function pointer address */ \ - ";;\n" \ - "}\n" \ - "1:\n" \ - "{ .mii\n" \ - "ld8 r2 = [r2]\n" /* load function descriptor address */ \ - "mov r17 = ip\n" /* get ip to calc return address */ \ - "mov r16 = gp\n" /* save gp */ \ - ";;\n" \ - "}\n" \ - "{ .mii\n" \ - "ld8 r3 = [r2], 8\n" /* load entry address */ \ - "adds r17 = 1f - 1b, r17\n" /* calculate return address */ \ - ";;\n" \ - "mov b7 = r3\n" /* set entry address */ \ - "}\n" \ - "{ .mib\n" \ - "ld8 gp = [r2]\n" /* load gp value */ \ - "mov b6 = r17\n" /* set return address */ \ - "br.cond.sptk.few b7\n" /* intrinsics are very short isns */ \ - "}\n" \ - "1:\n" \ - "{ .mii\n" \ - "mov gp = r16\n" /* restore gp value */ \ - "nop 0\n" \ - "nop 0\n" \ - ";;\n" \ - "}\n" - -#define PARAVIRT_OP(op) \ - [op_addr] "i"(&pv_cpu_ops.op) - -#define PARAVIRT_TYPE(type) \ - PARAVIRT_PATCH_TYPE_ ## type - -#define PARAVIRT_REG_CLOBBERS0 \ - "r2", "r3", /*"r8",*/ "r9", "r10", "r11", "r14", \ - "r15", "r16", "r17" - -#define PARAVIRT_REG_CLOBBERS1 \ - "r2","r3", /*"r8",*/ "r9", "r10", "r11", "r14", \ - "r15", "r16", "r17" - -#define PARAVIRT_REG_CLOBBERS2 \ - "r2", "r3", /*"r8", "r9",*/ "r10", "r11", "r14", \ - "r15", "r16", "r17" - -#define PARAVIRT_REG_CLOBBERS5 \ - "r2", "r3", /*"r8", "r9", "r10", "r11", "r14",*/ \ - "r15", "r16", "r17" - -#define PARAVIRT_BR_CLOBBERS \ - "b6", "b7" - -#define PARAVIRT_PR_CLOBBERS \ - "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15" - -#define PARAVIRT_AR_CLOBBERS \ - "ar.ccv" - -#define PARAVIRT_CLOBBERS0 \ - PARAVIRT_REG_CLOBBERS0, \ - PARAVIRT_BR_CLOBBERS, \ - PARAVIRT_PR_CLOBBERS, \ - PARAVIRT_AR_CLOBBERS, \ - "memory" - -#define PARAVIRT_CLOBBERS1 \ - PARAVIRT_REG_CLOBBERS1, \ - PARAVIRT_BR_CLOBBERS, \ - PARAVIRT_PR_CLOBBERS, \ - PARAVIRT_AR_CLOBBERS, \ - "memory" - -#define PARAVIRT_CLOBBERS2 \ - PARAVIRT_REG_CLOBBERS2, \ - PARAVIRT_BR_CLOBBERS, \ - PARAVIRT_PR_CLOBBERS, \ - PARAVIRT_AR_CLOBBERS, \ - "memory" - -#define PARAVIRT_CLOBBERS5 \ - PARAVIRT_REG_CLOBBERS5, \ - PARAVIRT_BR_CLOBBERS, \ - PARAVIRT_PR_CLOBBERS, \ - PARAVIRT_AR_CLOBBERS, \ - "memory" - -#define PARAVIRT_BR0(op, type) \ - register unsigned long ia64_clobber asm ("r8"); \ - asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \ - PARAVIRT_TYPE(type)) \ - : "=r"(ia64_clobber) \ - : PARAVIRT_OP(op) \ - : PARAVIRT_CLOBBERS0) - -#define PARAVIRT_BR0_RET(op, type) \ - register unsigned long ia64_intri_res asm ("r8"); \ - asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \ - PARAVIRT_TYPE(type)) \ - : "=r"(ia64_intri_res) \ - : PARAVIRT_OP(op) \ - : PARAVIRT_CLOBBERS0) - -#define PARAVIRT_BR1(op, type, arg1) \ - register unsigned long __##arg1 asm ("r8") = arg1; \ - register unsigned long ia64_clobber asm ("r8"); \ - asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \ - PARAVIRT_TYPE(type)) \ - : "=r"(ia64_clobber) \ - : PARAVIRT_OP(op), "0"(__##arg1) \ - : PARAVIRT_CLOBBERS1) - -#define PARAVIRT_BR1_RET(op, type, arg1) \ - register unsigned long ia64_intri_res asm ("r8"); \ - register unsigned long __##arg1 asm ("r8") = arg1; \ - asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \ - PARAVIRT_TYPE(type)) \ - : "=r"(ia64_intri_res) \ - : PARAVIRT_OP(op), "0"(__##arg1) \ - : PARAVIRT_CLOBBERS1) - -#define PARAVIRT_BR1_VOID(op, type, arg1) \ - register void *__##arg1 asm ("r8") = arg1; \ - register unsigned long ia64_clobber asm ("r8"); \ - asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \ - PARAVIRT_TYPE(type)) \ - : "=r"(ia64_clobber) \ - : PARAVIRT_OP(op), "0"(__##arg1) \ - : PARAVIRT_CLOBBERS1) - -#define PARAVIRT_BR2(op, type, arg1, arg2) \ - register unsigned long __##arg1 asm ("r8") = arg1; \ - register unsigned long __##arg2 asm ("r9") = arg2; \ - register unsigned long ia64_clobber1 asm ("r8"); \ - register unsigned long ia64_clobber2 asm ("r9"); \ - asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \ - PARAVIRT_TYPE(type)) \ - : "=r"(ia64_clobber1), "=r"(ia64_clobber2) \ - : PARAVIRT_OP(op), "0"(__##arg1), "1"(__##arg2) \ - : PARAVIRT_CLOBBERS2) - - -#define PARAVIRT_DEFINE_CPU_OP0(op, type) \ - static inline void \ - paravirt_ ## op (void) \ - { \ - PARAVIRT_BR0(op, type); \ - } - -#define PARAVIRT_DEFINE_CPU_OP0_RET(op, type) \ - static inline unsigned long \ - paravirt_ ## op (void) \ - { \ - PARAVIRT_BR0_RET(op, type); \ - return ia64_intri_res; \ - } - -#define PARAVIRT_DEFINE_CPU_OP1_VOID(op, type) \ - static inline void \ - paravirt_ ## op (void *arg1) \ - { \ - PARAVIRT_BR1_VOID(op, type, arg1); \ - } - -#define PARAVIRT_DEFINE_CPU_OP1(op, type) \ - static inline void \ - paravirt_ ## op (unsigned long arg1) \ - { \ - PARAVIRT_BR1(op, type, arg1); \ - } - -#define PARAVIRT_DEFINE_CPU_OP1_RET(op, type) \ - static inline unsigned long \ - paravirt_ ## op (unsigned long arg1) \ - { \ - PARAVIRT_BR1_RET(op, type, arg1); \ - return ia64_intri_res; \ - } - -#define PARAVIRT_DEFINE_CPU_OP2(op, type) \ - static inline void \ - paravirt_ ## op (unsigned long arg1, \ - unsigned long arg2) \ - { \ - PARAVIRT_BR2(op, type, arg1, arg2); \ - } - - -PARAVIRT_DEFINE_CPU_OP1_VOID(fc, FC); -PARAVIRT_DEFINE_CPU_OP1_RET(thash, THASH) -PARAVIRT_DEFINE_CPU_OP1_RET(get_cpuid, GET_CPUID) -PARAVIRT_DEFINE_CPU_OP1_RET(get_pmd, GET_PMD) -PARAVIRT_DEFINE_CPU_OP2(ptcga, PTCGA) -PARAVIRT_DEFINE_CPU_OP1_RET(get_rr, GET_RR) -PARAVIRT_DEFINE_CPU_OP2(set_rr, SET_RR) -PARAVIRT_DEFINE_CPU_OP0(ssm_i, SSM_I) -PARAVIRT_DEFINE_CPU_OP0(rsm_i, RSM_I) -PARAVIRT_DEFINE_CPU_OP0_RET(get_psr_i, GET_PSR_I) -PARAVIRT_DEFINE_CPU_OP1(intrin_local_irq_restore, INTRIN_LOCAL_IRQ_RESTORE) - -static inline void -paravirt_set_rr0_to_rr4(unsigned long val0, unsigned long val1, - unsigned long val2, unsigned long val3, - unsigned long val4) -{ - register unsigned long __val0 asm ("r8") = val0; - register unsigned long __val1 asm ("r9") = val1; - register unsigned long __val2 asm ("r10") = val2; - register unsigned long __val3 asm ("r11") = val3; - register unsigned long __val4 asm ("r14") = val4; - - register unsigned long ia64_clobber0 asm ("r8"); - register unsigned long ia64_clobber1 asm ("r9"); - register unsigned long ia64_clobber2 asm ("r10"); - register unsigned long ia64_clobber3 asm ("r11"); - register unsigned long ia64_clobber4 asm ("r14"); - - asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, - PARAVIRT_TYPE(SET_RR0_TO_RR4)) - : "=r"(ia64_clobber0), - "=r"(ia64_clobber1), - "=r"(ia64_clobber2), - "=r"(ia64_clobber3), - "=r"(ia64_clobber4) - : PARAVIRT_OP(set_rr0_to_rr4), - "0"(__val0), "1"(__val1), "2"(__val2), - "3"(__val3), "4"(__val4) - : PARAVIRT_CLOBBERS5); -} - -/* unsigned long paravirt_getreg(int reg) */ -#define __paravirt_getreg(reg) \ - ({ \ - register unsigned long ia64_intri_res asm ("r8"); \ - register unsigned long __reg asm ("r8") = (reg); \ - \ - BUILD_BUG_ON(!__builtin_constant_p(reg)); \ - asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \ - PARAVIRT_TYPE(GETREG) \ - + (reg)) \ - : "=r"(ia64_intri_res) \ - : PARAVIRT_OP(getreg), "0"(__reg) \ - : PARAVIRT_CLOBBERS1); \ - \ - ia64_intri_res; \ - }) - -/* void paravirt_setreg(int reg, unsigned long val) */ -#define paravirt_setreg(reg, val) \ - do { \ - register unsigned long __val asm ("r8") = val; \ - register unsigned long __reg asm ("r9") = reg; \ - register unsigned long ia64_clobber1 asm ("r8"); \ - register unsigned long ia64_clobber2 asm ("r9"); \ - \ - BUILD_BUG_ON(!__builtin_constant_p(reg)); \ - asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \ - PARAVIRT_TYPE(SETREG) \ - + (reg)) \ - : "=r"(ia64_clobber1), \ - "=r"(ia64_clobber2) \ - : PARAVIRT_OP(setreg), \ - "1"(__reg), "0"(__val) \ - : PARAVIRT_CLOBBERS2); \ - } while (0) - -#endif /* ASM_SUPPORTED */ -#endif /* CONFIG_PARAVIRT && ASM_SUPPOTED */ - #endif /* _ASM_IA64_PARAVIRT_PRIVOP_H */ diff --git a/trunk/arch/ia64/include/asm/smp.h b/trunk/arch/ia64/include/asm/smp.h index 598408336251..21c402365d0e 100644 --- a/trunk/arch/ia64/include/asm/smp.h +++ b/trunk/arch/ia64/include/asm/smp.h @@ -126,8 +126,7 @@ extern void identify_siblings (struct cpuinfo_ia64 *); extern int is_multithreading_enabled(void); extern void arch_send_call_function_single_ipi(int cpu); -extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); -#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask +extern void arch_send_call_function_ipi(cpumask_t mask); #else /* CONFIG_SMP */ diff --git a/trunk/arch/ia64/include/asm/spinlock.h b/trunk/arch/ia64/include/asm/spinlock.h index 13ab71576bc7..0229fb95fb38 100644 --- a/trunk/arch/ia64/include/asm/spinlock.h +++ b/trunk/arch/ia64/include/asm/spinlock.h @@ -120,38 +120,6 @@ do { \ #define __raw_read_can_lock(rw) (*(volatile int *)(rw) >= 0) #define __raw_write_can_lock(rw) (*(volatile int *)(rw) == 0) -#ifdef ASM_SUPPORTED - -static __always_inline void -__raw_read_lock_flags(raw_rwlock_t *lock, unsigned long flags) -{ - __asm__ __volatile__ ( - "tbit.nz p6, p0 = %1,%2\n" - "br.few 3f\n" - "1:\n" - "fetchadd4.rel r2 = [%0], -1;;\n" - "(p6) ssm psr.i\n" - "2:\n" - "hint @pause\n" - "ld4 r2 = [%0];;\n" - "cmp4.lt p7,p0 = r2, r0\n" - "(p7) br.cond.spnt.few 2b\n" - "(p6) rsm psr.i\n" - ";;\n" - "3:\n" - "fetchadd4.acq r2 = [%0], 1;;\n" - "cmp4.lt p7,p0 = r2, r0\n" - "(p7) br.cond.spnt.few 1b\n" - : : "r"(lock), "r"(flags), "i"(IA64_PSR_I_BIT) - : "p6", "p7", "r2", "memory"); -} - -#define __raw_read_lock(lock) __raw_read_lock_flags(lock, 0) - -#else /* !ASM_SUPPORTED */ - -#define __raw_read_lock_flags(rw, flags) __raw_read_lock(rw) - #define __raw_read_lock(rw) \ do { \ raw_rwlock_t *__read_lock_ptr = (rw); \ @@ -163,8 +131,6 @@ do { \ } \ } while (0) -#endif /* !ASM_SUPPORTED */ - #define __raw_read_unlock(rw) \ do { \ raw_rwlock_t *__read_lock_ptr = (rw); \ @@ -172,33 +138,20 @@ do { \ } while (0) #ifdef ASM_SUPPORTED - -static __always_inline void -__raw_write_lock_flags(raw_rwlock_t *lock, unsigned long flags) -{ - __asm__ __volatile__ ( - "tbit.nz p6, p0 = %1, %2\n" - "mov ar.ccv = r0\n" - "dep r29 = -1, r0, 31, 1\n" - "br.few 3f;;\n" - "1:\n" - "(p6) ssm psr.i\n" - "2:\n" - "hint @pause\n" - "ld4 r2 = [%0];;\n" - "cmp4.eq p0,p7 = r0, r2\n" - "(p7) br.cond.spnt.few 2b\n" - "(p6) rsm psr.i\n" - ";;\n" - "3:\n" - "cmpxchg4.acq r2 = [%0], r29, ar.ccv;;\n" - "cmp4.eq p0,p7 = r0, r2\n" - "(p7) br.cond.spnt.few 1b;;\n" - : : "r"(lock), "r"(flags), "i"(IA64_PSR_I_BIT) - : "ar.ccv", "p6", "p7", "r2", "r29", "memory"); -} - -#define __raw_write_lock(rw) __raw_write_lock_flags(rw, 0) +#define __raw_write_lock(rw) \ +do { \ + __asm__ __volatile__ ( \ + "mov ar.ccv = r0\n" \ + "dep r29 = -1, r0, 31, 1;;\n" \ + "1:\n" \ + "ld4 r2 = [%0];;\n" \ + "cmp4.eq p0,p7 = r0,r2\n" \ + "(p7) br.cond.spnt.few 1b \n" \ + "cmpxchg4.acq r2 = [%0], r29, ar.ccv;;\n" \ + "cmp4.eq p0,p7 = r0, r2\n" \ + "(p7) br.cond.spnt.few 1b;;\n" \ + :: "r"(rw) : "ar.ccv", "p7", "r2", "r29", "memory"); \ +} while(0) #define __raw_write_trylock(rw) \ ({ \ @@ -221,8 +174,6 @@ static inline void __raw_write_unlock(raw_rwlock_t *x) #else /* !ASM_SUPPORTED */ -#define __raw_write_lock_flags(l, flags) __raw_write_lock(l) - #define __raw_write_lock(l) \ ({ \ __u64 ia64_val, ia64_set_val = ia64_dep_mi(-1, 0, 31, 1); \ diff --git a/trunk/arch/ia64/include/asm/timex.h b/trunk/arch/ia64/include/asm/timex.h index 86c7db861180..4e03cfe74a0c 100644 --- a/trunk/arch/ia64/include/asm/timex.h +++ b/trunk/arch/ia64/include/asm/timex.h @@ -40,6 +40,5 @@ get_cycles (void) } extern void ia64_cpu_local_tick (void); -extern unsigned long long ia64_native_sched_clock (void); #endif /* _ASM_IA64_TIMEX_H */ diff --git a/trunk/arch/ia64/include/asm/topology.h b/trunk/arch/ia64/include/asm/topology.h index 7b4c8c70b2d1..3193f4417e16 100644 --- a/trunk/arch/ia64/include/asm/topology.h +++ b/trunk/arch/ia64/include/asm/topology.h @@ -43,6 +43,11 @@ */ #define parent_node(nid) (nid) +/* + * Returns the number of the first CPU on Node 'node'. + */ +#define node_to_first_cpu(node) (cpumask_first(cpumask_of_node(node))) + /* * Determines the node for a given pci bus */ @@ -112,6 +117,11 @@ void build_cpu_to_node_map(void); extern void arch_fix_phys_package_id(int num, u32 slot); +#define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ? \ + CPU_MASK_ALL : \ + node_to_cpumask(pcibus_to_node(bus)) \ + ) + #define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \ cpu_all_mask : \ cpumask_of_node(pcibus_to_node(bus))) diff --git a/trunk/arch/ia64/include/asm/uv/uv_hub.h b/trunk/arch/ia64/include/asm/uv/uv_hub.h index 53e9dfacd073..f607018af4a1 100644 --- a/trunk/arch/ia64/include/asm/uv/uv_hub.h +++ b/trunk/arch/ia64/include/asm/uv/uv_hub.h @@ -305,11 +305,5 @@ static inline int uv_num_possible_blades(void) return 1; } -static inline void uv_hub_send_ipi(int pnode, int apicid, int vector) -{ - /* not currently needed on ia64 */ -} - - #endif /* __ASM_IA64_UV_HUB__ */ diff --git a/trunk/arch/ia64/include/asm/uv/uv_mmrs.h b/trunk/arch/ia64/include/asm/uv/uv_mmrs.h index fe0b8f05e1a8..c149ef085437 100644 --- a/trunk/arch/ia64/include/asm/uv/uv_mmrs.h +++ b/trunk/arch/ia64/include/asm/uv/uv_mmrs.h @@ -8,8 +8,8 @@ * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved. */ -#ifndef _ASM_IA64_UV_UV_MMRS_H -#define _ASM_IA64_UV_UV_MMRS_H +#ifndef __ASM_IA64_UV_MMRS__ +#define __ASM_IA64_UV_MMRS__ #define UV_MMR_ENABLE (1UL << 63) @@ -242,158 +242,6 @@ union uvh_event_occurred0_u { #define UVH_EVENT_OCCURRED0_ALIAS 0x0000000000070008UL #define UVH_EVENT_OCCURRED0_ALIAS_32 0x005f0 -/* ========================================================================= */ -/* UVH_GR0_TLB_INT0_CONFIG */ -/* ========================================================================= */ -#define UVH_GR0_TLB_INT0_CONFIG 0x61b00UL - -#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_SHFT 0 -#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_GR0_TLB_INT0_CONFIG_DM_SHFT 8 -#define UVH_GR0_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_SHFT 11 -#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_GR0_TLB_INT0_CONFIG_STATUS_SHFT 12 -#define UVH_GR0_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_GR0_TLB_INT0_CONFIG_P_SHFT 13 -#define UVH_GR0_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_GR0_TLB_INT0_CONFIG_T_SHFT 15 -#define UVH_GR0_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_GR0_TLB_INT0_CONFIG_M_SHFT 16 -#define UVH_GR0_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_SHFT 32 -#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL - -union uvh_gr0_tlb_int0_config_u { - unsigned long v; - struct uvh_gr0_tlb_int0_config_s { - unsigned long vector_ : 8; /* RW */ - unsigned long dm : 3; /* RW */ - unsigned long destmode : 1; /* RW */ - unsigned long status : 1; /* RO */ - unsigned long p : 1; /* RO */ - unsigned long rsvd_14 : 1; /* */ - unsigned long t : 1; /* RO */ - unsigned long m : 1; /* RW */ - unsigned long rsvd_17_31: 15; /* */ - unsigned long apic_id : 32; /* RW */ - } s; -}; - -/* ========================================================================= */ -/* UVH_GR0_TLB_INT1_CONFIG */ -/* ========================================================================= */ -#define UVH_GR0_TLB_INT1_CONFIG 0x61b40UL - -#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_SHFT 0 -#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_GR0_TLB_INT1_CONFIG_DM_SHFT 8 -#define UVH_GR0_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_SHFT 11 -#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_GR0_TLB_INT1_CONFIG_STATUS_SHFT 12 -#define UVH_GR0_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_GR0_TLB_INT1_CONFIG_P_SHFT 13 -#define UVH_GR0_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_GR0_TLB_INT1_CONFIG_T_SHFT 15 -#define UVH_GR0_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_GR0_TLB_INT1_CONFIG_M_SHFT 16 -#define UVH_GR0_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_SHFT 32 -#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL - -union uvh_gr0_tlb_int1_config_u { - unsigned long v; - struct uvh_gr0_tlb_int1_config_s { - unsigned long vector_ : 8; /* RW */ - unsigned long dm : 3; /* RW */ - unsigned long destmode : 1; /* RW */ - unsigned long status : 1; /* RO */ - unsigned long p : 1; /* RO */ - unsigned long rsvd_14 : 1; /* */ - unsigned long t : 1; /* RO */ - unsigned long m : 1; /* RW */ - unsigned long rsvd_17_31: 15; /* */ - unsigned long apic_id : 32; /* RW */ - } s; -}; - -/* ========================================================================= */ -/* UVH_GR1_TLB_INT0_CONFIG */ -/* ========================================================================= */ -#define UVH_GR1_TLB_INT0_CONFIG 0x61f00UL - -#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_SHFT 0 -#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_GR1_TLB_INT0_CONFIG_DM_SHFT 8 -#define UVH_GR1_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_SHFT 11 -#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_GR1_TLB_INT0_CONFIG_STATUS_SHFT 12 -#define UVH_GR1_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_GR1_TLB_INT0_CONFIG_P_SHFT 13 -#define UVH_GR1_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_GR1_TLB_INT0_CONFIG_T_SHFT 15 -#define UVH_GR1_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_GR1_TLB_INT0_CONFIG_M_SHFT 16 -#define UVH_GR1_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_SHFT 32 -#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL - -union uvh_gr1_tlb_int0_config_u { - unsigned long v; - struct uvh_gr1_tlb_int0_config_s { - unsigned long vector_ : 8; /* RW */ - unsigned long dm : 3; /* RW */ - unsigned long destmode : 1; /* RW */ - unsigned long status : 1; /* RO */ - unsigned long p : 1; /* RO */ - unsigned long rsvd_14 : 1; /* */ - unsigned long t : 1; /* RO */ - unsigned long m : 1; /* RW */ - unsigned long rsvd_17_31: 15; /* */ - unsigned long apic_id : 32; /* RW */ - } s; -}; - -/* ========================================================================= */ -/* UVH_GR1_TLB_INT1_CONFIG */ -/* ========================================================================= */ -#define UVH_GR1_TLB_INT1_CONFIG 0x61f40UL - -#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_SHFT 0 -#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_GR1_TLB_INT1_CONFIG_DM_SHFT 8 -#define UVH_GR1_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_SHFT 11 -#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_GR1_TLB_INT1_CONFIG_STATUS_SHFT 12 -#define UVH_GR1_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_GR1_TLB_INT1_CONFIG_P_SHFT 13 -#define UVH_GR1_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_GR1_TLB_INT1_CONFIG_T_SHFT 15 -#define UVH_GR1_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_GR1_TLB_INT1_CONFIG_M_SHFT 16 -#define UVH_GR1_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_SHFT 32 -#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL - -union uvh_gr1_tlb_int1_config_u { - unsigned long v; - struct uvh_gr1_tlb_int1_config_s { - unsigned long vector_ : 8; /* RW */ - unsigned long dm : 3; /* RW */ - unsigned long destmode : 1; /* RW */ - unsigned long status : 1; /* RO */ - unsigned long p : 1; /* RO */ - unsigned long rsvd_14 : 1; /* */ - unsigned long t : 1; /* RO */ - unsigned long m : 1; /* RW */ - unsigned long rsvd_17_31: 15; /* */ - unsigned long apic_id : 32; /* RW */ - } s; -}; - /* ========================================================================= */ /* UVH_INT_CMPB */ /* ========================================================================= */ @@ -822,4 +670,4 @@ union uvh_si_alias2_overlay_config_u { }; -#endif /* _ASM_IA64_UV_UV_MMRS_H */ +#endif /* __ASM_IA64_UV_MMRS__ */ diff --git a/trunk/arch/ia64/include/asm/xen/hypervisor.h b/trunk/arch/ia64/include/asm/xen/hypervisor.h index e425227a418e..7a804e80fc67 100644 --- a/trunk/arch/ia64/include/asm/xen/hypervisor.h +++ b/trunk/arch/ia64/include/asm/xen/hypervisor.h @@ -33,6 +33,9 @@ #ifndef _ASM_IA64_XEN_HYPERVISOR_H #define _ASM_IA64_XEN_HYPERVISOR_H +#ifdef CONFIG_XEN + +#include #include #include /* to compile feature.c */ #include /* to comiple xen-netfront.c */ @@ -40,32 +43,22 @@ /* xen_domain_type is set before executing any C code by early_xen_setup */ enum xen_domain_type { - XEN_NATIVE, /* running on bare hardware */ - XEN_PV_DOMAIN, /* running in a PV domain */ - XEN_HVM_DOMAIN, /* running in a Xen hvm domain*/ + XEN_NATIVE, + XEN_PV_DOMAIN, + XEN_HVM_DOMAIN, }; -#ifdef CONFIG_XEN extern enum xen_domain_type xen_domain_type; -#else -#define xen_domain_type XEN_NATIVE -#endif #define xen_domain() (xen_domain_type != XEN_NATIVE) -#define xen_pv_domain() (xen_domain() && \ - xen_domain_type == XEN_PV_DOMAIN) -#define xen_hvm_domain() (xen_domain() && \ - xen_domain_type == XEN_HVM_DOMAIN) - -#ifdef CONFIG_XEN_DOM0 -#define xen_initial_domain() (xen_pv_domain() && \ +#define xen_pv_domain() (xen_domain_type == XEN_PV_DOMAIN) +#define xen_initial_domain() (xen_pv_domain() && \ (xen_start_info->flags & SIF_INITDOMAIN)) -#else -#define xen_initial_domain() (0) -#endif +#define xen_hvm_domain() (xen_domain_type == XEN_HVM_DOMAIN) +/* deprecated. remove this */ +#define is_running_on_xen() (xen_domain_type == XEN_PV_DOMAIN) -#ifdef CONFIG_XEN extern struct shared_info *HYPERVISOR_shared_info; extern struct start_info *xen_start_info; @@ -81,6 +74,16 @@ void force_evtchn_callback(void); /* For setup_arch() in arch/ia64/kernel/setup.c */ void xen_ia64_enable_opt_feature(void); + +#else /* CONFIG_XEN */ + +#define xen_domain() (0) +#define xen_pv_domain() (0) +#define xen_initial_domain() (0) +#define xen_hvm_domain() (0) +#define is_running_on_xen() (0) /* deprecated. remove this */ #endif +#define is_initial_xendomain() (0) /* deprecated. remove this */ + #endif /* _ASM_IA64_XEN_HYPERVISOR_H */ diff --git a/trunk/arch/ia64/include/asm/xen/inst.h b/trunk/arch/ia64/include/asm/xen/inst.h index c53a47611208..19c2ae1d878a 100644 --- a/trunk/arch/ia64/include/asm/xen/inst.h +++ b/trunk/arch/ia64/include/asm/xen/inst.h @@ -33,9 +33,6 @@ #define __paravirt_work_processed_syscall_target \ xen_work_processed_syscall -#define paravirt_fsyscall_table xen_fsyscall_table -#define paravirt_fsys_bubble_down xen_fsys_bubble_down - #define MOV_FROM_IFA(reg) \ movl reg = XSI_IFA; \ ;; \ @@ -113,27 +110,6 @@ .endm #define MOV_FROM_PSR(pred, reg, clob) __MOV_FROM_PSR pred, reg, clob -/* assuming ar.itc is read with interrupt disabled. */ -#define MOV_FROM_ITC(pred, pred_clob, reg, clob) \ -(pred) movl clob = XSI_ITC_OFFSET; \ - ;; \ -(pred) ld8 clob = [clob]; \ -(pred) mov reg = ar.itc; \ - ;; \ -(pred) add reg = reg, clob; \ - ;; \ -(pred) movl clob = XSI_ITC_LAST; \ - ;; \ -(pred) ld8 clob = [clob]; \ - ;; \ -(pred) cmp.geu.unc pred_clob, p0 = clob, reg; \ - ;; \ -(pred_clob) add reg = 1, clob; \ - ;; \ -(pred) movl clob = XSI_ITC_LAST; \ - ;; \ -(pred) st8 [clob] = reg - #define MOV_TO_IFA(reg, clob) \ movl clob = XSI_IFA; \ @@ -386,10 +362,6 @@ #define RSM_PSR_DT \ XEN_HYPER_RSM_PSR_DT -#define RSM_PSR_BE_I(clob0, clob1) \ - RSM_PSR_I(p0, clob0, clob1); \ - rum psr.be - #define SSM_PSR_DT_AND_SRLZ_I \ XEN_HYPER_SSM_PSR_DT diff --git a/trunk/arch/ia64/include/asm/xen/interface.h b/trunk/arch/ia64/include/asm/xen/interface.h index e951e740bdf2..f00fab40854d 100644 --- a/trunk/arch/ia64/include/asm/xen/interface.h +++ b/trunk/arch/ia64/include/asm/xen/interface.h @@ -209,15 +209,6 @@ struct mapped_regs { unsigned long krs[8]; /* kernel registers */ unsigned long tmp[16]; /* temp registers (e.g. for hyperprivops) */ - - /* itc paravirtualization - * vAR.ITC = mAR.ITC + itc_offset - * itc_last is one which was lastly passed to - * the guest OS in order to prevent it from - * going backwords. - */ - unsigned long itc_offset; - unsigned long itc_last; }; }; }; diff --git a/trunk/arch/ia64/include/asm/xen/minstate.h b/trunk/arch/ia64/include/asm/xen/minstate.h index c57fa910f2c9..4d92d9bbda7b 100644 --- a/trunk/arch/ia64/include/asm/xen/minstate.h +++ b/trunk/arch/ia64/include/asm/xen/minstate.h @@ -1,12 +1,3 @@ - -#ifdef CONFIG_VIRT_CPU_ACCOUNTING -/* read ar.itc in advance, and use it before leaving bank 0 */ -#define XEN_ACCOUNT_GET_STAMP \ - MOV_FROM_ITC(pUStk, p6, r20, r2); -#else -#define XEN_ACCOUNT_GET_STAMP -#endif - /* * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves * the minimum state necessary that allows us to turn psr.ic back @@ -132,7 +123,7 @@ ;; \ .mem.offset 0,0; st8.spill [r16]=r2,16; \ .mem.offset 8,0; st8.spill [r17]=r3,16; \ - XEN_ACCOUNT_GET_STAMP \ + ACCOUNT_GET_STAMP \ adds r2=IA64_PT_REGS_R16_OFFSET,r1; \ ;; \ EXTRA; \ diff --git a/trunk/arch/ia64/include/asm/xen/patchlist.h b/trunk/arch/ia64/include/asm/xen/patchlist.h deleted file mode 100644 index eae944e88846..000000000000 --- a/trunk/arch/ia64/include/asm/xen/patchlist.h +++ /dev/null @@ -1,38 +0,0 @@ -/****************************************************************************** - * arch/ia64/include/asm/xen/patchlist.h - * - * Copyright (c) 2008 Isaku Yamahata - * VA Linux Systems Japan K.K. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define __paravirt_start_gate_fsyscall_patchlist \ - __xen_start_gate_fsyscall_patchlist -#define __paravirt_end_gate_fsyscall_patchlist \ - __xen_end_gate_fsyscall_patchlist -#define __paravirt_start_gate_brl_fsys_bubble_down_patchlist \ - __xen_start_gate_brl_fsys_bubble_down_patchlist -#define __paravirt_end_gate_brl_fsys_bubble_down_patchlist \ - __xen_end_gate_brl_fsys_bubble_down_patchlist -#define __paravirt_start_gate_vtop_patchlist \ - __xen_start_gate_vtop_patchlist -#define __paravirt_end_gate_vtop_patchlist \ - __xen_end_gate_vtop_patchlist -#define __paravirt_start_gate_mckinley_e9_patchlist \ - __xen_start_gate_mckinley_e9_patchlist -#define __paravirt_end_gate_mckinley_e9_patchlist \ - __xen_end_gate_mckinley_e9_patchlist diff --git a/trunk/arch/ia64/include/asm/xen/privop.h b/trunk/arch/ia64/include/asm/xen/privop.h index fb4ec5e0b066..71ec7546e100 100644 --- a/trunk/arch/ia64/include/asm/xen/privop.h +++ b/trunk/arch/ia64/include/asm/xen/privop.h @@ -55,8 +55,6 @@ #define XSI_BANK1_R16 (XSI_BASE + XSI_BANK1_R16_OFS) #define XSI_BANKNUM (XSI_BASE + XSI_BANKNUM_OFS) #define XSI_IHA (XSI_BASE + XSI_IHA_OFS) -#define XSI_ITC_OFFSET (XSI_BASE + XSI_ITC_OFFSET_OFS) -#define XSI_ITC_LAST (XSI_BASE + XSI_ITC_LAST_OFS) #endif #ifndef __ASSEMBLY__ @@ -69,7 +67,7 @@ * may have different semantics depending on whether they are executed * at PL0 vs PL!=0. When paravirtualized, these instructions mustn't * be allowed to execute directly, lest incorrect semantics result. */ -extern void xen_fc(void *addr); +extern void xen_fc(unsigned long addr); extern unsigned long xen_thash(unsigned long addr); /* Note that "ttag" and "cover" are also privilege-sensitive; "ttag" @@ -82,10 +80,8 @@ extern unsigned long xen_thash(unsigned long addr); extern unsigned long xen_get_cpuid(int index); extern unsigned long xen_get_pmd(int index); -#ifndef ASM_SUPPORTED extern unsigned long xen_get_eflag(void); /* see xen_ia64_getreg */ extern void xen_set_eflag(unsigned long); /* see xen_ia64_setreg */ -#endif /************************************************/ /* Instructions paravirtualized for performance */ @@ -110,7 +106,6 @@ extern void xen_set_eflag(unsigned long); /* see xen_ia64_setreg */ #define xen_get_virtual_pend() \ (*(((uint8_t *)XEN_MAPPEDREGS->interrupt_mask_addr) - 1)) -#ifndef ASM_SUPPORTED /* Although all privileged operations can be left to trap and will * be properly handled by Xen, some are frequent enough that we use * hyperprivops for performance. */ @@ -128,7 +123,6 @@ extern void xen_set_rr0_to_rr4(unsigned long val0, unsigned long val1, unsigned long val4); extern void xen_set_kr(unsigned long index, unsigned long val); extern void xen_ptcga(unsigned long addr, unsigned long size); -#endif /* !ASM_SUPPORTED */ #endif /* !__ASSEMBLY__ */ diff --git a/trunk/arch/ia64/kernel/Makefile b/trunk/arch/ia64/kernel/Makefile index 5628e9a990a6..c381ea954892 100644 --- a/trunk/arch/ia64/kernel/Makefile +++ b/trunk/arch/ia64/kernel/Makefile @@ -5,9 +5,9 @@ extra-y := head.o init_task.o vmlinux.lds obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ - irq_lsapic.o ivt.o machvec.o pal.o paravirt_patchlist.o patch.o process.o perfmon.o ptrace.o sal.o \ + irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \ salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ - unwind.o mca.o mca_asm.o topology.o dma-mapping.o + unwind.o mca.o mca_asm.o topology.o obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o @@ -36,23 +36,46 @@ obj-$(CONFIG_PCI_MSI) += msi_ia64.o mca_recovery-y += mca_drv.o mca_drv_asm.o obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o -obj-$(CONFIG_PARAVIRT) += paravirt.o paravirtentry.o \ - paravirt_patch.o +obj-$(CONFIG_PARAVIRT) += paravirt.o paravirtentry.o obj-$(CONFIG_IA64_ESI) += esi.o ifneq ($(CONFIG_IA64_ESI),) obj-y += esi_stub.o # must be in kernel proper endif obj-$(CONFIG_DMAR) += pci-dma.o +ifeq ($(CONFIG_DMAR), y) obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o +endif + +# The gate DSO image is built using a special linker script. +targets += gate.so gate-syms.o + +extra-y += gate.so gate-syms.o gate.lds gate.o # fp_emulate() expects f2-f5,f16-f31 to contain the user-level state. CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31 -# The gate DSO image is built using a special linker script. -include $(srctree)/arch/ia64/kernel/Makefile.gate -# tell compiled for native -CPPFLAGS_gate.lds += -D__IA64_GATE_PARAVIRTUALIZED_NATIVE +CPPFLAGS_gate.lds := -P -C -U$(ARCH) + +quiet_cmd_gate = GATE $@ + cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@ + +GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \ + $(call ld-option, -Wl$(comma)--hash-style=sysv) +$(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE + $(call if_changed,gate) + +$(obj)/built-in.o: $(obj)/gate-syms.o +$(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o + +GATECFLAGS_gate-syms.o = -r +$(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE + $(call if_changed,gate) + +# gate-data.o contains the gate DSO image as data in section .data.gate. +# We must build gate.so before we can assemble it. +# Note: kbuild does not track this dependency due to usage of .incbin +$(obj)/gate-data.o: $(obj)/gate.so # Calculate NR_IRQ = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) based on config define sed-y @@ -88,9 +111,9 @@ include/asm-ia64/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s clean-files += $(objtree)/include/asm-ia64/nr-irqs.h # -# native ivt.S, entry.S and fsys.S +# native ivt.S and entry.S # -ASM_PARAVIRT_OBJS = ivt.o entry.o fsys.o +ASM_PARAVIRT_OBJS = ivt.o entry.o define paravirtualized_native AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE AFLAGS_pvchk-sed-$(1) += -D__IA64_ASM_PARAVIRTUALIZED_PVCHECK diff --git a/trunk/arch/ia64/kernel/Makefile.gate b/trunk/arch/ia64/kernel/Makefile.gate deleted file mode 100644 index 1d87f84069b3..000000000000 --- a/trunk/arch/ia64/kernel/Makefile.gate +++ /dev/null @@ -1,27 +0,0 @@ -# The gate DSO image is built using a special linker script. - -targets += gate.so gate-syms.o - -extra-y += gate.so gate-syms.o gate.lds gate.o - -CPPFLAGS_gate.lds := -P -C -U$(ARCH) - -quiet_cmd_gate = GATE $@ - cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@ - -GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \ - $(call ld-option, -Wl$(comma)--hash-style=sysv) -$(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE - $(call if_changed,gate) - -$(obj)/built-in.o: $(obj)/gate-syms.o -$(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o - -GATECFLAGS_gate-syms.o = -r -$(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE - $(call if_changed,gate) - -# gate-data.o contains the gate DSO image as data in section .data.gate. -# We must build gate.so before we can assemble it. -# Note: kbuild does not track this dependency due to usage of .incbin -$(obj)/gate-data.o: $(obj)/gate.so diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c index 5510317db37b..bdef2ce38c8b 100644 --- a/trunk/arch/ia64/kernel/acpi.c +++ b/trunk/arch/ia64/kernel/acpi.c @@ -890,7 +890,7 @@ __init void prefill_possible_map(void) possible, max((possible - available_cpus), 0)); for (i = 0; i < possible; i++) - set_cpu_possible(i, true); + cpu_set(i, cpu_possible_map); } int acpi_map_lsapic(acpi_handle handle, int *pcpu) @@ -928,9 +928,9 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) buffer.length = ACPI_ALLOCATE_BUFFER; buffer.pointer = NULL; - cpumask_complement(&tmp_map, cpu_present_mask); - cpu = cpumask_first(&tmp_map); - if (cpu >= nr_cpu_ids) + cpus_complement(tmp_map, cpu_present_map); + cpu = first_cpu(tmp_map); + if (cpu >= NR_CPUS) return -EINVAL; acpi_map_cpu2node(handle, cpu, physid); diff --git a/trunk/arch/ia64/kernel/asm-offsets.c b/trunk/arch/ia64/kernel/asm-offsets.c index af5650169043..742dbb1d5a4f 100644 --- a/trunk/arch/ia64/kernel/asm-offsets.c +++ b/trunk/arch/ia64/kernel/asm-offsets.c @@ -316,7 +316,5 @@ void foo(void) DEFINE_MAPPED_REG_OFS(XSI_BANK1_R16_OFS, bank1_regs[0]); DEFINE_MAPPED_REG_OFS(XSI_B0NATS_OFS, vbnat); DEFINE_MAPPED_REG_OFS(XSI_B1NATS_OFS, vnat); - DEFINE_MAPPED_REG_OFS(XSI_ITC_OFFSET_OFS, itc_offset); - DEFINE_MAPPED_REG_OFS(XSI_ITC_LAST_OFS, itc_last); #endif /* CONFIG_XEN */ } diff --git a/trunk/arch/ia64/kernel/dma-mapping.c b/trunk/arch/ia64/kernel/dma-mapping.c deleted file mode 100644 index 086a2aeb0404..000000000000 --- a/trunk/arch/ia64/kernel/dma-mapping.c +++ /dev/null @@ -1,13 +0,0 @@ -#include - -/* Set this to 1 if there is a HW IOMMU in the system */ -int iommu_detected __read_mostly; - -struct dma_map_ops *dma_ops; -EXPORT_SYMBOL(dma_ops); - -struct dma_map_ops *dma_get_ops(struct device *dev) -{ - return dma_ops; -} -EXPORT_SYMBOL(dma_get_ops); diff --git a/trunk/arch/ia64/kernel/efi.c b/trunk/arch/ia64/kernel/efi.c index 7ef80e8161ce..efaff15d8cf1 100644 --- a/trunk/arch/ia64/kernel/efi.c +++ b/trunk/arch/ia64/kernel/efi.c @@ -456,7 +456,6 @@ efi_map_pal_code (void) GRANULEROUNDDOWN((unsigned long) pal_vaddr), pte_val(pfn_pte(__pa(pal_vaddr) >> PAGE_SHIFT, PAGE_KERNEL)), IA64_GRANULE_SHIFT); - paravirt_dv_serialize_data(); ia64_set_psr(psr); /* restore psr */ } diff --git a/trunk/arch/ia64/kernel/entry.S b/trunk/arch/ia64/kernel/entry.S index ccfdeee9d89f..e5341e2c1175 100644 --- a/trunk/arch/ia64/kernel/entry.S +++ b/trunk/arch/ia64/kernel/entry.S @@ -735,7 +735,7 @@ GLOBAL_ENTRY(__paravirt_leave_syscall) __paravirt_work_processed_syscall: #ifdef CONFIG_VIRT_CPU_ACCOUNTING adds r2=PT(LOADRS)+16,r12 - MOV_FROM_ITC(pUStk, p9, r22, r19) // fetch time at leave +(pUStk) mov.m r22=ar.itc // fetch time at leave adds r18=TI_FLAGS+IA64_TASK_SIZE,r13 ;; (p6) ld4 r31=[r18] // load current_thread_info()->flags @@ -984,7 +984,7 @@ GLOBAL_ENTRY(__paravirt_leave_kernel) #ifdef CONFIG_VIRT_CPU_ACCOUNTING .pred.rel.mutex pUStk,pKStk MOV_FROM_PSR(pKStk, r22, r29) // M2 read PSR now that interrupts are disabled - MOV_FROM_ITC(pUStk, p9, r22, r29) // M fetch time at leave +(pUStk) mov.m r22=ar.itc // M fetch time at leave nop.i 0 ;; #else diff --git a/trunk/arch/ia64/kernel/fsys.S b/trunk/arch/ia64/kernel/fsys.S index 3567d54f8cee..c1625c7e1779 100644 --- a/trunk/arch/ia64/kernel/fsys.S +++ b/trunk/arch/ia64/kernel/fsys.S @@ -25,7 +25,6 @@ #include #include "entry.h" -#include "paravirt_inst.h" /* * See Documentation/ia64/fsys.txt for details on fsyscalls. @@ -280,7 +279,7 @@ ENTRY(fsys_gettimeofday) (p9) cmp.eq p13,p0 = 0,r30 // if mmio_ptr, clear p13 jitter control ;; .pred.rel.mutex p8,p9 - MOV_FROM_ITC(p8, p6, r2, r10) // CPU_TIMER. 36 clocks latency!!! +(p8) mov r2 = ar.itc // CPU_TIMER. 36 clocks latency!!! (p9) ld8 r2 = [r30] // MMIO_TIMER. Could also have latency issues.. (p13) ld8 r25 = [r19] // get itc_lastcycle value ld8 r9 = [r22],IA64_TIMESPEC_TV_NSEC_OFFSET // tv_sec @@ -419,7 +418,7 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set mov r17=(1 << (SIGKILL - 1)) | (1 << (SIGSTOP - 1)) ;; - RSM_PSR_I(p0, r18, r19) // mask interrupt delivery + rsm psr.i // mask interrupt delivery mov ar.ccv=0 andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP @@ -492,7 +491,7 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set #ifdef CONFIG_SMP st4.rel [r31]=r0 // release the lock #endif - SSM_PSR_I(p0, p9, r31) + ssm psr.i ;; srlz.d // ensure psr.i is set again @@ -514,7 +513,7 @@ EX(.fail_efault, (p15) st8 [r34]=r3) #ifdef CONFIG_SMP st4.rel [r31]=r0 // release the lock #endif - SSM_PSR_I(p0, p9, r17) + ssm psr.i ;; srlz.d br.sptk.many fsys_fallback_syscall // with signal pending, do the heavy-weight syscall @@ -522,7 +521,7 @@ EX(.fail_efault, (p15) st8 [r34]=r3) #ifdef CONFIG_SMP .lock_contention: /* Rather than spinning here, fall back on doing a heavy-weight syscall. */ - SSM_PSR_I(p0, p9, r17) + ssm psr.i ;; srlz.d br.sptk.many fsys_fallback_syscall @@ -593,17 +592,17 @@ ENTRY(fsys_fallback_syscall) adds r17=-1024,r15 movl r14=sys_call_table ;; - RSM_PSR_I(p0, r26, r27) + rsm psr.i shladd r18=r17,3,r14 ;; ld8 r18=[r18] // load normal (heavy-weight) syscall entry-point - MOV_FROM_PSR(p0, r29, r26) // read psr (12 cyc load latency) + mov r29=psr // read psr (12 cyc load latency) mov r27=ar.rsc mov r21=ar.fpsr mov r26=ar.pfs END(fsys_fallback_syscall) /* FALL THROUGH */ -GLOBAL_ENTRY(paravirt_fsys_bubble_down) +GLOBAL_ENTRY(fsys_bubble_down) .prologue .altrp b6 .body @@ -641,7 +640,7 @@ GLOBAL_ENTRY(paravirt_fsys_bubble_down) * * PSR.BE : already is turned off in __kernel_syscall_via_epc() * PSR.AC : don't care (kernel normally turns PSR.AC on) - * PSR.I : already turned off by the time paravirt_fsys_bubble_down gets + * PSR.I : already turned off by the time fsys_bubble_down gets * invoked * PSR.DFL: always 0 (kernel never turns it on) * PSR.DFH: don't care --- kernel never touches f32-f127 on its own @@ -651,7 +650,7 @@ GLOBAL_ENTRY(paravirt_fsys_bubble_down) * PSR.DB : don't care --- kernel never enables kernel-level * breakpoints * PSR.TB : must be 0 already; if it wasn't zero on entry to - * __kernel_syscall_via_epc, the branch to paravirt_fsys_bubble_down + * __kernel_syscall_via_epc, the branch to fsys_bubble_down * will trigger a taken branch; the taken-trap-handler then * converts the syscall into a break-based system-call. */ @@ -684,7 +683,7 @@ GLOBAL_ENTRY(paravirt_fsys_bubble_down) ;; mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0 #ifdef CONFIG_VIRT_CPU_ACCOUNTING - MOV_FROM_ITC(p0, p6, r30, r23) // M get cycle for accounting + mov.m r30=ar.itc // M get cycle for accounting #else nop.m 0 #endif @@ -735,21 +734,21 @@ GLOBAL_ENTRY(paravirt_fsys_bubble_down) mov rp=r14 // I0 set the real return addr and r3=_TIF_SYSCALL_TRACEAUDIT,r3 // A ;; - SSM_PSR_I(p0, p6, r22) // M2 we're on kernel stacks now, reenable irqs + ssm psr.i // M2 we're on kernel stacks now, reenable irqs cmp.eq p8,p0=r3,r0 // A (p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT nop.m 0 (p8) br.call.sptk.many b6=b6 // B (ignore return address) br.cond.spnt ia64_trace_syscall // B -END(paravirt_fsys_bubble_down) +END(fsys_bubble_down) .rodata .align 8 - .globl paravirt_fsyscall_table + .globl fsyscall_table - data8 paravirt_fsys_bubble_down -paravirt_fsyscall_table: + data8 fsys_bubble_down +fsyscall_table: data8 fsys_ni_syscall data8 0 // exit // 1025 data8 0 // read @@ -1034,4 +1033,4 @@ paravirt_fsyscall_table: // fill in zeros for the remaining entries .zero: - .space paravirt_fsyscall_table + 8*NR_syscalls - .zero, 0 + .space fsyscall_table + 8*NR_syscalls - .zero, 0 diff --git a/trunk/arch/ia64/kernel/gate.S b/trunk/arch/ia64/kernel/gate.S index cf5e0a105e16..74b1ccce4e84 100644 --- a/trunk/arch/ia64/kernel/gate.S +++ b/trunk/arch/ia64/kernel/gate.S @@ -13,7 +13,6 @@ #include #include #include -#include "paravirt_inst.h" /* * We can't easily refer to symbols inside the kernel. To avoid full runtime relocation, @@ -49,6 +48,87 @@ GLOBAL_ENTRY(__kernel_syscall_via_break) } END(__kernel_syscall_via_break) +/* + * On entry: + * r11 = saved ar.pfs + * r15 = system call # + * b0 = saved return address + * b6 = return address + * On exit: + * r11 = saved ar.pfs + * r15 = system call # + * b0 = saved return address + * all other "scratch" registers: undefined + * all "preserved" registers: same as on entry + */ + +GLOBAL_ENTRY(__kernel_syscall_via_epc) + .prologue + .altrp b6 + .body +{ + /* + * Note: the kernel cannot assume that the first two instructions in this + * bundle get executed. The remaining code must be safe even if + * they do not get executed. + */ + adds r17=-1024,r15 // A + mov r10=0 // A default to successful syscall execution + epc // B causes split-issue +} + ;; + rsm psr.be | psr.i // M2 (5 cyc to srlz.d) + LOAD_FSYSCALL_TABLE(r14) // X + ;; + mov r16=IA64_KR(CURRENT) // M2 (12 cyc) + shladd r18=r17,3,r14 // A + mov r19=NR_syscalls-1 // A + ;; + lfetch [r18] // M0|1 + mov r29=psr // M2 (12 cyc) + // If r17 is a NaT, p6 will be zero + cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)? + ;; + mov r21=ar.fpsr // M2 (12 cyc) + tnat.nz p10,p9=r15 // I0 + mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...) + ;; + srlz.d // M0 (forces split-issue) ensure PSR.BE==0 +(p6) ld8 r18=[r18] // M0|1 + nop.i 0 + ;; + nop.m 0 +(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!) + nop.i 0 + ;; +(p8) ssm psr.i +(p6) mov b7=r18 // I0 +(p8) br.dptk.many b7 // B + + mov r27=ar.rsc // M2 (12 cyc) +/* + * brl.cond doesn't work as intended because the linker would convert this branch + * into a branch to a PLT. Perhaps there will be a way to avoid this with some + * future version of the linker. In the meantime, we just use an indirect branch + * instead. + */ +#ifdef CONFIG_ITANIUM +(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry + ;; +(p6) ld8 r14=[r14] // r14 <- fsys_bubble_down + ;; +(p6) mov b7=r14 +(p6) br.sptk.many b7 +#else + BRL_COND_FSYS_BUBBLE_DOWN(p6) +#endif + ssm psr.i + mov r10=-1 +(p10) mov r8=EINVAL +(p9) mov r8=ENOSYS + FSYS_RETURN +END(__kernel_syscall_via_epc) + # define ARG0_OFF (16 + IA64_SIGFRAME_ARG0_OFFSET) # define ARG1_OFF (16 + IA64_SIGFRAME_ARG1_OFFSET) # define ARG2_OFF (16 + IA64_SIGFRAME_ARG2_OFFSET) @@ -294,92 +374,3 @@ restore_rbs: // invala not necessary as that will happen when returning to user-mode br.cond.sptk back_from_restore_rbs END(__kernel_sigtramp) - -/* - * On entry: - * r11 = saved ar.pfs - * r15 = system call # - * b0 = saved return address - * b6 = return address - * On exit: - * r11 = saved ar.pfs - * r15 = system call # - * b0 = saved return address - * all other "scratch" registers: undefined - * all "preserved" registers: same as on entry - */ - -GLOBAL_ENTRY(__kernel_syscall_via_epc) - .prologue - .altrp b6 - .body -{ - /* - * Note: the kernel cannot assume that the first two instructions in this - * bundle get executed. The remaining code must be safe even if - * they do not get executed. - */ - adds r17=-1024,r15 // A - mov r10=0 // A default to successful syscall execution - epc // B causes split-issue -} - ;; - RSM_PSR_BE_I(r20, r22) // M2 (5 cyc to srlz.d) - LOAD_FSYSCALL_TABLE(r14) // X - ;; - mov r16=IA64_KR(CURRENT) // M2 (12 cyc) - shladd r18=r17,3,r14 // A - mov r19=NR_syscalls-1 // A - ;; - lfetch [r18] // M0|1 - MOV_FROM_PSR(p0, r29, r8) // M2 (12 cyc) - // If r17 is a NaT, p6 will be zero - cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)? - ;; - mov r21=ar.fpsr // M2 (12 cyc) - tnat.nz p10,p9=r15 // I0 - mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...) - ;; - srlz.d // M0 (forces split-issue) ensure PSR.BE==0 -(p6) ld8 r18=[r18] // M0|1 - nop.i 0 - ;; - nop.m 0 -(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!) - nop.i 0 - ;; - SSM_PSR_I(p8, p14, r25) -(p6) mov b7=r18 // I0 -(p8) br.dptk.many b7 // B - - mov r27=ar.rsc // M2 (12 cyc) -/* - * brl.cond doesn't work as intended because the linker would convert this branch - * into a branch to a PLT. Perhaps there will be a way to avoid this with some - * future version of the linker. In the meantime, we just use an indirect branch - * instead. - */ -#ifdef CONFIG_ITANIUM -(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry - ;; -(p6) ld8 r14=[r14] // r14 <- fsys_bubble_down - ;; -(p6) mov b7=r14 -(p6) br.sptk.many b7 -#else - BRL_COND_FSYS_BUBBLE_DOWN(p6) -#endif - SSM_PSR_I(p0, p14, r10) - mov r10=-1 -(p10) mov r8=EINVAL -(p9) mov r8=ENOSYS - FSYS_RETURN - -#ifdef CONFIG_PARAVIRT - /* - * padd to make the size of this symbol constant - * independent of paravirtualization. - */ - .align PAGE_SIZE / 8 -#endif -END(__kernel_syscall_via_epc) diff --git a/trunk/arch/ia64/kernel/gate.lds.S b/trunk/arch/ia64/kernel/gate.lds.S index 88c64ed47c36..3cb1abc00e24 100644 --- a/trunk/arch/ia64/kernel/gate.lds.S +++ b/trunk/arch/ia64/kernel/gate.lds.S @@ -7,7 +7,6 @@ #include -#include "paravirt_patchlist.h" SECTIONS { @@ -34,21 +33,21 @@ SECTIONS . = GATE_ADDR + 0x600; .data.patch : { - __paravirt_start_gate_mckinley_e9_patchlist = .; + __start_gate_mckinley_e9_patchlist = .; *(.data.patch.mckinley_e9) - __paravirt_end_gate_mckinley_e9_patchlist = .; + __end_gate_mckinley_e9_patchlist = .; - __paravirt_start_gate_vtop_patchlist = .; + __start_gate_vtop_patchlist = .; *(.data.patch.vtop) - __paravirt_end_gate_vtop_patchlist = .; + __end_gate_vtop_patchlist = .; - __paravirt_start_gate_fsyscall_patchlist = .; + __start_gate_fsyscall_patchlist = .; *(.data.patch.fsyscall_table) - __paravirt_end_gate_fsyscall_patchlist = .; + __end_gate_fsyscall_patchlist = .; - __paravirt_start_gate_brl_fsys_bubble_down_patchlist = .; + __start_gate_brl_fsys_bubble_down_patchlist = .; *(.data.patch.brl_fsys_bubble_down) - __paravirt_end_gate_brl_fsys_bubble_down_patchlist = .; + __end_gate_brl_fsys_bubble_down_patchlist = .; } :readable .IA_64.unwind_info : { *(.IA_64.unwind_info*) } diff --git a/trunk/arch/ia64/kernel/head.S b/trunk/arch/ia64/kernel/head.S index 23f846de62d5..59301c472800 100644 --- a/trunk/arch/ia64/kernel/head.S +++ b/trunk/arch/ia64/kernel/head.S @@ -1050,7 +1050,7 @@ END(ia64_delay_loop) * except that the multiplication and the shift are done with 128-bit * intermediate precision so that we can produce a full 64-bit result. */ -GLOBAL_ENTRY(ia64_native_sched_clock) +GLOBAL_ENTRY(sched_clock) addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0 mov.m r9=ar.itc // fetch cycle-counter (35 cyc) ;; @@ -1066,13 +1066,7 @@ GLOBAL_ENTRY(ia64_native_sched_clock) ;; shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT br.ret.sptk.many rp -END(ia64_native_sched_clock) -#ifndef CONFIG_PARAVIRT - //unsigned long long - //sched_clock(void) __attribute__((alias("ia64_native_sched_clock"))); - .global sched_clock -sched_clock = ia64_native_sched_clock -#endif +END(sched_clock) #ifdef CONFIG_VIRT_CPU_ACCOUNTING GLOBAL_ENTRY(cycle_to_cputime) diff --git a/trunk/arch/ia64/kernel/ivt.S b/trunk/arch/ia64/kernel/ivt.S index ec9a5fdfa1b9..f675d8e33853 100644 --- a/trunk/arch/ia64/kernel/ivt.S +++ b/trunk/arch/ia64/kernel/ivt.S @@ -804,7 +804,7 @@ ENTRY(break_fault) /////////////////////////////////////////////////////////////////////// st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag #ifdef CONFIG_VIRT_CPU_ACCOUNTING - MOV_FROM_ITC(p0, p14, r30, r18) // M get cycle for accounting + mov.m r30=ar.itc // M get cycle for accounting #else mov b6=r30 // I0 setup syscall handler branch reg early #endif diff --git a/trunk/arch/ia64/kernel/machvec.c b/trunk/arch/ia64/kernel/machvec.c index d41a40ef80c0..7ccb228ceedc 100644 --- a/trunk/arch/ia64/kernel/machvec.c +++ b/trunk/arch/ia64/kernel/machvec.c @@ -1,5 +1,5 @@ #include -#include + #include #include @@ -75,16 +75,14 @@ machvec_timer_interrupt (int irq, void *dev_id) EXPORT_SYMBOL(machvec_timer_interrupt); void -machvec_dma_sync_single(struct device *hwdev, dma_addr_t dma_handle, size_t size, - enum dma_data_direction dir) +machvec_dma_sync_single (struct device *hwdev, dma_addr_t dma_handle, size_t size, int dir) { mb(); } EXPORT_SYMBOL(machvec_dma_sync_single); void -machvec_dma_sync_sg(struct device *hwdev, struct scatterlist *sg, int n, - enum dma_data_direction dir) +machvec_dma_sync_sg (struct device *hwdev, struct scatterlist *sg, int n, int dir) { mb(); } diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index 8f33a8840422..bab1de2d2f6a 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -1456,9 +1456,9 @@ ia64_mca_cmc_int_caller(int cmc_irq, void *arg) ia64_mca_cmc_int_handler(cmc_irq, arg); - cpuid = cpumask_next(cpuid+1, cpu_online_mask); + for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++); - if (cpuid < nr_cpu_ids) { + if (cpuid < NR_CPUS) { platform_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0); } else { /* If no log record, switch out of polling mode */ @@ -1525,7 +1525,7 @@ ia64_mca_cpe_int_caller(int cpe_irq, void *arg) ia64_mca_cpe_int_handler(cpe_irq, arg); - cpuid = cpumask_next(cpuid+1, cpu_online_mask); + for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++); if (cpuid < NR_CPUS) { platform_send_ipi(cpuid, IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0); diff --git a/trunk/arch/ia64/kernel/module.c b/trunk/arch/ia64/kernel/module.c index da3b0cf495a3..aaa7d901521f 100644 --- a/trunk/arch/ia64/kernel/module.c +++ b/trunk/arch/ia64/kernel/module.c @@ -446,14 +446,6 @@ module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings, mod->arch.opd = s; else if (strcmp(".IA_64.unwind", secstrings + s->sh_name) == 0) mod->arch.unwind = s; -#ifdef CONFIG_PARAVIRT - else if (strcmp(".paravirt_bundles", - secstrings + s->sh_name) == 0) - mod->arch.paravirt_bundles = s; - else if (strcmp(".paravirt_insts", - secstrings + s->sh_name) == 0) - mod->arch.paravirt_insts = s; -#endif if (!mod->arch.core_plt || !mod->arch.init_plt || !mod->arch.got || !mod->arch.opd) { printk(KERN_ERR "%s: sections missing\n", mod->name); @@ -533,7 +525,8 @@ get_ltoff (struct module *mod, uint64_t value, int *okp) goto found; /* Not enough GOT entries? */ - BUG_ON(e >= (struct got_entry *) (mod->arch.got->sh_addr + mod->arch.got->sh_size)); + if (e >= (struct got_entry *) (mod->arch.got->sh_addr + mod->arch.got->sh_size)) + BUG(); e->val = value; ++mod->arch.next_got_entry; @@ -928,30 +921,6 @@ module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mo DEBUGP("%s: init: entry=%p\n", __func__, mod->init); if (mod->arch.unwind) register_unwind_table(mod); -#ifdef CONFIG_PARAVIRT - if (mod->arch.paravirt_bundles) { - struct paravirt_patch_site_bundle *start = - (struct paravirt_patch_site_bundle *) - mod->arch.paravirt_bundles->sh_addr; - struct paravirt_patch_site_bundle *end = - (struct paravirt_patch_site_bundle *) - (mod->arch.paravirt_bundles->sh_addr + - mod->arch.paravirt_bundles->sh_size); - - paravirt_patch_apply_bundle(start, end); - } - if (mod->arch.paravirt_insts) { - struct paravirt_patch_site_inst *start = - (struct paravirt_patch_site_inst *) - mod->arch.paravirt_insts->sh_addr; - struct paravirt_patch_site_inst *end = - (struct paravirt_patch_site_inst *) - (mod->arch.paravirt_insts->sh_addr + - mod->arch.paravirt_insts->sh_size); - - paravirt_patch_apply_inst(start, end); - } -#endif return 0; } diff --git a/trunk/arch/ia64/kernel/palinfo.c b/trunk/arch/ia64/kernel/palinfo.c index a4f19c70aadd..e5c57f413ca2 100644 --- a/trunk/arch/ia64/kernel/palinfo.c +++ b/trunk/arch/ia64/kernel/palinfo.c @@ -1002,6 +1002,8 @@ create_palinfo_proc_entries(unsigned int cpu) *pdir = create_proc_read_entry( palinfo_entries[j].name, 0, cpu_dir, palinfo_read_entry, (void *)f.value); + if (*pdir) + (*pdir)->owner = THIS_MODULE; pdir++; } } diff --git a/trunk/arch/ia64/kernel/paravirt.c b/trunk/arch/ia64/kernel/paravirt.c index a21d7bb9c69c..9f14c16f6369 100644 --- a/trunk/arch/ia64/kernel/paravirt.c +++ b/trunk/arch/ia64/kernel/paravirt.c @@ -46,23 +46,13 @@ struct pv_info pv_info = { * initialization hooks. */ -static void __init -ia64_native_patch_branch(unsigned long tag, unsigned long type); - -struct pv_init_ops pv_init_ops = -{ -#ifdef ASM_SUPPORTED - .patch_bundle = ia64_native_patch_bundle, -#endif - .patch_branch = ia64_native_patch_branch, -}; +struct pv_init_ops pv_init_ops; /*************************************************************************** * pv_cpu_ops * intrinsics hooks. */ -#ifndef ASM_SUPPORTED /* ia64_native_xxx are macros so that we have to make them real functions */ #define DEFINE_VOID_FUNC1(name) \ @@ -70,14 +60,7 @@ struct pv_init_ops pv_init_ops = ia64_native_ ## name ## _func(unsigned long arg) \ { \ ia64_native_ ## name(arg); \ - } - -#define DEFINE_VOID_FUNC1_VOID(name) \ - static void \ - ia64_native_ ## name ## _func(void *arg) \ - { \ - ia64_native_ ## name(arg); \ - } + } \ #define DEFINE_VOID_FUNC2(name) \ static void \ @@ -85,7 +68,7 @@ struct pv_init_ops pv_init_ops = unsigned long arg1) \ { \ ia64_native_ ## name(arg0, arg1); \ - } + } \ #define DEFINE_FUNC0(name) \ static unsigned long \ @@ -101,7 +84,7 @@ struct pv_init_ops pv_init_ops = return ia64_native_ ## name(arg); \ } \ -DEFINE_VOID_FUNC1_VOID(fc); +DEFINE_VOID_FUNC1(fc); DEFINE_VOID_FUNC1(intrin_local_irq_restore); DEFINE_VOID_FUNC2(ptcga); @@ -291,266 +274,6 @@ ia64_native_setreg_func(int regnum, unsigned long val) break; } } -#else - -#define __DEFINE_FUNC(name, code) \ - extern const char ia64_native_ ## name ## _direct_start[]; \ - extern const char ia64_native_ ## name ## _direct_end[]; \ - asm (".align 32\n" \ - ".proc ia64_native_" #name "_func\n" \ - "ia64_native_" #name "_func:\n" \ - "ia64_native_" #name "_direct_start:\n" \ - code \ - "ia64_native_" #name "_direct_end:\n" \ - "br.cond.sptk.many b6\n" \ - ".endp ia64_native_" #name "_func\n") - -#define DEFINE_VOID_FUNC0(name, code) \ - extern void \ - ia64_native_ ## name ## _func(void); \ - __DEFINE_FUNC(name, code) - -#define DEFINE_VOID_FUNC1(name, code) \ - extern void \ - ia64_native_ ## name ## _func(unsigned long arg); \ - __DEFINE_FUNC(name, code) - -#define DEFINE_VOID_FUNC1_VOID(name, code) \ - extern void \ - ia64_native_ ## name ## _func(void *arg); \ - __DEFINE_FUNC(name, code) - -#define DEFINE_VOID_FUNC2(name, code) \ - extern void \ - ia64_native_ ## name ## _func(unsigned long arg0, \ - unsigned long arg1); \ - __DEFINE_FUNC(name, code) - -#define DEFINE_FUNC0(name, code) \ - extern unsigned long \ - ia64_native_ ## name ## _func(void); \ - __DEFINE_FUNC(name, code) - -#define DEFINE_FUNC1(name, type, code) \ - extern unsigned long \ - ia64_native_ ## name ## _func(type arg); \ - __DEFINE_FUNC(name, code) - -DEFINE_VOID_FUNC1_VOID(fc, - "fc r8\n"); -DEFINE_VOID_FUNC1(intrin_local_irq_restore, - ";;\n" - " cmp.ne p6, p7 = r8, r0\n" - ";;\n" - "(p6) ssm psr.i\n" - "(p7) rsm psr.i\n" - ";;\n" - "(p6) srlz.d\n"); - -DEFINE_VOID_FUNC2(ptcga, - "ptc.ga r8, r9\n"); -DEFINE_VOID_FUNC2(set_rr, - "mov rr[r8] = r9\n"); - -/* ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I */ -DEFINE_FUNC0(get_psr_i, - "mov r2 = " __stringify(1 << IA64_PSR_I_BIT) "\n" - "mov r8 = psr\n" - ";;\n" - "and r8 = r2, r8\n"); - -DEFINE_FUNC1(thash, unsigned long, - "thash r8 = r8\n"); -DEFINE_FUNC1(get_cpuid, int, - "mov r8 = cpuid[r8]\n"); -DEFINE_FUNC1(get_pmd, int, - "mov r8 = pmd[r8]\n"); -DEFINE_FUNC1(get_rr, unsigned long, - "mov r8 = rr[r8]\n"); - -DEFINE_VOID_FUNC0(ssm_i, - "ssm psr.i\n"); -DEFINE_VOID_FUNC0(rsm_i, - "rsm psr.i\n"); - -extern void -ia64_native_set_rr0_to_rr4_func(unsigned long val0, unsigned long val1, - unsigned long val2, unsigned long val3, - unsigned long val4); -__DEFINE_FUNC(set_rr0_to_rr4, - "mov rr[r0] = r8\n" - "movl r2 = 0x2000000000000000\n" - ";;\n" - "mov rr[r2] = r9\n" - "shl r3 = r2, 1\n" /* movl r3 = 0x4000000000000000 */ - ";;\n" - "add r2 = r2, r3\n" /* movl r2 = 0x6000000000000000 */ - "mov rr[r3] = r10\n" - ";;\n" - "mov rr[r2] = r11\n" - "shl r3 = r3, 1\n" /* movl r3 = 0x8000000000000000 */ - ";;\n" - "mov rr[r3] = r14\n"); - -extern unsigned long ia64_native_getreg_func(int regnum); -asm(".global ia64_native_getreg_func\n"); -#define __DEFINE_GET_REG(id, reg) \ - "mov r2 = " __stringify(_IA64_REG_ ## id) "\n" \ - ";;\n" \ - "cmp.eq p6, p0 = r2, r8\n" \ - ";;\n" \ - "(p6) mov r8 = " #reg "\n" \ - "(p6) br.cond.sptk.many b6\n" \ - ";;\n" -#define __DEFINE_GET_AR(id, reg) __DEFINE_GET_REG(AR_ ## id, ar.reg) -#define __DEFINE_GET_CR(id, reg) __DEFINE_GET_REG(CR_ ## id, cr.reg) - -__DEFINE_FUNC(getreg, - __DEFINE_GET_REG(GP, gp) - /*__DEFINE_GET_REG(IP, ip)*/ /* returned ip value shouldn't be constant */ - __DEFINE_GET_REG(PSR, psr) - __DEFINE_GET_REG(TP, tp) - __DEFINE_GET_REG(SP, sp) - - __DEFINE_GET_REG(AR_KR0, ar0) - __DEFINE_GET_REG(AR_KR1, ar1) - __DEFINE_GET_REG(AR_KR2, ar2) - __DEFINE_GET_REG(AR_KR3, ar3) - __DEFINE_GET_REG(AR_KR4, ar4) - __DEFINE_GET_REG(AR_KR5, ar5) - __DEFINE_GET_REG(AR_KR6, ar6) - __DEFINE_GET_REG(AR_KR7, ar7) - __DEFINE_GET_AR(RSC, rsc) - __DEFINE_GET_AR(BSP, bsp) - __DEFINE_GET_AR(BSPSTORE, bspstore) - __DEFINE_GET_AR(RNAT, rnat) - __DEFINE_GET_AR(FCR, fcr) - __DEFINE_GET_AR(EFLAG, eflag) - __DEFINE_GET_AR(CSD, csd) - __DEFINE_GET_AR(SSD, ssd) - __DEFINE_GET_REG(AR_CFLAG, ar27) - __DEFINE_GET_AR(FSR, fsr) - __DEFINE_GET_AR(FIR, fir) - __DEFINE_GET_AR(FDR, fdr) - __DEFINE_GET_AR(CCV, ccv) - __DEFINE_GET_AR(UNAT, unat) - __DEFINE_GET_AR(FPSR, fpsr) - __DEFINE_GET_AR(ITC, itc) - __DEFINE_GET_AR(PFS, pfs) - __DEFINE_GET_AR(LC, lc) - __DEFINE_GET_AR(EC, ec) - - __DEFINE_GET_CR(DCR, dcr) - __DEFINE_GET_CR(ITM, itm) - __DEFINE_GET_CR(IVA, iva) - __DEFINE_GET_CR(PTA, pta) - __DEFINE_GET_CR(IPSR, ipsr) - __DEFINE_GET_CR(ISR, isr) - __DEFINE_GET_CR(IIP, iip) - __DEFINE_GET_CR(IFA, ifa) - __DEFINE_GET_CR(ITIR, itir) - __DEFINE_GET_CR(IIPA, iipa) - __DEFINE_GET_CR(IFS, ifs) - __DEFINE_GET_CR(IIM, iim) - __DEFINE_GET_CR(IHA, iha) - __DEFINE_GET_CR(LID, lid) - __DEFINE_GET_CR(IVR, ivr) - __DEFINE_GET_CR(TPR, tpr) - __DEFINE_GET_CR(EOI, eoi) - __DEFINE_GET_CR(IRR0, irr0) - __DEFINE_GET_CR(IRR1, irr1) - __DEFINE_GET_CR(IRR2, irr2) - __DEFINE_GET_CR(IRR3, irr3) - __DEFINE_GET_CR(ITV, itv) - __DEFINE_GET_CR(PMV, pmv) - __DEFINE_GET_CR(CMCV, cmcv) - __DEFINE_GET_CR(LRR0, lrr0) - __DEFINE_GET_CR(LRR1, lrr1) - - "mov r8 = -1\n" /* unsupported case */ - ); - -extern void ia64_native_setreg_func(int regnum, unsigned long val); -asm(".global ia64_native_setreg_func\n"); -#define __DEFINE_SET_REG(id, reg) \ - "mov r2 = " __stringify(_IA64_REG_ ## id) "\n" \ - ";;\n" \ - "cmp.eq p6, p0 = r2, r9\n" \ - ";;\n" \ - "(p6) mov " #reg " = r8\n" \ - "(p6) br.cond.sptk.many b6\n" \ - ";;\n" -#define __DEFINE_SET_AR(id, reg) __DEFINE_SET_REG(AR_ ## id, ar.reg) -#define __DEFINE_SET_CR(id, reg) __DEFINE_SET_REG(CR_ ## id, cr.reg) -__DEFINE_FUNC(setreg, - "mov r2 = " __stringify(_IA64_REG_PSR_L) "\n" - ";;\n" - "cmp.eq p6, p0 = r2, r9\n" - ";;\n" - "(p6) mov psr.l = r8\n" -#ifdef HAVE_SERIALIZE_DIRECTIVE - ".serialize.data\n" -#endif - "(p6) br.cond.sptk.many b6\n" - __DEFINE_SET_REG(GP, gp) - __DEFINE_SET_REG(SP, sp) - - __DEFINE_SET_REG(AR_KR0, ar0) - __DEFINE_SET_REG(AR_KR1, ar1) - __DEFINE_SET_REG(AR_KR2, ar2) - __DEFINE_SET_REG(AR_KR3, ar3) - __DEFINE_SET_REG(AR_KR4, ar4) - __DEFINE_SET_REG(AR_KR5, ar5) - __DEFINE_SET_REG(AR_KR6, ar6) - __DEFINE_SET_REG(AR_KR7, ar7) - __DEFINE_SET_AR(RSC, rsc) - __DEFINE_SET_AR(BSP, bsp) - __DEFINE_SET_AR(BSPSTORE, bspstore) - __DEFINE_SET_AR(RNAT, rnat) - __DEFINE_SET_AR(FCR, fcr) - __DEFINE_SET_AR(EFLAG, eflag) - __DEFINE_SET_AR(CSD, csd) - __DEFINE_SET_AR(SSD, ssd) - __DEFINE_SET_REG(AR_CFLAG, ar27) - __DEFINE_SET_AR(FSR, fsr) - __DEFINE_SET_AR(FIR, fir) - __DEFINE_SET_AR(FDR, fdr) - __DEFINE_SET_AR(CCV, ccv) - __DEFINE_SET_AR(UNAT, unat) - __DEFINE_SET_AR(FPSR, fpsr) - __DEFINE_SET_AR(ITC, itc) - __DEFINE_SET_AR(PFS, pfs) - __DEFINE_SET_AR(LC, lc) - __DEFINE_SET_AR(EC, ec) - - __DEFINE_SET_CR(DCR, dcr) - __DEFINE_SET_CR(ITM, itm) - __DEFINE_SET_CR(IVA, iva) - __DEFINE_SET_CR(PTA, pta) - __DEFINE_SET_CR(IPSR, ipsr) - __DEFINE_SET_CR(ISR, isr) - __DEFINE_SET_CR(IIP, iip) - __DEFINE_SET_CR(IFA, ifa) - __DEFINE_SET_CR(ITIR, itir) - __DEFINE_SET_CR(IIPA, iipa) - __DEFINE_SET_CR(IFS, ifs) - __DEFINE_SET_CR(IIM, iim) - __DEFINE_SET_CR(IHA, iha) - __DEFINE_SET_CR(LID, lid) - __DEFINE_SET_CR(IVR, ivr) - __DEFINE_SET_CR(TPR, tpr) - __DEFINE_SET_CR(EOI, eoi) - __DEFINE_SET_CR(IRR0, irr0) - __DEFINE_SET_CR(IRR1, irr1) - __DEFINE_SET_CR(IRR2, irr2) - __DEFINE_SET_CR(IRR3, irr3) - __DEFINE_SET_CR(ITV, itv) - __DEFINE_SET_CR(PMV, pmv) - __DEFINE_SET_CR(CMCV, cmcv) - __DEFINE_SET_CR(LRR0, lrr0) - __DEFINE_SET_CR(LRR1, lrr1) - ); -#endif struct pv_cpu_ops pv_cpu_ops = { .fc = ia64_native_fc_func, @@ -643,258 +366,4 @@ ia64_native_do_steal_accounting(unsigned long *new_itm) struct pv_time_ops pv_time_ops = { .do_steal_accounting = ia64_native_do_steal_accounting, - .sched_clock = ia64_native_sched_clock, -}; - -/*************************************************************************** - * binary pacthing - * pv_init_ops.patch_bundle - */ - -#ifdef ASM_SUPPORTED -#define IA64_NATIVE_PATCH_DEFINE_GET_REG(name, reg) \ - __DEFINE_FUNC(get_ ## name, \ - ";;\n" \ - "mov r8 = " #reg "\n" \ - ";;\n") - -#define IA64_NATIVE_PATCH_DEFINE_SET_REG(name, reg) \ - __DEFINE_FUNC(set_ ## name, \ - ";;\n" \ - "mov " #reg " = r8\n" \ - ";;\n") - -#define IA64_NATIVE_PATCH_DEFINE_REG(name, reg) \ - IA64_NATIVE_PATCH_DEFINE_GET_REG(name, reg); \ - IA64_NATIVE_PATCH_DEFINE_SET_REG(name, reg) \ - -#define IA64_NATIVE_PATCH_DEFINE_AR(name, reg) \ - IA64_NATIVE_PATCH_DEFINE_REG(ar_ ## name, ar.reg) - -#define IA64_NATIVE_PATCH_DEFINE_CR(name, reg) \ - IA64_NATIVE_PATCH_DEFINE_REG(cr_ ## name, cr.reg) - - -IA64_NATIVE_PATCH_DEFINE_GET_REG(psr, psr); -IA64_NATIVE_PATCH_DEFINE_GET_REG(tp, tp); - -/* IA64_NATIVE_PATCH_DEFINE_SET_REG(psr_l, psr.l); */ -__DEFINE_FUNC(set_psr_l, - ";;\n" - "mov psr.l = r8\n" -#ifdef HAVE_SERIALIZE_DIRECTIVE - ".serialize.data\n" -#endif - ";;\n"); - -IA64_NATIVE_PATCH_DEFINE_REG(gp, gp); -IA64_NATIVE_PATCH_DEFINE_REG(sp, sp); - -IA64_NATIVE_PATCH_DEFINE_REG(kr0, ar0); -IA64_NATIVE_PATCH_DEFINE_REG(kr1, ar1); -IA64_NATIVE_PATCH_DEFINE_REG(kr2, ar2); -IA64_NATIVE_PATCH_DEFINE_REG(kr3, ar3); -IA64_NATIVE_PATCH_DEFINE_REG(kr4, ar4); -IA64_NATIVE_PATCH_DEFINE_REG(kr5, ar5); -IA64_NATIVE_PATCH_DEFINE_REG(kr6, ar6); -IA64_NATIVE_PATCH_DEFINE_REG(kr7, ar7); - -IA64_NATIVE_PATCH_DEFINE_AR(rsc, rsc); -IA64_NATIVE_PATCH_DEFINE_AR(bsp, bsp); -IA64_NATIVE_PATCH_DEFINE_AR(bspstore, bspstore); -IA64_NATIVE_PATCH_DEFINE_AR(rnat, rnat); -IA64_NATIVE_PATCH_DEFINE_AR(fcr, fcr); -IA64_NATIVE_PATCH_DEFINE_AR(eflag, eflag); -IA64_NATIVE_PATCH_DEFINE_AR(csd, csd); -IA64_NATIVE_PATCH_DEFINE_AR(ssd, ssd); -IA64_NATIVE_PATCH_DEFINE_REG(ar27, ar27); -IA64_NATIVE_PATCH_DEFINE_AR(fsr, fsr); -IA64_NATIVE_PATCH_DEFINE_AR(fir, fir); -IA64_NATIVE_PATCH_DEFINE_AR(fdr, fdr); -IA64_NATIVE_PATCH_DEFINE_AR(ccv, ccv); -IA64_NATIVE_PATCH_DEFINE_AR(unat, unat); -IA64_NATIVE_PATCH_DEFINE_AR(fpsr, fpsr); -IA64_NATIVE_PATCH_DEFINE_AR(itc, itc); -IA64_NATIVE_PATCH_DEFINE_AR(pfs, pfs); -IA64_NATIVE_PATCH_DEFINE_AR(lc, lc); -IA64_NATIVE_PATCH_DEFINE_AR(ec, ec); - -IA64_NATIVE_PATCH_DEFINE_CR(dcr, dcr); -IA64_NATIVE_PATCH_DEFINE_CR(itm, itm); -IA64_NATIVE_PATCH_DEFINE_CR(iva, iva); -IA64_NATIVE_PATCH_DEFINE_CR(pta, pta); -IA64_NATIVE_PATCH_DEFINE_CR(ipsr, ipsr); -IA64_NATIVE_PATCH_DEFINE_CR(isr, isr); -IA64_NATIVE_PATCH_DEFINE_CR(iip, iip); -IA64_NATIVE_PATCH_DEFINE_CR(ifa, ifa); -IA64_NATIVE_PATCH_DEFINE_CR(itir, itir); -IA64_NATIVE_PATCH_DEFINE_CR(iipa, iipa); -IA64_NATIVE_PATCH_DEFINE_CR(ifs, ifs); -IA64_NATIVE_PATCH_DEFINE_CR(iim, iim); -IA64_NATIVE_PATCH_DEFINE_CR(iha, iha); -IA64_NATIVE_PATCH_DEFINE_CR(lid, lid); -IA64_NATIVE_PATCH_DEFINE_CR(ivr, ivr); -IA64_NATIVE_PATCH_DEFINE_CR(tpr, tpr); -IA64_NATIVE_PATCH_DEFINE_CR(eoi, eoi); -IA64_NATIVE_PATCH_DEFINE_CR(irr0, irr0); -IA64_NATIVE_PATCH_DEFINE_CR(irr1, irr1); -IA64_NATIVE_PATCH_DEFINE_CR(irr2, irr2); -IA64_NATIVE_PATCH_DEFINE_CR(irr3, irr3); -IA64_NATIVE_PATCH_DEFINE_CR(itv, itv); -IA64_NATIVE_PATCH_DEFINE_CR(pmv, pmv); -IA64_NATIVE_PATCH_DEFINE_CR(cmcv, cmcv); -IA64_NATIVE_PATCH_DEFINE_CR(lrr0, lrr0); -IA64_NATIVE_PATCH_DEFINE_CR(lrr1, lrr1); - -static const struct paravirt_patch_bundle_elem ia64_native_patch_bundle_elems[] -__initdata_or_module = -{ -#define IA64_NATIVE_PATCH_BUNDLE_ELEM(name, type) \ - { \ - (void*)ia64_native_ ## name ## _direct_start, \ - (void*)ia64_native_ ## name ## _direct_end, \ - PARAVIRT_PATCH_TYPE_ ## type, \ - } - - IA64_NATIVE_PATCH_BUNDLE_ELEM(fc, FC), - IA64_NATIVE_PATCH_BUNDLE_ELEM(thash, THASH), - IA64_NATIVE_PATCH_BUNDLE_ELEM(get_cpuid, GET_CPUID), - IA64_NATIVE_PATCH_BUNDLE_ELEM(get_pmd, GET_PMD), - IA64_NATIVE_PATCH_BUNDLE_ELEM(ptcga, PTCGA), - IA64_NATIVE_PATCH_BUNDLE_ELEM(get_rr, GET_RR), - IA64_NATIVE_PATCH_BUNDLE_ELEM(set_rr, SET_RR), - IA64_NATIVE_PATCH_BUNDLE_ELEM(set_rr0_to_rr4, SET_RR0_TO_RR4), - IA64_NATIVE_PATCH_BUNDLE_ELEM(ssm_i, SSM_I), - IA64_NATIVE_PATCH_BUNDLE_ELEM(rsm_i, RSM_I), - IA64_NATIVE_PATCH_BUNDLE_ELEM(get_psr_i, GET_PSR_I), - IA64_NATIVE_PATCH_BUNDLE_ELEM(intrin_local_irq_restore, - INTRIN_LOCAL_IRQ_RESTORE), - -#define IA64_NATIVE_PATCH_BUNDLE_ELEM_GETREG(name, reg) \ - { \ - (void*)ia64_native_get_ ## name ## _direct_start, \ - (void*)ia64_native_get_ ## name ## _direct_end, \ - PARAVIRT_PATCH_TYPE_GETREG + _IA64_REG_ ## reg, \ - } - -#define IA64_NATIVE_PATCH_BUNDLE_ELEM_SETREG(name, reg) \ - { \ - (void*)ia64_native_set_ ## name ## _direct_start, \ - (void*)ia64_native_set_ ## name ## _direct_end, \ - PARAVIRT_PATCH_TYPE_SETREG + _IA64_REG_ ## reg, \ - } - -#define IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(name, reg) \ - IA64_NATIVE_PATCH_BUNDLE_ELEM_GETREG(name, reg), \ - IA64_NATIVE_PATCH_BUNDLE_ELEM_SETREG(name, reg) \ - -#define IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(name, reg) \ - IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(ar_ ## name, AR_ ## reg) - -#define IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(name, reg) \ - IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(cr_ ## name, CR_ ## reg) - - IA64_NATIVE_PATCH_BUNDLE_ELEM_GETREG(psr, PSR), - IA64_NATIVE_PATCH_BUNDLE_ELEM_GETREG(tp, TP), - - IA64_NATIVE_PATCH_BUNDLE_ELEM_SETREG(psr_l, PSR_L), - - IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(gp, GP), - IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(sp, SP), - - IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr0, AR_KR0), - IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr1, AR_KR1), - IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr2, AR_KR2), - IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr3, AR_KR3), - IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr4, AR_KR4), - IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr5, AR_KR5), - IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr6, AR_KR6), - IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr7, AR_KR7), - - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(rsc, RSC), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(bsp, BSP), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(bspstore, BSPSTORE), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(rnat, RNAT), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fcr, FCR), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(eflag, EFLAG), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(csd, CSD), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(ssd, SSD), - IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(ar27, AR_CFLAG), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fsr, FSR), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fir, FIR), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fdr, FDR), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(ccv, CCV), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(unat, UNAT), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fpsr, FPSR), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(itc, ITC), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(pfs, PFS), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(lc, LC), - IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(ec, EC), - - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(dcr, DCR), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(itm, ITM), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iva, IVA), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(pta, PTA), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(ipsr, IPSR), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(isr, ISR), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iip, IIP), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(ifa, IFA), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(itir, ITIR), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iipa, IIPA), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(ifs, IFS), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iim, IIM), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iha, IHA), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(lid, LID), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(ivr, IVR), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(tpr, TPR), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(eoi, EOI), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(irr0, IRR0), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(irr1, IRR1), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(irr2, IRR2), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(irr3, IRR3), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(itv, ITV), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(pmv, PMV), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(cmcv, CMCV), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(lrr0, LRR0), - IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(lrr1, LRR1), }; - -unsigned long __init_or_module -ia64_native_patch_bundle(void *sbundle, void *ebundle, unsigned long type) -{ - const unsigned long nelems = sizeof(ia64_native_patch_bundle_elems) / - sizeof(ia64_native_patch_bundle_elems[0]); - - return __paravirt_patch_apply_bundle(sbundle, ebundle, type, - ia64_native_patch_bundle_elems, - nelems, NULL); -} -#endif /* ASM_SUPPOTED */ - -extern const char ia64_native_switch_to[]; -extern const char ia64_native_leave_syscall[]; -extern const char ia64_native_work_processed_syscall[]; -extern const char ia64_native_leave_kernel[]; - -const struct paravirt_patch_branch_target ia64_native_branch_target[] -__initconst = { -#define PARAVIRT_BR_TARGET(name, type) \ - { \ - ia64_native_ ## name, \ - PARAVIRT_PATCH_TYPE_BR_ ## type, \ - } - PARAVIRT_BR_TARGET(switch_to, SWITCH_TO), - PARAVIRT_BR_TARGET(leave_syscall, LEAVE_SYSCALL), - PARAVIRT_BR_TARGET(work_processed_syscall, WORK_PROCESSED_SYSCALL), - PARAVIRT_BR_TARGET(leave_kernel, LEAVE_KERNEL), -}; - -static void __init -ia64_native_patch_branch(unsigned long tag, unsigned long type) -{ - const unsigned long nelem = - sizeof(ia64_native_branch_target) / - sizeof(ia64_native_branch_target[0]); - __paravirt_patch_apply_branch(tag, type, - ia64_native_branch_target, nelem); -} diff --git a/trunk/arch/ia64/kernel/paravirt_patch.c b/trunk/arch/ia64/kernel/paravirt_patch.c deleted file mode 100644 index bfdfef1b1ffd..000000000000 --- a/trunk/arch/ia64/kernel/paravirt_patch.c +++ /dev/null @@ -1,514 +0,0 @@ -/****************************************************************************** - * linux/arch/ia64/xen/paravirt_patch.c - * - * Copyright (c) 2008 Isaku Yamahata - * VA Linux Systems Japan K.K. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include - -typedef union ia64_inst { - struct { - unsigned long long qp : 6; - unsigned long long : 31; - unsigned long long opcode : 4; - unsigned long long reserved : 23; - } generic; - unsigned long long l; -} ia64_inst_t; - -/* - * flush_icache_range() can't be used here. - * we are here before cpu_init() which initializes - * ia64_i_cache_stride_shift. flush_icache_range() uses it. - */ -void __init_or_module -paravirt_flush_i_cache_range(const void *instr, unsigned long size) -{ - extern void paravirt_fc_i(const void *addr); - unsigned long i; - - for (i = 0; i < size; i += sizeof(bundle_t)) - paravirt_fc_i(instr + i); -} - -bundle_t* __init_or_module -paravirt_get_bundle(unsigned long tag) -{ - return (bundle_t *)(tag & ~3UL); -} - -unsigned long __init_or_module -paravirt_get_slot(unsigned long tag) -{ - return tag & 3UL; -} - -unsigned long __init_or_module -paravirt_get_num_inst(unsigned long stag, unsigned long etag) -{ - bundle_t *sbundle = paravirt_get_bundle(stag); - unsigned long sslot = paravirt_get_slot(stag); - bundle_t *ebundle = paravirt_get_bundle(etag); - unsigned long eslot = paravirt_get_slot(etag); - - return (ebundle - sbundle) * 3 + eslot - sslot + 1; -} - -unsigned long __init_or_module -paravirt_get_next_tag(unsigned long tag) -{ - unsigned long slot = paravirt_get_slot(tag); - - switch (slot) { - case 0: - case 1: - return tag + 1; - case 2: { - bundle_t *bundle = paravirt_get_bundle(tag); - return (unsigned long)(bundle + 1); - } - default: - BUG(); - } - /* NOTREACHED */ -} - -ia64_inst_t __init_or_module -paravirt_read_slot0(const bundle_t *bundle) -{ - ia64_inst_t inst; - inst.l = bundle->quad0.slot0; - return inst; -} - -ia64_inst_t __init_or_module -paravirt_read_slot1(const bundle_t *bundle) -{ - ia64_inst_t inst; - inst.l = bundle->quad0.slot1_p0 | - ((unsigned long long)bundle->quad1.slot1_p1 << 18UL); - return inst; -} - -ia64_inst_t __init_or_module -paravirt_read_slot2(const bundle_t *bundle) -{ - ia64_inst_t inst; - inst.l = bundle->quad1.slot2; - return inst; -} - -ia64_inst_t __init_or_module -paravirt_read_inst(unsigned long tag) -{ - bundle_t *bundle = paravirt_get_bundle(tag); - unsigned long slot = paravirt_get_slot(tag); - - switch (slot) { - case 0: - return paravirt_read_slot0(bundle); - case 1: - return paravirt_read_slot1(bundle); - case 2: - return paravirt_read_slot2(bundle); - default: - BUG(); - } - /* NOTREACHED */ -} - -void __init_or_module -paravirt_write_slot0(bundle_t *bundle, ia64_inst_t inst) -{ - bundle->quad0.slot0 = inst.l; -} - -void __init_or_module -paravirt_write_slot1(bundle_t *bundle, ia64_inst_t inst) -{ - bundle->quad0.slot1_p0 = inst.l; - bundle->quad1.slot1_p1 = inst.l >> 18UL; -} - -void __init_or_module -paravirt_write_slot2(bundle_t *bundle, ia64_inst_t inst) -{ - bundle->quad1.slot2 = inst.l; -} - -void __init_or_module -paravirt_write_inst(unsigned long tag, ia64_inst_t inst) -{ - bundle_t *bundle = paravirt_get_bundle(tag); - unsigned long slot = paravirt_get_slot(tag); - - switch (slot) { - case 0: - paravirt_write_slot0(bundle, inst); - break; - case 1: - paravirt_write_slot1(bundle, inst); - break; - case 2: - paravirt_write_slot2(bundle, inst); - break; - default: - BUG(); - break; - } - paravirt_flush_i_cache_range(bundle, sizeof(*bundle)); -} - -/* for debug */ -void -paravirt_print_bundle(const bundle_t *bundle) -{ - const unsigned long *quad = (const unsigned long *)bundle; - ia64_inst_t slot0 = paravirt_read_slot0(bundle); - ia64_inst_t slot1 = paravirt_read_slot1(bundle); - ia64_inst_t slot2 = paravirt_read_slot2(bundle); - - printk(KERN_DEBUG - "bundle 0x%p 0x%016lx 0x%016lx\n", bundle, quad[0], quad[1]); - printk(KERN_DEBUG - "bundle template 0x%x\n", - bundle->quad0.template); - printk(KERN_DEBUG - "slot0 0x%lx slot1_p0 0x%lx slot1_p1 0x%lx slot2 0x%lx\n", - (unsigned long)bundle->quad0.slot0, - (unsigned long)bundle->quad0.slot1_p0, - (unsigned long)bundle->quad1.slot1_p1, - (unsigned long)bundle->quad1.slot2); - printk(KERN_DEBUG - "slot0 0x%016llx slot1 0x%016llx slot2 0x%016llx\n", - slot0.l, slot1.l, slot2.l); -} - -static int noreplace_paravirt __init_or_module = 0; - -static int __init setup_noreplace_paravirt(char *str) -{ - noreplace_paravirt = 1; - return 1; -} -__setup("noreplace-paravirt", setup_noreplace_paravirt); - -#ifdef ASM_SUPPORTED -static void __init_or_module -fill_nop_bundle(void *sbundle, void *ebundle) -{ - extern const char paravirt_nop_bundle[]; - extern const unsigned long paravirt_nop_bundle_size; - - void *bundle = sbundle; - - BUG_ON((((unsigned long)sbundle) % sizeof(bundle_t)) != 0); - BUG_ON((((unsigned long)ebundle) % sizeof(bundle_t)) != 0); - - while (bundle < ebundle) { - memcpy(bundle, paravirt_nop_bundle, paravirt_nop_bundle_size); - - bundle += paravirt_nop_bundle_size; - } -} - -/* helper function */ -unsigned long __init_or_module -__paravirt_patch_apply_bundle(void *sbundle, void *ebundle, unsigned long type, - const struct paravirt_patch_bundle_elem *elems, - unsigned long nelems, - const struct paravirt_patch_bundle_elem **found) -{ - unsigned long used = 0; - unsigned long i; - - BUG_ON((((unsigned long)sbundle) % sizeof(bundle_t)) != 0); - BUG_ON((((unsigned long)ebundle) % sizeof(bundle_t)) != 0); - - found = NULL; - for (i = 0; i < nelems; i++) { - const struct paravirt_patch_bundle_elem *p = &elems[i]; - if (p->type == type) { - unsigned long need = p->ebundle - p->sbundle; - unsigned long room = ebundle - sbundle; - - if (found != NULL) - *found = p; - - if (room < need) { - /* no room to replace. skip it */ - printk(KERN_DEBUG - "the space is too small to put " - "bundles. type %ld need %ld room %ld\n", - type, need, room); - break; - } - - used = need; - memcpy(sbundle, p->sbundle, used); - break; - } - } - - return used; -} - -void __init_or_module -paravirt_patch_apply_bundle(const struct paravirt_patch_site_bundle *start, - const struct paravirt_patch_site_bundle *end) -{ - const struct paravirt_patch_site_bundle *p; - - if (noreplace_paravirt) - return; - if (pv_init_ops.patch_bundle == NULL) - return; - - for (p = start; p < end; p++) { - unsigned long used; - - used = (*pv_init_ops.patch_bundle)(p->sbundle, p->ebundle, - p->type); - if (used == 0) - continue; - - fill_nop_bundle(p->sbundle + used, p->ebundle); - paravirt_flush_i_cache_range(p->sbundle, - p->ebundle - p->sbundle); - } - ia64_sync_i(); - ia64_srlz_i(); -} - -/* - * nop.i, nop.m, nop.f instruction are same format. - * but nop.b has differennt format. - * This doesn't support nop.b for now. - */ -static void __init_or_module -fill_nop_inst(unsigned long stag, unsigned long etag) -{ - extern const bundle_t paravirt_nop_mfi_inst_bundle[]; - unsigned long tag; - const ia64_inst_t nop_inst = - paravirt_read_slot0(paravirt_nop_mfi_inst_bundle); - - for (tag = stag; tag < etag; tag = paravirt_get_next_tag(tag)) - paravirt_write_inst(tag, nop_inst); -} - -void __init_or_module -paravirt_patch_apply_inst(const struct paravirt_patch_site_inst *start, - const struct paravirt_patch_site_inst *end) -{ - const struct paravirt_patch_site_inst *p; - - if (noreplace_paravirt) - return; - if (pv_init_ops.patch_inst == NULL) - return; - - for (p = start; p < end; p++) { - unsigned long tag; - bundle_t *sbundle; - bundle_t *ebundle; - - tag = (*pv_init_ops.patch_inst)(p->stag, p->etag, p->type); - if (tag == p->stag) - continue; - - fill_nop_inst(tag, p->etag); - sbundle = paravirt_get_bundle(p->stag); - ebundle = paravirt_get_bundle(p->etag) + 1; - paravirt_flush_i_cache_range(sbundle, (ebundle - sbundle) * - sizeof(bundle_t)); - } - ia64_sync_i(); - ia64_srlz_i(); -} -#endif /* ASM_SUPPOTED */ - -/* brl.cond.sptk.many X3 */ -typedef union inst_x3_op { - ia64_inst_t inst; - struct { - unsigned long qp: 6; - unsigned long btyp: 3; - unsigned long unused: 3; - unsigned long p: 1; - unsigned long imm20b: 20; - unsigned long wh: 2; - unsigned long d: 1; - unsigned long i: 1; - unsigned long opcode: 4; - }; - unsigned long l; -} inst_x3_op_t; - -typedef union inst_x3_imm { - ia64_inst_t inst; - struct { - unsigned long unused: 2; - unsigned long imm39: 39; - }; - unsigned long l; -} inst_x3_imm_t; - -void __init_or_module -paravirt_patch_reloc_brl(unsigned long tag, const void *target) -{ - unsigned long tag_op = paravirt_get_next_tag(tag); - unsigned long tag_imm = tag; - bundle_t *bundle = paravirt_get_bundle(tag); - - ia64_inst_t inst_op = paravirt_read_inst(tag_op); - ia64_inst_t inst_imm = paravirt_read_inst(tag_imm); - - inst_x3_op_t inst_x3_op = { .l = inst_op.l }; - inst_x3_imm_t inst_x3_imm = { .l = inst_imm.l }; - - unsigned long imm60 = - ((unsigned long)target - (unsigned long)bundle) >> 4; - - BUG_ON(paravirt_get_slot(tag) != 1); /* MLX */ - BUG_ON(((unsigned long)target & (sizeof(bundle_t) - 1)) != 0); - - /* imm60[59] 1bit */ - inst_x3_op.i = (imm60 >> 59) & 1; - /* imm60[19:0] 20bit */ - inst_x3_op.imm20b = imm60 & ((1UL << 20) - 1); - /* imm60[58:20] 39bit */ - inst_x3_imm.imm39 = (imm60 >> 20) & ((1UL << 39) - 1); - - inst_op.l = inst_x3_op.l; - inst_imm.l = inst_x3_imm.l; - - paravirt_write_inst(tag_op, inst_op); - paravirt_write_inst(tag_imm, inst_imm); -} - -/* br.cond.sptk.many B1 */ -typedef union inst_b1 { - ia64_inst_t inst; - struct { - unsigned long qp: 6; - unsigned long btype: 3; - unsigned long unused: 3; - unsigned long p: 1; - unsigned long imm20b: 20; - unsigned long wh: 2; - unsigned long d: 1; - unsigned long s: 1; - unsigned long opcode: 4; - }; - unsigned long l; -} inst_b1_t; - -void __init -paravirt_patch_reloc_br(unsigned long tag, const void *target) -{ - bundle_t *bundle = paravirt_get_bundle(tag); - ia64_inst_t inst = paravirt_read_inst(tag); - unsigned long target25 = (unsigned long)target - (unsigned long)bundle; - inst_b1_t inst_b1; - - BUG_ON(((unsigned long)target & (sizeof(bundle_t) - 1)) != 0); - - inst_b1.l = inst.l; - if (target25 & (1UL << 63)) - inst_b1.s = 1; - else - inst_b1.s = 0; - - inst_b1.imm20b = target25 >> 4; - inst.l = inst_b1.l; - - paravirt_write_inst(tag, inst); -} - -void __init -__paravirt_patch_apply_branch( - unsigned long tag, unsigned long type, - const struct paravirt_patch_branch_target *entries, - unsigned int nr_entries) -{ - unsigned int i; - for (i = 0; i < nr_entries; i++) { - if (entries[i].type == type) { - paravirt_patch_reloc_br(tag, entries[i].entry); - break; - } - } -} - -static void __init -paravirt_patch_apply_branch(const struct paravirt_patch_site_branch *start, - const struct paravirt_patch_site_branch *end) -{ - const struct paravirt_patch_site_branch *p; - - if (noreplace_paravirt) - return; - if (pv_init_ops.patch_branch == NULL) - return; - - for (p = start; p < end; p++) - (*pv_init_ops.patch_branch)(p->tag, p->type); - - ia64_sync_i(); - ia64_srlz_i(); -} - -void __init -paravirt_patch_apply(void) -{ - extern const char __start_paravirt_bundles[]; - extern const char __stop_paravirt_bundles[]; - extern const char __start_paravirt_insts[]; - extern const char __stop_paravirt_insts[]; - extern const char __start_paravirt_branches[]; - extern const char __stop_paravirt_branches[]; - - paravirt_patch_apply_bundle((const struct paravirt_patch_site_bundle *) - __start_paravirt_bundles, - (const struct paravirt_patch_site_bundle *) - __stop_paravirt_bundles); - paravirt_patch_apply_inst((const struct paravirt_patch_site_inst *) - __start_paravirt_insts, - (const struct paravirt_patch_site_inst *) - __stop_paravirt_insts); - paravirt_patch_apply_branch((const struct paravirt_patch_site_branch *) - __start_paravirt_branches, - (const struct paravirt_patch_site_branch *) - __stop_paravirt_branches); -} - -/* - * Local variables: - * mode: C - * c-set-style: "linux" - * c-basic-offset: 8 - * tab-width: 8 - * indent-tabs-mode: t - * End: - */ diff --git a/trunk/arch/ia64/kernel/paravirt_patchlist.c b/trunk/arch/ia64/kernel/paravirt_patchlist.c deleted file mode 100644 index b28082a95d45..000000000000 --- a/trunk/arch/ia64/kernel/paravirt_patchlist.c +++ /dev/null @@ -1,79 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2008 Isaku Yamahata - * VA Linux Systems Japan K.K. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include - -#define DECLARE(name) \ - extern unsigned long \ - __ia64_native_start_gate_##name##_patchlist[]; \ - extern unsigned long \ - __ia64_native_end_gate_##name##_patchlist[] - -DECLARE(fsyscall); -DECLARE(brl_fsys_bubble_down); -DECLARE(vtop); -DECLARE(mckinley_e9); - -extern unsigned long __start_gate_section[]; - -#define ASSIGN(name) \ - .start_##name##_patchlist = \ - (unsigned long)__ia64_native_start_gate_##name##_patchlist, \ - .end_##name##_patchlist = \ - (unsigned long)__ia64_native_end_gate_##name##_patchlist - -struct pv_patchdata pv_patchdata __initdata = { - ASSIGN(fsyscall), - ASSIGN(brl_fsys_bubble_down), - ASSIGN(vtop), - ASSIGN(mckinley_e9), - - .gate_section = (void*)__start_gate_section, -}; - - -unsigned long __init -paravirt_get_gate_patchlist(enum pv_gate_patchlist type) -{ - -#define CASE(NAME, name) \ - case PV_GATE_START_##NAME: \ - return pv_patchdata.start_##name##_patchlist; \ - case PV_GATE_END_##NAME: \ - return pv_patchdata.end_##name##_patchlist; \ - - switch (type) { - CASE(FSYSCALL, fsyscall); - CASE(BRL_FSYS_BUBBLE_DOWN, brl_fsys_bubble_down); - CASE(VTOP, vtop); - CASE(MCKINLEY_E9, mckinley_e9); - default: - BUG(); - break; - } - return 0; -} - -void * __init -paravirt_get_gate_section(void) -{ - return pv_patchdata.gate_section; -} diff --git a/trunk/arch/ia64/kernel/paravirt_patchlist.h b/trunk/arch/ia64/kernel/paravirt_patchlist.h deleted file mode 100644 index 0684aa6c6507..000000000000 --- a/trunk/arch/ia64/kernel/paravirt_patchlist.h +++ /dev/null @@ -1,28 +0,0 @@ -/****************************************************************************** - * linux/arch/ia64/xen/paravirt_patchlist.h - * - * Copyright (c) 2008 Isaku Yamahata - * VA Linux Systems Japan K.K. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#if defined(__IA64_GATE_PARAVIRTUALIZED_XEN) -#include -#else -#include -#endif - diff --git a/trunk/arch/ia64/kernel/paravirtentry.S b/trunk/arch/ia64/kernel/paravirtentry.S index 6158560d7f17..2f42fcb9776a 100644 --- a/trunk/arch/ia64/kernel/paravirtentry.S +++ b/trunk/arch/ia64/kernel/paravirtentry.S @@ -20,11 +20,8 @@ * */ -#include #include #include -#include -#include #include "entry.h" #define DATA8(sym, init_value) \ @@ -35,87 +32,29 @@ data8 init_value ; \ .popsection -#define BRANCH(targ, reg, breg, type) \ - PARAVIRT_PATCH_SITE_BR(PARAVIRT_PATCH_TYPE_BR_ ## type) ; \ - ;; \ - movl reg=targ ; \ - ;; \ - ld8 reg=[reg] ; \ - ;; \ - mov breg=reg ; \ +#define BRANCH(targ, reg, breg) \ + movl reg=targ ; \ + ;; \ + ld8 reg=[reg] ; \ + ;; \ + mov breg=reg ; \ br.cond.sptk.many breg -#define BRANCH_PROC(sym, reg, breg, type) \ - DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \ - GLOBAL_ENTRY(paravirt_ ## sym) ; \ - BRANCH(paravirt_ ## sym ## _targ, reg, breg, type) ; \ +#define BRANCH_PROC(sym, reg, breg) \ + DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \ + GLOBAL_ENTRY(paravirt_ ## sym) ; \ + BRANCH(paravirt_ ## sym ## _targ, reg, breg) ; \ END(paravirt_ ## sym) -#define BRANCH_PROC_UNWINFO(sym, reg, breg, type) \ - DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \ - GLOBAL_ENTRY(paravirt_ ## sym) ; \ - PT_REGS_UNWIND_INFO(0) ; \ - BRANCH(paravirt_ ## sym ## _targ, reg, breg, type) ; \ +#define BRANCH_PROC_UNWINFO(sym, reg, breg) \ + DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \ + GLOBAL_ENTRY(paravirt_ ## sym) ; \ + PT_REGS_UNWIND_INFO(0) ; \ + BRANCH(paravirt_ ## sym ## _targ, reg, breg) ; \ END(paravirt_ ## sym) -BRANCH_PROC(switch_to, r22, b7, SWITCH_TO) -BRANCH_PROC_UNWINFO(leave_syscall, r22, b7, LEAVE_SYSCALL) -BRANCH_PROC(work_processed_syscall, r2, b7, WORK_PROCESSED_SYSCALL) -BRANCH_PROC_UNWINFO(leave_kernel, r22, b7, LEAVE_KERNEL) - - -#ifdef CONFIG_MODULES -#define __INIT_OR_MODULE .text -#define __INITDATA_OR_MODULE .data -#else -#define __INIT_OR_MODULE __INIT -#define __INITDATA_OR_MODULE __INITDATA -#endif /* CONFIG_MODULES */ - - __INIT_OR_MODULE - GLOBAL_ENTRY(paravirt_fc_i) - fc.i r32 - br.ret.sptk.many rp - END(paravirt_fc_i) - __FINIT - - __INIT_OR_MODULE - .align 32 - GLOBAL_ENTRY(paravirt_nop_b_inst_bundle) - { - nop.b 0 - nop.b 0 - nop.b 0 - } - END(paravirt_nop_b_inst_bundle) - __FINIT - - /* NOTE: nop.[mfi] has same format */ - __INIT_OR_MODULE - GLOBAL_ENTRY(paravirt_nop_mfi_inst_bundle) - { - nop.m 0 - nop.f 0 - nop.i 0 - } - END(paravirt_nop_mfi_inst_bundle) - __FINIT - - __INIT_OR_MODULE - GLOBAL_ENTRY(paravirt_nop_bundle) -paravirt_nop_bundle_start: - { - nop 0 - nop 0 - nop 0 - } -paravirt_nop_bundle_end: - END(paravirt_nop_bundle) - __FINIT - - __INITDATA_OR_MODULE - .align 8 - .global paravirt_nop_bundle_size -paravirt_nop_bundle_size: - data8 paravirt_nop_bundle_end - paravirt_nop_bundle_start +BRANCH_PROC(switch_to, r22, b7) +BRANCH_PROC_UNWINFO(leave_syscall, r22, b7) +BRANCH_PROC(work_processed_syscall, r2, b7) +BRANCH_PROC_UNWINFO(leave_kernel, r22, b7) diff --git a/trunk/arch/ia64/kernel/patch.c b/trunk/arch/ia64/kernel/patch.c index 68a1311db806..b83b2c516008 100644 --- a/trunk/arch/ia64/kernel/patch.c +++ b/trunk/arch/ia64/kernel/patch.c @@ -7,7 +7,6 @@ #include #include -#include #include #include #include @@ -170,35 +169,16 @@ ia64_patch_mckinley_e9 (unsigned long start, unsigned long end) ia64_srlz_i(); } -extern unsigned long ia64_native_fsyscall_table[NR_syscalls]; -extern char ia64_native_fsys_bubble_down[]; -struct pv_fsys_data pv_fsys_data __initdata = { - .fsyscall_table = (unsigned long *)ia64_native_fsyscall_table, - .fsys_bubble_down = (void *)ia64_native_fsys_bubble_down, -}; - -unsigned long * __init -paravirt_get_fsyscall_table(void) -{ - return pv_fsys_data.fsyscall_table; -} - -char * __init -paravirt_get_fsys_bubble_down(void) -{ - return pv_fsys_data.fsys_bubble_down; -} - static void __init patch_fsyscall_table (unsigned long start, unsigned long end) { - u64 fsyscall_table = (u64)paravirt_get_fsyscall_table(); + extern unsigned long fsyscall_table[NR_syscalls]; s32 *offp = (s32 *) start; u64 ip; while (offp < (s32 *) end) { ip = (u64) ia64_imva((char *) offp + *offp); - ia64_patch_imm64(ip, fsyscall_table); + ia64_patch_imm64(ip, (u64) fsyscall_table); ia64_fc((void *) ip); ++offp; } @@ -209,7 +189,7 @@ patch_fsyscall_table (unsigned long start, unsigned long end) static void __init patch_brl_fsys_bubble_down (unsigned long start, unsigned long end) { - u64 fsys_bubble_down = (u64)paravirt_get_fsys_bubble_down(); + extern char fsys_bubble_down[]; s32 *offp = (s32 *) start; u64 ip; @@ -227,13 +207,13 @@ patch_brl_fsys_bubble_down (unsigned long start, unsigned long end) void __init ia64_patch_gate (void) { -# define START(name) paravirt_get_gate_patchlist(PV_GATE_START_##name) -# define END(name) paravirt_get_gate_patchlist(PV_GATE_END_##name) +# define START(name) ((unsigned long) __start_gate_##name##_patchlist) +# define END(name) ((unsigned long)__end_gate_##name##_patchlist) - patch_fsyscall_table(START(FSYSCALL), END(FSYSCALL)); - patch_brl_fsys_bubble_down(START(BRL_FSYS_BUBBLE_DOWN), END(BRL_FSYS_BUBBLE_DOWN)); - ia64_patch_vtop(START(VTOP), END(VTOP)); - ia64_patch_mckinley_e9(START(MCKINLEY_E9), END(MCKINLEY_E9)); + patch_fsyscall_table(START(fsyscall), END(fsyscall)); + patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down)); + ia64_patch_vtop(START(vtop), END(vtop)); + ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9)); } void ia64_patch_phys_stack_reg(unsigned long val) @@ -249,7 +229,7 @@ void ia64_patch_phys_stack_reg(unsigned long val) while (offp < end) { ip = (u64) offp + *offp; ia64_patch(ip, mask, imm); - ia64_fc((void *)ip); + ia64_fc(ip); ++offp; } ia64_sync_i(); diff --git a/trunk/arch/ia64/kernel/pci-dma.c b/trunk/arch/ia64/kernel/pci-dma.c index e4cb443bb988..d0ada067a4af 100644 --- a/trunk/arch/ia64/kernel/pci-dma.c +++ b/trunk/arch/ia64/kernel/pci-dma.c @@ -32,6 +32,9 @@ int force_iommu __read_mostly = 1; int force_iommu __read_mostly; #endif +/* Set this to 1 if there is a HW IOMMU in the system */ +int iommu_detected __read_mostly; + /* Dummy device used for NULL arguments (normally ISA). Better would be probably a smaller DMA mask, but this is bug-to-bug compatible to i386. */ @@ -41,7 +44,18 @@ struct device fallback_dev = { .dma_mask = &fallback_dev.coherent_dma_mask, }; -extern struct dma_map_ops intel_dma_ops; +void __init pci_iommu_alloc(void) +{ + /* + * The order of these functions is important for + * fall-back/fail-over reasons + */ + detect_intel_iommu(); + +#ifdef CONFIG_SWIOTLB + pci_swiotlb_init(); +#endif +} static int __init pci_iommu_init(void) { @@ -65,12 +79,15 @@ iommu_dma_init(void) return; } +struct dma_mapping_ops *dma_ops; +EXPORT_SYMBOL(dma_ops); + int iommu_dma_supported(struct device *dev, u64 mask) { - struct dma_map_ops *ops = platform_dma_get_ops(dev); + struct dma_mapping_ops *ops = get_dma_ops(dev); - if (ops->dma_supported) - return ops->dma_supported(dev, mask); + if (ops->dma_supported_op) + return ops->dma_supported_op(dev, mask); /* Copied from i386. Doesn't make much sense, because it will only work for pci_alloc_coherent. @@ -99,25 +116,4 @@ int iommu_dma_supported(struct device *dev, u64 mask) } EXPORT_SYMBOL(iommu_dma_supported); -void __init pci_iommu_alloc(void) -{ - dma_ops = &intel_dma_ops; - - dma_ops->sync_single_for_cpu = machvec_dma_sync_single; - dma_ops->sync_sg_for_cpu = machvec_dma_sync_sg; - dma_ops->sync_single_for_device = machvec_dma_sync_single; - dma_ops->sync_sg_for_device = machvec_dma_sync_sg; - dma_ops->dma_supported = iommu_dma_supported; - - /* - * The order of these functions is important for - * fall-back/fail-over reasons - */ - detect_intel_iommu(); - -#ifdef CONFIG_SWIOTLB - pci_swiotlb_init(); -#endif -} - #endif diff --git a/trunk/arch/ia64/kernel/pci-swiotlb.c b/trunk/arch/ia64/kernel/pci-swiotlb.c index 573f02c39a00..16c50516dbc1 100644 --- a/trunk/arch/ia64/kernel/pci-swiotlb.c +++ b/trunk/arch/ia64/kernel/pci-swiotlb.c @@ -13,37 +13,23 @@ int swiotlb __read_mostly; EXPORT_SYMBOL(swiotlb); -static void *ia64_swiotlb_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp) -{ - if (dev->coherent_dma_mask != DMA_64BIT_MASK) - gfp |= GFP_DMA; - return swiotlb_alloc_coherent(dev, size, dma_handle, gfp); -} - -struct dma_map_ops swiotlb_dma_ops = { - .alloc_coherent = ia64_swiotlb_alloc_coherent, +struct dma_mapping_ops swiotlb_dma_ops = { + .mapping_error = swiotlb_dma_mapping_error, + .alloc_coherent = swiotlb_alloc_coherent, .free_coherent = swiotlb_free_coherent, - .map_page = swiotlb_map_page, - .unmap_page = swiotlb_unmap_page, - .map_sg = swiotlb_map_sg_attrs, - .unmap_sg = swiotlb_unmap_sg_attrs, + .map_single = swiotlb_map_single, + .unmap_single = swiotlb_unmap_single, .sync_single_for_cpu = swiotlb_sync_single_for_cpu, .sync_single_for_device = swiotlb_sync_single_for_device, .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu, .sync_single_range_for_device = swiotlb_sync_single_range_for_device, .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, .sync_sg_for_device = swiotlb_sync_sg_for_device, - .dma_supported = swiotlb_dma_supported, - .mapping_error = swiotlb_dma_mapping_error, + .map_sg = swiotlb_map_sg, + .unmap_sg = swiotlb_unmap_sg, + .dma_supported_op = swiotlb_dma_supported, }; -void __init swiotlb_dma_init(void) -{ - dma_ops = &swiotlb_dma_ops; - swiotlb_init(); -} - void __init pci_swiotlb_init(void) { if (!iommu_detected) { diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index 8a06dc480594..5c0f408cfd71 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -5603,7 +5603,7 @@ pfm_interrupt_handler(int irq, void *arg) * /proc/perfmon interface, for debug only */ -#define PFM_PROC_SHOW_HEADER ((void *)nr_cpu_ids+1) +#define PFM_PROC_SHOW_HEADER ((void *)NR_CPUS+1) static void * pfm_proc_start(struct seq_file *m, loff_t *pos) @@ -5612,7 +5612,7 @@ pfm_proc_start(struct seq_file *m, loff_t *pos) return PFM_PROC_SHOW_HEADER; } - while (*pos <= nr_cpu_ids) { + while (*pos <= NR_CPUS) { if (cpu_online(*pos - 1)) { return (void *)*pos; } diff --git a/trunk/arch/ia64/kernel/process.c b/trunk/arch/ia64/kernel/process.c index 5d7c0e5b9e76..c57162705147 100644 --- a/trunk/arch/ia64/kernel/process.c +++ b/trunk/arch/ia64/kernel/process.c @@ -413,7 +413,7 @@ ia64_load_extra (struct task_struct *task) * so there is nothing to worry about. */ int -copy_thread(unsigned long clone_flags, +copy_thread (int nr, unsigned long clone_flags, unsigned long user_stack_base, unsigned long user_stack_size, struct task_struct *p, struct pt_regs *regs) { diff --git a/trunk/arch/ia64/kernel/salinfo.c b/trunk/arch/ia64/kernel/salinfo.c index 7053c55b7649..ecb9eb78d687 100644 --- a/trunk/arch/ia64/kernel/salinfo.c +++ b/trunk/arch/ia64/kernel/salinfo.c @@ -317,7 +317,7 @@ salinfo_event_read(struct file *file, char __user *buffer, size_t count, loff_t } n = data->cpu_check; - for (i = 0; i < nr_cpu_ids; i++) { + for (i = 0; i < NR_CPUS; i++) { if (cpu_isset(n, data->cpu_event)) { if (!cpu_online(n)) { cpu_clear(n, data->cpu_event); @@ -326,7 +326,7 @@ salinfo_event_read(struct file *file, char __user *buffer, size_t count, loff_t cpu = n; break; } - if (++n == nr_cpu_ids) + if (++n == NR_CPUS) n = 0; } @@ -337,7 +337,7 @@ salinfo_event_read(struct file *file, char __user *buffer, size_t count, loff_t /* for next read, start checking at next CPU */ data->cpu_check = cpu; - if (++data->cpu_check == nr_cpu_ids) + if (++data->cpu_check == NR_CPUS) data->cpu_check = 0; snprintf(cmd, sizeof(cmd), "read %d\n", cpu); diff --git a/trunk/arch/ia64/kernel/setup.c b/trunk/arch/ia64/kernel/setup.c index 714066aeda7f..865af27c7737 100644 --- a/trunk/arch/ia64/kernel/setup.c +++ b/trunk/arch/ia64/kernel/setup.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include #include @@ -538,7 +537,6 @@ setup_arch (char **cmdline_p) paravirt_arch_setup_early(); ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist); - paravirt_patch_apply(); *cmdline_p = __va(ia64_boot_param->command_line); strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE); @@ -732,10 +730,10 @@ static void * c_start (struct seq_file *m, loff_t *pos) { #ifdef CONFIG_SMP - while (*pos < nr_cpu_ids && !cpu_online(*pos)) + while (*pos < NR_CPUS && !cpu_isset(*pos, cpu_online_map)) ++*pos; #endif - return *pos < nr_cpu_ids ? cpu_data(*pos) : NULL; + return *pos < NR_CPUS ? cpu_data(*pos) : NULL; } static void * @@ -1018,7 +1016,8 @@ cpu_init (void) | IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC)); atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; - BUG_ON(current->mm); + if (current->mm) + BUG(); ia64_mmu_init(ia64_imva(cpu_data)); ia64_mca_cpu_init(ia64_imva(cpu_data)); diff --git a/trunk/arch/ia64/kernel/smp.c b/trunk/arch/ia64/kernel/smp.c index 2ea4199d9c57..da8f020d82c1 100644 --- a/trunk/arch/ia64/kernel/smp.c +++ b/trunk/arch/ia64/kernel/smp.c @@ -166,11 +166,11 @@ send_IPI_allbutself (int op) * Called with preemption disabled. */ static inline void -send_IPI_mask(const struct cpumask *mask, int op) +send_IPI_mask(cpumask_t mask, int op) { unsigned int cpu; - for_each_cpu(cpu, mask) { + for_each_cpu_mask(cpu, mask) { send_IPI_single(cpu, op); } } @@ -316,7 +316,7 @@ void arch_send_call_function_single_ipi(int cpu) send_IPI_single(cpu, IPI_CALL_FUNC_SINGLE); } -void arch_send_call_function_ipi_mask(const struct cpumask *mask) +void arch_send_call_function_ipi(cpumask_t mask) { send_IPI_mask(mask, IPI_CALL_FUNC); } diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c index 7700e23034bb..52290547c85b 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -581,14 +581,14 @@ smp_build_cpu_map (void) ia64_cpu_to_sapicid[0] = boot_cpu_id; cpus_clear(cpu_present_map); - set_cpu_present(0, true); - set_cpu_possible(0, true); + cpu_set(0, cpu_present_map); + cpu_set(0, cpu_possible_map); for (cpu = 1, i = 0; i < smp_boot_data.cpu_count; i++) { sapicid = smp_boot_data.cpu_phys_id[i]; if (sapicid == boot_cpu_id) continue; - set_cpu_present(cpu, true); - set_cpu_possible(cpu, true); + cpu_set(cpu, cpu_present_map); + cpu_set(cpu, cpu_possible_map); ia64_cpu_to_sapicid[cpu] = sapicid; cpu++; } @@ -626,9 +626,12 @@ smp_prepare_cpus (unsigned int max_cpus) */ if (!max_cpus) { printk(KERN_INFO "SMP mode deactivated.\n"); - init_cpu_online(cpumask_of(0)); - init_cpu_present(cpumask_of(0)); - init_cpu_possible(cpumask_of(0)); + cpus_clear(cpu_online_map); + cpus_clear(cpu_present_map); + cpus_clear(cpu_possible_map); + cpu_set(0, cpu_online_map); + cpu_set(0, cpu_present_map); + cpu_set(0, cpu_possible_map); return; } } diff --git a/trunk/arch/ia64/kernel/time.c b/trunk/arch/ia64/kernel/time.c index 641c8b61c4f1..f0ebb342409d 100644 --- a/trunk/arch/ia64/kernel/time.c +++ b/trunk/arch/ia64/kernel/time.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -50,15 +49,6 @@ EXPORT_SYMBOL(last_cli_ip); #endif -#ifdef CONFIG_PARAVIRT -/* We need to define a real function for sched_clock, to override the - weak default version */ -unsigned long long sched_clock(void) -{ - return paravirt_sched_clock(); -} -#endif - #ifdef CONFIG_PARAVIRT static void paravirt_clocksource_resume(void) @@ -415,21 +405,6 @@ static struct irqaction timer_irqaction = { .name = "timer" }; -static struct platform_device rtc_efi_dev = { - .name = "rtc-efi", - .id = -1, -}; - -static int __init rtc_init(void) -{ - if (platform_device_register(&rtc_efi_dev) < 0) - printk(KERN_ERR "unable to register rtc device...\n"); - - /* not necessarily an error */ - return 0; -} -module_init(rtc_init); - void __init time_init (void) { diff --git a/trunk/arch/ia64/kernel/vmlinux.lds.S b/trunk/arch/ia64/kernel/vmlinux.lds.S index 4a95e86b9ac2..3765efc5f963 100644 --- a/trunk/arch/ia64/kernel/vmlinux.lds.S +++ b/trunk/arch/ia64/kernel/vmlinux.lds.S @@ -169,30 +169,6 @@ SECTIONS __end___mckinley_e9_bundles = .; } -#if defined(CONFIG_PARAVIRT) - . = ALIGN(16); - .paravirt_bundles : AT(ADDR(.paravirt_bundles) - LOAD_OFFSET) - { - __start_paravirt_bundles = .; - *(.paravirt_bundles) - __stop_paravirt_bundles = .; - } - . = ALIGN(16); - .paravirt_insts : AT(ADDR(.paravirt_insts) - LOAD_OFFSET) - { - __start_paravirt_insts = .; - *(.paravirt_insts) - __stop_paravirt_insts = .; - } - . = ALIGN(16); - .paravirt_branches : AT(ADDR(.paravirt_branches) - LOAD_OFFSET) - { - __start_paravirt_branches = .; - *(.paravirt_branches) - __stop_paravirt_branches = .; - } -#endif - #if defined(CONFIG_IA64_GENERIC) /* Machine Vector */ . = ALIGN(16); @@ -225,12 +201,6 @@ SECTIONS __start_gate_section = .; *(.data.gate) __stop_gate_section = .; -#ifdef CONFIG_XEN - . = ALIGN(PAGE_SIZE); - __xen_start_gate_section = .; - *(.data.gate.xen) - __xen_stop_gate_section = .; -#endif } . = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose * kernel data diff --git a/trunk/arch/ia64/kvm/kvm-ia64.c b/trunk/arch/ia64/kvm/kvm-ia64.c index 28af6a731bb8..076b00d1dbff 100644 --- a/trunk/arch/ia64/kvm/kvm-ia64.c +++ b/trunk/arch/ia64/kvm/kvm-ia64.c @@ -70,7 +70,7 @@ static void kvm_flush_icache(unsigned long start, unsigned long len) int l; for (l = 0; l < (len + 32); l += 32) - ia64_fc((void *)(start + l)); + ia64_fc(start + l); ia64_sync_i(); ia64_srlz_i(); diff --git a/trunk/arch/ia64/kvm/vcpu.c b/trunk/arch/ia64/kvm/vcpu.c index a18ee17b9192..d4d280505878 100644 --- a/trunk/arch/ia64/kvm/vcpu.c +++ b/trunk/arch/ia64/kvm/vcpu.c @@ -386,7 +386,7 @@ void set_rse_reg(struct kvm_pt_regs *regs, unsigned long r1, else *rnat_addr = (*rnat_addr) & (~nat_mask); - ia64_setreg(_IA64_REG_AR_BSPSTORE, (unsigned long)bspstore); + ia64_setreg(_IA64_REG_AR_BSPSTORE, bspstore); ia64_setreg(_IA64_REG_AR_RNAT, rnat); } local_irq_restore(psr); diff --git a/trunk/arch/ia64/kvm/vtlb.c b/trunk/arch/ia64/kvm/vtlb.c index 2c2501f13159..38232b37668b 100644 --- a/trunk/arch/ia64/kvm/vtlb.c +++ b/trunk/arch/ia64/kvm/vtlb.c @@ -210,7 +210,6 @@ void thash_vhpt_insert(struct kvm_vcpu *v, u64 pte, u64 itir, u64 va, int type) phy_pte &= ~PAGE_FLAGS_RV_MASK; psr = ia64_clear_ic(); ia64_itc(type, va, phy_pte, itir_ps(itir)); - paravirt_dv_serialize_data(); ia64_set_psr(psr); } @@ -457,7 +456,6 @@ void thash_purge_and_insert(struct kvm_vcpu *v, u64 pte, u64 itir, phy_pte &= ~PAGE_FLAGS_RV_MASK; psr = ia64_clear_ic(); ia64_itc(type, ifa, phy_pte, ps); - paravirt_dv_serialize_data(); ia64_set_psr(psr); } if (!(pte&VTLB_PTE_IO)) diff --git a/trunk/arch/ia64/mm/init.c b/trunk/arch/ia64/mm/init.c index c0f3bee69042..56e12903973c 100644 --- a/trunk/arch/ia64/mm/init.c +++ b/trunk/arch/ia64/mm/init.c @@ -35,7 +35,6 @@ #include #include #include -#include DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); @@ -260,7 +259,6 @@ put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot) static void __init setup_gate (void) { - void *gate_section; struct page *page; /* @@ -268,11 +266,10 @@ setup_gate (void) * headers etc. and once execute-only page to enable * privilege-promotion via "epc": */ - gate_section = paravirt_get_gate_section(); - page = virt_to_page(ia64_imva(gate_section)); + page = virt_to_page(ia64_imva(__start_gate_section)); put_kernel_page(page, GATE_ADDR, PAGE_READONLY); #ifdef HAVE_BUGGY_SEGREL - page = virt_to_page(ia64_imva(gate_section + PAGE_SIZE)); + page = virt_to_page(ia64_imva(__start_gate_section + PAGE_SIZE)); put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE); #else put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE); @@ -636,7 +633,8 @@ mem_init (void) #endif #ifdef CONFIG_FLATMEM - BUG_ON(!mem_map); + if (!mem_map) + BUG(); max_mapnr = max_low_pfn; #endif @@ -669,8 +667,8 @@ mem_init (void) * code can tell them apart. */ for (i = 0; i < NR_syscalls; ++i) { + extern unsigned long fsyscall_table[NR_syscalls]; extern unsigned long sys_call_table[NR_syscalls]; - unsigned long *fsyscall_table = paravirt_get_fsyscall_table(); if (!fsyscall_table[i] || nolwsys) fsyscall_table[i] = sys_call_table[i] | 1; diff --git a/trunk/arch/ia64/mm/tlb.c b/trunk/arch/ia64/mm/tlb.c index b9f3d7bbb338..bd9818a36b47 100644 --- a/trunk/arch/ia64/mm/tlb.c +++ b/trunk/arch/ia64/mm/tlb.c @@ -309,7 +309,7 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, preempt_disable(); #ifdef CONFIG_SMP - if (mm != current->active_mm || cpumask_weight(mm_cpumask(mm)) != 1) { + if (mm != current->active_mm || cpus_weight(mm->cpu_vm_mask) != 1) { platform_global_tlb_purge(mm, start, end, nbits); preempt_enable(); return; diff --git a/trunk/arch/ia64/scripts/pvcheck.sed b/trunk/arch/ia64/scripts/pvcheck.sed index e59809a3fc01..ba66ac2e4c60 100644 --- a/trunk/arch/ia64/scripts/pvcheck.sed +++ b/trunk/arch/ia64/scripts/pvcheck.sed @@ -17,7 +17,6 @@ s/mov.*=.*cr\.iip/.warning \"cr.iip should not used directly\"/g s/mov.*=.*cr\.ivr/.warning \"cr.ivr should not used directly\"/g s/mov.*=[^\.]*psr/.warning \"psr should not used directly\"/g # avoid ar.fpsr s/mov.*=.*ar\.eflags/.warning \"ar.eflags should not used directly\"/g -s/mov.*=.*ar\.itc.*/.warning \"ar.itc should not used directly\"/g s/mov.*cr\.ifa.*=.*/.warning \"cr.ifa should not used directly\"/g s/mov.*cr\.itir.*=.*/.warning \"cr.itir should not used directly\"/g s/mov.*cr\.iha.*=.*/.warning \"cr.iha should not used directly\"/g diff --git a/trunk/arch/ia64/sn/kernel/io_common.c b/trunk/arch/ia64/sn/kernel/io_common.c index 57f280dd9def..0d4ffa4da1da 100644 --- a/trunk/arch/ia64/sn/kernel/io_common.c +++ b/trunk/arch/ia64/sn/kernel/io_common.c @@ -135,7 +135,8 @@ static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, } war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL); - BUG_ON(!war_list); + if (!war_list) + BUG(); SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST, nasid, widget, __pa(war_list), 0, 0, 0 ,0); @@ -179,20 +180,23 @@ sn_common_hubdev_init(struct hubdev_info *hubdev) sizeof(struct sn_flush_device_kernel *); hubdev->hdi_flush_nasid_list.widget_p = kzalloc(size, GFP_KERNEL); - BUG_ON(!hubdev->hdi_flush_nasid_list.widget_p); + if (!hubdev->hdi_flush_nasid_list.widget_p) + BUG(); for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) { size = DEV_PER_WIDGET * sizeof(struct sn_flush_device_kernel); sn_flush_device_kernel = kzalloc(size, GFP_KERNEL); - BUG_ON(!sn_flush_device_kernel); + if (!sn_flush_device_kernel) + BUG(); dev_entry = sn_flush_device_kernel; for (device = 0; device < DEV_PER_WIDGET; device++, dev_entry++) { size = sizeof(struct sn_flush_device_common); dev_entry->common = kzalloc(size, GFP_KERNEL); - BUG_ON(!dev_entry->common); + if (!dev_entry->common) + BUG(); if (sn_prom_feature_available(PRF_DEVICE_FLUSH_LIST)) status = sal_get_device_dmaflush_list( hubdev->hdi_nasid, widget, device, @@ -322,7 +326,8 @@ sn_common_bus_fixup(struct pci_bus *bus, */ controller->platform_data = kzalloc(sizeof(struct sn_platform_data), GFP_KERNEL); - BUG_ON(controller->platform_data == NULL); + if (controller->platform_data == NULL) + BUG(); sn_platform_data = (struct sn_platform_data *) controller->platform_data; sn_platform_data->provider_soft = provider_soft; diff --git a/trunk/arch/ia64/sn/kernel/io_init.c b/trunk/arch/ia64/sn/kernel/io_init.c index ee774c366a06..e2eb2da60f96 100644 --- a/trunk/arch/ia64/sn/kernel/io_init.c +++ b/trunk/arch/ia64/sn/kernel/io_init.c @@ -128,7 +128,8 @@ sn_legacy_pci_window_fixup(struct pci_controller *controller, { controller->window = kcalloc(2, sizeof(struct pci_window), GFP_KERNEL); - BUG_ON(controller->window == NULL); + if (controller->window == NULL) + BUG(); controller->window[0].offset = legacy_io; controller->window[0].resource.name = "legacy_io"; controller->window[0].resource.flags = IORESOURCE_IO; @@ -167,7 +168,8 @@ sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, idx = controller->windows; new_count = controller->windows + count; new_window = kcalloc(new_count, sizeof(struct pci_window), GFP_KERNEL); - BUG_ON(new_window == NULL); + if (new_window == NULL) + BUG(); if (controller->window) { memcpy(new_window, controller->window, sizeof(struct pci_window) * controller->windows); @@ -220,7 +222,8 @@ sn_io_slot_fixup(struct pci_dev *dev) (u64) __pa(pcidev_info), (u64) __pa(sn_irq_info)); - BUG_ON(status); /* Cannot get platform pci device information */ + if (status) + BUG(); /* Cannot get platform pci device information */ /* Copy over PIO Mapped Addresses */ @@ -304,7 +307,8 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) prom_bussoft_ptr = __va(prom_bussoft_ptr); controller = kzalloc(sizeof(*controller), GFP_KERNEL); - BUG_ON(!controller); + if (!controller) + BUG(); controller->segment = segment; /* diff --git a/trunk/arch/ia64/sn/kernel/setup.c b/trunk/arch/ia64/sn/kernel/setup.c index e456f062f241..02c5b8a9fb60 100644 --- a/trunk/arch/ia64/sn/kernel/setup.c +++ b/trunk/arch/ia64/sn/kernel/setup.c @@ -732,7 +732,8 @@ void __init build_cnode_tables(void) kl_config_hdr_t *klgraph_header; nasid = cnodeid_to_nasid(node); klgraph_header = ia64_sn_get_klconfig_addr(nasid); - BUG_ON(klgraph_header == NULL); + if (klgraph_header == NULL) + BUG(); brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info); while (brd) { if (board_needs_cnode(brd->brd_type) && physical_node_map[brd->brd_nasid] < 0) { @@ -749,7 +750,7 @@ nasid_slice_to_cpuid(int nasid, int slice) { long cpu; - for (cpu = 0; cpu < nr_cpu_ids; cpu++) + for (cpu = 0; cpu < NR_CPUS; cpu++) if (cpuid_to_nasid(cpu) == nasid && cpuid_to_slice(cpu) == slice) return cpu; diff --git a/trunk/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/trunk/arch/ia64/sn/kernel/sn2/prominfo_proc.c index e63328818643..4dcce3d0e04c 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/prominfo_proc.c +++ b/trunk/arch/ia64/sn/kernel/sn2/prominfo_proc.c @@ -225,6 +225,7 @@ static struct proc_dir_entry *sgi_prominfo_entry; int __init prominfo_init(void) { struct proc_dir_entry **entp; + struct proc_dir_entry *p; cnodeid_t cnodeid; unsigned long nasid; int size; @@ -245,10 +246,14 @@ int __init prominfo_init(void) sprintf(name, "node%d", cnodeid); *entp = proc_mkdir(name, sgi_prominfo_entry); nasid = cnodeid_to_nasid(cnodeid); - create_proc_read_entry("fit", 0, *entp, read_fit_entry, + p = create_proc_read_entry("fit", 0, *entp, read_fit_entry, (void *)nasid); - create_proc_read_entry("version", 0, *entp, + if (p) + p->owner = THIS_MODULE; + p = create_proc_read_entry("version", 0, *entp, read_version_entry, (void *)nasid); + if (p) + p->owner = THIS_MODULE; entp++; } diff --git a/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c b/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c index 1176506b2bae..e585f9a2afb9 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c +++ b/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c @@ -133,7 +133,7 @@ sn2_ipi_flush_all_tlb(struct mm_struct *mm) unsigned long itc; itc = ia64_get_itc(); - smp_flush_tlb_cpumask(*mm_cpumask(mm)); + smp_flush_tlb_cpumask(mm->cpu_vm_mask); itc = ia64_get_itc() - itc; __get_cpu_var(ptcstats).shub_ipi_flushes_itc_clocks += itc; __get_cpu_var(ptcstats).shub_ipi_flushes++; @@ -182,7 +182,7 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, nodes_clear(nodes_flushed); i = 0; - for_each_cpu(cpu, mm_cpumask(mm)) { + for_each_cpu_mask(cpu, mm->cpu_vm_mask) { cnode = cpu_to_node(cpu); node_set(cnode, nodes_flushed); lcpu = cpu; @@ -461,7 +461,7 @@ bool sn_cpu_disable_allowed(int cpu) static void *sn2_ptc_seq_start(struct seq_file *file, loff_t * offset) { - if (*offset < nr_cpu_ids) + if (*offset < NR_CPUS) return offset; return NULL; } @@ -469,7 +469,7 @@ static void *sn2_ptc_seq_start(struct seq_file *file, loff_t * offset) static void *sn2_ptc_seq_next(struct seq_file *file, void *data, loff_t * offset) { (*offset)++; - if (*offset < nr_cpu_ids) + if (*offset < NR_CPUS) return offset; return NULL; } @@ -491,7 +491,7 @@ static int sn2_ptc_seq_show(struct seq_file *file, void *data) seq_printf(file, "# ptctest %d, flushopt %d\n", sn2_ptctest, sn2_flush_opt); } - if (cpu < nr_cpu_ids && cpu_online(cpu)) { + if (cpu < NR_CPUS && cpu_online(cpu)) { stat = &per_cpu(ptcstats, cpu); seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l, stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed, @@ -554,7 +554,7 @@ static int __init sn2_ptc_init(void) proc_sn2_ptc = proc_create(PTC_BASENAME, 0444, NULL, &proc_sn2_ptc_operations); - if (!proc_sn2_ptc) { + if (!&proc_sn2_ptc_operations) { printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME); return -EINVAL; } diff --git a/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 9e6491cf72bd..be339477f906 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -275,7 +275,8 @@ static int sn_hwperf_get_nearest_node_objdata(struct sn_hwperf_object_info *objb /* get it's interconnect topology */ sz = op->ports * sizeof(struct sn_hwperf_port_info); - BUG_ON(sz > sizeof(ptdata)); + if (sz > sizeof(ptdata)) + BUG(); e = ia64_sn_hwperf_op(sn_hwperf_master_nasid, SN_HWPERF_ENUM_PORTS, nodeobj->id, sz, (u64)&ptdata, 0, 0, NULL); @@ -309,7 +310,8 @@ static int sn_hwperf_get_nearest_node_objdata(struct sn_hwperf_object_info *objb if (router && (!found_cpu || !found_mem)) { /* search for a node connected to the same router */ sz = router->ports * sizeof(struct sn_hwperf_port_info); - BUG_ON(sz > sizeof(ptdata)); + if (sz > sizeof(ptdata)) + BUG(); e = ia64_sn_hwperf_op(sn_hwperf_master_nasid, SN_HWPERF_ENUM_PORTS, router->id, sz, (u64)&ptdata, 0, 0, NULL); @@ -610,7 +612,7 @@ static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info) op_info->a->arg &= SN_HWPERF_ARG_OBJID_MASK; if (cpu != SN_HWPERF_ARG_ANY_CPU) { - if (cpu >= nr_cpu_ids || !cpu_online(cpu)) { + if (cpu >= NR_CPUS || !cpu_online(cpu)) { r = -EINVAL; goto out; } diff --git a/trunk/arch/ia64/sn/pci/pci_dma.c b/trunk/arch/ia64/sn/pci/pci_dma.c index 8c130e8f00e1..863f5017baae 100644 --- a/trunk/arch/ia64/sn/pci/pci_dma.c +++ b/trunk/arch/ia64/sn/pci/pci_dma.c @@ -10,7 +10,7 @@ */ #include -#include +#include #include #include #include @@ -31,7 +31,7 @@ * this function. Of course, SN only supports devices that have 32 or more * address bits when using the PMU. */ -static int sn_dma_supported(struct device *dev, u64 mask) +int sn_dma_supported(struct device *dev, u64 mask) { BUG_ON(dev->bus != &pci_bus_type); @@ -39,6 +39,7 @@ static int sn_dma_supported(struct device *dev, u64 mask) return 0; return 1; } +EXPORT_SYMBOL(sn_dma_supported); /** * sn_dma_set_mask - set the DMA mask @@ -74,8 +75,8 @@ EXPORT_SYMBOL(sn_dma_set_mask); * queue for a SCSI controller). See Documentation/DMA-API.txt for * more information. */ -static void *sn_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t * dma_handle, gfp_t flags) +void *sn_dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t * dma_handle, gfp_t flags) { void *cpuaddr; unsigned long phys_addr; @@ -123,6 +124,7 @@ static void *sn_dma_alloc_coherent(struct device *dev, size_t size, return cpuaddr; } +EXPORT_SYMBOL(sn_dma_alloc_coherent); /** * sn_pci_free_coherent - free memory associated with coherent DMAable region @@ -134,8 +136,8 @@ static void *sn_dma_alloc_coherent(struct device *dev, size_t size, * Frees the memory allocated by dma_alloc_coherent(), potentially unmapping * any associated IOMMU mappings. */ -static void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, - dma_addr_t dma_handle) +void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, + dma_addr_t dma_handle) { struct pci_dev *pdev = to_pci_dev(dev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); @@ -145,6 +147,7 @@ static void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr provider->dma_unmap(pdev, dma_handle, 0); free_pages((unsigned long)cpu_addr, get_order(size)); } +EXPORT_SYMBOL(sn_dma_free_coherent); /** * sn_dma_map_single_attrs - map a single page for DMA @@ -170,12 +173,10 @@ static void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr * TODO: simplify our interface; * figure out how to save dmamap handle so can use two step. */ -static dma_addr_t sn_dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) +dma_addr_t sn_dma_map_single_attrs(struct device *dev, void *cpu_addr, + size_t size, int direction, + struct dma_attrs *attrs) { - void *cpu_addr = page_address(page) + offset; dma_addr_t dma_addr; unsigned long phys_addr; struct pci_dev *pdev = to_pci_dev(dev); @@ -200,6 +201,7 @@ static dma_addr_t sn_dma_map_page(struct device *dev, struct page *page, } return dma_addr; } +EXPORT_SYMBOL(sn_dma_map_single_attrs); /** * sn_dma_unmap_single_attrs - unamp a DMA mapped page @@ -213,20 +215,21 @@ static dma_addr_t sn_dma_map_page(struct device *dev, struct page *page, * by @dma_handle into the coherence domain. On SN, we're always cache * coherent, so we just need to free any ATEs associated with this mapping. */ -static void sn_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction dir, - struct dma_attrs *attrs) +void sn_dma_unmap_single_attrs(struct device *dev, dma_addr_t dma_addr, + size_t size, int direction, + struct dma_attrs *attrs) { struct pci_dev *pdev = to_pci_dev(dev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); BUG_ON(dev->bus != &pci_bus_type); - provider->dma_unmap(pdev, dma_addr, dir); + provider->dma_unmap(pdev, dma_addr, direction); } +EXPORT_SYMBOL(sn_dma_unmap_single_attrs); /** - * sn_dma_unmap_sg - unmap a DMA scatterlist + * sn_dma_unmap_sg_attrs - unmap a DMA scatterlist * @dev: device to unmap * @sg: scatterlist to unmap * @nhwentries: number of scatterlist entries @@ -235,9 +238,9 @@ static void sn_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, * * Unmap a set of streaming mode DMA translations. */ -static void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl, - int nhwentries, enum dma_data_direction dir, - struct dma_attrs *attrs) +void sn_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sgl, + int nhwentries, int direction, + struct dma_attrs *attrs) { int i; struct pci_dev *pdev = to_pci_dev(dev); @@ -247,14 +250,15 @@ static void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl, BUG_ON(dev->bus != &pci_bus_type); for_each_sg(sgl, sg, nhwentries, i) { - provider->dma_unmap(pdev, sg->dma_address, dir); + provider->dma_unmap(pdev, sg->dma_address, direction); sg->dma_address = (dma_addr_t) NULL; sg->dma_length = 0; } } +EXPORT_SYMBOL(sn_dma_unmap_sg_attrs); /** - * sn_dma_map_sg - map a scatterlist for DMA + * sn_dma_map_sg_attrs - map a scatterlist for DMA * @dev: device to map for * @sg: scatterlist to map * @nhwentries: number of entries @@ -268,9 +272,8 @@ static void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl, * * Maps each entry of @sg for DMA. */ -static int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, - int nhwentries, enum dma_data_direction dir, - struct dma_attrs *attrs) +int sn_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl, + int nhwentries, int direction, struct dma_attrs *attrs) { unsigned long phys_addr; struct scatterlist *saved_sg = sgl, *sg; @@ -307,7 +310,8 @@ static int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, * Free any successfully allocated entries. */ if (i > 0) - sn_dma_unmap_sg(dev, saved_sg, i, dir, attrs); + sn_dma_unmap_sg_attrs(dev, saved_sg, i, + direction, attrs); return 0; } @@ -316,36 +320,41 @@ static int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, return nhwentries; } +EXPORT_SYMBOL(sn_dma_map_sg_attrs); -static void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, - size_t size, enum dma_data_direction dir) +void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, + size_t size, int direction) { BUG_ON(dev->bus != &pci_bus_type); } +EXPORT_SYMBOL(sn_dma_sync_single_for_cpu); -static void sn_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, - size_t size, - enum dma_data_direction dir) +void sn_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, + size_t size, int direction) { BUG_ON(dev->bus != &pci_bus_type); } +EXPORT_SYMBOL(sn_dma_sync_single_for_device); -static void sn_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, - int nelems, enum dma_data_direction dir) +void sn_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, + int nelems, int direction) { BUG_ON(dev->bus != &pci_bus_type); } +EXPORT_SYMBOL(sn_dma_sync_sg_for_cpu); -static void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, - int nelems, enum dma_data_direction dir) +void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, + int nelems, int direction) { BUG_ON(dev->bus != &pci_bus_type); } +EXPORT_SYMBOL(sn_dma_sync_sg_for_device); -static int sn_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +int sn_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } +EXPORT_SYMBOL(sn_dma_mapping_error); u64 sn_dma_get_required_mask(struct device *dev) { @@ -462,23 +471,3 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) out: return ret; } - -static struct dma_map_ops sn_dma_ops = { - .alloc_coherent = sn_dma_alloc_coherent, - .free_coherent = sn_dma_free_coherent, - .map_page = sn_dma_map_page, - .unmap_page = sn_dma_unmap_page, - .map_sg = sn_dma_map_sg, - .unmap_sg = sn_dma_unmap_sg, - .sync_single_for_cpu = sn_dma_sync_single_for_cpu, - .sync_sg_for_cpu = sn_dma_sync_sg_for_cpu, - .sync_single_for_device = sn_dma_sync_single_for_device, - .sync_sg_for_device = sn_dma_sync_sg_for_device, - .mapping_error = sn_dma_mapping_error, - .dma_supported = sn_dma_supported, -}; - -void sn_dma_init(void) -{ - dma_ops = &sn_dma_ops; -} diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c index c659ad5613a0..060df4aa9916 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c @@ -256,7 +256,9 @@ void sn_dma_flush(u64 addr) hubinfo = (NODEPDA(nasid_to_cnodeid(nasid)))->pdinfo; - BUG_ON(!hubinfo); + if (!hubinfo) { + BUG(); + } flush_nasid_list = &hubinfo->hdi_flush_nasid_list; if (flush_nasid_list->widget_p == NULL) diff --git a/trunk/arch/ia64/xen/Makefile b/trunk/arch/ia64/xen/Makefile index e6f4a0a74228..0ad0224693d9 100644 --- a/trunk/arch/ia64/xen/Makefile +++ b/trunk/arch/ia64/xen/Makefile @@ -3,29 +3,14 @@ # obj-y := hypercall.o xenivt.o xensetup.o xen_pv_ops.o irq_xen.o \ - hypervisor.o xencomm.o xcom_hcall.o grant-table.o time.o suspend.o \ - gate-data.o + hypervisor.o xencomm.o xcom_hcall.o grant-table.o time.o suspend.o obj-$(CONFIG_IA64_GENERIC) += machvec.o -# The gate DSO image is built using a special linker script. -include $(srctree)/arch/ia64/kernel/Makefile.gate - -# tell compiled for xen -CPPFLAGS_gate.lds += -D__IA64_GATE_PARAVIRTUALIZED_XEN -AFLAGS_gate.o += -D__IA64_ASM_PARAVIRTUALIZED_XEN -D__IA64_GATE_PARAVIRTUALIZED_XEN - -# use same file of native. -$(obj)/gate.o: $(src)/../kernel/gate.S FORCE - $(call if_changed_dep,as_o_S) -$(obj)/gate.lds: $(src)/../kernel/gate.lds.S FORCE - $(call if_changed_dep,cpp_lds_S) - - AFLAGS_xenivt.o += -D__IA64_ASM_PARAVIRTUALIZED_XEN # xen multi compile -ASM_PARAVIRT_MULTI_COMPILE_SRCS = ivt.S entry.S fsys.S +ASM_PARAVIRT_MULTI_COMPILE_SRCS = ivt.S entry.S ASM_PARAVIRT_OBJS = $(addprefix xen-,$(ASM_PARAVIRT_MULTI_COMPILE_SRCS:.S=.o)) obj-y += $(ASM_PARAVIRT_OBJS) define paravirtualized_xen diff --git a/trunk/arch/ia64/xen/gate-data.S b/trunk/arch/ia64/xen/gate-data.S deleted file mode 100644 index 7d4830afc91d..000000000000 --- a/trunk/arch/ia64/xen/gate-data.S +++ /dev/null @@ -1,3 +0,0 @@ - .section .data.gate.xen, "aw" - - .incbin "arch/ia64/xen/gate.so" diff --git a/trunk/arch/ia64/xen/hypercall.S b/trunk/arch/ia64/xen/hypercall.S index e32dae444dd6..45e02bb64a92 100644 --- a/trunk/arch/ia64/xen/hypercall.S +++ b/trunk/arch/ia64/xen/hypercall.S @@ -9,7 +9,6 @@ #include #include -#ifdef __INTEL_COMPILER /* * Hypercalls without parameter. */ @@ -73,7 +72,6 @@ GLOBAL_ENTRY(xen_set_rr0_to_rr4) br.ret.sptk.many rp ;; END(xen_set_rr0_to_rr4) -#endif GLOBAL_ENTRY(xen_send_ipi) mov r14=r32 diff --git a/trunk/arch/ia64/xen/time.c b/trunk/arch/ia64/xen/time.c index fb8332690179..68d6204c3f16 100644 --- a/trunk/arch/ia64/xen/time.c +++ b/trunk/arch/ia64/xen/time.c @@ -175,58 +175,10 @@ static void xen_itc_jitter_data_reset(void) } while (unlikely(ret != lcycle)); } -/* based on xen_sched_clock() in arch/x86/xen/time.c. */ -/* - * This relies on HAVE_UNSTABLE_SCHED_CLOCK. If it can't be defined, - * something similar logic should be implemented here. - */ -/* - * Xen sched_clock implementation. Returns the number of unstolen - * nanoseconds, which is nanoseconds the VCPU spent in RUNNING+BLOCKED - * states. - */ -static unsigned long long xen_sched_clock(void) -{ - struct vcpu_runstate_info runstate; - - unsigned long long now; - unsigned long long offset; - unsigned long long ret; - - /* - * Ideally sched_clock should be called on a per-cpu basis - * anyway, so preempt should already be disabled, but that's - * not current practice at the moment. - */ - preempt_disable(); - - /* - * both ia64_native_sched_clock() and xen's runstate are - * based on mAR.ITC. So difference of them makes sense. - */ - now = ia64_native_sched_clock(); - - get_runstate_snapshot(&runstate); - - WARN_ON(runstate.state != RUNSTATE_running); - - offset = 0; - if (now > runstate.state_entry_time) - offset = now - runstate.state_entry_time; - ret = runstate.time[RUNSTATE_blocked] + - runstate.time[RUNSTATE_running] + - offset; - - preempt_enable(); - - return ret; -} - struct pv_time_ops xen_time_ops __initdata = { .init_missing_ticks_accounting = xen_init_missing_ticks_accounting, .do_steal_accounting = xen_do_steal_accounting, .clocksource_resume = xen_itc_jitter_data_reset, - .sched_clock = xen_sched_clock, }; /* Called after suspend, to resume time. */ diff --git a/trunk/arch/ia64/xen/xen_pv_ops.c b/trunk/arch/ia64/xen/xen_pv_ops.c index 5e2270a999fa..936cff3c96e0 100644 --- a/trunk/arch/ia64/xen/xen_pv_ops.c +++ b/trunk/arch/ia64/xen/xen_pv_ops.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -154,13 +153,6 @@ xen_post_smp_prepare_boot_cpu(void) xen_setup_vcpu_info_placement(); } -#ifdef ASM_SUPPORTED -static unsigned long __init_or_module -xen_patch_bundle(void *sbundle, void *ebundle, unsigned long type); -#endif -static void __init -xen_patch_branch(unsigned long tag, unsigned long type); - static const struct pv_init_ops xen_init_ops __initconst = { .banner = xen_banner, @@ -171,53 +163,6 @@ static const struct pv_init_ops xen_init_ops __initconst = { .arch_setup_nomca = xen_arch_setup_nomca, .post_smp_prepare_boot_cpu = xen_post_smp_prepare_boot_cpu, -#ifdef ASM_SUPPORTED - .patch_bundle = xen_patch_bundle, -#endif - .patch_branch = xen_patch_branch, -}; - -/*************************************************************************** - * pv_fsys_data - * addresses for fsys - */ - -extern unsigned long xen_fsyscall_table[NR_syscalls]; -extern char xen_fsys_bubble_down[]; -struct pv_fsys_data xen_fsys_data __initdata = { - .fsyscall_table = (unsigned long *)xen_fsyscall_table, - .fsys_bubble_down = (void *)xen_fsys_bubble_down, -}; - -/*************************************************************************** - * pv_patchdata - * patchdata addresses - */ - -#define DECLARE(name) \ - extern unsigned long __xen_start_gate_##name##_patchlist[]; \ - extern unsigned long __xen_end_gate_##name##_patchlist[] - -DECLARE(fsyscall); -DECLARE(brl_fsys_bubble_down); -DECLARE(vtop); -DECLARE(mckinley_e9); - -extern unsigned long __xen_start_gate_section[]; - -#define ASSIGN(name) \ - .start_##name##_patchlist = \ - (unsigned long)__xen_start_gate_##name##_patchlist, \ - .end_##name##_patchlist = \ - (unsigned long)__xen_end_gate_##name##_patchlist - -static struct pv_patchdata xen_patchdata __initdata = { - ASSIGN(fsyscall), - ASSIGN(brl_fsys_bubble_down), - ASSIGN(vtop), - ASSIGN(mckinley_e9), - - .gate_section = (void*)__xen_start_gate_section, }; /*************************************************************************** @@ -225,76 +170,6 @@ static struct pv_patchdata xen_patchdata __initdata = { * intrinsics hooks. */ -#ifndef ASM_SUPPORTED -static void -xen_set_itm_with_offset(unsigned long val) -{ - /* ia64_cpu_local_tick() calls this with interrupt enabled. */ - /* WARN_ON(!irqs_disabled()); */ - xen_set_itm(val - XEN_MAPPEDREGS->itc_offset); -} - -static unsigned long -xen_get_itm_with_offset(void) -{ - /* unused at this moment */ - printk(KERN_DEBUG "%s is called.\n", __func__); - - WARN_ON(!irqs_disabled()); - return ia64_native_getreg(_IA64_REG_CR_ITM) + - XEN_MAPPEDREGS->itc_offset; -} - -/* ia64_set_itc() is only called by - * cpu_init() with ia64_set_itc(0) and ia64_sync_itc(). - * So XEN_MAPPEDRESG->itc_offset cal be considered as almost constant. - */ -static void -xen_set_itc(unsigned long val) -{ - unsigned long mitc; - - WARN_ON(!irqs_disabled()); - mitc = ia64_native_getreg(_IA64_REG_AR_ITC); - XEN_MAPPEDREGS->itc_offset = val - mitc; - XEN_MAPPEDREGS->itc_last = val; -} - -static unsigned long -xen_get_itc(void) -{ - unsigned long res; - unsigned long itc_offset; - unsigned long itc_last; - unsigned long ret_itc_last; - - itc_offset = XEN_MAPPEDREGS->itc_offset; - do { - itc_last = XEN_MAPPEDREGS->itc_last; - res = ia64_native_getreg(_IA64_REG_AR_ITC); - res += itc_offset; - if (itc_last >= res) - res = itc_last + 1; - ret_itc_last = cmpxchg(&XEN_MAPPEDREGS->itc_last, - itc_last, res); - } while (unlikely(ret_itc_last != itc_last)); - return res; - -#if 0 - /* ia64_itc_udelay() calls ia64_get_itc() with interrupt enabled. - Should it be paravirtualized instead? */ - WARN_ON(!irqs_disabled()); - itc_offset = XEN_MAPPEDREGS->itc_offset; - itc_last = XEN_MAPPEDREGS->itc_last; - res = ia64_native_getreg(_IA64_REG_AR_ITC); - res += itc_offset; - if (itc_last >= res) - res = itc_last + 1; - XEN_MAPPEDREGS->itc_last = res; - return res; -#endif -} - static void xen_setreg(int regnum, unsigned long val) { switch (regnum) { @@ -306,14 +181,11 @@ static void xen_setreg(int regnum, unsigned long val) xen_set_eflag(val); break; #endif - case _IA64_REG_AR_ITC: - xen_set_itc(val); - break; case _IA64_REG_CR_TPR: xen_set_tpr(val); break; case _IA64_REG_CR_ITM: - xen_set_itm_with_offset(val); + xen_set_itm(val); break; case _IA64_REG_CR_EOI: xen_eoi(val); @@ -337,12 +209,6 @@ static unsigned long xen_getreg(int regnum) res = xen_get_eflag(); break; #endif - case _IA64_REG_AR_ITC: - res = xen_get_itc(); - break; - case _IA64_REG_CR_ITM: - res = xen_get_itm_with_offset(); - break; case _IA64_REG_CR_IVR: res = xen_get_ivr(); break; @@ -393,417 +259,8 @@ xen_intrin_local_irq_restore(unsigned long mask) else xen_rsm_i(); } -#else -#define __DEFINE_FUNC(name, code) \ - extern const char xen_ ## name ## _direct_start[]; \ - extern const char xen_ ## name ## _direct_end[]; \ - asm (".align 32\n" \ - ".proc xen_" #name "\n" \ - "xen_" #name ":\n" \ - "xen_" #name "_direct_start:\n" \ - code \ - "xen_" #name "_direct_end:\n" \ - "br.cond.sptk.many b6\n" \ - ".endp xen_" #name "\n") - -#define DEFINE_VOID_FUNC0(name, code) \ - extern void \ - xen_ ## name (void); \ - __DEFINE_FUNC(name, code) - -#define DEFINE_VOID_FUNC1(name, code) \ - extern void \ - xen_ ## name (unsigned long arg); \ - __DEFINE_FUNC(name, code) - -#define DEFINE_VOID_FUNC1_VOID(name, code) \ - extern void \ - xen_ ## name (void *arg); \ - __DEFINE_FUNC(name, code) - -#define DEFINE_VOID_FUNC2(name, code) \ - extern void \ - xen_ ## name (unsigned long arg0, \ - unsigned long arg1); \ - __DEFINE_FUNC(name, code) -#define DEFINE_FUNC0(name, code) \ - extern unsigned long \ - xen_ ## name (void); \ - __DEFINE_FUNC(name, code) - -#define DEFINE_FUNC1(name, type, code) \ - extern unsigned long \ - xen_ ## name (type arg); \ - __DEFINE_FUNC(name, code) - -#define XEN_PSR_I_ADDR_ADDR (XSI_BASE + XSI_PSR_I_ADDR_OFS) - -/* - * static void xen_set_itm_with_offset(unsigned long val) - * xen_set_itm(val - XEN_MAPPEDREGS->itc_offset); - */ -/* 2 bundles */ -DEFINE_VOID_FUNC1(set_itm_with_offset, - "mov r2 = " __stringify(XSI_BASE) " + " - __stringify(XSI_ITC_OFFSET_OFS) "\n" - ";;\n" - "ld8 r3 = [r2]\n" - ";;\n" - "sub r8 = r8, r3\n" - "break " __stringify(HYPERPRIVOP_SET_ITM) "\n"); - -/* - * static unsigned long xen_get_itm_with_offset(void) - * return ia64_native_getreg(_IA64_REG_CR_ITM) + XEN_MAPPEDREGS->itc_offset; - */ -/* 2 bundles */ -DEFINE_FUNC0(get_itm_with_offset, - "mov r2 = " __stringify(XSI_BASE) " + " - __stringify(XSI_ITC_OFFSET_OFS) "\n" - ";;\n" - "ld8 r3 = [r2]\n" - "mov r8 = cr.itm\n" - ";;\n" - "add r8 = r8, r2\n"); - -/* - * static void xen_set_itc(unsigned long val) - * unsigned long mitc; - * - * WARN_ON(!irqs_disabled()); - * mitc = ia64_native_getreg(_IA64_REG_AR_ITC); - * XEN_MAPPEDREGS->itc_offset = val - mitc; - * XEN_MAPPEDREGS->itc_last = val; - */ -/* 2 bundles */ -DEFINE_VOID_FUNC1(set_itc, - "mov r2 = " __stringify(XSI_BASE) " + " - __stringify(XSI_ITC_LAST_OFS) "\n" - "mov r3 = ar.itc\n" - ";;\n" - "sub r3 = r8, r3\n" - "st8 [r2] = r8, " - __stringify(XSI_ITC_LAST_OFS) " - " - __stringify(XSI_ITC_OFFSET_OFS) "\n" - ";;\n" - "st8 [r2] = r3\n"); - -/* - * static unsigned long xen_get_itc(void) - * unsigned long res; - * unsigned long itc_offset; - * unsigned long itc_last; - * unsigned long ret_itc_last; - * - * itc_offset = XEN_MAPPEDREGS->itc_offset; - * do { - * itc_last = XEN_MAPPEDREGS->itc_last; - * res = ia64_native_getreg(_IA64_REG_AR_ITC); - * res += itc_offset; - * if (itc_last >= res) - * res = itc_last + 1; - * ret_itc_last = cmpxchg(&XEN_MAPPEDREGS->itc_last, - * itc_last, res); - * } while (unlikely(ret_itc_last != itc_last)); - * return res; - */ -/* 5 bundles */ -DEFINE_FUNC0(get_itc, - "mov r2 = " __stringify(XSI_BASE) " + " - __stringify(XSI_ITC_OFFSET_OFS) "\n" - ";;\n" - "ld8 r9 = [r2], " __stringify(XSI_ITC_LAST_OFS) " - " - __stringify(XSI_ITC_OFFSET_OFS) "\n" - /* r9 = itc_offset */ - /* r2 = XSI_ITC_OFFSET */ - "888:\n" - "mov r8 = ar.itc\n" /* res = ar.itc */ - ";;\n" - "ld8 r3 = [r2]\n" /* r3 = itc_last */ - "add r8 = r8, r9\n" /* res = ar.itc + itc_offset */ - ";;\n" - "cmp.gtu p6, p0 = r3, r8\n" - ";;\n" - "(p6) add r8 = 1, r3\n" /* if (itc_last > res) itc_last + 1 */ - ";;\n" - "mov ar.ccv = r8\n" - ";;\n" - "cmpxchg8.acq r10 = [r2], r8, ar.ccv\n" - ";;\n" - "cmp.ne p6, p0 = r10, r3\n" - "(p6) hint @pause\n" - "(p6) br.cond.spnt 888b\n"); - -DEFINE_VOID_FUNC1_VOID(fc, - "break " __stringify(HYPERPRIVOP_FC) "\n"); - -/* - * psr_i_addr_addr = XEN_PSR_I_ADDR_ADDR - * masked_addr = *psr_i_addr_addr - * pending_intr_addr = masked_addr - 1 - * if (val & IA64_PSR_I) { - * masked = *masked_addr - * *masked_addr = 0:xen_set_virtual_psr_i(1) - * compiler barrier - * if (masked) { - * uint8_t pending = *pending_intr_addr; - * if (pending) - * XEN_HYPER_SSM_I - * } - * } else { - * *masked_addr = 1:xen_set_virtual_psr_i(0) - * } - */ -/* 6 bundles */ -DEFINE_VOID_FUNC1(intrin_local_irq_restore, - /* r8 = input value: 0 or IA64_PSR_I - * p6 = (flags & IA64_PSR_I) - * = if clause - * p7 = !(flags & IA64_PSR_I) - * = else clause - */ - "cmp.ne p6, p7 = r8, r0\n" - "mov r9 = " __stringify(XEN_PSR_I_ADDR_ADDR) "\n" - ";;\n" - /* r9 = XEN_PSR_I_ADDR */ - "ld8 r9 = [r9]\n" - ";;\n" - - /* r10 = masked previous value */ - "(p6) ld1.acq r10 = [r9]\n" - ";;\n" - - /* p8 = !masked interrupt masked previously? */ - "(p6) cmp.ne.unc p8, p0 = r10, r0\n" - - /* p7 = else clause */ - "(p7) mov r11 = 1\n" - ";;\n" - /* masked = 1 */ - "(p7) st1.rel [r9] = r11\n" - - /* p6 = if clause */ - /* masked = 0 - * r9 = masked_addr - 1 - * = pending_intr_addr - */ - "(p8) st1.rel [r9] = r0, -1\n" - ";;\n" - /* r8 = pending_intr */ - "(p8) ld1.acq r11 = [r9]\n" - ";;\n" - /* p9 = interrupt pending? */ - "(p8) cmp.ne.unc p9, p10 = r11, r0\n" - ";;\n" - "(p10) mf\n" - /* issue hypercall to trigger interrupt */ - "(p9) break " __stringify(HYPERPRIVOP_SSM_I) "\n"); - -DEFINE_VOID_FUNC2(ptcga, - "break " __stringify(HYPERPRIVOP_PTC_GA) "\n"); -DEFINE_VOID_FUNC2(set_rr, - "break " __stringify(HYPERPRIVOP_SET_RR) "\n"); - -/* - * tmp = XEN_MAPPEDREGS->interrupt_mask_addr = XEN_PSR_I_ADDR_ADDR; - * tmp = *tmp - * tmp = *tmp; - * psr_i = tmp? 0: IA64_PSR_I; - */ -/* 4 bundles */ -DEFINE_FUNC0(get_psr_i, - "mov r9 = " __stringify(XEN_PSR_I_ADDR_ADDR) "\n" - ";;\n" - "ld8 r9 = [r9]\n" /* r9 = XEN_PSR_I_ADDR */ - "mov r8 = 0\n" /* psr_i = 0 */ - ";;\n" - "ld1.acq r9 = [r9]\n" /* r9 = XEN_PSR_I */ - ";;\n" - "cmp.eq.unc p6, p0 = r9, r0\n" /* p6 = (XEN_PSR_I != 0) */ - ";;\n" - "(p6) mov r8 = " __stringify(1 << IA64_PSR_I_BIT) "\n"); - -DEFINE_FUNC1(thash, unsigned long, - "break " __stringify(HYPERPRIVOP_THASH) "\n"); -DEFINE_FUNC1(get_cpuid, int, - "break " __stringify(HYPERPRIVOP_GET_CPUID) "\n"); -DEFINE_FUNC1(get_pmd, int, - "break " __stringify(HYPERPRIVOP_GET_PMD) "\n"); -DEFINE_FUNC1(get_rr, unsigned long, - "break " __stringify(HYPERPRIVOP_GET_RR) "\n"); - -/* - * void xen_privop_ssm_i(void) - * - * int masked = !xen_get_virtual_psr_i(); - * // masked = *(*XEN_MAPPEDREGS->interrupt_mask_addr) - * xen_set_virtual_psr_i(1) - * // *(*XEN_MAPPEDREGS->interrupt_mask_addr) = 0 - * // compiler barrier - * if (masked) { - * uint8_t* pend_int_addr = - * (uint8_t*)(*XEN_MAPPEDREGS->interrupt_mask_addr) - 1; - * uint8_t pending = *pend_int_addr; - * if (pending) - * XEN_HYPER_SSM_I - * } - */ -/* 4 bundles */ -DEFINE_VOID_FUNC0(ssm_i, - "mov r8 = " __stringify(XEN_PSR_I_ADDR_ADDR) "\n" - ";;\n" - "ld8 r8 = [r8]\n" /* r8 = XEN_PSR_I_ADDR */ - ";;\n" - "ld1.acq r9 = [r8]\n" /* r9 = XEN_PSR_I */ - ";;\n" - "st1.rel [r8] = r0, -1\n" /* psr_i = 0. enable interrupt - * r8 = XEN_PSR_I_ADDR - 1 - * = pend_int_addr - */ - "cmp.eq.unc p0, p6 = r9, r0\n"/* p6 = !XEN_PSR_I - * previously interrupt - * masked? - */ - ";;\n" - "(p6) ld1.acq r8 = [r8]\n" /* r8 = xen_pend_int */ - ";;\n" - "(p6) cmp.eq.unc p6, p7 = r8, r0\n" /*interrupt pending?*/ - ";;\n" - /* issue hypercall to get interrupt */ - "(p7) break " __stringify(HYPERPRIVOP_SSM_I) "\n" - ";;\n"); - -/* - * psr_i_addr_addr = XEN_MAPPEDREGS->interrupt_mask_addr - * = XEN_PSR_I_ADDR_ADDR; - * psr_i_addr = *psr_i_addr_addr; - * *psr_i_addr = 1; - */ -/* 2 bundles */ -DEFINE_VOID_FUNC0(rsm_i, - "mov r8 = " __stringify(XEN_PSR_I_ADDR_ADDR) "\n" - /* r8 = XEN_PSR_I_ADDR */ - "mov r9 = 1\n" - ";;\n" - "ld8 r8 = [r8]\n" /* r8 = XEN_PSR_I */ - ";;\n" - "st1.rel [r8] = r9\n"); /* XEN_PSR_I = 1 */ - -extern void -xen_set_rr0_to_rr4(unsigned long val0, unsigned long val1, - unsigned long val2, unsigned long val3, - unsigned long val4); -__DEFINE_FUNC(set_rr0_to_rr4, - "break " __stringify(HYPERPRIVOP_SET_RR0_TO_RR4) "\n"); - - -extern unsigned long xen_getreg(int regnum); -#define __DEFINE_GET_REG(id, privop) \ - "mov r2 = " __stringify(_IA64_REG_ ## id) "\n" \ - ";;\n" \ - "cmp.eq p6, p0 = r2, r8\n" \ - ";;\n" \ - "(p6) break " __stringify(HYPERPRIVOP_GET_ ## privop) "\n" \ - "(p6) br.cond.sptk.many b6\n" \ - ";;\n" - -__DEFINE_FUNC(getreg, - __DEFINE_GET_REG(PSR, PSR) -#ifdef CONFIG_IA32_SUPPORT - __DEFINE_GET_REG(AR_EFLAG, EFLAG) -#endif - - /* get_itc */ - "mov r2 = " __stringify(_IA64_REG_AR_ITC) "\n" - ";;\n" - "cmp.eq p6, p0 = r2, r8\n" - ";;\n" - "(p6) br.cond.spnt xen_get_itc\n" - ";;\n" - - /* get itm */ - "mov r2 = " __stringify(_IA64_REG_CR_ITM) "\n" - ";;\n" - "cmp.eq p6, p0 = r2, r8\n" - ";;\n" - "(p6) br.cond.spnt xen_get_itm_with_offset\n" - ";;\n" - - __DEFINE_GET_REG(CR_IVR, IVR) - __DEFINE_GET_REG(CR_TPR, TPR) - - /* fall back */ - "movl r2 = ia64_native_getreg_func\n" - ";;\n" - "mov b7 = r2\n" - ";;\n" - "br.cond.sptk.many b7\n"); - -extern void xen_setreg(int regnum, unsigned long val); -#define __DEFINE_SET_REG(id, privop) \ - "mov r2 = " __stringify(_IA64_REG_ ## id) "\n" \ - ";;\n" \ - "cmp.eq p6, p0 = r2, r9\n" \ - ";;\n" \ - "(p6) break " __stringify(HYPERPRIVOP_ ## privop) "\n" \ - "(p6) br.cond.sptk.many b6\n" \ - ";;\n" - -__DEFINE_FUNC(setreg, - /* kr0 .. kr 7*/ - /* - * if (_IA64_REG_AR_KR0 <= regnum && - * regnum <= _IA64_REG_AR_KR7) { - * register __index asm ("r8") = regnum - _IA64_REG_AR_KR0 - * register __val asm ("r9") = val - * "break HYPERPRIVOP_SET_KR" - * } - */ - "mov r17 = r9\n" - "mov r2 = " __stringify(_IA64_REG_AR_KR0) "\n" - ";;\n" - "cmp.ge p6, p0 = r9, r2\n" - "sub r17 = r17, r2\n" - ";;\n" - "(p6) cmp.ge.unc p7, p0 = " - __stringify(_IA64_REG_AR_KR7) " - " __stringify(_IA64_REG_AR_KR0) - ", r17\n" - ";;\n" - "(p7) mov r9 = r8\n" - ";;\n" - "(p7) mov r8 = r17\n" - "(p7) break " __stringify(HYPERPRIVOP_SET_KR) "\n" - - /* set itm */ - "mov r2 = " __stringify(_IA64_REG_CR_ITM) "\n" - ";;\n" - "cmp.eq p6, p0 = r2, r8\n" - ";;\n" - "(p6) br.cond.spnt xen_set_itm_with_offset\n" - - /* set itc */ - "mov r2 = " __stringify(_IA64_REG_AR_ITC) "\n" - ";;\n" - "cmp.eq p6, p0 = r2, r8\n" - ";;\n" - "(p6) br.cond.spnt xen_set_itc\n" - -#ifdef CONFIG_IA32_SUPPORT - __DEFINE_SET_REG(AR_EFLAG, SET_EFLAG) -#endif - __DEFINE_SET_REG(CR_TPR, SET_TPR) - __DEFINE_SET_REG(CR_EOI, EOI) - - /* fall back */ - "movl r2 = ia64_native_setreg_func\n" - ";;\n" - "mov b7 = r2\n" - ";;\n" - "br.cond.sptk.many b7\n"); -#endif - -static const struct pv_cpu_ops xen_cpu_ops __initconst = { +static const struct pv_cpu_ops xen_cpu_ops __initdata = { .fc = xen_fc, .thash = xen_thash, .get_cpuid = xen_get_cpuid, @@ -880,7 +337,7 @@ xen_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val) HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op); } -static struct pv_iosapic_ops xen_iosapic_ops __initdata = { +static const struct pv_iosapic_ops xen_iosapic_ops __initconst = { .pcat_compat_init = xen_pcat_compat_init, .__get_irq_chip = xen_iosapic_get_irq_chip, @@ -898,8 +355,6 @@ xen_setup_pv_ops(void) xen_info_init(); pv_info = xen_info; pv_init_ops = xen_init_ops; - pv_fsys_data = xen_fsys_data; - pv_patchdata = xen_patchdata; pv_cpu_ops = xen_cpu_ops; pv_iosapic_ops = xen_iosapic_ops; pv_irq_ops = xen_irq_ops; @@ -907,252 +362,3 @@ xen_setup_pv_ops(void) paravirt_cpu_asm_init(&xen_cpu_asm_switch); } - -#ifdef ASM_SUPPORTED -/*************************************************************************** - * binary pacthing - * pv_init_ops.patch_bundle - */ - -#define DEFINE_FUNC_GETREG(name, privop) \ - DEFINE_FUNC0(get_ ## name, \ - "break "__stringify(HYPERPRIVOP_GET_ ## privop) "\n") - -DEFINE_FUNC_GETREG(psr, PSR); -DEFINE_FUNC_GETREG(eflag, EFLAG); -DEFINE_FUNC_GETREG(ivr, IVR); -DEFINE_FUNC_GETREG(tpr, TPR); - -#define DEFINE_FUNC_SET_KR(n) \ - DEFINE_VOID_FUNC0(set_kr ## n, \ - ";;\n" \ - "mov r9 = r8\n" \ - "mov r8 = " #n "\n" \ - "break " __stringify(HYPERPRIVOP_SET_KR) "\n") - -DEFINE_FUNC_SET_KR(0); -DEFINE_FUNC_SET_KR(1); -DEFINE_FUNC_SET_KR(2); -DEFINE_FUNC_SET_KR(3); -DEFINE_FUNC_SET_KR(4); -DEFINE_FUNC_SET_KR(5); -DEFINE_FUNC_SET_KR(6); -DEFINE_FUNC_SET_KR(7); - -#define __DEFINE_FUNC_SETREG(name, privop) \ - DEFINE_VOID_FUNC0(name, \ - "break "__stringify(HYPERPRIVOP_ ## privop) "\n") - -#define DEFINE_FUNC_SETREG(name, privop) \ - __DEFINE_FUNC_SETREG(set_ ## name, SET_ ## privop) - -DEFINE_FUNC_SETREG(eflag, EFLAG); -DEFINE_FUNC_SETREG(tpr, TPR); -__DEFINE_FUNC_SETREG(eoi, EOI); - -extern const char xen_check_events[]; -extern const char __xen_intrin_local_irq_restore_direct_start[]; -extern const char __xen_intrin_local_irq_restore_direct_end[]; -extern const unsigned long __xen_intrin_local_irq_restore_direct_reloc; - -asm ( - ".align 32\n" - ".proc xen_check_events\n" - "xen_check_events:\n" - /* masked = 0 - * r9 = masked_addr - 1 - * = pending_intr_addr - */ - "st1.rel [r9] = r0, -1\n" - ";;\n" - /* r8 = pending_intr */ - "ld1.acq r11 = [r9]\n" - ";;\n" - /* p9 = interrupt pending? */ - "cmp.ne p9, p10 = r11, r0\n" - ";;\n" - "(p10) mf\n" - /* issue hypercall to trigger interrupt */ - "(p9) break " __stringify(HYPERPRIVOP_SSM_I) "\n" - "br.cond.sptk.many b6\n" - ".endp xen_check_events\n" - "\n" - ".align 32\n" - ".proc __xen_intrin_local_irq_restore_direct\n" - "__xen_intrin_local_irq_restore_direct:\n" - "__xen_intrin_local_irq_restore_direct_start:\n" - "1:\n" - "{\n" - "cmp.ne p6, p7 = r8, r0\n" - "mov r17 = ip\n" /* get ip to calc return address */ - "mov r9 = "__stringify(XEN_PSR_I_ADDR_ADDR) "\n" - ";;\n" - "}\n" - "{\n" - /* r9 = XEN_PSR_I_ADDR */ - "ld8 r9 = [r9]\n" - ";;\n" - /* r10 = masked previous value */ - "(p6) ld1.acq r10 = [r9]\n" - "adds r17 = 1f - 1b, r17\n" /* calculate return address */ - ";;\n" - "}\n" - "{\n" - /* p8 = !masked interrupt masked previously? */ - "(p6) cmp.ne.unc p8, p0 = r10, r0\n" - "\n" - /* p7 = else clause */ - "(p7) mov r11 = 1\n" - ";;\n" - "(p8) mov b6 = r17\n" /* set return address */ - "}\n" - "{\n" - /* masked = 1 */ - "(p7) st1.rel [r9] = r11\n" - "\n" - "[99:]\n" - "(p8) brl.cond.dptk.few xen_check_events\n" - "}\n" - /* pv calling stub is 5 bundles. fill nop to adjust return address */ - "{\n" - "nop 0\n" - "nop 0\n" - "nop 0\n" - "}\n" - "1:\n" - "__xen_intrin_local_irq_restore_direct_end:\n" - ".endp __xen_intrin_local_irq_restore_direct\n" - "\n" - ".align 8\n" - "__xen_intrin_local_irq_restore_direct_reloc:\n" - "data8 99b\n" -); - -static struct paravirt_patch_bundle_elem xen_patch_bundle_elems[] -__initdata_or_module = -{ -#define XEN_PATCH_BUNDLE_ELEM(name, type) \ - { \ - (void*)xen_ ## name ## _direct_start, \ - (void*)xen_ ## name ## _direct_end, \ - PARAVIRT_PATCH_TYPE_ ## type, \ - } - - XEN_PATCH_BUNDLE_ELEM(fc, FC), - XEN_PATCH_BUNDLE_ELEM(thash, THASH), - XEN_PATCH_BUNDLE_ELEM(get_cpuid, GET_CPUID), - XEN_PATCH_BUNDLE_ELEM(get_pmd, GET_PMD), - XEN_PATCH_BUNDLE_ELEM(ptcga, PTCGA), - XEN_PATCH_BUNDLE_ELEM(get_rr, GET_RR), - XEN_PATCH_BUNDLE_ELEM(set_rr, SET_RR), - XEN_PATCH_BUNDLE_ELEM(set_rr0_to_rr4, SET_RR0_TO_RR4), - XEN_PATCH_BUNDLE_ELEM(ssm_i, SSM_I), - XEN_PATCH_BUNDLE_ELEM(rsm_i, RSM_I), - XEN_PATCH_BUNDLE_ELEM(get_psr_i, GET_PSR_I), - { - (void*)__xen_intrin_local_irq_restore_direct_start, - (void*)__xen_intrin_local_irq_restore_direct_end, - PARAVIRT_PATCH_TYPE_INTRIN_LOCAL_IRQ_RESTORE, - }, - -#define XEN_PATCH_BUNDLE_ELEM_GETREG(name, reg) \ - { \ - xen_get_ ## name ## _direct_start, \ - xen_get_ ## name ## _direct_end, \ - PARAVIRT_PATCH_TYPE_GETREG + _IA64_REG_ ## reg, \ - } - - XEN_PATCH_BUNDLE_ELEM_GETREG(psr, PSR), - XEN_PATCH_BUNDLE_ELEM_GETREG(eflag, AR_EFLAG), - - XEN_PATCH_BUNDLE_ELEM_GETREG(ivr, CR_IVR), - XEN_PATCH_BUNDLE_ELEM_GETREG(tpr, CR_TPR), - - XEN_PATCH_BUNDLE_ELEM_GETREG(itc, AR_ITC), - XEN_PATCH_BUNDLE_ELEM_GETREG(itm_with_offset, CR_ITM), - - -#define __XEN_PATCH_BUNDLE_ELEM_SETREG(name, reg) \ - { \ - xen_ ## name ## _direct_start, \ - xen_ ## name ## _direct_end, \ - PARAVIRT_PATCH_TYPE_SETREG + _IA64_REG_ ## reg, \ - } - -#define XEN_PATCH_BUNDLE_ELEM_SETREG(name, reg) \ - __XEN_PATCH_BUNDLE_ELEM_SETREG(set_ ## name, reg) - - XEN_PATCH_BUNDLE_ELEM_SETREG(kr0, AR_KR0), - XEN_PATCH_BUNDLE_ELEM_SETREG(kr1, AR_KR1), - XEN_PATCH_BUNDLE_ELEM_SETREG(kr2, AR_KR2), - XEN_PATCH_BUNDLE_ELEM_SETREG(kr3, AR_KR3), - XEN_PATCH_BUNDLE_ELEM_SETREG(kr4, AR_KR4), - XEN_PATCH_BUNDLE_ELEM_SETREG(kr5, AR_KR5), - XEN_PATCH_BUNDLE_ELEM_SETREG(kr6, AR_KR6), - XEN_PATCH_BUNDLE_ELEM_SETREG(kr7, AR_KR7), - - XEN_PATCH_BUNDLE_ELEM_SETREG(eflag, AR_EFLAG), - XEN_PATCH_BUNDLE_ELEM_SETREG(tpr, CR_TPR), - __XEN_PATCH_BUNDLE_ELEM_SETREG(eoi, CR_EOI), - - XEN_PATCH_BUNDLE_ELEM_SETREG(itc, AR_ITC), - XEN_PATCH_BUNDLE_ELEM_SETREG(itm_with_offset, CR_ITM), -}; - -static unsigned long __init_or_module -xen_patch_bundle(void *sbundle, void *ebundle, unsigned long type) -{ - const unsigned long nelems = sizeof(xen_patch_bundle_elems) / - sizeof(xen_patch_bundle_elems[0]); - unsigned long used; - const struct paravirt_patch_bundle_elem *found; - - used = __paravirt_patch_apply_bundle(sbundle, ebundle, type, - xen_patch_bundle_elems, nelems, - &found); - - if (found == NULL) - /* fallback */ - return ia64_native_patch_bundle(sbundle, ebundle, type); - if (used == 0) - return used; - - /* relocation */ - switch (type) { - case PARAVIRT_PATCH_TYPE_INTRIN_LOCAL_IRQ_RESTORE: { - unsigned long reloc = - __xen_intrin_local_irq_restore_direct_reloc; - unsigned long reloc_offset = reloc - (unsigned long) - __xen_intrin_local_irq_restore_direct_start; - unsigned long tag = (unsigned long)sbundle + reloc_offset; - paravirt_patch_reloc_brl(tag, xen_check_events); - break; - } - default: - /* nothing */ - break; - } - return used; -} -#endif /* ASM_SUPPOTED */ - -const struct paravirt_patch_branch_target xen_branch_target[] -__initconst = { -#define PARAVIRT_BR_TARGET(name, type) \ - { \ - &xen_ ## name, \ - PARAVIRT_PATCH_TYPE_BR_ ## type, \ - } - PARAVIRT_BR_TARGET(switch_to, SWITCH_TO), - PARAVIRT_BR_TARGET(leave_syscall, LEAVE_SYSCALL), - PARAVIRT_BR_TARGET(work_processed_syscall, WORK_PROCESSED_SYSCALL), - PARAVIRT_BR_TARGET(leave_kernel, LEAVE_KERNEL), -}; - -static void __init -xen_patch_branch(unsigned long tag, unsigned long type) -{ - const unsigned long nelem = - sizeof(xen_branch_target) / sizeof(xen_branch_target[0]); - __paravirt_patch_apply_branch(tag, type, xen_branch_target, nelem); -} diff --git a/trunk/arch/m32r/kernel/process.c b/trunk/arch/m32r/kernel/process.c index 3e876f0baebc..7103d91e1a2f 100644 --- a/trunk/arch/m32r/kernel/process.c +++ b/trunk/arch/m32r/kernel/process.c @@ -225,7 +225,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) return 0; /* Task didn't use the fpu at all. */ } -int copy_thread(unsigned long clone_flags, unsigned long spu, +int copy_thread(int nr, unsigned long clone_flags, unsigned long spu, unsigned long unused, struct task_struct *tsk, struct pt_regs *regs) { struct pt_regs *childregs = task_pt_regs(tsk); diff --git a/trunk/arch/m32r/kernel/time.c b/trunk/arch/m32r/kernel/time.c index cada3ba4b990..6ea017727cce 100644 --- a/trunk/arch/m32r/kernel/time.c +++ b/trunk/arch/m32r/kernel/time.c @@ -230,6 +230,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) static struct irqaction irq0 = { .handler = timer_interrupt, .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, .name = "MFT2", }; diff --git a/trunk/arch/m68k/include/asm/ide.h b/trunk/arch/m68k/include/asm/ide.h index 3958726664ba..b996a3c8cff5 100644 --- a/trunk/arch/m68k/include/asm/ide.h +++ b/trunk/arch/m68k/include/asm/ide.h @@ -30,28 +30,101 @@ #define _M68K_IDE_H #ifdef __KERNEL__ + + #include #include #include +#ifdef CONFIG_ATARI +#include +#include +#endif + +#ifdef CONFIG_MAC +#include +#endif + /* * Get rid of defs from io.h - ide has its private and conflicting versions * Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we * always use the `raw' MMIO versions */ +#undef inb +#undef inw +#undef insw +#undef inl +#undef insl +#undef outb +#undef outw +#undef outsw +#undef outl +#undef outsl #undef readb #undef readw +#undef readl #undef writeb #undef writew +#undef writel +#define inb in_8 +#define inw in_be16 +#define insw(port, addr, n) raw_insw((u16 *)port, addr, n) +#define inl in_be32 +#define insl(port, addr, n) raw_insl((u32 *)port, addr, n) +#define outb(val, port) out_8(port, val) +#define outw(val, port) out_be16(port, val) +#define outsw(port, addr, n) raw_outsw((u16 *)port, addr, n) +#define outl(val, port) out_be32(port, val) +#define outsl(port, addr, n) raw_outsl((u32 *)port, addr, n) #define readb in_8 #define readw in_be16 #define __ide_mm_insw(port, addr, n) raw_insw((u16 *)port, addr, n) +#define readl in_be32 #define __ide_mm_insl(port, addr, n) raw_insl((u32 *)port, addr, n) #define writeb(val, port) out_8(port, val) #define writew(val, port) out_be16(port, val) #define __ide_mm_outsw(port, addr, n) raw_outsw((u16 *)port, addr, n) +#define writel(val, port) out_be32(port, val) #define __ide_mm_outsl(port, addr, n) raw_outsl((u32 *)port, addr, n) +#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) +#define insw_swapw(port, addr, n) raw_insw_swapw((u16 *)port, addr, n) +#define outsw_swapw(port, addr, n) raw_outsw_swapw((u16 *)port, addr, n) +#endif + +#ifdef CONFIG_BLK_DEV_FALCON_IDE +#define IDE_ARCH_LOCK + +extern int falconide_intr_lock; + +static __inline__ void ide_release_lock (void) +{ + if (MACH_IS_ATARI) { + if (falconide_intr_lock == 0) { + printk("ide_release_lock: bug\n"); + return; + } + falconide_intr_lock = 0; + stdma_release(); + } +} + +static __inline__ void +ide_get_lock(irq_handler_t handler, void *data) +{ + if (MACH_IS_ATARI) { + if (falconide_intr_lock == 0) { + if (in_interrupt() > 0) + panic( "Falcon IDE hasn't ST-DMA lock in interrupt" ); + stdma_lock(handler, data); + falconide_intr_lock = 1; + } + } +} +#endif /* CONFIG_BLK_DEV_FALCON_IDE */ + +#define IDE_ARCH_ACK_INTR +#define ide_ack_intr(hwif) ((hwif)->ack_intr ? (hwif)->ack_intr(hwif) : 1) #endif /* __KERNEL__ */ #endif /* _M68K_IDE_H */ diff --git a/trunk/arch/m68k/kernel/process.c b/trunk/arch/m68k/kernel/process.c index ec37fb56c127..632ce016014d 100644 --- a/trunk/arch/m68k/kernel/process.c +++ b/trunk/arch/m68k/kernel/process.c @@ -233,7 +233,7 @@ asmlinkage int m68k_clone(struct pt_regs *regs) parent_tidptr, child_tidptr); } -int copy_thread(unsigned long clone_flags, unsigned long usp, +int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct * p, struct pt_regs * regs) { diff --git a/trunk/arch/m68knommu/kernel/process.c b/trunk/arch/m68knommu/kernel/process.c index 1e96c6eb6312..3f2d7745f31e 100644 --- a/trunk/arch/m68knommu/kernel/process.c +++ b/trunk/arch/m68knommu/kernel/process.c @@ -199,7 +199,7 @@ asmlinkage int m68k_clone(struct pt_regs *regs) return do_fork(clone_flags, newsp, regs, 0, NULL, NULL); } -int copy_thread(unsigned long clone_flags, +int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long topstk, struct task_struct * p, struct pt_regs * regs) { diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index dc787190430a..206cb7953b0c 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -77,6 +77,7 @@ config MIPS_COBALT select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN + select GENERIC_HARDIRQS_NO__DO_IRQ config MACH_DECSTATION bool "DECstations" @@ -131,6 +132,7 @@ config MACH_JAZZ select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL select SYS_SUPPORTS_100HZ + select GENERIC_HARDIRQS_NO__DO_IRQ help This a family of machines based on the MIPS R4030 chipset which was used by several vendors to build RISC/os and Windows NT workstations. @@ -152,6 +154,7 @@ config LASAT select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL if BROKEN select SYS_SUPPORTS_LITTLE_ENDIAN + select GENERIC_HARDIRQS_NO__DO_IRQ config LEMOTE_FULONG bool "Lemote Fulong mini-PC" @@ -172,6 +175,7 @@ config LEMOTE_FULONG select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_HIGHMEM select SYS_HAS_EARLY_PRINTK + select GENERIC_HARDIRQS_NO__DO_IRQ select GENERIC_ISA_DMA_SUPPORT_BROKEN select CPU_HAS_WB help @@ -246,6 +250,7 @@ config MACH_VR41XX select CEVT_R4K select CSRC_R4K select SYS_HAS_CPU_VR41XX + select GENERIC_HARDIRQS_NO__DO_IRQ config NXP_STB220 bool "NXP STB220 board" @@ -359,6 +364,7 @@ config SGI_IP27 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_NUMA select SYS_SUPPORTS_SMP + select GENERIC_HARDIRQS_NO__DO_IRQ help This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics workstations. To compile a Linux kernel that runs on these, say Y @@ -557,6 +563,7 @@ config MIKROTIK_RB532 select CEVT_R4K select CSRC_R4K select DMA_NONCOHERENT + select GENERIC_HARDIRQS_NO__DO_IRQ select HW_HAS_PCI select IRQ_CPU select SYS_HAS_CPU_MIPS32_R1 @@ -693,7 +700,8 @@ config SCHED_OMIT_FRAME_POINTER default y config GENERIC_HARDIRQS_NO__DO_IRQ - def_bool y + bool + default n # # Select some configuration options automatically based on user selections. @@ -912,6 +920,7 @@ config SOC_PNX833X select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_BIG_ENDIAN + select GENERIC_HARDIRQS_NO__DO_IRQ select GENERIC_GPIO select CPU_MIPSR2_IRQ_VI @@ -930,6 +939,7 @@ config SOC_PNX8550 select SYS_HAS_CPU_MIPS32_R1 select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_32BIT_KERNEL + select GENERIC_HARDIRQS_NO__DO_IRQ select GENERIC_GPIO config SWAP_IO_SPACE diff --git a/trunk/arch/mips/Makefile b/trunk/arch/mips/Makefile index 8d544c7c9fe9..22dab2e14348 100644 --- a/trunk/arch/mips/Makefile +++ b/trunk/arch/mips/Makefile @@ -720,17 +720,11 @@ ifdef CONFIG_MIPS32_O32 $(Q)$(MAKE) $(build)=. missing-syscalls EXTRA_CFLAGS="-mabi=32" endif -install: - $(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE) - $(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE) - $(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE) - archclean: @$(MAKE) $(clean)=arch/mips/boot @$(MAKE) $(clean)=arch/mips/lasat define archhelp - echo ' install - install kernel into $(INSTALL_PATH)' echo ' vmlinux.ecoff - ECOFF boot image' echo ' vmlinux.bin - Raw binary boot image' echo ' vmlinux.srec - SREC boot image' diff --git a/trunk/arch/mips/alchemy/Kconfig b/trunk/arch/mips/alchemy/Kconfig index 8128aebfb155..7f8ef13d0014 100644 --- a/trunk/arch/mips/alchemy/Kconfig +++ b/trunk/arch/mips/alchemy/Kconfig @@ -134,4 +134,4 @@ config SOC_AU1X00 select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_APM_EMULATION - select ARCH_REQUIRE_GPIOLIB + select GENERIC_HARDIRQS_NO__DO_IRQ diff --git a/trunk/arch/mips/alchemy/common/gpio.c b/trunk/arch/mips/alchemy/common/gpio.c index 91a9c4436c39..e660ddd611c4 100644 --- a/trunk/arch/mips/alchemy/common/gpio.c +++ b/trunk/arch/mips/alchemy/common/gpio.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli + * Copyright (C) 2007, OpenWrt.org, Florian Fainelli * Architecture specific GPIO support * * This program is free software; you can redistribute it and/or modify it @@ -27,175 +27,122 @@ * others have a second one : GPIO2 */ -#include #include -#include -#include -#include #include #include -struct au1000_gpio_chip { - struct gpio_chip chip; - void __iomem *regbase; -}; - +#define gpio1 sys #if !defined(CONFIG_SOC_AU1000) -static int au1000_gpio2_get(struct gpio_chip *chip, unsigned offset) -{ - u32 mask = 1 << offset; - struct au1000_gpio_chip *gpch; - gpch = container_of(chip, struct au1000_gpio_chip, chip); - return readl(gpch->regbase + AU1000_GPIO2_ST) & mask; -} +static struct au1x00_gpio2 *const gpio2 = (struct au1x00_gpio2 *) GPIO2_BASE; +#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000 -static void au1000_gpio2_set(struct gpio_chip *chip, - unsigned offset, int value) +static int au1xxx_gpio2_read(unsigned gpio) { - u32 mask = ((GPIO2_OUT_EN_MASK << offset) | (!!value << offset)); - struct au1000_gpio_chip *gpch; - unsigned long flags; - - gpch = container_of(chip, struct au1000_gpio_chip, chip); - - local_irq_save(flags); - writel(mask, gpch->regbase + AU1000_GPIO2_OUT); - local_irq_restore(flags); + gpio -= AU1XXX_GPIO_BASE; + return ((gpio2->pinstate >> gpio) & 0x01); } -static int au1000_gpio2_direction_input(struct gpio_chip *chip, unsigned offset) +static void au1xxx_gpio2_write(unsigned gpio, int value) { - u32 mask = 1 << offset; - u32 tmp; - struct au1000_gpio_chip *gpch; - unsigned long flags; + gpio -= AU1XXX_GPIO_BASE; - gpch = container_of(chip, struct au1000_gpio_chip, chip); - - local_irq_save(flags); - tmp = readl(gpch->regbase + AU1000_GPIO2_DIR); - tmp &= ~mask; - writel(tmp, gpch->regbase + AU1000_GPIO2_DIR); - local_irq_restore(flags); + gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio); +} +static int au1xxx_gpio2_direction_input(unsigned gpio) +{ + gpio -= AU1XXX_GPIO_BASE; + gpio2->dir &= ~(0x01 << gpio); return 0; } -static int au1000_gpio2_direction_output(struct gpio_chip *chip, - unsigned offset, int value) +static int au1xxx_gpio2_direction_output(unsigned gpio, int value) { - u32 mask = 1 << offset; - u32 out_mask = ((GPIO2_OUT_EN_MASK << offset) | (!!value << offset)); - u32 tmp; - struct au1000_gpio_chip *gpch; - unsigned long flags; - - gpch = container_of(chip, struct au1000_gpio_chip, chip); - - local_irq_save(flags); - tmp = readl(gpch->regbase + AU1000_GPIO2_DIR); - tmp |= mask; - writel(tmp, gpch->regbase + AU1000_GPIO2_DIR); - writel(out_mask, gpch->regbase + AU1000_GPIO2_OUT); - local_irq_restore(flags); - + gpio -= AU1XXX_GPIO_BASE; + gpio2->dir |= 0x01 << gpio; + gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio); return 0; } + #endif /* !defined(CONFIG_SOC_AU1000) */ -static int au1000_gpio1_get(struct gpio_chip *chip, unsigned offset) +static int au1xxx_gpio1_read(unsigned gpio) { - u32 mask = 1 << offset; - struct au1000_gpio_chip *gpch; - - gpch = container_of(chip, struct au1000_gpio_chip, chip); - return readl(gpch->regbase + AU1000_GPIO1_ST) & mask; + return (gpio1->pinstaterd >> gpio) & 0x01; } -static void au1000_gpio1_set(struct gpio_chip *chip, - unsigned offset, int value) +static void au1xxx_gpio1_write(unsigned gpio, int value) { - u32 mask = 1 << offset; - u32 reg_offset; - struct au1000_gpio_chip *gpch; - unsigned long flags; - - gpch = container_of(chip, struct au1000_gpio_chip, chip); - if (value) - reg_offset = AU1000_GPIO1_OUT; + gpio1->outputset = (0x01 << gpio); else - reg_offset = AU1000_GPIO1_CLR; - - local_irq_save(flags); - writel(mask, gpch->regbase + reg_offset); - local_irq_restore(flags); + /* Output a zero */ + gpio1->outputclr = (0x01 << gpio); } -static int au1000_gpio1_direction_input(struct gpio_chip *chip, unsigned offset) +static int au1xxx_gpio1_direction_input(unsigned gpio) { - u32 mask = 1 << offset; - struct au1000_gpio_chip *gpch; - - gpch = container_of(chip, struct au1000_gpio_chip, chip); - writel(mask, gpch->regbase + AU1000_GPIO1_ST); - + gpio1->pininputen = (0x01 << gpio); return 0; } -static int au1000_gpio1_direction_output(struct gpio_chip *chip, - unsigned offset, int value) +static int au1xxx_gpio1_direction_output(unsigned gpio, int value) { - u32 mask = 1 << offset; - struct au1000_gpio_chip *gpch; - - gpch = container_of(chip, struct au1000_gpio_chip, chip); - - writel(mask, gpch->regbase + AU1000_GPIO1_TRI_OUT); - au1000_gpio1_set(chip, offset, value); - + gpio1->trioutclr = (0x01 & gpio); + au1xxx_gpio1_write(gpio, value); return 0; } -struct au1000_gpio_chip au1000_gpio_chip[] = { - [0] = { - .regbase = (void __iomem *)SYS_BASE, - .chip = { - .label = "au1000-gpio1", - .direction_input = au1000_gpio1_direction_input, - .direction_output = au1000_gpio1_direction_output, - .get = au1000_gpio1_get, - .set = au1000_gpio1_set, - .base = 0, - .ngpio = 32, - }, - }, -#if !defined(CONFIG_SOC_AU1000) - [1] = { - .regbase = (void __iomem *)GPIO2_BASE, - .chip = { - .label = "au1000-gpio2", - .direction_input = au1000_gpio2_direction_input, - .direction_output = au1000_gpio2_direction_output, - .get = au1000_gpio2_get, - .set = au1000_gpio2_set, - .base = AU1XXX_GPIO_BASE, - .ngpio = 32, - }, - }, +int au1xxx_gpio_get_value(unsigned gpio) +{ + if (gpio >= AU1XXX_GPIO_BASE) +#if defined(CONFIG_SOC_AU1000) + return 0; +#else + return au1xxx_gpio2_read(gpio); #endif -}; + else + return au1xxx_gpio1_read(gpio); +} +EXPORT_SYMBOL(au1xxx_gpio_get_value); -static int __init au1000_gpio_init(void) +void au1xxx_gpio_set_value(unsigned gpio, int value) { - gpiochip_add(&au1000_gpio_chip[0].chip); -#if !defined(CONFIG_SOC_AU1000) - gpiochip_add(&au1000_gpio_chip[1].chip); + if (gpio >= AU1XXX_GPIO_BASE) +#if defined(CONFIG_SOC_AU1000) + ; +#else + au1xxx_gpio2_write(gpio, value); +#endif + else + au1xxx_gpio1_write(gpio, value); +} +EXPORT_SYMBOL(au1xxx_gpio_set_value); + +int au1xxx_gpio_direction_input(unsigned gpio) +{ + if (gpio >= AU1XXX_GPIO_BASE) +#if defined(CONFIG_SOC_AU1000) + return -ENODEV; +#else + return au1xxx_gpio2_direction_input(gpio); #endif - return 0; + return au1xxx_gpio1_direction_input(gpio); } -arch_initcall(au1000_gpio_init); +EXPORT_SYMBOL(au1xxx_gpio_direction_input); +int au1xxx_gpio_direction_output(unsigned gpio, int value) +{ + if (gpio >= AU1XXX_GPIO_BASE) +#if defined(CONFIG_SOC_AU1000) + return -ENODEV; +#else + return au1xxx_gpio2_direction_output(gpio, value); +#endif + + return au1xxx_gpio1_direction_output(gpio, value); +} +EXPORT_SYMBOL(au1xxx_gpio_direction_output); diff --git a/trunk/arch/mips/alchemy/devboards/pb1200/platform.c b/trunk/arch/mips/alchemy/devboards/pb1200/platform.c index 0d68e1985ffd..95303297c534 100644 --- a/trunk/arch/mips/alchemy/devboards/pb1200/platform.c +++ b/trunk/arch/mips/alchemy/devboards/pb1200/platform.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -132,12 +131,6 @@ static struct platform_device ide_device = { .resource = ide_resources }; -static struct smc91x_platdata smc_data = { - .flags = SMC91X_NOWAIT | SMC91X_USE_16BIT, - .leda = RPC_LED_100_10, - .ledb = RPC_LED_TX_RX, -}; - static struct resource smc91c111_resources[] = { [0] = { .name = "smc91x-regs", @@ -153,9 +146,6 @@ static struct resource smc91c111_resources[] = { }; static struct platform_device smc91c111_device = { - .dev = { - .platform_data = &smc_data, - }, .name = "smc91x", .id = -1, .num_resources = ARRAY_SIZE(smc91c111_resources), diff --git a/trunk/arch/mips/cavium-octeon/Makefile b/trunk/arch/mips/cavium-octeon/Makefile index d6903c3f3d51..1c2a7faf5881 100644 --- a/trunk/arch/mips/cavium-octeon/Makefile +++ b/trunk/arch/mips/cavium-octeon/Makefile @@ -14,5 +14,3 @@ obj-y += dma-octeon.o flash_setup.o obj-y += octeon-memcpy.o obj-$(CONFIG_SMP) += smp.o - -EXTRA_CFLAGS += -Werror diff --git a/trunk/arch/mips/cavium-octeon/flash_setup.c b/trunk/arch/mips/cavium-octeon/flash_setup.c index 008f657116eb..553d36cbcc42 100644 --- a/trunk/arch/mips/cavium-octeon/flash_setup.c +++ b/trunk/arch/mips/cavium-octeon/flash_setup.c @@ -57,7 +57,7 @@ static int __init flash_init(void) flash_map.bankwidth = 1; flash_map.virt = ioremap(flash_map.phys, flash_map.size); pr_notice("Bootbus flash: Setting flash for %luMB flash at " - "0x%08llx\n", flash_map.size >> 20, flash_map.phys); + "0x%08lx\n", flash_map.size >> 20, flash_map.phys); simple_map_init(&flash_map); mymtd = do_map_probe("cfi_probe", &flash_map); if (mymtd) { diff --git a/trunk/arch/mips/cavium-octeon/octeon-irq.c b/trunk/arch/mips/cavium-octeon/octeon-irq.c index 1c19af8daa62..fc72984a5dae 100644 --- a/trunk/arch/mips/cavium-octeon/octeon-irq.c +++ b/trunk/arch/mips/cavium-octeon/octeon-irq.c @@ -31,7 +31,7 @@ static void octeon_irq_core_ack(unsigned int irq) static void octeon_irq_core_eoi(unsigned int irq) { - struct irq_desc *desc = irq_desc + irq; + irq_desc_t *desc = irq_desc + irq; unsigned int bit = irq - OCTEON_IRQ_SW0; /* * If an IRQ is being processed while we are disabling it the diff --git a/trunk/arch/mips/cobalt/irq.c b/trunk/arch/mips/cobalt/irq.c index cb9bf820fe53..ac4fb912649d 100644 --- a/trunk/arch/mips/cobalt/irq.c +++ b/trunk/arch/mips/cobalt/irq.c @@ -47,6 +47,7 @@ asmlinkage void plat_irq_dispatch(void) static struct irqaction cascade = { .handler = no_action, + .mask = CPU_MASK_NONE, .name = "cascade", }; diff --git a/trunk/arch/mips/emma/markeins/irq.c b/trunk/arch/mips/emma/markeins/irq.c index 43828ae796ec..c2583ecc93cf 100644 --- a/trunk/arch/mips/emma/markeins/irq.c +++ b/trunk/arch/mips/emma/markeins/irq.c @@ -80,9 +80,9 @@ void emma2rh_irq_init(void) u32 i; for (i = 0; i < NUM_EMMA2RH_IRQ; i++) - set_irq_chip_and_handler_name(EMMA2RH_IRQ_BASE + i, - &emma2rh_irq_controller, - handle_level_irq, "level"); + set_irq_chip_and_handler(EMMA2RH_IRQ_BASE + i, + &emma2rh_irq_controller, + handle_level_irq); } static void emma2rh_sw_irq_enable(unsigned int irq) @@ -120,9 +120,9 @@ void emma2rh_sw_irq_init(void) u32 i; for (i = 0; i < NUM_EMMA2RH_IRQ_SW; i++) - set_irq_chip_and_handler_name(EMMA2RH_SW_IRQ_BASE + i, - &emma2rh_sw_irq_controller, - handle_level_irq, "level"); + set_irq_chip_and_handler(EMMA2RH_SW_IRQ_BASE + i, + &emma2rh_sw_irq_controller, + handle_level_irq); } static void emma2rh_gpio_irq_enable(unsigned int irq) @@ -148,12 +148,6 @@ static void emma2rh_gpio_irq_disable(unsigned int irq) } static void emma2rh_gpio_irq_ack(unsigned int irq) -{ - irq -= EMMA2RH_GPIO_IRQ_BASE; - emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq)); -} - -static void emma2rh_gpio_irq_mask_ack(unsigned int irq) { u32 reg; @@ -165,12 +159,27 @@ static void emma2rh_gpio_irq_mask_ack(unsigned int irq) emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); } +static void emma2rh_gpio_irq_end(unsigned int irq) +{ + u32 reg; + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + + irq -= EMMA2RH_GPIO_IRQ_BASE; + + reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); + reg |= 1 << irq; + emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); + } +} + struct irq_chip emma2rh_gpio_irq_controller = { .name = "emma2rh_gpio_irq", .ack = emma2rh_gpio_irq_ack, .mask = emma2rh_gpio_irq_disable, - .mask_ack = emma2rh_gpio_irq_mask_ack, + .mask_ack = emma2rh_gpio_irq_ack, .unmask = emma2rh_gpio_irq_enable, + .end = emma2rh_gpio_irq_end, }; void emma2rh_gpio_irq_init(void) @@ -178,14 +187,14 @@ void emma2rh_gpio_irq_init(void) u32 i; for (i = 0; i < NUM_EMMA2RH_IRQ_GPIO; i++) - set_irq_chip_and_handler_name(EMMA2RH_GPIO_IRQ_BASE + i, - &emma2rh_gpio_irq_controller, - handle_edge_irq, "edge"); + set_irq_chip(EMMA2RH_GPIO_IRQ_BASE + i, + &emma2rh_gpio_irq_controller); } static struct irqaction irq_cascade = { .handler = no_action, .flags = 0, + .mask = CPU_MASK_NONE, .name = "cascade", .dev_id = NULL, .next = NULL, @@ -204,7 +213,8 @@ void emma2rh_irq_dispatch(void) emma2rh_in32(EMMA2RH_BHIF_INT_EN_0); #ifdef EMMA2RH_SW_CASCADE - if (intStatus & (1UL << EMMA2RH_SW_CASCADE)) { + if (intStatus & + (1 << ((EMMA2RH_SW_CASCADE - EMMA2RH_IRQ_INT0) & (32 - 1)))) { u32 swIntStatus; swIntStatus = emma2rh_in32(EMMA2RH_BHIF_SW_INT) & emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); @@ -215,8 +225,6 @@ void emma2rh_irq_dispatch(void) } } } - /* Skip S/W interrupt */ - intStatus &= ~(1UL << EMMA2RH_SW_CASCADE); #endif for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) { @@ -230,7 +238,8 @@ void emma2rh_irq_dispatch(void) emma2rh_in32(EMMA2RH_BHIF_INT_EN_1); #ifdef EMMA2RH_GPIO_CASCADE - if (intStatus & (1UL << (EMMA2RH_GPIO_CASCADE % 32))) { + if (intStatus & + (1 << ((EMMA2RH_GPIO_CASCADE - EMMA2RH_IRQ_INT0) & (32 - 1)))) { u32 gpioIntStatus; gpioIntStatus = emma2rh_in32(EMMA2RH_GPIO_INT_ST) & emma2rh_in32(EMMA2RH_GPIO_INT_MASK); @@ -241,8 +250,6 @@ void emma2rh_irq_dispatch(void) } } } - /* Skip GPIO interrupt */ - intStatus &= ~(1UL << (EMMA2RH_GPIO_CASCADE % 32)); #endif for (i = 32, bitmask = 1; i < 64; i++, bitmask <<= 1) { diff --git a/trunk/arch/mips/emma/markeins/platform.c b/trunk/arch/mips/emma/markeins/platform.c index 80ae12ef87db..d5f47e4f0d18 100644 --- a/trunk/arch/mips/emma/markeins/platform.c +++ b/trunk/arch/mips/emma/markeins/platform.c @@ -110,7 +110,6 @@ struct platform_device i2c_emma_devices[] = { static struct plat_serial8250_port platform_serial_ports[] = { [0] = { .membase= (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3), - .mapbase = EMMA2RH_PFUR0_BASE + 3, .irq = EMMA2RH_IRQ_PFUR0, .uartclk = EMMA2RH_SERIAL_CLOCK, .regshift = 4, @@ -118,7 +117,6 @@ static struct plat_serial8250_port platform_serial_ports[] = { .flags = EMMA2RH_SERIAL_FLAGS, }, [1] = { .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3), - .mapbase = EMMA2RH_PFUR1_BASE + 3, .irq = EMMA2RH_IRQ_PFUR1, .uartclk = EMMA2RH_SERIAL_CLOCK, .regshift = 4, @@ -126,7 +124,6 @@ static struct plat_serial8250_port platform_serial_ports[] = { .flags = EMMA2RH_SERIAL_FLAGS, }, [2] = { .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3), - .mapbase = EMMA2RH_PFUR2_BASE + 3, .irq = EMMA2RH_IRQ_PFUR2, .uartclk = EMMA2RH_SERIAL_CLOCK, .regshift = 4, diff --git a/trunk/arch/mips/include/asm/cpu.h b/trunk/arch/mips/include/asm/cpu.h index 3bdc0e3d89cc..c018727c7ddc 100644 --- a/trunk/arch/mips/include/asm/cpu.h +++ b/trunk/arch/mips/include/asm/cpu.h @@ -209,7 +209,8 @@ enum cpu_type_enum { * MIPS32 class processors */ CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K, - CPU_ALCHEMY, CPU_PR4450, CPU_BCM3302, CPU_BCM4710, + CPU_AU1000, CPU_AU1100, CPU_AU1200, CPU_AU1210, CPU_AU1250, CPU_AU1500, + CPU_AU1550, CPU_PR4450, CPU_BCM3302, CPU_BCM4710, /* * MIPS64 class processors diff --git a/trunk/arch/mips/include/asm/hazards.h b/trunk/arch/mips/include/asm/hazards.h index a12d971db4f9..134e1fc8f4d6 100644 --- a/trunk/arch/mips/include/asm/hazards.h +++ b/trunk/arch/mips/include/asm/hazards.h @@ -87,7 +87,7 @@ do { \ : "=r" (tmp)); \ } while (0) -#elif defined(CONFIG_CPU_MIPSR1) && !defined(CONFIG_MACH_ALCHEMY) +#elif defined(CONFIG_CPU_MIPSR1) /* * These are slightly complicated by the fact that we guarantee R1 kernels to @@ -139,7 +139,7 @@ do { \ } while (0) #elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \ - defined(CONFIG_CPU_R5500) || defined(CONFIG_MACH_ALCHEMY) + defined(CONFIG_CPU_R5500) /* * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. diff --git a/trunk/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h b/trunk/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h deleted file mode 100644 index d5df0cab9b87..000000000000 --- a/trunk/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ - -#ifndef __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H -#define __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H - -#define cpu_has_tlb 1 -#define cpu_has_4kex 1 -#define cpu_has_3k_cache 0 -#define cpu_has_4k_cache 1 -#define cpu_has_tx39_cache 0 -#define cpu_has_fpu 0 -#define cpu_has_counter 1 -#define cpu_has_watch 1 -#define cpu_has_divec 1 -#define cpu_has_vce 0 -#define cpu_has_cache_cdex_p 0 -#define cpu_has_cache_cdex_s 0 -#define cpu_has_mcheck 1 -#define cpu_has_ejtag 1 -#define cpu_has_llsc 1 -#define cpu_has_mips16 0 -#define cpu_has_mdmx 0 -#define cpu_has_mips3d 0 -#define cpu_has_smartmips 0 -#define cpu_has_vtag_icache 0 -#define cpu_has_dc_aliases 0 -#define cpu_has_ic_fills_f_dc 1 -#define cpu_has_mips32r1 1 -#define cpu_has_mips32r2 0 -#define cpu_has_mips64r1 0 -#define cpu_has_mips64r2 0 -#define cpu_has_dsp 0 -#define cpu_has_mipsmt 0 -#define cpu_has_userlocal 0 -#define cpu_has_nofpuex 0 -#define cpu_has_64bits 0 -#define cpu_has_64bit_zero_reg 0 -#define cpu_has_vint 0 -#define cpu_has_veic 0 -#define cpu_has_inclusive_pcaches 0 - -#define cpu_dcache_line_size() 32 -#define cpu_icache_line_size() 32 - -#endif /* __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H */ diff --git a/trunk/arch/mips/include/asm/mach-au1x00/gpio.h b/trunk/arch/mips/include/asm/mach-au1x00/gpio.h index 34d9b7279024..2dc61e009a08 100644 --- a/trunk/arch/mips/include/asm/mach-au1x00/gpio.h +++ b/trunk/arch/mips/include/asm/mach-au1x00/gpio.h @@ -5,29 +5,65 @@ #define AU1XXX_GPIO_BASE 200 -/* GPIO bank 1 offsets */ -#define AU1000_GPIO1_TRI_OUT 0x0100 -#define AU1000_GPIO1_OUT 0x0108 -#define AU1000_GPIO1_ST 0x0110 -#define AU1000_GPIO1_CLR 0x010C +struct au1x00_gpio2 { + u32 dir; + u32 reserved; + u32 output; + u32 pinstate; + u32 inten; + u32 enable; +}; -/* GPIO bank 2 offsets */ -#define AU1000_GPIO2_DIR 0x00 -#define AU1000_GPIO2_RSVD 0x04 -#define AU1000_GPIO2_OUT 0x08 -#define AU1000_GPIO2_ST 0x0C -#define AU1000_GPIO2_INT 0x10 -#define AU1000_GPIO2_EN 0x14 +extern int au1xxx_gpio_get_value(unsigned gpio); +extern void au1xxx_gpio_set_value(unsigned gpio, int value); +extern int au1xxx_gpio_direction_input(unsigned gpio); +extern int au1xxx_gpio_direction_output(unsigned gpio, int value); -#define GPIO2_OUT_EN_MASK 0x00010000 -#define gpio_to_irq(gpio) NULL +/* Wrappers for the arch-neutral GPIO API */ -#define gpio_get_value __gpio_get_value -#define gpio_set_value __gpio_set_value +static inline int gpio_request(unsigned gpio, const char *label) +{ + /* Not yet implemented */ + return 0; +} -#define gpio_cansleep __gpio_cansleep +static inline void gpio_free(unsigned gpio) +{ + /* Not yet implemented */ +} +static inline int gpio_direction_input(unsigned gpio) +{ + return au1xxx_gpio_direction_input(gpio); +} + +static inline int gpio_direction_output(unsigned gpio, int value) +{ + return au1xxx_gpio_direction_output(gpio, value); +} + +static inline int gpio_get_value(unsigned gpio) +{ + return au1xxx_gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + au1xxx_gpio_set_value(gpio, value); +} + +static inline int gpio_to_irq(unsigned gpio) +{ + return gpio; +} + +static inline int irq_to_gpio(unsigned irq) +{ + return irq; +} + +/* For cansleep */ #include #endif /* _AU1XXX_GPIO_H_ */ diff --git a/trunk/arch/mips/include/asm/mach-bcm47xx/gpio.h b/trunk/arch/mips/include/asm/mach-bcm47xx/gpio.h index 1784fde2e28f..d8ff4cd89ab5 100644 --- a/trunk/arch/mips/include/asm/mach-bcm47xx/gpio.h +++ b/trunk/arch/mips/include/asm/mach-bcm47xx/gpio.h @@ -31,28 +31,24 @@ static inline void gpio_set_value(unsigned gpio, int value) static inline int gpio_direction_input(unsigned gpio) { - ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0); - return 0; + return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0); } static inline int gpio_direction_output(unsigned gpio, int value) { - ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio); - return 0; + return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio); } -static inline int gpio_intmask(unsigned gpio, int value) +static int gpio_intmask(unsigned gpio, int value) { - ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio, - value ? 1 << gpio : 0); - return 0; + return ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio, + value ? 1 << gpio : 0); } -static inline int gpio_polarity(unsigned gpio, int value) +static int gpio_polarity(unsigned gpio, int value) { - ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio, - value ? 1 << gpio : 0); - return 0; + return ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio, + value ? 1 << gpio : 0); } diff --git a/trunk/arch/mips/include/asm/mach-ip27/topology.h b/trunk/arch/mips/include/asm/mach-ip27/topology.h index 07547231e078..55d481569a1f 100644 --- a/trunk/arch/mips/include/asm/mach-ip27/topology.h +++ b/trunk/arch/mips/include/asm/mach-ip27/topology.h @@ -26,6 +26,7 @@ extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS]; #define parent_node(node) (node) #define node_to_cpumask(node) (hub_data(node)->h_cpus) #define cpumask_of_node(node) (&hub_data(node)->h_cpus) +#define node_to_first_cpu(node) (cpumask_first(cpumask_of_node(node))) struct pci_bus; extern int pcibus_to_node(struct pci_bus *); diff --git a/trunk/arch/mips/include/asm/mips-boards/generic.h b/trunk/arch/mips/include/asm/mips-boards/generic.h index c0da1a881e3d..7f0b034dd9a5 100644 --- a/trunk/arch/mips/include/asm/mips-boards/generic.h +++ b/trunk/arch/mips/include/asm/mips-boards/generic.h @@ -71,6 +71,8 @@ #define MIPS_REVISION_CORID (((*(volatile u32 *)ioremap(MIPS_REVISION_REG, 4)) >> 10) & 0x3f) +extern int mips_revision_corid; + #define MIPS_REVISION_SCON_OTHER 0 #define MIPS_REVISION_SCON_SOCITSC 1 #define MIPS_REVISION_SCON_SOCITSCP 2 diff --git a/trunk/arch/mips/include/asm/smp-ops.h b/trunk/arch/mips/include/asm/smp-ops.h index 64ffc0290b84..43c207e72a63 100644 --- a/trunk/arch/mips/include/asm/smp-ops.h +++ b/trunk/arch/mips/include/asm/smp-ops.h @@ -15,8 +15,6 @@ #include -struct task_struct; - struct plat_smp_ops { void (*send_ipi_single)(int cpu, unsigned int action); void (*send_ipi_mask)(cpumask_t mask, unsigned int action); diff --git a/trunk/arch/mips/include/asm/spinlock.h b/trunk/arch/mips/include/asm/spinlock.h index 5b60a09a0f08..0884947ebe27 100644 --- a/trunk/arch/mips/include/asm/spinlock.h +++ b/trunk/arch/mips/include/asm/spinlock.h @@ -76,7 +76,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) "2: \n" " .subsection 2 \n" "4: andi %[ticket], %[ticket], 0x1fff \n" - " sll %[ticket], 5 \n" + "5: sll %[ticket], 5 \n" " \n" "6: bnez %[ticket], 6b \n" " subu %[ticket], 1 \n" @@ -85,7 +85,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) " andi %[ticket], %[ticket], 0x1fff \n" " beq %[ticket], %[my_ticket], 2b \n" " subu %[ticket], %[my_ticket], %[ticket] \n" - " b 4b \n" + " b 5b \n" " subu %[ticket], %[ticket], 1 \n" " .previous \n" " .set pop \n" @@ -113,7 +113,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) " ll %[ticket], %[ticket_ptr] \n" " \n" "4: andi %[ticket], %[ticket], 0x1fff \n" - " sll %[ticket], 5 \n" + "5: sll %[ticket], 5 \n" " \n" "6: bnez %[ticket], 6b \n" " subu %[ticket], 1 \n" @@ -122,7 +122,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) " andi %[ticket], %[ticket], 0x1fff \n" " beq %[ticket], %[my_ticket], 2b \n" " subu %[ticket], %[my_ticket], %[ticket] \n" - " b 4b \n" + " b 5b \n" " subu %[ticket], %[ticket], 1 \n" " .previous \n" " .set pop \n" @@ -480,8 +480,6 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) return ret; } -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) #define _raw_spin_relax(lock) cpu_relax() #define _raw_read_relax(lock) cpu_relax() diff --git a/trunk/arch/mips/include/asm/types.h b/trunk/arch/mips/include/asm/types.h index 7956e69a3bd5..bcbb8d675af5 100644 --- a/trunk/arch/mips/include/asm/types.h +++ b/trunk/arch/mips/include/asm/types.h @@ -4,18 +4,12 @@ * for more details. * * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle - * Copyright (C) 2008 Wind River Systems, - * written by Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. */ #ifndef _ASM_TYPES_H #define _ASM_TYPES_H -/* - * We don't use int-l64.h for the kernel anymore but still use it for - * userspace to avoid code changes. - */ -#if (_MIPS_SZLONG == 64) && !defined(__KERNEL__) +#if _MIPS_SZLONG == 64 # include #else # include diff --git a/trunk/arch/mips/include/asm/unistd.h b/trunk/arch/mips/include/asm/unistd.h index 40005010827c..a73e1531e151 100644 --- a/trunk/arch/mips/include/asm/unistd.h +++ b/trunk/arch/mips/include/asm/unistd.h @@ -350,18 +350,16 @@ #define __NR_dup3 (__NR_Linux + 327) #define __NR_pipe2 (__NR_Linux + 328) #define __NR_inotify_init1 (__NR_Linux + 329) -#define __NR_preadv (__NR_Linux + 330) -#define __NR_pwritev (__NR_Linux + 331) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 331 +#define __NR_Linux_syscalls 329 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 331 +#define __NR_O32_Linux_syscalls 329 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -658,18 +656,16 @@ #define __NR_dup3 (__NR_Linux + 286) #define __NR_pipe2 (__NR_Linux + 287) #define __NR_inotify_init1 (__NR_Linux + 288) -#define __NR_preadv (__NR_Linux + 289) -#define __NR_pwritev (__NR_Linux + 290) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 290 +#define __NR_Linux_syscalls 288 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 290 +#define __NR_64_Linux_syscalls 288 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -970,18 +966,16 @@ #define __NR_dup3 (__NR_Linux + 290) #define __NR_pipe2 (__NR_Linux + 291) #define __NR_inotify_init1 (__NR_Linux + 292) -#define __NR_preadv (__NR_Linux + 293) -#define __NR_pwritev (__NR_Linux + 294) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 294 +#define __NR_Linux_syscalls 292 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 294 +#define __NR_N32_Linux_syscalls 292 #ifdef __KERNEL__ diff --git a/trunk/arch/mips/jazz/irq.c b/trunk/arch/mips/jazz/irq.c index d9b6a5b5399d..03965cb1b252 100644 --- a/trunk/arch/mips/jazz/irq.c +++ b/trunk/arch/mips/jazz/irq.c @@ -134,6 +134,7 @@ static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id) static struct irqaction r4030_timer_irqaction = { .handler = r4030_timer_interrupt, .flags = IRQF_DISABLED, + .mask = CPU_MASK_CPU0, .name = "R4030 timer", }; diff --git a/trunk/arch/mips/jazz/jazzdma.c b/trunk/arch/mips/jazz/jazzdma.c index f0fd636723be..c672c08d49e5 100644 --- a/trunk/arch/mips/jazz/jazzdma.c +++ b/trunk/arch/mips/jazz/jazzdma.c @@ -68,7 +68,8 @@ static int __init vdma_init(void) */ pgtbl = (VDMA_PGTBL_ENTRY *)__get_free_pages(GFP_KERNEL | GFP_DMA, get_order(VDMA_PGTBL_SIZE)); - BUG_ON(!pgtbl); + if (!pgtbl) + BUG(); dma_cache_wback_inv((unsigned long)pgtbl, VDMA_PGTBL_SIZE); pgtbl = (VDMA_PGTBL_ENTRY *)KSEG1ADDR(pgtbl); diff --git a/trunk/arch/mips/kernel/cevt-bcm1480.c b/trunk/arch/mips/kernel/cevt-bcm1480.c index a5182a207696..b820661678b0 100644 --- a/trunk/arch/mips/kernel/cevt-bcm1480.c +++ b/trunk/arch/mips/kernel/cevt-bcm1480.c @@ -144,6 +144,7 @@ void __cpuinit sb1480_clockevent_init(void) action->handler = sibyte_counter_handler; action->flags = IRQF_DISABLED | IRQF_PERCPU; + action->mask = cpumask_of_cpu(cpu); action->name = name; action->dev_id = cd; diff --git a/trunk/arch/mips/kernel/cevt-sb1250.c b/trunk/arch/mips/kernel/cevt-sb1250.c index 340f53e5c6b1..a2eebaafda52 100644 --- a/trunk/arch/mips/kernel/cevt-sb1250.c +++ b/trunk/arch/mips/kernel/cevt-sb1250.c @@ -143,6 +143,7 @@ void __cpuinit sb1250_clockevent_init(void) action->handler = sibyte_counter_handler; action->flags = IRQF_DISABLED | IRQF_PERCPU; + action->mask = cpumask_of_cpu(cpu); action->name = name; action->dev_id = cd; diff --git a/trunk/arch/mips/kernel/cpu-probe.c b/trunk/arch/mips/kernel/cpu-probe.c index b13b8eb30596..1bdbcad3bb74 100644 --- a/trunk/arch/mips/kernel/cpu-probe.c +++ b/trunk/arch/mips/kernel/cpu-probe.c @@ -183,7 +183,13 @@ void __init check_wait(void) case CPU_TX49XX: cpu_wait = r4k_wait_irqoff; break; - case CPU_ALCHEMY: + case CPU_AU1000: + case CPU_AU1100: + case CPU_AU1500: + case CPU_AU1550: + case CPU_AU1200: + case CPU_AU1210: + case CPU_AU1250: cpu_wait = au1k_wait; break; case CPU_20KC: @@ -777,30 +783,37 @@ static inline void cpu_probe_alchemy(struct cpuinfo_mips *c, unsigned int cpu) switch (c->processor_id & 0xff00) { case PRID_IMP_AU1_REV1: case PRID_IMP_AU1_REV2: - c->cputype = CPU_ALCHEMY; switch ((c->processor_id >> 24) & 0xff) { case 0: + c->cputype = CPU_AU1000; __cpu_name[cpu] = "Au1000"; break; case 1: + c->cputype = CPU_AU1500; __cpu_name[cpu] = "Au1500"; break; case 2: + c->cputype = CPU_AU1100; __cpu_name[cpu] = "Au1100"; break; case 3: + c->cputype = CPU_AU1550; __cpu_name[cpu] = "Au1550"; break; case 4: + c->cputype = CPU_AU1200; __cpu_name[cpu] = "Au1200"; - if ((c->processor_id & 0xff) == 2) + if ((c->processor_id & 0xff) == 2) { + c->cputype = CPU_AU1250; __cpu_name[cpu] = "Au1250"; + } break; case 5: + c->cputype = CPU_AU1210; __cpu_name[cpu] = "Au1210"; break; default: - __cpu_name[cpu] = "Au1xxx"; + panic("Unknown Au Core!"); break; } break; diff --git a/trunk/arch/mips/kernel/i8253.c b/trunk/arch/mips/kernel/i8253.c index 689719e34f08..f4d187825f96 100644 --- a/trunk/arch/mips/kernel/i8253.c +++ b/trunk/arch/mips/kernel/i8253.c @@ -98,6 +98,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) static struct irqaction irq0 = { .handler = timer_interrupt, .flags = IRQF_DISABLED | IRQF_NOBALANCING, + .mask = CPU_MASK_NONE, .name = "timer" }; @@ -120,6 +121,7 @@ void __init setup_pit_timer(void) cd->min_delta_ns = clockevent_delta2ns(0xF, cd); clockevents_register_device(cd); + irq0.mask = cpumask_of_cpu(cpu); setup_irq(0, &irq0); } diff --git a/trunk/arch/mips/kernel/i8259.c b/trunk/arch/mips/kernel/i8259.c index 01c0885a8061..413bd1d37f54 100644 --- a/trunk/arch/mips/kernel/i8259.c +++ b/trunk/arch/mips/kernel/i8259.c @@ -306,6 +306,7 @@ static void init_8259A(int auto_eoi) */ static struct irqaction irq2 = { .handler = no_action, + .mask = CPU_MASK_NONE, .name = "cascade", }; diff --git a/trunk/arch/mips/kernel/irq-msc01.c b/trunk/arch/mips/kernel/irq-msc01.c index 6a8cd28133d5..963c16d266ab 100644 --- a/trunk/arch/mips/kernel/irq-msc01.c +++ b/trunk/arch/mips/kernel/irq-msc01.c @@ -140,16 +140,14 @@ void __init init_msc_irqs(unsigned long icubase, unsigned int irqbase, msc_irqma switch (imp->im_type) { case MSC01_IRQ_EDGE: - set_irq_chip_and_handler_name(irqbase + n, - &msc_edgeirq_type, handle_edge_irq, "edge"); + set_irq_chip(irqbase+n, &msc_edgeirq_type); if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT); else MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl); break; case MSC01_IRQ_LEVEL: - set_irq_chip_and_handler_name(irqbase+n, - &msc_levelirq_type, handle_level_irq, "level"); + set_irq_chip(irqbase+n, &msc_levelirq_type); if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, 0); else diff --git a/trunk/arch/mips/kernel/irq_cpu.c b/trunk/arch/mips/kernel/irq_cpu.c index 55c8a3ca507b..0ee2567b780d 100644 --- a/trunk/arch/mips/kernel/irq_cpu.c +++ b/trunk/arch/mips/kernel/irq_cpu.c @@ -112,8 +112,7 @@ void __init mips_cpu_irq_init(void) */ if (cpu_has_mipsmt) for (i = irq_base; i < irq_base + 2; i++) - set_irq_chip_and_handler(i, &mips_mt_cpu_irq_controller, - handle_percpu_irq); + set_irq_chip(i, &mips_mt_cpu_irq_controller); for (i = irq_base + 2; i < irq_base + 8; i++) set_irq_chip_and_handler(i, &mips_cpu_irq_controller, diff --git a/trunk/arch/mips/kernel/linux32.c b/trunk/arch/mips/kernel/linux32.c index 6242bc68add7..2a472713de8e 100644 --- a/trunk/arch/mips/kernel/linux32.c +++ b/trunk/arch/mips/kernel/linux32.c @@ -133,9 +133,9 @@ SYSCALL_DEFINE4(32_ftruncate64, unsigned long, fd, unsigned long, __dummy, return sys_ftruncate(fd, merge_64(a2, a3)); } -SYSCALL_DEFINE5(32_llseek, unsigned int, fd, unsigned int, offset_high, - unsigned int, offset_low, loff_t __user *, result, - unsigned int, origin) +SYSCALL_DEFINE5(32_llseek, unsigned long, fd, unsigned long, offset_high, + unsigned long, offset_low, loff_t __user *, result, + unsigned long, origin) { return sys_llseek(fd, offset_high, offset_low, result, origin); } diff --git a/trunk/arch/mips/kernel/process.c b/trunk/arch/mips/kernel/process.c index 1eaaa450e20c..ca2e4026ad20 100644 --- a/trunk/arch/mips/kernel/process.c +++ b/trunk/arch/mips/kernel/process.c @@ -99,7 +99,7 @@ void flush_thread(void) { } -int copy_thread(unsigned long clone_flags, unsigned long usp, +int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { struct thread_info *ti = task_thread_info(p); diff --git a/trunk/arch/mips/kernel/scall32-o32.S b/trunk/arch/mips/kernel/scall32-o32.S index 0b31b9bda048..9ab70c3b5be6 100644 --- a/trunk/arch/mips/kernel/scall32-o32.S +++ b/trunk/arch/mips/kernel/scall32-o32.S @@ -650,8 +650,6 @@ einval: li v0, -ENOSYS sys sys_dup3 3 sys sys_pipe2 2 sys sys_inotify_init1 1 - sys sys_preadv 6 /* 4330 */ - sys sys_pwritev 6 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/trunk/arch/mips/kernel/scall64-64.S b/trunk/arch/mips/kernel/scall64-64.S index c647fd6e722f..9b4698667154 100644 --- a/trunk/arch/mips/kernel/scall64-64.S +++ b/trunk/arch/mips/kernel/scall64-64.S @@ -487,6 +487,4 @@ sys_call_table: PTR sys_dup3 PTR sys_pipe2 PTR sys_inotify_init1 - PTR sys_preadv - PTR sys_pwritev /* 5390 */ .size sys_call_table,.-sys_call_table diff --git a/trunk/arch/mips/kernel/scall64-n32.S b/trunk/arch/mips/kernel/scall64-n32.S index c2c16ef9218f..f61d6b0e5731 100644 --- a/trunk/arch/mips/kernel/scall64-n32.S +++ b/trunk/arch/mips/kernel/scall64-n32.S @@ -413,6 +413,4 @@ EXPORT(sysn32_call_table) PTR sys_dup3 /* 5290 */ PTR sys_pipe2 PTR sys_inotify_init1 - PTR sys_preadv - PTR sys_pwritev .size sysn32_call_table,.-sysn32_call_table diff --git a/trunk/arch/mips/kernel/scall64-o32.S b/trunk/arch/mips/kernel/scall64-o32.S index 002fac27021e..60997f1f69d4 100644 --- a/trunk/arch/mips/kernel/scall64-o32.S +++ b/trunk/arch/mips/kernel/scall64-o32.S @@ -533,6 +533,4 @@ sys_call_table: PTR sys_dup3 PTR sys_pipe2 PTR sys_inotify_init1 - PTR compat_sys_preadv /* 4330 */ - PTR compat_sys_pwritev .size sys_call_table,.-sys_call_table diff --git a/trunk/arch/mips/kernel/setup.c b/trunk/arch/mips/kernel/setup.c index 2950b97253b7..4430a1f8fdf1 100644 --- a/trunk/arch/mips/kernel/setup.c +++ b/trunk/arch/mips/kernel/setup.c @@ -277,8 +277,7 @@ static void __init bootmem_init(void) * not selected. Once that done we can determine the low bound * of usable memory. */ - reserved_end = max(init_initrd(), - (unsigned long) PFN_UP(__pa_symbol(&_end))); + reserved_end = max(init_initrd(), PFN_UP(__pa_symbol(&_end))); /* * max_low_pfn is not a number of pages. The number of pages diff --git a/trunk/arch/mips/kernel/smp-up.c b/trunk/arch/mips/kernel/smp-up.c index 878e3733bbb2..ead6c30eeb14 100644 --- a/trunk/arch/mips/kernel/smp-up.c +++ b/trunk/arch/mips/kernel/smp-up.c @@ -13,7 +13,7 @@ /* * Send inter-processor interrupt */ -static void up_send_ipi_single(int cpu, unsigned int action) +void up_send_ipi_single(int cpu, unsigned int action) { panic(KERN_ERR "%s called", __func__); } @@ -27,31 +27,31 @@ static inline void up_send_ipi_mask(cpumask_t mask, unsigned int action) * After we've done initial boot, this function is called to allow the * board code to clean up state, if needed */ -static void __cpuinit up_init_secondary(void) +void __cpuinit up_init_secondary(void) { } -static void __cpuinit up_smp_finish(void) +void __cpuinit up_smp_finish(void) { } /* Hook for after all CPUs are online */ -static void up_cpus_done(void) +void up_cpus_done(void) { } /* * Firmware CPU startup hook */ -static void __cpuinit up_boot_secondary(int cpu, struct task_struct *idle) +void __cpuinit up_boot_secondary(int cpu, struct task_struct *idle) { } -static void __init up_smp_setup(void) +void __init up_smp_setup(void) { } -static void __init up_prepare_cpus(unsigned int max_cpus) +void __init up_prepare_cpus(unsigned int max_cpus) { } diff --git a/trunk/arch/mips/kernel/smp.c b/trunk/arch/mips/kernel/smp.c index c937506a03aa..3da94704f816 100644 --- a/trunk/arch/mips/kernel/smp.c +++ b/trunk/arch/mips/kernel/smp.c @@ -44,7 +44,7 @@ #include #endif /* CONFIG_MIPS_MT_SMTC */ -static volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ +volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */ diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index e83da174b533..29fadaccecdd 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -1277,7 +1277,8 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) u32 *w; unsigned char *b; - BUG_ON(!cpu_has_veic && !cpu_has_vint); + if (!cpu_has_veic && !cpu_has_vint) + BUG(); if (addr == NULL) { handler = (unsigned long) do_default_vi; diff --git a/trunk/arch/mips/lasat/interrupt.c b/trunk/arch/mips/lasat/interrupt.c index 1353fb135ed3..d1ac7a25c856 100644 --- a/trunk/arch/mips/lasat/interrupt.c +++ b/trunk/arch/mips/lasat/interrupt.c @@ -104,6 +104,7 @@ asmlinkage void plat_irq_dispatch(void) static struct irqaction cascade = { .handler = no_action, + .mask = CPU_MASK_NONE, .name = "cascade", }; diff --git a/trunk/arch/mips/lemote/lm2e/irq.c b/trunk/arch/mips/lemote/lm2e/irq.c index 1d0a09f3b832..3e0b7beb1009 100644 --- a/trunk/arch/mips/lemote/lm2e/irq.c +++ b/trunk/arch/mips/lemote/lm2e/irq.c @@ -92,6 +92,7 @@ asmlinkage void plat_irq_dispatch(void) static struct irqaction cascade_irqaction = { .handler = no_action, + .mask = CPU_MASK_NONE, .name = "cascade", }; diff --git a/trunk/arch/mips/mm/c-r4k.c b/trunk/arch/mips/mm/c-r4k.c index 58d9075e86fe..871e828bc62a 100644 --- a/trunk/arch/mips/mm/c-r4k.c +++ b/trunk/arch/mips/mm/c-r4k.c @@ -1026,7 +1026,13 @@ static void __cpuinit probe_pcache(void) c->icache.flags |= MIPS_CACHE_VTAG; break; - case CPU_ALCHEMY: + case CPU_AU1000: + case CPU_AU1500: + case CPU_AU1100: + case CPU_AU1550: + case CPU_AU1200: + case CPU_AU1210: + case CPU_AU1250: c->icache.flags |= MIPS_CACHE_IC_F_DC; break; } @@ -1238,7 +1244,7 @@ void au1x00_fixup_config_od(void) /* * Au1100 errata actually keeps silence about this bit, so we set it * just in case for those revisions that require it to be set according - * to the (now gone) cpu table. + * to arch/mips/au1000/common/cputable.c */ case 0x02030200: /* Au1100 AB */ case 0x02030201: /* Au1100 BA */ @@ -1308,10 +1314,11 @@ static void __cpuinit coherency_setup(void) break; /* * We need to catch the early Alchemy SOCs with - * the write-only co_config.od bit and set it back to one on: - * Au1000 rev DA, HA, HB; Au1100 AB, BA, BC, Au1500 AB + * the write-only co_config.od bit and set it back to one... */ - case CPU_ALCHEMY: + case CPU_AU1000: /* rev. DA, HA, HB */ + case CPU_AU1100: /* rev. AB, BA, BC ?? */ + case CPU_AU1500: /* rev. AB */ au1x00_fixup_config_od(); break; diff --git a/trunk/arch/mips/mm/highmem.c b/trunk/arch/mips/mm/highmem.c index 4481656d1065..8f2cd8eda741 100644 --- a/trunk/arch/mips/mm/highmem.c +++ b/trunk/arch/mips/mm/highmem.c @@ -17,7 +17,8 @@ void *__kmap(struct page *page) void __kunmap(struct page *page) { - BUG_ON(in_interrupt()); + if (in_interrupt()) + BUG(); if (!PageHighMem(page)) return; kunmap_high(page); @@ -42,11 +43,11 @@ void *__kmap_atomic(struct page *page, enum km_type type) if (!PageHighMem(page)) return page_address(page); - debug_kmap_atomic(type); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); #ifdef CONFIG_DEBUG_HIGHMEM - BUG_ON(!pte_none(*(kmap_pte - idx))); + if (!pte_none(*(kmap_pte-idx))) + BUG(); #endif set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); local_flush_tlb_one((unsigned long)vaddr); @@ -65,7 +66,8 @@ void __kunmap_atomic(void *kvaddr, enum km_type type) return; } - BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); + if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx)) + BUG(); /* * force other mappings to Oops if they'll try to access @@ -89,7 +91,6 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) pagefault_disable(); - debug_kmap_atomic(type); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot)); diff --git a/trunk/arch/mips/mm/init.c b/trunk/arch/mips/mm/init.c index d9348946a19e..137c14bafd6b 100644 --- a/trunk/arch/mips/mm/init.c +++ b/trunk/arch/mips/mm/init.c @@ -307,7 +307,8 @@ void __init fixrange_init(unsigned long start, unsigned long end, if (pmd_none(*pmd)) { pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); set_pmd(pmd, __pmd((unsigned long)pte)); - BUG_ON(pte != pte_offset_kernel(pmd, 0)); + if (pte != pte_offset_kernel(pmd, 0)) + BUG(); } vaddr += PMD_SIZE; } diff --git a/trunk/arch/mips/mm/ioremap.c b/trunk/arch/mips/mm/ioremap.c index 0c43248347bd..59945b9ee23c 100644 --- a/trunk/arch/mips/mm/ioremap.c +++ b/trunk/arch/mips/mm/ioremap.c @@ -27,7 +27,8 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address, end = address + size; if (end > PMD_SIZE) end = PMD_SIZE; - BUG_ON(address >= end); + if (address >= end) + BUG(); pfn = phys_addr >> PAGE_SHIFT; do { if (!pte_none(*pte)) { @@ -51,7 +52,8 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, if (end > PGDIR_SIZE) end = PGDIR_SIZE; phys_addr -= address; - BUG_ON(address >= end); + if (address >= end) + BUG(); do { pte_t * pte = pte_alloc_kernel(pmd, address); if (!pte) @@ -73,7 +75,8 @@ static int remap_area_pages(unsigned long address, phys_t phys_addr, phys_addr -= address; dir = pgd_offset(&init_mm, address); flush_cache_all(); - BUG_ON(address >= end); + if (address >= end) + BUG(); do { pud_t *pud; pmd_t *pmd; diff --git a/trunk/arch/mips/mm/tlbex.c b/trunk/arch/mips/mm/tlbex.c index 0615b62efd6d..f335cf6cdd78 100644 --- a/trunk/arch/mips/mm/tlbex.c +++ b/trunk/arch/mips/mm/tlbex.c @@ -292,6 +292,13 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l, case CPU_R4300: case CPU_5KC: case CPU_TX49XX: + case CPU_AU1000: + case CPU_AU1100: + case CPU_AU1500: + case CPU_AU1550: + case CPU_AU1200: + case CPU_AU1210: + case CPU_AU1250: case CPU_PR4450: uasm_i_nop(p); tlbw(p); @@ -314,7 +321,6 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l, case CPU_R5500: if (m4kc_tlbp_war()) uasm_i_nop(p); - case CPU_ALCHEMY: tlbw(p); break; diff --git a/trunk/arch/mips/mti-malta/malta-init.c b/trunk/arch/mips/mti-malta/malta-init.c index 475038a141a6..4832af251668 100644 --- a/trunk/arch/mips/mti-malta/malta-init.c +++ b/trunk/arch/mips/mti-malta/malta-init.c @@ -48,7 +48,7 @@ int *_prom_argv, *_prom_envp; int init_debug = 0; -static int mips_revision_corid; +int mips_revision_corid; int mips_revision_sconid; /* Bonito64 system controller register base. */ diff --git a/trunk/arch/mips/sgi-ip27/ip27-berr.c b/trunk/arch/mips/sgi-ip27/ip27-berr.c index 04cebadc2b3c..7d05e68fdc77 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-berr.c +++ b/trunk/arch/mips/sgi-ip27/ip27-berr.c @@ -66,7 +66,7 @@ int ip27_be_handler(struct pt_regs *regs, int is_fixup) printk("Slice %c got %cbe at 0x%lx\n", 'A' + cpu, data ? 'd' : 'i', regs->cp0_epc); printk("Hub information:\n"); - printk("ERR_INT_PEND = 0x%06llx\n", LOCAL_HUB_L(PI_ERR_INT_PEND)); + printk("ERR_INT_PEND = 0x%06lx\n", LOCAL_HUB_L(PI_ERR_INT_PEND)); errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A); errst1 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS1_B : PI_ERR_STATUS1_A); dump_hub_information(errst0, errst1); diff --git a/trunk/arch/mips/sgi-ip27/ip27-nmi.c b/trunk/arch/mips/sgi-ip27/ip27-nmi.c index 6c5a630566f9..64459e7d891b 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-nmi.c +++ b/trunk/arch/mips/sgi-ip27/ip27-nmi.c @@ -143,8 +143,8 @@ void nmi_dump_hub_irq(nasid_t nasid, int slice) pend0 = REMOTE_HUB_L(nasid, PI_INT_PEND0); pend1 = REMOTE_HUB_L(nasid, PI_INT_PEND1); - printk("PI_INT_MASK0: %16Lx PI_INT_MASK1: %16Lx\n", mask0, mask1); - printk("PI_INT_PEND0: %16Lx PI_INT_PEND1: %16Lx\n", pend0, pend1); + printk("PI_INT_MASK0: %16lx PI_INT_MASK1: %16lx\n", mask0, mask1); + printk("PI_INT_PEND0: %16lx PI_INT_PEND1: %16lx\n", pend0, pend1); printk("\n\n"); } @@ -219,7 +219,7 @@ cont_nmi_dump(void) if (i == 1000) { for_each_online_node(node) if (NODEPDA(node)->dump_count == 0) { - cpu = cpumask_first(cpumask_of_node(node)); + cpu = node_to_first_cpu(node); for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) { CPUMASK_SETB(nmied_cpus, cpu); /* diff --git a/trunk/arch/mips/sgi-ip32/ip32-irq.c b/trunk/arch/mips/sgi-ip32/ip32-irq.c index 83a0b3c359da..0d6b6663d5f6 100644 --- a/trunk/arch/mips/sgi-ip32/ip32-irq.c +++ b/trunk/arch/mips/sgi-ip32/ip32-irq.c @@ -115,12 +115,14 @@ extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id); struct irqaction memerr_irq = { .handler = crime_memerr_intr, .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, .name = "CRIME memory error", }; struct irqaction cpuerr_irq = { .handler = crime_cpuerr_intr, .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, .name = "CRIME CPU error", }; @@ -323,11 +325,16 @@ static void mask_and_ack_maceisa_irq(unsigned int irq) { unsigned long mace_int; - /* edge triggered */ - mace_int = mace->perif.ctrl.istat; - mace_int &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ)); - mace->perif.ctrl.istat = mace_int; - + switch (irq) { + case MACEISA_PARALLEL_IRQ: + case MACEISA_SERIAL1_TDMAPR_IRQ: + case MACEISA_SERIAL2_TDMAPR_IRQ: + /* edge triggered */ + mace_int = mace->perif.ctrl.istat; + mace_int &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ)); + mace->perif.ctrl.istat = mace_int; + break; + } disable_maceisa_irq(irq); } @@ -337,16 +344,7 @@ static void end_maceisa_irq(unsigned irq) enable_maceisa_irq(irq); } -static struct irq_chip ip32_maceisa_level_interrupt = { - .name = "IP32 MACE ISA", - .ack = disable_maceisa_irq, - .mask = disable_maceisa_irq, - .mask_ack = disable_maceisa_irq, - .unmask = enable_maceisa_irq, - .end = end_maceisa_irq, -}; - -static struct irq_chip ip32_maceisa_edge_interrupt = { +static struct irq_chip ip32_maceisa_interrupt = { .name = "IP32 MACE ISA", .ack = mask_and_ack_maceisa_irq, .mask = disable_maceisa_irq, @@ -502,50 +500,27 @@ void __init arch_init_irq(void) for (irq = CRIME_IRQ_BASE; irq <= IP32_IRQ_MAX; irq++) { switch (irq) { case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ: - set_irq_chip_and_handler_name(irq,&ip32_mace_interrupt, - handle_level_irq, "level"); + set_irq_chip(irq, &ip32_mace_interrupt); break; - case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ: - set_irq_chip_and_handler_name(irq, - &ip32_macepci_interrupt, handle_level_irq, - "level"); + set_irq_chip(irq, &ip32_macepci_interrupt); break; - case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ: - set_irq_chip_and_handler_name(irq, - &crime_edge_interrupt, handle_edge_irq, "edge"); + set_irq_chip(irq, &crime_edge_interrupt); break; case CRIME_CPUERR_IRQ: case CRIME_MEMERR_IRQ: - set_irq_chip_and_handler_name(irq, - &crime_level_interrupt, handle_level_irq, - "level"); + set_irq_chip(irq, &crime_level_interrupt); break; - case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ: case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ: - set_irq_chip_and_handler_name(irq, - &crime_edge_interrupt, handle_edge_irq, "edge"); + set_irq_chip(irq, &crime_edge_interrupt); break; - case CRIME_VICE_IRQ: - set_irq_chip_and_handler_name(irq, - &crime_edge_interrupt, handle_edge_irq, "edge"); - break; - - case MACEISA_PARALLEL_IRQ: - case MACEISA_SERIAL1_TDMAPR_IRQ: - case MACEISA_SERIAL2_TDMAPR_IRQ: - set_irq_chip_and_handler_name(irq, - &ip32_maceisa_edge_interrupt, handle_edge_irq, - "edge"); + set_irq_chip(irq, &crime_edge_interrupt); break; - default: - set_irq_chip_and_handler_name(irq, - &ip32_maceisa_level_interrupt, handle_level_irq, - "level"); + set_irq_chip(irq, &ip32_maceisa_interrupt); break; } } diff --git a/trunk/arch/mips/sgi-ip32/ip32-memory.c b/trunk/arch/mips/sgi-ip32/ip32-memory.c index 828ce131c228..ca93ecf825ae 100644 --- a/trunk/arch/mips/sgi-ip32/ip32-memory.c +++ b/trunk/arch/mips/sgi-ip32/ip32-memory.c @@ -36,7 +36,7 @@ void __init prom_meminit(void) if (base + size > (256 << 20)) base += CRIME_HI_MEM_BASE; - printk("CRIME MC: bank %u base 0x%016Lx size %LuMiB\n", + printk("CRIME MC: bank %u base 0x%016lx size %luMiB\n", bank, base, size >> 20); add_memory_region(base, size, BOOT_MEM_RAM); } diff --git a/trunk/arch/mips/sibyte/bcm1480/irq.c b/trunk/arch/mips/sibyte/bcm1480/irq.c index 352352b3cb2f..12b465d404df 100644 --- a/trunk/arch/mips/sibyte/bcm1480/irq.c +++ b/trunk/arch/mips/sibyte/bcm1480/irq.c @@ -236,7 +236,7 @@ void __init init_bcm1480_irqs(void) int i; for (i = 0; i < BCM1480_NR_IRQS; i++) { - set_irq_chip_and_handler(i, &bcm1480_irq_type, handle_level_irq); + set_irq_chip(i, &bcm1480_irq_type); bcm1480_irq_owner[i] = 0; } } diff --git a/trunk/arch/mips/sibyte/sb1250/irq.c b/trunk/arch/mips/sibyte/sb1250/irq.c index c08ff582da6f..808ac2959b8c 100644 --- a/trunk/arch/mips/sibyte/sb1250/irq.c +++ b/trunk/arch/mips/sibyte/sb1250/irq.c @@ -220,7 +220,7 @@ void __init init_sb1250_irqs(void) int i; for (i = 0; i < SB1250_NR_IRQS; i++) { - set_irq_chip_and_handler(i, &sb1250_irq_type, handle_level_irq); + set_irq_chip(i, &sb1250_irq_type); sb1250_irq_owner[i] = 0; } } diff --git a/trunk/arch/mips/sni/a20r.c b/trunk/arch/mips/sni/a20r.c index 7dd76fb3b645..3f8cf5eb2f06 100644 --- a/trunk/arch/mips/sni/a20r.c +++ b/trunk/arch/mips/sni/a20r.c @@ -219,7 +219,7 @@ void __init sni_a20r_irq_init(void) int i; for (i = SNI_A20R_IRQ_BASE + 2 ; i < SNI_A20R_IRQ_BASE + 8; i++) - set_irq_chip_and_handler(i, &a20r_irq_type, handle_level_irq); + set_irq_chip(i, &a20r_irq_type); sni_hwint = a20r_hwint; change_c0_status(ST0_IM, IE_IRQ0); setup_irq(SNI_A20R_IRQ_BASE + 3, &sni_isa_irq); diff --git a/trunk/arch/mips/sni/pcimt.c b/trunk/arch/mips/sni/pcimt.c index 74e6c67982fb..834650f371e0 100644 --- a/trunk/arch/mips/sni/pcimt.c +++ b/trunk/arch/mips/sni/pcimt.c @@ -304,7 +304,7 @@ void __init sni_pcimt_irq_init(void) mips_cpu_irq_init(); /* Actually we've got more interrupts to handle ... */ for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++) - set_irq_chip_and_handler(i, &pcimt_irq_type, handle_level_irq); + set_irq_chip(i, &pcimt_irq_type); sni_hwint = sni_pcimt_hwint; change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3); } diff --git a/trunk/arch/mips/sni/pcit.c b/trunk/arch/mips/sni/pcit.c index 071a9573ac7f..e5f12cf96e8e 100644 --- a/trunk/arch/mips/sni/pcit.c +++ b/trunk/arch/mips/sni/pcit.c @@ -246,7 +246,7 @@ void __init sni_pcit_irq_init(void) mips_cpu_irq_init(); for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++) - set_irq_chip_and_handler(i, &pcit_irq_type, handle_level_irq); + set_irq_chip(i, &pcit_irq_type); *(volatile u32 *)SNI_PCIT_INT_REG = 0; sni_hwint = sni_pcit_hwint; change_c0_status(ST0_IM, IE_IRQ1); @@ -259,7 +259,7 @@ void __init sni_pcit_cplus_irq_init(void) mips_cpu_irq_init(); for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++) - set_irq_chip_and_handler(i, &pcit_irq_type, handle_level_irq); + set_irq_chip(i, &pcit_irq_type); *(volatile u32 *)SNI_PCIT_INT_REG = 0x40000000; sni_hwint = sni_pcit_hwint_cplus; change_c0_status(ST0_IM, IE_IRQ0); diff --git a/trunk/arch/mips/sni/rm200.c b/trunk/arch/mips/sni/rm200.c index 5e687819cbc2..5310aa75afa4 100644 --- a/trunk/arch/mips/sni/rm200.c +++ b/trunk/arch/mips/sni/rm200.c @@ -359,8 +359,7 @@ void sni_rm200_init_8259A(void) * IRQ2 is cascade interrupt to second interrupt controller */ static struct irqaction sni_rm200_irq2 = { - .handler = no_action, - .name = "cascade", + no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; static struct resource sni_rm200_pic1_resource = { @@ -488,7 +487,7 @@ void __init sni_rm200_irq_init(void) mips_cpu_irq_init(); /* Actually we've got more interrupts to handle ... */ for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++) - set_irq_chip_and_handler(i, &rm200_irq_type, handle_level_irq); + set_irq_chip(i, &rm200_irq_type); sni_hwint = sni_rm200_hwint; change_c0_status(ST0_IM, IE_IRQ0); setup_irq(SNI_RM200_INT_START + 0, &sni_rm200_i8259A_irq); diff --git a/trunk/arch/mips/txx9/Kconfig b/trunk/arch/mips/txx9/Kconfig index 0db7cf38ed8b..226e8bb2f0a1 100644 --- a/trunk/arch/mips/txx9/Kconfig +++ b/trunk/arch/mips/txx9/Kconfig @@ -20,6 +20,7 @@ config MACH_TXX9 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_BIG_ENDIAN + select GENERIC_HARDIRQS_NO__DO_IRQ config TOSHIBA_JMR3927 bool "Toshiba JMR-TX3927 board" diff --git a/trunk/arch/mips/vr41xx/common/irq.c b/trunk/arch/mips/vr41xx/common/irq.c index 9cc389109b19..92dd1a0ca352 100644 --- a/trunk/arch/mips/vr41xx/common/irq.c +++ b/trunk/arch/mips/vr41xx/common/irq.c @@ -32,6 +32,7 @@ static irq_cascade_t irq_cascade[NR_IRQS] __cacheline_aligned; static struct irqaction cascade_irqaction = { .handler = no_action, + .mask = CPU_MASK_NONE, .name = "cascade", }; diff --git a/trunk/arch/mn10300/kernel/process.c b/trunk/arch/mn10300/kernel/process.c index 234cf344cdce..b28c9a60445b 100644 --- a/trunk/arch/mn10300/kernel/process.c +++ b/trunk/arch/mn10300/kernel/process.c @@ -193,7 +193,7 @@ void prepare_to_copy(struct task_struct *tsk) * set up the kernel stack for a new thread and copy arch-specific thread * control information */ -int copy_thread(unsigned long clone_flags, +int copy_thread(int nr, unsigned long clone_flags, unsigned long c_usp, unsigned long ustk_size, struct task_struct *p, struct pt_regs *kregs) { diff --git a/trunk/arch/mn10300/kernel/time.c b/trunk/arch/mn10300/kernel/time.c index 395caf01b909..e4606586f94c 100644 --- a/trunk/arch/mn10300/kernel/time.c +++ b/trunk/arch/mn10300/kernel/time.c @@ -37,6 +37,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id); static struct irqaction timer_irq = { .handler = timer_interrupt, .flags = IRQF_DISABLED | IRQF_SHARED | IRQF_TIMER, + .mask = CPU_MASK_NONE, .name = "timer", }; diff --git a/trunk/arch/parisc/include/asm/spinlock.h b/trunk/arch/parisc/include/asm/spinlock.h index fae03e136fa8..f3d2090a18dc 100644 --- a/trunk/arch/parisc/include/asm/spinlock.h +++ b/trunk/arch/parisc/include/asm/spinlock.h @@ -187,9 +187,6 @@ static __inline__ int __raw_write_can_lock(raw_rwlock_t *rw) return !rw->counter; } -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) - #define _raw_spin_relax(lock) cpu_relax() #define _raw_read_relax(lock) cpu_relax() #define _raw_write_relax(lock) cpu_relax() diff --git a/trunk/arch/parisc/kernel/process.c b/trunk/arch/parisc/kernel/process.c index 8aa591ed9127..b80e02a4d81d 100644 --- a/trunk/arch/parisc/kernel/process.c +++ b/trunk/arch/parisc/kernel/process.c @@ -263,7 +263,7 @@ sys_vfork(struct pt_regs *regs) } int -copy_thread(unsigned long clone_flags, unsigned long usp, +copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, /* in ia64 this is "user_stack_size" */ struct task_struct * p, struct pt_regs * pregs) { diff --git a/trunk/arch/parisc/kernel/time.c b/trunk/arch/parisc/kernel/time.c index e75cae6072c5..9d46c43a4152 100644 --- a/trunk/arch/parisc/kernel/time.c +++ b/trunk/arch/parisc/kernel/time.c @@ -216,14 +216,17 @@ void __init start_cpu_itimer(void) per_cpu(cpu_data, cpu).it_value = next_tick; } -static struct platform_device rtc_parisc_dev = { +struct platform_device rtc_parisc_dev = { .name = "rtc-parisc", .id = -1, }; static int __init rtc_init(void) { - if (platform_device_register(&rtc_parisc_dev) < 0) + int ret; + + ret = platform_device_register(&rtc_parisc_dev); + if (ret < 0) printk(KERN_ERR "unable to register rtc device...\n"); /* not necessarily an error */ diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 45192dce65c4..74cc312c347c 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -111,7 +111,6 @@ config PPC select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACER - select HAVE_FUNCTION_GRAPH_TRACER select ARCH_WANT_OPTIONAL_GPIOLIB select HAVE_IDE select HAVE_IOREMAP_PROT @@ -228,9 +227,6 @@ config PPC_OF_PLATFORM_PCI depends on PPC64 # not supported on 32 bits yet default n -config ARCH_SUPPORTS_DEBUG_PAGEALLOC - def_bool y - source "init/Kconfig" source "kernel/Kconfig.freezer" @@ -316,7 +312,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE config KEXEC bool "kexec system call (EXPERIMENTAL)" - depends on BOOK3S && EXPERIMENTAL + depends on (PPC_PRPMC2800 || PPC_MULTIPLATFORM) && EXPERIMENTAL help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot @@ -413,18 +409,6 @@ config PPC_HAS_HASH_64K depends on PPC64 default n -config STDBINUTILS - bool "Using standard binutils settings" - depends on 44x - default y - help - Turning this option off allows you to select 256KB PAGE_SIZE on 44x. - Note, that kernel will be able to run only those applications, - which had been compiled using binutils later than 2.17.50.0.3 with - '-zmax-page-size' set to 256K (the default is 64K). Or, if using - the older binutils, you can patch them with a trivial patch, which - changes the ELF_MAXPAGESIZE definition from 0x10000 to 0x40000. - choice prompt "Page size" default PPC_4K_PAGES @@ -460,19 +444,6 @@ config PPC_64K_PAGES bool "64k page size" if 44x || PPC_STD_MMU_64 select PPC_HAS_HASH_64K if PPC_STD_MMU_64 -config PPC_256K_PAGES - bool "256k page size" if 44x - depends on !STDBINUTILS && (!SHMEM || BROKEN) - help - Make the page size 256k. - - As the ELF standard only requires alignment to support page - sizes up to 64k, you will need to compile all of your user - space applications with a non-standard binutils settings - (see the STDBINUTILS description for details). - - Say N unless you know what you are doing. - endchoice config FORCE_MAX_ZONEORDER @@ -485,8 +456,6 @@ config FORCE_MAX_ZONEORDER default "9" if PPC_STD_MMU_32 && PPC_16K_PAGES range 7 64 if PPC_STD_MMU_32 && PPC_64K_PAGES default "7" if PPC_STD_MMU_32 && PPC_64K_PAGES - range 5 64 if PPC_STD_MMU_32 && PPC_256K_PAGES - default "5" if PPC_STD_MMU_32 && PPC_256K_PAGES range 11 64 default "11" help @@ -625,7 +594,6 @@ config FSL_SOC config FSL_PCI bool select PPC_INDIRECT_PCI - select PCI_QUIRKS config 4xx_SOC bool @@ -762,22 +730,6 @@ config LOWMEM_SIZE hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL default "0x30000000" -config LOWMEM_CAM_NUM_BOOL - bool "Set number of CAMs to use to map low memory" - depends on ADVANCED_OPTIONS && FSL_BOOKE - help - This option allows you to set the maximum number of CAM slots that - will be used to map low memory. There are a limited number of slots - available and even more limited number that will fit in the L1 MMU. - However, using more entries will allow mapping more low memory. This - can be useful in optimizing the layout of kernel virtual memory. - - Say N here unless you know what you are doing. - -config LOWMEM_CAM_NUM - int "Number of CAMs to use to map low memory" if LOWMEM_CAM_NUM_BOOL - default 3 - config RELOCATABLE bool "Build a relocatable kernel (EXPERIMENTAL)" depends on EXPERIMENTAL && ADVANCED_OPTIONS && FLATMEM && FSL_BOOKE @@ -842,7 +794,7 @@ config PHYSICAL_START config PHYSICAL_ALIGN hex - default "0x04000000" if FSL_BOOKE + default "0x10000000" if FSL_BOOKE help This value puts the alignment restrictions on physical address where kernel is loaded and run from. Kernel is compiled for an @@ -863,6 +815,31 @@ config TASK_SIZE default "0x80000000" if PPC_PREP || PPC_8xx default "0xc0000000" +config CONSISTENT_START_BOOL + bool "Set custom consistent memory pool address" + depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE + help + This option allows you to set the base virtual address + of the consistent memory pool. This pool of virtual + memory is used to make consistent memory allocations. + +config CONSISTENT_START + hex "Base virtual address of consistent memory pool" if CONSISTENT_START_BOOL + default "0xfd000000" if (NOT_COHERENT_CACHE && 8xx) + default "0xff100000" if NOT_COHERENT_CACHE + +config CONSISTENT_SIZE_BOOL + bool "Set custom consistent memory pool size" + depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE + help + This option allows you to set the size of the + consistent memory pool. This pool of virtual memory + is used to make consistent memory allocations. + +config CONSISTENT_SIZE + hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL + default "0x00200000" if NOT_COHERENT_CACHE + config PIN_TLB bool "Pinned Kernel TLBs (860 ONLY)" depends on ADVANCED_OPTIONS && 8xx diff --git a/trunk/arch/powerpc/Kconfig.debug b/trunk/arch/powerpc/Kconfig.debug index a1098e23221f..08f7cc0a1953 100644 --- a/trunk/arch/powerpc/Kconfig.debug +++ b/trunk/arch/powerpc/Kconfig.debug @@ -27,6 +27,15 @@ config DEBUG_STACK_USAGE This option will slow down process creation somewhat. +config DEBUG_PAGEALLOC + bool "Debug page memory allocations" + depends on DEBUG_KERNEL && !HIBERNATION + help + Unmap pages from the kernel linear mapping after free_pages(). + This results in a large slowdown, but helps to find certain types + of memory corruptions. + + config HCALL_STATS bool "Hypervisor call instrumentation" depends on PPC_PSERIES && DEBUG_FS @@ -120,7 +129,7 @@ config BDI_SWITCH config BOOTX_TEXT bool "Support for early boot text console (BootX or OpenFirmware only)" - depends on PPC_OF && PPC_BOOK3S + depends on PPC_OF && PPC_MULTIPLATFORM help Say Y here to see progress messages from the boot firmware in text mode. Requires either BootX or Open Firmware. diff --git a/trunk/arch/powerpc/Makefile b/trunk/arch/powerpc/Makefile index 551fc58c05cf..72d17f50e54f 100644 --- a/trunk/arch/powerpc/Makefile +++ b/trunk/arch/powerpc/Makefile @@ -147,8 +147,8 @@ core-y += arch/powerpc/kernel/ \ arch/powerpc/mm/ \ arch/powerpc/lib/ \ arch/powerpc/sysdev/ \ - arch/powerpc/platforms/ \ - arch/powerpc/math-emu/ + arch/powerpc/platforms/ +core-$(CONFIG_MATH_EMULATION) += arch/powerpc/math-emu/ core-$(CONFIG_XMON) += arch/powerpc/xmon/ core-$(CONFIG_KVM) += arch/powerpc/kvm/ diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index 4458abb67c51..e84df338ea29 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -70,7 +70,7 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \ cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \ virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \ - cuboot-acadia.c cuboot-amigaone.c + cuboot-acadia.c src-boot := $(src-wlib) $(src-plat) empty.c src-boot := $(addprefix $(obj)/, $(src-boot)) @@ -235,9 +235,7 @@ image-$(CONFIG_PPC_ADDER875) += cuImage.adder875-uboot \ dtbImage.adder875-redboot # Board ports in arch/powerpc/platform/52xx/Kconfig -image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200 lite5200.dtb -image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200b lite5200b.dtb -image-$(CONFIG_PPC_MEDIA5200) += cuImage.media5200 media5200.dtb +image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200 cuImage.lite5200b # Board ports in arch/powerpc/platform/82xx/Kconfig image-$(CONFIG_MPC8272_ADS) += cuImage.mpc8272ads @@ -276,9 +274,6 @@ image-$(CONFIG_STORCENTER) += cuImage.storcenter image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2 image-$(CONFIG_PPC_C2K) += cuImage.c2k -# Board port in arch/powerpc/platform/amigaone/Kconfig -image-$(CONFIG_AMIGAONE) += cuImage.amigaone - # For 32-bit powermacs, build the COFF and miboot images # as well as the ELF images. ifeq ($(CONFIG_PPC32),y) diff --git a/trunk/arch/powerpc/boot/cuboot-amigaone.c b/trunk/arch/powerpc/boot/cuboot-amigaone.c deleted file mode 100644 index d5029674030b..000000000000 --- a/trunk/arch/powerpc/boot/cuboot-amigaone.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Old U-boot compatibility for AmigaOne - * - * Author: Gerhard Pircher (gerhard_pircher@gmx.net) - * - * Based on cuboot-83xx.c - * Copyright (c) 2007 Freescale Semiconductor, Inc. - * - * 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 "ops.h" -#include "stdio.h" -#include "cuboot.h" - -#include "ppcboot.h" - -static bd_t bd; - -static void platform_fixups(void) -{ - dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); - dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 4, bd.bi_busfreq); -} - -void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7) -{ - CUBOOT_INIT(); - fdt_init(_dtb_start); - serial_console_init(); - platform_ops.fixups = platform_fixups; -} diff --git a/trunk/arch/powerpc/boot/dts/amigaone.dts b/trunk/arch/powerpc/boot/dts/amigaone.dts deleted file mode 100644 index 26549fca2ed4..000000000000 --- a/trunk/arch/powerpc/boot/dts/amigaone.dts +++ /dev/null @@ -1,173 +0,0 @@ -/* - * AmigaOne Device Tree Source - * - * Copyright 2008 Gerhard Pircher (gerhard_pircher@gmx.net) - * - * 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. - */ - -/dts-v1/; - -/ { - model = "AmigaOne"; - compatible = "eyetech,amigaone"; - coherency-off; - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #cpus = <1>; - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // 33.3 MHz, from U-boot - clock-frequency = <0>; // From U-boot - bus-frequency = <0>; // From U-boot - }; - }; - - memory { - device_type = "memory"; - reg = <0 0>; // From U-boot - }; - - pci@80000000 { - device_type = "pci"; - compatible = "mai-logic,articia-s"; - bus-frequency = <33333333>; - bus-range = <0 0xff>; - ranges = <0x01000000 0 0x00000000 0xfe000000 0 0x00c00000 // PCI I/O - 0x02000000 0 0x80000000 0x80000000 0 0x7d000000 // PCI memory - 0x02000000 0 0x00000000 0xfd000000 0 0x01000000>; // PCI alias memory (ISA) - // Configuration address and data register. - reg = <0xfec00cf8 4 - 0xfee00cfc 4>; - 8259-interrupt-acknowledge = <0xfef00000>; - // Do not define a interrupt-parent here, if there is no - // interrupt-map property. - #address-cells = <3>; - #size-cells = <2>; - - isa@7 { - device_type = "isa"; - compatible = "pciclass,0601"; - vendor-id = <0x00001106>; - device-id = <0x00000686>; - revision-id = <0x00000010>; - class-code = <0x00060100>; - subsystem-id = <0>; - subsystem-vendor-id = <0>; - devsel-speed = <0x00000001>; - min-grant = <0>; - max-latency = <0>; - /* First 64k for I/O at 0x0 on PCI mapped to 0x0 on ISA. */ - ranges = <0x00000001 0 0x01000000 0 0x00000000 0x00010000>; - interrupt-parent = <&i8259>; - #interrupt-cells = <2>; - #address-cells = <2>; - #size-cells = <1>; - - dma-controller@0 { - compatible = "pnpPNP,200"; - reg = <1 0x00000000 0x00000020 - 1 0x00000080 0x00000010 - 1 0x000000c0 0x00000020>; - }; - - i8259: interrupt-controller@20 { - device_type = "interrupt-controller"; - compatible = "pnpPNP,000"; - interrupt-controller; - reg = <1 0x00000020 0x00000002 - 1 0x000000a0 0x00000002 - 1 0x000004d0 0x00000002>; - reserved-interrupts = <2>; - #interrupt-cells = <2>; - }; - - timer@40 { - // Also adds pcspkr to platform devices. - compatible = "pnpPNP,100"; - reg = <1 0x00000040 0x00000020>; - }; - - 8042@60 { - device_type = "8042"; - reg = <1 0x00000060 0x00000001 - 1 0x00000064 0x00000001>; - interrupts = <1 3 12 3>; - #address-cells = <1>; - #size-cells = <0>; - - keyboard@0 { - compatible = "pnpPNP,303"; - reg = <0>; - }; - - mouse@1 { - compatible = "pnpPNP,f03"; - reg = <1>; - }; - }; - - rtc@70 { - compatible = "pnpPNP,b00"; - reg = <1 0x00000070 0x00000002>; - interrupts = <8 3>; - }; - - serial@3f8 { - device_type = "serial"; - compatible = "pnpPNP,501","pnpPNP,500"; - reg = <1 0x000003f8 0x00000008>; - interrupts = <4 3>; - clock-frequency = <1843200>; - current-speed = <115200>; - }; - - serial@2f8 { - device_type = "serial"; - compatible = "pnpPNP,501","pnpPNP,500"; - reg = <1 0x000002f8 0x00000008>; - interrupts = <3 3>; - clock-frequency = <1843200>; - current-speed = <115200>; - }; - - parallel@378 { - device_type = "parallel"; - // No ECP support for now, otherwise add "pnpPNP,401". - compatible = "pnpPNP,400"; - reg = <1 0x00000378 0x00000003 - 1 0x00000778 0x00000003>; - }; - - fdc@3f0 { - device_type = "fdc"; - compatible = "pnpPNP,700"; - reg = <1 0x000003f0 0x00000008>; - interrupts = <6 3>; - #address-cells = <1>; - #size-cells = <0>; - - disk@0 { - reg = <0>; - }; - }; - }; - }; - - chosen { - linux,stdout-path = "/pci@80000000/isa@7/serial@3f8"; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/asp834x-redboot.dts b/trunk/arch/powerpc/boot/dts/asp834x-redboot.dts index 7da84fd7be93..524af7ef9f26 100644 --- a/trunk/arch/powerpc/boot/dts/asp834x-redboot.dts +++ b/trunk/arch/powerpc/boot/dts/asp834x-redboot.dts @@ -181,76 +181,70 @@ phy_type = "ulpi"; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&ipic>; + interrupts = <17 0x8>; + reg = <0x1>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&ipic>; + interrupts = <18 0x8>; + reg = <0x2>; + device_type = "ethernet-phy"; + }; + + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 08 e5 11 32 33 ]; interrupts = <32 0x8 33 0x8 34 0x8>; interrupt-parent = <&ipic>; tbi-handle = <&tbi0>; phy-handle = <&phy0>; linux,network-index = <0>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&ipic>; - interrupts = <17 0x8>; - reg = <0x1>; - device_type = "ethernet-phy"; - }; - - phy1: ethernet-phy@1 { - interrupt-parent = <&ipic>; - interrupts = <18 0x8>; - reg = <0x2>; - device_type = "ethernet-phy"; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 08 e5 11 32 34 ]; interrupts = <35 0x8 36 0x8 37 0x8>; interrupt-parent = <&ipic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; linux,network-index = <1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/canyonlands.dts b/trunk/arch/powerpc/boot/dts/canyonlands.dts index 5fd1ad09bdf2..4447def69dc5 100644 --- a/trunk/arch/powerpc/boot/dts/canyonlands.dts +++ b/trunk/arch/powerpc/boot/dts/canyonlands.dts @@ -149,20 +149,6 @@ /*RXDE*/ 0x5 0x4>; }; - USB0: ehci@bffd0400 { - compatible = "ibm,usb-ehci-460ex", "usb-ehci"; - interrupt-parent = <&UIC2>; - interrupts = <0x1d 4>; - reg = <4 0xbffd0400 0x90 4 0xbffd0490 0x70>; - }; - - USB1: usb@bffd0000 { - compatible = "ohci-le"; - reg = <4 0xbffd0000 0x60>; - interrupt-parent = <&UIC2>; - interrupts = <0x1e 4>; - }; - POB0: opb { compatible = "ibm,opb-460ex", "ibm,opb"; #address-cells = <1>; @@ -266,20 +252,6 @@ reg = <0xef600700 0x00000014>; interrupt-parent = <&UIC0>; interrupts = <0x2 0x4>; - #address-cells = <1>; - #size-cells = <0>; - rtc@68 { - compatible = "stm,m41t80"; - reg = <0x68>; - interrupt-parent = <&UIC2>; - interrupts = <0x19 0x8>; - }; - sttm@48 { - compatible = "ad,ad7414"; - reg = <0x48>; - interrupt-parent = <&UIC1>; - interrupts = <0x14 0x8>; - }; }; IIC1: i2c@ef600800 { diff --git a/trunk/arch/powerpc/boot/dts/cm5200.dts b/trunk/arch/powerpc/boot/dts/cm5200.dts index cee8080aa245..2f74cc4e093e 100644 --- a/trunk/arch/powerpc/boot/dts/cm5200.dts +++ b/trunk/arch/powerpc/boot/dts/cm5200.dts @@ -17,7 +17,6 @@ compatible = "schindler,cm5200"; #address-cells = <1>; #size-cells = <1>; - interrupt-parent = <&mpc5200_pic>; cpus { #address-cells = <1>; @@ -67,6 +66,7 @@ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; reg = <0x600 0x10>; interrupts = <1 9 0>; + interrupt-parent = <&mpc5200_pic>; fsl,has-wdt; }; @@ -74,76 +74,84 @@ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; reg = <0x610 0x10>; interrupts = <1 10 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@620 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; reg = <0x620 0x10>; interrupts = <1 11 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@630 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; reg = <0x630 0x10>; interrupts = <1 12 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@640 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; reg = <0x640 0x10>; interrupts = <1 13 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@650 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; reg = <0x650 0x10>; interrupts = <1 14 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@660 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; reg = <0x660 0x10>; interrupts = <1 15 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@670 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; reg = <0x670 0x10>; interrupts = <1 16 0>; + interrupt-parent = <&mpc5200_pic>; }; rtc@800 { // Real time clock compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; reg = <0x800 0x100>; interrupts = <1 5 0 1 6 0>; + interrupt-parent = <&mpc5200_pic>; }; - gpio_simple: gpio@b00 { + gpio@b00 { compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; reg = <0xb00 0x40>; interrupts = <1 7 0>; - gpio-controller; - #gpio-cells = <2>; + interrupt-parent = <&mpc5200_pic>; }; - gpio_wkup: gpio@c00 { + gpio@c00 { compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; reg = <0xc00 0x40>; interrupts = <1 8 0 0 3 0>; - gpio-controller; - #gpio-cells = <2>; + interrupt-parent = <&mpc5200_pic>; }; spi@f00 { compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; reg = <0xf00 0x20>; interrupts = <2 13 0 2 14 0>; + interrupt-parent = <&mpc5200_pic>; }; usb@1000 { compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; reg = <0x1000 0xff>; interrupts = <2 6 0>; + interrupt-parent = <&mpc5200_pic>; }; dma-controller@1200 { @@ -153,6 +161,7 @@ 3 4 0 3 5 0 3 6 0 3 7 0 3 8 0 3 9 0 3 10 0 3 11 0 3 12 0 3 13 0 3 14 0 3 15 0>; + interrupt-parent = <&mpc5200_pic>; }; xlb@1f00 { @@ -161,34 +170,48 @@ }; serial@2000 { // PSC1 + device_type = "serial"; compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + port-number = <0>; // Logical port assignment reg = <0x2000 0x100>; interrupts = <2 1 0>; + interrupt-parent = <&mpc5200_pic>; }; serial@2200 { // PSC2 - compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + device_type = "serial"; + compatible = "fsl,mpc5200-psc-uart"; + port-number = <1>; // Logical port assignment reg = <0x2200 0x100>; interrupts = <2 2 0>; + interrupt-parent = <&mpc5200_pic>; }; serial@2400 { // PSC3 - compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + device_type = "serial"; + compatible = "fsl,mpc5200-psc-uart"; + port-number = <2>; // Logical port assignment reg = <0x2400 0x100>; interrupts = <2 3 0>; + interrupt-parent = <&mpc5200_pic>; }; serial@2c00 { // PSC6 + device_type = "serial"; compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + port-number = <5>; // Logical port assignment reg = <0x2c00 0x100>; interrupts = <2 4 0>; + interrupt-parent = <&mpc5200_pic>; }; ethernet@3000 { + device_type = "network"; compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; reg = <0x3000 0x400>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <2 5 0>; + interrupt-parent = <&mpc5200_pic>; phy-handle = <&phy0>; }; @@ -198,8 +221,10 @@ compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + interrupt-parent = <&mpc5200_pic>; phy0: ethernet-phy@0 { + device_type = "ethernet-phy"; reg = <0>; }; }; @@ -210,6 +235,7 @@ compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; reg = <0x3d40 0x40>; interrupts = <2 16 0>; + interrupt-parent = <&mpc5200_pic>; fsl5200-clocking; }; @@ -219,8 +245,9 @@ }; }; - localbus { - compatible = "fsl,mpc5200b-lpb","simple-bus"; + lpb { + model = "fsl,lpb"; + compatible = "fsl,lpb"; #address-cells = <2>; #size-cells = <1>; ranges = <0 0 0xfc000000 0x2000000>; diff --git a/trunk/arch/powerpc/boot/dts/digsy_mtc.dts b/trunk/arch/powerpc/boot/dts/digsy_mtc.dts deleted file mode 100644 index 4c36186ef946..000000000000 --- a/trunk/arch/powerpc/boot/dts/digsy_mtc.dts +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Digsy MTC board Device Tree Source - * - * Copyright (C) 2009 Semihalf - * - * Based on the CM5200 by M. Balakowicz - * - * 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. - */ - -/dts-v1/; - -/ { - model = "intercontrol,digsy-mtc"; - compatible = "intercontrol,digsy-mtc"; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&mpc5200_pic>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,5200@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; - i-cache-line-size = <32>; - d-cache-size = <0x4000>; // L1, 16K - i-cache-size = <0x4000>; // L1, 16K - timebase-frequency = <0>; // from bootloader - bus-frequency = <0>; // from bootloader - clock-frequency = <0>; // from bootloader - }; - }; - - memory { - device_type = "memory"; - reg = <0x00000000 0x02000000>; // 32MB - }; - - soc5200@f0000000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc5200b-immr"; - ranges = <0 0xf0000000 0x0000c000>; - reg = <0xf0000000 0x00000100>; - bus-frequency = <0>; // from bootloader - system-frequency = <0>; // from bootloader - - cdm@200 { - compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm"; - reg = <0x200 0x38>; - }; - - mpc5200_pic: interrupt-controller@500 { - // 5200 interrupts are encoded into two levels; - interrupt-controller; - #interrupt-cells = <3>; - compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; - reg = <0x500 0x80>; - }; - - timer@600 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x600 0x10>; - interrupts = <1 9 0>; - fsl,has-wdt; - }; - - timer@610 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x610 0x10>; - interrupts = <1 10 0>; - }; - - timer@620 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x620 0x10>; - interrupts = <1 11 0>; - }; - - timer@630 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x630 0x10>; - interrupts = <1 12 0>; - }; - - timer@640 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x640 0x10>; - interrupts = <1 13 0>; - }; - - timer@650 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x650 0x10>; - interrupts = <1 14 0>; - }; - - timer@660 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x660 0x10>; - interrupts = <1 15 0>; - }; - - timer@670 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x670 0x10>; - interrupts = <1 16 0>; - }; - - gpio_simple: gpio@b00 { - compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; - reg = <0xb00 0x40>; - interrupts = <1 7 0>; - gpio-controller; - #gpio-cells = <2>; - }; - - gpio_wkup: gpio@c00 { - compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; - reg = <0xc00 0x40>; - interrupts = <1 8 0 0 3 0>; - gpio-controller; - #gpio-cells = <2>; - }; - - spi@f00 { - compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; - reg = <0xf00 0x20>; - interrupts = <2 13 0 2 14 0>; - }; - - usb@1000 { - compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; - reg = <0x1000 0xff>; - interrupts = <2 6 0>; - }; - - dma-controller@1200 { - compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; - reg = <0x1200 0x80>; - interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 - 3 4 0 3 5 0 3 6 0 3 7 0 - 3 8 0 3 9 0 3 10 0 3 11 0 - 3 12 0 3 13 0 3 14 0 3 15 0>; - }; - - xlb@1f00 { - compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb"; - reg = <0x1f00 0x100>; - }; - - serial@2600 { // PSC4 - compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; - reg = <0x2600 0x100>; - interrupts = <2 11 0>; - }; - - serial@2800 { // PSC5 - compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; - reg = <0x2800 0x100>; - interrupts = <2 12 0>; - }; - - ethernet@3000 { - compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; - reg = <0x3000 0x400>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <2 5 0>; - phy-handle = <&phy0>; - }; - - mdio@3000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; - reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts - interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. - - phy0: ethernet-phy@0 { - reg = <0>; - }; - }; - - ata@3a00 { - compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; - reg = <0x3a00 0x100>; - interrupts = <2 7 0>; - }; - - i2c@3d00 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; - reg = <0x3d00 0x40>; - interrupts = <2 15 0>; - fsl5200-clocking; - - rtc@50 { - compatible = "at,24c08"; - reg = <0x50>; - }; - - rtc@68 { - compatible = "dallas,ds1339"; - reg = <0x68>; - }; - }; - - sram@8000 { - compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram"; - reg = <0x8000 0x4000>; - }; - }; - - lpb { - compatible = "fsl,mpc5200b-lpb","simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - ranges = <0 0 0xff000000 0x1000000>; - - // 16-bit flash device at LocalPlus Bus CS0 - flash@0,0 { - compatible = "cfi-flash"; - reg = <0 0 0x1000000>; - bank-width = <2>; - device-width = <2>; - #size-cells = <1>; - #address-cells = <1>; - - partition@0 { - label = "kernel"; - reg = <0x0 0x00200000>; - }; - partition@200000 { - label = "root"; - reg = <0x00200000 0x00300000>; - }; - partition@500000 { - label = "user"; - reg = <0x00500000 0x00a00000>; - }; - partition@f00000 { - label = "u-boot"; - reg = <0x00f00000 0x100000>; - }; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/gef_ppc9a.dts b/trunk/arch/powerpc/boot/dts/gef_ppc9a.dts deleted file mode 100644 index d47ad0718759..000000000000 --- a/trunk/arch/powerpc/boot/dts/gef_ppc9a.dts +++ /dev/null @@ -1,367 +0,0 @@ -/* - * GE Fanuc PPC9A Device Tree Source - * - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Based on: SBS CM6 Device Tree Source - * Copyright 2007 SBS Technologies GmbH & Co. KG - * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) - * Copyright 2006 Freescale Semiconductor Inc. - */ - -/* - * Compiled with dtc -I dts -O dtb -o gef_ppc9a.dtb gef_ppc9a.dts - */ - -/dts-v1/; - -/ { - model = "GEF_PPC9A"; - compatible = "gef,ppc9a"; - #address-cells = <1>; - #size-cells = <1>; - - aliases { - ethernet0 = &enet0; - ethernet1 = &enet1; - serial0 = &serial0; - serial1 = &serial1; - pci0 = &pci0; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,8641@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - PowerPC,8641@1 { - device_type = "cpu"; - reg = <1>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - }; - - memory { - device_type = "memory"; - reg = <0x0 0x40000000>; // set by uboot - }; - - localbus@fef05000 { - #address-cells = <2>; - #size-cells = <1>; - compatible = "fsl,mpc8641-localbus", "simple-bus"; - reg = <0xfef05000 0x1000>; - interrupts = <19 2>; - interrupt-parent = <&mpic>; - - ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash - 1 0 0xe8000000 0x08000000 // Paged Flash 0 - 2 0 0xe0000000 0x08000000 // Paged Flash 1 - 3 0 0xfc100000 0x00020000 // NVRAM - 4 0 0xfc000000 0x00008000 // FPGA - 5 0 0xfc008000 0x00008000 // AFIX FPGA - 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit) - 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit) - - /* flash@0,0 is a mirror of part of the memory in flash@1,0 - flash@0,0 { - compatible = "gef,ppc9a-firmware-mirror", "cfi-flash"; - reg = <0x0 0x0 0x1000000>; - bank-width = <4>; - device-width = <2>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "firmware"; - reg = <0x0 0x1000000>; - read-only; - }; - }; - */ - - flash@1,0 { - compatible = "gef,ppc9a-paged-flash", "cfi-flash"; - reg = <0x1 0x0 0x8000000>; - bank-width = <4>; - device-width = <2>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "user"; - reg = <0x0 0x7800000>; - }; - partition@7800000 { - label = "firmware"; - reg = <0x7800000 0x800000>; - read-only; - }; - }; - - fpga@4,0 { - compatible = "gef,ppc9a-fpga-regs"; - reg = <0x4 0x0 0x40>; - }; - - wdt@4,2000 { - compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00", - "gef,fpga-wdt"; - reg = <0x4 0x2000 0x8>; - interrupts = <0x1a 0x4>; - interrupt-parent = <&gef_pic>; - }; - /* Second watchdog available, driver currently supports one. - wdt@4,2010 { - compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00", - "gef,fpga-wdt"; - reg = <0x4 0x2010 0x8>; - interrupts = <0x1b 0x4>; - interrupt-parent = <&gef_pic>; - }; - */ - gef_pic: pic@4,4000 { - #interrupt-cells = <1>; - interrupt-controller; - compatible = "gef,ppc9a-fpga-pic", "gef,fpga-pic-1.00"; - reg = <0x4 0x4000 0x20>; - interrupts = <0x8 - 0x9>; - interrupt-parent = <&mpic>; - - }; - gef_gpio: gpio@7,14000 { - #gpio-cells = <2>; - compatible = "gef,ppc9a-gpio", "gef,sbc610-gpio"; - reg = <0x7 0x14000 0x24>; - gpio-controller; - }; - }; - - soc@fef00000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - compatible = "fsl,mpc8641-soc", "simple-bus"; - ranges = <0x0 0xfef00000 0x00100000>; - reg = <0xfef00000 0x100000>; // CCSRBAR 1M - bus-frequency = <33333333>; - - i2c1: i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <0x2b 0x2>; - interrupt-parent = <&mpic>; - dfsrr; - - hwmon@48 { - compatible = "national,lm92"; - reg = <0x48>; - }; - - hwmon@4c { - compatible = "adi,adt7461"; - reg = <0x4c>; - }; - - rtc@51 { - compatible = "epson,rx8581"; - reg = <0x00000051>; - }; - - eti@6b { - compatible = "dallas,ds1682"; - reg = <0x6b>; - }; - }; - - i2c2: i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl-i2c"; - reg = <0x3100 0x100>; - interrupts = <0x2b 0x2>; - interrupt-parent = <&mpic>; - dfsrr; - }; - - dma@21300 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; - reg = <0x21300 0x4>; - ranges = <0x0 0x21100 0x200>; - cell-index = <0>; - dma-channel@0 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x0 0x80>; - cell-index = <0>; - interrupt-parent = <&mpic>; - interrupts = <20 2>; - }; - dma-channel@80 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x80 0x80>; - cell-index = <1>; - interrupt-parent = <&mpic>; - interrupts = <21 2>; - }; - dma-channel@100 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x100 0x80>; - cell-index = <2>; - interrupt-parent = <&mpic>; - interrupts = <22 2>; - }; - dma-channel@180 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x180 0x80>; - cell-index = <3>; - interrupt-parent = <&mpic>; - interrupts = <23 2>; - }; - }; - - enet0: ethernet@24000 { - #address-cells = <1>; - #size-cells = <1>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy0>; - phy-connection-type = "gmii"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&gef_pic>; - interrupts = <0x9 0x4>; - reg = <1>; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&gef_pic>; - interrupts = <0x8 0x4>; - reg = <3>; - }; - }; - }; - - enet1: ethernet@26000 { - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <0x26000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy2>; - phy-connection-type = "gmii"; - }; - - serial0: serial@4500 { - cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <0x4500 0x100>; - clock-frequency = <0>; - interrupts = <0x2a 0x2>; - interrupt-parent = <&mpic>; - }; - - serial1: serial@4600 { - cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <0x4600 0x100>; - clock-frequency = <0>; - interrupts = <0x1c 0x2>; - interrupt-parent = <&mpic>; - }; - - mpic: pic@40000 { - clock-frequency = <0>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <0x40000 0x40000>; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - }; - - global-utilities@e0000 { - compatible = "fsl,mpc8641-guts"; - reg = <0xe0000 0x1000>; - fsl,has-rstcr; - }; - }; - - pci0: pcie@fef08000 { - compatible = "fsl,mpc8641-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <0xfef08000 0x1000>; - bus-range = <0x0 0xff>; - ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 - 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <0x18 0x2>; - interrupt-map-mask = <0xf800 0x0 0x0 0x7>; - interrupt-map = < - 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1 - 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1 - 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1 - 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1 - >; - - pcie@0 { - reg = <0 0 0 0 0>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - ranges = <0x02000000 0x0 0x80000000 - 0x02000000 0x0 0x80000000 - 0x0 0x40000000 - - 0x01000000 0x0 0x00000000 - 0x01000000 0x0 0x00000000 - 0x0 0x00400000>; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/gef_sbc310.dts b/trunk/arch/powerpc/boot/dts/gef_sbc310.dts deleted file mode 100644 index 1569117e5ddc..000000000000 --- a/trunk/arch/powerpc/boot/dts/gef_sbc310.dts +++ /dev/null @@ -1,367 +0,0 @@ -/* - * GE Fanuc SBC310 Device Tree Source - * - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Based on: SBS CM6 Device Tree Source - * Copyright 2007 SBS Technologies GmbH & Co. KG - * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) - * Copyright 2006 Freescale Semiconductor Inc. - */ - -/* - * Compiled with dtc -I dts -O dtb -o gef_sbc310.dtb gef_sbc310.dts - */ - -/dts-v1/; - -/ { - model = "GEF_SBC310"; - compatible = "gef,sbc310"; - #address-cells = <1>; - #size-cells = <1>; - - aliases { - ethernet0 = &enet0; - ethernet1 = &enet1; - serial0 = &serial0; - serial1 = &serial1; - pci0 = &pci0; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,8641@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - PowerPC,8641@1 { - device_type = "cpu"; - reg = <1>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - }; - - memory { - device_type = "memory"; - reg = <0x0 0x40000000>; // set by uboot - }; - - localbus@fef05000 { - #address-cells = <2>; - #size-cells = <1>; - compatible = "fsl,mpc8641-localbus", "simple-bus"; - reg = <0xfef05000 0x1000>; - interrupts = <19 2>; - interrupt-parent = <&mpic>; - - ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash - 1 0 0xe0000000 0x08000000 // Paged Flash 0 - 2 0 0xe8000000 0x08000000 // Paged Flash 1 - 3 0 0xfc100000 0x00020000 // NVRAM - 4 0 0xfc000000 0x00010000>; // FPGA - - /* flash@0,0 is a mirror of part of the memory in flash@1,0 - flash@0,0 { - compatible = "cfi-flash"; - reg = <0 0 0x01000000>; - bank-width = <2>; - device-width = <2>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "firmware"; - reg = <0x00000000 0x01000000>; - read-only; - }; - }; - */ - - flash@1,0 { - compatible = "cfi-flash"; - reg = <1 0 0x8000000>; - bank-width = <2>; - device-width = <2>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "user"; - reg = <0x00000000 0x07800000>; - }; - partition@7800000 { - label = "firmware"; - reg = <0x07800000 0x00800000>; - read-only; - }; - }; - - fpga@4,0 { - compatible = "gef,fpga-regs"; - reg = <0x4 0x0 0x40>; - }; - - wdt@4,2000 { - #interrupt-cells = <2>; - device_type = "watchdog"; - compatible = "gef,fpga-wdt"; - reg = <0x4 0x2000 0x8>; - interrupts = <0x1a 0x4>; - interrupt-parent = <&gef_pic>; - }; -/* - wdt@4,2010 { - #interrupt-cells = <2>; - device_type = "watchdog"; - compatible = "gef,fpga-wdt"; - reg = <0x4 0x2010 0x8>; - interrupts = <0x1b 0x4>; - interrupt-parent = <&gef_pic>; - }; -*/ - gef_pic: pic@4,4000 { - #interrupt-cells = <1>; - interrupt-controller; - compatible = "gef,fpga-pic"; - reg = <0x4 0x4000 0x20>; - interrupts = <0x8 - 0x9>; - interrupt-parent = <&mpic>; - - }; - gef_gpio: gpio@4,8000 { - #gpio-cells = <2>; - compatible = "gef,sbc310-gpio"; - reg = <0x4 0x8000 0x24>; - gpio-controller; - }; - }; - - soc@fef00000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; - compatible = "simple-bus"; - ranges = <0x0 0xfef00000 0x00100000>; - reg = <0xfef00000 0x100000>; // CCSRBAR 1M - bus-frequency = <33333333>; - - i2c1: i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <0x2b 0x2>; - interrupt-parent = <&mpic>; - dfsrr; - - rtc@51 { - compatible = "epson,rx8581"; - reg = <0x00000051>; - }; - }; - - i2c2: i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl-i2c"; - reg = <0x3100 0x100>; - interrupts = <0x2b 0x2>; - interrupt-parent = <&mpic>; - dfsrr; - - hwmon@48 { - compatible = "national,lm92"; - reg = <0x48>; - }; - - hwmon@4c { - compatible = "adi,adt7461"; - reg = <0x4c>; - }; - - eti@6b { - compatible = "dallas,ds1682"; - reg = <0x6b>; - }; - }; - - dma@21300 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; - reg = <0x21300 0x4>; - ranges = <0x0 0x21100 0x200>; - cell-index = <0>; - dma-channel@0 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x0 0x80>; - cell-index = <0>; - interrupt-parent = <&mpic>; - interrupts = <20 2>; - }; - dma-channel@80 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x80 0x80>; - cell-index = <1>; - interrupt-parent = <&mpic>; - interrupts = <21 2>; - }; - dma-channel@100 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x100 0x80>; - cell-index = <2>; - interrupt-parent = <&mpic>; - interrupts = <22 2>; - }; - dma-channel@180 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x180 0x80>; - cell-index = <3>; - interrupt-parent = <&mpic>; - interrupts = <23 2>; - }; - }; - - enet0: ethernet@24000 { - #address-cells = <1>; - #size-cells = <1>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy0>; - phy-connection-type = "gmii"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&gef_pic>; - interrupts = <0x9 0x4>; - reg = <1>; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&gef_pic>; - interrupts = <0x8 0x4>; - reg = <3>; - }; - }; - }; - - enet1: ethernet@26000 { - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <0x26000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy2>; - phy-connection-type = "gmii"; - }; - - serial0: serial@4500 { - cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <0x4500 0x100>; - clock-frequency = <0>; - interrupts = <0x2a 0x2>; - interrupt-parent = <&mpic>; - }; - - serial1: serial@4600 { - cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <0x4600 0x100>; - clock-frequency = <0>; - interrupts = <0x1c 0x2>; - interrupt-parent = <&mpic>; - }; - - mpic: pic@40000 { - clock-frequency = <0>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <0x40000 0x40000>; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - }; - - global-utilities@e0000 { - compatible = "fsl,mpc8641-guts"; - reg = <0xe0000 0x1000>; - fsl,has-rstcr; - }; - }; - - pci0: pcie@fef08000 { - compatible = "fsl,mpc8641-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <0xfef08000 0x1000>; - bus-range = <0x0 0xff>; - ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 - 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <0x18 0x2>; - interrupt-map-mask = <0xf800 0x0 0x0 0x7>; - interrupt-map = < - 0x0000 0x0 0x0 0x1 &mpic 0x0 0x2 - 0x0000 0x0 0x0 0x2 &mpic 0x1 0x2 - 0x0000 0x0 0x0 0x3 &mpic 0x2 0x2 - 0x0000 0x0 0x0 0x4 &mpic 0x3 0x2 - >; - - pcie@0 { - reg = <0 0 0 0 0>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - ranges = <0x02000000 0x0 0x80000000 - 0x02000000 0x0 0x80000000 - 0x0 0x40000000 - - 0x01000000 0x0 0x00000000 - 0x01000000 0x0 0x00000000 - 0x0 0x00400000>; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/gef_sbc610.dts b/trunk/arch/powerpc/boot/dts/gef_sbc610.dts index 6582dbd36da7..e78c355c7bac 100644 --- a/trunk/arch/powerpc/boot/dts/gef_sbc610.dts +++ b/trunk/arch/powerpc/boot/dts/gef_sbc610.dts @@ -71,7 +71,7 @@ #address-cells = <2>; #size-cells = <1>; compatible = "fsl,mpc8641-localbus", "simple-bus"; - reg = <0xfef05000 0x1000>; + reg = <0xf8005000 0x1000>; interrupts = <19 2>; interrupt-parent = <&mpic>; @@ -202,37 +202,34 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&gef_pic>; + interrupts = <0x9 0x4>; + reg = <1>; + }; + phy2: ethernet-phy@2 { + interrupt-parent = <&gef_pic>; + interrupts = <0x8 0x4>; + reg = <3>; + }; + }; + + enet0: ethernet@24000 { device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>; interrupt-parent = <&mpic>; phy-handle = <&phy0>; phy-connection-type = "gmii"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&gef_pic>; - interrupts = <0x9 0x4>; - reg = <1>; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&gef_pic>; - interrupts = <0x8 0x4>; - reg = <3>; - }; - }; }; enet1: ethernet@26000 { diff --git a/trunk/arch/powerpc/boot/dts/ksi8560.dts b/trunk/arch/powerpc/boot/dts/ksi8560.dts index 308fe7c29dea..3bfff47418db 100644 --- a/trunk/arch/powerpc/boot/dts/ksi8560.dts +++ b/trunk/arch/powerpc/boot/dts/ksi8560.dts @@ -124,72 +124,67 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { /* For TSECs */ #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + PHY1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + reg = <0x1>; + device_type = "ethernet-phy"; + }; + + PHY2: ethernet-phy@2 { + interrupt-parent = <&mpic>; + reg = <0x2>; + device_type = "ethernet-phy"; + }; + + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + + enet0: ethernet@24000 { device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; /* Mac address filled in by bootwrapper */ local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&PHY1>; - - mdio@520 { /* For TSECs */ - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - PHY1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - reg = <0x1>; - device_type = "ethernet-phy"; - }; - - PHY2: ethernet-phy@2 { - interrupt-parent = <&mpic>; - reg = <0x2>; - device_type = "ethernet-phy"; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; /* Mac address filled in by bootwrapper */ local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <0x23 0x2 0x24 0x2 0x28 0x2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&PHY2>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; mpic: pic@40000 { diff --git a/trunk/arch/powerpc/boot/dts/lite5200.dts b/trunk/arch/powerpc/boot/dts/lite5200.dts index de30b3f9eb26..3f7a5dce8de0 100644 --- a/trunk/arch/powerpc/boot/dts/lite5200.dts +++ b/trunk/arch/powerpc/boot/dts/lite5200.dts @@ -17,7 +17,6 @@ compatible = "fsl,lite5200"; #address-cells = <1>; #size-cells = <1>; - interrupt-parent = <&mpc5200_pic>; cpus { #address-cells = <1>; @@ -59,74 +58,96 @@ // 5200 interrupts are encoded into two levels; interrupt-controller; #interrupt-cells = <3>; + device_type = "interrupt-controller"; compatible = "fsl,mpc5200-pic"; reg = <0x500 0x80>; }; timer@600 { // General Purpose Timer compatible = "fsl,mpc5200-gpt"; + cell-index = <0>; reg = <0x600 0x10>; interrupts = <1 9 0>; + interrupt-parent = <&mpc5200_pic>; fsl,has-wdt; }; timer@610 { // General Purpose Timer compatible = "fsl,mpc5200-gpt"; + cell-index = <1>; reg = <0x610 0x10>; interrupts = <1 10 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@620 { // General Purpose Timer compatible = "fsl,mpc5200-gpt"; + cell-index = <2>; reg = <0x620 0x10>; interrupts = <1 11 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@630 { // General Purpose Timer compatible = "fsl,mpc5200-gpt"; + cell-index = <3>; reg = <0x630 0x10>; interrupts = <1 12 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@640 { // General Purpose Timer compatible = "fsl,mpc5200-gpt"; + cell-index = <4>; reg = <0x640 0x10>; interrupts = <1 13 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@650 { // General Purpose Timer compatible = "fsl,mpc5200-gpt"; + cell-index = <5>; reg = <0x650 0x10>; interrupts = <1 14 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@660 { // General Purpose Timer compatible = "fsl,mpc5200-gpt"; + cell-index = <6>; reg = <0x660 0x10>; interrupts = <1 15 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@670 { // General Purpose Timer compatible = "fsl,mpc5200-gpt"; + cell-index = <7>; reg = <0x670 0x10>; interrupts = <1 16 0>; + interrupt-parent = <&mpc5200_pic>; }; rtc@800 { // Real time clock compatible = "fsl,mpc5200-rtc"; reg = <0x800 0x100>; interrupts = <1 5 0 1 6 0>; + interrupt-parent = <&mpc5200_pic>; }; can@900 { compatible = "fsl,mpc5200-mscan"; + cell-index = <0>; interrupts = <2 17 0>; + interrupt-parent = <&mpc5200_pic>; reg = <0x900 0x80>; }; can@980 { compatible = "fsl,mpc5200-mscan"; + cell-index = <1>; interrupts = <2 18 0>; + interrupt-parent = <&mpc5200_pic>; reg = <0x980 0x80>; }; @@ -134,33 +155,39 @@ compatible = "fsl,mpc5200-gpio"; reg = <0xb00 0x40>; interrupts = <1 7 0>; + interrupt-parent = <&mpc5200_pic>; }; gpio@c00 { compatible = "fsl,mpc5200-gpio-wkup"; reg = <0xc00 0x40>; interrupts = <1 8 0 0 3 0>; + interrupt-parent = <&mpc5200_pic>; }; spi@f00 { compatible = "fsl,mpc5200-spi"; reg = <0xf00 0x20>; interrupts = <2 13 0 2 14 0>; + interrupt-parent = <&mpc5200_pic>; }; usb@1000 { compatible = "fsl,mpc5200-ohci","ohci-be"; reg = <0x1000 0xff>; interrupts = <2 6 0>; + interrupt-parent = <&mpc5200_pic>; }; dma-controller@1200 { + device_type = "dma-controller"; compatible = "fsl,mpc5200-bestcomm"; reg = <0x1200 0x80>; interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 3 4 0 3 5 0 3 6 0 3 7 0 3 8 0 3 9 0 3 10 0 3 11 0 3 12 0 3 13 0 3 14 0 3 15 0>; + interrupt-parent = <&mpc5200_pic>; }; xlb@1f00 { @@ -169,10 +196,13 @@ }; serial@2000 { // PSC1 + device_type = "serial"; compatible = "fsl,mpc5200-psc-uart"; + port-number = <0>; // Logical port assignment cell-index = <0>; reg = <0x2000 0x100>; interrupts = <2 1 0>; + interrupt-parent = <&mpc5200_pic>; }; // PSC2 in ac97 mode example @@ -181,6 +211,7 @@ // cell-index = <1>; // reg = <0x2200 0x100>; // interrupts = <2 2 0>; + // interrupt-parent = <&mpc5200_pic>; //}; // PSC3 in CODEC mode example @@ -189,22 +220,27 @@ // cell-index = <2>; // reg = <0x2400 0x100>; // interrupts = <2 3 0>; + // interrupt-parent = <&mpc5200_pic>; //}; // PSC4 in uart mode example //serial@2600 { // PSC4 + // device_type = "serial"; // compatible = "fsl,mpc5200-psc-uart"; // cell-index = <3>; // reg = <0x2600 0x100>; // interrupts = <2 11 0>; + // interrupt-parent = <&mpc5200_pic>; //}; // PSC5 in uart mode example //serial@2800 { // PSC5 + // device_type = "serial"; // compatible = "fsl,mpc5200-psc-uart"; // cell-index = <4>; // reg = <0x2800 0x100>; // interrupts = <2 12 0>; + // interrupt-parent = <&mpc5200_pic>; //}; // PSC6 in spi mode example @@ -213,13 +249,16 @@ // cell-index = <5>; // reg = <0x2c00 0x100>; // interrupts = <2 4 0>; + // interrupt-parent = <&mpc5200_pic>; //}; ethernet@3000 { + device_type = "network"; compatible = "fsl,mpc5200-fec"; reg = <0x3000 0x400>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <2 5 0>; + interrupt-parent = <&mpc5200_pic>; phy-handle = <&phy0>; }; @@ -229,24 +268,30 @@ compatible = "fsl,mpc5200-mdio"; reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + interrupt-parent = <&mpc5200_pic>; phy0: ethernet-phy@1 { + device_type = "ethernet-phy"; reg = <1>; }; }; ata@3a00 { + device_type = "ata"; compatible = "fsl,mpc5200-ata"; reg = <0x3a00 0x100>; interrupts = <2 7 0>; + interrupt-parent = <&mpc5200_pic>; }; i2c@3d00 { #address-cells = <1>; #size-cells = <0>; compatible = "fsl,mpc5200-i2c","fsl-i2c"; + cell-index = <0>; reg = <0x3d00 0x40>; interrupts = <2 15 0>; + interrupt-parent = <&mpc5200_pic>; fsl5200-clocking; }; @@ -254,12 +299,14 @@ #address-cells = <1>; #size-cells = <0>; compatible = "fsl,mpc5200-i2c","fsl-i2c"; + cell-index = <1>; reg = <0x3d40 0x40>; interrupts = <2 16 0>; + interrupt-parent = <&mpc5200_pic>; fsl5200-clocking; }; sram@8000 { - compatible = "fsl,mpc5200-sram"; + compatible = "fsl,mpc5200-sram","sram"; reg = <0x8000 0x4000>; }; }; @@ -278,6 +325,7 @@ 0xc000 0 0 4 &mpc5200_pic 0 0 3>; clock-frequency = <0>; // From boot loader interrupts = <2 8 0 2 9 0 2 10 0>; + interrupt-parent = <&mpc5200_pic>; bus-range = <0 0>; ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000 0x02000000 0 0xa0000000 0xa0000000 0 0x10000000 diff --git a/trunk/arch/powerpc/boot/dts/lite5200b.dts b/trunk/arch/powerpc/boot/dts/lite5200b.dts index c63e3566479e..63e3bb48e843 100644 --- a/trunk/arch/powerpc/boot/dts/lite5200b.dts +++ b/trunk/arch/powerpc/boot/dts/lite5200b.dts @@ -17,7 +17,6 @@ compatible = "fsl,lite5200b"; #address-cells = <1>; #size-cells = <1>; - interrupt-parent = <&mpc5200_pic>; cpus { #address-cells = <1>; @@ -59,112 +58,136 @@ // 5200 interrupts are encoded into two levels; interrupt-controller; #interrupt-cells = <3>; + device_type = "interrupt-controller"; compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; reg = <0x500 0x80>; }; timer@600 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + cell-index = <0>; reg = <0x600 0x10>; interrupts = <1 9 0>; + interrupt-parent = <&mpc5200_pic>; fsl,has-wdt; }; timer@610 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + cell-index = <1>; reg = <0x610 0x10>; interrupts = <1 10 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@620 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + cell-index = <2>; reg = <0x620 0x10>; interrupts = <1 11 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@630 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + cell-index = <3>; reg = <0x630 0x10>; interrupts = <1 12 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@640 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + cell-index = <4>; reg = <0x640 0x10>; interrupts = <1 13 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@650 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + cell-index = <5>; reg = <0x650 0x10>; interrupts = <1 14 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@660 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + cell-index = <6>; reg = <0x660 0x10>; interrupts = <1 15 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@670 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + cell-index = <7>; reg = <0x670 0x10>; interrupts = <1 16 0>; + interrupt-parent = <&mpc5200_pic>; }; rtc@800 { // Real time clock compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; reg = <0x800 0x100>; interrupts = <1 5 0 1 6 0>; + interrupt-parent = <&mpc5200_pic>; }; can@900 { compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; + cell-index = <0>; interrupts = <2 17 0>; + interrupt-parent = <&mpc5200_pic>; reg = <0x900 0x80>; }; can@980 { compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; + cell-index = <1>; interrupts = <2 18 0>; + interrupt-parent = <&mpc5200_pic>; reg = <0x980 0x80>; }; - gpio_simple: gpio@b00 { + gpio@b00 { compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; reg = <0xb00 0x40>; interrupts = <1 7 0>; - gpio-controller; - #gpio-cells = <2>; + interrupt-parent = <&mpc5200_pic>; }; - gpio_wkup: gpio@c00 { + gpio@c00 { compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; reg = <0xc00 0x40>; interrupts = <1 8 0 0 3 0>; - gpio-controller; - #gpio-cells = <2>; + interrupt-parent = <&mpc5200_pic>; }; spi@f00 { compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; reg = <0xf00 0x20>; interrupts = <2 13 0 2 14 0>; + interrupt-parent = <&mpc5200_pic>; }; usb@1000 { compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; reg = <0x1000 0xff>; interrupts = <2 6 0>; + interrupt-parent = <&mpc5200_pic>; }; dma-controller@1200 { + device_type = "dma-controller"; compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; reg = <0x1200 0x80>; interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 3 4 0 3 5 0 3 6 0 3 7 0 3 8 0 3 9 0 3 10 0 3 11 0 3 12 0 3 13 0 3 14 0 3 15 0>; + interrupt-parent = <&mpc5200_pic>; }; xlb@1f00 { @@ -173,10 +196,13 @@ }; serial@2000 { // PSC1 + device_type = "serial"; compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + port-number = <0>; // Logical port assignment cell-index = <0>; reg = <0x2000 0x100>; interrupts = <2 1 0>; + interrupt-parent = <&mpc5200_pic>; }; // PSC2 in ac97 mode example @@ -185,6 +211,7 @@ // cell-index = <1>; // reg = <0x2200 0x100>; // interrupts = <2 2 0>; + // interrupt-parent = <&mpc5200_pic>; //}; // PSC3 in CODEC mode example @@ -193,22 +220,27 @@ // cell-index = <2>; // reg = <0x2400 0x100>; // interrupts = <2 3 0>; + // interrupt-parent = <&mpc5200_pic>; //}; // PSC4 in uart mode example //serial@2600 { // PSC4 + // device_type = "serial"; // compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; // cell-index = <3>; // reg = <0x2600 0x100>; // interrupts = <2 11 0>; + // interrupt-parent = <&mpc5200_pic>; //}; // PSC5 in uart mode example //serial@2800 { // PSC5 + // device_type = "serial"; // compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; // cell-index = <4>; // reg = <0x2800 0x100>; // interrupts = <2 12 0>; + // interrupt-parent = <&mpc5200_pic>; //}; // PSC6 in spi mode example @@ -217,40 +249,49 @@ // cell-index = <5>; // reg = <0x2c00 0x100>; // interrupts = <2 4 0>; + // interrupt-parent = <&mpc5200_pic>; //}; ethernet@3000 { + device_type = "network"; compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; reg = <0x3000 0x400>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <2 5 0>; + interrupt-parent = <&mpc5200_pic>; phy-handle = <&phy0>; }; mdio@3000 { #address-cells = <1>; #size-cells = <0>; - compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; + compatible = "fsl,mpc5200b-mdio", "fsl,mpc5200-mdio"; reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + interrupt-parent = <&mpc5200_pic>; phy0: ethernet-phy@0 { + device_type = "ethernet-phy"; reg = <0>; }; }; ata@3a00 { + device_type = "ata"; compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; reg = <0x3a00 0x100>; interrupts = <2 7 0>; + interrupt-parent = <&mpc5200_pic>; }; i2c@3d00 { #address-cells = <1>; #size-cells = <0>; compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + cell-index = <0>; reg = <0x3d00 0x40>; interrupts = <2 15 0>; + interrupt-parent = <&mpc5200_pic>; fsl5200-clocking; }; @@ -258,13 +299,14 @@ #address-cells = <1>; #size-cells = <0>; compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + cell-index = <1>; reg = <0x3d40 0x40>; interrupts = <2 16 0>; + interrupt-parent = <&mpc5200_pic>; fsl5200-clocking; }; - sram@8000 { - compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram"; + compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram","sram"; reg = <0x8000 0x4000>; }; }; @@ -288,6 +330,7 @@ 0xc800 0 0 4 &mpc5200_pic 0 0 3>; clock-frequency = <0>; // From boot loader interrupts = <2 8 0 2 9 0 2 10 0>; + interrupt-parent = <&mpc5200_pic>; bus-range = <0 0>; ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000 0x02000000 0 0xa0000000 0xa0000000 0 0x10000000 diff --git a/trunk/arch/powerpc/boot/dts/media5200.dts b/trunk/arch/powerpc/boot/dts/media5200.dts deleted file mode 100644 index e297d8b41875..000000000000 --- a/trunk/arch/powerpc/boot/dts/media5200.dts +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Freescale Media5200 board Device Tree Source - * - * Copyright 2009 Secret Lab Technologies Ltd. - * Grant Likely - * Steven Cavanagh - * - * 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. - */ - -/dts-v1/; - -/ { - model = "fsl,media5200"; - compatible = "fsl,media5200"; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&mpc5200_pic>; - - aliases { - console = &console; - ethernet0 = ð0; - }; - - chosen { - linux,stdout-path = &console; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,5200@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; - i-cache-line-size = <32>; - d-cache-size = <0x4000>; // L1, 16K - i-cache-size = <0x4000>; // L1, 16K - timebase-frequency = <33000000>; // 33 MHz, these were configured by U-Boot - bus-frequency = <132000000>; // 132 MHz - clock-frequency = <396000000>; // 396 MHz - }; - }; - - memory { - device_type = "memory"; - reg = <0x00000000 0x08000000>; // 128MB RAM - }; - - soc@f0000000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc5200b-immr"; - ranges = <0 0xf0000000 0x0000c000>; - reg = <0xf0000000 0x00000100>; - bus-frequency = <132000000>;// 132 MHz - system-frequency = <0>; // from bootloader - - cdm@200 { - compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm"; - reg = <0x200 0x38>; - }; - - mpc5200_pic: interrupt-controller@500 { - // 5200 interrupts are encoded into two levels; - interrupt-controller; - #interrupt-cells = <3>; - compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; - reg = <0x500 0x80>; - }; - - timer@600 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x600 0x10>; - interrupts = <1 9 0>; - fsl,has-wdt; - }; - - timer@610 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x610 0x10>; - interrupts = <1 10 0>; - }; - - timer@620 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x620 0x10>; - interrupts = <1 11 0>; - }; - - timer@630 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x630 0x10>; - interrupts = <1 12 0>; - }; - - timer@640 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x640 0x10>; - interrupts = <1 13 0>; - }; - - timer@650 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x650 0x10>; - interrupts = <1 14 0>; - }; - - timer@660 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x660 0x10>; - interrupts = <1 15 0>; - }; - - timer@670 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x670 0x10>; - interrupts = <1 16 0>; - }; - - rtc@800 { // Real time clock - compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; - reg = <0x800 0x100>; - interrupts = <1 5 0 1 6 0>; - }; - - can@900 { - compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; - interrupts = <2 17 0>; - reg = <0x900 0x80>; - }; - - can@980 { - compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; - interrupts = <2 18 0>; - reg = <0x980 0x80>; - }; - - gpio_simple: gpio@b00 { - compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; - reg = <0xb00 0x40>; - interrupts = <1 7 0>; - gpio-controller; - #gpio-cells = <2>; - }; - - gpio_wkup: gpio@c00 { - compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; - reg = <0xc00 0x40>; - interrupts = <1 8 0 0 3 0>; - gpio-controller; - #gpio-cells = <2>; - }; - - spi@f00 { - compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; - reg = <0xf00 0x20>; - interrupts = <2 13 0 2 14 0>; - }; - - usb@1000 { - compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; - reg = <0x1000 0x100>; - interrupts = <2 6 0>; - }; - - dma-controller@1200 { - compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; - reg = <0x1200 0x80>; - interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 - 3 4 0 3 5 0 3 6 0 3 7 0 - 3 8 0 3 9 0 3 10 0 3 11 0 - 3 12 0 3 13 0 3 14 0 3 15 0>; - }; - - xlb@1f00 { - compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb"; - reg = <0x1f00 0x100>; - }; - - // PSC6 in uart mode - console: serial@2c00 { // PSC6 - compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; - cell-index = <5>; - port-number = <0>; // Logical port assignment - reg = <0x2c00 0x100>; - interrupts = <2 4 0>; - }; - - eth0: ethernet@3000 { - compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; - reg = <0x3000 0x400>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <2 5 0>; - phy-handle = <&phy0>; - }; - - mdio@3000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; - reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts - interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. - - phy0: ethernet-phy@0 { - reg = <0>; - }; - }; - - ata@3a00 { - compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; - reg = <0x3a00 0x100>; - interrupts = <2 7 0>; - }; - - i2c@3d00 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; - reg = <0x3d00 0x40>; - interrupts = <2 15 0>; - fsl5200-clocking; - }; - - i2c@3d40 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; - reg = <0x3d40 0x40>; - interrupts = <2 16 0>; - fsl5200-clocking; - }; - - sram@8000 { - compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram"; - reg = <0x8000 0x4000>; - }; - }; - - pci@f0000d00 { - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci"; - reg = <0xf0000d00 0x100>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0xc000 0 0 1 &media5200_fpga 0 2 // 1st slot - 0xc000 0 0 2 &media5200_fpga 0 3 - 0xc000 0 0 3 &media5200_fpga 0 4 - 0xc000 0 0 4 &media5200_fpga 0 5 - - 0xc800 0 0 1 &media5200_fpga 0 3 // 2nd slot - 0xc800 0 0 2 &media5200_fpga 0 4 - 0xc800 0 0 3 &media5200_fpga 0 5 - 0xc800 0 0 4 &media5200_fpga 0 2 - - 0xd000 0 0 1 &media5200_fpga 0 4 // miniPCI - 0xd000 0 0 2 &media5200_fpga 0 5 - - 0xe000 0 0 1 &media5200_fpga 0 5 // CoralIP - >; - clock-frequency = <0>; // From boot loader - interrupts = <2 8 0 2 9 0 2 10 0>; - interrupt-parent = <&mpc5200_pic>; - bus-range = <0 0>; - ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000 - 0x02000000 0 0xa0000000 0xa0000000 0 0x10000000 - 0x01000000 0 0x00000000 0xb0000000 0 0x01000000>; - }; - - localbus { - compatible = "fsl,mpc5200b-lpb","simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - - ranges = < 0 0 0xfc000000 0x02000000 - 1 0 0xfe000000 0x02000000 - 2 0 0xf0010000 0x00010000 - 3 0 0xf0020000 0x00010000 >; - - flash@0,0 { - compatible = "amd,am29lv28ml", "cfi-flash"; - reg = <0 0x0 0x2000000>; // 32 MB - bank-width = <4>; // Width in bytes of the flash bank - device-width = <2>; // Two devices on each bank - }; - - flash@1,0 { - compatible = "amd,am29lv28ml", "cfi-flash"; - reg = <1 0 0x2000000>; // 32 MB - bank-width = <4>; // Width in bytes of the flash bank - device-width = <2>; // Two devices on each bank - }; - - media5200_fpga: fpga@2,0 { - compatible = "fsl,media5200-fpga"; - interrupt-controller; - #interrupt-cells = <2>; // 0:bank 1:id; no type field - reg = <2 0 0x10000>; - - interrupt-parent = <&mpc5200_pic>; - interrupts = <0 0 3 // IRQ bank 0 - 1 1 3>; // IRQ bank 1 - }; - - uart@3,0 { - compatible = "ti,tl16c752bpt"; - reg = <3 0 0x10000>; - interrupt-parent = <&media5200_fpga>; - interrupts = <0 0 0 1>; // 2 irqs - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/motionpro.dts b/trunk/arch/powerpc/boot/dts/motionpro.dts index 7be8ca038676..52ba6f98b273 100644 --- a/trunk/arch/powerpc/boot/dts/motionpro.dts +++ b/trunk/arch/powerpc/boot/dts/motionpro.dts @@ -17,7 +17,6 @@ compatible = "promess,motionpro"; #address-cells = <1>; #size-cells = <1>; - interrupt-parent = <&mpc5200_pic>; cpus { #address-cells = <1>; @@ -67,6 +66,7 @@ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; reg = <0x600 0x10>; interrupts = <1 9 0>; + interrupt-parent = <&mpc5200_pic>; fsl,has-wdt; }; @@ -74,30 +74,35 @@ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; reg = <0x610 0x10>; interrupts = <1 10 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@620 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; reg = <0x620 0x10>; interrupts = <1 11 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@630 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; reg = <0x630 0x10>; interrupts = <1 12 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@640 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; reg = <0x640 0x10>; interrupts = <1 13 0>; + interrupt-parent = <&mpc5200_pic>; }; timer@650 { // General Purpose Timer compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; reg = <0x650 0x10>; interrupts = <1 14 0>; + interrupt-parent = <&mpc5200_pic>; }; motionpro-led@660 { // Motion-PRO status LED @@ -105,6 +110,7 @@ label = "motionpro-statusled"; reg = <0x660 0x10>; interrupts = <1 15 0>; + interrupt-parent = <&mpc5200_pic>; blink-delay = <100>; // 100 msec }; @@ -113,46 +119,49 @@ label = "motionpro-readyled"; reg = <0x670 0x10>; interrupts = <1 16 0>; + interrupt-parent = <&mpc5200_pic>; }; rtc@800 { // Real time clock compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; reg = <0x800 0x100>; interrupts = <1 5 0 1 6 0>; + interrupt-parent = <&mpc5200_pic>; }; can@980 { compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; interrupts = <2 18 0>; + interrupt-parent = <&mpc5200_pic>; reg = <0x980 0x80>; }; - gpio_simple: gpio@b00 { + gpio@b00 { compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; reg = <0xb00 0x40>; interrupts = <1 7 0>; - gpio-controller; - #gpio-cells = <2>; + interrupt-parent = <&mpc5200_pic>; }; - gpio_wkup: gpio@c00 { + gpio@c00 { compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; reg = <0xc00 0x40>; interrupts = <1 8 0 0 3 0>; - gpio-controller; - #gpio-cells = <2>; + interrupt-parent = <&mpc5200_pic>; }; spi@f00 { compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; reg = <0xf00 0x20>; interrupts = <2 13 0 2 14 0>; + interrupt-parent = <&mpc5200_pic>; }; usb@1000 { compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; reg = <0x1000 0xff>; interrupts = <2 6 0>; + interrupt-parent = <&mpc5200_pic>; }; dma-controller@1200 { @@ -162,6 +171,7 @@ 3 4 0 3 5 0 3 6 0 3 7 0 3 8 0 3 9 0 3 10 0 3 11 0 3 12 0 3 13 0 3 14 0 3 15 0>; + interrupt-parent = <&mpc5200_pic>; }; xlb@1f00 { @@ -170,9 +180,12 @@ }; serial@2000 { // PSC1 + device_type = "serial"; compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + port-number = <0>; // Logical port assignment reg = <0x2000 0x100>; interrupts = <2 1 0>; + interrupt-parent = <&mpc5200_pic>; }; // PSC2 in spi master mode @@ -181,20 +194,26 @@ cell-index = <1>; reg = <0x2200 0x100>; interrupts = <2 2 0>; + interrupt-parent = <&mpc5200_pic>; }; // PSC5 in uart mode serial@2800 { // PSC5 + device_type = "serial"; compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + port-number = <4>; // Logical port assignment reg = <0x2800 0x100>; interrupts = <2 12 0>; + interrupt-parent = <&mpc5200_pic>; }; ethernet@3000 { + device_type = "network"; compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; reg = <0x3000 0x400>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <2 5 0>; + interrupt-parent = <&mpc5200_pic>; phy-handle = <&phy0>; }; @@ -204,8 +223,10 @@ compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + interrupt-parent = <&mpc5200_pic>; phy0: ethernet-phy@2 { + device_type = "ethernet-phy"; reg = <2>; }; }; @@ -214,6 +235,7 @@ compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; reg = <0x3a00 0x100>; interrupts = <2 7 0>; + interrupt-parent = <&mpc5200_pic>; }; i2c@3d40 { @@ -222,6 +244,7 @@ compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; reg = <0x3d40 0x40>; interrupts = <2 16 0>; + interrupt-parent = <&mpc5200_pic>; fsl5200-clocking; rtc@68 { @@ -236,8 +259,8 @@ }; }; - localbus { - compatible = "fsl,mpc5200b-lpb","simple-bus"; + lpb { + compatible = "fsl,lpb"; #address-cells = <2>; #size-cells = <1>; ranges = <0 0 0xff000000 0x01000000 @@ -250,6 +273,7 @@ compatible = "promess,motionpro-kollmorgen"; reg = <1 0 0x10000>; interrupts = <1 1 0>; + interrupt-parent = <&mpc5200_pic>; }; // 8-bit board CPLD on LocalPlus Bus CS2 diff --git a/trunk/arch/powerpc/boot/dts/mpc8313erdb.dts b/trunk/arch/powerpc/boot/dts/mpc8313erdb.dts index 761faa7b6964..3ebf7ec0484c 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8313erdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8313erdb.dts @@ -180,7 +180,7 @@ #address-cells = <1>; #size-cells = <1>; sleep = <&pmc 0x20000000>; - ranges = <0x0 0x24000 0x1000>; + ranges; cell-index = <0>; device_type = "network"; @@ -195,11 +195,11 @@ fixed-link = <1 1 1000 0 0>; fsl,magic-packet; - mdio@520 { + mdio@24520 { #address-cells = <1>; #size-cells = <0>; compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; + reg = <0x24520 0x20>; phy4: ethernet-phy@4 { interrupt-parent = <&ipic>; interrupts = <20 0x8>; @@ -221,7 +221,6 @@ model = "eTSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <34 0x8 33 0x8 32 0x8>; interrupt-parent = <&ipic>; @@ -230,11 +229,11 @@ sleep = <&pmc 0x10000000>; fsl,magic-packet; - mdio@520 { + mdio@25520 { #address-cells = <1>; #size-cells = <0>; compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; + reg = <0x25520 0x20>; tbi1: tbi-phy@11 { reg = <0x11>; diff --git a/trunk/arch/powerpc/boot/dts/mpc8315erdb.dts b/trunk/arch/powerpc/boot/dts/mpc8315erdb.dts index 3f4c5fb988a0..71784165b77e 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -22,8 +22,6 @@ serial0 = &serial0; serial1 = &serial1; pci0 = &pci0; - pci1 = &pci1; - pci2 = &pci2; }; cpus { @@ -190,74 +188,66 @@ phy_type = "utmi"; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + phy0: ethernet-phy@0 { + interrupt-parent = <&ipic>; + interrupts = <20 0x8>; + reg = <0x0>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&ipic>; + interrupts = <19 0x8>; + reg = <0x1>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <32 0x8 33 0x8 34 0x8>; interrupt-parent = <&ipic>; tbi-handle = <&tbi0>; phy-handle = < &phy0 >; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&ipic>; - interrupts = <20 0x8>; - reg = <0x0>; - device_type = "ethernet-phy"; - }; - - phy1: ethernet-phy@1 { - interrupt-parent = <&ipic>; - interrupts = <19 0x8>; - reg = <0x1>; - device_type = "ethernet-phy"; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 0x8 36 0x8 37 0x8>; interrupt-parent = <&ipic>; tbi-handle = <&tbi1>; phy-handle = < &phy1 >; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { @@ -359,66 +349,4 @@ compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; - - pci1: pcie@e0009000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - device_type = "pci"; - compatible = "fsl,mpc8315-pcie", "fsl,mpc8314-pcie"; - reg = <0xe0009000 0x00001000>; - ranges = <0x02000000 0 0xa0000000 0xa0000000 0 0x10000000 - 0x01000000 0 0x00000000 0xb1000000 0 0x00800000>; - bus-range = <0 255>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0 0 0 1 &ipic 1 8 - 0 0 0 2 &ipic 1 8 - 0 0 0 3 &ipic 1 8 - 0 0 0 4 &ipic 1 8>; - clock-frequency = <0>; - - pcie@0 { - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - reg = <0 0 0 0 0>; - ranges = <0x02000000 0 0xa0000000 - 0x02000000 0 0xa0000000 - 0 0x10000000 - 0x01000000 0 0x00000000 - 0x01000000 0 0x00000000 - 0 0x00800000>; - }; - }; - - pci2: pcie@e000a000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - device_type = "pci"; - compatible = "fsl,mpc8315-pcie", "fsl,mpc8314-pcie"; - reg = <0xe000a000 0x00001000>; - ranges = <0x02000000 0 0xc0000000 0xc0000000 0 0x10000000 - 0x01000000 0 0x00000000 0xd1000000 0 0x00800000>; - bus-range = <0 255>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0 0 0 1 &ipic 2 8 - 0 0 0 2 &ipic 2 8 - 0 0 0 3 &ipic 2 8 - 0 0 0 4 &ipic 2 8>; - clock-frequency = <0>; - - pcie@0 { - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - reg = <0 0 0 0 0>; - ranges = <0x02000000 0 0xc0000000 - 0x02000000 0 0xc0000000 - 0 0x10000000 - 0x01000000 0 0x00000000 - 0x01000000 0 0x00000000 - 0 0x00800000>; - }; - }; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts b/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts index 4319bd70a580..dea30910c136 100644 --- a/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts @@ -152,21 +152,10 @@ }; par_io@1400 { - #address-cells = <1>; - #size-cells = <1>; reg = <0x1400 0x100>; - ranges = <3 0x1448 0x18>; - compatible = "fsl,mpc8323-qe-pario"; device_type = "par_io"; num-ports = <7>; - qe_pio_d: gpio-controller@1448 { - #gpio-cells = <2>; - compatible = "fsl,mpc8323-qe-pario-bank"; - reg = <3 0x18>; - gpio-controller; - }; - ucc2pio:ucc_pin@02 { pio-map = < /* port pin dir open_drain assignment has_irq */ @@ -236,25 +225,12 @@ }; spi@4c0 { - #address-cells = <1>; - #size-cells = <0>; cell-index = <0>; compatible = "fsl,spi"; reg = <0x4c0 0x40>; interrupts = <2>; interrupt-parent = <&qeic>; - gpios = <&qe_pio_d 13 0>; mode = "cpu-qe"; - - mmc-slot@0 { - compatible = "fsl,mpc8323rdb-mmc-slot", - "mmc-spi-slot"; - reg = <0>; - gpios = <&qe_pio_d 14 1 - &qe_pio_d 15 0>; - voltage-ranges = <3300 3300>; - spi-max-frequency = <50000000>; - }; }; spi@500 { diff --git a/trunk/arch/powerpc/boot/dts/mpc8349emitx.dts b/trunk/arch/powerpc/boot/dts/mpc8349emitx.dts index 1ae38f0ddef8..b5eda94a8e2a 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -170,52 +170,57 @@ phy_type = "ulpi"; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + /* Vitesse 8201 */ + phy1c: ethernet-phy@1c { + interrupt-parent = <&ipic>; + interrupts = <18 0x8>; + reg = <0x1c>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <32 0x8 33 0x8 34 0x8>; interrupt-parent = <&ipic>; tbi-handle = <&tbi0>; phy-handle = <&phy1c>; linux,network-index = <0>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - /* Vitesse 8201 */ - phy1c: ethernet-phy@1c { - interrupt-parent = <&ipic>; - interrupts = <18 0x8>; - reg = <0x1c>; - device_type = "ethernet-phy"; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 0x8 36 0x8 37 0x8>; interrupt-parent = <&ipic>; @@ -223,18 +228,6 @@ fixed-link = <1 1 1000 0 0>; linux,network-index = <1>; tbi-handle = <&tbi1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/trunk/arch/powerpc/boot/dts/mpc8349emitxgp.dts index 662abe1fb804..c87a6015e165 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8349emitxgp.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8349emitxgp.dts @@ -149,41 +149,37 @@ phy_type = "ulpi"; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + /* Vitesse 8201 */ + phy1c: ethernet-phy@1c { + interrupt-parent = <&ipic>; + interrupts = <18 0x8>; + reg = <0x1c>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <32 0x8 33 0x8 34 0x8>; interrupt-parent = <&ipic>; tbi-handle = <&tbi0>; phy-handle = <&phy1c>; linux,network-index = <0>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - /* Vitesse 8201 */ - phy1c: ethernet-phy@1c { - interrupt-parent = <&ipic>; - interrupts = <18 0x8>; - reg = <0x1c>; - device_type = "ethernet-phy"; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/mpc834x_mds.dts b/trunk/arch/powerpc/boot/dts/mpc834x_mds.dts index d9f0a2325fa4..d9adba01c09c 100644 --- a/trunk/arch/powerpc/boot/dts/mpc834x_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc834x_mds.dts @@ -167,76 +167,69 @@ phy_type = "ulpi"; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&ipic>; + interrupts = <17 0x8>; + reg = <0x0>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&ipic>; + interrupts = <18 0x8>; + reg = <0x1>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <32 0x8 33 0x8 34 0x8>; interrupt-parent = <&ipic>; tbi-handle = <&tbi0>; phy-handle = <&phy0>; linux,network-index = <0>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&ipic>; - interrupts = <17 0x8>; - reg = <0x0>; - device_type = "ethernet-phy"; - }; - - phy1: ethernet-phy@1 { - interrupt-parent = <&ipic>; - interrupts = <18 0x8>; - reg = <0x1>; - device_type = "ethernet-phy"; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 0x8 36 0x8 37 0x8>; interrupt-parent = <&ipic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; linux,network-index = <1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/mpc8377_mds.dts b/trunk/arch/powerpc/boot/dts/mpc8377_mds.dts index 963708017e6c..1d14d7052e6d 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8377_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8377_mds.dts @@ -23,8 +23,6 @@ serial0 = &serial0; serial1 = &serial1; pci0 = &pci0; - pci1 = &pci1; - pci2 = &pci2; }; cpus { @@ -129,38 +127,21 @@ reg = <0x200 0x100>; }; - sleep-nexus { + i2c@3000 { #address-cells = <1>; - #size-cells = <1>; - compatible = "simple-bus"; - sleep = <&pmc 0x0c000000>; - ranges; - - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <14 0x8>; - interrupt-parent = <&ipic>; - dfsrr; - - rtc@68 { - compatible = "dallas,ds1374"; - reg = <0x68>; - interrupts = <19 0x8>; - interrupt-parent = <&ipic>; - }; - }; + #size-cells = <0>; + cell-index = <0>; + compatible = "fsl-i2c"; + reg = <0x3000 0x100>; + interrupts = <14 0x8>; + interrupt-parent = <&ipic>; + dfsrr; - sdhci@2e000 { - compatible = "fsl,mpc8377-esdhc", "fsl,mpc8379-esdhc"; - reg = <0x2e000 0x1000>; - interrupts = <42 0x8>; + rtc@68 { + compatible = "dallas,ds1374"; + reg = <0x68>; + interrupts = <19 0x8>; interrupt-parent = <&ipic>; - /* Filled in by U-Boot */ - clock-frequency = <0>; }; }; @@ -193,83 +174,70 @@ interrupts = <38 0x8>; dr_mode = "host"; phy_type = "ulpi"; - sleep = <&pmc 0x00c00000>; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + phy2: ethernet-phy@2 { + interrupt-parent = <&ipic>; + interrupts = <17 0x8>; + reg = <0x2>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&ipic>; + interrupts = <18 0x8>; + reg = <0x3>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <32 0x8 33 0x8 34 0x8>; phy-connection-type = "mii"; interrupt-parent = <&ipic>; tbi-handle = <&tbi0>; phy-handle = <&phy2>; - sleep = <&pmc 0xc0000000>; - fsl,magic-packet; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy2: ethernet-phy@2 { - interrupt-parent = <&ipic>; - interrupts = <17 0x8>; - reg = <0x2>; - device_type = "ethernet-phy"; - }; - - phy3: ethernet-phy@3 { - interrupt-parent = <&ipic>; - interrupts = <18 0x8>; - reg = <0x3>; - device_type = "ethernet-phy"; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 0x8 36 0x8 37 0x8>; phy-connection-type = "mii"; interrupt-parent = <&ipic>; tbi-handle = <&tbi1>; phy-handle = <&phy3>; - sleep = <&pmc 0x30000000>; - fsl,magic-packet; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { @@ -341,7 +309,14 @@ fsl,channel-fifo-len = <24>; fsl,exec-units-mask = <0x9fe>; fsl,descriptor-types-mask = <0x3ab0ebf>; - sleep = <&pmc 0x03000000>; + }; + + sdhc@2e000 { + model = "eSDHC"; + compatible = "fsl,esdhc"; + reg = <0x2e000 0x1000>; + interrupts = <42 0x8>; + interrupt-parent = <&ipic>; }; sata@18000 { @@ -349,7 +324,6 @@ reg = <0x18000 0x1000>; interrupts = <44 0x8>; interrupt-parent = <&ipic>; - sleep = <&pmc 0x000000c0>; }; sata@19000 { @@ -357,7 +331,6 @@ reg = <0x19000 0x1000>; interrupts = <45 0x8>; interrupt-parent = <&ipic>; - sleep = <&pmc 0x00000030>; }; /* IPIC @@ -373,13 +346,6 @@ #interrupt-cells = <2>; reg = <0x700 0x100>; }; - - pmc: power@b00 { - compatible = "fsl,mpc8377-pmc", "fsl,mpc8349-pmc"; - reg = <0xb00 0x100 0xa00 0x100>; - interrupts = <80 0x8>; - interrupt-parent = <&ipic>; - }; }; pci0: pci@e0008500 { @@ -434,7 +400,6 @@ ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000 0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>; - sleep = <&pmc 0x00010000>; clock-frequency = <0>; #interrupt-cells = <1>; #size-cells = <2>; @@ -444,68 +409,4 @@ compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; - - pci1: pcie@e0009000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - device_type = "pci"; - compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie"; - reg = <0xe0009000 0x00001000>; - ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000 - 0x01000000 0 0x00000000 0xb8000000 0 0x00800000>; - bus-range = <0 255>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0 0 0 1 &ipic 1 8 - 0 0 0 2 &ipic 1 8 - 0 0 0 3 &ipic 1 8 - 0 0 0 4 &ipic 1 8>; - sleep = <&pmc 0x00300000>; - clock-frequency = <0>; - - pcie@0 { - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - reg = <0 0 0 0 0>; - ranges = <0x02000000 0 0xa8000000 - 0x02000000 0 0xa8000000 - 0 0x10000000 - 0x01000000 0 0x00000000 - 0x01000000 0 0x00000000 - 0 0x00800000>; - }; - }; - - pci2: pcie@e000a000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - device_type = "pci"; - compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie"; - reg = <0xe000a000 0x00001000>; - ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000 - 0x01000000 0 0x00000000 0xd8000000 0 0x00800000>; - bus-range = <0 255>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0 0 0 1 &ipic 2 8 - 0 0 0 2 &ipic 2 8 - 0 0 0 3 &ipic 2 8 - 0 0 0 4 &ipic 2 8>; - sleep = <&pmc 0x000c0000>; - clock-frequency = <0>; - - pcie@0 { - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - reg = <0 0 0 0 0>; - ranges = <0x02000000 0 0xc8000000 - 0x02000000 0 0xc8000000 - 0 0x10000000 - 0x01000000 0 0x00000000 - 0x01000000 0 0x00000000 - 0 0x00800000>; - }; - }; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8377_rdb.dts b/trunk/arch/powerpc/boot/dts/mpc8377_rdb.dts index 053339390c22..9413af3b9925 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8377_rdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8377_rdb.dts @@ -22,8 +22,6 @@ serial0 = &serial0; serial1 = &serial1; pci0 = &pci0; - pci1 = &pci1; - pci2 = &pci2; }; cpus { @@ -109,72 +107,26 @@ reg = <0x200 0x100>; }; - gpio1: gpio-controller@c00 { - #gpio-cells = <2>; - compatible = "fsl,mpc8377-gpio", "fsl,mpc8349-gpio"; - reg = <0xc00 0x100>; - interrupts = <74 0x8>; - interrupt-parent = <&ipic>; - gpio-controller; - }; - - gpio2: gpio-controller@d00 { - #gpio-cells = <2>; - compatible = "fsl,mpc8377-gpio", "fsl,mpc8349-gpio"; - reg = <0xd00 0x100>; - interrupts = <75 0x8>; - interrupt-parent = <&ipic>; - gpio-controller; - }; - - sleep-nexus { + i2c@3000 { #address-cells = <1>; - #size-cells = <1>; - compatible = "simple-bus"; - sleep = <&pmc 0x0c000000>; - ranges; - - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <14 0x8>; - interrupt-parent = <&ipic>; - dfsrr; - - dtt@48 { - compatible = "national,lm75"; - reg = <0x48>; - }; - - at24@50 { - compatible = "at24,24c256"; - reg = <0x50>; - }; - - rtc@68 { - compatible = "dallas,ds1339"; - reg = <0x68>; - }; - - mcu_pio: mcu@a { - #gpio-cells = <2>; - compatible = "fsl,mc9s08qg8-mpc8377erdb", - "fsl,mcu-mpc8349emitx"; - reg = <0x0a>; - gpio-controller; - }; + #size-cells = <0>; + cell-index = <0>; + compatible = "fsl-i2c"; + reg = <0x3000 0x100>; + interrupts = <14 0x8>; + interrupt-parent = <&ipic>; + dfsrr; + rtc@68 { + compatible = "dallas,ds1339"; + reg = <0x68>; }; - sdhci@2e000 { - compatible = "fsl,mpc8377-esdhc", "fsl,mpc8379-esdhc"; - reg = <0x2e000 0x1000>; - interrupts = <42 0x8>; - interrupt-parent = <&ipic>; - /* Filled in by U-Boot */ - clock-frequency = <0>; + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8377erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; }; }; @@ -245,76 +197,64 @@ interrupt-parent = <&ipic>; interrupts = <38 0x8>; phy_type = "ulpi"; - sleep = <&pmc 0x00c00000>; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + phy2: ethernet-phy@2 { + interrupt-parent = <&ipic>; + interrupts = <17 0x8>; + reg = <0x2>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <32 0x8 33 0x8 34 0x8>; phy-connection-type = "mii"; interrupt-parent = <&ipic>; tbi-handle = <&tbi0>; phy-handle = <&phy2>; - sleep = <&pmc 0xc0000000>; - fsl,magic-packet; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy2: ethernet-phy@2 { - interrupt-parent = <&ipic>; - interrupts = <17 0x8>; - reg = <0x2>; - device_type = "ethernet-phy"; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 0x8 36 0x8 37 0x8>; phy-connection-type = "mii"; interrupt-parent = <&ipic>; fixed-link = <1 1 1000 0 0>; tbi-handle = <&tbi1>; - sleep = <&pmc 0x30000000>; - fsl,magic-packet; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { @@ -347,7 +287,6 @@ fsl,channel-fifo-len = <24>; fsl,exec-units-mask = <0x9fe>; fsl,descriptor-types-mask = <0x3ab0ebf>; - sleep = <&pmc 0x03000000>; }; sata@18000 { @@ -355,7 +294,6 @@ reg = <0x18000 0x1000>; interrupts = <44 0x8>; interrupt-parent = <&ipic>; - sleep = <&pmc 0x000000c0>; }; sata@19000 { @@ -363,7 +301,6 @@ reg = <0x19000 0x1000>; interrupts = <45 0x8>; interrupt-parent = <&ipic>; - sleep = <&pmc 0x00000030>; }; /* IPIC @@ -379,13 +316,6 @@ #interrupt-cells = <2>; reg = <0x700 0x100>; }; - - pmc: power@b00 { - compatible = "fsl,mpc8377-pmc", "fsl,mpc8349-pmc"; - reg = <0xb00 0x100 0xa00 0x100>; - interrupts = <80 0x8>; - interrupt-parent = <&ipic>; - }; }; pci0: pci@e0008500 { @@ -411,7 +341,6 @@ ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>; - sleep = <&pmc 0x00010000>; clock-frequency = <66666666>; #interrupt-cells = <1>; #size-cells = <2>; @@ -421,68 +350,4 @@ compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; - - pci1: pcie@e0009000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - device_type = "pci"; - compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie"; - reg = <0xe0009000 0x00001000>; - ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000 - 0x01000000 0 0x00000000 0xb8000000 0 0x00800000>; - bus-range = <0 255>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0 0 0 1 &ipic 1 8 - 0 0 0 2 &ipic 1 8 - 0 0 0 3 &ipic 1 8 - 0 0 0 4 &ipic 1 8>; - sleep = <&pmc 0x00300000>; - clock-frequency = <0>; - - pcie@0 { - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - reg = <0 0 0 0 0>; - ranges = <0x02000000 0 0xa8000000 - 0x02000000 0 0xa8000000 - 0 0x10000000 - 0x01000000 0 0x00000000 - 0x01000000 0 0x00000000 - 0 0x00800000>; - }; - }; - - pci2: pcie@e000a000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - device_type = "pci"; - compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie"; - reg = <0xe000a000 0x00001000>; - ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000 - 0x01000000 0 0x00000000 0xd8000000 0 0x00800000>; - bus-range = <0 255>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0 0 0 1 &ipic 2 8 - 0 0 0 2 &ipic 2 8 - 0 0 0 3 &ipic 2 8 - 0 0 0 4 &ipic 2 8>; - sleep = <&pmc 0x000c0000>; - clock-frequency = <0>; - - pcie@0 { - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - reg = <0 0 0 0 0>; - ranges = <0x02000000 0 0xc8000000 - 0x02000000 0 0xc8000000 - 0 0x10000000 - 0x01000000 0 0x00000000 - 0x01000000 0 0x00000000 - 0 0x00800000>; - }; - }; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8378_mds.dts b/trunk/arch/powerpc/boot/dts/mpc8378_mds.dts index 651ff2f9db2d..b85fc02682d2 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8378_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8378_mds.dts @@ -23,8 +23,6 @@ serial0 = &serial0; serial1 = &serial1; pci0 = &pci0; - pci1 = &pci1; - pci2 = &pci2; }; cpus { @@ -129,38 +127,21 @@ reg = <0x200 0x100>; }; - sleep-nexus { + i2c@3000 { #address-cells = <1>; - #size-cells = <1>; - compatible = "simple-bus"; - sleep = <&pmc 0x0c000000>; - ranges; - - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <14 0x8>; - interrupt-parent = <&ipic>; - dfsrr; - - rtc@68 { - compatible = "dallas,ds1374"; - reg = <0x68>; - interrupts = <19 0x8>; - interrupt-parent = <&ipic>; - }; - }; + #size-cells = <0>; + cell-index = <0>; + compatible = "fsl-i2c"; + reg = <0x3000 0x100>; + interrupts = <14 0x8>; + interrupt-parent = <&ipic>; + dfsrr; - sdhci@2e000 { - compatible = "fsl,mpc8378-esdhc", "fsl,mpc8379-esdhc"; - reg = <0x2e000 0x1000>; - interrupts = <42 0x8>; + rtc@68 { + compatible = "dallas,ds1374"; + reg = <0x68>; + interrupts = <19 0x8>; interrupt-parent = <&ipic>; - /* Filled in by U-Boot */ - clock-frequency = <0>; }; }; @@ -232,83 +213,70 @@ interrupts = <38 0x8>; dr_mode = "host"; phy_type = "ulpi"; - sleep = <&pmc 0x00c00000>; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + phy2: ethernet-phy@2 { + interrupt-parent = <&ipic>; + interrupts = <17 0x8>; + reg = <0x2>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&ipic>; + interrupts = <18 0x8>; + reg = <0x3>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <32 0x8 33 0x8 34 0x8>; phy-connection-type = "mii"; interrupt-parent = <&ipic>; tbi-handle = <&tbi0>; phy-handle = <&phy2>; - sleep = <&pmc 0xc0000000>; - fsl,magic-packet; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy2: ethernet-phy@2 { - interrupt-parent = <&ipic>; - interrupts = <17 0x8>; - reg = <0x2>; - device_type = "ethernet-phy"; - }; - - phy3: ethernet-phy@3 { - interrupt-parent = <&ipic>; - interrupts = <18 0x8>; - reg = <0x3>; - device_type = "ethernet-phy"; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 0x8 36 0x8 37 0x8>; phy-connection-type = "mii"; interrupt-parent = <&ipic>; tbi-handle = <&tbi1>; phy-handle = <&phy3>; - sleep = <&pmc 0x30000000>; - fsl,magic-packet; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { @@ -341,7 +309,14 @@ fsl,channel-fifo-len = <24>; fsl,exec-units-mask = <0x9fe>; fsl,descriptor-types-mask = <0x3ab0ebf>; - sleep = <&pmc 0x03000000>; + }; + + sdhc@2e000 { + model = "eSDHC"; + compatible = "fsl,esdhc"; + reg = <0x2e000 0x1000>; + interrupts = <42 0x8>; + interrupt-parent = <&ipic>; }; /* IPIC @@ -357,13 +332,6 @@ #interrupt-cells = <2>; reg = <0x700 0x100>; }; - - pmc: power@b00 { - compatible = "fsl,mpc8378-pmc", "fsl,mpc8349-pmc"; - reg = <0xb00 0x100 0xa00 0x100>; - interrupts = <80 0x8>; - interrupt-parent = <&ipic>; - }; }; pci0: pci@e0008500 { @@ -419,7 +387,6 @@ 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000 0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>; clock-frequency = <0>; - sleep = <&pmc 0x00010000>; #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; @@ -428,68 +395,4 @@ compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; - - pci1: pcie@e0009000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - device_type = "pci"; - compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie"; - reg = <0xe0009000 0x00001000>; - ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000 - 0x01000000 0 0x00000000 0xb8000000 0 0x00800000>; - bus-range = <0 255>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0 0 0 1 &ipic 1 8 - 0 0 0 2 &ipic 1 8 - 0 0 0 3 &ipic 1 8 - 0 0 0 4 &ipic 1 8>; - sleep = <&pmc 0x00300000>; - clock-frequency = <0>; - - pcie@0 { - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - reg = <0 0 0 0 0>; - ranges = <0x02000000 0 0xa8000000 - 0x02000000 0 0xa8000000 - 0 0x10000000 - 0x01000000 0 0x00000000 - 0x01000000 0 0x00000000 - 0 0x00800000>; - }; - }; - - pci2: pcie@e000a000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - device_type = "pci"; - compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie"; - reg = <0xe000a000 0x00001000>; - ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000 - 0x01000000 0 0x00000000 0xd8000000 0 0x00800000>; - bus-range = <0 255>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0 0 0 1 &ipic 2 8 - 0 0 0 2 &ipic 2 8 - 0 0 0 3 &ipic 2 8 - 0 0 0 4 &ipic 2 8>; - sleep = <&pmc 0x000c0000>; - clock-frequency = <0>; - - pcie@0 { - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - reg = <0 0 0 0 0>; - ranges = <0x02000000 0 0xc8000000 - 0x02000000 0 0xc8000000 - 0 0x10000000 - 0x01000000 0 0x00000000 - 0x01000000 0 0x00000000 - 0 0x00800000>; - }; - }; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8378_rdb.dts b/trunk/arch/powerpc/boot/dts/mpc8378_rdb.dts index 5d90e85704c3..23c10ce22c2c 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8378_rdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8378_rdb.dts @@ -22,8 +22,6 @@ serial0 = &serial0; serial1 = &serial1; pci0 = &pci0; - pci1 = &pci1; - pci2 = &pci2; }; cpus { @@ -109,72 +107,26 @@ reg = <0x200 0x100>; }; - gpio1: gpio-controller@c00 { - #gpio-cells = <2>; - compatible = "fsl,mpc8378-gpio", "fsl,mpc8349-gpio"; - reg = <0xc00 0x100>; - interrupts = <74 0x8>; - interrupt-parent = <&ipic>; - gpio-controller; - }; - - gpio2: gpio-controller@d00 { - #gpio-cells = <2>; - compatible = "fsl,mpc8378-gpio", "fsl,mpc8349-gpio"; - reg = <0xd00 0x100>; - interrupts = <75 0x8>; - interrupt-parent = <&ipic>; - gpio-controller; - }; - - sleep-nexus { + i2c@3000 { #address-cells = <1>; - #size-cells = <1>; - compatible = "simple-bus"; - sleep = <&pmc 0x0c000000>; - ranges; - - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <14 0x8>; - interrupt-parent = <&ipic>; - dfsrr; - - dtt@48 { - compatible = "national,lm75"; - reg = <0x48>; - }; - - at24@50 { - compatible = "at24,24c256"; - reg = <0x50>; - }; - - rtc@68 { - compatible = "dallas,ds1339"; - reg = <0x68>; - }; - - mcu_pio: mcu@a { - #gpio-cells = <2>; - compatible = "fsl,mc9s08qg8-mpc8378erdb", - "fsl,mcu-mpc8349emitx"; - reg = <0x0a>; - gpio-controller; - }; + #size-cells = <0>; + cell-index = <0>; + compatible = "fsl-i2c"; + reg = <0x3000 0x100>; + interrupts = <14 0x8>; + interrupt-parent = <&ipic>; + dfsrr; + rtc@68 { + compatible = "dallas,ds1339"; + reg = <0x68>; }; - sdhci@2e000 { - compatible = "fsl,mpc8378-esdhc", "fsl,mpc8379-esdhc"; - reg = <0x2e000 0x1000>; - interrupts = <42 0x8>; - interrupt-parent = <&ipic>; - /* Filled in by U-Boot */ - clock-frequency = <0>; + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8378erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; }; }; @@ -245,76 +197,62 @@ interrupt-parent = <&ipic>; interrupts = <38 0x8>; phy_type = "ulpi"; - sleep = <&pmc 0x00c00000>; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + phy2: ethernet-phy@2 { + interrupt-parent = <&ipic>; + interrupts = <17 0x8>; + reg = <0x2>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <32 0x8 33 0x8 34 0x8>; phy-connection-type = "mii"; interrupt-parent = <&ipic>; - tbi-handle = <&tbi0>; phy-handle = <&phy2>; - sleep = <&pmc 0xc0000000>; - fsl,magic-packet; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy2: ethernet-phy@2 { - interrupt-parent = <&ipic>; - interrupts = <17 0x8>; - reg = <0x2>; - device_type = "ethernet-phy"; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 0x8 36 0x8 37 0x8>; phy-connection-type = "mii"; interrupt-parent = <&ipic>; fixed-link = <1 1 1000 0 0>; - tbi-handle = <&tbi1>; - sleep = <&pmc 0x30000000>; - fsl,magic-packet; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { @@ -347,7 +285,6 @@ fsl,channel-fifo-len = <24>; fsl,exec-units-mask = <0x9fe>; fsl,descriptor-types-mask = <0x3ab0ebf>; - sleep = <&pmc 0x03000000>; }; /* IPIC @@ -363,13 +300,6 @@ #interrupt-cells = <2>; reg = <0x700 0x100>; }; - - pmc: power@b00 { - compatible = "fsl,mpc8378-pmc", "fsl,mpc8349-pmc"; - reg = <0xb00 0x100 0xa00 0x100>; - interrupts = <80 0x8>; - interrupt-parent = <&ipic>; - }; }; pci0: pci@e0008500 { @@ -395,7 +325,6 @@ ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>; - sleep = <&pmc 0x00010000>; clock-frequency = <66666666>; #interrupt-cells = <1>; #size-cells = <2>; @@ -405,68 +334,4 @@ compatible = "fsl,mpc8349-pci"; device_type = "pci"; }; - - pci1: pcie@e0009000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - device_type = "pci"; - compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie"; - reg = <0xe0009000 0x00001000>; - ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000 - 0x01000000 0 0x00000000 0xb8000000 0 0x00800000>; - bus-range = <0 255>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0 0 0 1 &ipic 1 8 - 0 0 0 2 &ipic 1 8 - 0 0 0 3 &ipic 1 8 - 0 0 0 4 &ipic 1 8>; - sleep = <&pmc 0x00300000>; - clock-frequency = <0>; - - pcie@0 { - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - reg = <0 0 0 0 0>; - ranges = <0x02000000 0 0xa8000000 - 0x02000000 0 0xa8000000 - 0 0x10000000 - 0x01000000 0 0x00000000 - 0x01000000 0 0x00000000 - 0 0x00800000>; - }; - }; - - pci2: pcie@e000a000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - device_type = "pci"; - compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie"; - reg = <0xe000a000 0x00001000>; - ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000 - 0x01000000 0 0x00000000 0xd8000000 0 0x00800000>; - bus-range = <0 255>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0 0 0 1 &ipic 2 8 - 0 0 0 2 &ipic 2 8 - 0 0 0 3 &ipic 2 8 - 0 0 0 4 &ipic 2 8>; - sleep = <&pmc 0x000c0000>; - clock-frequency = <0>; - - pcie@0 { - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - reg = <0 0 0 0 0>; - ranges = <0x02000000 0 0xc8000000 - 0x02000000 0 0xc8000000 - 0 0x10000000 - 0x01000000 0 0x00000000 - 0x01000000 0 0x00000000 - 0 0x00800000>; - }; - }; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8379_mds.dts b/trunk/arch/powerpc/boot/dts/mpc8379_mds.dts index d6f208b8297a..acf06c438dbf 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8379_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8379_mds.dts @@ -127,38 +127,21 @@ reg = <0x200 0x100>; }; - sleep-nexus { + i2c@3000 { #address-cells = <1>; - #size-cells = <1>; - compatible = "simple-bus"; - sleep = <&pmc 0x0c000000>; - ranges; - - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <14 0x8>; - interrupt-parent = <&ipic>; - dfsrr; - - rtc@68 { - compatible = "dallas,ds1374"; - reg = <0x68>; - interrupts = <19 0x8>; - interrupt-parent = <&ipic>; - }; - }; + #size-cells = <0>; + cell-index = <0>; + compatible = "fsl-i2c"; + reg = <0x3000 0x100>; + interrupts = <14 0x8>; + interrupt-parent = <&ipic>; + dfsrr; - sdhci@2e000 { - compatible = "fsl,mpc8379-esdhc"; - reg = <0x2e000 0x1000>; - interrupts = <42 0x8>; + rtc@68 { + compatible = "dallas,ds1374"; + reg = <0x68>; + interrupts = <19 0x8>; interrupt-parent = <&ipic>; - /* Filled in by U-Boot */ - clock-frequency = <0>; }; }; @@ -230,83 +213,69 @@ interrupts = <38 0x8>; dr_mode = "host"; phy_type = "ulpi"; - sleep = <&pmc 0x00c00000>; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + phy2: ethernet-phy@2 { + interrupt-parent = <&ipic>; + interrupts = <17 0x8>; + reg = <0x2>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&ipic>; + interrupts = <18 0x8>; + reg = <0x3>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <32 0x8 33 0x8 34 0x8>; phy-connection-type = "mii"; interrupt-parent = <&ipic>; tbi-handle = <&tbi0>; phy-handle = <&phy2>; - sleep = <&pmc 0xc0000000>; - fsl,magic-packet; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy2: ethernet-phy@2 { - interrupt-parent = <&ipic>; - interrupts = <17 0x8>; - reg = <0x2>; - device_type = "ethernet-phy"; - }; - - phy3: ethernet-phy@3 { - interrupt-parent = <&ipic>; - interrupts = <18 0x8>; - reg = <0x3>; - device_type = "ethernet-phy"; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 0x8 36 0x8 37 0x8>; phy-connection-type = "mii"; interrupt-parent = <&ipic>; tbi-handle = <&tbi1>; phy-handle = <&phy3>; - sleep = <&pmc 0x30000000>; - fsl,magic-packet; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { @@ -339,7 +308,14 @@ fsl,channel-fifo-len = <24>; fsl,exec-units-mask = <0x9fe>; fsl,descriptor-types-mask = <0x3ab0ebf>; - sleep = <&pmc 0x03000000>; + }; + + sdhc@2e000 { + model = "eSDHC"; + compatible = "fsl,esdhc"; + reg = <0x2e000 0x1000>; + interrupts = <42 0x8>; + interrupt-parent = <&ipic>; }; sata@18000 { @@ -347,7 +323,6 @@ reg = <0x18000 0x1000>; interrupts = <44 0x8>; interrupt-parent = <&ipic>; - sleep = <&pmc 0x000000c0>; }; sata@19000 { @@ -355,7 +330,6 @@ reg = <0x19000 0x1000>; interrupts = <45 0x8>; interrupt-parent = <&ipic>; - sleep = <&pmc 0x00000030>; }; sata@1a000 { @@ -363,7 +337,6 @@ reg = <0x1a000 0x1000>; interrupts = <46 0x8>; interrupt-parent = <&ipic>; - sleep = <&pmc 0x0000000c>; }; sata@1b000 { @@ -371,7 +344,6 @@ reg = <0x1b000 0x1000>; interrupts = <47 0x8>; interrupt-parent = <&ipic>; - sleep = <&pmc 0x00000003>; }; /* IPIC @@ -387,13 +359,6 @@ #interrupt-cells = <2>; reg = <0x700 0x100>; }; - - pmc: power@b00 { - compatible = "fsl,mpc8379-pmc", "fsl,mpc8349-pmc"; - reg = <0xb00 0x100 0xa00 0x100>; - interrupts = <80 0x8>; - interrupt-parent = <&ipic>; - }; }; pci0: pci@e0008500 { @@ -448,7 +413,6 @@ ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000 0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>; - sleep = <&pmc 0x00010000>; clock-frequency = <0>; #interrupt-cells = <1>; #size-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/mpc8379_rdb.dts b/trunk/arch/powerpc/boot/dts/mpc8379_rdb.dts index 98ae95bd18f4..72cdc3c4c7e3 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8379_rdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8379_rdb.dts @@ -107,72 +107,26 @@ reg = <0x200 0x100>; }; - gpio1: gpio-controller@c00 { - #gpio-cells = <2>; - compatible = "fsl,mpc8379-gpio", "fsl,mpc8349-gpio"; - reg = <0xc00 0x100>; - interrupts = <74 0x8>; - interrupt-parent = <&ipic>; - gpio-controller; - }; - - gpio2: gpio-controller@d00 { - #gpio-cells = <2>; - compatible = "fsl,mpc8379-gpio", "fsl,mpc8349-gpio"; - reg = <0xd00 0x100>; - interrupts = <75 0x8>; - interrupt-parent = <&ipic>; - gpio-controller; - }; - - sleep-nexus { + i2c@3000 { #address-cells = <1>; - #size-cells = <1>; - compatible = "simple-bus"; - sleep = <&pmc 0x0c000000>; - ranges; - - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <14 0x8>; - interrupt-parent = <&ipic>; - dfsrr; - - dtt@48 { - compatible = "national,lm75"; - reg = <0x48>; - }; - - at24@50 { - compatible = "at24,24c256"; - reg = <0x50>; - }; - - rtc@68 { - compatible = "dallas,ds1339"; - reg = <0x68>; - }; - - mcu_pio: mcu@a { - #gpio-cells = <2>; - compatible = "fsl,mc9s08qg8-mpc8379erdb", - "fsl,mcu-mpc8349emitx"; - reg = <0x0a>; - gpio-controller; - }; + #size-cells = <0>; + cell-index = <0>; + compatible = "fsl-i2c"; + reg = <0x3000 0x100>; + interrupts = <14 0x8>; + interrupt-parent = <&ipic>; + dfsrr; + rtc@68 { + compatible = "dallas,ds1339"; + reg = <0x68>; }; - sdhci@2e000 { - compatible = "fsl,mpc8379-esdhc"; - reg = <0x2e000 0x1000>; - interrupts = <42 0x8>; - interrupt-parent = <&ipic>; - /* Filled in by U-Boot */ - clock-frequency = <0>; + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8379erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; }; }; @@ -243,76 +197,63 @@ interrupt-parent = <&ipic>; interrupts = <38 0x8>; phy_type = "ulpi"; - sleep = <&pmc 0x00c00000>; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + phy2: ethernet-phy@2 { + interrupt-parent = <&ipic>; + interrupts = <17 0x8>; + reg = <0x2>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <32 0x8 33 0x8 34 0x8>; phy-connection-type = "mii"; interrupt-parent = <&ipic>; tbi-handle = <&tbi0>; phy-handle = <&phy2>; - sleep = <&pmc 0xc0000000>; - fsl,magic-packet; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy2: ethernet-phy@2 { - interrupt-parent = <&ipic>; - interrupts = <17 0x8>; - reg = <0x2>; - device_type = "ethernet-phy"; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 0x8 36 0x8 37 0x8>; phy-connection-type = "mii"; interrupt-parent = <&ipic>; fixed-link = <1 1 1000 0 0>; tbi-handle = <&tbi1>; - sleep = <&pmc 0x30000000>; - fsl,magic-packet; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { @@ -345,7 +286,6 @@ fsl,channel-fifo-len = <24>; fsl,exec-units-mask = <0x9fe>; fsl,descriptor-types-mask = <0x3ab0ebf>; - sleep = <&pmc 0x03000000>; }; sata@18000 { @@ -353,7 +293,6 @@ reg = <0x18000 0x1000>; interrupts = <44 0x8>; interrupt-parent = <&ipic>; - sleep = <&pmc 0x000000c0>; }; sata@19000 { @@ -361,7 +300,6 @@ reg = <0x19000 0x1000>; interrupts = <45 0x8>; interrupt-parent = <&ipic>; - sleep = <&pmc 0x00000030>; }; sata@1a000 { @@ -369,7 +307,6 @@ reg = <0x1a000 0x1000>; interrupts = <46 0x8>; interrupt-parent = <&ipic>; - sleep = <&pmc 0x0000000c>; }; sata@1b000 { @@ -377,7 +314,6 @@ reg = <0x1b000 0x1000>; interrupts = <47 0x8>; interrupt-parent = <&ipic>; - sleep = <&pmc 0x00000003>; }; /* IPIC @@ -393,13 +329,6 @@ #interrupt-cells = <2>; reg = <0x700 0x100>; }; - - pmc: power@b00 { - compatible = "fsl,mpc8379-pmc", "fsl,mpc8349-pmc"; - reg = <0xb00 0x100 0xa00 0x100>; - interrupts = <80 0x8>; - interrupt-parent = <&ipic>; - }; }; pci0: pci@e0008500 { @@ -425,7 +354,6 @@ ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>; - sleep = <&pmc 0x00010000>; clock-frequency = <66666666>; #interrupt-cells = <1>; #size-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/mpc8536ds.dts b/trunk/arch/powerpc/boot/dts/mpc8536ds.dts index b31c5041350b..3c905df1812c 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8536ds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8536ds.dts @@ -137,6 +137,42 @@ }; }; + mdio@24520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <10 0x1>; + reg = <0>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <10 0x1>; + reg = <1>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@26520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x26520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + usb@22000 { compatible = "fsl,mpc8536-usb2-mph", "fsl-usb2-mph"; reg = <0x22000 0x1000>; @@ -158,73 +194,31 @@ }; enet0: ethernet@24000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy1>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <10 0x1>; - reg = <0>; - device_type = "ethernet-phy"; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <10 0x1>; - reg = <1>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <31 2 32 2 33 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy0>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; usb@2b000 { diff --git a/trunk/arch/powerpc/boot/dts/mpc8540ads.dts b/trunk/arch/powerpc/boot/dts/mpc8540ads.dts index ddd67be10b03..79570ffe41b9 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8540ads.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8540ads.dts @@ -126,106 +126,97 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <5 1>; + reg = <0x0>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <5 1>; + reg = <0x1>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&mpic>; + interrupts = <7 1>; + reg = <0x3>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@26520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x26520 0x20>; + + tbi2: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy0>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; - reg = <0x0>; - device_type = "ethernet-phy"; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; - reg = <0x1>; - device_type = "ethernet-phy"; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <7 1>; - reg = <0x3>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet2: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <2>; device_type = "network"; model = "FEC"; compatible = "gianfar"; reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <41 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi2>; phy-handle = <&phy3>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/mpc8541cds.dts b/trunk/arch/powerpc/boot/dts/mpc8541cds.dts index e45097f44fbd..221036a8ce23 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8541cds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8541cds.dts @@ -126,72 +126,66 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <5 1>; + reg = <0x0>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <5 1>; + reg = <0x1>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy0>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; - reg = <0x0>; - device_type = "ethernet-phy"; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; - reg = <0x1>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/mpc8544ds.dts b/trunk/arch/powerpc/boot/dts/mpc8544ds.dts index 7c6932be0197..0668d1048779 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8544ds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8544ds.dts @@ -98,6 +98,44 @@ dfsrr; }; + mdio@24520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <0x0>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <0x1>; + device_type = "ethernet-phy"; + }; + + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@26520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x26520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + dma@21300 { #address-cells = <1>; #size-cells = <1>; @@ -140,74 +178,31 @@ }; enet0: ethernet@24000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; phy-handle = <&phy0>; tbi-handle = <&tbi0>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0x0>; - device_type = "ethernet-phy"; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0x1>; - device_type = "ethernet-phy"; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <31 2 32 2 33 2>; interrupt-parent = <&mpic>; phy-handle = <&phy1>; tbi-handle = <&tbi1>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/mpc8548cds.dts b/trunk/arch/powerpc/boot/dts/mpc8548cds.dts index 804e90353293..df774a7088ff 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8548cds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8548cds.dts @@ -142,141 +142,129 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <5 1>; + reg = <0x0>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <5 1>; + reg = <0x1>; + device_type = "ethernet-phy"; + }; + phy2: ethernet-phy@2 { + interrupt-parent = <&mpic>; + interrupts = <5 1>; + reg = <0x2>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&mpic>; + interrupts = <5 1>; + reg = <0x3>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@26520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x26520 0x20>; + + tbi2: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@27520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x27520 0x20>; + + tbi3: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy0>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; - reg = <0x0>; - device_type = "ethernet-phy"; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; - reg = <0x1>; - device_type = "ethernet-phy"; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; - reg = <0x2>; - device_type = "ethernet-phy"; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; - reg = <0x3>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; /* eTSEC 3/4 are currently broken enet2: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <2>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <31 2 32 2 33 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi2>; phy-handle = <&phy2>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet3: ethernet@27000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <3>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x27000 0x1000>; - ranges = <0x0 0x27000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <37 2 38 2 39 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi3>; phy-handle = <&phy3>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi3: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; */ diff --git a/trunk/arch/powerpc/boot/dts/mpc8555cds.dts b/trunk/arch/powerpc/boot/dts/mpc8555cds.dts index 9484f0729b10..053b01e1c93b 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8555cds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8555cds.dts @@ -126,72 +126,66 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <5 1>; + reg = <0x0>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <5 1>; + reg = <0x1>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy0>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; - reg = <0x0>; - device_type = "ethernet-phy"; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; - reg = <0x1>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/mpc8560ads.dts b/trunk/arch/powerpc/boot/dts/mpc8560ads.dts index cc2acf87d02f..11b1bcbe14ce 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8560ads.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8560ads.dts @@ -115,84 +115,78 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <5 1>; + reg = <0x0>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <5 1>; + reg = <0x1>; + device_type = "ethernet-phy"; + }; + phy2: ethernet-phy@2 { + interrupt-parent = <&mpic>; + interrupts = <7 1>; + reg = <0x2>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&mpic>; + interrupts = <7 1>; + reg = <0x3>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy0>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; - reg = <0x0>; - device_type = "ethernet-phy"; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; - reg = <0x1>; - device_type = "ethernet-phy"; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <7 1>; - reg = <0x2>; - device_type = "ethernet-phy"; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <7 1>; - reg = <0x3>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; mpic: pic@40000 { diff --git a/trunk/arch/powerpc/boot/dts/mpc8568mds.dts b/trunk/arch/powerpc/boot/dts/mpc8568mds.dts index 9d52e3b25047..1955bd9e113d 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8568mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8568mds.dts @@ -149,84 +149,78 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@7 { + interrupt-parent = <&mpic>; + interrupts = <1 1>; + reg = <0x7>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <2 1>; + reg = <0x1>; + device_type = "ethernet-phy"; + }; + phy2: ethernet-phy@2 { + interrupt-parent = <&mpic>; + interrupts = <1 1>; + reg = <0x2>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&mpic>; + interrupts = <2 1>; + reg = <0x3>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy2>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@7 { - interrupt-parent = <&mpic>; - interrupts = <1 1>; - reg = <0x7>; - device_type = "ethernet-phy"; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <2 1>; - reg = <0x1>; - device_type = "ethernet-phy"; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <1 1>; - reg = <0x2>; - device_type = "ethernet-phy"; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <2 1>; - reg = <0x3>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy3>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/mpc8572ds.dts b/trunk/arch/powerpc/boot/dts/mpc8572ds.dts index 6e79a4169088..359c3b727420 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8572ds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8572ds.dts @@ -1,7 +1,7 @@ /* * MPC8572 DS Device Tree Source * - * Copyright 2007-2009 Freescale Semiconductor Inc. + * Copyright 2007, 2008 Freescale Semiconductor Inc. * * 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 @@ -312,141 +312,129 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <0x0>; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <0x1>; + }; + phy2: ethernet-phy@2 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <0x2>; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <0x3>; + }; + + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@26520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x26520 0x20>; + + tbi2: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@27520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x27520 0x20>; + + tbi3: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy0>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0x0>; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0x1>; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0x2>; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0x3>; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet2: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <2>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <31 2 32 2 33 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi2>; phy-handle = <&phy2>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet3: ethernet@27000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <3>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x27000 0x1000>; - ranges = <0x0 0x27000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <37 2 38 2 39 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi3>; phy-handle = <&phy3>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi3: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { @@ -655,7 +643,7 @@ 0x1000000 0x0 0x0 0x1000000 0x0 0x0 - 0x0 0x10000>; + 0x0 0x100000>; uli1575@0 { reg = <0x0 0x0 0x0 0x0 0x0>; #size-cells = <2>; @@ -666,7 +654,7 @@ 0x1000000 0x0 0x0 0x1000000 0x0 0x0 - 0x0 0x10000>; + 0x0 0x100000>; isa@1e { device_type = "isa"; #interrupt-cells = <2>; @@ -756,7 +744,7 @@ 0x1000000 0x0 0x0 0x1000000 0x0 0x0 - 0x0 0x10000>; + 0x0 0x100000>; }; }; @@ -793,7 +781,7 @@ 0x1000000 0x0 0x0 0x1000000 0x0 0x0 - 0x0 0x10000>; + 0x0 0x100000>; }; }; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8572ds_36b.dts b/trunk/arch/powerpc/boot/dts/mpc8572ds_36b.dts deleted file mode 100644 index dbd81a764742..000000000000 --- a/trunk/arch/powerpc/boot/dts/mpc8572ds_36b.dts +++ /dev/null @@ -1,799 +0,0 @@ -/* - * MPC8572 DS Device Tree Source - * - * Copyright 2007-2009 Freescale Semiconductor Inc. - * - * 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. - */ - -/dts-v1/; -/ { - model = "fsl,MPC8572DS"; - compatible = "fsl,MPC8572DS"; - #address-cells = <2>; - #size-cells = <2>; - - aliases { - ethernet0 = &enet0; - ethernet1 = &enet1; - ethernet2 = &enet2; - ethernet3 = &enet3; - serial0 = &serial0; - serial1 = &serial1; - pci0 = &pci0; - pci1 = &pci1; - pci2 = &pci2; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,8572@0 { - device_type = "cpu"; - reg = <0x0>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <0x8000>; // L1, 32K - i-cache-size = <0x8000>; // L1, 32K - timebase-frequency = <0>; - bus-frequency = <0>; - clock-frequency = <0>; - next-level-cache = <&L2>; - }; - - PowerPC,8572@1 { - device_type = "cpu"; - reg = <0x1>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <0x8000>; // L1, 32K - i-cache-size = <0x8000>; // L1, 32K - timebase-frequency = <0>; - bus-frequency = <0>; - clock-frequency = <0>; - next-level-cache = <&L2>; - }; - }; - - memory { - device_type = "memory"; - }; - - localbus@fffe05000 { - #address-cells = <2>; - #size-cells = <1>; - compatible = "fsl,mpc8572-elbc", "fsl,elbc", "simple-bus"; - reg = <0xf 0xffe05000 0 0x1000>; - interrupts = <19 2>; - interrupt-parent = <&mpic>; - - ranges = <0x0 0x0 0xf 0xe8000000 0x08000000 - 0x1 0x0 0xf 0xe0000000 0x08000000 - 0x2 0x0 0xf 0xffa00000 0x00040000 - 0x3 0x0 0xf 0xffdf0000 0x00008000 - 0x4 0x0 0xf 0xffa40000 0x00040000 - 0x5 0x0 0xf 0xffa80000 0x00040000 - 0x6 0x0 0xf 0xffac0000 0x00040000>; - - nor@0,0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "cfi-flash"; - reg = <0x0 0x0 0x8000000>; - bank-width = <2>; - device-width = <1>; - - ramdisk@0 { - reg = <0x0 0x03000000>; - read-only; - }; - - diagnostic@3000000 { - reg = <0x03000000 0x00e00000>; - read-only; - }; - - dink@3e00000 { - reg = <0x03e00000 0x00200000>; - read-only; - }; - - kernel@4000000 { - reg = <0x04000000 0x00400000>; - read-only; - }; - - jffs2@4400000 { - reg = <0x04400000 0x03b00000>; - }; - - dtb@7f00000 { - reg = <0x07f00000 0x00080000>; - read-only; - }; - - u-boot@7f80000 { - reg = <0x07f80000 0x00080000>; - read-only; - }; - }; - - nand@2,0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8572-fcm-nand", - "fsl,elbc-fcm-nand"; - reg = <0x2 0x0 0x40000>; - - u-boot@0 { - reg = <0x0 0x02000000>; - read-only; - }; - - jffs2@2000000 { - reg = <0x02000000 0x10000000>; - }; - - ramdisk@12000000 { - reg = <0x12000000 0x08000000>; - read-only; - }; - - kernel@1a000000 { - reg = <0x1a000000 0x04000000>; - }; - - dtb@1e000000 { - reg = <0x1e000000 0x01000000>; - read-only; - }; - - empty@1f000000 { - reg = <0x1f000000 0x21000000>; - }; - }; - - nand@4,0 { - compatible = "fsl,mpc8572-fcm-nand", - "fsl,elbc-fcm-nand"; - reg = <0x4 0x0 0x40000>; - }; - - nand@5,0 { - compatible = "fsl,mpc8572-fcm-nand", - "fsl,elbc-fcm-nand"; - reg = <0x5 0x0 0x40000>; - }; - - nand@6,0 { - compatible = "fsl,mpc8572-fcm-nand", - "fsl,elbc-fcm-nand"; - reg = <0x6 0x0 0x40000>; - }; - }; - - soc8572@fffe00000 { - #address-cells = <1>; - #size-cells = <1>; - device_type = "soc"; - compatible = "simple-bus"; - ranges = <0x0 0xf 0xffe00000 0x100000>; - reg = <0xf 0xffe00000 0 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed - bus-frequency = <0>; // Filled out by uboot. - - memory-controller@2000 { - compatible = "fsl,mpc8572-memory-controller"; - reg = <0x2000 0x1000>; - interrupt-parent = <&mpic>; - interrupts = <18 2>; - }; - - memory-controller@6000 { - compatible = "fsl,mpc8572-memory-controller"; - reg = <0x6000 0x1000>; - interrupt-parent = <&mpic>; - interrupts = <18 2>; - }; - - L2: l2-cache-controller@20000 { - compatible = "fsl,mpc8572-l2-cache-controller"; - reg = <0x20000 0x1000>; - cache-line-size = <32>; // 32 bytes - cache-size = <0x100000>; // L2, 1M - interrupt-parent = <&mpic>; - interrupts = <16 2>; - }; - - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <43 2>; - interrupt-parent = <&mpic>; - dfsrr; - }; - - i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <1>; - compatible = "fsl-i2c"; - reg = <0x3100 0x100>; - interrupts = <43 2>; - interrupt-parent = <&mpic>; - dfsrr; - }; - - dma@c300 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8572-dma", "fsl,eloplus-dma"; - reg = <0xc300 0x4>; - ranges = <0x0 0xc100 0x200>; - cell-index = <1>; - dma-channel@0 { - compatible = "fsl,mpc8572-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x0 0x80>; - cell-index = <0>; - interrupt-parent = <&mpic>; - interrupts = <76 2>; - }; - dma-channel@80 { - compatible = "fsl,mpc8572-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x80 0x80>; - cell-index = <1>; - interrupt-parent = <&mpic>; - interrupts = <77 2>; - }; - dma-channel@100 { - compatible = "fsl,mpc8572-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x100 0x80>; - cell-index = <2>; - interrupt-parent = <&mpic>; - interrupts = <78 2>; - }; - dma-channel@180 { - compatible = "fsl,mpc8572-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x180 0x80>; - cell-index = <3>; - interrupt-parent = <&mpic>; - interrupts = <79 2>; - }; - }; - - dma@21300 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8572-dma", "fsl,eloplus-dma"; - reg = <0x21300 0x4>; - ranges = <0x0 0x21100 0x200>; - cell-index = <0>; - dma-channel@0 { - compatible = "fsl,mpc8572-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x0 0x80>; - cell-index = <0>; - interrupt-parent = <&mpic>; - interrupts = <20 2>; - }; - dma-channel@80 { - compatible = "fsl,mpc8572-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x80 0x80>; - cell-index = <1>; - interrupt-parent = <&mpic>; - interrupts = <21 2>; - }; - dma-channel@100 { - compatible = "fsl,mpc8572-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x100 0x80>; - cell-index = <2>; - interrupt-parent = <&mpic>; - interrupts = <22 2>; - }; - dma-channel@180 { - compatible = "fsl,mpc8572-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x180 0x80>; - cell-index = <3>; - interrupt-parent = <&mpic>; - interrupts = <23 2>; - }; - }; - - enet0: ethernet@24000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <0>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <29 2 30 2 34 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi0>; - phy-handle = <&phy0>; - phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0x0>; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0x1>; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0x2>; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0x3>; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - }; - - enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <1>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <35 2 36 2 40 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi1>; - phy-handle = <&phy1>; - phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - }; - - enet2: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <2>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <31 2 32 2 33 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi2>; - phy-handle = <&phy2>; - phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - }; - - enet3: ethernet@27000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <3>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <0x27000 0x1000>; - ranges = <0x0 0x27000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <37 2 38 2 39 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi3>; - phy-handle = <&phy3>; - phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi3: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - }; - - serial0: serial@4500 { - cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <0x4500 0x100>; - clock-frequency = <0>; - interrupts = <42 2>; - interrupt-parent = <&mpic>; - }; - - serial1: serial@4600 { - cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <0x4600 0x100>; - clock-frequency = <0>; - interrupts = <42 2>; - interrupt-parent = <&mpic>; - }; - - global-utilities@e0000 { //global utilities block - compatible = "fsl,mpc8572-guts"; - reg = <0xe0000 0x1000>; - fsl,has-rstcr; - }; - - msi@41600 { - compatible = "fsl,mpc8572-msi", "fsl,mpic-msi"; - reg = <0x41600 0x80>; - msi-available-ranges = <0 0x100>; - interrupts = < - 0xe0 0 - 0xe1 0 - 0xe2 0 - 0xe3 0 - 0xe4 0 - 0xe5 0 - 0xe6 0 - 0xe7 0>; - interrupt-parent = <&mpic>; - }; - - crypto@30000 { - compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2", - "fsl,sec2.1", "fsl,sec2.0"; - reg = <0x30000 0x10000>; - interrupts = <45 2 58 2>; - interrupt-parent = <&mpic>; - fsl,num-channels = <4>; - fsl,channel-fifo-len = <24>; - fsl,exec-units-mask = <0x9fe>; - fsl,descriptor-types-mask = <0x3ab0ebf>; - }; - - mpic: pic@40000 { - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <0x40000 0x40000>; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - }; - }; - - pci0: pcie@fffe08000 { - cell-index = <0>; - compatible = "fsl,mpc8548-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <0xf 0xffe08000 0 0x1000>; - bus-range = <0 255>; - ranges = <0x2000000 0x0 0xc0000000 0xc 0x00000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x00010000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <24 2>; - interrupt-map-mask = <0xff00 0x0 0x0 0x7>; - interrupt-map = < - /* IDSEL 0x11 func 0 - PCI slot 1 */ - 0x8800 0x0 0x0 0x1 &mpic 0x2 0x1 - 0x8800 0x0 0x0 0x2 &mpic 0x3 0x1 - 0x8800 0x0 0x0 0x3 &mpic 0x4 0x1 - 0x8800 0x0 0x0 0x4 &mpic 0x1 0x1 - - /* IDSEL 0x11 func 1 - PCI slot 1 */ - 0x8900 0x0 0x0 0x1 &mpic 0x2 0x1 - 0x8900 0x0 0x0 0x2 &mpic 0x3 0x1 - 0x8900 0x0 0x0 0x3 &mpic 0x4 0x1 - 0x8900 0x0 0x0 0x4 &mpic 0x1 0x1 - - /* IDSEL 0x11 func 2 - PCI slot 1 */ - 0x8a00 0x0 0x0 0x1 &mpic 0x2 0x1 - 0x8a00 0x0 0x0 0x2 &mpic 0x3 0x1 - 0x8a00 0x0 0x0 0x3 &mpic 0x4 0x1 - 0x8a00 0x0 0x0 0x4 &mpic 0x1 0x1 - - /* IDSEL 0x11 func 3 - PCI slot 1 */ - 0x8b00 0x0 0x0 0x1 &mpic 0x2 0x1 - 0x8b00 0x0 0x0 0x2 &mpic 0x3 0x1 - 0x8b00 0x0 0x0 0x3 &mpic 0x4 0x1 - 0x8b00 0x0 0x0 0x4 &mpic 0x1 0x1 - - /* IDSEL 0x11 func 4 - PCI slot 1 */ - 0x8c00 0x0 0x0 0x1 &mpic 0x2 0x1 - 0x8c00 0x0 0x0 0x2 &mpic 0x3 0x1 - 0x8c00 0x0 0x0 0x3 &mpic 0x4 0x1 - 0x8c00 0x0 0x0 0x4 &mpic 0x1 0x1 - - /* IDSEL 0x11 func 5 - PCI slot 1 */ - 0x8d00 0x0 0x0 0x1 &mpic 0x2 0x1 - 0x8d00 0x0 0x0 0x2 &mpic 0x3 0x1 - 0x8d00 0x0 0x0 0x3 &mpic 0x4 0x1 - 0x8d00 0x0 0x0 0x4 &mpic 0x1 0x1 - - /* IDSEL 0x11 func 6 - PCI slot 1 */ - 0x8e00 0x0 0x0 0x1 &mpic 0x2 0x1 - 0x8e00 0x0 0x0 0x2 &mpic 0x3 0x1 - 0x8e00 0x0 0x0 0x3 &mpic 0x4 0x1 - 0x8e00 0x0 0x0 0x4 &mpic 0x1 0x1 - - /* IDSEL 0x11 func 7 - PCI slot 1 */ - 0x8f00 0x0 0x0 0x1 &mpic 0x2 0x1 - 0x8f00 0x0 0x0 0x2 &mpic 0x3 0x1 - 0x8f00 0x0 0x0 0x3 &mpic 0x4 0x1 - 0x8f00 0x0 0x0 0x4 &mpic 0x1 0x1 - - /* IDSEL 0x12 func 0 - PCI slot 2 */ - 0x9000 0x0 0x0 0x1 &mpic 0x3 0x1 - 0x9000 0x0 0x0 0x2 &mpic 0x4 0x1 - 0x9000 0x0 0x0 0x3 &mpic 0x1 0x1 - 0x9000 0x0 0x0 0x4 &mpic 0x2 0x1 - - /* IDSEL 0x12 func 1 - PCI slot 2 */ - 0x9100 0x0 0x0 0x1 &mpic 0x3 0x1 - 0x9100 0x0 0x0 0x2 &mpic 0x4 0x1 - 0x9100 0x0 0x0 0x3 &mpic 0x1 0x1 - 0x9100 0x0 0x0 0x4 &mpic 0x2 0x1 - - /* IDSEL 0x12 func 2 - PCI slot 2 */ - 0x9200 0x0 0x0 0x1 &mpic 0x3 0x1 - 0x9200 0x0 0x0 0x2 &mpic 0x4 0x1 - 0x9200 0x0 0x0 0x3 &mpic 0x1 0x1 - 0x9200 0x0 0x0 0x4 &mpic 0x2 0x1 - - /* IDSEL 0x12 func 3 - PCI slot 2 */ - 0x9300 0x0 0x0 0x1 &mpic 0x3 0x1 - 0x9300 0x0 0x0 0x2 &mpic 0x4 0x1 - 0x9300 0x0 0x0 0x3 &mpic 0x1 0x1 - 0x9300 0x0 0x0 0x4 &mpic 0x2 0x1 - - /* IDSEL 0x12 func 4 - PCI slot 2 */ - 0x9400 0x0 0x0 0x1 &mpic 0x3 0x1 - 0x9400 0x0 0x0 0x2 &mpic 0x4 0x1 - 0x9400 0x0 0x0 0x3 &mpic 0x1 0x1 - 0x9400 0x0 0x0 0x4 &mpic 0x2 0x1 - - /* IDSEL 0x12 func 5 - PCI slot 2 */ - 0x9500 0x0 0x0 0x1 &mpic 0x3 0x1 - 0x9500 0x0 0x0 0x2 &mpic 0x4 0x1 - 0x9500 0x0 0x0 0x3 &mpic 0x1 0x1 - 0x9500 0x0 0x0 0x4 &mpic 0x2 0x1 - - /* IDSEL 0x12 func 6 - PCI slot 2 */ - 0x9600 0x0 0x0 0x1 &mpic 0x3 0x1 - 0x9600 0x0 0x0 0x2 &mpic 0x4 0x1 - 0x9600 0x0 0x0 0x3 &mpic 0x1 0x1 - 0x9600 0x0 0x0 0x4 &mpic 0x2 0x1 - - /* IDSEL 0x12 func 7 - PCI slot 2 */ - 0x9700 0x0 0x0 0x1 &mpic 0x3 0x1 - 0x9700 0x0 0x0 0x2 &mpic 0x4 0x1 - 0x9700 0x0 0x0 0x3 &mpic 0x1 0x1 - 0x9700 0x0 0x0 0x4 &mpic 0x2 0x1 - - // IDSEL 0x1c USB - 0xe000 0x0 0x0 0x1 &i8259 0xc 0x2 - 0xe100 0x0 0x0 0x2 &i8259 0x9 0x2 - 0xe200 0x0 0x0 0x3 &i8259 0xa 0x2 - 0xe300 0x0 0x0 0x4 &i8259 0xb 0x2 - - // IDSEL 0x1d Audio - 0xe800 0x0 0x0 0x1 &i8259 0x6 0x2 - - // IDSEL 0x1e Legacy - 0xf000 0x0 0x0 0x1 &i8259 0x7 0x2 - 0xf100 0x0 0x0 0x1 &i8259 0x7 0x2 - - // IDSEL 0x1f IDE/SATA - 0xf800 0x0 0x0 0x1 &i8259 0xe 0x2 - 0xf900 0x0 0x0 0x1 &i8259 0x5 0x2 - - >; - - pcie@0 { - reg = <0x0 0x0 0x0 0x0 0x0>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - ranges = <0x2000000 0x0 0xc0000000 - 0x2000000 0x0 0xc0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x10000>; - uli1575@0 { - reg = <0x0 0x0 0x0 0x0 0x0>; - #size-cells = <2>; - #address-cells = <3>; - ranges = <0x2000000 0x0 0xc0000000 - 0x2000000 0x0 0xc0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x10000>; - isa@1e { - device_type = "isa"; - #interrupt-cells = <2>; - #size-cells = <1>; - #address-cells = <2>; - reg = <0xf000 0x0 0x0 0x0 0x0>; - ranges = <0x1 0x0 0x1000000 0x0 0x0 - 0x1000>; - interrupt-parent = <&i8259>; - - i8259: interrupt-controller@20 { - reg = <0x1 0x20 0x2 - 0x1 0xa0 0x2 - 0x1 0x4d0 0x2>; - interrupt-controller; - device_type = "interrupt-controller"; - #address-cells = <0>; - #interrupt-cells = <2>; - compatible = "chrp,iic"; - interrupts = <9 2>; - interrupt-parent = <&mpic>; - }; - - i8042@60 { - #size-cells = <0>; - #address-cells = <1>; - reg = <0x1 0x60 0x1 0x1 0x64 0x1>; - interrupts = <1 3 12 3>; - interrupt-parent = - <&i8259>; - - keyboard@0 { - reg = <0x0>; - compatible = "pnpPNP,303"; - }; - - mouse@1 { - reg = <0x1>; - compatible = "pnpPNP,f03"; - }; - }; - - rtc@70 { - compatible = "pnpPNP,b00"; - reg = <0x1 0x70 0x2>; - }; - - gpio@400 { - reg = <0x1 0x400 0x80>; - }; - }; - }; - }; - - }; - - pci1: pcie@fffe09000 { - cell-index = <1>; - compatible = "fsl,mpc8548-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <0xf 0xffe09000 0 0x1000>; - bus-range = <0 255>; - ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x00010000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <25 2>; - interrupt-map-mask = <0xf800 0x0 0x0 0x7>; - interrupt-map = < - /* IDSEL 0x0 */ - 0000 0x0 0x0 0x1 &mpic 0x4 0x1 - 0000 0x0 0x0 0x2 &mpic 0x5 0x1 - 0000 0x0 0x0 0x3 &mpic 0x6 0x1 - 0000 0x0 0x0 0x4 &mpic 0x7 0x1 - >; - pcie@0 { - reg = <0x0 0x0 0x0 0x0 0x0>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - ranges = <0x2000000 0x0 0xc0000000 - 0x2000000 0x0 0xc0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x10000>; - }; - }; - - pci2: pcie@fffe0a000 { - cell-index = <2>; - compatible = "fsl,mpc8548-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <0xf 0xffe0a000 0 0x1000>; - bus-range = <0 255>; - ranges = <0x2000000 0x0 0xc0000000 0xc 0x40000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0xf 0xffc20000 0x0 0x00010000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <26 2>; - interrupt-map-mask = <0xf800 0x0 0x0 0x7>; - interrupt-map = < - /* IDSEL 0x0 */ - 0000 0x0 0x0 0x1 &mpic 0x0 0x1 - 0000 0x0 0x0 0x2 &mpic 0x1 0x1 - 0000 0x0 0x0 0x3 &mpic 0x2 0x1 - 0000 0x0 0x0 0x4 &mpic 0x3 0x1 - >; - pcie@0 { - reg = <0x0 0x0 0x0 0x0 0x0>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - ranges = <0x2000000 0x0 0xc0000000 - 0x2000000 0x0 0xc0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x10000>; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts b/trunk/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts index 2bc0c7189653..fd462efa9e61 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts @@ -6,7 +6,7 @@ * This dts file allows core0 to have memory, l2, i2c, dma1, global-util, eth0, * eth1, crypto, pci0, pci1. * - * Copyright 2007-2009 Freescale Semiconductor Inc. + * Copyright 2007, 2008 Freescale Semiconductor Inc. * * 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 @@ -148,38 +148,35 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <0x0>; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <0x1>; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; phy-handle = <&phy0>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0x0>; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0x1>; - }; - }; }; enet1: ethernet@25000 { @@ -230,7 +227,7 @@ device_type = "open-pic"; protected-sources = < 31 32 33 37 38 39 /* enet2 enet3 */ - 76 77 78 79 26 42 /* dma2 pci2 serial*/ + 76 77 78 79 27 42 /* dma2 pci2 serial*/ 0xe0 0xe1 0xe2 0xe3 /* msi */ 0xe4 0xe5 0xe6 0xe7 >; @@ -379,7 +376,7 @@ 0x1000000 0x0 0x0 0x1000000 0x0 0x0 - 0x0 0x10000>; + 0x0 0x100000>; uli1575@0 { reg = <0x0 0x0 0x0 0x0 0x0>; #size-cells = <2>; @@ -390,7 +387,7 @@ 0x1000000 0x0 0x0 0x1000000 0x0 0x0 - 0x0 0x10000>; + 0x0 0x100000>; isa@1e { device_type = "isa"; #interrupt-cells = <2>; @@ -480,7 +477,7 @@ 0x1000000 0x0 0x0 0x1000000 0x0 0x0 - 0x0 0x10000>; + 0x0 0x100000>; }; }; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts b/trunk/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts index 159cb3a875f0..e35230f2ac93 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts @@ -7,7 +7,7 @@ * * Please note to add "-b 1" for core1's dts compiling. * - * Copyright 2007-2009 Freescale Semiconductor Inc. + * Copyright 2007, 2008 Freescale Semiconductor Inc. * * 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 @@ -186,7 +186,7 @@ protected-sources = < 18 16 10 42 45 58 /* MEM L2 mdio serial crypto */ 29 30 34 35 36 40 /* enet0 enet1 */ - 24 25 20 21 22 23 /* pci0 pci1 dma1 */ + 24 26 20 21 22 23 /* pcie0 pcie1 dma1 */ 43 /* i2c */ 0x1 0x2 0x3 0x4 /* pci slot */ 0x9 0xa 0xb 0xc /* usb */ @@ -228,7 +228,7 @@ 0x1000000 0x0 0x0 0x1000000 0x0 0x0 - 0x0 0x10000>; + 0x0 0x100000>; }; }; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts b/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts index 1bd3ebe11437..f724d72c7b92 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts @@ -217,7 +217,6 @@ codec-handle = <&cs4270>; fsl,playback-dma = <&dma00>; fsl,capture-dma = <&dma01>; - fsl,fifo-depth = <8>; }; ssi@16100 { @@ -226,7 +225,6 @@ reg = <0x16100 0x100>; interrupt-parent = <&mpic>; interrupts = <63 2>; - fsl,fifo-depth = <8>; }; dma@21300 { diff --git a/trunk/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/trunk/arch/powerpc/boot/dts/mpc8641_hpcn.dts index d72beb192460..4481532cbe77 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8641_hpcn.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8641_hpcn.dts @@ -180,144 +180,133 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <0>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <1>; + device_type = "ethernet-phy"; + }; + phy2: ethernet-phy@2 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <2>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <3>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@26520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x26520 0x20>; + + tbi2: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@27520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x27520 0x20>; + + tbi3: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy0>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0>; - device_type = "ethernet-phy"; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <1>; - device_type = "ethernet-phy"; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <2>; - device_type = "ethernet-phy"; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <3>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet2: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <2>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <31 2 32 2 33 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi2>; phy-handle = <&phy2>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet3: ethernet@27000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <3>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x27000 0x1000>; - ranges = <0x0 0x27000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <37 2 38 2 39 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi3>; phy-handle = <&phy3>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi3: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/pcm030.dts b/trunk/arch/powerpc/boot/dts/pcm030.dts index 895834713894..be2c11ca0594 100644 --- a/trunk/arch/powerpc/boot/dts/pcm030.dts +++ b/trunk/arch/powerpc/boot/dts/pcm030.dts @@ -19,7 +19,6 @@ compatible = "phytec,pcm030"; #address-cells = <1>; #size-cells = <1>; - interrupt-parent = <&mpc5200_pic>; cpus { #address-cells = <1>; @@ -30,26 +29,26 @@ reg = <0>; d-cache-line-size = <32>; i-cache-line-size = <32>; - d-cache-size = <0x4000>; // L1, 16K - i-cache-size = <0x4000>; // L1, 16K - timebase-frequency = <0>; // from bootloader - bus-frequency = <0>; // from bootloader - clock-frequency = <0>; // from bootloader + d-cache-size = <0x4000>; /* L1, 16K */ + i-cache-size = <0x4000>; /* L1, 16K */ + timebase-frequency = <0>; /* From Bootloader */ + bus-frequency = <0>; /* From Bootloader */ + clock-frequency = <0>; /* From Bootloader */ }; }; memory { device_type = "memory"; - reg = <0x00000000 0x04000000>; // 64MB + reg = <0x00000000 0x04000000>; /* 64MB */ }; soc5200@f0000000 { #address-cells = <1>; #size-cells = <1>; compatible = "fsl,mpc5200b-immr"; - ranges = <0 0xf0000000 0x0000c000>; - bus-frequency = <0>; // from bootloader - system-frequency = <0>; // from bootloader + ranges = <0x0 0xf0000000 0x0000c000>; + bus-frequency = <0>; /* From bootloader */ + system-frequency = <0>; /* From bootloader */ cdm@200 { compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm"; @@ -57,70 +56,87 @@ }; mpc5200_pic: interrupt-controller@500 { - // 5200 interrupts are encoded into two levels; + /* 5200 interrupts are encoded into two levels; */ interrupt-controller; #interrupt-cells = <3>; + device_type = "interrupt-controller"; compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; reg = <0x500 0x80>; }; - timer@600 { // General Purpose Timer + timer@600 { /* General Purpose Timer */ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + cell-index = <0>; reg = <0x600 0x10>; - interrupts = <1 9 0>; + interrupts = <0x1 0x9 0x0>; + interrupt-parent = <&mpc5200_pic>; fsl,has-wdt; }; - timer@610 { // General Purpose Timer + timer@610 { /* General Purpose Timer */ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; + cell-index = <1>; reg = <0x610 0x10>; - interrupts = <1 10 0>; + interrupts = <0x1 0xa 0x0>; + interrupt-parent = <&mpc5200_pic>; }; - gpt2: timer@620 { // General Purpose Timer in GPIO mode + gpt2: timer@620 { /* General Purpose Timer in GPIO mode */ compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio"; + cell-index = <2>; reg = <0x620 0x10>; - interrupts = <1 11 0>; + interrupts = <0x1 0xb 0x0>; + interrupt-parent = <&mpc5200_pic>; gpio-controller; #gpio-cells = <2>; }; - gpt3: timer@630 { // General Purpose Timer in GPIO mode + gpt3: timer@630 { /* General Purpose Timer in GPIO mode */ compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio"; + cell-index = <3>; reg = <0x630 0x10>; - interrupts = <1 12 0>; + interrupts = <0x1 0xc 0x0>; + interrupt-parent = <&mpc5200_pic>; gpio-controller; #gpio-cells = <2>; }; - gpt4: timer@640 { // General Purpose Timer in GPIO mode + gpt4: timer@640 { /* General Purpose Timer in GPIO mode */ compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio"; + cell-index = <4>; reg = <0x640 0x10>; - interrupts = <1 13 0>; + interrupts = <0x1 0xd 0x0>; + interrupt-parent = <&mpc5200_pic>; gpio-controller; #gpio-cells = <2>; }; - gpt5: timer@650 { // General Purpose Timer in GPIO mode + gpt5: timer@650 { /* General Purpose Timer in GPIO mode */ compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio"; + cell-index = <5>; reg = <0x650 0x10>; - interrupts = <1 14 0>; + interrupts = <0x1 0xe 0x0>; + interrupt-parent = <&mpc5200_pic>; gpio-controller; #gpio-cells = <2>; }; - gpt6: timer@660 { // General Purpose Timer in GPIO mode + gpt6: timer@660 { /* General Purpose Timer in GPIO mode */ compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio"; + cell-index = <6>; reg = <0x660 0x10>; - interrupts = <1 15 0>; + interrupts = <0x1 0xf 0x0>; + interrupt-parent = <&mpc5200_pic>; gpio-controller; #gpio-cells = <2>; }; - gpt7: timer@670 { // General Purpose Timer in GPIO mode + gpt7: timer@670 { /* General Purpose Timer in GPIO mode */ compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio"; + cell-index = <7>; reg = <0x670 0x10>; - interrupts = <1 16 0>; + interrupts = <0x1 0x10 0x0>; + interrupt-parent = <&mpc5200_pic>; gpio-controller; #gpio-cells = <2>; }; @@ -128,33 +144,40 @@ rtc@800 { // Real time clock compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; reg = <0x800 0x100>; - interrupts = <1 5 0 1 6 0>; + interrupts = <0x1 0x5 0x0 0x1 0x6 0x0>; + interrupt-parent = <&mpc5200_pic>; }; can@900 { compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; - interrupts = <2 17 0>; + cell-index = <0>; + interrupts = <0x2 0x11 0x0>; + interrupt-parent = <&mpc5200_pic>; reg = <0x900 0x80>; }; can@980 { compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; - interrupts = <2 18 0>; + cell-index = <1>; + interrupts = <0x2 0x12 0x0>; + interrupt-parent = <&mpc5200_pic>; reg = <0x980 0x80>; }; gpio_simple: gpio@b00 { compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; reg = <0xb00 0x40>; - interrupts = <1 7 0>; + interrupts = <0x1 0x7 0x0>; + interrupt-parent = <&mpc5200_pic>; gpio-controller; #gpio-cells = <2>; }; - gpio_wkup: gpio@c00 { + gpio_wkup: gpio-wkup@c00 { compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; reg = <0xc00 0x40>; - interrupts = <1 8 0 0 3 0>; + interrupts = <0x1 0x8 0x0 0x0 0x3 0x0>; + interrupt-parent = <&mpc5200_pic>; gpio-controller; #gpio-cells = <2>; }; @@ -162,22 +185,26 @@ spi@f00 { compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; reg = <0xf00 0x20>; - interrupts = <2 13 0 2 14 0>; + interrupts = <0x2 0xd 0x0 0x2 0xe 0x0>; + interrupt-parent = <&mpc5200_pic>; }; usb@1000 { compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; reg = <0x1000 0xff>; - interrupts = <2 6 0>; + interrupts = <0x2 0x6 0x0>; + interrupt-parent = <&mpc5200_pic>; }; dma-controller@1200 { + device_type = "dma-controller"; compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; reg = <0x1200 0x80>; - interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 - 3 4 0 3 5 0 3 6 0 3 7 0 - 3 8 0 3 9 0 3 10 0 3 11 0 - 3 12 0 3 13 0 3 14 0 3 15 0>; + interrupts = <0x3 0x0 0x0 0x3 0x1 0x0 0x3 0x2 0x0 0x3 0x3 0x0 + 0x3 0x4 0x0 0x3 0x5 0x0 0x3 0x6 0x0 0x3 0x7 0x0 + 0x3 0x8 0x0 0x3 0x9 0x0 0x3 0xa 0x0 0x3 0xb 0x0 + 0x3 0xc 0x0 0x3 0xd 0x0 0x3 0xe 0x0 0x3 0xf 0x0>; + interrupt-parent = <&mpc5200_pic>; }; xlb@1f00 { @@ -186,19 +213,24 @@ }; ac97@2000 { /* PSC1 in ac97 mode */ + device_type = "sound"; compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97"; cell-index = <0>; reg = <0x2000 0x100>; - interrupts = <2 1 0>; + interrupts = <0x2 0x2 0x0>; + interrupt-parent = <&mpc5200_pic>; }; /* PSC2 port is used by CAN1/2 */ serial@2400 { /* PSC3 in UART mode */ + device_type = "serial"; compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + port-number = <0>; cell-index = <2>; reg = <0x2400 0x100>; - interrupts = <2 3 0>; + interrupts = <0x2 0x3 0x0>; + interrupt-parent = <&mpc5200_pic>; }; /* PSC4 is ??? */ @@ -206,44 +238,55 @@ /* PSC5 is ??? */ serial@2c00 { /* PSC6 in UART mode */ + device_type = "serial"; compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; + port-number = <1>; cell-index = <5>; reg = <0x2c00 0x100>; - interrupts = <2 4 0>; + interrupts = <0x2 0x4 0x0>; + interrupt-parent = <&mpc5200_pic>; }; ethernet@3000 { + device_type = "network"; compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; reg = <0x3000 0x400>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <2 5 0>; + local-mac-address = [00 00 00 00 00 00]; + interrupts = <0x2 0x5 0x0>; + interrupt-parent = <&mpc5200_pic>; phy-handle = <&phy0>; }; mdio@3000 { #address-cells = <1>; #size-cells = <0>; - compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; - reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts - interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. - - phy0: ethernet-phy@0 { - reg = <0>; + compatible = "fsl,mpc5200b-mdio", "fsl,mpc5200-mdio"; + reg = <0x3000 0x400>; /* fec range, since we need to setup fec interrupts */ + interrupts = <0x2 0x5 0x0>; /* these are for "mii command finished", not link changes & co. */ + interrupt-parent = <&mpc5200_pic>; + + phy0:ethernet-phy@0 { + device_type = "ethernet-phy"; + reg = <0x0>; }; }; ata@3a00 { + device_type = "ata"; compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; reg = <0x3a00 0x100>; - interrupts = <2 7 0>; + interrupts = <0x2 0x7 0x0>; + interrupt-parent = <&mpc5200_pic>; }; i2c@3d00 { #address-cells = <1>; #size-cells = <0>; compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + cell-index = <0>; reg = <0x3d00 0x40>; - interrupts = <2 15 0>; + interrupts = <0x2 0xf 0x0>; + interrupt-parent = <&mpc5200_pic>; fsl5200-clocking; }; @@ -251,8 +294,10 @@ #address-cells = <1>; #size-cells = <0>; compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + cell-index = <1>; reg = <0x3d40 0x40>; - interrupts = <2 16 0>; + interrupts = <0x2 0x10 0x0>; + interrupt-parent = <&mpc5200_pic>; fsl5200-clocking; rtc@51 { compatible = "nxp,pcf8563"; @@ -262,7 +307,7 @@ }; sram@8000 { - compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram"; + compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram","sram"; reg = <0x8000 0x4000>; }; @@ -295,21 +340,22 @@ device_type = "pci"; compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci"; reg = <0xf0000d00 0x100>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3 // 1st slot - 0xc000 0 0 2 &mpc5200_pic 1 1 3 - 0xc000 0 0 3 &mpc5200_pic 1 2 3 - 0xc000 0 0 4 &mpc5200_pic 1 3 3 - - 0xc800 0 0 1 &mpc5200_pic 1 1 3 // 2nd slot - 0xc800 0 0 2 &mpc5200_pic 1 2 3 - 0xc800 0 0 3 &mpc5200_pic 1 3 3 - 0xc800 0 0 4 &mpc5200_pic 0 0 3>; + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; + interrupt-map = <0xc000 0x0 0x0 0x1 &mpc5200_pic 0x0 0x0 0x3 /* 1st slot */ + 0xc000 0x0 0x0 0x2 &mpc5200_pic 0x1 0x1 0x3 + 0xc000 0x0 0x0 0x3 &mpc5200_pic 0x1 0x2 0x3 + 0xc000 0x0 0x0 0x4 &mpc5200_pic 0x1 0x3 0x3 + + 0xc800 0x0 0x0 0x1 &mpc5200_pic 0x1 0x1 0x3 /* 2nd slot */ + 0xc800 0x0 0x0 0x2 &mpc5200_pic 0x1 0x2 0x3 + 0xc800 0x0 0x0 0x3 &mpc5200_pic 0x1 0x3 0x3 + 0xc800 0x0 0x0 0x4 &mpc5200_pic 0x0 0x0 0x3>; clock-frequency = <0>; // From boot loader - interrupts = <2 8 0 2 9 0 2 10 0>; + interrupts = <0x2 0x8 0x0 0x2 0x9 0x0 0x2 0xa 0x0>; + interrupt-parent = <&mpc5200_pic>; bus-range = <0 0>; - ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000 - 0x02000000 0 0xa0000000 0xa0000000 0 0x10000000 - 0x01000000 0 0x00000000 0xb0000000 0 0x01000000>; + ranges = <0x42000000 0x0 0x80000000 0x80000000 0x0 0x20000000 + 0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000 + 0x01000000 0x0 0x00000000 0xb0000000 0x0 0x01000000>; }; }; diff --git a/trunk/arch/powerpc/boot/dts/pcm032.dts b/trunk/arch/powerpc/boot/dts/pcm032.dts deleted file mode 100644 index 030042678392..000000000000 --- a/trunk/arch/powerpc/boot/dts/pcm032.dts +++ /dev/null @@ -1,392 +0,0 @@ -/* - * phyCORE-MPC5200B-IO (pcm032) board Device Tree Source - * - * Copyright (C) 2006-2009 Pengutronix - * Sascha Hauer - * Juergen Beisert - * Wolfram Sang - * - * 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. - */ - -/dts-v1/; - -/ { - model = "phytec,pcm032"; - compatible = "phytec,pcm032"; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&mpc5200_pic>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,5200@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; - i-cache-line-size = <32>; - d-cache-size = <0x4000>; // L1, 16K - i-cache-size = <0x4000>; // L1, 16K - timebase-frequency = <0>; // from bootloader - bus-frequency = <0>; // from bootloader - clock-frequency = <0>; // from bootloader - }; - }; - - memory { - device_type = "memory"; - reg = <0x00000000 0x08000000>; // 128MB - }; - - soc5200@f0000000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc5200b-immr"; - ranges = <0 0xf0000000 0x0000c000>; - bus-frequency = <0>; // from bootloader - system-frequency = <0>; // from bootloader - - cdm@200 { - compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm"; - reg = <0x200 0x38>; - }; - - mpc5200_pic: interrupt-controller@500 { - // 5200 interrupts are encoded into two levels; - interrupt-controller; - #interrupt-cells = <3>; - compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic"; - reg = <0x500 0x80>; - }; - - timer@600 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x600 0x10>; - interrupts = <1 9 0>; - fsl,has-wdt; - }; - - timer@610 { // General Purpose Timer - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x610 0x10>; - interrupts = <1 10 0>; - }; - - gpt2: timer@620 { // General Purpose Timer in GPIO mode - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x620 0x10>; - interrupts = <1 11 0>; - gpio-controller; - #gpio-cells = <2>; - }; - - gpt3: timer@630 { // General Purpose Timer in GPIO mode - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x630 0x10>; - interrupts = <1 12 0>; - gpio-controller; - #gpio-cells = <2>; - }; - - gpt4: timer@640 { // General Purpose Timer in GPIO mode - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x640 0x10>; - interrupts = <1 13 0>; - gpio-controller; - #gpio-cells = <2>; - }; - - gpt5: timer@650 { // General Purpose Timer in GPIO mode - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x650 0x10>; - interrupts = <1 14 0>; - gpio-controller; - #gpio-cells = <2>; - }; - - gpt6: timer@660 { // General Purpose Timer in GPIO mode - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x660 0x10>; - interrupts = <1 15 0>; - gpio-controller; - #gpio-cells = <2>; - }; - - gpt7: timer@670 { // General Purpose Timer in GPIO mode - compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; - reg = <0x670 0x10>; - interrupts = <1 16 0>; - gpio-controller; - #gpio-cells = <2>; - }; - - rtc@800 { // Real time clock - compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc"; - reg = <0x800 0x100>; - interrupts = <1 5 0 1 6 0>; - }; - - can@900 { - compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; - interrupts = <2 17 0>; - reg = <0x900 0x80>; - }; - - can@980 { - compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan"; - interrupts = <2 18 0>; - reg = <0x980 0x80>; - }; - - gpio_simple: gpio@b00 { - compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio"; - reg = <0xb00 0x40>; - interrupts = <1 7 0>; - gpio-controller; - #gpio-cells = <2>; - }; - - gpio_wkup: gpio@c00 { - compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup"; - reg = <0xc00 0x40>; - interrupts = <1 8 0 0 3 0>; - gpio-controller; - #gpio-cells = <2>; - }; - - spi@f00 { - compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; - reg = <0xf00 0x20>; - interrupts = <2 13 0 2 14 0>; - }; - - usb@1000 { - compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be"; - reg = <0x1000 0xff>; - interrupts = <2 6 0>; - }; - - dma-controller@1200 { - compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm"; - reg = <0x1200 0x80>; - interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 - 3 4 0 3 5 0 3 6 0 3 7 0 - 3 8 0 3 9 0 3 10 0 3 11 0 - 3 12 0 3 13 0 3 14 0 3 15 0>; - }; - - xlb@1f00 { - compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb"; - reg = <0x1f00 0x100>; - }; - - ac97@2000 { /* PSC1 is ac97 */ - compatible = "fsl,mpc5200b-psc-ac97","fsl,mpc5200-psc-ac97"; - cell-index = <0>; - reg = <0x2000 0x100>; - interrupts = <2 1 0>; - }; - - /* PSC2 port is used by CAN1/2 */ - - serial@2400 { /* PSC3 in UART mode */ - compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; - cell-index = <2>; - reg = <0x2400 0x100>; - interrupts = <2 3 0>; - }; - - /* PSC4 is ??? */ - - /* PSC5 is ??? */ - - serial@2c00 { /* PSC6 in UART mode */ - compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart"; - cell-index = <5>; - reg = <0x2c00 0x100>; - interrupts = <2 4 0>; - }; - - ethernet@3000 { - compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec"; - reg = <0x3000 0x400>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <2 5 0>; - phy-handle = <&phy0>; - }; - - mdio@3000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio"; - reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts - interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. - - phy0: ethernet-phy@0 { - reg = <0>; - }; - }; - - ata@3a00 { - compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata"; - reg = <0x3a00 0x100>; - interrupts = <2 7 0>; - }; - - i2c@3d00 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; - reg = <0x3d00 0x40>; - interrupts = <2 15 0>; - fsl5200-clocking; - }; - - i2c@3d40 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; - reg = <0x3d40 0x40>; - interrupts = <2 16 0>; - fsl5200-clocking; - rtc@51 { - compatible = "nxp,pcf8563"; - reg = <0x51>; - }; - eeprom@52 { - compatible = "at24,24c32"; - reg = <0x52>; - }; - }; - - sram@8000 { - compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram"; - reg = <0x8000 0x4000>; - }; - }; - - pci@f0000d00 { - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci"; - reg = <0xf0000d00 0x100>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3 // 1st slot - 0xc000 0 0 2 &mpc5200_pic 1 1 3 - 0xc000 0 0 3 &mpc5200_pic 1 2 3 - 0xc000 0 0 4 &mpc5200_pic 1 3 3 - - 0xc800 0 0 1 &mpc5200_pic 1 1 3 // 2nd slot - 0xc800 0 0 2 &mpc5200_pic 1 2 3 - 0xc800 0 0 3 &mpc5200_pic 1 3 3 - 0xc800 0 0 4 &mpc5200_pic 0 0 3>; - clock-frequency = <0>; // From boot loader - interrupts = <2 8 0 2 9 0 2 10 0>; - bus-range = <0 0>; - ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000 - 0x02000000 0 0xa0000000 0xa0000000 0 0x10000000 - 0x01000000 0 0x00000000 0xb0000000 0 0x01000000>; - }; - - localbus { - compatible = "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus"; - - #address-cells = <2>; - #size-cells = <1>; - - ranges = <0 0 0xfe000000 0x02000000 - 1 0 0xfc000000 0x02000000 - 2 0 0xfbe00000 0x00200000 - 3 0 0xf9e00000 0x02000000 - 4 0 0xf7e00000 0x02000000 - 5 0 0xe6000000 0x02000000 - 6 0 0xe8000000 0x02000000 - 7 0 0xea000000 0x02000000>; - - flash@0,0 { - compatible = "cfi-flash"; - reg = <0 0 0x02000000>; - bank-width = <4>; - #size-cells = <1>; - #address-cells = <1>; - - partition@0 { - label = "ubootl"; - reg = <0x00000000 0x00040000>; - }; - partition@40000 { - label = "kernel"; - reg = <0x00040000 0x001c0000>; - }; - partition@200000 { - label = "jffs2"; - reg = <0x00200000 0x01d00000>; - }; - partition@1f00000 { - label = "uboot"; - reg = <0x01f00000 0x00040000>; - }; - partition@1f40000 { - label = "env"; - reg = <0x01f40000 0x00040000>; - }; - partition@1f80000 { - label = "oftree"; - reg = <0x01f80000 0x00040000>; - }; - partition@1fc0000 { - label = "space"; - reg = <0x01fc0000 0x00040000>; - }; - }; - - sram@2,0 { - compatible = "mtd-ram"; - reg = <2 0 0x00200000>; - bank-width = <2>; - }; - - /* - * example snippets for FPGA - * - * fpga@3,0 { - * compatible = "fpga_driver"; - * reg = <3 0 0x02000000>; - * bank-width = <4>; - * }; - * - * fpga@4,0 { - * compatible = "fpga_driver"; - * reg = <4 0 0x02000000>; - * bank-width = <4>; - * }; - */ - - /* - * example snippets for free chipselects - * - * device@5,0 { - * compatible = "custom_driver"; - * reg = <5 0 0x02000000>; - * }; - * - * device@6,0 { - * compatible = "custom_driver"; - * reg = <6 0 0x02000000>; - * }; - * - * device@7,0 { - * compatible = "custom_driver"; - * reg = <7 0 0x02000000>; - * }; - */ - }; -}; - diff --git a/trunk/arch/powerpc/boot/dts/redwood.dts b/trunk/arch/powerpc/boot/dts/redwood.dts deleted file mode 100644 index ad402c488741..000000000000 --- a/trunk/arch/powerpc/boot/dts/redwood.dts +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Device Tree Source for AMCC Redwood(460SX) - * - * Copyright 2008 AMCC - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without - * any warranty of any kind, whether express or implied. - */ - -/dts-v1/; - -/ { - #address-cells = <2>; - #size-cells = <1>; - model = "amcc,redwood"; - compatible = "amcc,redwood"; - dcr-parent = <&{/cpus/cpu@0}>; - - aliases { - ethernet0 = &EMAC0; - serial0 = &UART0; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - model = "PowerPC,460SX"; - reg = <0x00000000>; - clock-frequency = <0>; /* Filled in by U-Boot */ - timebase-frequency = <0>; /* Filled in by U-Boot */ - i-cache-line-size = <32>; - d-cache-line-size = <32>; - i-cache-size = <32768>; - d-cache-size = <32768>; - dcr-controller; - dcr-access-method = "native"; - }; - }; - - memory { - device_type = "memory"; - reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by U-Boot */ - }; - - UIC0: interrupt-controller0 { - compatible = "ibm,uic-460sx","ibm,uic"; - interrupt-controller; - cell-index = <0>; - dcr-reg = <0x0c0 0x009>; - #address-cells = <0>; - #size-cells = <0>; - #interrupt-cells = <2>; - }; - - UIC1: interrupt-controller1 { - compatible = "ibm,uic-460sx","ibm,uic"; - interrupt-controller; - cell-index = <1>; - dcr-reg = <0x0d0 0x009>; - #address-cells = <0>; - #size-cells = <0>; - #interrupt-cells = <2>; - interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ - interrupt-parent = <&UIC0>; - }; - - UIC2: interrupt-controller2 { - compatible = "ibm,uic-460sx","ibm,uic"; - interrupt-controller; - cell-index = <2>; - dcr-reg = <0x0e0 0x009>; - #address-cells = <0>; - #size-cells = <0>; - #interrupt-cells = <2>; - interrupts = <0xa 0x4 0xb 0x4>; /* cascade */ - interrupt-parent = <&UIC0>; - }; - - UIC3: interrupt-controller3 { - compatible = "ibm,uic-460sx","ibm,uic"; - interrupt-controller; - cell-index = <3>; - dcr-reg = <0x0f0 0x009>; - #address-cells = <0>; - #size-cells = <0>; - #interrupt-cells = <2>; - interrupts = <0x10 0x4 0x11 0x4>; /* cascade */ - interrupt-parent = <&UIC0>; - }; - - SDR0: sdr { - compatible = "ibm,sdr-460sx"; - dcr-reg = <0x00e 0x002>; - }; - - CPR0: cpr { - compatible = "ibm,cpr-460sx"; - dcr-reg = <0x00c 0x002>; - }; - - plb { - compatible = "ibm,plb-460sx", "ibm,plb4"; - #address-cells = <2>; - #size-cells = <1>; - ranges; - clock-frequency = <0>; /* Filled in by U-Boot */ - - SDRAM0: sdram { - compatible = "ibm,sdram-460sx", "ibm,sdram-405gp"; - dcr-reg = <0x010 0x002>; - }; - - MAL0: mcmal { - compatible = "ibm,mcmal-460sx", "ibm,mcmal2"; - dcr-reg = <0x180 0x62>; - num-tx-chans = <4>; - num-rx-chans = <32>; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&UIC1>; - interrupts = < /*TXEOB*/ 0x6 0x4 - /*RXEOB*/ 0x7 0x4 - /*SERR*/ 0x1 0x4 - /*TXDE*/ 0x2 0x4 - /*RXDE*/ 0x3 0x4 - /*COAL TX0*/ 0x18 0x2 - /*COAL TX1*/ 0x19 0x2 - /*COAL TX2*/ 0x1a 0x2 - /*COAL TX3*/ 0x1b 0x2 - /*COAL RX0*/ 0x1c 0x2 - /*COAL RX1*/ 0x1d 0x2 - /*COAL RX2*/ 0x1e 0x2 - /*COAL RX3*/ 0x1f 0x2>; - }; - - POB0: opb { - compatible = "ibm,opb-460sx", "ibm,opb"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0xb0000000 0x00000004 0xb0000000 0x50000000>; - clock-frequency = <0>; /* Filled in by U-Boot */ - - EBC0: ebc { - compatible = "ibm,ebc-460sx", "ibm,ebc"; - dcr-reg = <0x012 0x002>; - #address-cells = <2>; - #size-cells = <1>; - clock-frequency = <0>; /* Filled in by U-Boot */ - /* ranges property is supplied by U-Boot */ - interrupts = <0x6 0x4>; - interrupt-parent = <&UIC1>; - - nor_flash@0,0 { - compatible = "amd,s29gl512n", "cfi-flash"; - bank-width = <2>; - reg = <0x0000000 0x00000000 0x04000000>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "kernel"; - reg = <0x00000000 0x001e0000>; - }; - partition@1e0000 { - label = "dtb"; - reg = <0x001e0000 0x00020000>; - }; - partition@200000 { - label = "ramdisk"; - reg = <0x00200000 0x01400000>; - }; - partition@1600000 { - label = "jffs2"; - reg = <0x01600000 0x00400000>; - }; - partition@1a00000 { - label = "user"; - reg = <0x01a00000 0x02560000>; - }; - partition@3f60000 { - label = "env"; - reg = <0x03f60000 0x00040000>; - }; - partition@3fa0000 { - label = "u-boot"; - reg = <0x03fa0000 0x00060000>; - }; - }; - }; - - UART0: serial@ef600200 { - device_type = "serial"; - compatible = "ns16550"; - reg = <0xef600200 0x00000008>; - virtual-reg = <0xef600200>; - clock-frequency = <0>; /* Filled in by U-Boot */ - current-speed = <0>; /* Filled in by U-Boot */ - interrupt-parent = <&UIC0>; - interrupts = <0x0 0x4>; - }; - - RGMII0: emac-rgmii@ef600900 { - compatible = "ibm,rgmii-460sx", "ibm,rgmii"; - reg = <0xef600900 0x00000008>; - }; - - EMAC0: ethernet@ef600a00 { - device_type = "network"; - compatible = "ibm,emac-460sx", "ibm,emac4"; - interrupt-parent = <&EMAC0>; - interrupts = <0x0 0x1>; - #interrupt-cells = <1>; - #address-cells = <0>; - #size-cells = <0>; - interrupt-map = ; - reg = <0xef600a00 0x00000070>; - local-mac-address = [000000000000]; /* Filled in by U-Boot */ - mal-device = <&MAL0>; - mal-tx-channel = <0>; - mal-rx-channel = <0>; - cell-index = <0>; - max-frame-size = <9000>; - rx-fifo-size = <4096>; - tx-fifo-size = <2048>; - phy-mode = "rgmii"; - phy-map = <0x00000000>; - rgmii-device = <&RGMII0>; - rgmii-channel = <0>; - has-inverted-stacr-oc; - has-new-stacr-staopc; - }; - - }; - - }; - chosen { - linux,stdout-path = "/plb/opb/serial@ef600200"; - }; - -}; diff --git a/trunk/arch/powerpc/boot/dts/sbc8349.dts b/trunk/arch/powerpc/boot/dts/sbc8349.dts index a36dbbc48694..8d365a57ebc1 100644 --- a/trunk/arch/powerpc/boot/dts/sbc8349.dts +++ b/trunk/arch/powerpc/boot/dts/sbc8349.dts @@ -159,76 +159,68 @@ phy_type = "ulpi"; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@19 { + interrupt-parent = <&ipic>; + interrupts = <20 0x8>; + reg = <0x19>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1a { + interrupt-parent = <&ipic>; + interrupts = <21 0x8>; + reg = <0x1a>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <32 0x8 33 0x8 34 0x8>; interrupt-parent = <&ipic>; tbi-handle = <&tbi0>; phy-handle = <&phy0>; linux,network-index = <0>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@19 { - interrupt-parent = <&ipic>; - interrupts = <20 0x8>; - reg = <0x19>; - device_type = "ethernet-phy"; - }; - - phy1: ethernet-phy@1a { - interrupt-parent = <&ipic>; - interrupts = <21 0x8>; - reg = <0x1a>; - device_type = "ethernet-phy"; - }; - - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 0x8 36 0x8 37 0x8>; interrupt-parent = <&ipic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; linux,network-index = <1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/sbc8548.dts b/trunk/arch/powerpc/boot/dts/sbc8548.dts index 9c5079fec4f2..2baf4a51f224 100644 --- a/trunk/arch/powerpc/boot/dts/sbc8548.dts +++ b/trunk/arch/powerpc/boot/dts/sbc8548.dts @@ -234,72 +234,66 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@19 { + interrupt-parent = <&mpic>; + interrupts = <0x6 0x1>; + reg = <0x19>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1a { + interrupt-parent = <&mpic>; + interrupts = <0x7 0x1>; + reg = <0x1a>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy0>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@19 { - interrupt-parent = <&mpic>; - interrupts = <0x6 0x1>; - reg = <0x19>; - device_type = "ethernet-phy"; - }; - phy1: ethernet-phy@1a { - interrupt-parent = <&mpic>; - interrupts = <0x7 0x1>; - reg = <0x1a>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <0x23 0x2 0x24 0x2 0x28 0x2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/sbc8560.dts b/trunk/arch/powerpc/boot/dts/sbc8560.dts index b772405a9a0a..01542f7062ab 100644 --- a/trunk/arch/powerpc/boot/dts/sbc8560.dts +++ b/trunk/arch/powerpc/boot/dts/sbc8560.dts @@ -139,83 +139,77 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + phy0: ethernet-phy@19 { + interrupt-parent = <&mpic>; + interrupts = <0x6 0x1>; + reg = <0x19>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1a { + interrupt-parent = <&mpic>; + interrupts = <0x7 0x1>; + reg = <0x1a>; + device_type = "ethernet-phy"; + }; + phy2: ethernet-phy@1b { + interrupt-parent = <&mpic>; + interrupts = <0x8 0x1>; + reg = <0x1b>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@1c { + interrupt-parent = <&mpic>; + interrupts = <0x8 0x1>; + reg = <0x1c>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy0>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - phy0: ethernet-phy@19 { - interrupt-parent = <&mpic>; - interrupts = <0x6 0x1>; - reg = <0x19>; - device_type = "ethernet-phy"; - }; - phy1: ethernet-phy@1a { - interrupt-parent = <&mpic>; - interrupts = <0x7 0x1>; - reg = <0x1a>; - device_type = "ethernet-phy"; - }; - phy2: ethernet-phy@1b { - interrupt-parent = <&mpic>; - interrupts = <0x8 0x1>; - reg = <0x1b>; - device_type = "ethernet-phy"; - }; - phy3: ethernet-phy@1c { - interrupt-parent = <&mpic>; - interrupts = <0x8 0x1>; - reg = <0x1c>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <0x23 0x2 0x24 0x2 0x28 0x2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; mpic: pic@40000 { diff --git a/trunk/arch/powerpc/boot/dts/sbc8641d.dts b/trunk/arch/powerpc/boot/dts/sbc8641d.dts index e3e914e78caa..36db981548e4 100644 --- a/trunk/arch/powerpc/boot/dts/sbc8641d.dts +++ b/trunk/arch/powerpc/boot/dts/sbc8641d.dts @@ -192,144 +192,132 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@1f { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <0x1f>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <0>; + device_type = "ethernet-phy"; + }; + phy2: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <1>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@2 { + interrupt-parent = <&mpic>; + interrupts = <10 1>; + reg = <2>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@26520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x26520 0x20>; + + tbi2: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@27520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x27520 0x20>; + + tbi3: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy0>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@1f { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0x1f>; - device_type = "ethernet-phy"; - }; - phy1: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0>; - device_type = "ethernet-phy"; - }; - phy2: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <1>; - device_type = "ethernet-phy"; - }; - phy3: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <2>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet2: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <2>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <31 2 32 2 33 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi2>; phy-handle = <&phy2>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet3: ethernet@27000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <3>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x27000 0x1000>; - ranges = <0x0 0x27000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <37 2 38 2 39 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi3>; phy-handle = <&phy3>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi3: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/socrates.dts b/trunk/arch/powerpc/boot/dts/socrates.dts deleted file mode 100644 index b8d0fc6f0042..000000000000 --- a/trunk/arch/powerpc/boot/dts/socrates.dts +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Device Tree Source for the Socrates board (MPC8544). - * - * Copyright (c) 2008 Emcraft Systems. - * Sergei Poselenov, - * - * 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. - */ - -/dts-v1/; - -/ { - model = "abb,socrates"; - compatible = "abb,socrates"; - #address-cells = <1>; - #size-cells = <1>; - - aliases { - ethernet0 = &enet0; - ethernet1 = &enet1; - serial0 = &serial0; - serial1 = &serial1; - pci0 = &pci0; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,8544@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; - i-cache-line-size = <32>; - d-cache-size = <0x8000>; // L1, 32K - i-cache-size = <0x8000>; // L1, 32K - timebase-frequency = <0>; - bus-frequency = <0>; - clock-frequency = <0>; - next-level-cache = <&L2>; - }; - }; - - memory { - device_type = "memory"; - reg = <0x00000000 0x00000000>; // Filled in by U-Boot - }; - - soc8544@e0000000 { - #address-cells = <1>; - #size-cells = <1>; - - ranges = <0x00000000 0xe0000000 0x00100000>; - reg = <0xe0000000 0x00001000>; // CCSRBAR 1M - bus-frequency = <0>; // Filled in by U-Boot - compatible = "fsl,mpc8544-immr", "simple-bus"; - - memory-controller@2000 { - compatible = "fsl,mpc8544-memory-controller"; - reg = <0x2000 0x1000>; - interrupt-parent = <&mpic>; - interrupts = <18 2>; - }; - - L2: l2-cache-controller@20000 { - compatible = "fsl,mpc8544-l2-cache-controller"; - reg = <0x20000 0x1000>; - cache-line-size = <32>; - cache-size = <0x40000>; // L2, 256K - interrupt-parent = <&mpic>; - interrupts = <16 2>; - }; - - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <43 2>; - interrupt-parent = <&mpic>; - dfsrr; - - dtt@28 { - compatible = "winbond,w83782d"; - reg = <0x28>; - }; - rtc@32 { - compatible = "epson,rx8025"; - reg = <0x32>; - interrupts = <7 1>; - interrupt-parent = <&mpic>; - }; - dtt@4c { - compatible = "dallas,ds75"; - reg = <0x4c>; - }; - ts@4a { - compatible = "ti,tsc2003"; - reg = <0x4a>; - interrupt-parent = <&mpic>; - interrupts = <8 1>; - }; - }; - - i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <1>; - compatible = "fsl-i2c"; - reg = <0x3100 0x100>; - interrupts = <43 2>; - interrupt-parent = <&mpic>; - dfsrr; - }; - - enet0: ethernet@24000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <0>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <29 2 30 2 34 2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy0>; - tbi-handle = <&tbi0>; - phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <0 1>; - reg = <0>; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <0 1>; - reg = <1>; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - }; - }; - }; - - enet1: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <1>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <31 2 32 2 33 2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy1>; - tbi-handle = <&tbi1>; - phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - }; - }; - }; - - serial0: serial@4500 { - cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <0x4500 0x100>; - clock-frequency = <0>; - interrupts = <42 2>; - interrupt-parent = <&mpic>; - }; - - serial1: serial@4600 { - cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <0x4600 0x100>; - clock-frequency = <0>; - interrupts = <42 2>; - interrupt-parent = <&mpic>; - }; - - global-utilities@e0000 { //global utilities block - compatible = "fsl,mpc8548-guts"; - reg = <0xe0000 0x1000>; - fsl,has-rstcr; - }; - - mpic: pic@40000 { - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <0x40000 0x40000>; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - }; - }; - - - localbus { - compatible = "fsl,mpc8544-localbus", - "fsl,pq3-localbus", - "simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - reg = <0xe0005000 0x40>; - - ranges = <0 0 0xfc000000 0x04000000 - 2 0 0xc8000000 0x04000000 - 3 0 0xc0000000 0x00100000 - >; /* Overwritten by U-Boot */ - - nor_flash@0,0 { - compatible = "amd,s29gl256n", "cfi-flash"; - bank-width = <2>; - reg = <0x0 0x000000 0x4000000>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "kernel"; - reg = <0x0 0x1e0000>; - read-only; - }; - partition@1e0000 { - label = "dtb"; - reg = <0x1e0000 0x20000>; - }; - partition@200000 { - label = "root"; - reg = <0x200000 0x200000>; - }; - partition@400000 { - label = "user"; - reg = <0x400000 0x3b80000>; - }; - partition@3f80000 { - label = "env"; - reg = <0x3f80000 0x40000>; - read-only; - }; - partition@3fc0000 { - label = "u-boot"; - reg = <0x3fc0000 0x40000>; - read-only; - }; - }; - - display@2,0 { - compatible = "fujitsu,lime"; - reg = <2 0x0 0x4000000>; - interrupt-parent = <&mpic>; - interrupts = <6 1>; - }; - - fpga_pic: fpga-pic@3,10 { - compatible = "abb,socrates-fpga-pic"; - reg = <3 0x10 0x10>; - interrupt-controller; - /* IRQs 2, 10, 11, active low, level-sensitive */ - interrupts = <2 1 10 1 11 1>; - interrupt-parent = <&mpic>; - #interrupt-cells = <3>; - }; - - spi@3,60 { - compatible = "abb,socrates-spi"; - reg = <3 0x60 0x10>; - interrupts = <8 4 0>; // number, type, routing - interrupt-parent = <&fpga_pic>; - }; - - nand@3,70 { - compatible = "abb,socrates-nand"; - reg = <3 0x70 0x04>; - bank-width = <1>; - #address-cells = <1>; - #size-cells = <1>; - data@0 { - label = "data"; - reg = <0x0 0x40000000>; - }; - }; - - can@3,100 { - compatible = "philips,sja1000"; - reg = <3 0x100 0x80>; - interrupts = <2 8 1>; // number, type, routing - interrupt-parent = <&fpga_pic>; - }; - }; - - pci0: pci@e0008000 { - cell-index = <0>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - compatible = "fsl,mpc8540-pci"; - device_type = "pci"; - reg = <0xe0008000 0x1000>; - clock-frequency = <66666666>; - - interrupt-map-mask = <0xf800 0x0 0x0 0x7>; - interrupt-map = < - /* IDSEL 0x11 */ - 0x8800 0x0 0x0 1 &mpic 5 1 - /* IDSEL 0x12 */ - 0x9000 0x0 0x0 1 &mpic 4 1>; - interrupt-parent = <&mpic>; - interrupts = <24 2>; - bus-range = <0x0 0x0>; - ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000 - 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x01000000>; - }; - -}; diff --git a/trunk/arch/powerpc/boot/dts/stx_gp3_8560.dts b/trunk/arch/powerpc/boot/dts/stx_gp3_8560.dts index 8b173957fb5f..fff33fe6efc6 100644 --- a/trunk/arch/powerpc/boot/dts/stx_gp3_8560.dts +++ b/trunk/arch/powerpc/boot/dts/stx_gp3_8560.dts @@ -124,72 +124,66 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy2: ethernet-phy@2 { + interrupt-parent = <&mpic>; + interrupts = <5 4>; + reg = <2>; + device_type = "ethernet-phy"; + }; + phy4: ethernet-phy@4 { + interrupt-parent = <&mpic>; + interrupts = <5 4>; + reg = <4>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy2>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy2: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <5 4>; - reg = <2>; - device_type = "ethernet-phy"; - }; - phy4: ethernet-phy@4 { - interrupt-parent = <&mpic>; - interrupts = <5 4>; - reg = <4>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy4>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; mpic: pic@40000 { diff --git a/trunk/arch/powerpc/boot/dts/tqm5200.dts b/trunk/arch/powerpc/boot/dts/tqm5200.dts index c9590b58b7b0..906302e26a62 100644 --- a/trunk/arch/powerpc/boot/dts/tqm5200.dts +++ b/trunk/arch/powerpc/boot/dts/tqm5200.dts @@ -17,7 +17,6 @@ compatible = "tqc,tqm5200"; #address-cells = <1>; #size-cells = <1>; - interrupt-parent = <&mpc5200_pic>; cpus { #address-cells = <1>; @@ -67,33 +66,36 @@ compatible = "fsl,mpc5200-gpt"; reg = <0x600 0x10>; interrupts = <1 9 0>; + interrupt-parent = <&mpc5200_pic>; fsl,has-wdt; }; can@900 { compatible = "fsl,mpc5200-mscan"; interrupts = <2 17 0>; + interrupt-parent = <&mpc5200_pic>; reg = <0x900 0x80>; }; can@980 { compatible = "fsl,mpc5200-mscan"; interrupts = <2 18 0>; + interrupt-parent = <&mpc5200_pic>; reg = <0x980 0x80>; }; - gpio_simple: gpio@b00 { + gpio@b00 { compatible = "fsl,mpc5200-gpio"; reg = <0xb00 0x40>; interrupts = <1 7 0>; - gpio-controller; - #gpio-cells = <2>; + interrupt-parent = <&mpc5200_pic>; }; usb@1000 { compatible = "fsl,mpc5200-ohci","ohci-be"; reg = <0x1000 0xff>; interrupts = <2 6 0>; + interrupt-parent = <&mpc5200_pic>; }; dma-controller@1200 { @@ -103,6 +105,7 @@ 3 4 0 3 5 0 3 6 0 3 7 0 3 8 0 3 9 0 3 10 0 3 11 0 3 12 0 3 13 0 3 14 0 3 15 0>; + interrupt-parent = <&mpc5200_pic>; }; xlb@1f00 { @@ -111,28 +114,39 @@ }; serial@2000 { // PSC1 + device_type = "serial"; compatible = "fsl,mpc5200-psc-uart"; + port-number = <0>; // Logical port assignment reg = <0x2000 0x100>; interrupts = <2 1 0>; + interrupt-parent = <&mpc5200_pic>; }; serial@2200 { // PSC2 + device_type = "serial"; compatible = "fsl,mpc5200-psc-uart"; + port-number = <1>; // Logical port assignment reg = <0x2200 0x100>; interrupts = <2 2 0>; + interrupt-parent = <&mpc5200_pic>; }; serial@2400 { // PSC3 + device_type = "serial"; compatible = "fsl,mpc5200-psc-uart"; + port-number = <2>; // Logical port assignment reg = <0x2400 0x100>; interrupts = <2 3 0>; + interrupt-parent = <&mpc5200_pic>; }; ethernet@3000 { + device_type = "network"; compatible = "fsl,mpc5200-fec"; reg = <0x3000 0x400>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <2 5 0>; + interrupt-parent = <&mpc5200_pic>; phy-handle = <&phy0>; }; @@ -142,8 +156,10 @@ compatible = "fsl,mpc5200-mdio"; reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + interrupt-parent = <&mpc5200_pic>; phy0: ethernet-phy@0 { + device_type = "ethernet-phy"; reg = <0>; }; }; @@ -152,6 +168,7 @@ compatible = "fsl,mpc5200-ata"; reg = <0x3a00 0x100>; interrupts = <2 7 0>; + interrupt-parent = <&mpc5200_pic>; }; i2c@3d40 { @@ -160,6 +177,7 @@ compatible = "fsl,mpc5200-i2c","fsl-i2c"; reg = <0x3d40 0x40>; interrupts = <2 16 0>; + interrupt-parent = <&mpc5200_pic>; fsl5200-clocking; rtc@68 { @@ -174,8 +192,9 @@ }; }; - localbus { - compatible = "fsl,mpc5200-lpb","simple-bus"; + lpb { + model = "fsl,lpb"; + compatible = "fsl,lpb"; #address-cells = <2>; #size-cells = <1>; ranges = <0 0 0xfc000000 0x02000000>; @@ -204,6 +223,7 @@ 0xc000 0 0 4 &mpc5200_pic 0 0 3>; clock-frequency = <0>; // From boot loader interrupts = <2 8 0 2 9 0 2 10 0>; + interrupt-parent = <&mpc5200_pic>; bus-range = <0 0>; ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000 0x02000000 0 0x90000000 0x90000000 0 0x10000000 diff --git a/trunk/arch/powerpc/boot/dts/tqm8540.dts b/trunk/arch/powerpc/boot/dts/tqm8540.dts index ac9413a29f9f..a693f01c21aa 100644 --- a/trunk/arch/powerpc/boot/dts/tqm8540.dts +++ b/trunk/arch/powerpc/boot/dts/tqm8540.dts @@ -84,11 +84,6 @@ interrupt-parent = <&mpic>; dfsrr; - dtt@50 { - compatible = "national,lm75"; - reg = <0x50>; - }; - rtc@68 { compatible = "dallas,ds1337"; reg = <0x68>; @@ -136,103 +131,94 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <1>; + device_type = "ethernet-phy"; + }; + phy2: ethernet-phy@2 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <2>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <3>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@26520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x26520 0x20>; + + tbi2: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; phy-handle = <&phy2>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <1>; - device_type = "ethernet-phy"; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <2>; - device_type = "ethernet-phy"; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <3>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; phy-handle = <&phy1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet2: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <2>; device_type = "network"; model = "FEC"; compatible = "gianfar"; reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <41 2>; interrupt-parent = <&mpic>; phy-handle = <&phy3>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/tqm8541.dts b/trunk/arch/powerpc/boot/dts/tqm8541.dts index c71bb5dd5e5e..9e3f5f0dde20 100644 --- a/trunk/arch/powerpc/boot/dts/tqm8541.dts +++ b/trunk/arch/powerpc/boot/dts/tqm8541.dts @@ -83,11 +83,6 @@ interrupt-parent = <&mpic>; dfsrr; - dtt@50 { - compatible = "national,lm75"; - reg = <0x50>; - }; - rtc@68 { compatible = "dallas,ds1337"; reg = <0x68>; @@ -135,78 +130,72 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <1>; + device_type = "ethernet-phy"; + }; + phy2: ethernet-phy@2 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <2>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <3>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy2>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <1>; - device_type = "ethernet-phy"; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <2>; - device_type = "ethernet-phy"; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <3>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/tqm8548-bigflash.dts b/trunk/arch/powerpc/boot/dts/tqm8548-bigflash.dts index 28b1a95257cd..15086eb65c50 100644 --- a/trunk/arch/powerpc/boot/dts/tqm8548-bigflash.dts +++ b/trunk/arch/powerpc/boot/dts/tqm8548-bigflash.dts @@ -85,11 +85,6 @@ interrupt-parent = <&mpic>; dfsrr; - dtt@50 { - compatible = "national,lm75"; - reg = <0x50>; - }; - rtc@68 { compatible = "dallas,ds1337"; reg = <0x68>; @@ -148,146 +143,134 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy1: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <1>; + device_type = "ethernet-phy"; + }; + phy2: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <2>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <3>; + device_type = "ethernet-phy"; + }; + phy4: ethernet-phy@4 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <4>; + device_type = "ethernet-phy"; + }; + phy5: ethernet-phy@5 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <5>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@26520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x26520 0x20>; + + tbi2: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@27520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x27520 0x20>; + + tbi3: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy2>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy1: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <1>; - device_type = "ethernet-phy"; - }; - phy2: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <2>; - device_type = "ethernet-phy"; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <3>; - device_type = "ethernet-phy"; - }; - phy4: ethernet-phy@4 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <4>; - device_type = "ethernet-phy"; - }; - phy5: ethernet-phy@5 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <5>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet2: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <2>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <31 2 32 2 33 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi2>; phy-handle = <&phy3>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet3: ethernet@27000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <3>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x27000 0x1000>; - ranges = <0x0 0x27000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <37 2 38 2 39 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi3>; phy-handle = <&phy4>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi3: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { @@ -382,14 +365,14 @@ can0@2,0 { compatible = "intel,82527"; // Bosch CC770 reg = <2 0x0 0x100>; - interrupts = <4 1>; + interrupts = <4 0>; interrupt-parent = <&mpic>; }; can1@2,100 { compatible = "intel,82527"; // Bosch CC770 reg = <2 0x100 0x100>; - interrupts = <4 1>; + interrupts = <4 0>; interrupt-parent = <&mpic>; }; diff --git a/trunk/arch/powerpc/boot/dts/tqm8548.dts b/trunk/arch/powerpc/boot/dts/tqm8548.dts index 826fb622cd3c..b7b65f5e79b6 100644 --- a/trunk/arch/powerpc/boot/dts/tqm8548.dts +++ b/trunk/arch/powerpc/boot/dts/tqm8548.dts @@ -85,11 +85,6 @@ interrupt-parent = <&mpic>; dfsrr; - dtt@50 { - compatible = "national,lm75"; - reg = <0x50>; - }; - rtc@68 { compatible = "dallas,ds1337"; reg = <0x68>; @@ -148,146 +143,134 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy1: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <1>; + device_type = "ethernet-phy"; + }; + phy2: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <2>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <3>; + device_type = "ethernet-phy"; + }; + phy4: ethernet-phy@4 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <4>; + device_type = "ethernet-phy"; + }; + phy5: ethernet-phy@5 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <5>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@26520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x26520 0x20>; + + tbi2: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@27520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x27520 0x20>; + + tbi3: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy2>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy1: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <1>; - device_type = "ethernet-phy"; - }; - phy2: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <2>; - device_type = "ethernet-phy"; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <3>; - device_type = "ethernet-phy"; - }; - phy4: ethernet-phy@4 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <4>; - device_type = "ethernet-phy"; - }; - phy5: ethernet-phy@5 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <5>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet2: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <2>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <31 2 32 2 33 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi2>; phy-handle = <&phy3>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet3: ethernet@27000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <3>; device_type = "network"; model = "eTSEC"; compatible = "gianfar"; reg = <0x27000 0x1000>; - ranges = <0x0 0x27000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <37 2 38 2 39 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi3>; phy-handle = <&phy4>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi3: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { @@ -382,14 +365,14 @@ can0@2,0 { compatible = "intel,82527"; // Bosch CC770 reg = <2 0x0 0x100>; - interrupts = <4 1>; + interrupts = <4 0>; interrupt-parent = <&mpic>; }; can1@2,100 { compatible = "intel,82527"; // Bosch CC770 reg = <2 0x100 0x100>; - interrupts = <4 1>; + interrupts = <4 0>; interrupt-parent = <&mpic>; }; diff --git a/trunk/arch/powerpc/boot/dts/tqm8555.dts b/trunk/arch/powerpc/boot/dts/tqm8555.dts index a133ded6dddb..cf92b4e7945e 100644 --- a/trunk/arch/powerpc/boot/dts/tqm8555.dts +++ b/trunk/arch/powerpc/boot/dts/tqm8555.dts @@ -83,11 +83,6 @@ interrupt-parent = <&mpic>; dfsrr; - dtt@50 { - compatible = "national,lm75"; - reg = <0x50>; - }; - rtc@68 { compatible = "dallas,ds1337"; reg = <0x68>; @@ -135,78 +130,72 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <1>; + device_type = "ethernet-phy"; + }; + phy2: ethernet-phy@2 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <2>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <3>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy2>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <1>; - device_type = "ethernet-phy"; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <2>; - device_type = "ethernet-phy"; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <3>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; serial0: serial@4500 { diff --git a/trunk/arch/powerpc/boot/dts/tqm8560.dts b/trunk/arch/powerpc/boot/dts/tqm8560.dts index 649e2e576267..9e1ab2d2f669 100644 --- a/trunk/arch/powerpc/boot/dts/tqm8560.dts +++ b/trunk/arch/powerpc/boot/dts/tqm8560.dts @@ -85,11 +85,6 @@ interrupt-parent = <&mpic>; dfsrr; - dtt@50 { - compatible = "national,lm75"; - reg = <0x50>; - }; - rtc@68 { compatible = "dallas,ds1337"; reg = <0x68>; @@ -137,78 +132,72 @@ }; }; - enet0: ethernet@24000 { + mdio@24520 { #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <1>; + device_type = "ethernet-phy"; + }; + phy2: ethernet-phy@2 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <2>; + device_type = "ethernet-phy"; + }; + phy3: ethernet-phy@3 { + interrupt-parent = <&mpic>; + interrupts = <8 1>; + reg = <3>; + device_type = "ethernet-phy"; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + mdio@25520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-tbi"; + reg = <0x25520 0x20>; + + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <29 2 30 2 34 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi0>; phy-handle = <&phy2>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <1>; - device_type = "ethernet-phy"; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <2>; - device_type = "ethernet-phy"; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <8 1>; - reg = <3>; - device_type = "ethernet-phy"; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; cell-index = <1>; device_type = "network"; model = "TSEC"; compatible = "gianfar"; reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <35 2 36 2 40 2>; interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; mpic: pic@40000 { @@ -346,14 +335,14 @@ can0@2,0 { compatible = "intel,82527"; // Bosch CC770 reg = <2 0x0 0x100>; - interrupts = <4 1>; + interrupts = <4 0>; interrupt-parent = <&mpic>; }; can1@2,100 { compatible = "intel,82527"; // Bosch CC770 reg = <2 0x100 0x100>; - interrupts = <4 1>; + interrupts = <4 0>; interrupt-parent = <&mpic>; }; }; diff --git a/trunk/arch/powerpc/boot/dts/virtex440-ml507.dts b/trunk/arch/powerpc/boot/dts/virtex440-ml507.dts index 52d8c1ad26a1..dc8e78e2dceb 100644 --- a/trunk/arch/powerpc/boot/dts/virtex440-ml507.dts +++ b/trunk/arch/powerpc/boot/dts/virtex440-ml507.dts @@ -7,15 +7,6 @@ * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any * kind, whether express or implied. - * - * --- - * - * Device Tree Generator version: 1.1 - * - * CAUTION: This file is automatically generated by libgen. - * Version: Xilinx EDK 10.1.03 EDK_K_SP3.6 - * - * XPS project directory: ml507_ppc440_emb_ref */ /dts-v1/; @@ -31,8 +22,8 @@ reg = < 0 0x10000000 >; } ; chosen { - bootargs = "console=ttyS0 root=/dev/ram"; - linux,stdout-path = &RS232_Uart_1; + bootargs = "console=ttyS0 ip=on root=/dev/ram"; + linux,stdout-path = "/plb@0/serial@83e00000"; } ; cpus { #address-cells = <1>; @@ -145,19 +136,19 @@ compatible = "xlnx,ll-dma-1.00.a"; dcr-reg = < 0x80 0x11 >; interrupt-parent = <&xps_intc_0>; - interrupts = < 10 2 11 2 >; + interrupts = < 9 2 0xa 2 >; } ; } ; } ; plb_v46_0: plb@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "xlnx,plb-v46-1.03.a", "simple-bus"; + compatible = "xlnx,plb-v46-1.02.a", "simple-bus"; ranges ; DIP_Switches_8Bit: gpio@81460000 { compatible = "xlnx,xps-gpio-1.00.a"; interrupt-parent = <&xps_intc_0>; - interrupts = < 7 2 >; + interrupts = < 6 2 >; reg = < 0x81460000 0x10000 >; xlnx,all-inputs = <1>; xlnx,all-inputs-2 = <0>; @@ -172,86 +163,6 @@ xlnx,tri-default = <0xffffffff>; xlnx,tri-default-2 = <0xffffffff>; } ; - FLASH: flash@fc000000 { - bank-width = <2>; - compatible = "xlnx,xps-mch-emc-2.00.a", "cfi-flash"; - reg = < 0xfc000000 0x2000000 >; - xlnx,family = "virtex5"; - xlnx,include-datawidth-matching-0 = <0x1>; - xlnx,include-datawidth-matching-1 = <0x0>; - xlnx,include-datawidth-matching-2 = <0x0>; - xlnx,include-datawidth-matching-3 = <0x0>; - xlnx,include-negedge-ioregs = <0x0>; - xlnx,include-plb-ipif = <0x1>; - xlnx,include-wrbuf = <0x1>; - xlnx,max-mem-width = <0x10>; - xlnx,mch-native-dwidth = <0x20>; - xlnx,mch-plb-clk-period-ps = <0x2710>; - xlnx,mch-splb-awidth = <0x20>; - xlnx,mch0-accessbuf-depth = <0x10>; - xlnx,mch0-protocol = <0x0>; - xlnx,mch0-rddatabuf-depth = <0x10>; - xlnx,mch1-accessbuf-depth = <0x10>; - xlnx,mch1-protocol = <0x0>; - xlnx,mch1-rddatabuf-depth = <0x10>; - xlnx,mch2-accessbuf-depth = <0x10>; - xlnx,mch2-protocol = <0x0>; - xlnx,mch2-rddatabuf-depth = <0x10>; - xlnx,mch3-accessbuf-depth = <0x10>; - xlnx,mch3-protocol = <0x0>; - xlnx,mch3-rddatabuf-depth = <0x10>; - xlnx,mem0-width = <0x10>; - xlnx,mem1-width = <0x20>; - xlnx,mem2-width = <0x20>; - xlnx,mem3-width = <0x20>; - xlnx,num-banks-mem = <0x1>; - xlnx,num-channels = <0x2>; - xlnx,priority-mode = <0x0>; - xlnx,synch-mem-0 = <0x0>; - xlnx,synch-mem-1 = <0x0>; - xlnx,synch-mem-2 = <0x0>; - xlnx,synch-mem-3 = <0x0>; - xlnx,synch-pipedelay-0 = <0x2>; - xlnx,synch-pipedelay-1 = <0x2>; - xlnx,synch-pipedelay-2 = <0x2>; - xlnx,synch-pipedelay-3 = <0x2>; - xlnx,tavdv-ps-mem-0 = <0x1adb0>; - xlnx,tavdv-ps-mem-1 = <0x3a98>; - xlnx,tavdv-ps-mem-2 = <0x3a98>; - xlnx,tavdv-ps-mem-3 = <0x3a98>; - xlnx,tcedv-ps-mem-0 = <0x1adb0>; - xlnx,tcedv-ps-mem-1 = <0x3a98>; - xlnx,tcedv-ps-mem-2 = <0x3a98>; - xlnx,tcedv-ps-mem-3 = <0x3a98>; - xlnx,thzce-ps-mem-0 = <0x88b8>; - xlnx,thzce-ps-mem-1 = <0x1b58>; - xlnx,thzce-ps-mem-2 = <0x1b58>; - xlnx,thzce-ps-mem-3 = <0x1b58>; - xlnx,thzoe-ps-mem-0 = <0x1b58>; - xlnx,thzoe-ps-mem-1 = <0x1b58>; - xlnx,thzoe-ps-mem-2 = <0x1b58>; - xlnx,thzoe-ps-mem-3 = <0x1b58>; - xlnx,tlzwe-ps-mem-0 = <0x88b8>; - xlnx,tlzwe-ps-mem-1 = <0x0>; - xlnx,tlzwe-ps-mem-2 = <0x0>; - xlnx,tlzwe-ps-mem-3 = <0x0>; - xlnx,twc-ps-mem-0 = <0x2af8>; - xlnx,twc-ps-mem-1 = <0x3a98>; - xlnx,twc-ps-mem-2 = <0x3a98>; - xlnx,twc-ps-mem-3 = <0x3a98>; - xlnx,twp-ps-mem-0 = <0x11170>; - xlnx,twp-ps-mem-1 = <0x2ee0>; - xlnx,twp-ps-mem-2 = <0x2ee0>; - xlnx,twp-ps-mem-3 = <0x2ee0>; - xlnx,xcl0-linesize = <0x4>; - xlnx,xcl0-writexfer = <0x1>; - xlnx,xcl1-linesize = <0x4>; - xlnx,xcl1-writexfer = <0x1>; - xlnx,xcl2-linesize = <0x4>; - xlnx,xcl2-writexfer = <0x1>; - xlnx,xcl3-linesize = <0x4>; - xlnx,xcl3-writexfer = <0x1>; - } ; Hard_Ethernet_MAC: xps-ll-temac@81c00000 { #address-cells = <1>; #size-cells = <1>; @@ -274,19 +185,6 @@ xlnx,txfifo = <0x1000>; } ; } ; - IIC_EEPROM: i2c@81600000 { - compatible = "xlnx,xps-iic-2.00.a"; - interrupt-parent = <&xps_intc_0>; - interrupts = < 6 2 >; - reg = < 0x81600000 0x10000 >; - xlnx,clk-freq = <0x5f5e100>; - xlnx,family = "virtex5"; - xlnx,gpo-width = <0x1>; - xlnx,iic-freq = <0x186a0>; - xlnx,scl-inertial-delay = <0x0>; - xlnx,sda-inertial-delay = <0x0>; - xlnx,ten-bit-adr = <0x0>; - } ; LEDs_8Bit: gpio@81400000 { compatible = "xlnx,xps-gpio-1.00.a"; reg = < 0x81400000 0x10000 >; @@ -322,7 +220,7 @@ Push_Buttons_5Bit: gpio@81440000 { compatible = "xlnx,xps-gpio-1.00.a"; interrupt-parent = <&xps_intc_0>; - interrupts = < 8 2 >; + interrupts = < 7 2 >; reg = < 0x81440000 0x10000 >; xlnx,all-inputs = <1>; xlnx,all-inputs-2 = <0>; @@ -339,13 +237,13 @@ } ; RS232_Uart_1: serial@83e00000 { clock-frequency = <100000000>; - compatible = "xlnx,xps-uart16550-2.00.b", "ns16550"; - current-speed = <9600>; + compatible = "xlnx,xps-uart16550-2.00.a", "ns16550"; + current-speed = <0x2580>; device_type = "serial"; interrupt-parent = <&xps_intc_0>; - interrupts = < 9 2 >; + interrupts = < 8 2 >; reg = < 0x83e00000 0x10000 >; - reg-offset = <0x1003>; + reg-offset = <3>; reg-shift = <2>; xlnx,family = "virtex5"; xlnx,has-external-rclk = <0>; @@ -370,7 +268,7 @@ compatible = "xlnx,xps-intc-1.00.a"; interrupt-controller ; reg = < 0x81800000 0x10000 >; - xlnx,num-intr-inputs = <0xc>; + xlnx,num-intr-inputs = <0xb>; } ; xps_timebase_wdt_1: xps-timebase-wdt@83a00000 { compatible = "xlnx,xps-timebase-wdt-1.00.b"; diff --git a/trunk/arch/powerpc/boot/serial.c b/trunk/arch/powerpc/boot/serial.c index f2156f07571f..8b3607cb53fb 100644 --- a/trunk/arch/powerpc/boot/serial.c +++ b/trunk/arch/powerpc/boot/serial.c @@ -117,8 +117,7 @@ int serial_console_init(void) if (devp == NULL) goto err_out; - if (dt_is_compatible(devp, "ns16550") || - dt_is_compatible(devp, "pnpPNP,501")) + if (dt_is_compatible(devp, "ns16550")) rc = ns16550_console_init(devp, &serial_cd); else if (dt_is_compatible(devp, "marvell,mv64360-mpsc")) rc = mpsc_console_init(devp, &serial_cd); diff --git a/trunk/arch/powerpc/boot/wrapper b/trunk/arch/powerpc/boot/wrapper index 3ac75aecdb94..965c237c122d 100755 --- a/trunk/arch/powerpc/boot/wrapper +++ b/trunk/arch/powerpc/boot/wrapper @@ -186,9 +186,6 @@ cuboot*) *-mpc85*|*-tqm85*|*-sbc85*) platformo=$object/cuboot-85xx.o ;; - *-amigaone) - link_address='0x800000' - ;; esac ;; ps3) @@ -214,11 +211,11 @@ simpleboot-virtex405-*) binary=y ;; simpleboot-virtex440-*) - platformo="$object/fixed-head.o $object/simpleboot.o $object/virtex.o" + platformo="$object/simpleboot.o $object/virtex.o" binary=y ;; simpleboot-*) - platformo="$object/fixed-head.o $object/simpleboot.o" + platformo="$object/simpleboot.o" binary=y ;; asp834x-redboot) diff --git a/trunk/arch/powerpc/configs/44x/canyonlands_defconfig b/trunk/arch/powerpc/configs/44x/canyonlands_defconfig index f9a08ee49b96..81cdcc4b9278 100644 --- a/trunk/arch/powerpc/configs/44x/canyonlands_defconfig +++ b/trunk/arch/powerpc/configs/44x/canyonlands_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29-rc3 -# Mon Feb 2 13:13:04 2009 +# Linux kernel version: 2.6.29-rc2 +# Tue Jan 20 08:22:35 2009 # # CONFIG_PPC64 is not set @@ -74,15 +74,6 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set - -# -# RCU Subsystem -# -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set @@ -156,6 +147,11 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_FREEZER is not set CONFIG_PPC4xx_PCI_EXPRESS=y @@ -377,7 +373,6 @@ CONFIG_CONNECTOR=y CONFIG_PROC_EVENTS=y # CONFIG_MTD is not set CONFIG_OF_DEVICE=y -CONFIG_OF_I2C=y # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_FD is not set @@ -389,7 +384,6 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=35000 @@ -472,15 +466,6 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y # # Enable WiMAX (Networking options) to see the WiMAX drivers # - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -548,136 +533,13 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set CONFIG_DEVPORT=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_HELPER_AUTO=y - -# -# I2C Hardware Bus support -# - -# -# PC SMBus host controller drivers -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_ISCH is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -CONFIG_I2C_IBM_IIC=y -# CONFIG_I2C_MPC is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_SIMTEC is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_DS1682 is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C is not set # CONFIG_SPI is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_GPIOLIB is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -CONFIG_SENSORS_AD7414=y -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7462 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set -# CONFIG_SENSORS_ADT7475 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_I5K_AMB is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_LTC4245 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_HWMON is not set # CONFIG_THERMAL is not set # CONFIG_THERMAL_HWMON is not set # CONFIG_WATCHDOG is not set @@ -694,12 +556,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set -# CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_PCF50633 is not set # CONFIG_REGULATOR is not set # @@ -717,7 +574,6 @@ CONFIG_SSB_POSSIBLE=y # Multimedia drivers # CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set # # Graphics support @@ -734,109 +590,7 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m # # CONFIG_DISPLAY_SUPPORT is not set # CONFIG_SOUND is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -CONFIG_USB_MON=y -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -CONFIG_USB_EHCI_HCD=m -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set -CONFIG_USB_EHCI_HCD_PPC_OF=y -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_HCD_PPC_OF=y -CONFIG_USB_OHCI_HCD_PPC_OF_BE=y -CONFIG_USB_OHCI_HCD_PPC_OF_LE=y -CONFIG_USB_OHCI_HCD_PCI=y -CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y -CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_WHCI_HCD is not set -# CONFIG_USB_HWA_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set -# CONFIG_USB_TMC is not set - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; -# - -# -# see USB_STORAGE Help for more information -# -CONFIG_USB_LIBUSUAL=y - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set - -# -# USB port drivers -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set -# CONFIG_USB_GADGET is not set - -# -# OTG and related infrastructure -# +# CONFIG_USB_SUPPORT is not set # CONFIG_UWB is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set diff --git a/trunk/arch/powerpc/configs/44x/redwood_defconfig b/trunk/arch/powerpc/configs/44x/redwood_defconfig deleted file mode 100644 index e665433762ba..000000000000 --- a/trunk/arch/powerpc/configs/44x/redwood_defconfig +++ /dev/null @@ -1,1176 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.29-rc3 -# Wed Feb 4 14:31:09 2009 -# -# CONFIG_PPC64 is not set - -# -# Processor support -# -# CONFIG_6xx is not set -# CONFIG_PPC_85xx is not set -# CONFIG_PPC_8xx is not set -# CONFIG_40x is not set -CONFIG_44x=y -# CONFIG_E200 is not set -CONFIG_PPC_FPU=y -CONFIG_4xx=y -CONFIG_BOOKE=y -CONFIG_PTE_64BIT=y -CONFIG_PHYS_64BIT=y -CONFIG_PPC_MMU_NOHASH=y -# CONFIG_PPC_MM_SLICES is not set -CONFIG_NOT_COHERENT_CACHE=y -CONFIG_PPC32=y -CONFIG_WORD_SIZE=32 -CONFIG_ARCH_PHYS_ADDR_T_64BIT=y -CONFIG_MMU=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_HARDIRQS=y -# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set -CONFIG_IRQ_PER_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_OF=y -CONFIG_PPC_UDBG_16550=y -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -# CONFIG_DEFAULT_UIMAGE is not set -CONFIG_PPC_DCR_NATIVE=y -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_PPC_DCR=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set - -# -# RCU Subsystem -# -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set -# CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set -# CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -# CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_PCI_QUIRKS=y -CONFIG_SLUB_DEBUG=y -# CONFIG_SLAB is not set -CONFIG_SLUB=y -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_IOREMAP_PROT=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_BLOCK=y -CONFIG_LBD=y -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -# CONFIG_FREEZER is not set -CONFIG_PPC4xx_PCI_EXPRESS=y - -# -# Platform support -# -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PQ2ADS is not set -# CONFIG_BAMBOO is not set -# CONFIG_EBONY is not set -# CONFIG_SAM440EP is not set -# CONFIG_SEQUOIA is not set -# CONFIG_TAISHAN is not set -# CONFIG_KATMAI is not set -# CONFIG_RAINIER is not set -# CONFIG_WARP is not set -# CONFIG_ARCHES is not set -# CONFIG_CANYONLANDS is not set -# CONFIG_GLACIER is not set -CONFIG_REDWOOD=y -# CONFIG_YOSEMITE is not set -# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set -CONFIG_PPC44x_SIMPLE=y -# CONFIG_PPC4xx_GPIO is not set -CONFIG_460SX=y -# CONFIG_IPIC is not set -# CONFIG_MPIC is not set -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_FSL_ULI1575 is not set -# CONFIG_SIMPLE_GPIO is not set - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_SCHED_HRTICK=y -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -# CONFIG_HAVE_AOUT is not set -# CONFIG_BINFMT_MISC is not set -# CONFIG_MATH_EMULATION is not set -# CONFIG_IOMMU_HELPER is not set -CONFIG_PPC_NEED_DMA_SYNC_OPS=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_HAS_WALK_MEMORY=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_MIGRATION=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -CONFIG_UNEVICTABLE_LRU=y -CONFIG_PPC_4K_PAGES=y -# CONFIG_PPC_16K_PAGES is not set -# CONFIG_PPC_64K_PAGES is not set -CONFIG_FORCE_MAX_ZONEORDER=11 -CONFIG_PROC_DEVICETREE=y -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="" -CONFIG_EXTRA_TARGETS="" -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_ZONE_DMA=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_4xx_SOC=y -CONFIG_PPC_PCI_CHOICE=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_SYSCALL=y -CONFIG_PCIEPORTBUS=y -CONFIG_PCIEAER=y -# CONFIG_PCIEASPM is not set -CONFIG_ARCH_SUPPORTS_MSI=y -# CONFIG_PCI_MSI is not set -CONFIG_PCI_LEGACY=y -# CONFIG_PCI_DEBUG is not set -# CONFIG_PCI_STUB is not set -# CONFIG_PCCARD is not set -# CONFIG_HOTPLUG_PCI is not set -# CONFIG_HAS_RAPIDIO is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_PAGE_OFFSET=0xc0000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_PHYSICAL_START=0x00000000 -CONFIG_TASK_SIZE=0xc0000000 -CONFIG_CONSISTENT_START=0xff100000 -CONFIG_CONSISTENT_SIZE=0x00200000 -CONFIG_NET=y - -# -# Networking options -# -CONFIG_COMPAT_NET_DEV_OPS=y -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_NET_DSA is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set -# CONFIG_DCB is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y -# CONFIG_WIRELESS_EXT is not set -# CONFIG_LIB80211 is not set -# CONFIG_MAC80211 is not set -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -CONFIG_CONNECTOR=y -CONFIG_PROC_EVENTS=y -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_TESTS is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_PHYSMAP_OF=y -# CONFIG_MTD_INTEL_VR_NOR is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_ONENAND is not set - -# -# LPDDR flash memory drivers -# -# CONFIG_MTD_LPDDR is not set -# CONFIG_MTD_QINFO_PROBE is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -CONFIG_OF_DEVICE=y -CONFIG_OF_I2C=y -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=35000 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_XILINX_SYSACE is not set -# CONFIG_BLK_DEV_HD is not set -# CONFIG_MISC_DEVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -CONFIG_CHR_DEV_SG=y -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -CONFIG_SCSI_SAS_ATTRS=y -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_LIBFC is not set -# CONFIG_FCOE is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set -# CONFIG_SCSI_DH is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -CONFIG_FUSION=y -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -CONFIG_FUSION_SAS=y -CONFIG_FUSION_MAX_SGE=128 -# CONFIG_FUSION_CTL is not set -# CONFIG_FUSION_LOGGING is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# Enable only one of the two stacks, unless you know what you are doing -# -# CONFIG_FIREWIRE is not set -# CONFIG_IEEE1394 is not set -CONFIG_I2O=y -CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y -CONFIG_I2O_EXT_ADAPTEC=y -# CONFIG_I2O_CONFIG is not set -# CONFIG_I2O_BUS is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set -# CONFIG_MACINTOSH_DRIVERS is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -# CONFIG_ARCNET is not set -# CONFIG_PHYLIB is not set -CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_IBM_NEW_EMAC=y -CONFIG_IBM_NEW_EMAC_RXB=256 -CONFIG_IBM_NEW_EMAC_TXB=256 -CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 -CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 -CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 -CONFIG_IBM_NEW_EMAC_DEBUG=y -CONFIG_IBM_NEW_EMAC_ZMII=y -CONFIG_IBM_NEW_EMAC_RGMII=y -CONFIG_IBM_NEW_EMAC_TAH=y -CONFIG_IBM_NEW_EMAC_EMAC4=y -# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -# CONFIG_NET_PCI is not set -# CONFIG_B44 is not set -# CONFIG_ATL2 is not set -CONFIG_NETDEV_1000=y -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -CONFIG_E1000E=y -# CONFIG_IP1000 is not set -# CONFIG_IGB is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set -# CONFIG_ATL1E is not set -# CONFIG_JME is not set -# CONFIG_NETDEV_10000 is not set -# CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_NR_UARTS=1 -CONFIG_SERIAL_8250_RUNTIME_UARTS=1 -CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set -CONFIG_SERIAL_8250_SHARE_IRQ=y -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_RSA is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_SERIAL_OF_PLATFORM=y -# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_HVC_UDBG is not set -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_NVRAM is not set -# CONFIG_GEN_RTC is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_HELPER_AUTO=y - -# -# I2C Hardware Bus support -# - -# -# PC SMBus host controller drivers -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_ISCH is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -CONFIG_I2C_IBM_IIC=y -# CONFIG_I2C_MPC is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_SIMTEC is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set - -# -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_DS1682 is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set -CONFIG_I2C_DEBUG_CORE=y -CONFIG_I2C_DEBUG_ALGO=y -CONFIG_I2C_DEBUG_BUS=y -CONFIG_I2C_DEBUG_CHIP=y -# CONFIG_SPI is not set -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -# CONFIG_GPIOLIB is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set -# CONFIG_WATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -CONFIG_DAB=y - -# -# Graphics support -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=m -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_SOUND is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_UWB is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -# CONFIG_EDAC is not set -# CONFIG_RTC_CLASS is not set -CONFIG_DMADEVICES=y - -# -# DMA Devices -# -# CONFIG_UIO is not set -# CONFIG_STAGING is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y -# CONFIG_SQUASHFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -CONFIG_ROOT_NFS=y -# CONFIG_NFSD is not set -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_SUNRPC_REGISTER_V4 is not set -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_NLS is not set -# CONFIG_DLM is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_LAST_BIT=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -# CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_HAVE_LMB=y - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y - -# -# Tracers -# -# CONFIG_FUNCTION_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_TRACE_BRANCH_PROFILING is not set -# CONFIG_STACK_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -CONFIG_PRINT_STACK_DEPTH=64 -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_CODE_PATCHING_SELFTEST is not set -# CONFIG_FTR_FIXUP_SELFTEST is not set -# CONFIG_MSI_BITMAP_SELFTEST is not set -# CONFIG_XMON is not set -# CONFIG_IRQSTACKS is not set -# CONFIG_VIRQ_DEBUG is not set -# CONFIG_BDI_SWITCH is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -# CONFIG_CRYPTO_FIPS is not set -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_GF128MUL=y -# CONFIG_CRYPTO_NULL is not set -CONFIG_CRYPTO_CRYPTD=y -CONFIG_CRYPTO_AUTHENC=y -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -CONFIG_CRYPTO_CCM=y -CONFIG_CRYPTO_GCM=y -CONFIG_CRYPTO_SEQIV=y - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_CTR=y -CONFIG_CRYPTO_CTS=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_LRW=y -CONFIG_CRYPTO_PCBC=y -CONFIG_CRYPTO_XTS=y - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_XCBC=y - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -CONFIG_CRYPTO_AES=y -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=y -CONFIG_CRYPTO_BLOWFISH=y -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_LZO is not set - -# -# Random Number Generation -# -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_HW=y -# CONFIG_CRYPTO_DEV_HIFN_795X is not set -# CONFIG_PPC_CLOCK is not set -# CONFIG_VIRTUALIZATION is not set diff --git a/trunk/arch/powerpc/configs/85xx/socrates_defconfig b/trunk/arch/powerpc/configs/85xx/socrates_defconfig deleted file mode 100644 index 0cc9048290a8..000000000000 --- a/trunk/arch/powerpc/configs/85xx/socrates_defconfig +++ /dev/null @@ -1,1410 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.26.2 -# Sat Oct 18 11:06:13 2008 -# -# CONFIG_PPC64 is not set - -# -# Processor support -# -# CONFIG_6xx is not set -CONFIG_PPC_85xx=y -# CONFIG_PPC_8xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_E200 is not set -CONFIG_E500=y -CONFIG_BOOKE=y -CONFIG_FSL_BOOKE=y -CONFIG_FSL_EMB_PERFMON=y -# CONFIG_PHYS_64BIT is not set -CONFIG_SPE=y -# CONFIG_PPC_MM_SLICES is not set -CONFIG_PPC32=y -CONFIG_WORD_SIZE=32 -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_HARDIRQS=y -# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set -CONFIG_IRQ_PER_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_OF=y -CONFIG_PPC_UDBG_16550=y -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -CONFIG_DEFAULT_UIMAGE=y -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=16 -# CONFIG_CGROUPS is not set -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -# CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_SYSCTL_SYSCALL_CHECK=y -# CONFIG_KALLSYMS is not set -# CONFIG_HOTPLUG is not set -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -# CONFIG_EPOLL is not set -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLUB_DEBUG=y -# CONFIG_SLAB is not set -CONFIG_SLUB=y -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set -CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -# CONFIG_HAVE_DMA_ATTRS is not set -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y - -# -# Platform support -# -# CONFIG_PPC_MPC512x is not set -# CONFIG_PPC_MPC5121 is not set -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PQ2ADS is not set -CONFIG_MPC85xx=y -# CONFIG_MPC8540_ADS is not set -# CONFIG_MPC8560_ADS is not set -# CONFIG_MPC85xx_CDS is not set -# CONFIG_MPC85xx_MDS is not set -# CONFIG_MPC85xx_DS is not set -CONFIG_SOCRATES=y -# CONFIG_KSI8560 is not set -# CONFIG_STX_GP3 is not set -# CONFIG_TQM8540 is not set -# CONFIG_TQM8541 is not set -# CONFIG_TQM8555 is not set -# CONFIG_TQM8560 is not set -# CONFIG_SBC8548 is not set -# CONFIG_SBC8560 is not set -# CONFIG_IPIC is not set -CONFIG_MPIC=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set -# CONFIG_FSL_ULI1575 is not set - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -# CONFIG_TICK_ONESHOT is not set -# CONFIG_NO_HZ is not set -# CONFIG_HIGH_RES_TIMERS is not set -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -# CONFIG_SCHED_HRTICK is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_MATH_EMULATION=y -# CONFIG_IOMMU_HELPER is not set -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_HAS_WALK_MEMORY=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -CONFIG_FORCE_MAX_ZONEORDER=11 -# CONFIG_PROC_DEVICETREE is not set -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_ZONE_DMA=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_FSL_SOC=y -CONFIG_FSL_PCI=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_SYSCALL=y -# CONFIG_PCIEPORTBUS is not set -CONFIG_ARCH_SUPPORTS_MSI=y -# CONFIG_PCI_MSI is not set -CONFIG_PCI_LEGACY=y -# CONFIG_HAS_RAPIDIO is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_PAGE_OFFSET=0xc0000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_PHYSICAL_START=0x00000000 -CONFIG_PHYSICAL_ALIGN=0x10000000 -CONFIG_TASK_SIZE=0xc0000000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -CONFIG_CAN=y -CONFIG_CAN_RAW=y -CONFIG_CAN_BCM=y - -# -# CAN Device Drivers -# -# CONFIG_CAN_VCAN is not set -# CONFIG_CAN_OLD_DRIVERS is not set -# CONFIG_CAN_SLCAN is not set -CONFIG_CAN_SJA1000=y -CONFIG_CAN_SJA1000_MEM_OF=y -# CONFIG_CAN_EMS_PCI is not set -# CONFIG_CAN_IXXAT_PCI is not set -# CONFIG_CAN_PEAK_PCI is not set -# CONFIG_CAN_KVASER_PCI is not set -# CONFIG_CAN_MSCAN is not set -# CONFIG_CAN_DEBUG_DEVICES is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_PHYSMAP_OF=y -# CONFIG_MTD_INTEL_VR_NOR is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_DATAFLASH is not set -# CONFIG_MTD_M25P80 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -CONFIG_MTD_NAND=y -# CONFIG_MTD_NAND_VERIFY_WRITE is not set -# CONFIG_MTD_NAND_ECC_SMC is not set -# CONFIG_MTD_NAND_MUSEUM_IDS is not set -CONFIG_MTD_NAND_IDS=y -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_CAFE is not set -# CONFIG_MTD_NAND_NANDSIM is not set -# CONFIG_MTD_NAND_PLATFORM is not set -# CONFIG_MTD_ALAUDA is not set -# CONFIG_MTD_NAND_FSL_ELBC is not set -CONFIG_MTD_NAND_SOCRATES=y -# CONFIG_MTD_ONENAND is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -CONFIG_OF_DEVICE=y -CONFIG_OF_I2C=y -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=32768 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y -# CONFIG_PHANTOM is not set -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_ENCLOSURE_SERVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -# CONFIG_SCSI_LOWLEVEL is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# Enable only one of the two stacks, unless you know what you are doing -# -# CONFIG_FIREWIRE is not set -# CONFIG_IEEE1394 is not set -# CONFIG_I2O is not set -# CONFIG_MACINTOSH_DRIVERS is not set -CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -# CONFIG_ARCNET is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=y -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_ENC28J60 is not set -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_NET_PCI is not set -# CONFIG_B44 is not set -CONFIG_NETDEV_1000=y -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_E1000E is not set -# CONFIG_E1000E_ENABLED is not set -# CONFIG_IP1000 is not set -# CONFIG_IGB is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_GIANFAR=y -CONFIG_GFAR_NAPI=y -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set -# CONFIG_NETDEV_10000 is not set -# CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=800 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 -# CONFIG_INPUT_JOYDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_TOUCHSCREEN_ADS7846 is not set -# CONFIG_TOUCHSCREEN_FUJITSU is not set -# CONFIG_TOUCHSCREEN_GUNZE is not set -# CONFIG_TOUCHSCREEN_ELO is not set -# CONFIG_TOUCHSCREEN_MTOUCH is not set -# CONFIG_TOUCHSCREEN_MK712 is not set -# CONFIG_TOUCHSCREEN_PENMOUNT is not set -# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set -# CONFIG_TOUCHSCREEN_TOUCHWIN is not set -# CONFIG_TOUCHSCREEN_UCB1400 is not set -CONFIG_TOUCHSCREEN_TSC2003=y -# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_OF_PLATFORM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_NVRAM is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -CONFIG_I2C_MPC=y -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_TINY_USB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_PLATFORM is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_DS1682 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set -CONFIG_SPI=y -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -# CONFIG_SPI_BITBANG is not set -CONFIG_SPI_SOCRATES=y - -# -# SPI Protocol Masters -# -# CONFIG_SPI_AT25 is not set -# CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -CONFIG_HWMON=y -CONFIG_HWMON_VID=y -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_I5K_AMB is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM70 is not set -CONFIG_SENSORS_LM75=y -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -CONFIG_SENSORS_W83781D=y -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -CONFIG_HWMON_DEBUG_CHIP=y -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set -# CONFIG_WATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set - -# -# Graphics support -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB_DDC is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -CONFIG_FB_FOREIGN_ENDIAN=y -CONFIG_FB_BOTH_ENDIAN=y -# CONFIG_FB_BIG_ENDIAN is not set -# CONFIG_FB_LITTLE_ENDIAN is not set -# CONFIG_FB_SYS_FOPS is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# -CONFIG_FB_MB862XX=y -# CONFIG_FB_MB862XX_PCI_GDC is not set -CONFIG_FB_MB862XX_LIME=y -# CONFIG_FB_PRE_INIT_FB is not set -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_OF is not set -# CONFIG_FB_CT65550 is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_IMSTT is not set -# CONFIG_FB_VGA16 is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_RADEON is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_S3 is not set -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_VT8623 is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_ARK is not set -# CONFIG_FB_PM3 is not set -# CONFIG_FB_FSL_DIU is not set -# CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_FB_VIRTUAL is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -CONFIG_FONTS=y -# CONFIG_FONT_8x8 is not set -CONFIG_FONT_8x16=y -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_7x14 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set -# CONFIG_FONT_MINI_4x6 is not set -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_SUN12x22 is not set -# CONFIG_FONT_10x18 is not set -# CONFIG_LOGO is not set - -# -# Sound -# -# CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set -# CONFIG_USB_EHCI_FSL is not set -CONFIG_USB_EHCI_HCD_PPC_OF=y -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_HCD_PPC_OF=y -CONFIG_USB_OHCI_HCD_PPC_OF_BE=y -# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set -CONFIG_USB_OHCI_HCD_PCI=y -CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y -CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_GADGET is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -# CONFIG_EDAC is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -CONFIG_RTC_DRV_RX8025=y - -# -# SPI RTC drivers -# -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RS5C348 is not set - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -CONFIG_RTC_DRV_PPC=y -# CONFIG_DMADEVICES is not set -# CONFIG_UIO is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -# CONFIG_JFFS2_LZO is not set -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_SUNRPC_BIND34 is not set -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SYSV68_PARTITION is not set -# CONFIG_NLS is not set -# CONFIG_DLM is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_HAVE_LMB=y - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_SAMPLES is not set -# CONFIG_IRQSTACKS is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -# CONFIG_CRYPTO_MANAGER is not set -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -# CONFIG_CRYPTO_CBC is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_LZO is not set -CONFIG_CRYPTO_HW=y -# CONFIG_CRYPTO_DEV_HIFN_795X is not set -# CONFIG_PPC_CLOCK is not set -# CONFIG_VIRTUALIZATION is not set diff --git a/trunk/arch/powerpc/configs/86xx/gef_ppc9a_defconfig b/trunk/arch/powerpc/configs/86xx/gef_ppc9a_defconfig deleted file mode 100644 index df2c16337794..000000000000 --- a/trunk/arch/powerpc/configs/86xx/gef_ppc9a_defconfig +++ /dev/null @@ -1,1889 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.29-rc7 -# Fri Mar 13 15:36:11 2009 -# -# CONFIG_PPC64 is not set - -# -# Processor support -# -CONFIG_6xx=y -# CONFIG_PPC_85xx is not set -# CONFIG_PPC_8xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_E200 is not set -CONFIG_PPC_FPU=y -# CONFIG_PHYS_64BIT is not set -CONFIG_ALTIVEC=y -CONFIG_PPC_STD_MMU=y -CONFIG_PPC_STD_MMU_32=y -# CONFIG_PPC_MM_SLICES is not set -CONFIG_SMP=y -CONFIG_NR_CPUS=2 -CONFIG_PPC32=y -CONFIG_WORD_SIZE=32 -# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -CONFIG_MMU=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_HARDIRQS=y -# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set -CONFIG_IRQ_PER_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_LOCKBREAK=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_GPIO=y -# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_OF=y -CONFIG_PPC_UDBG_16550=y -CONFIG_GENERIC_TBSYNC=y -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -CONFIG_DEFAULT_UIMAGE=y -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set - -# -# RCU Subsystem -# -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set -# CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -CONFIG_RELAY=y -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_PCI_QUIRKS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_IOREMAP_PROT=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_USE_GENERIC_SMP_HELPERS=y -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_STOP_MACHINE=y -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -# CONFIG_FREEZER is not set - -# -# Platform support -# -CONFIG_PPC_MULTIPLATFORM=y -CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_MPC5121_ADS is not set -# CONFIG_MPC5121_GENERIC is not set -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_PMAC is not set -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PPC_82xx is not set -# CONFIG_PQ2ADS is not set -# CONFIG_PPC_83xx is not set -CONFIG_PPC_86xx=y -# CONFIG_MPC8641_HPCN is not set -# CONFIG_SBC8641D is not set -# CONFIG_MPC8610_HPCD is not set -CONFIG_GEF_PPC9A=y -# CONFIG_GEF_SBC310 is not set -# CONFIG_GEF_SBC610 is not set -CONFIG_MPC8641=y -# CONFIG_IPIC is not set -CONFIG_MPIC=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_TAU is not set -# CONFIG_QUICC_ENGINE is not set -# CONFIG_FSL_ULI1575 is not set -# CONFIG_MPC8xxx_GPIO is not set -# CONFIG_SIMPLE_GPIO is not set - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -CONFIG_TICK_ONESHOT=y -# CONFIG_NO_HZ is not set -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_100 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_300 is not set -CONFIG_HZ_1000=y -CONFIG_HZ=1000 -CONFIG_SCHED_HRTICK=y -# CONFIG_PREEMPT_NONE is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREEMPT=y -CONFIG_BINFMT_ELF=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -# CONFIG_HAVE_AOUT is not set -CONFIG_BINFMT_MISC=m -# CONFIG_IOMMU_HELPER is not set -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_HAS_WALK_MEMORY=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y -# CONFIG_KEXEC is not set -# CONFIG_CRASH_DUMP is not set -CONFIG_IRQ_ALL_CPUS=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_MIGRATION=y -# CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -CONFIG_UNEVICTABLE_LRU=y -CONFIG_PPC_4K_PAGES=y -# CONFIG_PPC_16K_PAGES is not set -# CONFIG_PPC_64K_PAGES is not set -CONFIG_FORCE_MAX_ZONEORDER=11 -# CONFIG_PROC_DEVICETREE is not set -# CONFIG_CMDLINE_BOOL is not set -CONFIG_EXTRA_TARGETS="" -# CONFIG_PM is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_ZONE_DMA=y -CONFIG_GENERIC_ISA_DMA=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_FSL_SOC=y -CONFIG_FSL_PCI=y -CONFIG_PPC_PCI_CHOICE=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_SYSCALL=y -CONFIG_PCIEPORTBUS=y -CONFIG_PCIEAER=y -# CONFIG_PCIEASPM is not set -CONFIG_ARCH_SUPPORTS_MSI=y -# CONFIG_PCI_MSI is not set -# CONFIG_PCI_LEGACY is not set -CONFIG_PCI_DEBUG=y -# CONFIG_PCI_STUB is not set -# CONFIG_PCCARD is not set -# CONFIG_HOTPLUG_PCI is not set -# CONFIG_HAS_RAPIDIO is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_PAGE_OFFSET=0xc0000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_PHYSICAL_START=0x00000000 -CONFIG_TASK_SIZE=0xc0000000 -CONFIG_NET=y - -# -# Networking options -# -CONFIG_COMPAT_NET_DEV_OPS=y -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=m -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -CONFIG_XFRM_IPCOMP=m -CONFIG_NET_KEY=m -# CONFIG_NET_KEY_MIGRATE is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_ASK_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -CONFIG_INET_XFRM_TUNNEL=m -CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -CONFIG_IPV6=m -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -# CONFIG_IPV6_MIP6 is not set -CONFIG_INET6_XFRM_TUNNEL=m -CONFIG_INET6_TUNNEL=m -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=m -CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=m -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_IPV6_MROUTE is not set -# CONFIG_NETLABEL is not set -# CONFIG_NETWORK_SECMARK is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_NETFILTER_ADVANCED=y -CONFIG_BRIDGE_NETFILTER=y - -# -# Core Netfilter Configuration -# -# CONFIG_NETFILTER_NETLINK_QUEUE is not set -# CONFIG_NETFILTER_NETLINK_LOG is not set -# CONFIG_NF_CONNTRACK is not set -CONFIG_NETFILTER_XTABLES=m -# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -# CONFIG_NETFILTER_XT_TARGET_MARK is not set -# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set -# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set -# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set -# CONFIG_NETFILTER_XT_TARGET_TRACE is not set -# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set -# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set -# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set -# CONFIG_NETFILTER_XT_MATCH_DCCP is not set -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -# CONFIG_NETFILTER_XT_MATCH_ESP is not set -# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set -# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set -# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_MAC is not set -# CONFIG_NETFILTER_XT_MATCH_MARK is not set -# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set -# CONFIG_NETFILTER_XT_MATCH_OWNER is not set -# CONFIG_NETFILTER_XT_MATCH_POLICY is not set -# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set -# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set -# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set -# CONFIG_NETFILTER_XT_MATCH_REALM is not set -# CONFIG_NETFILTER_XT_MATCH_RECENT is not set -# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set -# CONFIG_NETFILTER_XT_MATCH_STRING is not set -# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set -# CONFIG_NETFILTER_XT_MATCH_TIME is not set -# CONFIG_NETFILTER_XT_MATCH_U32 is not set -# CONFIG_IP_VS is not set - -# -# IP: Netfilter Configuration -# -# CONFIG_NF_DEFRAG_IPV4 is not set -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m -# CONFIG_IP_NF_MATCH_AH is not set -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_ECN=m -# CONFIG_IP_NF_TARGET_TTL is not set -CONFIG_IP_NF_RAW=m -# CONFIG_IP_NF_SECURITY is not set -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m - -# -# IPv6: Netfilter Configuration -# -CONFIG_IP6_NF_QUEUE=m -CONFIG_IP6_NF_IPTABLES=m -# CONFIG_IP6_NF_MATCH_AH is not set -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -# CONFIG_IP6_NF_MATCH_MH is not set -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_TARGET_LOG=m -CONFIG_IP6_NF_FILTER=m -# CONFIG_IP6_NF_TARGET_REJECT is not set -CONFIG_IP6_NF_MANGLE=m -# CONFIG_IP6_NF_TARGET_HL is not set -CONFIG_IP6_NF_RAW=m -# CONFIG_IP6_NF_SECURITY is not set -# CONFIG_BRIDGE_NF_EBTABLES is not set -# CONFIG_IP_DCCP is not set -CONFIG_IP_SCTP=m -# CONFIG_SCTP_DBG_MSG is not set -# CONFIG_SCTP_DBG_OBJCNT is not set -# CONFIG_SCTP_HMAC_NONE is not set -# CONFIG_SCTP_HMAC_SHA1 is not set -CONFIG_SCTP_HMAC_MD5=y -CONFIG_TIPC=m -# CONFIG_TIPC_ADVANCED is not set -# CONFIG_TIPC_DEBUG is not set -CONFIG_ATM=m -CONFIG_ATM_CLIP=m -# CONFIG_ATM_CLIP_NO_ICMP is not set -CONFIG_ATM_LANE=m -CONFIG_ATM_MPOA=m -CONFIG_ATM_BR2684=m -# CONFIG_ATM_BR2684_IPFILTER is not set -CONFIG_STP=m -CONFIG_BRIDGE=m -# CONFIG_NET_DSA is not set -CONFIG_VLAN_8021Q=m -# CONFIG_VLAN_8021Q_GVRP is not set -# CONFIG_DECNET is not set -CONFIG_LLC=m -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -CONFIG_WAN_ROUTER=m -CONFIG_NET_SCHED=y - -# -# Queueing/Scheduling -# -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_ATM=m -CONFIG_NET_SCH_PRIO=m -# CONFIG_NET_SCH_MULTIQ is not set -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_NETEM=m -# CONFIG_NET_SCH_DRR is not set - -# -# Classification -# -CONFIG_NET_CLS=y -# CONFIG_NET_CLS_BASIC is not set -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -# CONFIG_CLS_U32_PERF is not set -# CONFIG_CLS_U32_MARK is not set -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -# CONFIG_NET_CLS_FLOW is not set -# CONFIG_NET_EMATCH is not set -# CONFIG_NET_CLS_ACT is not set -# CONFIG_NET_CLS_IND is not set -CONFIG_NET_SCH_FIFO=y -# CONFIG_DCB is not set - -# -# Network testing -# -CONFIG_NET_PKTGEN=m -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_FIB_RULES=y -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y -# CONFIG_WIRELESS_EXT is not set -# CONFIG_LIB80211 is not set -# CONFIG_MAC80211 is not set -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_TESTS is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_PHYSMAP_OF=y -# CONFIG_MTD_INTEL_VR_NOR is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_ONENAND is not set - -# -# LPDDR flash memory drivers -# -# CONFIG_MTD_LPDDR is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -CONFIG_OF_DEVICE=y -CONFIG_OF_GPIO=y -CONFIG_OF_I2C=y -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_CRYPTOLOOP=m -CONFIG_BLK_DEV_NBD=m -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=131072 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_MISC_DEVICES=y -# CONFIG_PHANTOM is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HP_ILO is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_93CX6 is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_LIBFC is not set -# CONFIG_FCOE is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set -# CONFIG_SCSI_DH is not set -CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set -CONFIG_SATA_PMP=y -# CONFIG_SATA_AHCI is not set -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_FSL is not set -CONFIG_ATA_SFF=y -# CONFIG_SATA_SVW is not set -# CONFIG_ATA_PIIX is not set -# CONFIG_SATA_MV is not set -# CONFIG_SATA_NV is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -CONFIG_SATA_SIL=y -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set -# CONFIG_SATA_INIC162X is not set -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD640_PCI is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_IT8213 is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MARVELL is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NINJA32 is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_NS87415 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set -# CONFIG_PATA_PLATFORM is not set -# CONFIG_PATA_SCH is not set -# CONFIG_MD is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# Enable only one of the two stacks, unless you know what you are doing -# -# CONFIG_FIREWIRE is not set -# CONFIG_IEEE1394 is not set -# CONFIG_I2O is not set -# CONFIG_MACINTOSH_DRIVERS is not set -CONFIG_NETDEVICES=y -CONFIG_DUMMY=m -CONFIG_BONDING=m -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=m -# CONFIG_VETH is not set -# CONFIG_ARCNET is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -# CONFIG_NET_PCI is not set -# CONFIG_B44 is not set -# CONFIG_ATL2 is not set -CONFIG_NETDEV_1000=y -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_E1000E is not set -# CONFIG_IP1000 is not set -# CONFIG_IGB is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_GIANFAR=y -# CONFIG_MV643XX_ETH is not set -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set -# CONFIG_ATL1E is not set -# CONFIG_ATL1C is not set -# CONFIG_JME is not set -# CONFIG_NETDEV_10000 is not set -# CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -# CONFIG_WAN is not set -CONFIG_ATM_DRIVERS=y -# CONFIG_ATM_DUMMY is not set -# CONFIG_ATM_TCP is not set -# CONFIG_ATM_LANAI is not set -# CONFIG_ATM_ENI is not set -# CONFIG_ATM_FIRESTREAM is not set -# CONFIG_ATM_ZATM is not set -# CONFIG_ATM_NICSTAR is not set -# CONFIG_ATM_IDT77252 is not set -# CONFIG_ATM_AMBASSADOR is not set -# CONFIG_ATM_HORIZON is not set -# CONFIG_ATM_IA is not set -# CONFIG_ATM_FORE200E is not set -# CONFIG_ATM_HE is not set -# CONFIG_ATM_SOLOS is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -CONFIG_PPP=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m -# CONFIG_PPP_MPPE is not set -CONFIG_PPPOE=m -CONFIG_PPPOATM=m -# CONFIG_PPPOL2TP is not set -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLHC=m -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y -# CONFIG_NET_FC is not set -CONFIG_NETCONSOLE=y -# CONFIG_NETCONSOLE_DYNAMIC is not set -CONFIG_NETPOLL=y -CONFIG_NETPOLL_TRAP=y -CONFIG_NET_POLL_CONTROLLER=y -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_OF_PLATFORM is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_HVC_UDBG is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -CONFIG_NVRAM=y -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_HELPER_AUTO=y - -# -# I2C Hardware Bus support -# - -# -# PC SMBus host controller drivers -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_ISCH is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_GPIO is not set -CONFIG_I2C_MPC=y -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_SIMTEC is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -CONFIG_DS1682=y -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set -# CONFIG_SPI is not set -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -CONFIG_ARCH_REQUIRE_GPIOLIB=y -CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set -# CONFIG_GPIO_SYSFS is not set - -# -# Memory mapped GPIO expanders: -# -# CONFIG_GPIO_XILINX is not set - -# -# I2C GPIO expanders: -# -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCF857X is not set - -# -# PCI GPIO expanders: -# -# CONFIG_GPIO_BT8XX is not set - -# -# SPI GPIO expanders: -# -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_AD7414 is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7462 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set -# CONFIG_SENSORS_ADT7475 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_I5K_AMB is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -CONFIG_SENSORS_LM90=y -CONFIG_SENSORS_LM92=y -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_LTC4245 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -# CONFIG_ALIM7101_WDT is not set -CONFIG_GEF_WDT=y -# CONFIG_8xxx_WDT is not set - -# -# PCI-based Watchdog Cards -# -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_WDTPCI is not set - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_TPS65010 is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set - -# -# Graphics support -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=m -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Console display driver support -# -CONFIG_VGA_CONSOLE=y -# CONFIG_VGACON_SOFT_SCROLLBACK is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_HID_PID is not set -# CONFIG_USB_HIDDEV is not set - -# -# Special HID drivers -# -CONFIG_HID_COMPAT=y -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_EZKEY=y -CONFIG_HID_GYRATION=y -CONFIG_HID_LOGITECH=y -# CONFIG_LOGITECH_FF is not set -# CONFIG_LOGIRUMBLEPAD2_FF is not set -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y -# CONFIG_HID_NTRIG is not set -CONFIG_HID_PANTHERLORD=y -# CONFIG_PANTHERLORD_FF is not set -CONFIG_HID_PETALYNX=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y -CONFIG_HID_SUNPLUS=y -# CONFIG_GREENASIA_FF is not set -# CONFIG_HID_TOPSEED is not set -CONFIG_THRUSTMASTER_FF=m -CONFIG_ZEROPLUS_FF=m -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -# CONFIG_USB_DEVICE_CLASS is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -# CONFIG_USB_MON is not set -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set -# CONFIG_USB_EHCI_FSL is not set -# CONFIG_USB_EHCI_HCD_PPC_OF is not set -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_HCD_PPC_OF is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_WHCI_HCD is not set -# CONFIG_USB_HWA_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set -# CONFIG_USB_TMC is not set - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; -# - -# -# see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB port drivers -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set -# CONFIG_USB_ATM is not set -# CONFIG_USB_GADGET is not set - -# -# OTG and related infrastructure -# -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_UWB is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -# CONFIG_EDAC is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -# CONFIG_RTC_INTF_PROC is not set -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -CONFIG_RTC_DRV_RX8581=y - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_RTC_DRV_PPC is not set -# CONFIG_DMADEVICES is not set -# CONFIG_UIO is not set -# CONFIG_STAGING is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -# CONFIG_EXT2_FS_SECURITY is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4_FS is not set -CONFIG_JBD=y -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_FILE_LOCKING=y -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -# CONFIG_JFFS2_LZO is not set -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -# CONFIG_NFSD is not set -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -# CONFIG_SUNRPC_REGISTER_V4 is not set -CONFIG_RPCSEC_GSS_KRB5=y -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -CONFIG_CIFS=m -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -CONFIG_CIFS_XATTR=y -CONFIG_CIFS_POSIX=y -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_EXPERIMENTAL is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m -# CONFIG_DLM is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_LAST_BIT=y -CONFIG_CRC_CCITT=m -# CONFIG_CRC16 is not set -# CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_HAVE_LMB=y - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y - -# -# Tracers -# -# CONFIG_FUNCTION_TRACER is not set -# CONFIG_PREEMPT_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_TRACE_BRANCH_PROFILING is not set -# CONFIG_STACK_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -CONFIG_PRINT_STACK_DEPTH=64 -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_CODE_PATCHING_SELFTEST is not set -# CONFIG_FTR_FIXUP_SELFTEST is not set -# CONFIG_MSI_BITMAP_SELFTEST is not set -# CONFIG_XMON is not set -# CONFIG_IRQSTACKS is not set -# CONFIG_BDI_SWITCH is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -CONFIG_SECURITY=y -# CONFIG_SECURITYFS is not set -CONFIG_SECURITY_NETWORK=y -# CONFIG_SECURITY_NETWORK_XFRM is not set -# CONFIG_SECURITY_PATH is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -# CONFIG_SECURITY_ROOTPLUG is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -# CONFIG_CRYPTO_FIPS is not set -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=m -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -# CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_NULL=m -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_AUTHENC=m -CONFIG_CRYPTO_TEST=m - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=m -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_MICHAEL_MIC=m -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -# CONFIG_CRYPTO_TGR192 is not set -CONFIG_CRYPTO_WP512=m - -# -# Ciphers -# -CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_BLOWFISH=m -# CONFIG_CRYPTO_CAMELLIA is not set -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -CONFIG_CRYPTO_KHAZAD=m -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=m -# CONFIG_CRYPTO_LZO is not set - -# -# Random Number Generation -# -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_HW is not set -# CONFIG_PPC_CLOCK is not set -# CONFIG_VIRTUALIZATION is not set diff --git a/trunk/arch/powerpc/configs/86xx/gef_sbc310_defconfig b/trunk/arch/powerpc/configs/86xx/gef_sbc310_defconfig deleted file mode 100644 index bd236b3d915a..000000000000 --- a/trunk/arch/powerpc/configs/86xx/gef_sbc310_defconfig +++ /dev/null @@ -1,1613 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.29-rc3 -# Wed Jan 28 23:05:34 2009 -# -# CONFIG_PPC64 is not set - -# -# Processor support -# -CONFIG_6xx=y -# CONFIG_PPC_85xx is not set -# CONFIG_PPC_8xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_E200 is not set -CONFIG_PPC_FPU=y -# CONFIG_PHYS_64BIT is not set -CONFIG_ALTIVEC=y -CONFIG_PPC_STD_MMU=y -CONFIG_PPC_STD_MMU_32=y -# CONFIG_PPC_MM_SLICES is not set -CONFIG_SMP=y -CONFIG_NR_CPUS=2 -CONFIG_PPC32=y -CONFIG_WORD_SIZE=32 -# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -CONFIG_MMU=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_HARDIRQS=y -# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set -CONFIG_IRQ_PER_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_LOCKBREAK=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_GPIO=y -# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_OF=y -CONFIG_PPC_UDBG_16550=y -CONFIG_GENERIC_TBSYNC=y -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -CONFIG_DEFAULT_UIMAGE=y -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set - -# -# RCU Subsystem -# -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set -# CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -CONFIG_RELAY=y -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_PCI_QUIRKS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_IOREMAP_PROT=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_USE_GENERIC_SMP_HELPERS=y -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_STOP_MACHINE=y -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -# CONFIG_FREEZER is not set -CONFIG_PPC_MSI_BITMAP=y - -# -# Platform support -# -CONFIG_PPC_MULTIPLATFORM=y -CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_MPC5121_ADS is not set -# CONFIG_MPC5121_GENERIC is not set -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_PMAC is not set -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PPC_82xx is not set -# CONFIG_PQ2ADS is not set -# CONFIG_PPC_83xx is not set -CONFIG_PPC_86xx=y -# CONFIG_MPC8641_HPCN is not set -# CONFIG_SBC8641D is not set -# CONFIG_MPC8610_HPCD is not set -CONFIG_GEF_SBC310=y -# CONFIG_GEF_SBC610 is not set -CONFIG_MPC8641=y -# CONFIG_IPIC is not set -CONFIG_MPIC=y -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_TAU is not set -# CONFIG_QUICC_ENGINE is not set -# CONFIG_FSL_ULI1575 is not set -# CONFIG_MPC8xxx_GPIO is not set -# CONFIG_SIMPLE_GPIO is not set - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -CONFIG_TICK_ONESHOT=y -# CONFIG_NO_HZ is not set -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_100 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_300 is not set -CONFIG_HZ_1000=y -CONFIG_HZ=1000 -CONFIG_SCHED_HRTICK=y -# CONFIG_PREEMPT_NONE is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREEMPT=y -CONFIG_BINFMT_ELF=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -# CONFIG_HAVE_AOUT is not set -CONFIG_BINFMT_MISC=y -# CONFIG_IOMMU_HELPER is not set -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_HAS_WALK_MEMORY=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y -# CONFIG_KEXEC is not set -# CONFIG_CRASH_DUMP is not set -CONFIG_IRQ_ALL_CPUS=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_MIGRATION=y -# CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -CONFIG_UNEVICTABLE_LRU=y -CONFIG_PPC_4K_PAGES=y -# CONFIG_PPC_16K_PAGES is not set -# CONFIG_PPC_64K_PAGES is not set -CONFIG_FORCE_MAX_ZONEORDER=11 -# CONFIG_PROC_DEVICETREE is not set -# CONFIG_CMDLINE_BOOL is not set -CONFIG_EXTRA_TARGETS="" -# CONFIG_PM is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_ZONE_DMA=y -CONFIG_GENERIC_ISA_DMA=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_FSL_SOC=y -CONFIG_FSL_PCI=y -CONFIG_PPC_PCI_CHOICE=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_SYSCALL=y -CONFIG_PCIEPORTBUS=y -CONFIG_PCIEAER=y -# CONFIG_PCIEASPM is not set -CONFIG_ARCH_SUPPORTS_MSI=y -CONFIG_PCI_MSI=y -# CONFIG_PCI_LEGACY is not set -# CONFIG_PCI_STUB is not set -# CONFIG_PCCARD is not set -# CONFIG_HOTPLUG_PCI is not set -# CONFIG_HAS_RAPIDIO is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_LOWMEM_CAM_NUM=3 -CONFIG_PAGE_OFFSET=0xc0000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_PHYSICAL_START=0x00000000 -CONFIG_TASK_SIZE=0xc0000000 -CONFIG_NET=y - -# -# Networking options -# -CONFIG_COMPAT_NET_DEV_OPS=y -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=m -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -CONFIG_XFRM_IPCOMP=m -CONFIG_NET_KEY=m -# CONFIG_NET_KEY_MIGRATE is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_ASK_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -CONFIG_INET_XFRM_TUNNEL=m -CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -# CONFIG_INET_XFRM_MODE_BEET is not set -CONFIG_INET_LRO=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -CONFIG_IPV6=m -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -# CONFIG_IPV6_MIP6 is not set -CONFIG_INET6_XFRM_TUNNEL=m -CONFIG_INET6_TUNNEL=m -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=m -CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=m -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_IPV6_MROUTE is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_NET_DSA is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set -# CONFIG_DCB is not set - -# -# Network testing -# -CONFIG_NET_PKTGEN=m -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_FIB_RULES=y -# CONFIG_WIRELESS is not set -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_TESTS is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_PHYSMAP_OF=y -# CONFIG_MTD_INTEL_VR_NOR is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_ONENAND is not set - -# -# LPDDR flash memory drivers -# -# CONFIG_MTD_LPDDR is not set -# CONFIG_MTD_QINFO_PROBE is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -CONFIG_OF_DEVICE=y -CONFIG_OF_GPIO=y -CONFIG_OF_I2C=y -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_CRYPTOLOOP=m -CONFIG_BLK_DEV_NBD=m -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=131072 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_MISC_DEVICES=y -# CONFIG_PHANTOM is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HP_ILO is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_93CX6 is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_LIBFC is not set -# CONFIG_FCOE is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set -# CONFIG_SCSI_DH is not set -CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set -CONFIG_SATA_PMP=y -# CONFIG_SATA_AHCI is not set -CONFIG_SATA_SIL24=y -# CONFIG_SATA_FSL is not set -# CONFIG_ATA_SFF is not set -# CONFIG_MD is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# Enable only one of the two stacks, unless you know what you are doing -# -# CONFIG_FIREWIRE is not set -# CONFIG_IEEE1394 is not set -# CONFIG_I2O is not set -# CONFIG_MACINTOSH_DRIVERS is not set -CONFIG_NETDEVICES=y -CONFIG_DUMMY=m -CONFIG_BONDING=m -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=m -# CONFIG_VETH is not set -# CONFIG_ARCNET is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -# CONFIG_NET_PCI is not set -# CONFIG_B44 is not set -# CONFIG_ATL2 is not set -CONFIG_NETDEV_1000=y -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_E1000E is not set -# CONFIG_IP1000 is not set -# CONFIG_IGB is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_GIANFAR=y -# CONFIG_MV643XX_ETH is not set -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set -# CONFIG_ATL1E is not set -# CONFIG_JME is not set -# CONFIG_NETDEV_10000 is not set -# CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -CONFIG_PPP=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m -# CONFIG_PPP_MPPE is not set -CONFIG_PPPOE=m -# CONFIG_PPPOL2TP is not set -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLHC=m -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y -# CONFIG_NET_FC is not set -CONFIG_NETCONSOLE=y -# CONFIG_NETCONSOLE_DYNAMIC is not set -CONFIG_NETPOLL=y -CONFIG_NETPOLL_TRAP=y -CONFIG_NET_POLL_CONTROLLER=y -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_OF_PLATFORM is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_HVC_UDBG is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -CONFIG_NVRAM=y -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_HELPER_AUTO=y - -# -# I2C Hardware Bus support -# - -# -# PC SMBus host controller drivers -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_ISCH is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_GPIO is not set -CONFIG_I2C_MPC=y -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_SIMTEC is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -CONFIG_DS1682=y -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set -# CONFIG_SPI is not set -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -CONFIG_ARCH_REQUIRE_GPIOLIB=y -CONFIG_GPIOLIB=y -CONFIG_GPIO_SYSFS=y - -# -# Memory mapped GPIO expanders: -# -# CONFIG_GPIO_XILINX is not set - -# -# I2C GPIO expanders: -# -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCF857X is not set - -# -# PCI GPIO expanders: -# -# CONFIG_GPIO_BT8XX is not set - -# -# SPI GPIO expanders: -# -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_AD7414 is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7462 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set -# CONFIG_SENSORS_ADT7475 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_I5K_AMB is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -CONFIG_SENSORS_LM90=y -CONFIG_SENSORS_LM92=y -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_LTC4245 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -# CONFIG_ALIM7101_WDT is not set -CONFIG_GEF_WDT=y -# CONFIG_8xxx_WDT is not set - -# -# PCI-based Watchdog Cards -# -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_WDTPCI is not set - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_TPS65010 is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set - -# -# Graphics support -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=m -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Console display driver support -# -CONFIG_VGA_CONSOLE=y -# CONFIG_VGACON_SOFT_SCROLLBACK is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_HID_PID is not set -# CONFIG_USB_HIDDEV is not set - -# -# Special HID drivers -# -CONFIG_HID_COMPAT=y -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_EZKEY=y -CONFIG_HID_GYRATION=y -CONFIG_HID_LOGITECH=y -# CONFIG_LOGITECH_FF is not set -# CONFIG_LOGIRUMBLEPAD2_FF is not set -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y -# CONFIG_HID_NTRIG is not set -CONFIG_HID_PANTHERLORD=y -# CONFIG_PANTHERLORD_FF is not set -CONFIG_HID_PETALYNX=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y -CONFIG_HID_SUNPLUS=y -# CONFIG_GREENASIA_FF is not set -# CONFIG_HID_TOPSEED is not set -# CONFIG_THRUSTMASTER_FF is not set -# CONFIG_ZEROPLUS_FF is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -# CONFIG_USB_DEVICE_CLASS is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -# CONFIG_USB_MON is not set -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set -# CONFIG_USB_EHCI_FSL is not set -# CONFIG_USB_EHCI_HCD_PPC_OF is not set -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_HCD_PPC_OF is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_WHCI_HCD is not set -# CONFIG_USB_HWA_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set -# CONFIG_USB_TMC is not set - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; -# - -# -# see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB port drivers -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set -# CONFIG_USB_GADGET is not set - -# -# OTG and related infrastructure -# -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_UWB is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -# CONFIG_EDAC is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -# CONFIG_RTC_INTF_PROC is not set -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -CONFIG_RTC_DRV_RX8581=y - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_RTC_DRV_PPC is not set -# CONFIG_DMADEVICES is not set -# CONFIG_UIO is not set -# CONFIG_STAGING is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -# CONFIG_EXT2_FS_SECURITY is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4_FS is not set -CONFIG_JBD=y -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_FILE_LOCKING=y -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=y -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_FAT_DEFAULT_IOCHARSET="ascii" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -# CONFIG_JFFS2_LZO is not set -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -# CONFIG_NFSD is not set -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -# CONFIG_SUNRPC_REGISTER_V4 is not set -CONFIG_RPCSEC_GSS_KRB5=y -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -CONFIG_CIFS=m -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -CONFIG_CIFS_XATTR=y -CONFIG_CIFS_POSIX=y -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_EXPERIMENTAL is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m -# CONFIG_DLM is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_LAST_BIT=y -CONFIG_CRC_CCITT=y -# CONFIG_CRC16 is not set -CONFIG_CRC_T10DIF=y -CONFIG_CRC_ITU_T=y -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -CONFIG_LIBCRC32C=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_HAVE_LMB=y - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_LATENCYTOP is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y - -# -# Tracers -# -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_PRINT_STACK_DEPTH=64 -# CONFIG_IRQSTACKS is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -# CONFIG_CRYPTO_FIPS is not set -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=m -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_AUTHENC=m -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=m -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -CONFIG_CRYPTO_CRC32C=y -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=m -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=m -# CONFIG_CRYPTO_LZO is not set - -# -# Random Number Generation -# -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_HW is not set -# CONFIG_PPC_CLOCK is not set -# CONFIG_VIRTUALIZATION is not set diff --git a/trunk/arch/powerpc/configs/amigaone_defconfig b/trunk/arch/powerpc/configs/amigaone_defconfig deleted file mode 100644 index b63cc38df6b1..000000000000 --- a/trunk/arch/powerpc/configs/amigaone_defconfig +++ /dev/null @@ -1,1636 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.29-rc3 -# Sun Feb 1 14:22:42 2009 -# -# CONFIG_PPC64 is not set - -# -# Processor support -# -CONFIG_6xx=y -# CONFIG_PPC_85xx is not set -# CONFIG_PPC_8xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_E200 is not set -CONFIG_PPC_FPU=y -CONFIG_ALTIVEC=y -CONFIG_PPC_STD_MMU=y -CONFIG_PPC_STD_MMU_32=y -# CONFIG_PPC_MM_SLICES is not set -# CONFIG_SMP is not set -CONFIG_NOT_COHERENT_CACHE=y -CONFIG_CHECK_CACHE_COHERENCY=y -CONFIG_PPC32=y -CONFIG_WORD_SIZE=32 -# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -CONFIG_MMU=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_HARDIRQS=y -# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set -CONFIG_IRQ_PER_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_OF=y -CONFIG_PPC_UDBG_16550=y -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -CONFIG_DEFAULT_UIMAGE=y -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set - -# -# RCU Subsystem -# -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=15 -# CONFIG_GROUP_SCHED is not set -# CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -# CONFIG_RELAY is not set -CONFIG_NAMESPACES=y -# CONFIG_UTS_NS is not set -# CONFIG_IPC_NS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set -# CONFIG_NET_NS is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -# CONFIG_EMBEDDED is not set -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_PCSPKR_PLATFORM=y -# CONFIG_COMPAT_BRK is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_PCI_QUIRKS=y -CONFIG_SLUB_DEBUG=y -# CONFIG_SLAB is not set -CONFIG_SLUB=y -# CONFIG_SLOB is not set -# CONFIG_PROFILING is not set -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_IOREMAP_PROT=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_BLOCK=y -CONFIG_LBD=y -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -# CONFIG_FREEZER is not set - -# -# Platform support -# -CONFIG_PPC_MULTIPLATFORM=y -CONFIG_CLASSIC32=y -# CONFIG_PPC_CHRP is not set -# CONFIG_MPC5121_ADS is not set -# CONFIG_MPC5121_GENERIC is not set -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_PMAC is not set -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PPC_82xx is not set -# CONFIG_PQ2ADS is not set -# CONFIG_PPC_83xx is not set -# CONFIG_PPC_86xx is not set -# CONFIG_EMBEDDED6xx is not set -CONFIG_AMIGAONE=y -# CONFIG_IPIC is not set -# CONFIG_MPIC is not set -# CONFIG_MPIC_WEIRD is not set -CONFIG_PPC_I8259=y -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_TAU is not set -# CONFIG_FSL_ULI1575 is not set -# CONFIG_SIMPLE_GPIO is not set - -# -# Kernel options -# -CONFIG_HIGHMEM=y -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_SCHED_HRTICK=y -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -# CONFIG_HAVE_AOUT is not set -CONFIG_BINFMT_MISC=y -# CONFIG_IOMMU_HELPER is not set -CONFIG_PPC_NEED_DMA_SYNC_OPS=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_HAS_WALK_MEMORY=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y -# CONFIG_KEXEC is not set -# CONFIG_CRASH_DUMP is not set -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_MIGRATION is not set -# CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -CONFIG_UNEVICTABLE_LRU=y -CONFIG_PPC_4K_PAGES=y -# CONFIG_PPC_16K_PAGES is not set -# CONFIG_PPC_64K_PAGES is not set -CONFIG_FORCE_MAX_ZONEORDER=11 -CONFIG_PROC_DEVICETREE=y -# CONFIG_CMDLINE_BOOL is not set -CONFIG_EXTRA_TARGETS="" -# CONFIG_PM is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_ZONE_DMA=y -CONFIG_GENERIC_ISA_DMA=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_SYSCALL=y -# CONFIG_PCIEPORTBUS is not set -CONFIG_ARCH_SUPPORTS_MSI=y -# CONFIG_PCI_MSI is not set -# CONFIG_PCI_LEGACY is not set -# CONFIG_PCI_DEBUG is not set -# CONFIG_PCI_STUB is not set -# CONFIG_PCCARD is not set -# CONFIG_HOTPLUG_PCI is not set -# CONFIG_HAS_RAPIDIO is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_PAGE_OFFSET=0xc0000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_PHYSICAL_START=0x00000000 -CONFIG_TASK_SIZE=0xc0000000 -CONFIG_CONSISTENT_START=0xff100000 -CONFIG_CONSISTENT_SIZE=0x00200000 -CONFIG_NET=y - -# -# Networking options -# -CONFIG_COMPAT_NET_DEV_OPS=y -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_NETWORK_SECMARK is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -# CONFIG_NETFILTER_ADVANCED is not set - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_NETLINK_LOG=m -CONFIG_NF_CONNTRACK=m -CONFIG_NF_CONNTRACK_FTP=m -CONFIG_NF_CONNTRACK_IRC=m -CONFIG_NF_CONNTRACK_SIP=m -CONFIG_NF_CT_NETLINK=m -CONFIG_NETFILTER_XTABLES=m -# CONFIG_NETFILTER_XT_TARGET_MARK is not set -# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set -# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set -# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set -# CONFIG_NETFILTER_XT_MATCH_MARK is not set -# CONFIG_NETFILTER_XT_MATCH_STATE is not set -# CONFIG_IP_VS is not set - -# -# IP: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV4=m -CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_CONNTRACK_PROC_COMPAT=y -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m -# CONFIG_IP_NF_TARGET_ULOG is not set -CONFIG_NF_NAT=m -CONFIG_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_NF_NAT_FTP=m -CONFIG_NF_NAT_IRC=m -# CONFIG_NF_NAT_TFTP is not set -# CONFIG_NF_NAT_AMANDA is not set -# CONFIG_NF_NAT_PPTP is not set -# CONFIG_NF_NAT_H323 is not set -CONFIG_NF_NAT_SIP=m -# CONFIG_IP_NF_MANGLE is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_NET_DSA is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set -# CONFIG_DCB is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -# CONFIG_WIRELESS is not set -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_STANDALONE is not set -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set -CONFIG_OF_DEVICE=y -CONFIG_OF_I2C=y -CONFIG_PARPORT=y -CONFIG_PARPORT_PC=y -# CONFIG_PARPORT_SERIAL is not set -CONFIG_PARPORT_PC_FIFO=y -# CONFIG_PARPORT_PC_SUPERIO is not set -# CONFIG_PARPORT_GSC is not set -# CONFIG_PARPORT_AX88796 is not set -# CONFIG_PARPORT_1284 is not set -CONFIG_BLK_DEV=y -CONFIG_BLK_DEV_FD=y -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_XIP is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_MISC_DEVICES=y -# CONFIG_PHANTOM is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HP_ILO is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_93CX6 is not set -CONFIG_HAVE_IDE=y -CONFIG_IDE=y - -# -# Please see Documentation/ide/ide.txt for help/info on IDE drives -# -CONFIG_IDE_TIMINGS=y -CONFIG_IDE_ATAPI=y -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_IDE_GD=y -CONFIG_IDE_GD_ATA=y -# CONFIG_IDE_GD_ATAPI is not set -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_IDE_TASK_IOCTL is not set -CONFIG_IDE_PROC_FS=y - -# -# IDE chipset support/bugfixes -# -# CONFIG_BLK_DEV_PLATFORM is not set -CONFIG_BLK_DEV_IDEDMA_SFF=y - -# -# PCI IDE chipsets support -# -CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_IDEPCI_PCIBUS_ORDER is not set -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT8172 is not set -# CONFIG_BLK_DEV_IT8213 is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -CONFIG_BLK_DEV_SIIMAGE=y -# CONFIG_BLK_DEV_SL82C105 is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -# CONFIG_BLK_DEV_TC86C001 is not set -CONFIG_BLK_DEV_IDEDMA=y - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_CHR_DEV_SG=y -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -CONFIG_SCSI_SPI_ATTRS=y -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_LIBFC is not set -# CONFIG_FCOE is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_PPA is not set -# CONFIG_SCSI_IMM is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_STEX is not set -CONFIG_SCSI_SYM53C8XX_2=y -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -# CONFIG_SCSI_SYM53C8XX_MMIO is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set -# CONFIG_SCSI_DH is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# Enable only one of the two stacks, unless you know what you are doing -# -# CONFIG_FIREWIRE is not set -# CONFIG_IEEE1394 is not set -# CONFIG_I2O is not set -# CONFIG_MACINTOSH_DRIVERS is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -# CONFIG_ARCNET is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -CONFIG_NET_VENDOR_3COM=y -CONFIG_VORTEX=y -# CONFIG_TYPHOON is not set -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -CONFIG_8139CP=y -CONFIG_8139TOO=y -CONFIG_8139TOO_PIO=y -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_R6040 is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SMSC9420 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_SC92031 is not set -# CONFIG_NET_POCKET is not set -# CONFIG_ATL2 is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set -# CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -CONFIG_PPP=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_MPPE=m -CONFIG_PPPOE=m -# CONFIG_PPPOL2TP is not set -# CONFIG_SLIP is not set -CONFIG_SLHC=m -# CONFIG_NET_FC is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_LIFEBOOK=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_ELANTECH is not set -# CONFIG_MOUSE_PS2_TOUCHKIT is not set -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_APPLETOUCH is not set -# CONFIG_MOUSE_BCM5974 is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -CONFIG_INPUT_MISC=y -CONFIG_INPUT_PCSPKR=y -# CONFIG_INPUT_ATI_REMOTE is not set -# CONFIG_INPUT_ATI_REMOTE2 is not set -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_YEALINK is not set -# CONFIG_INPUT_CM109 is not set -CONFIG_INPUT_UINPUT=y - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PARKBD is not set -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_SERIO_XILINX_XPS_PS2 is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_OF_PLATFORM is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_PRINTER is not set -# CONFIG_PPDEV is not set -# CONFIG_HVC_UDBG is not set -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_NVRAM is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -# CONFIG_I2C_CHARDEV is not set -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_ALGOBIT=y - -# -# I2C Hardware Bus support -# - -# -# PC SMBus host controller drivers -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_ISCH is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_MPC is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_SIMTEC is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_PARPORT is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_DS1682 is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set -# CONFIG_SPI is not set -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -# CONFIG_GPIOLIB is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set -# CONFIG_WATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set - -# -# Graphics support -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -CONFIG_FB=y -CONFIG_FIRMWARE_EDID=y -CONFIG_FB_DDC=y -# CONFIG_FB_BOOT_VESA_SUPPORT is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -# CONFIG_FB_FOREIGN_ENDIAN is not set -# CONFIG_FB_SYS_FOPS is not set -# CONFIG_FB_SVGALIB is not set -CONFIG_FB_MACMODES=y -CONFIG_FB_BACKLIGHT=y -CONFIG_FB_MODE_HELPERS=y -CONFIG_FB_TILEBLITTING=y - -# -# Frame buffer hardware drivers -# -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_OF is not set -# CONFIG_FB_CT65550 is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_IMSTT is not set -# CONFIG_FB_VGA16 is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_MATROX is not set -CONFIG_FB_RADEON=y -CONFIG_FB_RADEON_I2C=y -CONFIG_FB_RADEON_BACKLIGHT=y -# CONFIG_FB_RADEON_DEBUG is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_S3 is not set -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_VIA is not set -# CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set -CONFIG_FB_3DFX=y -# CONFIG_FB_3DFX_ACCEL is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_VT8623 is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_ARK is not set -# CONFIG_FB_PM3 is not set -# CONFIG_FB_CARMINE is not set -# CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MB862XX is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=m -# CONFIG_LCD_ILI9320 is not set -# CONFIG_LCD_PLATFORM is not set -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BACKLIGHT_GENERIC=y - -# -# Display device support -# -CONFIG_DISPLAY_SUPPORT=m - -# -# Display hardware drivers -# - -# -# Console display driver support -# -CONFIG_VGA_CONSOLE=y -# CONFIG_VGACON_SOFT_SCROLLBACK is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_MONO=y -CONFIG_LOGO_LINUX_VGA16=y -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_HID_PID is not set -# CONFIG_USB_HIDDEV is not set - -# -# Special HID drivers -# -CONFIG_HID_COMPAT=y -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_EZKEY=y -CONFIG_HID_GYRATION=y -CONFIG_HID_LOGITECH=y -# CONFIG_LOGITECH_FF is not set -# CONFIG_LOGIRUMBLEPAD2_FF is not set -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y -CONFIG_HID_NTRIG=y -CONFIG_HID_PANTHERLORD=y -# CONFIG_PANTHERLORD_FF is not set -CONFIG_HID_PETALYNX=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y -CONFIG_HID_SUNPLUS=y -# CONFIG_GREENASIA_FF is not set -CONFIG_HID_TOPSEED=y -# CONFIG_THRUSTMASTER_FF is not set -# CONFIG_ZEROPLUS_FF is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set -CONFIG_USB_MON=y -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -# CONFIG_USB_EHCI_HCD is not set -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_HCD_PPC_OF is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -CONFIG_USB_UHCI_HCD=y -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_WHCI_HCD is not set -# CONFIG_USB_HWA_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set -# CONFIG_USB_TMC is not set - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; -# - -# -# see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=m -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set -# CONFIG_USB_GADGET is not set - -# -# OTG and related infrastructure -# -# CONFIG_UWB is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -# CONFIG_EDAC is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_RX8581 is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -CONFIG_RTC_DRV_CMOS=y -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_RTC_DRV_PPC is not set -# CONFIG_DMADEVICES is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_UIO is not set -# CONFIG_STAGING is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_EXT4_FS=y -# CONFIG_EXT4DEV_COMPAT is not set -CONFIG_EXT4_FS_XATTR=y -# CONFIG_EXT4_FS_POSIX_ACL is not set -# CONFIG_EXT4_FS_SECURITY is not set -CONFIG_JBD=y -CONFIG_JBD2=y -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -CONFIG_AFFS_FS=m -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -CONFIG_AMIGA_PARTITION=y -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SYSV68_PARTITION is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=m -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set -# CONFIG_DLM is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_LAST_BIT=y -CONFIG_CRC_CCITT=m -CONFIG_CRC16=y -CONFIG_CRC_T10DIF=y -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_HAVE_LMB=y - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_MUTEXES=y -CONFIG_DEBUG_SPINLOCK_SLEEP=y -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_HIGHMEM is not set -CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y - -# -# Tracers -# -# CONFIG_FUNCTION_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_TRACE_BRANCH_PROFILING is not set -# CONFIG_STACK_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -CONFIG_PRINT_STACK_DEPTH=64 -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_CODE_PATCHING_SELFTEST is not set -# CONFIG_FTR_FIXUP_SELFTEST is not set -# CONFIG_MSI_BITMAP_SELFTEST is not set -CONFIG_XMON=y -CONFIG_XMON_DEFAULT=y -CONFIG_XMON_DISASSEMBLY=y -CONFIG_DEBUGGER=y -CONFIG_IRQSTACKS=y -# CONFIG_BDI_SWITCH is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -# CONFIG_CRYPTO_FIPS is not set -CONFIG_CRYPTO_ALGAPI=m -CONFIG_CRYPTO_ALGAPI2=m -CONFIG_CRYPTO_AEAD2=m -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_BLKCIPHER2=m -CONFIG_CRYPTO_HASH=m -CONFIG_CRYPTO_HASH2=m -CONFIG_CRYPTO_RNG2=m -CONFIG_CRYPTO_MANAGER=m -CONFIG_CRYPTO_MANAGER2=m -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=m -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=m -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=m -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=m -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_LZO is not set - -# -# Random Number Generation -# -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_HW is not set -# CONFIG_PPC_CLOCK is not set -# CONFIG_VIRTUALIZATION is not set diff --git a/trunk/arch/powerpc/configs/mpc5200_defconfig b/trunk/arch/powerpc/configs/mpc5200_defconfig index af0cd55605d0..81afc8b373d7 100644 --- a/trunk/arch/powerpc/configs/mpc5200_defconfig +++ b/trunk/arch/powerpc/configs/mpc5200_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29-rc3 -# Fri Feb 6 09:48:53 2009 +# Linux kernel version: 2.6.29-rc2 +# Mon Jan 26 21:40:44 2009 # # CONFIG_PPC64 is not set @@ -388,10 +388,7 @@ CONFIG_MTD=y CONFIG_MTD_CONCAT=y CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_TESTS is not set -CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 -# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set -# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y # CONFIG_MTD_OF_PARTS is not set # CONFIG_MTD_AR7_PARTS is not set @@ -505,7 +502,7 @@ CONFIG_MISC_DEVICES=y # # EEPROM support # -CONFIG_EEPROM_AT24=y +# CONFIG_EEPROM_AT24 is not set # CONFIG_EEPROM_LEGACY is not set # CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y @@ -681,7 +678,7 @@ CONFIG_PHYLIB=y # CONFIG_MARVELL_PHY is not set # CONFIG_DAVICOM_PHY is not set # CONFIG_QSEMI_PHY is not set -CONFIG_LXT_PHY=y +# CONFIG_LXT_PHY is not set # CONFIG_CICADA_PHY is not set # CONFIG_VITESSE_PHY is not set # CONFIG_SMSC_PHY is not set @@ -818,6 +815,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_RAW_DRIVER is not set @@ -1282,61 +1281,7 @@ CONFIG_NEW_LEDS=y # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set # CONFIG_EDAC is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -CONFIG_RTC_DRV_DS1307=y -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_RX8581 is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_RTC_DRV_PPC is not set +# CONFIG_RTC_CLASS is not set # CONFIG_DMADEVICES is not set # CONFIG_UIO is not set # CONFIG_STAGING is not set diff --git a/trunk/arch/powerpc/configs/ppc64_defconfig b/trunk/arch/powerpc/configs/ppc64_defconfig index 252401824575..88c6295b76c1 100644 --- a/trunk/arch/powerpc/configs/ppc64_defconfig +++ b/trunk/arch/powerpc/configs/ppc64_defconfig @@ -2067,9 +2067,9 @@ CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_DEBUG_STACK_USAGE=y # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_HCALL_STATS is not set -CONFIG_CODE_PATCHING_SELFTEST=y -CONFIG_FTR_FIXUP_SELFTEST=y -CONFIG_MSI_BITMAP_SELFTEST=y +# CONFIG_CODE_PATCHING_SELFTEST is not set +# CONFIG_FTR_FIXUP_SELFTEST is not set +# CONFIG_MSI_BITMAP_SELFTEST is not set CONFIG_XMON=y # CONFIG_XMON_DEFAULT is not set CONFIG_XMON_DISASSEMBLY=y diff --git a/trunk/arch/powerpc/include/asm/code-patching.h b/trunk/arch/powerpc/include/asm/code-patching.h index 37c32aba79b7..107d9b915e33 100644 --- a/trunk/arch/powerpc/include/asm/code-patching.h +++ b/trunk/arch/powerpc/include/asm/code-patching.h @@ -11,7 +11,9 @@ */ #include -#include + +#define PPC_NOP_INSTR 0x60000000 +#define PPC_LWSYNC_INSTR 0x7c2004ac /* Flags for create_branch: * "b" == create_branch(addr, target, 0); diff --git a/trunk/arch/powerpc/include/asm/cputable.h b/trunk/arch/powerpc/include/asm/cputable.h index 80f315e8a421..21172badd708 100644 --- a/trunk/arch/powerpc/include/asm/cputable.h +++ b/trunk/arch/powerpc/include/asm/cputable.h @@ -145,7 +145,6 @@ extern const char *powerpc_base_platform; #define CPU_FTR_USE_TB ASM_CONST(0x0000000000000040) #define CPU_FTR_L2CSR ASM_CONST(0x0000000000000080) #define CPU_FTR_601 ASM_CONST(0x0000000000000100) -#define CPU_FTR_DBELL ASM_CONST(0x0000000000000200) #define CPU_FTR_CAN_NAP ASM_CONST(0x0000000000000400) #define CPU_FTR_L3CR ASM_CONST(0x0000000000000800) #define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x0000000000001000) @@ -376,8 +375,7 @@ extern const char *powerpc_base_platform; CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE) #define CPU_FTRS_E500MC (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \ - CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ - CPU_FTR_DBELL) + CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE) #define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) /* 64-bit CPUs */ diff --git a/trunk/arch/powerpc/include/asm/dbell.h b/trunk/arch/powerpc/include/asm/dbell.h deleted file mode 100644 index 501189a543d1..000000000000 --- a/trunk/arch/powerpc/include/asm/dbell.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2009 Freescale Semicondutor, Inc. - * - * 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. - * - * provides masks and opcode images for use by code generation, emulation - * and for instructions that older assemblers might not know about - */ -#ifndef _ASM_POWERPC_DBELL_H -#define _ASM_POWERPC_DBELL_H - -#include -#include - -#include - -#define PPC_DBELL_MSG_BRDCAST (0x04000000) -#define PPC_DBELL_TYPE(x) (((x) & 0xf) << 28) -enum ppc_dbell { - PPC_DBELL = 0, /* doorbell */ - PPC_DBELL_CRIT = 1, /* critical doorbell */ - PPC_G_DBELL = 2, /* guest doorbell */ - PPC_G_DBELL_CRIT = 3, /* guest critical doorbell */ - PPC_G_DBELL_MC = 4, /* guest mcheck doorbell */ -}; - -#ifdef CONFIG_SMP -extern unsigned long dbell_smp_message[NR_CPUS]; -extern void smp_dbell_message_pass(int target, int msg); -#endif - -static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag) -{ - u32 msg = PPC_DBELL_TYPE(type) | (flags & PPC_DBELL_MSG_BRDCAST) | - (tag & 0x07ffffff); - - __asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg)); -} - -#endif /* _ASM_POWERPC_DBELL_H */ diff --git a/trunk/arch/powerpc/include/asm/dma-mapping.h b/trunk/arch/powerpc/include/asm/dma-mapping.h index c69f2b5f0cc4..86cef7ddc8d5 100644 --- a/trunk/arch/powerpc/include/asm/dma-mapping.h +++ b/trunk/arch/powerpc/include/asm/dma-mapping.h @@ -109,8 +109,18 @@ static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) * only ISA DMA device we support is the floppy and we have a hack * in the floppy driver directly to get a device for us. */ - if (unlikely(dev == NULL)) + + if (unlikely(dev == NULL) || dev->archdata.dma_ops == NULL) { +#ifdef CONFIG_PPC64 return NULL; +#else + /* Use default on 32-bit if dma_ops is not set up */ + /* TODO: Long term, we should fix drivers so that dev and + * archdata dma_ops are set up for all buses. + */ + return &dma_direct_ops; +#endif + } return dev->archdata.dma_ops; } diff --git a/trunk/arch/powerpc/include/asm/elf.h b/trunk/arch/powerpc/include/asm/elf.h index 1a856b15226e..b5600ce6055e 100644 --- a/trunk/arch/powerpc/include/asm/elf.h +++ b/trunk/arch/powerpc/include/asm/elf.h @@ -8,7 +8,6 @@ #endif #include - #include #include #include @@ -179,8 +178,7 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[ELF_NVSRHALFREG]; the loader. We need to make sure that it is out of the way of the program that it will "exec", and that there is sufficient room for the brk. */ -extern unsigned long randomize_et_dyn(unsigned long base); -#define ELF_ET_DYN_BASE (randomize_et_dyn(0x20000000)) +#define ELF_ET_DYN_BASE (0x20000000) /* * Our registers are always unsigned longs, whether we're a 32 bit @@ -272,14 +270,6 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp); #define VDSO_AUX_ENT(a,b) NEW_AUX_ENT(a,b); -/* 1GB for 64bit, 8MB for 32bit */ -#define STACK_RND_MASK (is_32bit_task() ? \ - (0x7ff >> (PAGE_SHIFT - 12)) : \ - (0x3ffff >> (PAGE_SHIFT - 12))) - -extern unsigned long arch_randomize_brk(struct mm_struct *mm); -#define arch_randomize_brk arch_randomize_brk - #endif /* __KERNEL__ */ /* diff --git a/trunk/arch/powerpc/include/asm/fixmap.h b/trunk/arch/powerpc/include/asm/fixmap.h index d60fd18f428c..8428b38a3d30 100644 --- a/trunk/arch/powerpc/include/asm/fixmap.h +++ b/trunk/arch/powerpc/include/asm/fixmap.h @@ -61,7 +61,7 @@ extern void __set_fixmap (enum fixed_addresses idx, * Some hardware wants to get fixmapped without caching. */ #define set_fixmap_nocache(idx, phys) \ - __set_fixmap(idx, phys, PAGE_KERNEL_NCG) + __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE) #define clear_fixmap(idx) \ __set_fixmap(idx, 0, __pgprot(0)) diff --git a/trunk/arch/powerpc/include/asm/ftrace.h b/trunk/arch/powerpc/include/asm/ftrace.h index dde1296b8b41..e5f2ae8362f7 100644 --- a/trunk/arch/powerpc/include/asm/ftrace.h +++ b/trunk/arch/powerpc/include/asm/ftrace.h @@ -5,44 +5,7 @@ #define MCOUNT_ADDR ((long)(_mcount)) #define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ -#ifdef __ASSEMBLY__ - -/* Based off of objdump optput from glibc */ - -#define MCOUNT_SAVE_FRAME \ - stwu r1,-48(r1); \ - stw r3, 12(r1); \ - stw r4, 16(r1); \ - stw r5, 20(r1); \ - stw r6, 24(r1); \ - mflr r3; \ - lwz r4, 52(r1); \ - mfcr r5; \ - stw r7, 28(r1); \ - stw r8, 32(r1); \ - stw r9, 36(r1); \ - stw r10,40(r1); \ - stw r3, 44(r1); \ - stw r5, 8(r1) - -#define MCOUNT_RESTORE_FRAME \ - lwz r6, 8(r1); \ - lwz r0, 44(r1); \ - lwz r3, 12(r1); \ - mtctr r0; \ - lwz r4, 16(r1); \ - mtcr r6; \ - lwz r5, 20(r1); \ - lwz r6, 24(r1); \ - lwz r0, 52(r1); \ - lwz r7, 28(r1); \ - lwz r8, 32(r1); \ - mtlr r0; \ - lwz r9, 36(r1); \ - lwz r10,40(r1); \ - addi r1, r1, 48 - -#else /* !__ASSEMBLY__ */ +#ifndef __ASSEMBLY__ extern void _mcount(void); #ifdef CONFIG_DYNAMIC_FTRACE diff --git a/trunk/arch/powerpc/include/asm/highmem.h b/trunk/arch/powerpc/include/asm/highmem.h index 684a73f4324f..04e4a620952e 100644 --- a/trunk/arch/powerpc/include/asm/highmem.h +++ b/trunk/arch/powerpc/include/asm/highmem.h @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -40,15 +39,15 @@ extern pte_t *pkmap_page_table; * chunk of RAM. */ /* - * We use one full pte table with 4K pages. And with 16K/64K/256K pages pte - * table covers enough memory (32MB/512MB/2GB resp.), so that both FIXMAP - * and PKMAP can be placed in a single pte table. We use 512 pages for PKMAP - * in case of 16K/64K/256K page sizes. + * We use one full pte table with 4K pages. And with 16K/64K pages pte + * table covers enough memory (32MB and 512MB resp.) that both FIXMAP + * and PKMAP can be placed in single pte table. We use 1024 pages for + * PKMAP in case of 16K/64K pages. */ #ifdef CONFIG_PPC_4K_PAGES #define PKMAP_ORDER PTE_SHIFT #else -#define PKMAP_ORDER 9 +#define PKMAP_ORDER 10 #endif #define LAST_PKMAP (1 << PKMAP_ORDER) #ifndef CONFIG_PPC_4K_PAGES @@ -95,13 +94,12 @@ static inline void *kmap_atomic_prot(struct page *page, enum km_type type, pgpro if (!PageHighMem(page)) return page_address(page); - debug_kmap_atomic(type); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(!pte_none(*(kmap_pte-idx))); #endif - __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot), 1); + __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot)); local_flush_tlb_page(NULL, vaddr); return (void*) vaddr; diff --git a/trunk/arch/powerpc/include/asm/hw_irq.h b/trunk/arch/powerpc/include/asm/hw_irq.h index b7e034b0a6dd..f75a5fc64d2e 100644 --- a/trunk/arch/powerpc/include/asm/hw_irq.h +++ b/trunk/arch/powerpc/include/asm/hw_irq.h @@ -129,7 +129,7 @@ static inline int irqs_disabled_flags(unsigned long flags) * interrupt-retrigger: should we handle this via lost interrupts and IPIs * or should we not care like we do now ? --BenH. */ -struct irq_chip; +struct hw_interrupt_type; #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_HW_IRQ_H */ diff --git a/trunk/arch/powerpc/include/asm/io.h b/trunk/arch/powerpc/include/asm/io.h index 001f2f11c19b..494cd8b0a278 100644 --- a/trunk/arch/powerpc/include/asm/io.h +++ b/trunk/arch/powerpc/include/asm/io.h @@ -632,9 +632,6 @@ static inline void iosync(void) * ioremap_flags and cannot be hooked (but can be used by a hook on one * of the previous ones) * - * * __ioremap_caller is the same as above but takes an explicit caller - * reference rather than using __builtin_return_address(0) - * * * __iounmap, is the low level implementation used by iounmap and cannot * be hooked (but can be used by a hook on iounmap) * @@ -649,9 +646,6 @@ extern void iounmap(volatile void __iomem *addr); extern void __iomem *__ioremap(phys_addr_t, unsigned long size, unsigned long flags); -extern void __iomem *__ioremap_caller(phys_addr_t, unsigned long size, - unsigned long flags, void *caller); - extern void __iounmap(volatile void __iomem *addr); extern void __iomem * __ioremap_at(phys_addr_t pa, void *ea, diff --git a/trunk/arch/powerpc/include/asm/lppaca.h b/trunk/arch/powerpc/include/asm/lppaca.h index 68235f7e4a8f..25aaa97facd8 100644 --- a/trunk/arch/powerpc/include/asm/lppaca.h +++ b/trunk/arch/powerpc/include/asm/lppaca.h @@ -97,7 +97,7 @@ struct lppaca { u64 saved_gpr4; // Saved GPR4 x28-x2F u64 saved_gpr5; // Saved GPR5 x30-x37 - u8 dtl_enable_mask; // Dispatch Trace Log mask x38-x38 + u8 reserved4; // Reserved x38-x38 u8 donate_dedicated_cpu; // Donate dedicated CPU cycles x39-x39 u8 fpregs_in_use; // FP regs in use x3A-x3A u8 pmcregs_in_use; // PMC regs in use x3B-x3B @@ -133,10 +133,8 @@ struct lppaca { //============================================================================= // CACHE_LINE_4-5 0x0180 - 0x027F Contains PMC interrupt data //============================================================================= - u32 page_ins; // CMO Hint - # page ins by OS x00-x03 - u8 reserved8[148]; // Reserved x04-x97 - volatile u64 dtl_idx; // Dispatch Trace Log head idx x98-x9F - u8 reserved9[96]; // Reserved xA0-xFF + u32 page_ins; // CMO Hint - # page ins by OS x00-x04 + u8 pmc_save_area[252]; // PMC interrupt Area x04-xFF } __attribute__((__aligned__(0x400))); extern struct lppaca lppaca[]; diff --git a/trunk/arch/powerpc/include/asm/machdep.h b/trunk/arch/powerpc/include/asm/machdep.h index 0efdb1dfdc5f..2740c44ff717 100644 --- a/trunk/arch/powerpc/include/asm/machdep.h +++ b/trunk/arch/powerpc/include/asm/machdep.h @@ -90,7 +90,7 @@ struct machdep_calls { void (*tce_flush)(struct iommu_table *tbl); void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size, - unsigned long flags, void *caller); + unsigned long flags); void (*iounmap)(volatile void __iomem *token); #ifdef CONFIG_PM @@ -327,6 +327,8 @@ extern void __devinit smp_generic_take_timebase(void); */ /* Print a boot progress message. */ void ppc64_boot_msg(unsigned int src, const char *msg); +/* Print a termination message (print only -- does not stop the kernel) */ +void ppc64_terminate_msg(unsigned int src, const char *msg); static inline void log_error(char *buf, unsigned int err_type, int fatal) { diff --git a/trunk/arch/powerpc/include/asm/mmu-44x.h b/trunk/arch/powerpc/include/asm/mmu-44x.h index 3c86576bfefa..27cc6fdcd3b7 100644 --- a/trunk/arch/powerpc/include/asm/mmu-44x.h +++ b/trunk/arch/powerpc/include/asm/mmu-44x.h @@ -83,8 +83,6 @@ typedef struct { #define PPC44x_TLBE_SIZE PPC44x_TLB_16K #elif (PAGE_SHIFT == 16) #define PPC44x_TLBE_SIZE PPC44x_TLB_64K -#elif (PAGE_SHIFT == 18) -#define PPC44x_TLBE_SIZE PPC44x_TLB_256K #else #error "Unsupported PAGE_SIZE" #endif diff --git a/trunk/arch/powerpc/include/asm/mmu-book3e.h b/trunk/arch/powerpc/include/asm/mmu-fsl-booke.h similarity index 53% rename from trunk/arch/powerpc/include/asm/mmu-book3e.h rename to trunk/arch/powerpc/include/asm/mmu-fsl-booke.h index 7e74cff81d86..4285b64a65e0 100644 --- a/trunk/arch/powerpc/include/asm/mmu-book3e.h +++ b/trunk/arch/powerpc/include/asm/mmu-fsl-booke.h @@ -1,42 +1,26 @@ -#ifndef _ASM_POWERPC_MMU_BOOK3E_H_ -#define _ASM_POWERPC_MMU_BOOK3E_H_ +#ifndef _ASM_POWERPC_MMU_FSL_BOOKE_H_ +#define _ASM_POWERPC_MMU_FSL_BOOKE_H_ /* - * Freescale Book-E/Book-3e (ISA 2.06+) MMU support + * Freescale Book-E MMU support */ -/* Book-3e defined page sizes */ -#define BOOK3E_PAGESZ_1K 0 -#define BOOK3E_PAGESZ_2K 1 -#define BOOK3E_PAGESZ_4K 2 -#define BOOK3E_PAGESZ_8K 3 -#define BOOK3E_PAGESZ_16K 4 -#define BOOK3E_PAGESZ_32K 5 -#define BOOK3E_PAGESZ_64K 6 -#define BOOK3E_PAGESZ_128K 7 -#define BOOK3E_PAGESZ_256K 8 -#define BOOK3E_PAGESZ_512K 9 -#define BOOK3E_PAGESZ_1M 10 -#define BOOK3E_PAGESZ_2M 11 -#define BOOK3E_PAGESZ_4M 12 -#define BOOK3E_PAGESZ_8M 13 -#define BOOK3E_PAGESZ_16M 14 -#define BOOK3E_PAGESZ_32M 15 -#define BOOK3E_PAGESZ_64M 16 -#define BOOK3E_PAGESZ_128M 17 -#define BOOK3E_PAGESZ_256M 18 -#define BOOK3E_PAGESZ_512M 19 -#define BOOK3E_PAGESZ_1GB 20 -#define BOOK3E_PAGESZ_2GB 21 -#define BOOK3E_PAGESZ_4GB 22 -#define BOOK3E_PAGESZ_8GB 23 -#define BOOK3E_PAGESZ_16GB 24 -#define BOOK3E_PAGESZ_32GB 25 -#define BOOK3E_PAGESZ_64GB 26 -#define BOOK3E_PAGESZ_128GB 27 -#define BOOK3E_PAGESZ_256GB 28 -#define BOOK3E_PAGESZ_512GB 29 -#define BOOK3E_PAGESZ_1TB 30 -#define BOOK3E_PAGESZ_2TB 31 +/* Book-E defined page sizes */ +#define BOOKE_PAGESZ_1K 0 +#define BOOKE_PAGESZ_4K 1 +#define BOOKE_PAGESZ_16K 2 +#define BOOKE_PAGESZ_64K 3 +#define BOOKE_PAGESZ_256K 4 +#define BOOKE_PAGESZ_1M 5 +#define BOOKE_PAGESZ_4M 6 +#define BOOKE_PAGESZ_16M 7 +#define BOOKE_PAGESZ_64M 8 +#define BOOKE_PAGESZ_256M 9 +#define BOOKE_PAGESZ_1GB 10 +#define BOOKE_PAGESZ_4GB 11 +#define BOOKE_PAGESZ_16GB 12 +#define BOOKE_PAGESZ_64GB 13 +#define BOOKE_PAGESZ_256GB 14 +#define BOOKE_PAGESZ_1TB 15 #define MAS0_TLBSEL(x) ((x << 28) & 0x30000000) #define MAS0_ESEL(x) ((x << 16) & 0x0FFF0000) @@ -45,9 +29,8 @@ #define MAS1_VALID 0x80000000 #define MAS1_IPROT 0x40000000 #define MAS1_TID(x) ((x << 16) & 0x3FFF0000) -#define MAS1_IND 0x00002000 #define MAS1_TS 0x00001000 -#define MAS1_TSIZE(x) ((x << 7) & 0x00000F80) +#define MAS1_TSIZE(x) ((x << 8) & 0x00000F00) #define MAS2_EPN 0xFFFFF000 #define MAS2_X0 0x00000040 @@ -57,7 +40,7 @@ #define MAS2_M 0x00000004 #define MAS2_G 0x00000002 #define MAS2_E 0x00000001 -#define MAS2_EPN_MASK(size) (~0 << (size + 10)) +#define MAS2_EPN_MASK(size) (~0 << (2*(size) + 10)) #define MAS2_VAL(addr, size, flags) ((addr) & MAS2_EPN_MASK(size) | (flags)) #define MAS3_RPN 0xFFFFF000 @@ -73,7 +56,7 @@ #define MAS3_SR 0x00000001 #define MAS4_TLBSELD(x) MAS0_TLBSEL(x) -#define MAS4_INDD 0x00008000 +#define MAS4_TIDDSEL 0x000F0000 #define MAS4_TSIZED(x) MAS1_TSIZE(x) #define MAS4_X0D 0x00000040 #define MAS4_X1D 0x00000020 @@ -85,7 +68,6 @@ #define MAS6_SPID0 0x3FFF0000 #define MAS6_SPID1 0x00007FFE -#define MAS6_ISIZE(x) MAS1_TSIZE(x) #define MAS6_SAS 0x00000001 #define MAS6_SPID MAS6_SPID0 @@ -102,4 +84,4 @@ typedef struct { } mm_context_t; #endif /* !__ASSEMBLY__ */ -#endif /* _ASM_POWERPC_MMU_BOOK3E_H_ */ +#endif /* _ASM_POWERPC_MMU_FSL_BOOKE_H_ */ diff --git a/trunk/arch/powerpc/include/asm/mmu-hash64.h b/trunk/arch/powerpc/include/asm/mmu-hash64.h index 98c104a09961..68b752626808 100644 --- a/trunk/arch/powerpc/include/asm/mmu-hash64.h +++ b/trunk/arch/powerpc/include/asm/mmu-hash64.h @@ -284,6 +284,8 @@ extern void add_gpage(unsigned long addr, unsigned long page_size, unsigned long number_of_pages); extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr); +extern void htab_initialize(void); +extern void htab_initialize_secondary(void); extern void hpte_init_native(void); extern void hpte_init_lpar(void); extern void hpte_init_iSeries(void); diff --git a/trunk/arch/powerpc/include/asm/mmu.h b/trunk/arch/powerpc/include/asm/mmu.h index cbf154387091..6e7639911318 100644 --- a/trunk/arch/powerpc/include/asm/mmu.h +++ b/trunk/arch/powerpc/include/asm/mmu.h @@ -36,9 +36,9 @@ */ #define MMU_FTR_USE_TLBIVAX_BCAST ASM_CONST(0x00040000) -/* Enable use of tlbilx invalidate instructions. +/* Enable use of tlbilx invalidate-by-PID variant. */ -#define MMU_FTR_USE_TLBILX ASM_CONST(0x00080000) +#define MMU_FTR_USE_TLBILX_PID ASM_CONST(0x00080000) /* This indicates that the processor cannot handle multiple outstanding * broadcast tlbivax or tlbsync. This makes the code use a spinlock @@ -46,12 +46,6 @@ */ #define MMU_FTR_LOCK_BCAST_INVAL ASM_CONST(0x00100000) -/* This indicates that the processor doesn't handle way selection - * properly and needs SW to track and update the LRU state. This - * is specific to an errata on e300c2/c3/c4 class parts - */ -#define MMU_FTR_NEED_DTLB_SW_LRU ASM_CONST(0x00200000) - #ifndef __ASSEMBLY__ #include @@ -62,10 +56,6 @@ static inline int mmu_has_feature(unsigned long feature) extern unsigned int __start___mmu_ftr_fixup, __stop___mmu_ftr_fixup; -/* MMU initialization (64-bit only fo now) */ -extern void early_init_mmu(void); -extern void early_init_mmu_secondary(void); - #endif /* !__ASSEMBLY__ */ @@ -81,9 +71,9 @@ extern void early_init_mmu_secondary(void); #elif defined(CONFIG_44x) /* 44x-style software loaded TLB */ # include -#elif defined(CONFIG_PPC_BOOK3E_MMU) -/* Freescale Book-E software loaded TLB or Book-3e (ISA 2.06+) MMU */ -# include +#elif defined(CONFIG_FSL_BOOKE) +/* Freescale Book-E software loaded TLB */ +# include #elif defined (CONFIG_PPC_8xx) /* Motorola/Freescale 8xx software loaded TLB */ # include diff --git a/trunk/arch/powerpc/include/asm/mmu_context.h b/trunk/arch/powerpc/include/asm/mmu_context.h index b7063669f972..ab4f19263c42 100644 --- a/trunk/arch/powerpc/include/asm/mmu_context.h +++ b/trunk/arch/powerpc/include/asm/mmu_context.h @@ -31,7 +31,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) { /* Mark this context has been used on the new CPU */ - cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); + cpu_set(smp_processor_id(), next->cpu_vm_mask); /* 32-bit keeps track of the current PGDIR in the thread struct */ #ifdef CONFIG_PPC32 diff --git a/trunk/arch/powerpc/include/asm/mpc52xx.h b/trunk/arch/powerpc/include/asm/mpc52xx.h index 52e049cd9e68..81a23932a160 100644 --- a/trunk/arch/powerpc/include/asm/mpc52xx.h +++ b/trunk/arch/powerpc/include/asm/mpc52xx.h @@ -273,7 +273,6 @@ extern void mpc5200_setup_xlb_arbiter(void); extern void mpc52xx_declare_of_platform_devices(void); extern void mpc52xx_map_common_devices(void); extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv); -extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node); extern void mpc52xx_restart(char *cmd); /* mpc52xx_pic.c */ diff --git a/trunk/arch/powerpc/include/asm/page.h b/trunk/arch/powerpc/include/asm/page.h index 32cbf16f10ea..197d569f5bd3 100644 --- a/trunk/arch/powerpc/include/asm/page.h +++ b/trunk/arch/powerpc/include/asm/page.h @@ -19,14 +19,12 @@ #include /* - * On regular PPC32 page size is 4K (but we support 4K/16K/64K/256K pages + * On regular PPC32 page size is 4K (but we support 4K/16K/64K pages * on PPC44x). For PPC64 we support either 4K or 64K software * page size. When using 64K pages however, whether we are really supporting * 64K pages in HW or not is irrelevant to those definitions. */ -#if defined(CONFIG_PPC_256K_PAGES) -#define PAGE_SHIFT 18 -#elif defined(CONFIG_PPC_64K_PAGES) +#if defined(CONFIG_PPC_64K_PAGES) #define PAGE_SHIFT 16 #elif defined(CONFIG_PPC_16K_PAGES) #define PAGE_SHIFT 14 diff --git a/trunk/arch/powerpc/include/asm/page_32.h b/trunk/arch/powerpc/include/asm/page_32.h index a0e3f6e6b4ee..1458d9500381 100644 --- a/trunk/arch/powerpc/include/asm/page_32.h +++ b/trunk/arch/powerpc/include/asm/page_32.h @@ -19,11 +19,7 @@ #define PTE_FLAGS_OFFSET 0 #endif -#ifdef CONFIG_PPC_256K_PAGES -#define PTE_SHIFT (PAGE_SHIFT - PTE_T_LOG2 - 2) /* 1/4 of a page */ -#else #define PTE_SHIFT (PAGE_SHIFT - PTE_T_LOG2) /* full page */ -#endif #ifndef __ASSEMBLY__ /* diff --git a/trunk/arch/powerpc/include/asm/pci.h b/trunk/arch/powerpc/include/asm/pci.h index ba17d5d90a49..3548159a1beb 100644 --- a/trunk/arch/powerpc/include/asm/pci.h +++ b/trunk/arch/powerpc/include/asm/pci.h @@ -114,10 +114,6 @@ extern int pci_domain_nr(struct pci_bus *bus); /* Decide whether to display the domain number in /proc */ extern int pci_proc_domain(struct pci_bus *bus); -/* MSI arch hooks */ -#define arch_setup_msi_irqs arch_setup_msi_irqs -#define arch_teardown_msi_irqs arch_teardown_msi_irqs -#define arch_msi_check_device arch_msi_check_device struct vm_area_struct; /* Map a range of PCI memory or I/O space for a device into user space */ diff --git a/trunk/arch/powerpc/include/asm/pgtable-ppc64-4k.h b/trunk/arch/powerpc/include/asm/pgtable-4k.h similarity index 57% rename from trunk/arch/powerpc/include/asm/pgtable-ppc64-4k.h rename to trunk/arch/powerpc/include/asm/pgtable-4k.h index 6eefdcffa359..1dbca4e7de67 100644 --- a/trunk/arch/powerpc/include/asm/pgtable-ppc64-4k.h +++ b/trunk/arch/powerpc/include/asm/pgtable-4k.h @@ -1,5 +1,5 @@ -#ifndef _ASM_POWERPC_PGTABLE_PPC64_4K_H -#define _ASM_POWERPC_PGTABLE_PPC64_4K_H +#ifndef _ASM_POWERPC_PGTABLE_4K_H +#define _ASM_POWERPC_PGTABLE_4K_H /* * Entries per page directory level. The PTE level must use a 64b record * for each page table entry. The PMD and PGD level use a 32b record for @@ -40,6 +40,28 @@ #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) +/* PTE bits */ +#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */ +#define _PAGE_SECONDARY 0x8000 /* software: HPTE is in secondary group */ +#define _PAGE_GROUP_IX 0x7000 /* software: HPTE index within group */ +#define _PAGE_F_SECOND _PAGE_SECONDARY +#define _PAGE_F_GIX _PAGE_GROUP_IX +#define _PAGE_SPECIAL 0x10000 /* software: special page */ +#define __HAVE_ARCH_PTE_SPECIAL + +/* PTE flags to conserve for HPTE identification */ +#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | \ + _PAGE_SECONDARY | _PAGE_GROUP_IX) + +/* There is no 4K PFN hack on 4K pages */ +#define _PAGE_4K_PFN 0 + +/* PAGE_MASK gives the right answer below, but only by accident */ +/* It should be preserving the high 48 bits and then specifically */ +/* preserving _PAGE_SECONDARY | _PAGE_GROUP_IX */ +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \ + _PAGE_HPTEFLAGS | _PAGE_SPECIAL) + /* Bits to mask out from a PMD to get to the PTE page */ #define PMD_MASKED_BITS 0 /* Bits to mask out from a PUD to get to the PMD page */ @@ -47,6 +69,30 @@ /* Bits to mask out from a PGD to get to the PUD page */ #define PGD_MASKED_BITS 0 +/* shift to put page number into pte */ +#define PTE_RPN_SHIFT (17) + +#ifdef STRICT_MM_TYPECHECKS +#define __real_pte(e,p) ((real_pte_t){(e)}) +#define __rpte_to_pte(r) ((r).pte) +#else +#define __real_pte(e,p) (e) +#define __rpte_to_pte(r) (__pte(r)) +#endif +#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> 12) + +#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ + do { \ + index = 0; \ + shift = mmu_psize_defs[psize].shift; \ + +#define pte_iterate_hashed_end() } while(0) + +#ifdef CONFIG_PPC_HAS_HASH_64K +#define pte_pagesize_index(mm, addr, pte) get_slice_psize(mm, addr) +#else +#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K +#endif /* * 4-level page tables related bits @@ -66,9 +112,6 @@ #define pud_ERROR(e) \ printk("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e)) -/* - * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range() */ #define remap_4k_pfn(vma, addr, pfn, prot) \ remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot)) - -#endif /* _ASM_POWERPC_PGTABLE_PPC64_4K_H */ +#endif /* _ASM_POWERPC_PGTABLE_4K_H */ diff --git a/trunk/arch/powerpc/include/asm/pte-hash64-64k.h b/trunk/arch/powerpc/include/asm/pgtable-64k.h similarity index 73% rename from trunk/arch/powerpc/include/asm/pte-hash64-64k.h rename to trunk/arch/powerpc/include/asm/pgtable-64k.h index e05d26fa372f..7389003349a6 100644 --- a/trunk/arch/powerpc/include/asm/pte-hash64-64k.h +++ b/trunk/arch/powerpc/include/asm/pgtable-64k.h @@ -1,6 +1,76 @@ -/* To be include by pgtable-hash64.h only */ +#ifndef _ASM_POWERPC_PGTABLE_64K_H +#define _ASM_POWERPC_PGTABLE_64K_H + +#include + + +#define PTE_INDEX_SIZE 12 +#define PMD_INDEX_SIZE 12 +#define PUD_INDEX_SIZE 0 +#define PGD_INDEX_SIZE 4 + +#ifndef __ASSEMBLY__ +#define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE) +#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE) +#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE) + +#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE) +#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) +#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) + +#ifdef CONFIG_PPC_SUBPAGE_PROT +/* + * For the sub-page protection option, we extend the PGD with one of + * these. Basically we have a 3-level tree, with the top level being + * the protptrs array. To optimize speed and memory consumption when + * only addresses < 4GB are being protected, pointers to the first + * four pages of sub-page protection words are stored in the low_prot + * array. + * Each page of sub-page protection words protects 1GB (4 bytes + * protects 64k). For the 3-level tree, each page of pointers then + * protects 8TB. + */ +struct subpage_prot_table { + unsigned long maxaddr; /* only addresses < this are protected */ + unsigned int **protptrs[2]; + unsigned int *low_prot[4]; +}; + +#undef PGD_TABLE_SIZE +#define PGD_TABLE_SIZE ((sizeof(pgd_t) << PGD_INDEX_SIZE) + \ + sizeof(struct subpage_prot_table)) + +#define SBP_L1_BITS (PAGE_SHIFT - 2) +#define SBP_L2_BITS (PAGE_SHIFT - 3) +#define SBP_L1_COUNT (1 << SBP_L1_BITS) +#define SBP_L2_COUNT (1 << SBP_L2_BITS) +#define SBP_L2_SHIFT (PAGE_SHIFT + SBP_L1_BITS) +#define SBP_L3_SHIFT (SBP_L2_SHIFT + SBP_L2_BITS) + +extern void subpage_prot_free(pgd_t *pgd); + +static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd) +{ + return (struct subpage_prot_table *)(pgd + PTRS_PER_PGD); +} +#endif /* CONFIG_PPC_SUBPAGE_PROT */ +#endif /* __ASSEMBLY__ */ + +/* With 4k base page size, hugepage PTEs go at the PMD level */ +#define MIN_HUGEPTE_SHIFT PAGE_SHIFT + +/* PMD_SHIFT determines what a second-level page table entry can map */ +#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE) +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) + +/* PGDIR_SHIFT determines what a third-level page table entry can map */ +#define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE) +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) /* Additional PTE bits (don't change without checking asm in hash_low.S) */ +#define __HAVE_ARCH_PTE_SPECIAL #define _PAGE_SPECIAL 0x00000400 /* software: special page */ #define _PAGE_HPTE_SUB 0x0ffff000 /* combo only: sub pages HPTE bits */ #define _PAGE_HPTE_SUB0 0x08000000 /* combo only: first sub page */ @@ -37,15 +107,21 @@ * of addressable physical space, or 46 bits for the special 4k PFNs. */ #define PTE_RPN_SHIFT (30) +#define PTE_RPN_MAX (1UL << (64 - PTE_RPN_SHIFT)) +#define PTE_RPN_MASK (~((1UL<> (index))) + /* Trick: we set __end to va + 64k, which happens works for * a 16M page as well as we want only one iteration */ @@ -75,41 +152,4 @@ remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \ __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN)) - -#ifdef CONFIG_PPC_SUBPAGE_PROT -/* - * For the sub-page protection option, we extend the PGD with one of - * these. Basically we have a 3-level tree, with the top level being - * the protptrs array. To optimize speed and memory consumption when - * only addresses < 4GB are being protected, pointers to the first - * four pages of sub-page protection words are stored in the low_prot - * array. - * Each page of sub-page protection words protects 1GB (4 bytes - * protects 64k). For the 3-level tree, each page of pointers then - * protects 8TB. - */ -struct subpage_prot_table { - unsigned long maxaddr; /* only addresses < this are protected */ - unsigned int **protptrs[2]; - unsigned int *low_prot[4]; -}; - -#undef PGD_TABLE_SIZE -#define PGD_TABLE_SIZE ((sizeof(pgd_t) << PGD_INDEX_SIZE) + \ - sizeof(struct subpage_prot_table)) - -#define SBP_L1_BITS (PAGE_SHIFT - 2) -#define SBP_L2_BITS (PAGE_SHIFT - 3) -#define SBP_L1_COUNT (1 << SBP_L1_BITS) -#define SBP_L2_COUNT (1 << SBP_L2_BITS) -#define SBP_L2_SHIFT (PAGE_SHIFT + SBP_L1_BITS) -#define SBP_L3_SHIFT (SBP_L2_SHIFT + SBP_L2_BITS) - -extern void subpage_prot_free(pgd_t *pgd); - -static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd) -{ - return (struct subpage_prot_table *)(pgd + PTRS_PER_PGD); -} -#endif /* CONFIG_PPC_SUBPAGE_PROT */ -#endif /* __ASSEMBLY__ */ +#endif /* _ASM_POWERPC_PGTABLE_64K_H */ diff --git a/trunk/arch/powerpc/include/asm/pgtable-ppc32.h b/trunk/arch/powerpc/include/asm/pgtable-ppc32.h index ba45c997830f..820b5f0a35ce 100644 --- a/trunk/arch/powerpc/include/asm/pgtable-ppc32.h +++ b/trunk/arch/powerpc/include/asm/pgtable-ppc32.h @@ -18,6 +18,55 @@ extern int icache_44x_need_flush; #endif /* __ASSEMBLY__ */ +/* + * The PowerPC MMU uses a hash table containing PTEs, together with + * a set of 16 segment registers (on 32-bit implementations), to define + * the virtual to physical address mapping. + * + * We use the hash table as an extended TLB, i.e. a cache of currently + * active mappings. We maintain a two-level page table tree, much + * like that used by the i386, for the sake of the Linux memory + * management code. Low-level assembler code in hashtable.S + * (procedure hash_page) is responsible for extracting ptes from the + * tree and putting them into the hash table when necessary, and + * updating the accessed and modified bits in the page table tree. + */ + +/* + * The PowerPC MPC8xx uses a TLB with hardware assisted, software tablewalk. + * We also use the two level tables, but we can put the real bits in them + * needed for the TLB and tablewalk. These definitions require Mx_CTR.PPM = 0, + * Mx_CTR.PPCS = 0, and MD_CTR.TWAM = 1. The level 2 descriptor has + * additional page protection (when Mx_CTR.PPCS = 1) that allows TLB hit + * based upon user/super access. The TLB does not have accessed nor write + * protect. We assume that if the TLB get loaded with an entry it is + * accessed, and overload the changed bit for write protect. We use + * two bits in the software pte that are supposed to be set to zero in + * the TLB entry (24 and 25) for these indicators. Although the level 1 + * descriptor contains the guarded and writethrough/copyback bits, we can + * set these at the page level since they get copied from the Mx_TWC + * register when the TLB entry is loaded. We will use bit 27 for guard, since + * that is where it exists in the MD_TWC, and bit 26 for writethrough. + * These will get masked from the level 2 descriptor at TLB load time, and + * copied to the MD_TWC before it gets loaded. + * Large page sizes added. We currently support two sizes, 4K and 8M. + * This also allows a TLB hander optimization because we can directly + * load the PMD into MD_TWC. The 8M pages are only used for kernel + * mapping of well known areas. The PMD (PGD) entries contain control + * flags in addition to the address, so care must be taken that the + * software no longer assumes these are only pointers. + */ + +/* + * At present, all PowerPC 400-class processors share a similar TLB + * architecture. The instruction and data sides share a unified, + * 64-entry, fully-associative TLB which is maintained totally under + * software control. In addition, the instruction side has a + * hardware-managed, 4-entry, fully-associative TLB which serves as a + * first level to the shared TLB. These two TLBs are known as the UTLB + * and ITLB, respectively (see "mmu.h" for definitions). + */ + /* * The normal case is that PTEs are 32-bits and we have a 1-page * 1024-entry pgdir pointing to 1-page 1024-entry PTE pages. -- paulus @@ -86,22 +135,409 @@ extern int icache_44x_need_flush; */ #if defined(CONFIG_40x) -#include + +/* There are several potential gotchas here. The 40x hardware TLBLO + field looks like this: + + 0 1 2 3 4 ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + RPN..................... 0 0 EX WR ZSEL....... W I M G + + Where possible we make the Linux PTE bits match up with this + + - bits 20 and 21 must be cleared, because we use 4k pages (40x can + support down to 1k pages), this is done in the TLBMiss exception + handler. + - We use only zones 0 (for kernel pages) and 1 (for user pages) + of the 16 available. Bit 24-26 of the TLB are cleared in the TLB + miss handler. Bit 27 is PAGE_USER, thus selecting the correct + zone. + - PRESENT *must* be in the bottom two bits because swap cache + entries use the top 30 bits. Because 40x doesn't support SMP + anyway, M is irrelevant so we borrow it for PAGE_PRESENT. Bit 30 + is cleared in the TLB miss handler before the TLB entry is loaded. + - All other bits of the PTE are loaded into TLBLO without + modification, leaving us only the bits 20, 21, 24, 25, 26, 30 for + software PTE bits. We actually use use bits 21, 24, 25, and + 30 respectively for the software bits: ACCESSED, DIRTY, RW, and + PRESENT. +*/ + +/* Definitions for 40x embedded chips. */ +#define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */ +#define _PAGE_FILE 0x001 /* when !present: nonlinear file mapping */ +#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */ +#define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */ +#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */ +#define _PAGE_USER 0x010 /* matches one of the zone permission bits */ +#define _PAGE_RW 0x040 /* software: Writes permitted */ +#define _PAGE_DIRTY 0x080 /* software: dirty page */ +#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */ +#define _PAGE_HWEXEC 0x200 /* hardware: EX permission */ +#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */ + +#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */ +#define _PMD_BAD 0x802 +#define _PMD_SIZE 0x0e0 /* size field, != 0 for large-page PMD entry */ +#define _PMD_SIZE_4M 0x0c0 +#define _PMD_SIZE_16M 0x0e0 +#define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4)) + +/* Until my rework is finished, 40x still needs atomic PTE updates */ +#define PTE_ATOMIC_UPDATES 1 + #elif defined(CONFIG_44x) -#include +/* + * Definitions for PPC440 + * + * Because of the 3 word TLB entries to support 36-bit addressing, + * the attribute are difficult to map in such a fashion that they + * are easily loaded during exception processing. I decided to + * organize the entry so the ERPN is the only portion in the + * upper word of the PTE and the attribute bits below are packed + * in as sensibly as they can be in the area below a 4KB page size + * oriented RPN. This at least makes it easy to load the RPN and + * ERPN fields in the TLB. -Matt + * + * Note that these bits preclude future use of a page size + * less than 4KB. + * + * + * PPC 440 core has following TLB attribute fields; + * + * TLB1: + * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + * RPN................................. - - - - - - ERPN....... + * + * TLB2: + * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + * - - - - - - U0 U1 U2 U3 W I M G E - UX UW UR SX SW SR + * + * Newer 440 cores (440x6 as used on AMCC 460EX/460GT) have additional + * TLB2 storage attibute fields. Those are: + * + * TLB2: + * 0...10 11 12 13 14 15 16...31 + * no change WL1 IL1I IL1D IL2I IL2D no change + * + * There are some constrains and options, to decide mapping software bits + * into TLB entry. + * + * - PRESENT *must* be in the bottom three bits because swap cache + * entries use the top 29 bits for TLB2. + * + * - FILE *must* be in the bottom three bits because swap cache + * entries use the top 29 bits for TLB2. + * + * - CACHE COHERENT bit (M) has no effect on original PPC440 cores, + * because it doesn't support SMP. However, some later 460 variants + * have -some- form of SMP support and so I keep the bit there for + * future use + * + * With the PPC 44x Linux implementation, the 0-11th LSBs of the PTE are used + * for memory protection related functions (see PTE structure in + * include/asm-ppc/mmu.h). The _PAGE_XXX definitions in this file map to the + * above bits. Note that the bit values are CPU specific, not architecture + * specific. + * + * The kernel PTE entry holds an arch-dependent swp_entry structure under + * certain situations. In other words, in such situations some portion of + * the PTE bits are used as a swp_entry. In the PPC implementation, the + * 3-24th LSB are shared with swp_entry, however the 0-2nd three LSB still + * hold protection values. That means the three protection bits are + * reserved for both PTE and SWAP entry at the most significant three + * LSBs. + * + * There are three protection bits available for SWAP entry: + * _PAGE_PRESENT + * _PAGE_FILE + * _PAGE_HASHPTE (if HW has) + * + * So those three bits have to be inside of 0-2nd LSB of PTE. + * + */ + +#define _PAGE_PRESENT 0x00000001 /* S: PTE valid */ +#define _PAGE_RW 0x00000002 /* S: Write permission */ +#define _PAGE_FILE 0x00000004 /* S: nonlinear file mapping */ +#define _PAGE_HWEXEC 0x00000004 /* H: Execute permission */ +#define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */ +#define _PAGE_DIRTY 0x00000010 /* S: Page dirty */ +#define _PAGE_SPECIAL 0x00000020 /* S: Special page */ +#define _PAGE_USER 0x00000040 /* S: User page */ +#define _PAGE_ENDIAN 0x00000080 /* H: E bit */ +#define _PAGE_GUARDED 0x00000100 /* H: G bit */ +#define _PAGE_COHERENT 0x00000200 /* H: M bit */ +#define _PAGE_NO_CACHE 0x00000400 /* H: I bit */ +#define _PAGE_WRITETHRU 0x00000800 /* H: W bit */ + +/* TODO: Add large page lowmem mapping support */ +#define _PMD_PRESENT 0 +#define _PMD_PRESENT_MASK (PAGE_MASK) +#define _PMD_BAD (~PAGE_MASK) + +/* ERPN in a PTE never gets cleared, ignore it */ +#define _PTE_NONE_MASK 0xffffffff00000000ULL + +#define __HAVE_ARCH_PTE_SPECIAL + #elif defined(CONFIG_FSL_BOOKE) -#include +/* + MMU Assist Register 3: + + 32 33 34 35 36 ... 50 51 52 53 54 55 56 57 58 59 60 61 62 63 + RPN...................... 0 0 U0 U1 U2 U3 UX SX UW SW UR SR + + - PRESENT *must* be in the bottom three bits because swap cache + entries use the top 29 bits. + + - FILE *must* be in the bottom three bits because swap cache + entries use the top 29 bits. +*/ + +/* Definitions for FSL Book-E Cores */ +#define _PAGE_PRESENT 0x00001 /* S: PTE contains a translation */ +#define _PAGE_USER 0x00002 /* S: User page (maps to UR) */ +#define _PAGE_FILE 0x00002 /* S: when !present: nonlinear file mapping */ +#define _PAGE_RW 0x00004 /* S: Write permission (SW) */ +#define _PAGE_DIRTY 0x00008 /* S: Page dirty */ +#define _PAGE_HWEXEC 0x00010 /* H: SX permission */ +#define _PAGE_ACCESSED 0x00020 /* S: Page referenced */ + +#define _PAGE_ENDIAN 0x00040 /* H: E bit */ +#define _PAGE_GUARDED 0x00080 /* H: G bit */ +#define _PAGE_COHERENT 0x00100 /* H: M bit */ +#define _PAGE_NO_CACHE 0x00200 /* H: I bit */ +#define _PAGE_WRITETHRU 0x00400 /* H: W bit */ +#define _PAGE_SPECIAL 0x00800 /* S: Special page */ + +#ifdef CONFIG_PTE_64BIT +/* ERPN in a PTE never gets cleared, ignore it */ +#define _PTE_NONE_MASK 0xffffffffffff0000ULL +#endif + +#define _PMD_PRESENT 0 +#define _PMD_PRESENT_MASK (PAGE_MASK) +#define _PMD_BAD (~PAGE_MASK) + +#define __HAVE_ARCH_PTE_SPECIAL + #elif defined(CONFIG_8xx) -#include +/* Definitions for 8xx embedded chips. */ +#define _PAGE_PRESENT 0x0001 /* Page is valid */ +#define _PAGE_FILE 0x0002 /* when !present: nonlinear file mapping */ +#define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */ +#define _PAGE_SHARED 0x0004 /* No ASID (context) compare */ + +/* These five software bits must be masked out when the entry is loaded + * into the TLB. + */ +#define _PAGE_EXEC 0x0008 /* software: i-cache coherency required */ +#define _PAGE_GUARDED 0x0010 /* software: guarded access */ +#define _PAGE_DIRTY 0x0020 /* software: page changed */ +#define _PAGE_RW 0x0040 /* software: user write access allowed */ +#define _PAGE_ACCESSED 0x0080 /* software: page referenced */ + +/* Setting any bits in the nibble with the follow two controls will + * require a TLB exception handler change. It is assumed unused bits + * are always zero. + */ +#define _PAGE_HWWRITE 0x0100 /* h/w write enable: never set in Linux PTE */ +#define _PAGE_USER 0x0800 /* One of the PP bits, the other is USER&~RW */ + +#define _PMD_PRESENT 0x0001 +#define _PMD_BAD 0x0ff0 +#define _PMD_PAGE_MASK 0x000c +#define _PMD_PAGE_8M 0x000c + +#define _PTE_NONE_MASK _PAGE_ACCESSED + +/* Until my rework is finished, 8xx still needs atomic PTE updates */ +#define PTE_ATOMIC_UPDATES 1 + #else /* CONFIG_6xx */ -#include +/* Definitions for 60x, 740/750, etc. */ +#define _PAGE_PRESENT 0x001 /* software: pte contains a translation */ +#define _PAGE_HASHPTE 0x002 /* hash_page has made an HPTE for this pte */ +#define _PAGE_FILE 0x004 /* when !present: nonlinear file mapping */ +#define _PAGE_USER 0x004 /* usermode access allowed */ +#define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */ +#define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */ +#define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */ +#define _PAGE_WRITETHRU 0x040 /* W: cache write-through */ +#define _PAGE_DIRTY 0x080 /* C: page changed */ +#define _PAGE_ACCESSED 0x100 /* R: page referenced */ +#define _PAGE_EXEC 0x200 /* software: i-cache coherency required */ +#define _PAGE_RW 0x400 /* software: user write access allowed */ +#define _PAGE_SPECIAL 0x800 /* software: Special page */ + +#ifdef CONFIG_PTE_64BIT +/* We never clear the high word of the pte */ +#define _PTE_NONE_MASK (0xffffffff00000000ULL | _PAGE_HASHPTE) +#else +#define _PTE_NONE_MASK _PAGE_HASHPTE #endif -/* And here we include common definitions */ -#include +#define _PMD_PRESENT 0 +#define _PMD_PRESENT_MASK (PAGE_MASK) +#define _PMD_BAD (~PAGE_MASK) + +/* Hash table based platforms need atomic updates of the linux PTE */ +#define PTE_ATOMIC_UPDATES 1 + +#define __HAVE_ARCH_PTE_SPECIAL + +#endif + +/* + * Some bits are only used on some cpu families... + */ +#ifndef _PAGE_HASHPTE +#define _PAGE_HASHPTE 0 +#endif +#ifndef _PTE_NONE_MASK +#define _PTE_NONE_MASK 0 +#endif +#ifndef _PAGE_SHARED +#define _PAGE_SHARED 0 +#endif +#ifndef _PAGE_HWWRITE +#define _PAGE_HWWRITE 0 +#endif +#ifndef _PAGE_HWEXEC +#define _PAGE_HWEXEC 0 +#endif +#ifndef _PAGE_EXEC +#define _PAGE_EXEC 0 +#endif +#ifndef _PAGE_ENDIAN +#define _PAGE_ENDIAN 0 +#endif +#ifndef _PAGE_COHERENT +#define _PAGE_COHERENT 0 +#endif +#ifndef _PAGE_WRITETHRU +#define _PAGE_WRITETHRU 0 +#endif +#ifndef _PAGE_SPECIAL +#define _PAGE_SPECIAL 0 +#endif +#ifndef _PMD_PRESENT_MASK +#define _PMD_PRESENT_MASK _PMD_PRESENT +#endif +#ifndef _PMD_SIZE +#define _PMD_SIZE 0 +#define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE() +#endif + +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \ + _PAGE_SPECIAL) + + +#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \ + _PAGE_WRITETHRU | _PAGE_ENDIAN | \ + _PAGE_USER | _PAGE_ACCESSED | \ + _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \ + _PAGE_EXEC | _PAGE_HWEXEC) + +/* + * We define 2 sets of base prot bits, one for basic pages (ie, + * cacheable kernel and user pages) and one for non cacheable + * pages. We always set _PAGE_COHERENT when SMP is enabled or + * the processor might need it for DMA coherency. + */ +#if defined(CONFIG_SMP) || defined(CONFIG_PPC_STD_MMU) +#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT) +#else +#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED) +#endif +#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_NO_CACHE) + +#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE) +#define _PAGE_KERNEL (_PAGE_BASE | _PAGE_SHARED | _PAGE_WRENABLE) +#define _PAGE_KERNEL_NC (_PAGE_BASE_NC | _PAGE_SHARED | _PAGE_WRENABLE) + +#ifdef CONFIG_PPC_STD_MMU +/* On standard PPC MMU, no user access implies kernel read/write access, + * so to write-protect kernel memory we must turn on user access */ +#define _PAGE_KERNEL_RO (_PAGE_BASE | _PAGE_SHARED | _PAGE_USER) +#else +#define _PAGE_KERNEL_RO (_PAGE_BASE | _PAGE_SHARED) +#endif + +#define _PAGE_IO (_PAGE_KERNEL_NC | _PAGE_GUARDED) +#define _PAGE_RAM (_PAGE_KERNEL | _PAGE_HWEXEC) + +#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) ||\ + defined(CONFIG_KPROBES) +/* We want the debuggers to be able to set breakpoints anywhere, so + * don't write protect the kernel text */ +#define _PAGE_RAM_TEXT _PAGE_RAM +#else +#define _PAGE_RAM_TEXT (_PAGE_KERNEL_RO | _PAGE_HWEXEC) +#endif + +#define PAGE_NONE __pgprot(_PAGE_BASE) +#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER) +#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) +#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW) +#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC) +#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER) +#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) + +#define PAGE_KERNEL __pgprot(_PAGE_RAM) +#define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO) + +/* + * The PowerPC can only do execute protection on a segment (256MB) basis, + * not on a page basis. So we consider execute permission the same as read. + * Also, write permissions imply read permissions. + * This is the closest we can get.. + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY_X +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY_X +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY_X +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY_X + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY_X +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED_X +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY_X +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED_X #ifndef __ASSEMBLY__ +/* Make sure we get a link error if PMD_PAGE_SIZE is ever called on a + * kernel without large page PMD support */ +extern unsigned long bad_call_to_PMD_PAGE_SIZE(void); + +/* + * Conversions between PTE values and page frame numbers. + */ + +/* in some case we want to additionaly adjust where the pfn is in the pte to + * allow room for more flags */ +#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT) +#define PFN_SHIFT_OFFSET (PAGE_SHIFT + 8) +#else +#define PFN_SHIFT_OFFSET (PAGE_SHIFT) +#endif +#define pte_pfn(x) (pte_val(x) >> PFN_SHIFT_OFFSET) +#define pte_page(x) pfn_to_page(pte_pfn(x)) + +#define pfn_pte(pfn, prot) __pte(((pte_basic_t)(pfn) << PFN_SHIFT_OFFSET) |\ + pgprot_val(prot)) +#define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot) +#endif /* __ASSEMBLY__ */ + +#define pte_none(pte) ((pte_val(pte) & ~_PTE_NONE_MASK) == 0) +#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT) #define pte_clear(mm, addr, ptep) \ do { pte_update(ptep, ~_PAGE_HASHPTE, 0); } while (0) @@ -110,6 +546,43 @@ extern int icache_44x_need_flush; #define pmd_present(pmd) (pmd_val(pmd) & _PMD_PRESENT_MASK) #define pmd_clear(pmdp) do { pmd_val(*(pmdp)) = 0; } while (0) +#ifndef __ASSEMBLY__ +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } +static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } + +static inline pte_t pte_wrprotect(pte_t pte) { + pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); return pte; } +static inline pte_t pte_mkclean(pte_t pte) { + pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; } +static inline pte_t pte_mkold(pte_t pte) { + pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } + +static inline pte_t pte_mkwrite(pte_t pte) { + pte_val(pte) |= _PAGE_RW; return pte; } +static inline pte_t pte_mkdirty(pte_t pte) { + pte_val(pte) |= _PAGE_DIRTY; return pte; } +static inline pte_t pte_mkyoung(pte_t pte) { + pte_val(pte) |= _PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkspecial(pte_t pte) { + pte_val(pte) |= _PAGE_SPECIAL; return pte; } +static inline pgprot_t pte_pgprot(pte_t pte) +{ + return __pgprot(pte_val(pte) & PAGE_PROT_BITS); +} + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); + return pte; +} + /* * When flushing the tlb entry for a page, we also need to flush the hash * table entry. flush_hash_pages is assembler (for speed) in hashtable.S. @@ -126,19 +599,11 @@ extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, unsigned long address); /* - * PTE updates. This function is called whenever an existing - * valid PTE is updated. This does -not- include set_pte_at() - * which nowadays only sets a new PTE. + * Atomic PTE updates. * - * Depending on the type of MMU, we may need to use atomic updates - * and the PTE may be either 32 or 64 bit wide. In the later case, - * when using atomic updates, only the low part of the PTE is - * accessed atomically. - * - * In addition, on 44x, we also maintain a global flag indicating - * that an executable user mapping was modified, which is needed - * to properly flush the virtually tagged instruction cache of - * those implementations. + * pte_update clears and sets bit atomically, and returns + * the old pte value. In the 64-bit PTE case we lock around the + * low PTE word since we expect ALL flag bits to be there */ #ifndef CONFIG_PTE_64BIT static inline unsigned long pte_update(pte_t *p, @@ -202,6 +667,44 @@ static inline unsigned long long pte_update(pte_t *p, } #endif /* CONFIG_PTE_64BIT */ +/* + * set_pte stores a linux PTE into the linux page table. + * On machines which use an MMU hash table we avoid changing the + * _PAGE_HASHPTE bit. + */ + +static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ +#if (_PAGE_HASHPTE != 0) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT) + pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE); +#elif defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP) +#if _PAGE_HASHPTE != 0 + if (pte_val(*ptep) & _PAGE_HASHPTE) + flush_hash_entry(mm, ptep, addr); +#endif + __asm__ __volatile__("\ + stw%U0%X0 %2,%0\n\ + eieio\n\ + stw%U0%X0 %L2,%1" + : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) + : "r" (pte) : "memory"); +#else + *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) + | (pte_val(pte) & ~_PAGE_HASHPTE)); +#endif +} + + +static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ +#if defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP) && defined(CONFIG_DEBUG_VM) + WARN_ON(pte_present(*ptep)); +#endif + __set_pte_at(mm, addr, ptep, pte); +} + /* * 2.6 calls this without flushing the TLB entry; this is wrong * for our hash-based implementation, we fix that up here. @@ -242,14 +745,24 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, } -static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) +#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS +static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty) { unsigned long bits = pte_val(entry) & - (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | - _PAGE_HWEXEC | _PAGE_EXEC); + (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW); pte_update(ptep, 0, bits); } +#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \ +({ \ + int __changed = !pte_same(*(__ptep), __entry); \ + if (__changed) { \ + __ptep_set_access_flags(__ptep, __entry, __dirty); \ + flush_tlb_page_nohash(__vma, __address); \ + } \ + __changed; \ +}) + #define __HAVE_ARCH_PTE_SAME #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0) diff --git a/trunk/arch/powerpc/include/asm/pgtable-ppc64-64k.h b/trunk/arch/powerpc/include/asm/pgtable-ppc64-64k.h deleted file mode 100644 index 6cc085b945a5..000000000000 --- a/trunk/arch/powerpc/include/asm/pgtable-ppc64-64k.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _ASM_POWERPC_PGTABLE_PPC64_64K_H -#define _ASM_POWERPC_PGTABLE_PPC64_64K_H - -#include - - -#define PTE_INDEX_SIZE 12 -#define PMD_INDEX_SIZE 12 -#define PUD_INDEX_SIZE 0 -#define PGD_INDEX_SIZE 4 - -#ifndef __ASSEMBLY__ - -#define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE) -#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE) -#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE) - -#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE) -#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) -#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) - -/* With 4k base page size, hugepage PTEs go at the PMD level */ -#define MIN_HUGEPTE_SHIFT PAGE_SHIFT - -/* PMD_SHIFT determines what a second-level page table entry can map */ -#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE) -#define PMD_SIZE (1UL << PMD_SHIFT) -#define PMD_MASK (~(PMD_SIZE-1)) - -/* PGDIR_SHIFT determines what a third-level page table entry can map */ -#define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE) -#define PGDIR_SIZE (1UL << PGDIR_SHIFT) -#define PGDIR_MASK (~(PGDIR_SIZE-1)) - -#endif /* __ASSEMBLY__ */ - -/* Bits to mask out from a PMD to get to the PTE page */ -#define PMD_MASKED_BITS 0x1ff -/* Bits to mask out from a PGD/PUD to get to the PMD page */ -#define PUD_MASKED_BITS 0x1ff - -#endif /* _ASM_POWERPC_PGTABLE_PPC64_64K_H */ diff --git a/trunk/arch/powerpc/include/asm/pgtable-ppc64.h b/trunk/arch/powerpc/include/asm/pgtable-ppc64.h index c40db05f21e0..b0f18be81d9f 100644 --- a/trunk/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/trunk/arch/powerpc/include/asm/pgtable-ppc64.h @@ -11,9 +11,9 @@ #endif /* __ASSEMBLY__ */ #ifdef CONFIG_PPC_64K_PAGES -#include +#include #else -#include +#include #endif #define FIRST_USER_ADDRESS 0 @@ -25,8 +25,6 @@ PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT) #define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE) - -/* Some sanity checking */ #if TASK_SIZE_USER64 > PGTABLE_RANGE #error TASK_SIZE_USER64 exceeds pagetable range #endif @@ -35,6 +33,7 @@ #error TASK_SIZE_USER64 exceeds user VSID range #endif + /* * Define the address range of the vmalloc VM area. */ @@ -77,12 +76,83 @@ /* - * Include the PTE bits definitions + * Common bits in a linux-style PTE. These match the bits in the + * (hardware-defined) PowerPC PTE as closely as possible. Additional + * bits may be defined in pgtable-*.h */ -#include -#include +#define _PAGE_PRESENT 0x0001 /* software: pte contains a translation */ +#define _PAGE_USER 0x0002 /* matches one of the PP bits */ +#define _PAGE_FILE 0x0002 /* (!present only) software: pte holds file offset */ +#define _PAGE_EXEC 0x0004 /* No execute on POWER4 and newer (we invert) */ +#define _PAGE_GUARDED 0x0008 +#define _PAGE_COHERENT 0x0010 /* M: enforce memory coherence (SMP systems) */ +#define _PAGE_NO_CACHE 0x0020 /* I: cache inhibit */ +#define _PAGE_WRITETHRU 0x0040 /* W: cache write-through */ +#define _PAGE_DIRTY 0x0080 /* C: page changed */ +#define _PAGE_ACCESSED 0x0100 /* R: page referenced */ +#define _PAGE_RW 0x0200 /* software: user write access allowed */ +#define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */ + +/* Strong Access Ordering */ +#define _PAGE_SAO (_PAGE_WRITETHRU | _PAGE_NO_CACHE | _PAGE_COHERENT) + +#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT) + +#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY) + +/* __pgprot defined in arch/powerpc/include/asm/page.h */ +#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) + +#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER) +#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER | _PAGE_EXEC) +#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER) +#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) +#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER) +#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) +#define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_WRENABLE) +#define PAGE_KERNEL_CI __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ + _PAGE_WRENABLE | _PAGE_NO_CACHE | _PAGE_GUARDED) +#define PAGE_KERNEL_EXEC __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_EXEC) + +#define PAGE_AGP __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_NO_CACHE) +#define HAVE_PAGE_AGP + +#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | \ + _PAGE_NO_CACHE | _PAGE_WRITETHRU | \ + _PAGE_4K_PFN | _PAGE_RW | _PAGE_USER | \ + _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_EXEC) +/* PTEIDX nibble */ +#define _PTEIDX_SECONDARY 0x8 +#define _PTEIDX_GROUP_IX 0x7 +/* + * POWER4 and newer have per page execute protection, older chips can only + * do this on a segment (256MB) basis. + * + * Also, write permissions imply read permissions. + * This is the closest we can get.. + * + * Note due to the way vm flags are laid out, the bits are XWR + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY_X +#define __P101 PAGE_READONLY_X +#define __P110 PAGE_COPY_X +#define __P111 PAGE_COPY_X + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY_X +#define __S101 PAGE_READONLY_X +#define __S110 PAGE_SHARED_X +#define __S111 PAGE_SHARED_X + #ifdef CONFIG_PPC_MM_SLICES #define HAVE_ARCH_UNMAPPED_AREA #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN @@ -91,39 +161,33 @@ #ifndef __ASSEMBLY__ /* - * This is the default implementation of various PTE accessors, it's - * used in all cases except Book3S with 64K pages where we have a - * concept of sub-pages + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + * + * mk_pte takes a (struct page *) as input */ -#ifndef __real_pte +#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) -#ifdef STRICT_MM_TYPECHECKS -#define __real_pte(e,p) ((real_pte_t){(e)}) -#define __rpte_to_pte(r) ((r).pte) -#else -#define __real_pte(e,p) (e) -#define __rpte_to_pte(r) (__pte(r)) -#endif -#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> 12) - -#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ - do { \ - index = 0; \ - shift = mmu_psize_defs[psize].shift; \ +static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) +{ + pte_t pte; -#define pte_iterate_hashed_end() } while(0) -#ifdef CONFIG_PPC_HAS_HASH_64K -#define pte_pagesize_index(mm, addr, pte) get_slice_psize(mm, addr) -#else -#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K -#endif + pte_val(pte) = (pfn << PTE_RPN_SHIFT) | pgprot_val(pgprot); + return pte; +} -#endif /* __real_pte */ +#define pte_modify(_pte, newprot) \ + (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))) +#define pte_none(pte) ((pte_val(pte) & ~_PAGE_HPTEFLAGS) == 0) +#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT) /* pte_clear moved to later in this file */ +#define pte_pfn(x) ((unsigned long)((pte_val(x)>>PTE_RPN_SHIFT))) +#define pte_page(x) pfn_to_page(pte_pfn(x)) + #define PMD_BAD_BITS (PTE_TABLE_SIZE-1) #define PUD_BAD_BITS (PMD_TABLE_SIZE-1) @@ -171,6 +235,36 @@ /* This now only contains the vmalloc pages */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW;} +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY;} +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;} +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE;} +static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } + +static inline pte_t pte_wrprotect(pte_t pte) { + pte_val(pte) &= ~(_PAGE_RW); return pte; } +static inline pte_t pte_mkclean(pte_t pte) { + pte_val(pte) &= ~(_PAGE_DIRTY); return pte; } +static inline pte_t pte_mkold(pte_t pte) { + pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkwrite(pte_t pte) { + pte_val(pte) |= _PAGE_RW; return pte; } +static inline pte_t pte_mkdirty(pte_t pte) { + pte_val(pte) |= _PAGE_DIRTY; return pte; } +static inline pte_t pte_mkyoung(pte_t pte) { + pte_val(pte) |= _PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkhuge(pte_t pte) { + return pte; } +static inline pte_t pte_mkspecial(pte_t pte) { + pte_val(pte) |= _PAGE_SPECIAL; return pte; } +static inline pgprot_t pte_pgprot(pte_t pte) +{ + return __pgprot(pte_val(pte) & PAGE_PROT_BITS); +} /* Atomic PTE updates */ static inline unsigned long pte_update(struct mm_struct *mm, @@ -178,7 +272,6 @@ static inline unsigned long pte_update(struct mm_struct *mm, pte_t *ptep, unsigned long clr, int huge) { -#ifdef PTE_ATOMIC_UPDATES unsigned long old, tmp; __asm__ __volatile__( @@ -191,13 +284,6 @@ static inline unsigned long pte_update(struct mm_struct *mm, : "=&r" (old), "=&r" (tmp), "=m" (*ptep) : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY) : "cc" ); -#else - unsigned long old = pte_val(*ptep); - *ptep = __pte(old & ~clr); -#endif - /* huge pages use the old page table lock */ - if (!huge) - assert_pte_locked(mm, addr); if (old & _PAGE_HASHPTE) hpte_need_flush(mm, addr, ptep, old, huge); @@ -273,17 +359,26 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_update(mm, addr, ptep, ~0UL, 0); } +/* + * set_pte stores a linux PTE into the linux page table. + */ +static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ + if (pte_present(*ptep)) + pte_clear(mm, addr, ptep); + pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS); + *ptep = pte; +} /* Set the dirty and/or accessed bits atomically in a linux PTE, this * function doesn't need to flush the hash entry */ -static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) +#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS +static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty) { unsigned long bits = pte_val(entry) & - (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | - _PAGE_EXEC | _PAGE_HWEXEC); - -#ifdef PTE_ATOMIC_UPDATES + (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); unsigned long old, tmp; __asm__ __volatile__( @@ -296,11 +391,16 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) :"=&r" (old), "=&r" (tmp), "=m" (*ptep) :"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY) :"cc"); -#else - unsigned long old = pte_val(*ptep); - *ptep = __pte(old | bits); -#endif } +#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \ +({ \ + int __changed = !pte_same(*(__ptep), __entry); \ + if (__changed) { \ + __ptep_set_access_flags(__ptep, __entry, __dirty); \ + flush_tlb_page_nohash(__vma, __address); \ + } \ + __changed; \ +}) #define __HAVE_ARCH_PTE_SAME #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0) diff --git a/trunk/arch/powerpc/include/asm/pgtable.h b/trunk/arch/powerpc/include/asm/pgtable.h index eb17da781128..07f55e601696 100644 --- a/trunk/arch/powerpc/include/asm/pgtable.h +++ b/trunk/arch/powerpc/include/asm/pgtable.h @@ -6,17 +6,7 @@ #include /* For TASK_SIZE */ #include #include - struct mm_struct; - -#ifdef CONFIG_DEBUG_VM -extern void assert_pte_locked(struct mm_struct *mm, unsigned long addr); -#else /* CONFIG_DEBUG_VM */ -static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr) -{ -} -#endif /* !CONFIG_DEBUG_VM */ - #endif /* !__ASSEMBLY__ */ #if defined(CONFIG_PPC64) @@ -27,130 +17,6 @@ static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr) #ifndef __ASSEMBLY__ -/* Generic accessors to PTE bits */ -static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } -static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } -static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } -static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } -static inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; } -static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; } -static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); } - -/* Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - * - * Even if PTEs can be unsigned long long, a PFN is always an unsigned - * long for now. - */ -static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) { - return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) | - pgprot_val(pgprot)); } -static inline unsigned long pte_pfn(pte_t pte) { - return pte_val(pte) >> PTE_RPN_SHIFT; } - -/* Keep these as a macros to avoid include dependency mess */ -#define pte_page(x) pfn_to_page(pte_pfn(x)) -#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) - -/* Generic modifiers for PTE bits */ -static inline pte_t pte_wrprotect(pte_t pte) { - pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); return pte; } -static inline pte_t pte_mkclean(pte_t pte) { - pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; } -static inline pte_t pte_mkold(pte_t pte) { - pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } -static inline pte_t pte_mkwrite(pte_t pte) { - pte_val(pte) |= _PAGE_RW; return pte; } -static inline pte_t pte_mkdirty(pte_t pte) { - pte_val(pte) |= _PAGE_DIRTY; return pte; } -static inline pte_t pte_mkyoung(pte_t pte) { - pte_val(pte) |= _PAGE_ACCESSED; return pte; } -static inline pte_t pte_mkspecial(pte_t pte) { - pte_val(pte) |= _PAGE_SPECIAL; return pte; } -static inline pte_t pte_mkhuge(pte_t pte) { - return pte; } -static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ - pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); - return pte; -} - - -/* Insert a PTE, top-level function is out of line. It uses an inline - * low level function in the respective pgtable-* files - */ -extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, - pte_t pte); - -/* This low level function performs the actual PTE insertion - * Setting the PTE depends on the MMU type and other factors. It's - * an horrible mess that I'm not going to try to clean up now but - * I'm keeping it in one place rather than spread around - */ -static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pte, int percpu) -{ -#if defined(CONFIG_PPC_STD_MMU_32) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT) - /* First case is 32-bit Hash MMU in SMP mode with 32-bit PTEs. We use the - * helper pte_update() which does an atomic update. We need to do that - * because a concurrent invalidation can clear _PAGE_HASHPTE. If it's a - * per-CPU PTE such as a kmap_atomic, we do a simple update preserving - * the hash bits instead (ie, same as the non-SMP case) - */ - if (percpu) - *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) - | (pte_val(pte) & ~_PAGE_HASHPTE)); - else - pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte)); - -#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP) - /* Second case is 32-bit with 64-bit PTE in SMP mode. In this case, we - * can just store as long as we do the two halves in the right order - * with a barrier in between. This is possible because we take care, - * in the hash code, to pre-invalidate if the PTE was already hashed, - * which synchronizes us with any concurrent invalidation. - * In the percpu case, we also fallback to the simple update preserving - * the hash bits - */ - if (percpu) { - *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) - | (pte_val(pte) & ~_PAGE_HASHPTE)); - return; - } -#if _PAGE_HASHPTE != 0 - if (pte_val(*ptep) & _PAGE_HASHPTE) - flush_hash_entry(mm, ptep, addr); -#endif - __asm__ __volatile__("\ - stw%U0%X0 %2,%0\n\ - eieio\n\ - stw%U0%X0 %L2,%1" - : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) - : "r" (pte) : "memory"); - -#elif defined(CONFIG_PPC_STD_MMU_32) - /* Third case is 32-bit hash table in UP mode, we need to preserve - * the _PAGE_HASHPTE bit since we may not have invalidated the previous - * translation in the hash yet (done in a subsequent flush_tlb_xxx()) - * and see we need to keep track that this PTE needs invalidating - */ - *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE) - | (pte_val(pte) & ~_PAGE_HASHPTE)); - -#else - /* Anything else just stores the PTE normally. That covers all 64-bit - * cases, and 32-bit non-hash with 64-bit PTEs in UP mode - */ - *ptep = pte; -#endif -} - - -#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS -extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, - pte_t *ptep, pte_t entry, int dirty); - /* * Macro to mark a page protection value as "uncacheable". */ diff --git a/trunk/arch/powerpc/include/asm/ppc-opcode.h b/trunk/arch/powerpc/include/asm/ppc-opcode.h deleted file mode 100644 index f4a4db8d5555..000000000000 --- a/trunk/arch/powerpc/include/asm/ppc-opcode.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2009 Freescale Semicondutor, Inc. - * - * 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. - * - * provides masks and opcode images for use by code generation, emulation - * and for instructions that older assemblers might not know about - */ -#ifndef _ASM_POWERPC_PPC_OPCODE_H -#define _ASM_POWERPC_PPC_OPCODE_H - -#include -#include - -/* sorted alphabetically */ -#define PPC_INST_DCBA 0x7c0005ec -#define PPC_INST_DCBA_MASK 0xfc0007fe -#define PPC_INST_DCBAL 0x7c2005ec -#define PPC_INST_DCBZL 0x7c2007ec -#define PPC_INST_ISEL 0x7c00001e -#define PPC_INST_ISEL_MASK 0xfc00003e -#define PPC_INST_LSWI 0x7c0004aa -#define PPC_INST_LSWX 0x7c00042a -#define PPC_INST_LWSYNC 0x7c2004ac -#define PPC_INST_MCRXR 0x7c000400 -#define PPC_INST_MCRXR_MASK 0xfc0007fe -#define PPC_INST_MFSPR_PVR 0x7c1f42a6 -#define PPC_INST_MFSPR_PVR_MASK 0xfc1fffff -#define PPC_INST_MSGSND 0x7c00019c -#define PPC_INST_NOP 0x60000000 -#define PPC_INST_POPCNTB 0x7c0000f4 -#define PPC_INST_POPCNTB_MASK 0xfc0007fe -#define PPC_INST_RFCI 0x4c000066 -#define PPC_INST_RFDI 0x4c00004e -#define PPC_INST_RFMCI 0x4c00004c - -#define PPC_INST_STRING 0x7c00042a -#define PPC_INST_STRING_MASK 0xfc0007fe -#define PPC_INST_STRING_GEN_MASK 0xfc00067e - -#define PPC_INST_STSWI 0x7c0005aa -#define PPC_INST_STSWX 0x7c00052a -#define PPC_INST_TLBILX 0x7c000626 -#define PPC_INST_WAIT 0x7c00007c - -/* macros to insert fields into opcodes */ -#define __PPC_RA(a) ((a & 0x1f) << 16) -#define __PPC_RB(b) ((b & 0x1f) << 11) -#define __PPC_T_TLB(t) ((t & 0x3) << 21) -#define __PPC_WC(w) ((w & 0x3) << 21) - -/* Deal with instructions that older assemblers aren't aware of */ -#define PPC_DCBAL(a, b) stringify_in_c(.long PPC_INST_DCBAL | \ - __PPC_RA(a) | __PPC_RB(b)) -#define PPC_DCBZL(a, b) stringify_in_c(.long PPC_INST_DCBZL | \ - __PPC_RA(a) | __PPC_RB(b)) -#define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \ - __PPC_RB(b)) -#define PPC_RFCI stringify_in_c(.long PPC_INST_RFCI) -#define PPC_RFDI stringify_in_c(.long PPC_INST_RFDI) -#define PPC_RFMCI stringify_in_c(.long PPC_INST_RFMCI) -#define PPC_TLBILX(t, a, b) stringify_in_c(.long PPC_INST_TLBILX | \ - __PPC_T_TLB(t) | __PPC_RA(a) | __PPC_RB(b)) -#define PPC_TLBILX_ALL(a, b) PPC_TLBILX(0, a, b) -#define PPC_TLBILX_PID(a, b) PPC_TLBILX(1, a, b) -#define PPC_TLBILX_VA(a, b) PPC_TLBILX(3, a, b) -#define PPC_WAIT(w) stringify_in_c(.long PPC_INST_WAIT | \ - __PPC_WC(w)) - -#endif /* _ASM_POWERPC_PPC_OPCODE_H */ diff --git a/trunk/arch/powerpc/include/asm/ppc_asm.h b/trunk/arch/powerpc/include/asm/ppc_asm.h index f59a66684aed..1a0d628eb114 100644 --- a/trunk/arch/powerpc/include/asm/ppc_asm.h +++ b/trunk/arch/powerpc/include/asm/ppc_asm.h @@ -7,7 +7,6 @@ #include #include #include -#include #ifndef __ASSEMBLY__ #error __FILE__ should only be used in assembler files @@ -168,6 +167,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \ #define HMT_MEDIUM_HIGH or 5,5,5 # medium high priority #define HMT_HIGH or 3,3,3 +/* handle instructions that older assemblers may not know */ +#define RFCI .long 0x4c000066 /* rfci instruction */ +#define RFDI .long 0x4c00004e /* rfdi instruction */ +#define RFMCI .long 0x4c00004c /* rfmci instruction */ + #ifdef __KERNEL__ #ifdef CONFIG_PPC64 diff --git a/trunk/arch/powerpc/include/asm/processor.h b/trunk/arch/powerpc/include/asm/processor.h index 9eed29eee604..d3466490104a 100644 --- a/trunk/arch/powerpc/include/asm/processor.h +++ b/trunk/arch/powerpc/include/asm/processor.h @@ -313,25 +313,6 @@ static inline void prefetchw(const void *x) #define HAVE_ARCH_PICK_MMAP_LAYOUT #endif -#ifdef CONFIG_PPC64 -static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32) -{ - unsigned long sp; - - if (is_32) - sp = regs->gpr[1] & 0x0ffffffffUL; - else - sp = regs->gpr[1]; - - return sp; -} -#else -static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32) -{ - return regs->gpr[1]; -} -#endif - #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_PROCESSOR_H */ diff --git a/trunk/arch/powerpc/include/asm/ps3av.h b/trunk/arch/powerpc/include/asm/ps3av.h index 0427b0b53d2d..cd24ac16660a 100644 --- a/trunk/arch/powerpc/include/asm/ps3av.h +++ b/trunk/arch/powerpc/include/asm/ps3av.h @@ -730,7 +730,7 @@ extern int ps3av_cmd_av_get_hw_conf(struct ps3av_pkt_av_get_hw_conf *); extern int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *, u32); -extern int ps3av_set_video_mode(int); +extern int ps3av_set_video_mode(u32); extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32); extern int ps3av_get_auto_mode(void); extern int ps3av_get_mode(void); diff --git a/trunk/arch/powerpc/include/asm/ps3fb.h b/trunk/arch/powerpc/include/asm/ps3fb.h index 90dbefb8cfc4..e7233a849680 100644 --- a/trunk/arch/powerpc/include/asm/ps3fb.h +++ b/trunk/arch/powerpc/include/asm/ps3fb.h @@ -21,7 +21,6 @@ #include #include -#include /* ioctl */ #define PS3FB_IOCTL_SETMODE _IOW('r', 1, int) /* set video mode */ diff --git a/trunk/arch/powerpc/include/asm/pte-40x.h b/trunk/arch/powerpc/include/asm/pte-40x.h deleted file mode 100644 index 07630faae029..000000000000 --- a/trunk/arch/powerpc/include/asm/pte-40x.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef _ASM_POWERPC_PTE_40x_H -#define _ASM_POWERPC_PTE_40x_H -#ifdef __KERNEL__ - -/* - * At present, all PowerPC 400-class processors share a similar TLB - * architecture. The instruction and data sides share a unified, - * 64-entry, fully-associative TLB which is maintained totally under - * software control. In addition, the instruction side has a - * hardware-managed, 4-entry, fully-associative TLB which serves as a - * first level to the shared TLB. These two TLBs are known as the UTLB - * and ITLB, respectively (see "mmu.h" for definitions). - * - * There are several potential gotchas here. The 40x hardware TLBLO - * field looks like this: - * - * 0 1 2 3 4 ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - * RPN..................... 0 0 EX WR ZSEL....... W I M G - * - * Where possible we make the Linux PTE bits match up with this - * - * - bits 20 and 21 must be cleared, because we use 4k pages (40x can - * support down to 1k pages), this is done in the TLBMiss exception - * handler. - * - We use only zones 0 (for kernel pages) and 1 (for user pages) - * of the 16 available. Bit 24-26 of the TLB are cleared in the TLB - * miss handler. Bit 27 is PAGE_USER, thus selecting the correct - * zone. - * - PRESENT *must* be in the bottom two bits because swap cache - * entries use the top 30 bits. Because 40x doesn't support SMP - * anyway, M is irrelevant so we borrow it for PAGE_PRESENT. Bit 30 - * is cleared in the TLB miss handler before the TLB entry is loaded. - * - All other bits of the PTE are loaded into TLBLO without - * modification, leaving us only the bits 20, 21, 24, 25, 26, 30 for - * software PTE bits. We actually use use bits 21, 24, 25, and - * 30 respectively for the software bits: ACCESSED, DIRTY, RW, and - * PRESENT. - */ - -#define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */ -#define _PAGE_FILE 0x001 /* when !present: nonlinear file mapping */ -#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */ -#define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */ -#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */ -#define _PAGE_USER 0x010 /* matches one of the zone permission bits */ -#define _PAGE_RW 0x040 /* software: Writes permitted */ -#define _PAGE_DIRTY 0x080 /* software: dirty page */ -#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */ -#define _PAGE_HWEXEC 0x200 /* hardware: EX permission */ -#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */ - -#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */ -#define _PMD_BAD 0x802 -#define _PMD_SIZE 0x0e0 /* size field, != 0 for large-page PMD entry */ -#define _PMD_SIZE_4M 0x0c0 -#define _PMD_SIZE_16M 0x0e0 - -#define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4)) - -/* Until my rework is finished, 40x still needs atomic PTE updates */ -#define PTE_ATOMIC_UPDATES 1 - -#endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_PTE_40x_H */ diff --git a/trunk/arch/powerpc/include/asm/pte-44x.h b/trunk/arch/powerpc/include/asm/pte-44x.h deleted file mode 100644 index 37e98bcf83e0..000000000000 --- a/trunk/arch/powerpc/include/asm/pte-44x.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef _ASM_POWERPC_PTE_44x_H -#define _ASM_POWERPC_PTE_44x_H -#ifdef __KERNEL__ - -/* - * Definitions for PPC440 - * - * Because of the 3 word TLB entries to support 36-bit addressing, - * the attribute are difficult to map in such a fashion that they - * are easily loaded during exception processing. I decided to - * organize the entry so the ERPN is the only portion in the - * upper word of the PTE and the attribute bits below are packed - * in as sensibly as they can be in the area below a 4KB page size - * oriented RPN. This at least makes it easy to load the RPN and - * ERPN fields in the TLB. -Matt - * - * This isn't entirely true anymore, at least some bits are now - * easier to move into the TLB from the PTE. -BenH. - * - * Note that these bits preclude future use of a page size - * less than 4KB. - * - * - * PPC 440 core has following TLB attribute fields; - * - * TLB1: - * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - * RPN................................. - - - - - - ERPN....... - * - * TLB2: - * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - * - - - - - - U0 U1 U2 U3 W I M G E - UX UW UR SX SW SR - * - * Newer 440 cores (440x6 as used on AMCC 460EX/460GT) have additional - * TLB2 storage attibute fields. Those are: - * - * TLB2: - * 0...10 11 12 13 14 15 16...31 - * no change WL1 IL1I IL1D IL2I IL2D no change - * - * There are some constrains and options, to decide mapping software bits - * into TLB entry. - * - * - PRESENT *must* be in the bottom three bits because swap cache - * entries use the top 29 bits for TLB2. - * - * - FILE *must* be in the bottom three bits because swap cache - * entries use the top 29 bits for TLB2. - * - * - CACHE COHERENT bit (M) has no effect on original PPC440 cores, - * because it doesn't support SMP. However, some later 460 variants - * have -some- form of SMP support and so I keep the bit there for - * future use - * - * With the PPC 44x Linux implementation, the 0-11th LSBs of the PTE are used - * for memory protection related functions (see PTE structure in - * include/asm-ppc/mmu.h). The _PAGE_XXX definitions in this file map to the - * above bits. Note that the bit values are CPU specific, not architecture - * specific. - * - * The kernel PTE entry holds an arch-dependent swp_entry structure under - * certain situations. In other words, in such situations some portion of - * the PTE bits are used as a swp_entry. In the PPC implementation, the - * 3-24th LSB are shared with swp_entry, however the 0-2nd three LSB still - * hold protection values. That means the three protection bits are - * reserved for both PTE and SWAP entry at the most significant three - * LSBs. - * - * There are three protection bits available for SWAP entry: - * _PAGE_PRESENT - * _PAGE_FILE - * _PAGE_HASHPTE (if HW has) - * - * So those three bits have to be inside of 0-2nd LSB of PTE. - * - */ - -#define _PAGE_PRESENT 0x00000001 /* S: PTE valid */ -#define _PAGE_RW 0x00000002 /* S: Write permission */ -#define _PAGE_FILE 0x00000004 /* S: nonlinear file mapping */ -#define _PAGE_HWEXEC 0x00000004 /* H: Execute permission */ -#define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */ -#define _PAGE_DIRTY 0x00000010 /* S: Page dirty */ -#define _PAGE_SPECIAL 0x00000020 /* S: Special page */ -#define _PAGE_USER 0x00000040 /* S: User page */ -#define _PAGE_ENDIAN 0x00000080 /* H: E bit */ -#define _PAGE_GUARDED 0x00000100 /* H: G bit */ -#define _PAGE_COHERENT 0x00000200 /* H: M bit */ -#define _PAGE_NO_CACHE 0x00000400 /* H: I bit */ -#define _PAGE_WRITETHRU 0x00000800 /* H: W bit */ - -/* TODO: Add large page lowmem mapping support */ -#define _PMD_PRESENT 0 -#define _PMD_PRESENT_MASK (PAGE_MASK) -#define _PMD_BAD (~PAGE_MASK) - -/* ERPN in a PTE never gets cleared, ignore it */ -#define _PTE_NONE_MASK 0xffffffff00000000ULL - - -#endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_PTE_44x_H */ diff --git a/trunk/arch/powerpc/include/asm/pte-8xx.h b/trunk/arch/powerpc/include/asm/pte-8xx.h deleted file mode 100644 index 8c6e31251034..000000000000 --- a/trunk/arch/powerpc/include/asm/pte-8xx.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef _ASM_POWERPC_PTE_8xx_H -#define _ASM_POWERPC_PTE_8xx_H -#ifdef __KERNEL__ - -/* - * The PowerPC MPC8xx uses a TLB with hardware assisted, software tablewalk. - * We also use the two level tables, but we can put the real bits in them - * needed for the TLB and tablewalk. These definitions require Mx_CTR.PPM = 0, - * Mx_CTR.PPCS = 0, and MD_CTR.TWAM = 1. The level 2 descriptor has - * additional page protection (when Mx_CTR.PPCS = 1) that allows TLB hit - * based upon user/super access. The TLB does not have accessed nor write - * protect. We assume that if the TLB get loaded with an entry it is - * accessed, and overload the changed bit for write protect. We use - * two bits in the software pte that are supposed to be set to zero in - * the TLB entry (24 and 25) for these indicators. Although the level 1 - * descriptor contains the guarded and writethrough/copyback bits, we can - * set these at the page level since they get copied from the Mx_TWC - * register when the TLB entry is loaded. We will use bit 27 for guard, since - * that is where it exists in the MD_TWC, and bit 26 for writethrough. - * These will get masked from the level 2 descriptor at TLB load time, and - * copied to the MD_TWC before it gets loaded. - * Large page sizes added. We currently support two sizes, 4K and 8M. - * This also allows a TLB hander optimization because we can directly - * load the PMD into MD_TWC. The 8M pages are only used for kernel - * mapping of well known areas. The PMD (PGD) entries contain control - * flags in addition to the address, so care must be taken that the - * software no longer assumes these are only pointers. - */ - -/* Definitions for 8xx embedded chips. */ -#define _PAGE_PRESENT 0x0001 /* Page is valid */ -#define _PAGE_FILE 0x0002 /* when !present: nonlinear file mapping */ -#define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */ -#define _PAGE_SHARED 0x0004 /* No ASID (context) compare */ - -/* These five software bits must be masked out when the entry is loaded - * into the TLB. - */ -#define _PAGE_EXEC 0x0008 /* software: i-cache coherency required */ -#define _PAGE_GUARDED 0x0010 /* software: guarded access */ -#define _PAGE_DIRTY 0x0020 /* software: page changed */ -#define _PAGE_RW 0x0040 /* software: user write access allowed */ -#define _PAGE_ACCESSED 0x0080 /* software: page referenced */ - -/* Setting any bits in the nibble with the follow two controls will - * require a TLB exception handler change. It is assumed unused bits - * are always zero. - */ -#define _PAGE_HWWRITE 0x0100 /* h/w write enable: never set in Linux PTE */ -#define _PAGE_USER 0x0800 /* One of the PP bits, the other is USER&~RW */ - -#define _PMD_PRESENT 0x0001 -#define _PMD_BAD 0x0ff0 -#define _PMD_PAGE_MASK 0x000c -#define _PMD_PAGE_8M 0x000c - -#define _PTE_NONE_MASK _PAGE_ACCESSED - -/* Until my rework is finished, 8xx still needs atomic PTE updates */ -#define PTE_ATOMIC_UPDATES 1 - -/* We need to add _PAGE_SHARED to kernel pages */ -#define _PAGE_KERNEL_RO (_PAGE_SHARED) -#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE) - -#endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_PTE_8xx_H */ diff --git a/trunk/arch/powerpc/include/asm/pte-common.h b/trunk/arch/powerpc/include/asm/pte-common.h deleted file mode 100644 index d9740e886801..000000000000 --- a/trunk/arch/powerpc/include/asm/pte-common.h +++ /dev/null @@ -1,180 +0,0 @@ -/* Included from asm/pgtable-*.h only ! */ - -/* - * Some bits are only used on some cpu families... Make sure that all - * the undefined gets a sensible default - */ -#ifndef _PAGE_HASHPTE -#define _PAGE_HASHPTE 0 -#endif -#ifndef _PAGE_SHARED -#define _PAGE_SHARED 0 -#endif -#ifndef _PAGE_HWWRITE -#define _PAGE_HWWRITE 0 -#endif -#ifndef _PAGE_HWEXEC -#define _PAGE_HWEXEC 0 -#endif -#ifndef _PAGE_EXEC -#define _PAGE_EXEC 0 -#endif -#ifndef _PAGE_ENDIAN -#define _PAGE_ENDIAN 0 -#endif -#ifndef _PAGE_COHERENT -#define _PAGE_COHERENT 0 -#endif -#ifndef _PAGE_WRITETHRU -#define _PAGE_WRITETHRU 0 -#endif -#ifndef _PAGE_SPECIAL -#define _PAGE_SPECIAL 0 -#endif -#ifndef _PAGE_4K_PFN -#define _PAGE_4K_PFN 0 -#endif -#ifndef _PAGE_PSIZE -#define _PAGE_PSIZE 0 -#endif -#ifndef _PMD_PRESENT_MASK -#define _PMD_PRESENT_MASK _PMD_PRESENT -#endif -#ifndef _PMD_SIZE -#define _PMD_SIZE 0 -#define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE() -#endif -#ifndef _PAGE_KERNEL_RO -#define _PAGE_KERNEL_RO 0 -#endif -#ifndef _PAGE_KERNEL_RW -#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE) -#endif -#ifndef _PAGE_HPTEFLAGS -#define _PAGE_HPTEFLAGS _PAGE_HASHPTE -#endif -#ifndef _PTE_NONE_MASK -#define _PTE_NONE_MASK _PAGE_HPTEFLAGS -#endif - -/* Make sure we get a link error if PMD_PAGE_SIZE is ever called on a - * kernel without large page PMD support - */ -#ifndef __ASSEMBLY__ -extern unsigned long bad_call_to_PMD_PAGE_SIZE(void); -#endif /* __ASSEMBLY__ */ - -/* Location of the PFN in the PTE. Most 32-bit platforms use the same - * as _PAGE_SHIFT here (ie, naturally aligned). - * Platform who don't just pre-define the value so we don't override it here - */ -#ifndef PTE_RPN_SHIFT -#define PTE_RPN_SHIFT (PAGE_SHIFT) -#endif - -/* The mask convered by the RPN must be a ULL on 32-bit platforms with - * 64-bit PTEs - */ -#if defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) -#define PTE_RPN_MAX (1ULL << (64 - PTE_RPN_SHIFT)) -#define PTE_RPN_MASK (~((1ULL< -#else -#include -#endif - -#endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_PTE_HASH64_H */ diff --git a/trunk/arch/powerpc/include/asm/reg.h b/trunk/arch/powerpc/include/asm/reg.h index c9ff1ec97479..f484a343efba 100644 --- a/trunk/arch/powerpc/include/asm/reg.h +++ b/trunk/arch/powerpc/include/asm/reg.h @@ -155,8 +155,6 @@ #define CTRL_RUNLATCH 0x1 #define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ #define DABR_TRANSLATION (1UL << 2) -#define DABR_DATA_WRITE (1UL << 1) -#define DABR_DATA_READ (1UL << 0) #define SPRN_DABR2 0x13D /* e300 */ #define SPRN_DABRX 0x3F7 /* Data Address Breakpoint Register Extension */ #define DABRX_USER (1UL << 0) diff --git a/trunk/arch/powerpc/include/asm/reg_booke.h b/trunk/arch/powerpc/include/asm/reg_booke.h index a56f4d61aa72..67453766bff1 100644 --- a/trunk/arch/powerpc/include/asm/reg_booke.h +++ b/trunk/arch/powerpc/include/asm/reg_booke.h @@ -10,7 +10,6 @@ #define __ASM_POWERPC_REG_BOOKE_H__ /* Machine State Register (MSR) Fields */ -#define MSR_GS (1<<28) /* Guest state */ #define MSR_UCLE (1<<26) /* User-mode cache lock enable */ #define MSR_SPE (1<<25) /* Enable SPE */ #define MSR_DWE (1<<10) /* Debug Wait Enable */ @@ -111,7 +110,6 @@ #define SPRN_L1CSR0 0x3F2 /* L1 Cache Control and Status Register 0 */ #define SPRN_L1CSR1 0x3F3 /* L1 Cache Control and Status Register 1 */ #define SPRN_MMUCSR0 0x3F4 /* MMU Control and Status Register 0 */ -#define SPRN_MMUCFG 0x3F7 /* MMU Configuration Register */ #define SPRN_PIT 0x3DB /* Programmable Interval Timer */ #define SPRN_BUCSR 0x3F5 /* Branch Unit Control and Status */ #define SPRN_L2CSR0 0x3F9 /* L2 Data Cache Control and Status Register 0 */ diff --git a/trunk/arch/powerpc/include/asm/spinlock.h b/trunk/arch/powerpc/include/asm/spinlock.h index c3b193121f81..36864364e601 100644 --- a/trunk/arch/powerpc/include/asm/spinlock.h +++ b/trunk/arch/powerpc/include/asm/spinlock.h @@ -287,9 +287,6 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) rw->lock = 0; } -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) - #define _raw_spin_relax(lock) __spin_yield(lock) #define _raw_read_relax(lock) __rw_yield(lock) #define _raw_write_relax(lock) __rw_yield(lock) diff --git a/trunk/arch/powerpc/include/asm/suspend.h b/trunk/arch/powerpc/include/asm/suspend.h index c6efc3466aa6..cbf2c9404c37 100644 --- a/trunk/arch/powerpc/include/asm/suspend.h +++ b/trunk/arch/powerpc/include/asm/suspend.h @@ -3,4 +3,7 @@ static inline int arch_prepare_suspend(void) { return 0; } +void save_processor_state(void); +void restore_processor_state(void); + #endif /* __ASM_POWERPC_SUSPEND_H */ diff --git a/trunk/arch/powerpc/include/asm/system.h b/trunk/arch/powerpc/include/asm/system.h index f612798e1c93..2a4be19a92c4 100644 --- a/trunk/arch/powerpc/include/asm/system.h +++ b/trunk/arch/powerpc/include/asm/system.h @@ -531,7 +531,7 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new, #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) #endif -extern unsigned long arch_align_stack(unsigned long sp); +#define arch_align_stack(x) (x) /* Used in very early kernel initialization. */ extern unsigned long reloc_offset(void); diff --git a/trunk/arch/powerpc/include/asm/thread_info.h b/trunk/arch/powerpc/include/asm/thread_info.h index 9aba5a38a7c4..9665a26a253a 100644 --- a/trunk/arch/powerpc/include/asm/thread_info.h +++ b/trunk/arch/powerpc/include/asm/thread_info.h @@ -12,10 +12,8 @@ /* We have 8k stacks on ppc32 and 16k on ppc64 */ -#if defined(CONFIG_PPC64) +#ifdef CONFIG_PPC64 #define THREAD_SHIFT 14 -#elif defined(CONFIG_PPC_256K_PAGES) -#define THREAD_SHIFT 15 #else #define THREAD_SHIFT 13 #endif @@ -156,13 +154,6 @@ static inline void set_restore_sigmask(void) ti->local_flags |= _TLF_RESTORE_SIGMASK; set_bit(TIF_SIGPENDING, &ti->flags); } - -#ifdef CONFIG_PPC64 -#define is_32bit_task() (test_thread_flag(TIF_32BIT)) -#else -#define is_32bit_task() (1) -#endif - #endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/trunk/arch/powerpc/include/asm/topology.h b/trunk/arch/powerpc/include/asm/topology.h index 054a16d68082..375258559ae6 100644 --- a/trunk/arch/powerpc/include/asm/topology.h +++ b/trunk/arch/powerpc/include/asm/topology.h @@ -24,6 +24,11 @@ static inline cpumask_t node_to_cpumask(int node) #define cpumask_of_node(node) (&numa_cpumask_lookup_table[node]) +static inline int node_to_first_cpu(int node) +{ + return cpumask_first(cpumask_of_node(node)); +} + int of_node_to_nid(struct device_node *device); struct pci_bus; diff --git a/trunk/arch/powerpc/include/asm/udbg.h b/trunk/arch/powerpc/include/asm/udbg.h index cd21e5e6b04f..6418ceea44b7 100644 --- a/trunk/arch/powerpc/include/asm/udbg.h +++ b/trunk/arch/powerpc/include/asm/udbg.h @@ -15,7 +15,6 @@ #include extern void (*udbg_putc)(char c); -extern void (*udbg_flush)(void); extern int (*udbg_getc)(void); extern int (*udbg_getc_poll)(void); diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile index 71901fbda4a5..8d1a419df35d 100644 --- a/trunk/arch/powerpc/kernel/Makefile +++ b/trunk/arch/powerpc/kernel/Makefile @@ -18,10 +18,12 @@ CFLAGS_REMOVE_cputable.o = -pg -mno-sched-epilog CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog CFLAGS_REMOVE_prom.o = -pg -mno-sched-epilog -# do not trace tracer code + +ifdef CONFIG_DYNAMIC_FTRACE +# dynamic ftrace setup. CFLAGS_REMOVE_ftrace.o = -pg -mno-sched-epilog -# timers used by tracing -CFLAGS_REMOVE_time.o = -pg -mno-sched-epilog +endif + endif obj-y := cputable.o ptrace.o syscalls.o \ @@ -59,7 +61,6 @@ obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o \ obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o obj-$(CONFIG_44x) += cpu_setup_44x.o -obj-$(CONFIG_FSL_BOOKE) += cpu_setup_fsl_booke.o dbell.o extra-$(CONFIG_PPC_STD_MMU) := head_32.o extra-$(CONFIG_PPC64) := head_64.o @@ -75,7 +76,7 @@ obj-y += time.o prom.o traps.o setup-common.o \ obj-$(CONFIG_PPC32) += entry_32.o setup_32.o obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o obj-$(CONFIG_KGDB) += kgdb.o -obj-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init.o +obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o obj-$(CONFIG_MODULES) += ppc_ksyms.o obj-$(CONFIG_BOOTX_TEXT) += btext.o obj-$(CONFIG_SMP) += smp.o @@ -93,7 +94,6 @@ obj-$(CONFIG_AUDIT) += audit.o obj64-$(CONFIG_AUDIT) += compat_audit.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o -obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o diff --git a/trunk/arch/powerpc/kernel/align.c b/trunk/arch/powerpc/kernel/align.c index 5ffcfaa77d6a..73cb6a3229ae 100644 --- a/trunk/arch/powerpc/kernel/align.c +++ b/trunk/arch/powerpc/kernel/align.c @@ -187,7 +187,7 @@ static struct aligninfo aligninfo[128] = { { 4, ST+F+S+U }, /* 11 1 1010: stfsux */ { 8, ST+F+U }, /* 11 1 1011: stfdux */ INVALID, /* 11 1 1100 */ - { 4, LD+F }, /* 11 1 1101: lfiwzx */ + INVALID, /* 11 1 1101 */ INVALID, /* 11 1 1110 */ INVALID, /* 11 1 1111 */ }; diff --git a/trunk/arch/powerpc/kernel/asm-offsets.c b/trunk/arch/powerpc/kernel/asm-offsets.c index 1e40bc053946..42fe4da4e8ae 100644 --- a/trunk/arch/powerpc/kernel/asm-offsets.c +++ b/trunk/arch/powerpc/kernel/asm-offsets.c @@ -284,6 +284,9 @@ int main(void) #endif /* ! CONFIG_PPC64 */ /* About the CPU features table */ + DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec)); + DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask)); + DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value)); DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore)); diff --git a/trunk/arch/powerpc/kernel/cpu_setup_44x.S b/trunk/arch/powerpc/kernel/cpu_setup_44x.S index 7d606f89a839..10b4ab1008af 100644 --- a/trunk/arch/powerpc/kernel/cpu_setup_44x.S +++ b/trunk/arch/powerpc/kernel/cpu_setup_44x.S @@ -34,7 +34,6 @@ _GLOBAL(__setup_cpu_440grx) blr _GLOBAL(__setup_cpu_460ex) _GLOBAL(__setup_cpu_460gt) -_GLOBAL(__setup_cpu_460sx) mflr r4 bl __init_fpu_44x bl __fixup_440A_mcheck diff --git a/trunk/arch/powerpc/kernel/cpu_setup_6xx.S b/trunk/arch/powerpc/kernel/cpu_setup_6xx.S index 54f767e31a1a..72d1d7395254 100644 --- a/trunk/arch/powerpc/kernel/cpu_setup_6xx.S +++ b/trunk/arch/powerpc/kernel/cpu_setup_6xx.S @@ -15,14 +15,9 @@ #include #include #include -#include _GLOBAL(__setup_cpu_603) mflr r4 -BEGIN_MMU_FTR_SECTION - li r10,0 - mtspr SPRN_SPRG4,r10 /* init SW LRU tracking */ -END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU) BEGIN_FTR_SECTION bl __init_fpu_registers END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE) diff --git a/trunk/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/trunk/arch/powerpc/kernel/cpu_setup_fsl_booke.S deleted file mode 100644 index eb4b9adcedb4..000000000000 --- a/trunk/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file contains low level CPU setup functions. - * Kumar Gala - * Copyright 2009 Freescale Semiconductor, Inc. - * - * Based on cpu_setup_6xx code by - * Benjamin Herrenschmidt - * - * 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 - -_GLOBAL(__setup_cpu_e200) - /* enable dedicated debug exception handling resources (Debug APU) */ - mfspr r3,SPRN_HID0 - ori r3,r3,HID0_DAPUEN@l - mtspr SPRN_HID0,r3 - b __setup_e200_ivors -_GLOBAL(__setup_cpu_e500v1) -_GLOBAL(__setup_cpu_e500v2) - b __setup_e500_ivors -_GLOBAL(__setup_cpu_e500mc) - b __setup_e500mc_ivors - diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c index cd1b687544f3..923f87aff20a 100644 --- a/trunk/arch/powerpc/kernel/cputable.c +++ b/trunk/arch/powerpc/kernel/cputable.c @@ -35,10 +35,6 @@ const char *powerpc_base_platform; * and ppc64 */ #ifdef CONFIG_PPC32 -extern void __setup_cpu_e200(unsigned long offset, struct cpu_spec* spec); -extern void __setup_cpu_e500v1(unsigned long offset, struct cpu_spec* spec); -extern void __setup_cpu_e500v2(unsigned long offset, struct cpu_spec* spec); -extern void __setup_cpu_e500mc(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec); @@ -47,7 +43,6 @@ extern void __setup_cpu_440spe(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_440x5(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_460ex(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_460gt(unsigned long offset, struct cpu_spec* spec); -extern void __setup_cpu_460sx(unsigned long offset, struct cpu_spec *spec); extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec); @@ -731,8 +726,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_setup = __setup_cpu_750, .machine_check = machine_check_generic, .platform = "ppc750", - .oprofile_cpu_type = "ppc/750", - .oprofile_type = PPC_OPROFILE_G4, }, { /* 750FX rev 2.0 must disable HID0[DPM] */ .pvr_mask = 0xffffffff, @@ -748,8 +741,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_setup = __setup_cpu_750, .machine_check = machine_check_generic, .platform = "ppc750", - .oprofile_cpu_type = "ppc/750", - .oprofile_type = PPC_OPROFILE_G4, }, { /* 750FX (All revs except 2.0) */ .pvr_mask = 0xffff0000, @@ -765,8 +756,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_setup = __setup_cpu_750fx, .machine_check = machine_check_generic, .platform = "ppc750", - .oprofile_cpu_type = "ppc/750", - .oprofile_type = PPC_OPROFILE_G4, }, { /* 750GX */ .pvr_mask = 0xffff0000, @@ -782,8 +771,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_setup = __setup_cpu_750fx, .machine_check = machine_check_generic, .platform = "ppc750", - .oprofile_cpu_type = "ppc/750", - .oprofile_type = PPC_OPROFILE_G4, }, { /* 740/750 (L2CR bit need fixup for 740) */ .pvr_mask = 0xffff0000, @@ -1090,8 +1077,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_name = "e300c2", .cpu_features = CPU_FTRS_E300C2, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, - .mmu_features = MMU_FTR_USE_HIGH_BATS | - MMU_FTR_NEED_DTLB_SW_LRU, + .mmu_features = MMU_FTR_USE_HIGH_BATS, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603, @@ -1104,8 +1090,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_name = "e300c3", .cpu_features = CPU_FTRS_E300, .cpu_user_features = COMMON_USER, - .mmu_features = MMU_FTR_USE_HIGH_BATS | - MMU_FTR_NEED_DTLB_SW_LRU, + .mmu_features = MMU_FTR_USE_HIGH_BATS, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603, @@ -1120,8 +1105,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_name = "e300c4", .cpu_features = CPU_FTRS_E300, .cpu_user_features = COMMON_USER, - .mmu_features = MMU_FTR_USE_HIGH_BATS | - MMU_FTR_NEED_DTLB_SW_LRU, + .mmu_features = MMU_FTR_USE_HIGH_BATS, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603, @@ -1650,19 +1634,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_440A, .platform = "ppc440", }, - { /* 460SX */ - .pvr_mask = 0xffffff00, - .pvr_value = 0x13541800, - .cpu_name = "460SX", - .cpu_features = CPU_FTRS_44X, - .cpu_user_features = COMMON_USER_BOOKE, - .mmu_features = MMU_FTR_TYPE_44x, - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_460sx, - .machine_check = machine_check_440A, - .platform = "ppc440", - }, { /* default match */ .pvr_mask = 0x00000000, .pvr_value = 0x00000000, @@ -1716,7 +1687,6 @@ static struct cpu_spec __initdata cpu_specs[] = { PPC_FEATURE_UNIFIED_CACHE, .mmu_features = MMU_FTR_TYPE_FSL_E, .dcache_bsize = 32, - .cpu_setup = __setup_cpu_e200, .machine_check = machine_check_e200, .platform = "ppc5554", } @@ -1736,7 +1706,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .num_pmcs = 4, .oprofile_cpu_type = "ppc/e500", .oprofile_type = PPC_OPROFILE_FSL_EMB, - .cpu_setup = __setup_cpu_e500v1, .machine_check = machine_check_e500, .platform = "ppc8540", }, @@ -1755,7 +1724,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .num_pmcs = 4, .oprofile_cpu_type = "ppc/e500", .oprofile_type = PPC_OPROFILE_FSL_EMB, - .cpu_setup = __setup_cpu_e500v2, .machine_check = machine_check_e500, .platform = "ppc8548", }, @@ -1765,14 +1733,12 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_name = "e500mc", .cpu_features = CPU_FTRS_E500MC, .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, - .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS | - MMU_FTR_USE_TLBILX, + .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS, .icache_bsize = 64, .dcache_bsize = 64, .num_pmcs = 4, .oprofile_cpu_type = "ppc/e500", /* xxx - galak, e500mc? */ .oprofile_type = PPC_OPROFILE_FSL_EMB, - .cpu_setup = __setup_cpu_e500mc, .machine_check = machine_check_e500, .platform = "ppce500mc", }, @@ -1796,84 +1762,74 @@ static struct cpu_spec __initdata cpu_specs[] = { static struct cpu_spec the_cpu_spec; -static void __init setup_cpu_spec(unsigned long offset, struct cpu_spec *s) +struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr) { + struct cpu_spec *s = cpu_specs; struct cpu_spec *t = &the_cpu_spec; - struct cpu_spec old; + int i; + s = PTRRELOC(s); t = PTRRELOC(t); - old = *t; - /* Copy everything, then do fixups */ - *t = *s; - - /* - * If we are overriding a previous value derived from the real - * PVR with a new value obtained using a logical PVR value, - * don't modify the performance monitor fields. - */ - if (old.num_pmcs && !s->num_pmcs) { - t->num_pmcs = old.num_pmcs; - t->pmc_type = old.pmc_type; - t->oprofile_type = old.oprofile_type; - t->oprofile_mmcra_sihv = old.oprofile_mmcra_sihv; - t->oprofile_mmcra_sipr = old.oprofile_mmcra_sipr; - t->oprofile_mmcra_clear = old.oprofile_mmcra_clear; - - /* - * If we have passed through this logic once before and - * have pulled the default case because the real PVR was - * not found inside cpu_specs[], then we are possibly - * running in compatibility mode. In that case, let the - * oprofiler know which set of compatibility counters to - * pull from by making sure the oprofile_cpu_type string - * is set to that of compatibility mode. If the - * oprofile_cpu_type already has a value, then we are - * possibly overriding a real PVR with a logical one, - * and, in that case, keep the current value for - * oprofile_cpu_type. - */ - if (old.oprofile_cpu_type == NULL) - t->oprofile_cpu_type = s->oprofile_cpu_type; - } - - *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec; + for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) + if ((pvr & s->pvr_mask) == s->pvr_value) { + /* + * If we are overriding a previous value derived + * from the real PVR with a new value obtained + * using a logical PVR value, don't modify the + * performance monitor fields. + */ + if (t->num_pmcs && !s->num_pmcs) { + t->cpu_name = s->cpu_name; + t->cpu_features = s->cpu_features; + t->cpu_user_features = s->cpu_user_features; + t->icache_bsize = s->icache_bsize; + t->dcache_bsize = s->dcache_bsize; + t->cpu_setup = s->cpu_setup; + t->cpu_restore = s->cpu_restore; + t->platform = s->platform; + /* + * If we have passed through this logic once + * before and have pulled the default case + * because the real PVR was not found inside + * cpu_specs[], then we are possibly running in + * compatibility mode. In that case, let the + * oprofiler know which set of compatibility + * counters to pull from by making sure the + * oprofile_cpu_type string is set to that of + * compatibility mode. If the oprofile_cpu_type + * already has a value, then we are possibly + * overriding a real PVR with a logical one, and, + * in that case, keep the current value for + * oprofile_cpu_type. + */ + if (t->oprofile_cpu_type == NULL) + t->oprofile_cpu_type = s->oprofile_cpu_type; + } else + *t = *s; + *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec; - /* - * Set the base platform string once; assumes - * we're called with real pvr first. - */ - if (*PTRRELOC(&powerpc_base_platform) == NULL) - *PTRRELOC(&powerpc_base_platform) = t->platform; + /* + * Set the base platform string once; assumes + * we're called with real pvr first. + */ + if (*PTRRELOC(&powerpc_base_platform) == NULL) + *PTRRELOC(&powerpc_base_platform) = t->platform; #if defined(CONFIG_PPC64) || defined(CONFIG_BOOKE) - /* ppc64 and booke expect identify_cpu to also call setup_cpu for - * that processor. I will consolidate that at a later time, for now, - * just use #ifdef. We also don't need to PTRRELOC the function - * pointer on ppc64 and booke as we are running at 0 in real mode - * on ppc64 and reloc_offset is always 0 on booke. - */ - if (s->cpu_setup) { - s->cpu_setup(offset, s); - } + /* ppc64 and booke expect identify_cpu to also call + * setup_cpu for that processor. I will consolidate + * that at a later time, for now, just use #ifdef. + * we also don't need to PTRRELOC the function pointer + * on ppc64 and booke as we are running at 0 in real + * mode on ppc64 and reloc_offset is always 0 on booke. + */ + if (s->cpu_setup) { + s->cpu_setup(offset, s); + } #endif /* CONFIG_PPC64 || CONFIG_BOOKE */ -} - -struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr) -{ - struct cpu_spec *s = cpu_specs; - int i; - - s = PTRRELOC(s); - - for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) { - if ((pvr & s->pvr_mask) == s->pvr_value) { - setup_cpu_spec(offset, s); return s; } - } - BUG(); - return NULL; } diff --git a/trunk/arch/powerpc/kernel/crash_dump.c b/trunk/arch/powerpc/kernel/crash_dump.c index 5fb667a60894..19671aca6591 100644 --- a/trunk/arch/powerpc/kernel/crash_dump.c +++ b/trunk/arch/powerpc/kernel/crash_dump.c @@ -48,7 +48,7 @@ static void __init create_trampoline(unsigned long addr) * branch to "addr" we jump to ("addr" + 32 MB). Although it requires * two instructions it doesn't require any registers. */ - patch_instruction(p, PPC_INST_NOP); + patch_instruction(p, PPC_NOP_INSTR); patch_branch(++p, addr + PHYSICAL_START, 0); } diff --git a/trunk/arch/powerpc/kernel/dbell.c b/trunk/arch/powerpc/kernel/dbell.c deleted file mode 100644 index 1493734cd871..000000000000 --- a/trunk/arch/powerpc/kernel/dbell.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Author: Kumar Gala - * - * Copyright 2009 Freescale Semiconductor Inc. - * - * 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 - -#ifdef CONFIG_SMP -unsigned long dbell_smp_message[NR_CPUS]; - -void smp_dbell_message_pass(int target, int msg) -{ - int i; - - if(target < NR_CPUS) { - set_bit(msg, &dbell_smp_message[target]); - ppc_msgsnd(PPC_DBELL, 0, target); - } - else if(target == MSG_ALL_BUT_SELF) { - for_each_online_cpu(i) { - if (i == smp_processor_id()) - continue; - set_bit(msg, &dbell_smp_message[i]); - ppc_msgsnd(PPC_DBELL, 0, i); - } - } - else { /* target == MSG_ALL */ - for_each_online_cpu(i) - set_bit(msg, &dbell_smp_message[i]); - ppc_msgsnd(PPC_DBELL, PPC_DBELL_MSG_BRDCAST, 0); - } -} -#endif diff --git a/trunk/arch/powerpc/kernel/entry_32.S b/trunk/arch/powerpc/kernel/entry_32.S index 4dd38f129153..6f7eb7e00c79 100644 --- a/trunk/arch/powerpc/kernel/entry_32.S +++ b/trunk/arch/powerpc/kernel/entry_32.S @@ -63,7 +63,7 @@ debug_transfer_to_handler: .globl crit_transfer_to_handler crit_transfer_to_handler: -#ifdef CONFIG_PPC_BOOK3E_MMU +#ifdef CONFIG_FSL_BOOKE mfspr r0,SPRN_MAS0 stw r0,MAS0(r11) mfspr r0,SPRN_MAS1 @@ -78,7 +78,7 @@ crit_transfer_to_handler: mfspr r0,SPRN_MAS7 stw r0,MAS7(r11) #endif /* CONFIG_PHYS_64BIT */ -#endif /* CONFIG_PPC_BOOK3E_MMU */ +#endif /* CONFIG_FSL_BOOKE */ #ifdef CONFIG_44x mfspr r0,SPRN_MMUCR stw r0,MMUCR(r11) @@ -914,7 +914,7 @@ exc_exit_restart_end: mtspr SPRN_##exc_lvl_srr0,r9; \ mtspr SPRN_##exc_lvl_srr1,r10; -#if defined(CONFIG_PPC_BOOK3E_MMU) +#if defined(CONFIG_FSL_BOOKE) #ifdef CONFIG_PHYS_64BIT #define RESTORE_MAS7 \ lwz r11,MAS7(r1); \ @@ -956,7 +956,7 @@ ret_from_crit_exc: lwz r10,crit_srr1@l(r10); mtspr SPRN_SRR0,r9; mtspr SPRN_SRR1,r10; - RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI) + RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI) #endif /* CONFIG_40x */ #ifdef CONFIG_BOOKE @@ -967,7 +967,7 @@ ret_from_crit_exc: stw r10,KSP_LIMIT(r9) RESTORE_xSRR(SRR0,SRR1); RESTORE_MMU_REGS; - RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI) + RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI) .globl ret_from_debug_exc ret_from_debug_exc: @@ -981,7 +981,7 @@ ret_from_debug_exc: RESTORE_xSRR(SRR0,SRR1); RESTORE_xSRR(CSRR0,CSRR1); RESTORE_MMU_REGS; - RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, PPC_RFDI) + RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI) .globl ret_from_mcheck_exc ret_from_mcheck_exc: @@ -992,7 +992,7 @@ ret_from_mcheck_exc: RESTORE_xSRR(CSRR0,CSRR1); RESTORE_xSRR(DSRR0,DSRR1); RESTORE_MMU_REGS; - RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, PPC_RFMCI) + RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI) #endif /* CONFIG_BOOKE */ /* @@ -1176,27 +1176,59 @@ _GLOBAL(_mcount) bctr _GLOBAL(ftrace_caller) - MCOUNT_SAVE_FRAME - /* r3 ends up with link register */ + /* Based off of objdump optput from glibc */ + stwu r1,-48(r1) + stw r3, 12(r1) + stw r4, 16(r1) + stw r5, 20(r1) + stw r6, 24(r1) + mflr r3 + lwz r4, 52(r1) + mfcr r5 + stw r7, 28(r1) + stw r8, 32(r1) + stw r9, 36(r1) + stw r10,40(r1) + stw r3, 44(r1) + stw r5, 8(r1) subi r3, r3, MCOUNT_INSN_SIZE .globl ftrace_call ftrace_call: bl ftrace_stub nop -#ifdef CONFIG_FUNCTION_GRAPH_TRACER -.globl ftrace_graph_call -ftrace_graph_call: - b ftrace_graph_stub -_GLOBAL(ftrace_graph_stub) -#endif - MCOUNT_RESTORE_FRAME - /* old link register ends up in ctr reg */ + lwz r6, 8(r1) + lwz r0, 44(r1) + lwz r3, 12(r1) + mtctr r0 + lwz r4, 16(r1) + mtcr r6 + lwz r5, 20(r1) + lwz r6, 24(r1) + lwz r0, 52(r1) + lwz r7, 28(r1) + lwz r8, 32(r1) + mtlr r0 + lwz r9, 36(r1) + lwz r10,40(r1) + addi r1, r1, 48 bctr #else _GLOBAL(mcount) _GLOBAL(_mcount) - - MCOUNT_SAVE_FRAME + stwu r1,-48(r1) + stw r3, 12(r1) + stw r4, 16(r1) + stw r5, 20(r1) + stw r6, 24(r1) + mflr r3 + lwz r4, 52(r1) + mfcr r5 + stw r7, 28(r1) + stw r8, 32(r1) + stw r9, 36(r1) + stw r10,40(r1) + stw r3, 44(r1) + stw r5, 8(r1) subi r3, r3, MCOUNT_INSN_SIZE LOAD_REG_ADDR(r5, ftrace_trace_function) @@ -1204,55 +1236,28 @@ _GLOBAL(_mcount) mtctr r5 bctrl + nop -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - b ftrace_graph_caller -#endif - MCOUNT_RESTORE_FRAME + lwz r6, 8(r1) + lwz r0, 44(r1) + lwz r3, 12(r1) + mtctr r0 + lwz r4, 16(r1) + mtcr r6 + lwz r5, 20(r1) + lwz r6, 24(r1) + lwz r0, 52(r1) + lwz r7, 28(r1) + lwz r8, 32(r1) + mtlr r0 + lwz r9, 36(r1) + lwz r10,40(r1) + addi r1, r1, 48 bctr #endif _GLOBAL(ftrace_stub) blr -#ifdef CONFIG_FUNCTION_GRAPH_TRACER -_GLOBAL(ftrace_graph_caller) - /* load r4 with local address */ - lwz r4, 44(r1) - subi r4, r4, MCOUNT_INSN_SIZE - - /* get the parent address */ - addi r3, r1, 52 - - bl prepare_ftrace_return - nop - - MCOUNT_RESTORE_FRAME - /* old link register ends up in ctr reg */ - bctr - -_GLOBAL(return_to_handler) - /* need to save return values */ - stwu r1, -32(r1) - stw r3, 20(r1) - stw r4, 16(r1) - stw r31, 12(r1) - mr r31, r1 - - bl ftrace_return_to_handler - nop - - /* return value has real return address */ - mtlr r3 - - lwz r3, 20(r1) - lwz r4, 16(r1) - lwz r31,12(r1) - lwz r1, 0(r1) - - /* Jump back to real return address */ - blr -#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ - #endif /* CONFIG_MCOUNT */ diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index abfc32330479..383ed6eb0085 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -908,12 +908,6 @@ _GLOBAL(ftrace_caller) ftrace_call: bl ftrace_stub nop -#ifdef CONFIG_FUNCTION_GRAPH_TRACER -.globl ftrace_graph_call -ftrace_graph_call: - b ftrace_graph_stub -_GLOBAL(ftrace_graph_stub) -#endif ld r0, 128(r1) mtlr r0 addi r1, r1, 112 @@ -937,90 +931,13 @@ _GLOBAL(_mcount) ld r5,0(r5) mtctr r5 bctrl - nop - - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - b ftrace_graph_caller -#endif - ld r0, 128(r1) - mtlr r0 - addi r1, r1, 112 -_GLOBAL(ftrace_stub) - blr - -#endif /* CONFIG_DYNAMIC_FTRACE */ - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER -_GLOBAL(ftrace_graph_caller) - /* load r4 with local address */ - ld r4, 128(r1) - subi r4, r4, MCOUNT_INSN_SIZE - /* get the parent address */ - ld r11, 112(r1) - addi r3, r11, 16 - - bl .prepare_ftrace_return nop - ld r0, 128(r1) mtlr r0 addi r1, r1, 112 +_GLOBAL(ftrace_stub) blr -_GLOBAL(return_to_handler) - /* need to save return values */ - std r4, -24(r1) - std r3, -16(r1) - std r31, -8(r1) - mr r31, r1 - stdu r1, -112(r1) - - bl .ftrace_return_to_handler - nop - - /* return value has real return address */ - mtlr r3 - - ld r1, 0(r1) - ld r4, -24(r1) - ld r3, -16(r1) - ld r31, -8(r1) - - /* Jump back to real return address */ - blr - -_GLOBAL(mod_return_to_handler) - /* need to save return values */ - std r4, -32(r1) - std r3, -24(r1) - /* save TOC */ - std r2, -16(r1) - std r31, -8(r1) - mr r31, r1 - stdu r1, -112(r1) - - /* - * We are in a module using the module's TOC. - * Switch to our TOC to run inside the core kernel. - */ - LOAD_REG_IMMEDIATE(r4,ftrace_return_to_handler) - ld r2, 8(r4) - - bl .ftrace_return_to_handler - nop - - /* return value has real return address */ - mtlr r3 - - ld r1, 0(r1) - ld r4, -32(r1) - ld r3, -24(r1) - ld r2, -16(r1) - ld r31, -8(r1) - - /* Jump back to real return address */ - blr -#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ -#endif /* CONFIG_FUNCTION_TRACER */ +#endif +#endif diff --git a/trunk/arch/powerpc/kernel/ftrace.c b/trunk/arch/powerpc/kernel/ftrace.c index 5b5d16b2cac8..60c60ccf5e3c 100644 --- a/trunk/arch/powerpc/kernel/ftrace.c +++ b/trunk/arch/powerpc/kernel/ftrace.c @@ -5,9 +5,6 @@ * * Thanks goes out to P.A. Semi, Inc for supplying me with a PPC64 box. * - * Added function graph tracer code, taken from x86 that was written - * by Frederic Weisbecker, and ported to PPC by Steven Rostedt. - * */ #include @@ -23,6 +20,14 @@ #include #include +#if 0 +#define DEBUGP printk +#else +#define DEBUGP(fmt , ...) do { } while (0) +#endif + +static unsigned int ftrace_nop = PPC_NOP_INSTR; + #ifdef CONFIG_PPC32 # define GET_ADDR(addr) addr #else @@ -30,23 +35,37 @@ # define GET_ADDR(addr) (*(unsigned long *)addr) #endif -#ifdef CONFIG_DYNAMIC_FTRACE -static unsigned int ftrace_nop_replace(void) + +static unsigned int ftrace_calc_offset(long ip, long addr) { - return PPC_INST_NOP; + return (int)(addr - ip); } -static unsigned int -ftrace_call_replace(unsigned long ip, unsigned long addr, int link) +static unsigned char *ftrace_nop_replace(void) { - unsigned int op; + return (char *)&ftrace_nop; +} + +static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) +{ + static unsigned int op; + /* + * It would be nice to just use create_function_call, but that will + * update the code itself. Here we need to just return the + * instruction that is going to be modified, without modifying the + * code. + */ addr = GET_ADDR(addr); - /* if (link) set op to 'bl' else 'b' */ - op = create_branch((unsigned int *)ip, addr, link ? 1 : 0); + /* Set to "bl addr" */ + op = 0x48000001 | (ftrace_calc_offset(ip, addr) & 0x03fffffc); - return op; + /* + * No locking needed, this must be called via kstop_machine + * which in essence is like running on a uniprocessor machine. + */ + return (unsigned char *)&op; } #ifdef CONFIG_PPC64 @@ -58,9 +77,10 @@ ftrace_call_replace(unsigned long ip, unsigned long addr, int link) #endif static int -ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new) +ftrace_modify_code(unsigned long ip, unsigned char *old_code, + unsigned char *new_code) { - unsigned int replaced; + unsigned char replaced[MCOUNT_INSN_SIZE]; /* * Note: Due to modules and __init, code can @@ -73,15 +93,15 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new) */ /* read the text we want to modify */ - if (probe_kernel_read(&replaced, (void *)ip, MCOUNT_INSN_SIZE)) + if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE)) return -EFAULT; /* Make sure it is what we expect it to be */ - if (replaced != old) + if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0) return -EINVAL; /* replace the text with the new text */ - if (probe_kernel_write((void *)ip, &new, MCOUNT_INSN_SIZE)) + if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE)) return -EPERM; flush_icache_range(ip, ip + 8); @@ -99,8 +119,6 @@ static int test_24bit_addr(unsigned long ip, unsigned long addr) return create_branch((unsigned int *)ip, addr, 0); } -#ifdef CONFIG_MODULES - static int is_bl_op(unsigned int op) { return (op & 0xfc000003) == 0x48000001; @@ -157,7 +175,7 @@ __ftrace_make_nop(struct module *mod, * 0xe8, 0x4c, 0x00, 0x28, ld r2,40(r12) */ - pr_debug("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc); + DEBUGP("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc); /* Find where the trampoline jumps to */ if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) { @@ -165,7 +183,7 @@ __ftrace_make_nop(struct module *mod, return -EFAULT; } - pr_debug(" %08x %08x", jmp[0], jmp[1]); + DEBUGP(" %08x %08x", jmp[0], jmp[1]); /* verify that this is what we expect it to be */ if (((jmp[0] & 0xffff0000) != 0x3d820000) || @@ -181,18 +199,18 @@ __ftrace_make_nop(struct module *mod, offset = ((unsigned)((unsigned short)jmp[0]) << 16) + (int)((short)jmp[1]); - pr_debug(" %x ", offset); + DEBUGP(" %x ", offset); /* get the address this jumps too */ tramp = mod->arch.toc + offset + 32; - pr_debug("toc: %lx", tramp); + DEBUGP("toc: %lx", tramp); if (probe_kernel_read(jmp, (void *)tramp, 8)) { printk(KERN_ERR "Failed to read %lx\n", tramp); return -EFAULT; } - pr_debug(" %08x %08x\n", jmp[0], jmp[1]); + DEBUGP(" %08x %08x\n", jmp[0], jmp[1]); ptr = ((unsigned long)jmp[0] << 32) + jmp[1]; @@ -269,7 +287,7 @@ __ftrace_make_nop(struct module *mod, * 0x4e, 0x80, 0x04, 0x20 bctr */ - pr_debug("ip:%lx jumps to %lx", ip, tramp); + DEBUGP("ip:%lx jumps to %lx", ip, tramp); /* Find where the trampoline jumps to */ if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) { @@ -277,7 +295,7 @@ __ftrace_make_nop(struct module *mod, return -EFAULT; } - pr_debug(" %08x %08x ", jmp[0], jmp[1]); + DEBUGP(" %08x %08x ", jmp[0], jmp[1]); /* verify that this is what we expect it to be */ if (((jmp[0] & 0xffff0000) != 0x3d600000) || @@ -293,7 +311,7 @@ __ftrace_make_nop(struct module *mod, if (tramp & 0x8000) tramp -= 0x10000; - pr_debug(" %x ", tramp); + DEBUGP(" %x ", tramp); if (tramp != addr) { printk(KERN_ERR @@ -302,7 +320,7 @@ __ftrace_make_nop(struct module *mod, return -EINVAL; } - op = PPC_INST_NOP; + op = PPC_NOP_INSTR; if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE)) return -EPERM; @@ -312,13 +330,12 @@ __ftrace_make_nop(struct module *mod, return 0; } #endif /* PPC64 */ -#endif /* CONFIG_MODULES */ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr) { + unsigned char *old, *new; unsigned long ip = rec->ip; - unsigned int old, new; /* * If the calling address is more that 24 bits away, @@ -327,12 +344,11 @@ int ftrace_make_nop(struct module *mod, */ if (test_24bit_addr(ip, addr)) { /* within range */ - old = ftrace_call_replace(ip, addr, 1); + old = ftrace_call_replace(ip, addr); new = ftrace_nop_replace(); return ftrace_modify_code(ip, old, new); } -#ifdef CONFIG_MODULES /* * Out of range jumps are called from modules. * We should either already have a pointer to the module @@ -357,13 +373,9 @@ int ftrace_make_nop(struct module *mod, mod = rec->arch.mod; return __ftrace_make_nop(mod, rec, addr); -#else - /* We should not get here without modules */ - return -EINVAL; -#endif /* CONFIG_MODULES */ + } -#ifdef CONFIG_MODULES #ifdef CONFIG_PPC64 static int __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) @@ -380,7 +392,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) * b +8; ld r2,40(r1) */ if (((op[0] != 0x48000008) || (op[1] != 0xe8410028)) && - ((op[0] != PPC_INST_NOP) || (op[1] != PPC_INST_NOP))) { + ((op[0] != PPC_NOP_INSTR) || (op[1] != PPC_NOP_INSTR))) { printk(KERN_ERR "Expected NOPs but have %x %x\n", op[0], op[1]); return -EINVAL; } @@ -402,7 +414,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) /* ld r2,40(r1) */ op[1] = 0xe8410028; - pr_debug("write to %lx\n", rec->ip); + DEBUGP("write to %lx\n", rec->ip); if (probe_kernel_write((void *)ip, op, MCOUNT_INSN_SIZE * 2)) return -EPERM; @@ -423,7 +435,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) return -EFAULT; /* It should be pointing to a nop */ - if (op != PPC_INST_NOP) { + if (op != PPC_NOP_INSTR) { printk(KERN_ERR "Expected NOP but have %x\n", op); return -EINVAL; } @@ -442,7 +454,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) return -EINVAL; } - pr_debug("write to %lx\n", rec->ip); + DEBUGP("write to %lx\n", rec->ip); if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE)) return -EPERM; @@ -452,12 +464,11 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) return 0; } #endif /* CONFIG_PPC64 */ -#endif /* CONFIG_MODULES */ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) { + unsigned char *old, *new; unsigned long ip = rec->ip; - unsigned int old, new; /* * If the calling address is more that 24 bits away, @@ -467,11 +478,10 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) if (test_24bit_addr(ip, addr)) { /* within range */ old = ftrace_nop_replace(); - new = ftrace_call_replace(ip, addr, 1); + new = ftrace_call_replace(ip, addr); return ftrace_modify_code(ip, old, new); } -#ifdef CONFIG_MODULES /* * Out of range jumps are called from modules. * Being that we are converting from nop, it had better @@ -483,20 +493,16 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) } return __ftrace_make_call(rec, addr); -#else - /* We should not get here without modules */ - return -EINVAL; -#endif /* CONFIG_MODULES */ } int ftrace_update_ftrace_func(ftrace_func_t func) { unsigned long ip = (unsigned long)(&ftrace_call); - unsigned int old, new; + unsigned char old[MCOUNT_INSN_SIZE], *new; int ret; - old = *(unsigned int *)&ftrace_call; - new = ftrace_call_replace(ip, (unsigned long)func, 1); + memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE); + new = ftrace_call_replace(ip, (unsigned long)func); ret = ftrace_modify_code(ip, old, new); return ret; @@ -511,115 +517,3 @@ int __init ftrace_dyn_arch_init(void *data) return 0; } -#endif /* CONFIG_DYNAMIC_FTRACE */ - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - -#ifdef CONFIG_DYNAMIC_FTRACE -extern void ftrace_graph_call(void); -extern void ftrace_graph_stub(void); - -int ftrace_enable_ftrace_graph_caller(void) -{ - unsigned long ip = (unsigned long)(&ftrace_graph_call); - unsigned long addr = (unsigned long)(&ftrace_graph_caller); - unsigned long stub = (unsigned long)(&ftrace_graph_stub); - unsigned int old, new; - - old = ftrace_call_replace(ip, stub, 0); - new = ftrace_call_replace(ip, addr, 0); - - return ftrace_modify_code(ip, old, new); -} - -int ftrace_disable_ftrace_graph_caller(void) -{ - unsigned long ip = (unsigned long)(&ftrace_graph_call); - unsigned long addr = (unsigned long)(&ftrace_graph_caller); - unsigned long stub = (unsigned long)(&ftrace_graph_stub); - unsigned int old, new; - - old = ftrace_call_replace(ip, addr, 0); - new = ftrace_call_replace(ip, stub, 0); - - return ftrace_modify_code(ip, old, new); -} -#endif /* CONFIG_DYNAMIC_FTRACE */ - -#ifdef CONFIG_PPC64 -extern void mod_return_to_handler(void); -#endif - -/* - * Hook the return address and push it in the stack of return addrs - * in current thread info. - */ -void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) -{ - unsigned long old; - unsigned long long calltime; - int faulted; - struct ftrace_graph_ent trace; - unsigned long return_hooker = (unsigned long)&return_to_handler; - - if (unlikely(atomic_read(¤t->tracing_graph_pause))) - return; - -#if CONFIG_PPC64 - /* non core kernel code needs to save and restore the TOC */ - if (REGION_ID(self_addr) != KERNEL_REGION_ID) - return_hooker = (unsigned long)&mod_return_to_handler; -#endif - - return_hooker = GET_ADDR(return_hooker); - - /* - * Protect against fault, even if it shouldn't - * happen. This tool is too much intrusive to - * ignore such a protection. - */ - asm volatile( - "1: " PPC_LL "%[old], 0(%[parent])\n" - "2: " PPC_STL "%[return_hooker], 0(%[parent])\n" - " li %[faulted], 0\n" - "3:\n" - - ".section .fixup, \"ax\"\n" - "4: li %[faulted], 1\n" - " b 3b\n" - ".previous\n" - - ".section __ex_table,\"a\"\n" - PPC_LONG_ALIGN "\n" - PPC_LONG "1b,4b\n" - PPC_LONG "2b,4b\n" - ".previous" - - : [old] "=r" (old), [faulted] "=r" (faulted) - : [parent] "r" (parent), [return_hooker] "r" (return_hooker) - : "memory" - ); - - if (unlikely(faulted)) { - ftrace_graph_stop(); - WARN_ON(1); - return; - } - - calltime = cpu_clock(raw_smp_processor_id()); - - if (ftrace_push_return_trace(old, calltime, - self_addr, &trace.depth) == -EBUSY) { - *parent = old; - return; - } - - trace.func = self_addr; - - /* Only trace if the calling function expects to */ - if (!ftrace_graph_entry(&trace)) { - current->curr_ret_stack--; - *parent = old; - } -} -#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ diff --git a/trunk/arch/powerpc/kernel/head_32.S b/trunk/arch/powerpc/kernel/head_32.S index 54e68c11ae15..d794a637e421 100644 --- a/trunk/arch/powerpc/kernel/head_32.S +++ b/trunk/arch/powerpc/kernel/head_32.S @@ -108,21 +108,18 @@ __start: * because OF may have I/O devices mapped into that area * (particularly on CHRP). */ +#ifdef CONFIG_PPC_MULTIPLATFORM cmpwi 0,r5,0 beq 1f -#ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE /* find out where we are now */ bcl 20,31,$+4 0: mflr r8 /* r8 = runtime addr here */ addis r8,r8,(_stext - 0b)@ha addi r8,r8,(_stext - 0b)@l /* current runtime base addr */ bl prom_init -#endif /* CONFIG_PPC_OF_BOOT_TRAMPOLINE */ - - /* We never return. We also hit that trap if trying to boot - * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */ trap +#endif /* * Check for BootX signature when supporting PowerMac and branch to @@ -475,11 +472,12 @@ SystemCall: . = 0x1000 InstructionTLBMiss: /* - * r0: scratch + * r0: stored ctr * r1: linux style pte ( later becomes ppc hardware pte ) * r2: ptr to linux-style pte * r3: scratch */ + mfctr r0 /* Get PTE (linux-style) and check access */ mfspr r3,SPRN_IMISS lis r1,PAGE_OFFSET@h /* check if kernel address */ @@ -498,27 +496,28 @@ InstructionTLBMiss: rlwinm. r2,r2,0,0,19 /* extract address of pte page */ beq- InstructionAddressInvalid /* return if no mapping */ rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ - lwz r0,0(r2) /* get linux-style pte */ - andc. r1,r1,r0 /* check access & ~permission */ + lwz r3,0(r2) /* get linux-style pte */ + andc. r1,r1,r3 /* check access & ~permission */ bne- InstructionAddressInvalid /* return if access not permitted */ - ori r0,r0,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */ + ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */ /* * NOTE! We are assuming this is not an SMP system, otherwise * we would need to update the pte atomically with lwarx/stwcx. */ - stw r0,0(r2) /* update PTE (accessed bit) */ + stw r3,0(r2) /* update PTE (accessed bit) */ /* Convert linux-style PTE to low word of PPC-style PTE */ - rlwinm r1,r0,32-10,31,31 /* _PAGE_RW -> PP lsb */ - rlwinm r2,r0,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */ + rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */ + rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */ and r1,r1,r2 /* writable if _RW and _DIRTY */ - rlwimi r0,r0,32-1,30,30 /* _PAGE_USER -> PP msb */ - rlwimi r0,r0,32-1,31,31 /* _PAGE_USER -> PP lsb */ + rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ + rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ ori r1,r1,0xe04 /* clear out reserved bits */ - andc r1,r0,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ + andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ BEGIN_FTR_SECTION rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) mtspr SPRN_RPA,r1 + mfspr r3,SPRN_IMISS tlbli r3 mfspr r3,SPRN_SRR1 /* Need to restore CR0 */ mtcrf 0x80,r3 @@ -529,6 +528,7 @@ InstructionAddressInvalid: addis r1,r1,0x2000 mtspr SPRN_DSISR,r1 /* (shouldn't be needed) */ + mtctr r0 /* Restore CTR */ andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */ or r2,r2,r1 mtspr SPRN_SRR1,r2 @@ -549,11 +549,12 @@ InstructionAddressInvalid: . = 0x1100 DataLoadTLBMiss: /* - * r0: scratch + * r0: stored ctr * r1: linux style pte ( later becomes ppc hardware pte ) * r2: ptr to linux-style pte * r3: scratch */ + mfctr r0 /* Get PTE (linux-style) and check access */ mfspr r3,SPRN_DMISS lis r1,PAGE_OFFSET@h /* check if kernel address */ @@ -572,48 +573,38 @@ DataLoadTLBMiss: rlwinm. r2,r2,0,0,19 /* extract address of pte page */ beq- DataAddressInvalid /* return if no mapping */ rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ - lwz r0,0(r2) /* get linux-style pte */ - andc. r1,r1,r0 /* check access & ~permission */ + lwz r3,0(r2) /* get linux-style pte */ + andc. r1,r1,r3 /* check access & ~permission */ bne- DataAddressInvalid /* return if access not permitted */ - ori r0,r0,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */ + ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */ /* * NOTE! We are assuming this is not an SMP system, otherwise * we would need to update the pte atomically with lwarx/stwcx. */ - stw r0,0(r2) /* update PTE (accessed bit) */ + stw r3,0(r2) /* update PTE (accessed bit) */ /* Convert linux-style PTE to low word of PPC-style PTE */ - rlwinm r1,r0,32-10,31,31 /* _PAGE_RW -> PP lsb */ - rlwinm r2,r0,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */ + rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */ + rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */ and r1,r1,r2 /* writable if _RW and _DIRTY */ - rlwimi r0,r0,32-1,30,30 /* _PAGE_USER -> PP msb */ - rlwimi r0,r0,32-1,31,31 /* _PAGE_USER -> PP lsb */ + rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ + rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ ori r1,r1,0xe04 /* clear out reserved bits */ - andc r1,r0,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ + andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ BEGIN_FTR_SECTION rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) mtspr SPRN_RPA,r1 - mfspr r2,SPRN_SRR1 /* Need to restore CR0 */ - mtcrf 0x80,r2 -BEGIN_MMU_FTR_SECTION - li r0,1 - mfspr r1,SPRN_SPRG4 - rlwinm r2,r3,20,27,31 /* Get Address bits 15:19 */ - slw r0,r0,r2 - xor r1,r0,r1 - srw r0,r1,r2 - mtspr SPRN_SPRG4,r1 - mfspr r2,SPRN_SRR1 - rlwimi r2,r0,31-14,14,14 - mtspr SPRN_SRR1,r2 -END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU) + mfspr r3,SPRN_DMISS tlbld r3 + mfspr r3,SPRN_SRR1 /* Need to restore CR0 */ + mtcrf 0x80,r3 rfi DataAddressInvalid: mfspr r3,SPRN_SRR1 rlwinm r1,r3,9,6,6 /* Get load/store bit */ addis r1,r1,0x2000 mtspr SPRN_DSISR,r1 + mtctr r0 /* Restore CTR */ andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */ mtspr SPRN_SRR1,r2 mfspr r1,SPRN_DMISS /* Get failing address */ @@ -633,11 +624,12 @@ DataAddressInvalid: . = 0x1200 DataStoreTLBMiss: /* - * r0: scratch + * r0: stored ctr * r1: linux style pte ( later becomes ppc hardware pte ) * r2: ptr to linux-style pte * r3: scratch */ + mfctr r0 /* Get PTE (linux-style) and check access */ mfspr r3,SPRN_DMISS lis r1,PAGE_OFFSET@h /* check if kernel address */ @@ -656,38 +648,27 @@ DataStoreTLBMiss: rlwinm. r2,r2,0,0,19 /* extract address of pte page */ beq- DataAddressInvalid /* return if no mapping */ rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ - lwz r0,0(r2) /* get linux-style pte */ - andc. r1,r1,r0 /* check access & ~permission */ + lwz r3,0(r2) /* get linux-style pte */ + andc. r1,r1,r3 /* check access & ~permission */ bne- DataAddressInvalid /* return if access not permitted */ - ori r0,r0,_PAGE_ACCESSED|_PAGE_DIRTY + ori r3,r3,_PAGE_ACCESSED|_PAGE_DIRTY /* * NOTE! We are assuming this is not an SMP system, otherwise * we would need to update the pte atomically with lwarx/stwcx. */ - stw r0,0(r2) /* update PTE (accessed/dirty bits) */ + stw r3,0(r2) /* update PTE (accessed/dirty bits) */ /* Convert linux-style PTE to low word of PPC-style PTE */ - rlwimi r0,r0,32-1,30,30 /* _PAGE_USER -> PP msb */ + rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ li r1,0xe05 /* clear out reserved bits & PP lsb */ - andc r1,r0,r1 /* PP = user? 2: 0 */ + andc r1,r3,r1 /* PP = user? 2: 0 */ BEGIN_FTR_SECTION rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) mtspr SPRN_RPA,r1 - mfspr r2,SPRN_SRR1 /* Need to restore CR0 */ - mtcrf 0x80,r2 -BEGIN_MMU_FTR_SECTION - li r0,1 - mfspr r1,SPRN_SPRG4 - rlwinm r2,r3,20,27,31 /* Get Address bits 15:19 */ - slw r0,r0,r2 - xor r1,r0,r1 - srw r0,r1,r2 - mtspr SPRN_SPRG4,r1 - mfspr r2,SPRN_SRR1 - rlwimi r2,r0,31-14,14,14 - mtspr SPRN_SRR1,r2 -END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU) + mfspr r3,SPRN_DMISS tlbld r3 + mfspr r3,SPRN_SRR1 /* Need to restore CR0 */ + mtcrf 0x80,r3 rfi #ifndef CONFIG_ALTIVEC diff --git a/trunk/arch/powerpc/kernel/head_64.S b/trunk/arch/powerpc/kernel/head_64.S index 50ef505b8fb6..ebaedafc8e67 100644 --- a/trunk/arch/powerpc/kernel/head_64.S +++ b/trunk/arch/powerpc/kernel/head_64.S @@ -1360,7 +1360,6 @@ _GLOBAL(__start_initialization_multiplatform) b .__after_prom_start _INIT_STATIC(__boot_from_prom) -#ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE /* Save parameters */ mr r31,r3 mr r30,r4 @@ -1391,10 +1390,7 @@ _INIT_STATIC(__boot_from_prom) /* Do all of the interaction with OF client interface */ mr r8,r26 bl .prom_init -#endif /* #CONFIG_PPC_OF_BOOT_TRAMPOLINE */ - - /* We never return. We also hit that trap if trying to boot - * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */ + /* We never return */ trap _STATIC(__after_prom_start) diff --git a/trunk/arch/powerpc/kernel/head_booke.h b/trunk/arch/powerpc/kernel/head_booke.h index 95f39f1e68d4..fce2df988504 100644 --- a/trunk/arch/powerpc/kernel/head_booke.h +++ b/trunk/arch/powerpc/kernel/head_booke.h @@ -10,15 +10,6 @@ mtspr SPRN_IVOR##vector_number,r26; \ sync -#if (THREAD_SHIFT < 15) -#define ALLOC_STACK_FRAME(reg, val) \ - addi reg,reg,val -#else -#define ALLOC_STACK_FRAME(reg, val) \ - addis reg,reg,val@ha; \ - addi reg,reg,val@l -#endif - #define NORMAL_EXCEPTION_PROLOG \ mtspr SPRN_SPRG0,r10; /* save two registers to work with */\ mtspr SPRN_SPRG1,r11; \ @@ -29,7 +20,7 @@ beq 1f; \ mfspr r1,SPRN_SPRG3; /* if from user, start at top of */\ lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\ - ALLOC_STACK_FRAME(r1, THREAD_SIZE); \ + addi r1,r1,THREAD_SIZE; \ 1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\ mr r11,r1; \ stw r10,_CCR(r11); /* save various registers */\ @@ -79,10 +70,10 @@ /* only on e500mc/e200 */ #define DEBUG_STACK_BASE dbgirq_ctx -#ifdef CONFIG_E200 -#define DEBUG_SPRG SPRN_SPRG6W -#else +#ifdef CONFIG_PPC_E500MC #define DEBUG_SPRG SPRN_SPRG9 +#else +#define DEBUG_SPRG SPRN_SPRG6W #endif #define EXC_LVL_FRAME_OVERHEAD (THREAD_SIZE - INT_FRAME_SIZE - EXC_LVL_SIZE) @@ -288,7 +279,7 @@ lwz r11,GPR11(r8); \ mfspr r8,DEBUG_SPRG; \ \ - PPC_RFDI; \ + RFDI; \ b .; \ \ /* continue normal handling for a debug exception... */ \ diff --git a/trunk/arch/powerpc/kernel/head_fsl_booke.S b/trunk/arch/powerpc/kernel/head_fsl_booke.S index 4c22620d009b..36ffb3504a4f 100644 --- a/trunk/arch/powerpc/kernel/head_fsl_booke.S +++ b/trunk/arch/powerpc/kernel/head_fsl_booke.S @@ -103,15 +103,10 @@ invstr: mflr r6 /* Make it accessible */ or r7,r7,r4 mtspr SPRN_MAS6,r7 tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ +#ifndef CONFIG_E200 mfspr r7,SPRN_MAS1 andis. r7,r7,MAS1_VALID@h bne match_TLB - - mfspr r7,SPRN_MMUCFG - rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ - cmpwi r7,3 - bne match_TLB /* skip if NPIDS != 3 */ - mfspr r7,SPRN_PID1 slwi r7,r7,16 or r7,r7,r4 @@ -125,7 +120,7 @@ invstr: mflr r6 /* Make it accessible */ or r7,r7,r4 mtspr SPRN_MAS6,r7 tlbsx 0,r6 /* Fall through, we had to match */ - +#endif match_TLB: mfspr r7,SPRN_MAS0 rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */ @@ -173,7 +168,7 @@ skpinv: addi r6,r6,1 /* Increment */ /* grab and fixup the RPN */ mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */ - rlwinm r6,r6,25,27,31 + rlwinm r6,r6,25,27,30 li r8,-1 addi r6,r6,10 slw r6,r8,r6 /* convert to mask */ @@ -199,7 +194,7 @@ skpinv: addi r6,r6,1 /* Increment */ xori r6,r4,1 /* Setup TMP mapping in the other Address space */ slwi r6,r6,12 oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h - ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l + ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l mtspr SPRN_MAS1,r6 mfspr r6,SPRN_MAS2 li r7,0 /* temp EPN = 0 */ @@ -220,19 +215,14 @@ skpinv: addi r6,r6,1 /* Increment */ /* 4. Clear out PIDs & Search info */ li r6,0 - mtspr SPRN_MAS6,r6 mtspr SPRN_PID0,r6 - - mfspr r7,SPRN_MMUCFG - rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ - cmpwi r7,3 - bne 2f /* skip if NPIDS != 3 */ - +#ifndef CONFIG_E200 mtspr SPRN_PID1,r6 mtspr SPRN_PID2,r6 +#endif + mtspr SPRN_MAS6,r6 /* 5. Invalidate mapping we started in */ -2: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ mtspr SPRN_MAS0,r7 @@ -257,10 +247,10 @@ skpinv: addi r6,r6,1 /* Increment */ lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ mtspr SPRN_MAS0,r6 lis r6,(MAS1_VALID|MAS1_IPROT)@h - ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l + ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l mtspr SPRN_MAS1,r6 - lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h - ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l + lis r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@h + ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@l mtspr SPRN_MAS2,r6 mtspr SPRN_MAS3,r8 tlbwe @@ -308,14 +298,26 @@ skpinv: addi r6,r6,1 /* Increment */ SET_IVOR(12, WatchdogTimer); SET_IVOR(13, DataTLBError); SET_IVOR(14, InstructionTLBError); + SET_IVOR(15, DebugDebug); +#if defined(CONFIG_E500) && !defined(CONFIG_PPC_E500MC) SET_IVOR(15, DebugCrit); +#endif + SET_IVOR(32, SPEUnavailable); + SET_IVOR(33, SPEFloatingPointData); + SET_IVOR(34, SPEFloatingPointRound); +#ifndef CONFIG_E200 + SET_IVOR(35, PerformanceMonitor); +#endif +#ifdef CONFIG_PPC_E500MC + SET_IVOR(36, Doorbell); +#endif /* Establish the interrupt vector base */ lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ mtspr SPRN_IVPR,r4 /* Setup the defaults for TLB entries */ - li r2,(MAS4_TSIZED(BOOK3E_PAGESZ_4K))@l + li r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l #ifdef CONFIG_E200 oris r2,r2,MAS4_TLBSELD(1)@h #endif @@ -327,6 +329,12 @@ skpinv: addi r6,r6,1 /* Increment */ oris r2,r2,HID0_DOZE@h mtspr SPRN_HID0, r2 #endif +#ifdef CONFIG_E200 + /* enable dedicated debug exception handling resources (Debug APU) */ + mfspr r2,SPRN_HID0 + ori r2,r2,HID0_DAPUEN@l + mtspr SPRN_HID0,r2 +#endif #if !defined(CONFIG_BDI_SWITCH) /* @@ -698,13 +706,15 @@ interrupt_base: /* Performance Monitor */ EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD) - EXCEPTION(0x2070, Doorbell, doorbell_exception, EXC_XFER_STD) - - CRITICAL_EXCEPTION(0x2080, CriticalDoorbell, unknown_exception) +#ifdef CONFIG_PPC_E500MC + EXCEPTION(0x2070, Doorbell, unknown_exception, EXC_XFER_STD) +#endif /* Debug Interrupt */ DEBUG_DEBUG_EXCEPTION +#if defined(CONFIG_E500) && !defined(CONFIG_PPC_E500MC) DEBUG_CRIT_EXCEPTION +#endif /* * Local functions @@ -887,47 +897,6 @@ KernelSPE: * Global functions */ -/* Adjust or setup IVORs for e200 */ -_GLOBAL(__setup_e200_ivors) - li r3,DebugDebug@l - mtspr SPRN_IVOR15,r3 - li r3,SPEUnavailable@l - mtspr SPRN_IVOR32,r3 - li r3,SPEFloatingPointData@l - mtspr SPRN_IVOR33,r3 - li r3,SPEFloatingPointRound@l - mtspr SPRN_IVOR34,r3 - sync - blr - -/* Adjust or setup IVORs for e500v1/v2 */ -_GLOBAL(__setup_e500_ivors) - li r3,DebugCrit@l - mtspr SPRN_IVOR15,r3 - li r3,SPEUnavailable@l - mtspr SPRN_IVOR32,r3 - li r3,SPEFloatingPointData@l - mtspr SPRN_IVOR33,r3 - li r3,SPEFloatingPointRound@l - mtspr SPRN_IVOR34,r3 - li r3,PerformanceMonitor@l - mtspr SPRN_IVOR35,r3 - sync - blr - -/* Adjust or setup IVORs for e500mc */ -_GLOBAL(__setup_e500mc_ivors) - li r3,DebugDebug@l - mtspr SPRN_IVOR15,r3 - li r3,PerformanceMonitor@l - mtspr SPRN_IVOR35,r3 - li r3,Doorbell@l - mtspr SPRN_IVOR36,r3 - li r3,CriticalDoorbell@l - mtspr SPRN_IVOR37,r3 - sync - blr - /* * extern void loadcam_entry(unsigned int index) * @@ -1120,7 +1089,7 @@ __secondary_start: mtspr SPRN_SPRG3,r4 /* Setup the defaults for TLB entries */ - li r4,(MAS4_TSIZED(BOOK3E_PAGESZ_4K))@l + li r4,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l mtspr SPRN_MAS4,r4 /* Jump to start_secondary */ diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 5576147e57b6..1b55ffdf0026 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -171,7 +171,7 @@ int show_interrupts(struct seq_file *p, void *v) { int i = *(loff_t *)v, j; struct irqaction *action; - struct irq_desc *desc; + irq_desc_t *desc; unsigned long flags; if (i == 0) { @@ -1038,7 +1038,7 @@ arch_initcall(irq_late_init); static int virq_debug_show(struct seq_file *m, void *private) { unsigned long flags; - struct irq_desc *desc; + irq_desc_t *desc; const char *p; char none[] = "none"; int i; diff --git a/trunk/arch/powerpc/kernel/module_64.c b/trunk/arch/powerpc/kernel/module_64.c index 8fbb12508bf3..8992b031a7b6 100644 --- a/trunk/arch/powerpc/kernel/module_64.c +++ b/trunk/arch/powerpc/kernel/module_64.c @@ -329,7 +329,7 @@ static unsigned long stub_for_addr(Elf64_Shdr *sechdrs, restore r2. */ static int restore_r2(u32 *instruction, struct module *me) { - if (*instruction != PPC_INST_NOP) { + if (*instruction != PPC_NOP_INSTR) { printk("%s: Expect noop after relocate, got %08x\n", me->name, *instruction); return 0; diff --git a/trunk/arch/powerpc/kernel/msi.c b/trunk/arch/powerpc/kernel/msi.c index 8bbc12d20f5c..3bb7d3dd28be 100644 --- a/trunk/arch/powerpc/kernel/msi.c +++ b/trunk/arch/powerpc/kernel/msi.c @@ -9,7 +9,6 @@ #include #include -#include #include @@ -20,10 +19,6 @@ int arch_msi_check_device(struct pci_dev* dev, int nvec, int type) return -ENOSYS; } - /* PowerPC doesn't support multiple MSI yet */ - if (type == PCI_CAP_ID_MSI && nvec > 1) - return 1; - if (ppc_md.msi_check_device) { pr_debug("msi: Using platform check routine.\n"); return ppc_md.msi_check_device(dev, nvec, type); diff --git a/trunk/arch/powerpc/kernel/pci-common.c b/trunk/arch/powerpc/kernel/pci-common.c index 9c69e7e145c5..0f4181272311 100644 --- a/trunk/arch/powerpc/kernel/pci-common.c +++ b/trunk/arch/powerpc/kernel/pci-common.c @@ -38,7 +38,6 @@ #include static DEFINE_SPINLOCK(hose_spinlock); -LIST_HEAD(hose_list); /* XXX kill that some day ... */ static int global_phb_number; /* Global phb counter */ @@ -50,7 +49,7 @@ resource_size_t isa_mem_base; unsigned int ppc_pci_flags = 0; -static struct dma_mapping_ops *pci_dma_ops = &dma_direct_ops; +static struct dma_mapping_ops *pci_dma_ops; void set_pci_dma_ops(struct dma_mapping_ops *dma_ops) { @@ -114,24 +113,19 @@ void pcibios_free_controller(struct pci_controller *phb) kfree(phb); } -static resource_size_t pcibios_io_size(const struct pci_controller *hose) -{ -#ifdef CONFIG_PPC64 - return hose->pci_io_size; -#else - return hose->io_resource.end - hose->io_resource.start + 1; -#endif -} - int pcibios_vaddr_is_ioport(void __iomem *address) { int ret = 0; struct pci_controller *hose; - resource_size_t size; + unsigned long size; spin_lock(&hose_spinlock); list_for_each_entry(hose, &hose_list, list_node) { - size = pcibios_io_size(hose); +#ifdef CONFIG_PPC64 + size = hose->pci_io_size; +#else + size = hose->io_resource.end - hose->io_resource.start + 1; +#endif if (address >= hose->io_base_virt && address < (hose->io_base_virt + size)) { ret = 1; @@ -142,29 +136,6 @@ int pcibios_vaddr_is_ioport(void __iomem *address) return ret; } -unsigned long pci_address_to_pio(phys_addr_t address) -{ - struct pci_controller *hose; - resource_size_t size; - unsigned long ret = ~0; - - spin_lock(&hose_spinlock); - list_for_each_entry(hose, &hose_list, list_node) { - size = pcibios_io_size(hose); - if (address >= hose->io_base_phys && - address < (hose->io_base_phys + size)) { - unsigned long base = - (unsigned long)hose->io_base_virt - _IO_BASE; - ret = base + (address - hose->io_base_phys); - break; - } - } - spin_unlock(&hose_spinlock); - - return ret; -} -EXPORT_SYMBOL_GPL(pci_address_to_pio); - /* * Return the domain number for this bus. */ @@ -1482,7 +1453,7 @@ void __init pcibios_resource_survey(void) * we proceed to assigning things that were left unassigned */ if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { - pr_debug("PCI: Assigning unassigned resources...\n"); + pr_debug("PCI: Assigning unassigned resouces...\n"); pci_assign_unassigned_resources(); } diff --git a/trunk/arch/powerpc/kernel/pci_32.c b/trunk/arch/powerpc/kernel/pci_32.c index d473634e39e3..132cd80afa21 100644 --- a/trunk/arch/powerpc/kernel/pci_32.c +++ b/trunk/arch/powerpc/kernel/pci_32.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -44,6 +43,8 @@ static u8* pci_to_OF_bus_map; */ static int pci_assign_all_buses; +LIST_HEAD(hose_list); + static int pci_bus_count; /* This will remain NULL for now, until isa-bridge.c is made common @@ -218,23 +219,16 @@ scan_OF_pci_childs(struct device_node *parent, pci_OF_scan_iterator filter, void static struct device_node *scan_OF_for_pci_dev(struct device_node *parent, unsigned int devfn) { - struct device_node *np, *cnp; + struct device_node *np; const u32 *reg; unsigned int psize; for_each_child_of_node(parent, np) { reg = of_get_property(np, "reg", &psize); - if (reg && psize >= 4 && ((reg[0] >> 8) & 0xff) == devfn) + if (reg == NULL || psize < 4) + continue; + if (((reg[0] >> 8) & 0xff) == devfn) return np; - - /* Note: some OFs create a parent node "multifunc-device" as - * a fake root for all functions of a multi-function device, - * we go down them as well. */ - if (!strcmp(np->name, "multifunc-device")) { - cnp = scan_OF_for_pci_dev(np, devfn); - if (cnp) - return cnp; - } } return NULL; } @@ -497,6 +491,24 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) return result; } +unsigned long pci_address_to_pio(phys_addr_t address) +{ + struct pci_controller *hose, *tmp; + + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { + unsigned int size = hose->io_resource.end - + hose->io_resource.start + 1; + if (address >= hose->io_base_phys && + address < (hose->io_base_phys + size)) { + unsigned long base = + (unsigned long)hose->io_base_virt - _IO_BASE; + return base + (address - hose->io_base_phys); + } + } + return (unsigned int)-1; +} +EXPORT_SYMBOL(pci_address_to_pio); + /* * Null PCI config access functions, for the case when we can't * find a hose. diff --git a/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index be574fc0d92f..ea8eda8c87cf 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -43,6 +43,8 @@ unsigned long pci_probe_only = 1; unsigned long pci_io_base = ISA_IO_BASE; EXPORT_SYMBOL(pci_io_base); +LIST_HEAD(hose_list); + static void fixup_broken_pcnet32(struct pci_dev* dev) { if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { @@ -522,6 +524,23 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) } EXPORT_SYMBOL_GPL(pcibios_map_io_space); +unsigned long pci_address_to_pio(phys_addr_t address) +{ + struct pci_controller *hose, *tmp; + + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { + if (address >= hose->io_base_phys && + address < (hose->io_base_phys + hose->pci_io_size)) { + unsigned long base = + (unsigned long)hose->io_base_virt - _IO_BASE; + return base + (address - hose->io_base_phys); + } + } + return (unsigned int)-1; +} +EXPORT_SYMBOL_GPL(pci_address_to_pio); + + #define IOBASE_BRIDGE_NUMBER 0 #define IOBASE_MEMORY 1 #define IOBASE_IO 2 diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 7b44a33f03c2..fb7049c054c0 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -33,10 +33,7 @@ #include #include #include -#include #include -#include -#include #include #include @@ -598,7 +595,7 @@ void prepare_to_copy(struct task_struct *tsk) /* * Copy a thread.. */ -int copy_thread(unsigned long clone_flags, unsigned long usp, +int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { @@ -1011,14 +1008,6 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) unsigned long sp, ip, lr, newsp; int count = 0; int firstframe = 1; -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - int curr_frame = current->curr_ret_stack; - extern void return_to_handler(void); - unsigned long addr = (unsigned long)return_to_handler; -#ifdef CONFIG_PPC64 - addr = *(unsigned long*)addr; -#endif -#endif sp = (unsigned long) stack; if (tsk == NULL) @@ -1041,13 +1030,6 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) ip = stack[STACK_FRAME_LR_SAVE]; if (!firstframe || ip != lr) { printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip); -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - if (ip == addr && curr_frame >= 0) { - printk(" (%pS)", - (void *)current->ret_stack[curr_frame].ret); - curr_frame--; - } -#endif if (firstframe) printk(" (unreliable)"); printk("\n"); @@ -1140,43 +1122,3 @@ void thread_info_cache_init(void) } #endif /* THREAD_SHIFT < PAGE_SHIFT */ - -unsigned long arch_align_stack(unsigned long sp) -{ - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) - sp -= get_random_int() & ~PAGE_MASK; - return sp & ~0xf; -} - -static inline unsigned long brk_rnd(void) -{ - unsigned long rnd = 0; - - /* 8MB for 32bit, 1GB for 64bit */ - if (is_32bit_task()) - rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT))); - else - rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT))); - - return rnd << PAGE_SHIFT; -} - -unsigned long arch_randomize_brk(struct mm_struct *mm) -{ - unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd()); - - if (ret < mm->brk) - return mm->brk; - - return ret; -} - -unsigned long randomize_et_dyn(unsigned long base) -{ - unsigned long ret = PAGE_ALIGN(base + brk_rnd()); - - if (ret < base) - return base; - - return ret; -} diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c index 5ec6a9e23933..f00f83109ab3 100644 --- a/trunk/arch/powerpc/kernel/prom.c +++ b/trunk/arch/powerpc/kernel/prom.c @@ -1075,6 +1075,11 @@ static void __init early_reserve_mem(void) DBG("reserving: %llx -> %llx\n", base, size); lmb_reserve(base, size); } + +#if 0 + DBG("memory reserved, lmbs :\n"); + lmb_dump_all(); +#endif } #ifdef CONFIG_PHYP_DUMP @@ -1216,7 +1221,6 @@ void __init early_init_devtree(void *params) lmb_enforce_memory_limit(limit); lmb_analyze(); - lmb_dump_all(); DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index 2e026c0407d4..7f1b33d5e30d 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -2283,8 +2283,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, */ prom_init_stdout(); - prom_printf("Preparing to boot %s", RELOC(linux_banner)); - /* * Get default machine type. At this point, we do not differentiate * between pSeries SMP and pSeries LPAR diff --git a/trunk/arch/powerpc/kernel/prom_init_check.sh b/trunk/arch/powerpc/kernel/prom_init_check.sh index 1ac136b128f0..ea3a2ec03ffa 100644 --- a/trunk/arch/powerpc/kernel/prom_init_check.sh +++ b/trunk/arch/powerpc/kernel/prom_init_check.sh @@ -20,7 +20,7 @@ WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush _end enter_prom memcpy memset reloc_offset __secondary_hold __secondary_hold_acknowledge __secondary_hold_spinloop __start strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224 -reloc_got2 kernstart_addr memstart_addr linux_banner" +reloc_got2 kernstart_addr memstart_addr" NM="$1" OBJ="$2" diff --git a/trunk/arch/powerpc/kernel/rtas.c b/trunk/arch/powerpc/kernel/rtas.c index ee4c7609b649..fdfe14c4bdef 100644 --- a/trunk/arch/powerpc/kernel/rtas.c +++ b/trunk/arch/powerpc/kernel/rtas.c @@ -46,7 +46,6 @@ EXPORT_SYMBOL(rtas); struct rtas_suspend_me_data { atomic_t working; /* number of cpus accessing this struct */ - atomic_t done; int token; /* ibm,suspend-me */ int error; struct completion *complete; /* wait on this until working == 0 */ @@ -690,7 +689,7 @@ static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; #ifdef CONFIG_PPC_PSERIES static void rtas_percpu_suspend_me(void *info) { - long rc = H_SUCCESS; + long rc; unsigned long msr_save; int cpu; struct rtas_suspend_me_data *data = @@ -702,8 +701,7 @@ static void rtas_percpu_suspend_me(void *info) msr_save = mfmsr(); mtmsr(msr_save & ~(MSR_EE)); - while (rc == H_SUCCESS && !atomic_read(&data->done)) - rc = plpar_hcall_norets(H_JOIN); + rc = plpar_hcall_norets(H_JOIN); mtmsr(msr_save); @@ -726,9 +724,6 @@ static void rtas_percpu_suspend_me(void *info) smp_processor_id(), rc); data->error = rc; } - - atomic_set(&data->done, 1); - /* This cpu did the suspend or got an error; in either case, * we need to prod all other other cpus out of join state. * Extra prods are harmless. @@ -771,7 +766,6 @@ static int rtas_ibm_suspend_me(struct rtas_args *args) } atomic_set(&data.working, 0); - atomic_set(&data.done, 0); data.token = rtas_token("ibm,suspend-me"); data.error = 0; data.complete = &done; diff --git a/trunk/arch/powerpc/kernel/rtas_flash.c b/trunk/arch/powerpc/kernel/rtas_flash.c index 13011a96a977..149cb112cd1a 100644 --- a/trunk/arch/powerpc/kernel/rtas_flash.c +++ b/trunk/arch/powerpc/kernel/rtas_flash.c @@ -669,6 +669,7 @@ static void remove_flash_pde(struct proc_dir_entry *dp) { if (dp) { kfree(dp->data); + dp->owner = NULL; remove_proc_entry(dp->name, dp->parent); } } diff --git a/trunk/arch/powerpc/kernel/setup-common.c b/trunk/arch/powerpc/kernel/setup-common.c index 9774f9fed96e..705fc4bf3800 100644 --- a/trunk/arch/powerpc/kernel/setup-common.c +++ b/trunk/arch/powerpc/kernel/setup-common.c @@ -35,8 +35,6 @@ #include #include #include -#include -#include #include #include #include @@ -671,37 +669,3 @@ static int powerpc_debugfs_init(void) } arch_initcall(powerpc_debugfs_init); #endif - -static int ppc_dflt_bus_notify(struct notifier_block *nb, - unsigned long action, void *data) -{ - struct device *dev = data; - - /* We are only intereted in device addition */ - if (action != BUS_NOTIFY_ADD_DEVICE) - return 0; - - set_dma_ops(dev, &dma_direct_ops); - - return NOTIFY_DONE; -} - -static struct notifier_block ppc_dflt_plat_bus_notifier = { - .notifier_call = ppc_dflt_bus_notify, - .priority = INT_MAX, -}; - -static struct notifier_block ppc_dflt_of_bus_notifier = { - .notifier_call = ppc_dflt_bus_notify, - .priority = INT_MAX, -}; - -static int __init setup_bus_notifier(void) -{ - bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier); - bus_register_notifier(&of_platform_bus_type, &ppc_dflt_of_bus_notifier); - - return 0; -} - -arch_initcall(setup_bus_notifier); diff --git a/trunk/arch/powerpc/kernel/setup_64.c b/trunk/arch/powerpc/kernel/setup_64.c index c410c606955d..2d34196bba8c 100644 --- a/trunk/arch/powerpc/kernel/setup_64.c +++ b/trunk/arch/powerpc/kernel/setup_64.c @@ -202,6 +202,8 @@ void __init early_setup(unsigned long dt_ptr) /* Fix up paca fields required for the boot cpu */ get_paca()->cpu_start = 1; + get_paca()->stab_real = __pa((u64)&initial_stab); + get_paca()->stab_addr = (u64)&initial_stab; /* Probe the machine type */ probe_machine(); @@ -210,8 +212,20 @@ void __init early_setup(unsigned long dt_ptr) DBG("Found, Initializing memory management...\n"); - /* Initialize the hash table or TLB handling */ - early_init_mmu(); + /* + * Initialize the MMU Hash table and create the linear mapping + * of memory. Has to be done before stab/slb initialization as + * this is currently where the page size encoding is obtained + */ + htab_initialize(); + + /* + * Initialize stab / SLB management except on iSeries + */ + if (cpu_has_feature(CPU_FTR_SLB)) + slb_initialize(); + else if (!firmware_has_feature(FW_FEATURE_ISERIES)) + stab_initialize(get_paca()->stab_real); DBG(" <- early_setup()\n"); } @@ -219,11 +233,22 @@ void __init early_setup(unsigned long dt_ptr) #ifdef CONFIG_SMP void early_setup_secondary(void) { + struct paca_struct *lpaca = get_paca(); + /* Mark interrupts enabled in PACA */ - get_paca()->soft_enabled = 0; + lpaca->soft_enabled = 0; - /* Initialize the hash table or TLB handling */ - early_init_mmu_secondary(); + /* Initialize hash table for that CPU */ + htab_initialize_secondary(); + + /* Initialize STAB/SLB. We use a virtual address as it works + * in real mode on pSeries and we want a virutal address on + * iSeries anyway + */ + if (cpu_has_feature(CPU_FTR_SLB)) + slb_initialize(); + else + stab_initialize(lpaca->stab_addr); } #endif /* CONFIG_SMP */ @@ -553,6 +578,13 @@ void ppc64_boot_msg(unsigned int src, const char *msg) printk("[boot]%04x %s\n", src, msg); } +/* Print a termination message (print only -- does not stop the kernel) */ +void ppc64_terminate_msg(unsigned int src, const char *msg) +{ + ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg); + printk("[terminate]%04x %s\n", src, msg); +} + void cpu_die(void) { if (ppc_md.cpu_die) diff --git a/trunk/arch/powerpc/kernel/signal.c b/trunk/arch/powerpc/kernel/signal.c index 00b5078da9a3..a54405ebd7b0 100644 --- a/trunk/arch/powerpc/kernel/signal.c +++ b/trunk/arch/powerpc/kernel/signal.c @@ -26,12 +26,12 @@ int show_unhandled_signals = 0; * Allocate space for the signal frame */ void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, - size_t frame_size, int is_32) + size_t frame_size) { unsigned long oldsp, newsp; /* Default to using normal stack */ - oldsp = get_clean_sp(regs, is_32); + oldsp = regs->gpr[1]; /* Check for alt stack */ if ((ka->sa.sa_flags & SA_ONSTACK) && diff --git a/trunk/arch/powerpc/kernel/signal.h b/trunk/arch/powerpc/kernel/signal.h index 6c0ddfc0603e..b427bf8e1d8f 100644 --- a/trunk/arch/powerpc/kernel/signal.h +++ b/trunk/arch/powerpc/kernel/signal.h @@ -15,7 +15,7 @@ extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags); extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, - size_t frame_size, int is_32); + size_t frame_size); extern void restore_sigmask(sigset_t *set); extern int handle_signal32(unsigned long sig, struct k_sigaction *ka, @@ -39,12 +39,22 @@ extern unsigned long copy_vsx_from_user(struct task_struct *task, #ifdef CONFIG_PPC64 +static inline int is_32bit_task(void) +{ + return test_thread_flag(TIF_32BIT); +} + extern int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs); #else /* CONFIG_PPC64 */ +static inline int is_32bit_task(void) +{ + return 1; +} + static inline int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs) diff --git a/trunk/arch/powerpc/kernel/signal_32.c b/trunk/arch/powerpc/kernel/signal_32.c index d670429a1608..b13abf305996 100644 --- a/trunk/arch/powerpc/kernel/signal_32.c +++ b/trunk/arch/powerpc/kernel/signal_32.c @@ -836,7 +836,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, /* Set up Signal Frame */ /* Put a Real Time Context onto stack */ - rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf), 1); + rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf)); addr = rt_sf; if (unlikely(rt_sf == NULL)) goto badframe; @@ -1182,7 +1182,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, unsigned long newsp = 0; /* Set up Signal Frame */ - frame = get_sigframe(ka, regs, sizeof(*frame), 1); + frame = get_sigframe(ka, regs, sizeof(*frame)); if (unlikely(frame == NULL)) goto badframe; sc = (struct sigcontext __user *) &frame->sctx; diff --git a/trunk/arch/powerpc/kernel/signal_64.c b/trunk/arch/powerpc/kernel/signal_64.c index 2fe6fc64b614..e132891d3cea 100644 --- a/trunk/arch/powerpc/kernel/signal_64.c +++ b/trunk/arch/powerpc/kernel/signal_64.c @@ -402,7 +402,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, unsigned long newsp = 0; long err = 0; - frame = get_sigframe(ka, regs, sizeof(*frame), 0); + frame = get_sigframe(ka, regs, sizeof(*frame)); if (unlikely(frame == NULL)) goto badframe; diff --git a/trunk/arch/powerpc/kernel/sysfs.c b/trunk/arch/powerpc/kernel/sysfs.c index f41aec85aa49..4a2ee08af6a7 100644 --- a/trunk/arch/powerpc/kernel/sysfs.c +++ b/trunk/arch/powerpc/kernel/sysfs.c @@ -134,23 +134,44 @@ void ppc_enable_pmcs(void) } EXPORT_SYMBOL(ppc_enable_pmcs); +#if defined(CONFIG_6xx) || defined(CONFIG_PPC64) +/* XXX convert to rusty's on_one_cpu */ +static unsigned long run_on_cpu(unsigned long cpu, + unsigned long (*func)(unsigned long), + unsigned long arg) +{ + cpumask_t old_affinity = current->cpus_allowed; + unsigned long ret; + + /* should return -EINVAL to userspace */ + if (set_cpus_allowed(current, cpumask_of_cpu(cpu))) + return 0; + + ret = func(arg); + + set_cpus_allowed(current, old_affinity); + + return ret; +} +#endif + #define SYSFS_PMCSETUP(NAME, ADDRESS) \ -static void read_##NAME(void *val) \ +static unsigned long read_##NAME(unsigned long junk) \ { \ - *(unsigned long *)val = mfspr(ADDRESS); \ + return mfspr(ADDRESS); \ } \ -static void write_##NAME(void *val) \ +static unsigned long write_##NAME(unsigned long val) \ { \ ppc_enable_pmcs(); \ - mtspr(ADDRESS, *(unsigned long *)val); \ + mtspr(ADDRESS, val); \ + return 0; \ } \ static ssize_t show_##NAME(struct sys_device *dev, \ struct sysdev_attribute *attr, \ char *buf) \ { \ struct cpu *cpu = container_of(dev, struct cpu, sysdev); \ - unsigned long val; \ - smp_call_function_single(cpu->sysdev.id, read_##NAME, &val, 1); \ + unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \ return sprintf(buf, "%lx\n", val); \ } \ static ssize_t __used \ @@ -162,7 +183,7 @@ static ssize_t __used \ int ret = sscanf(buf, "%lx", &val); \ if (ret != 1) \ return -EINVAL; \ - smp_call_function_single(cpu->sysdev.id, write_##NAME, &val, 1); \ + run_on_cpu(cpu->sysdev.id, write_##NAME, val); \ return count; \ } diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index 678fbff0d206..5457e9575685 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -52,10 +52,6 @@ #include #endif #include -#include -#ifdef CONFIG_FSL_BOOKE -#include -#endif #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) int (*__debugger)(struct pt_regs *regs); @@ -641,6 +637,29 @@ static void parse_fpe(struct pt_regs *regs) * bits is faster and easier. * */ +#define INST_MFSPR_PVR 0x7c1f42a6 +#define INST_MFSPR_PVR_MASK 0xfc1fffff + +#define INST_DCBA 0x7c0005ec +#define INST_DCBA_MASK 0xfc0007fe + +#define INST_MCRXR 0x7c000400 +#define INST_MCRXR_MASK 0xfc0007fe + +#define INST_STRING 0x7c00042a +#define INST_STRING_MASK 0xfc0007fe +#define INST_STRING_GEN_MASK 0xfc00067e +#define INST_LSWI 0x7c0004aa +#define INST_LSWX 0x7c00042a +#define INST_STSWI 0x7c0005aa +#define INST_STSWX 0x7c00052a + +#define INST_POPCNTB 0x7c0000f4 +#define INST_POPCNTB_MASK 0xfc0007fe + +#define INST_ISEL 0x7c00001e +#define INST_ISEL_MASK 0xfc00003e + static int emulate_string_inst(struct pt_regs *regs, u32 instword) { u8 rT = (instword >> 21) & 0x1f; @@ -651,20 +670,20 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) int pos = 0; /* Early out if we are an invalid form of lswx */ - if ((instword & PPC_INST_STRING_MASK) == PPC_INST_LSWX) + if ((instword & INST_STRING_MASK) == INST_LSWX) if ((rT == rA) || (rT == NB_RB)) return -EINVAL; EA = (rA == 0) ? 0 : regs->gpr[rA]; - switch (instword & PPC_INST_STRING_MASK) { - case PPC_INST_LSWX: - case PPC_INST_STSWX: + switch (instword & INST_STRING_MASK) { + case INST_LSWX: + case INST_STSWX: EA += NB_RB; num_bytes = regs->xer & 0x7f; break; - case PPC_INST_LSWI: - case PPC_INST_STSWI: + case INST_LSWI: + case INST_STSWI: num_bytes = (NB_RB == 0) ? 32 : NB_RB; break; default: @@ -676,9 +695,9 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) u8 val; u32 shift = 8 * (3 - (pos & 0x3)); - switch ((instword & PPC_INST_STRING_MASK)) { - case PPC_INST_LSWX: - case PPC_INST_LSWI: + switch ((instword & INST_STRING_MASK)) { + case INST_LSWX: + case INST_LSWI: if (get_user(val, (u8 __user *)EA)) return -EFAULT; /* first time updating this reg, @@ -687,8 +706,8 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) regs->gpr[rT] = 0; regs->gpr[rT] |= val << shift; break; - case PPC_INST_STSWI: - case PPC_INST_STSWX: + case INST_STSWI: + case INST_STSWX: val = regs->gpr[rT] >> shift; if (put_user(val, (u8 __user *)EA)) return -EFAULT; @@ -756,18 +775,18 @@ static int emulate_instruction(struct pt_regs *regs) return -EFAULT; /* Emulate the mfspr rD, PVR. */ - if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) { + if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) { rd = (instword >> 21) & 0x1f; regs->gpr[rd] = mfspr(SPRN_PVR); return 0; } /* Emulating the dcba insn is just a no-op. */ - if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) + if ((instword & INST_DCBA_MASK) == INST_DCBA) return 0; /* Emulate the mcrxr insn. */ - if ((instword & PPC_INST_MCRXR_MASK) == PPC_INST_MCRXR) { + if ((instword & INST_MCRXR_MASK) == INST_MCRXR) { int shift = (instword >> 21) & 0x1c; unsigned long msk = 0xf0000000UL >> shift; @@ -777,16 +796,16 @@ static int emulate_instruction(struct pt_regs *regs) } /* Emulate load/store string insn. */ - if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) + if ((instword & INST_STRING_GEN_MASK) == INST_STRING) return emulate_string_inst(regs, instword); /* Emulate the popcntb (Population Count Bytes) instruction. */ - if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) { + if ((instword & INST_POPCNTB_MASK) == INST_POPCNTB) { return emulate_popcntb_inst(regs, instword); } /* Emulate isel (Integer Select) instruction */ - if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) { + if ((instword & INST_ISEL_MASK) == INST_ISEL) { return emulate_isel(regs, instword); } @@ -1125,24 +1144,6 @@ void vsx_assist_exception(struct pt_regs *regs) #endif /* CONFIG_VSX */ #ifdef CONFIG_FSL_BOOKE - -void doorbell_exception(struct pt_regs *regs) -{ -#ifdef CONFIG_SMP - int cpu = smp_processor_id(); - int msg; - - if (num_online_cpus() < 2) - return; - - for (msg = 0; msg < 4; msg++) - if (test_and_clear_bit(msg, &dbell_smp_message[cpu])) - smp_message_recv(msg); -#else - printk(KERN_WARNING "Received doorbell on non-smp system\n"); -#endif -} - void CacheLockingException(struct pt_regs *regs, unsigned long address, unsigned long error_code) { diff --git a/trunk/arch/powerpc/kernel/udbg.c b/trunk/arch/powerpc/kernel/udbg.c index fc9af47e2128..7d6c9bb8c77f 100644 --- a/trunk/arch/powerpc/kernel/udbg.c +++ b/trunk/arch/powerpc/kernel/udbg.c @@ -18,7 +18,6 @@ #include void (*udbg_putc)(char c); -void (*udbg_flush)(void); int (*udbg_getc)(void); int (*udbg_getc_poll)(void); @@ -77,9 +76,6 @@ void udbg_puts(const char *s) while ((c = *s++) != '\0') udbg_putc(c); } - - if (udbg_flush) - udbg_flush(); } #if 0 else { @@ -102,9 +98,6 @@ int udbg_write(const char *s, int n) } } - if (udbg_flush) - udbg_flush(); - return n - remain; } diff --git a/trunk/arch/powerpc/kernel/udbg_16550.c b/trunk/arch/powerpc/kernel/udbg_16550.c index 0362a891e54e..7b7da8cfd5e8 100644 --- a/trunk/arch/powerpc/kernel/udbg_16550.c +++ b/trunk/arch/powerpc/kernel/udbg_16550.c @@ -48,21 +48,14 @@ struct NS16550 { static struct NS16550 __iomem *udbg_comport; -static void udbg_550_flush(void) +static void udbg_550_putc(char c) { if (udbg_comport) { while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0) /* wait for idle */; - } -} - -static void udbg_550_putc(char c) -{ - if (udbg_comport) { + out_8(&udbg_comport->thr, c); if (c == '\n') udbg_550_putc('\r'); - udbg_550_flush(); - out_8(&udbg_comport->thr, c); } } @@ -115,7 +108,6 @@ void udbg_init_uart(void __iomem *comport, unsigned int speed, /* Clear & enable FIFOs */ out_8(&udbg_comport->fcr ,0x07); udbg_putc = udbg_550_putc; - udbg_flush = udbg_550_flush; udbg_getc = udbg_550_getc; udbg_getc_poll = udbg_550_getc_poll; } @@ -157,21 +149,14 @@ unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock) } #ifdef CONFIG_PPC_MAPLE -void udbg_maple_real_flush(void) +void udbg_maple_real_putc(char c) { if (udbg_comport) { while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0) /* wait for idle */; - } -} - -void udbg_maple_real_putc(char c) -{ - if (udbg_comport) { + real_writeb(c, &udbg_comport->thr); eieio(); if (c == '\n') udbg_maple_real_putc('\r'); - udbg_maple_real_flush(); - real_writeb(c, &udbg_comport->thr); eieio(); } } @@ -180,28 +165,20 @@ void __init udbg_init_maple_realmode(void) udbg_comport = (struct NS16550 __iomem *)0xf40003f8; udbg_putc = udbg_maple_real_putc; - udbg_flush = udbg_maple_real_flush; udbg_getc = NULL; udbg_getc_poll = NULL; } #endif /* CONFIG_PPC_MAPLE */ #ifdef CONFIG_PPC_PASEMI -void udbg_pas_real_flush(void) +void udbg_pas_real_putc(char c) { if (udbg_comport) { while ((real_205_readb(&udbg_comport->lsr) & LSR_THRE) == 0) /* wait for idle */; - } -} - -void udbg_pas_real_putc(char c) -{ - if (udbg_comport) { + real_205_writeb(c, &udbg_comport->thr); eieio(); if (c == '\n') udbg_pas_real_putc('\r'); - udbg_pas_real_flush(); - real_205_writeb(c, &udbg_comport->thr); eieio(); } } @@ -210,7 +187,6 @@ void udbg_init_pas_realmode(void) udbg_comport = (struct NS16550 __iomem *)0xfcff03f8UL; udbg_putc = udbg_pas_real_putc; - udbg_flush = udbg_pas_real_flush; udbg_getc = NULL; udbg_getc_poll = NULL; } @@ -219,21 +195,14 @@ void udbg_init_pas_realmode(void) #ifdef CONFIG_PPC_EARLY_DEBUG_44x #include -static int udbg_44x_as1_flush(void) +static void udbg_44x_as1_putc(char c) { if (udbg_comport) { while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0) /* wait for idle */; - } -} - -static void udbg_44x_as1_putc(char c) -{ - if (udbg_comport) { + as1_writeb(c, &udbg_comport->thr); eieio(); if (c == '\n') udbg_44x_as1_putc('\r'); - udbg_44x_as1_flush(); - as1_writeb(c, &udbg_comport->thr); eieio(); } } @@ -253,27 +222,19 @@ void __init udbg_init_44x_as1(void) (struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR; udbg_putc = udbg_44x_as1_putc; - udbg_flush = udbg_44x_as1_flush; udbg_getc = udbg_44x_as1_getc; } #endif /* CONFIG_PPC_EARLY_DEBUG_44x */ #ifdef CONFIG_PPC_EARLY_DEBUG_40x -static void udbg_40x_real_flush(void) +static void udbg_40x_real_putc(char c) { if (udbg_comport) { while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0) /* wait for idle */; - } -} - -static void udbg_40x_real_putc(char c) -{ - if (udbg_comport) { + real_writeb(c, &udbg_comport->thr); eieio(); if (c == '\n') udbg_40x_real_putc('\r'); - udbg_40x_real_flush(); - real_writeb(c, &udbg_comport->thr); eieio(); } } @@ -293,7 +254,6 @@ void __init udbg_init_40x_realmode(void) CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR; udbg_putc = udbg_40x_real_putc; - udbg_flush = udbg_40x_real_flush; udbg_getc = udbg_40x_real_getc; udbg_getc_poll = NULL; } diff --git a/trunk/arch/powerpc/kernel/vio.c b/trunk/arch/powerpc/kernel/vio.c index 819e59f6f7c7..d3694498f3af 100644 --- a/trunk/arch/powerpc/kernel/vio.c +++ b/trunk/arch/powerpc/kernel/vio.c @@ -482,7 +482,7 @@ static void vio_cmo_balance(struct work_struct *work) cmo->excess.size = cmo->entitled - cmo->reserve.size; cmo->excess.free = cmo->excess.size - need; - cancel_delayed_work(to_delayed_work(work)); + cancel_delayed_work(container_of(work, struct delayed_work, work)); spin_unlock_irqrestore(&vio_cmo.lock, flags); } diff --git a/trunk/arch/powerpc/kernel/vmlinux.lds.S b/trunk/arch/powerpc/kernel/vmlinux.lds.S index b9ef1644a722..67f07f453385 100644 --- a/trunk/arch/powerpc/kernel/vmlinux.lds.S +++ b/trunk/arch/powerpc/kernel/vmlinux.lds.S @@ -58,7 +58,6 @@ SECTIONS SCHED_TEXT LOCK_TEXT KPROBES_TEXT - IRQENTRY_TEXT #ifdef CONFIG_PPC32 *(.got1) diff --git a/trunk/arch/powerpc/lib/dma-noncoherent.c b/trunk/arch/powerpc/lib/dma-noncoherent.c index 005a28d380af..b7dc4c19f582 100644 --- a/trunk/arch/powerpc/lib/dma-noncoherent.c +++ b/trunk/arch/powerpc/lib/dma-noncoherent.c @@ -29,10 +29,120 @@ #include #include #include -#include #include +/* + * This address range defaults to a value that is safe for all + * platforms which currently set CONFIG_NOT_COHERENT_CACHE. It + * can be further configured for specific applications under + * the "Advanced Setup" menu. -Matt + */ +#define CONSISTENT_BASE (CONFIG_CONSISTENT_START) +#define CONSISTENT_END (CONFIG_CONSISTENT_START + CONFIG_CONSISTENT_SIZE) +#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT) + +/* + * This is the page table (2MB) covering uncached, DMA consistent allocations + */ +static pte_t *consistent_pte; +static DEFINE_SPINLOCK(consistent_lock); + +/* + * VM region handling support. + * + * This should become something generic, handling VM region allocations for + * vmalloc and similar (ioremap, module space, etc). + * + * I envisage vmalloc()'s supporting vm_struct becoming: + * + * struct vm_struct { + * struct vm_region region; + * unsigned long flags; + * struct page **pages; + * unsigned int nr_pages; + * unsigned long phys_addr; + * }; + * + * get_vm_area() would then call vm_region_alloc with an appropriate + * struct vm_region head (eg): + * + * struct vm_region vmalloc_head = { + * .vm_list = LIST_HEAD_INIT(vmalloc_head.vm_list), + * .vm_start = VMALLOC_START, + * .vm_end = VMALLOC_END, + * }; + * + * However, vmalloc_head.vm_start is variable (typically, it is dependent on + * the amount of RAM found at boot time.) I would imagine that get_vm_area() + * would have to initialise this each time prior to calling vm_region_alloc(). + */ +struct ppc_vm_region { + struct list_head vm_list; + unsigned long vm_start; + unsigned long vm_end; +}; + +static struct ppc_vm_region consistent_head = { + .vm_list = LIST_HEAD_INIT(consistent_head.vm_list), + .vm_start = CONSISTENT_BASE, + .vm_end = CONSISTENT_END, +}; + +static struct ppc_vm_region * +ppc_vm_region_alloc(struct ppc_vm_region *head, size_t size, gfp_t gfp) +{ + unsigned long addr = head->vm_start, end = head->vm_end - size; + unsigned long flags; + struct ppc_vm_region *c, *new; + + new = kmalloc(sizeof(struct ppc_vm_region), gfp); + if (!new) + goto out; + + spin_lock_irqsave(&consistent_lock, flags); + + list_for_each_entry(c, &head->vm_list, vm_list) { + if ((addr + size) < addr) + goto nospc; + if ((addr + size) <= c->vm_start) + goto found; + addr = c->vm_end; + if (addr > end) + goto nospc; + } + + found: + /* + * Insert this entry _before_ the one we found. + */ + list_add_tail(&new->vm_list, &c->vm_list); + new->vm_start = addr; + new->vm_end = addr + size; + + spin_unlock_irqrestore(&consistent_lock, flags); + return new; + + nospc: + spin_unlock_irqrestore(&consistent_lock, flags); + kfree(new); + out: + return NULL; +} + +static struct ppc_vm_region *ppc_vm_region_find(struct ppc_vm_region *head, unsigned long addr) +{ + struct ppc_vm_region *c; + + list_for_each_entry(c, &head->vm_list, vm_list) { + if (c->vm_start == addr) + goto out; + } + c = NULL; + out: + return c; +} + /* * Allocate DMA-coherent memory space and return both the kernel remapped * virtual and bus address for that space. @@ -41,21 +151,21 @@ void * __dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp) { struct page *page; + struct ppc_vm_region *c; unsigned long order; - int i; - unsigned int nr_pages = PAGE_ALIGN(size)>>PAGE_SHIFT; - unsigned int array_size = nr_pages * sizeof(struct page *); - struct page **pages; - struct page *end; u64 mask = 0x00ffffff, limit; /* ISA default */ - struct vm_struct *area; - BUG_ON(!mem_init_done); + if (!consistent_pte) { + printk(KERN_ERR "%s: not initialised\n", __func__); + dump_stack(); + return NULL; + } + size = PAGE_ALIGN(size); limit = (mask + 1) & ~mask; - if (limit && size >= limit) { - printk(KERN_WARNING "coherent allocation too big (requested " - "%#x mask %#Lx)\n", size, mask); + if ((limit && size >= limit) || size >= (CONSISTENT_END - CONSISTENT_BASE)) { + printk(KERN_WARNING "coherent allocation too big (requested %#x mask %#Lx)\n", + size, mask); return NULL; } @@ -68,8 +178,6 @@ __dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp) if (!page) goto no_page; - end = page + (1 << order); - /* * Invalidate any data that might be lurking in the * kernel direct-mapped region for device DMA. @@ -80,59 +188,48 @@ __dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp) flush_dcache_range(kaddr, kaddr + size); } - split_page(page, order); - /* - * Set the "dma handle" + * Allocate a virtual address in the consistent mapping region. */ - *handle = page_to_phys(page); - - area = get_vm_area_caller(size, VM_IOREMAP, - __builtin_return_address(1)); - if (!area) - goto out_free_pages; - - if (array_size > PAGE_SIZE) { - pages = vmalloc(array_size); - area->flags |= VM_VPAGES; - } else { - pages = kmalloc(array_size, GFP_KERNEL); - } - if (!pages) - goto out_free_area; + c = ppc_vm_region_alloc(&consistent_head, size, + gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); + if (c) { + unsigned long vaddr = c->vm_start; + pte_t *pte = consistent_pte + CONSISTENT_OFFSET(vaddr); + struct page *end = page + (1 << order); - area->pages = pages; - area->nr_pages = nr_pages; + split_page(page, order); - for (i = 0; i < nr_pages; i++) - pages[i] = page + i; + /* + * Set the "dma handle" + */ + *handle = page_to_phys(page); - if (map_vm_area(area, pgprot_noncached(PAGE_KERNEL), &pages)) - goto out_unmap; + do { + BUG_ON(!pte_none(*pte)); - /* - * Free the otherwise unused pages. - */ - page += nr_pages; - while (page < end) { - __free_page(page); - page++; + SetPageReserved(page); + set_pte_at(&init_mm, vaddr, + pte, mk_pte(page, pgprot_noncached(PAGE_KERNEL))); + page++; + pte++; + vaddr += PAGE_SIZE; + } while (size -= PAGE_SIZE); + + /* + * Free the otherwise unused pages. + */ + while (page < end) { + __free_page(page); + page++; + } + + return (void *)c->vm_start; } - return area->addr; -out_unmap: - vunmap(area->addr); - if (array_size > PAGE_SIZE) - vfree(pages); - else - kfree(pages); - goto out_free_pages; -out_free_area: - free_vm_area(area); -out_free_pages: if (page) __free_pages(page, order); -no_page: + no_page: return NULL; } EXPORT_SYMBOL(__dma_alloc_coherent); @@ -142,11 +239,103 @@ EXPORT_SYMBOL(__dma_alloc_coherent); */ void __dma_free_coherent(size_t size, void *vaddr) { - vfree(vaddr); + struct ppc_vm_region *c; + unsigned long flags, addr; + pte_t *ptep; + + size = PAGE_ALIGN(size); + + spin_lock_irqsave(&consistent_lock, flags); + + c = ppc_vm_region_find(&consistent_head, (unsigned long)vaddr); + if (!c) + goto no_area; + + if ((c->vm_end - c->vm_start) != size) { + printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n", + __func__, c->vm_end - c->vm_start, size); + dump_stack(); + size = c->vm_end - c->vm_start; + } + + ptep = consistent_pte + CONSISTENT_OFFSET(c->vm_start); + addr = c->vm_start; + do { + pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep); + unsigned long pfn; + + ptep++; + addr += PAGE_SIZE; + if (!pte_none(pte) && pte_present(pte)) { + pfn = pte_pfn(pte); + + if (pfn_valid(pfn)) { + struct page *page = pfn_to_page(pfn); + ClearPageReserved(page); + + __free_page(page); + continue; + } + } + + printk(KERN_CRIT "%s: bad page in kernel page table\n", + __func__); + } while (size -= PAGE_SIZE); + + flush_tlb_kernel_range(c->vm_start, c->vm_end); + + list_del(&c->vm_list); + + spin_unlock_irqrestore(&consistent_lock, flags); + + kfree(c); + return; + + no_area: + spin_unlock_irqrestore(&consistent_lock, flags); + printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n", + __func__, vaddr); + dump_stack(); } EXPORT_SYMBOL(__dma_free_coherent); +/* + * Initialise the consistent memory allocation. + */ +static int __init dma_alloc_init(void) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + int ret = 0; + + do { + pgd = pgd_offset(&init_mm, CONSISTENT_BASE); + pud = pud_alloc(&init_mm, pgd, CONSISTENT_BASE); + pmd = pmd_alloc(&init_mm, pud, CONSISTENT_BASE); + if (!pmd) { + printk(KERN_ERR "%s: no pmd tables\n", __func__); + ret = -ENOMEM; + break; + } + + pte = pte_alloc_kernel(pmd, CONSISTENT_BASE); + if (!pte) { + printk(KERN_ERR "%s: no pte tables\n", __func__); + ret = -ENOMEM; + break; + } + + consistent_pte = pte; + } while (0); + + return ret; +} + +core_initcall(dma_alloc_init); + /* * make an area consistent. */ diff --git a/trunk/arch/powerpc/lib/feature-fixups.c b/trunk/arch/powerpc/lib/feature-fixups.c index 7e8865bcd683..8c5a03be31e0 100644 --- a/trunk/arch/powerpc/lib/feature-fixups.c +++ b/trunk/arch/powerpc/lib/feature-fixups.c @@ -85,7 +85,7 @@ static int patch_feature_section(unsigned long value, struct fixup_entry *fcur) } for (; dest < end; dest++) - patch_instruction(dest, PPC_INST_NOP); + patch_instruction(dest, PPC_NOP_INSTR); return 0; } @@ -122,7 +122,7 @@ void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) for (; start < end; start++) { dest = (void *)start + *start; - patch_instruction(dest, PPC_INST_LWSYNC); + patch_instruction(dest, PPC_LWSYNC_INSTR); } } diff --git a/trunk/arch/powerpc/math-emu/Makefile b/trunk/arch/powerpc/math-emu/Makefile index 0c16ab947f1f..f9e506a735ae 100644 --- a/trunk/arch/powerpc/math-emu/Makefile +++ b/trunk/arch/powerpc/math-emu/Makefile @@ -1,4 +1,6 @@ +obj-y := math.o fmr.o lfd.o stfd.o + obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \ fctiw.o fctiwz.o fdiv.o fdivs.o \ fmadd.o fmadds.o fmsub.o fmsubs.o \ @@ -7,8 +9,7 @@ obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \ fres.o frsp.o frsqrte.o fsel.o lfs.o \ fsqrt.o fsqrts.o fsub.o fsubs.o \ mcrfs.o mffs.o mtfsb0.o mtfsb1.o \ - mtfsf.o mtfsfi.o stfiwx.o stfs.o \ - math.o fmr.o lfd.o stfd.o + mtfsf.o mtfsfi.o stfiwx.o stfs.o obj-$(CONFIG_SPE) += math_efp.o diff --git a/trunk/arch/powerpc/mm/Makefile b/trunk/arch/powerpc/mm/Makefile index 17290bcedc5e..953cc4a1cde5 100644 --- a/trunk/arch/powerpc/mm/Makefile +++ b/trunk/arch/powerpc/mm/Makefile @@ -6,7 +6,7 @@ ifeq ($(CONFIG_PPC64),y) EXTRA_CFLAGS += -mno-minimal-toc endif -obj-y := fault.o mem.o pgtable.o gup.o \ +obj-y := fault.o mem.o pgtable.o \ init_$(CONFIG_WORD_SIZE).o \ pgtable_$(CONFIG_WORD_SIZE).o obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \ @@ -14,7 +14,7 @@ obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \ hash-$(CONFIG_PPC_NATIVE) := hash_native_64.o obj-$(CONFIG_PPC64) += hash_utils_64.o \ slb_low.o slb.o stab.o \ - mmap_64.o $(hash-y) + gup.o mmap.o $(hash-y) obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o obj-$(CONFIG_PPC_STD_MMU) += hash_low_$(CONFIG_WORD_SIZE).o \ tlb_hash$(CONFIG_WORD_SIZE).o \ diff --git a/trunk/arch/powerpc/mm/fault.c b/trunk/arch/powerpc/mm/fault.c index 76993941cac9..91c7b8636b8a 100644 --- a/trunk/arch/powerpc/mm/fault.c +++ b/trunk/arch/powerpc/mm/fault.c @@ -253,33 +253,45 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, #endif /* CONFIG_8xx */ if (is_exec) { -#ifdef CONFIG_PPC_STD_MMU - /* Protection fault on exec go straight to failure on - * Hash based MMUs as they either don't support per-page - * execute permission, or if they do, it's handled already - * at the hash level. This test would probably have to - * be removed if we change the way this works to make hash - * processors use the same I/D cache coherency mechanism - * as embedded. - */ +#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) + /* protection fault */ if (error_code & DSISR_PROTFAULT) goto bad_area; -#endif /* CONFIG_PPC_STD_MMU */ - /* * Allow execution from readable areas if the MMU does not * provide separate controls over reading and executing. - * - * Note: That code used to not be enabled for 4xx/BookE. - * It is now as I/D cache coherency for these is done at - * set_pte_at() time and I see no reason why the test - * below wouldn't be valid on those processors. This -may- - * break programs compiled with a really old ABI though. */ if (!(vma->vm_flags & VM_EXEC) && (cpu_has_feature(CPU_FTR_NOEXECUTE) || !(vma->vm_flags & (VM_READ | VM_WRITE)))) goto bad_area; +#else + pte_t *ptep; + pmd_t *pmdp; + + /* Since 4xx/Book-E supports per-page execute permission, + * we lazily flush dcache to icache. */ + ptep = NULL; + if (get_pteptr(mm, address, &ptep, &pmdp)) { + spinlock_t *ptl = pte_lockptr(mm, pmdp); + spin_lock(ptl); + if (pte_present(*ptep)) { + struct page *page = pte_page(*ptep); + + if (!test_bit(PG_arch_1, &page->flags)) { + flush_dcache_icache_page(page); + set_bit(PG_arch_1, &page->flags); + } + pte_update(ptep, 0, _PAGE_HWEXEC | + _PAGE_ACCESSED); + local_flush_tlb_page(vma, address); + pte_unmap_unlock(ptep, ptl); + up_read(&mm->mmap_sem); + return 0; + } + pte_unmap_unlock(ptep, ptl); + } +#endif /* a write */ } else if (is_write) { if (!(vma->vm_flags & VM_WRITE)) diff --git a/trunk/arch/powerpc/mm/fsl_booke_mmu.c b/trunk/arch/powerpc/mm/fsl_booke_mmu.c index bb3d65998e6b..ea6e41e39d9f 100644 --- a/trunk/arch/powerpc/mm/fsl_booke_mmu.c +++ b/trunk/arch/powerpc/mm/fsl_booke_mmu.c @@ -56,14 +56,10 @@ extern void loadcam_entry(unsigned int index); unsigned int tlbcam_index; -static unsigned long cam[CONFIG_LOWMEM_CAM_NUM]; +static unsigned long __cam0, __cam1, __cam2; #define NUM_TLBCAMS (16) -#if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS) -#error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS" -#endif - struct tlbcam TLBCAM[NUM_TLBCAMS]; struct tlbcamrange { @@ -111,7 +107,7 @@ void settlbcam(int index, unsigned long virt, phys_addr_t phys, unsigned int tsize, lz; asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size)); - tsize = 21 - lz; + tsize = (21 - lz) / 2; #ifdef CONFIG_SMP if ((flags & _PAGE_NO_CACHE) == 0) @@ -156,19 +152,19 @@ void invalidate_tlbcam_entry(int index) loadcam_entry(index); } -unsigned long __init mmu_mapin_ram(void) +void __init cam_mapin_ram(unsigned long cam0, unsigned long cam1, + unsigned long cam2) { - unsigned long virt = PAGE_OFFSET; - phys_addr_t phys = memstart_addr; - - while (cam[tlbcam_index] && tlbcam_index < ARRAY_SIZE(cam)) { - settlbcam(tlbcam_index, virt, phys, cam[tlbcam_index], PAGE_KERNEL_X, 0); - virt += cam[tlbcam_index]; - phys += cam[tlbcam_index]; + settlbcam(0, PAGE_OFFSET, memstart_addr, cam0, _PAGE_KERNEL, 0); + tlbcam_index++; + if (cam1) { tlbcam_index++; + settlbcam(1, PAGE_OFFSET+cam0, memstart_addr+cam0, cam1, _PAGE_KERNEL, 0); + } + if (cam2) { + tlbcam_index++; + settlbcam(2, PAGE_OFFSET+cam0+cam1, memstart_addr+cam0+cam1, cam2, _PAGE_KERNEL, 0); } - - return virt - PAGE_OFFSET; } /* @@ -179,46 +175,51 @@ void __init MMU_init_hw(void) flush_instruction_cache(); } +unsigned long __init mmu_mapin_ram(void) +{ + cam_mapin_ram(__cam0, __cam1, __cam2); + + return __cam0 + __cam1 + __cam2; +} + + void __init adjust_total_lowmem(void) { + phys_addr_t max_lowmem_size = __max_low_memory; + phys_addr_t cam_max_size = 0x10000000; phys_addr_t ram; - unsigned int max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xff; - char buf[ARRAY_SIZE(cam) * 5 + 1], *p = buf; - int i; - unsigned long virt = PAGE_OFFSET & 0xffffffffUL; - unsigned long phys = memstart_addr & 0xffffffffUL; - /* Convert (4^max) kB to (2^max) bytes */ - max_cam = max_cam * 2 + 10; + /* adjust CAM size to max_lowmem_size */ + if (max_lowmem_size < cam_max_size) + cam_max_size = max_lowmem_size; - /* adjust lowmem size to __max_low_memory */ - ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem); + /* adjust lowmem size to max_lowmem_size */ + ram = min(max_lowmem_size, total_lowmem); /* Calculate CAM values */ - __max_low_memory = 0; - for (i = 0; ram && i < ARRAY_SIZE(cam); i++) { - unsigned int camsize = __ilog2(ram) & ~1U; - unsigned int align = __ffs(virt | phys) & ~1U; - - if (camsize > align) - camsize = align; - if (camsize > max_cam) - camsize = max_cam; - - cam[i] = 1UL << camsize; - ram -= cam[i]; - __max_low_memory += cam[i]; - virt += cam[i]; - phys += cam[i]; - - p += sprintf(p, "%lu/", cam[i] >> 20); + __cam0 = 1UL << 2 * (__ilog2(ram) / 2); + if (__cam0 > cam_max_size) + __cam0 = cam_max_size; + ram -= __cam0; + if (ram) { + __cam1 = 1UL << 2 * (__ilog2(ram) / 2); + if (__cam1 > cam_max_size) + __cam1 = cam_max_size; + ram -= __cam1; + } + if (ram) { + __cam2 = 1UL << 2 * (__ilog2(ram) / 2); + if (__cam2 > cam_max_size) + __cam2 = cam_max_size; + ram -= __cam2; } - for (; i < ARRAY_SIZE(cam); i++) - p += sprintf(p, "0/"); - p[-1] = '\0'; - pr_info("Memory CAM mapping: %s Mb, residual: %dMb\n", buf, - (unsigned int)((total_lowmem - __max_low_memory) >> 20)); + printk(KERN_INFO "Memory CAM mapping: CAM0=%ldMb, CAM1=%ldMb," + " CAM2=%ldMb residual: %ldMb\n", + __cam0 >> 20, __cam1 >> 20, __cam2 >> 20, + (long int)((total_lowmem - __cam0 - __cam1 - __cam2) + >> 20)); + __max_low_memory = __cam0 + __cam1 + __cam2; __initial_memory_limit_addr = memstart_addr + __max_low_memory; } diff --git a/trunk/arch/powerpc/mm/gup.c b/trunk/arch/powerpc/mm/gup.c index bc400c78c97f..28a114db3ba0 100644 --- a/trunk/arch/powerpc/mm/gup.c +++ b/trunk/arch/powerpc/mm/gup.c @@ -14,8 +14,6 @@ #include #include -#ifdef __HAVE_ARCH_PTE_SPECIAL - /* * The performance critical leaf functions are made noinline otherwise gcc * inlines everything into a single function which results in too much @@ -153,11 +151,8 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, unsigned long addr, len, end; unsigned long next; pgd_t *pgdp; - int nr = 0; -#ifdef CONFIG_PPC64 + int psize, nr = 0; unsigned int shift; - int psize; -#endif pr_debug("%s(%lx,%x,%s)\n", __func__, start, nr_pages, write ? "write" : "read"); @@ -210,13 +205,8 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, */ local_irq_disable(); -#ifdef CONFIG_PPC64 - /* Those bits are related to hugetlbfs implementation and only exist - * on 64-bit for now - */ psize = get_slice_psize(mm, addr); shift = mmu_psize_defs[psize].shift; -#endif /* CONFIG_PPC64 */ #ifdef CONFIG_HUGETLB_PAGE if (unlikely(mmu_huge_psizes[psize])) { @@ -246,9 +236,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, do { pgd_t pgd = *pgdp; -#ifdef CONFIG_PPC64 VM_BUG_ON(shift != mmu_psize_defs[get_slice_psize(mm, addr)].shift); -#endif pr_debug(" %016lx: normal pgd %p\n", addr, (void *)pgd_val(pgd)); next = pgd_addr_end(addr, end); @@ -291,5 +279,3 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, return ret; } } - -#endif /* __HAVE_ARCH_PTE_SPECIAL */ diff --git a/trunk/arch/powerpc/mm/hash_utils_64.c b/trunk/arch/powerpc/mm/hash_utils_64.c index db556d25c3a7..8d5b4758c13a 100644 --- a/trunk/arch/powerpc/mm/hash_utils_64.c +++ b/trunk/arch/powerpc/mm/hash_utils_64.c @@ -516,7 +516,7 @@ static int __init htab_dt_scan_pftsize(unsigned long node, static unsigned long __init htab_get_table_size(void) { - unsigned long mem_size, rnd_mem_size, pteg_count, psize; + unsigned long mem_size, rnd_mem_size, pteg_count; /* If hash size isn't already provided by the platform, we try to * retrieve it from the device-tree. If it's not there neither, we @@ -534,8 +534,7 @@ static unsigned long __init htab_get_table_size(void) rnd_mem_size <<= 1; /* # pages / 2 */ - psize = mmu_psize_defs[mmu_virtual_psize].shift; - pteg_count = max(rnd_mem_size >> (psize + 1), 1UL << 11); + pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11); return pteg_count << 7; } @@ -590,7 +589,7 @@ static void __init htab_finish_init(void) make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp); } -static void __init htab_initialize(void) +void __init htab_initialize(void) { unsigned long table; unsigned long pteg_count; @@ -732,43 +731,11 @@ static void __init htab_initialize(void) #undef KB #undef MB -void __init early_init_mmu(void) +void htab_initialize_secondary(void) { - /* Setup initial STAB address in the PACA */ - get_paca()->stab_real = __pa((u64)&initial_stab); - get_paca()->stab_addr = (u64)&initial_stab; - - /* Initialize the MMU Hash table and create the linear mapping - * of memory. Has to be done before stab/slb initialization as - * this is currently where the page size encoding is obtained - */ - htab_initialize(); - - /* Initialize stab / SLB management except on iSeries - */ - if (cpu_has_feature(CPU_FTR_SLB)) - slb_initialize(); - else if (!firmware_has_feature(FW_FEATURE_ISERIES)) - stab_initialize(get_paca()->stab_real); -} - -#ifdef CONFIG_SMP -void __init early_init_mmu_secondary(void) -{ - /* Initialize hash table for that CPU */ if (!firmware_has_feature(FW_FEATURE_LPAR)) mtspr(SPRN_SDR1, _SDR1); - - /* Initialize STAB/SLB. We use a virtual address as it works - * in real mode on pSeries and we want a virutal address on - * iSeries anyway - */ - if (cpu_has_feature(CPU_FTR_SLB)) - slb_initialize(); - else - stab_initialize(get_paca()->stab_addr); } -#endif /* CONFIG_SMP */ /* * Called by asm hashtable.S for doing lazy icache flush @@ -891,7 +858,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) unsigned long vsid; struct mm_struct *mm; pte_t *ptep; - const struct cpumask *tmp; + cpumask_t tmp; int rc, user_region = 0, local = 0; int psize, ssize; @@ -939,8 +906,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) return 1; /* Check CPU locality */ - tmp = cpumask_of(smp_processor_id()); - if (user_region && cpumask_equal(mm_cpumask(mm), tmp)) + tmp = cpumask_of_cpu(smp_processor_id()); + if (user_region && cpus_equal(mm->cpu_vm_mask, tmp)) local = 1; #ifdef CONFIG_HUGETLB_PAGE @@ -1056,6 +1023,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, unsigned long vsid; void *pgdir; pte_t *ptep; + cpumask_t mask; unsigned long flags; int local = 0; int ssize; @@ -1098,7 +1066,8 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, local_irq_save(flags); /* Is that local to this CPU ? */ - if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) + mask = cpumask_of_cpu(smp_processor_id()); + if (cpus_equal(mm->cpu_vm_mask, mask)) local = 1; /* Hash it in */ diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index f668fa9ba804..f00f09a77f12 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -472,7 +472,40 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, { #ifdef CONFIG_PPC_STD_MMU unsigned long access = 0, trap; +#endif + unsigned long pfn = pte_pfn(pte); + + /* handle i-cache coherency */ + if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) && + !cpu_has_feature(CPU_FTR_NOEXECUTE) && + pfn_valid(pfn)) { + struct page *page = pfn_to_page(pfn); +#ifdef CONFIG_8xx + /* On 8xx, cache control instructions (particularly + * "dcbst" from flush_dcache_icache) fault as write + * operation if there is an unpopulated TLB entry + * for the address in question. To workaround that, + * we invalidate the TLB here, thus avoiding dcbst + * misbehaviour. + */ + _tlbil_va(address, 0 /* 8xx doesn't care about PID */); +#endif + /* The _PAGE_USER test should really be _PAGE_EXEC, but + * older glibc versions execute some code from no-exec + * pages, which for now we are supporting. If exec-only + * pages are ever implemented, this will have to change. + */ + if (!PageReserved(page) && (pte_val(pte) & _PAGE_USER) + && !test_bit(PG_arch_1, &page->flags)) { + if (vma->vm_mm == current->active_mm) { + __flush_dcache_icache((void *) address); + } else + flush_dcache_icache_page(page); + set_bit(PG_arch_1, &page->flags); + } + } +#ifdef CONFIG_PPC_STD_MMU /* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */ if (!pte_young(pte) || address >= TASK_SIZE) return; diff --git a/trunk/arch/powerpc/mm/mmap_64.c b/trunk/arch/powerpc/mm/mmap.c similarity index 65% rename from trunk/arch/powerpc/mm/mmap_64.c rename to trunk/arch/powerpc/mm/mmap.c index 0d957a4c70fe..86010fc7d3b1 100644 --- a/trunk/arch/powerpc/mm/mmap_64.c +++ b/trunk/arch/powerpc/mm/mmap.c @@ -24,57 +24,16 @@ #include #include -#include #include /* * Top of mmap area (just below the process stack). * - * Leave at least a ~128 MB hole on 32bit applications. - * - * On 64bit applications we randomise the stack by 1GB so we need to - * space our mmap start address by a further 1GB, otherwise there is a - * chance the mmap area will end up closer to the stack than our ulimit - * requires. + * Leave an at least ~128 MB hole. */ -#define MIN_GAP32 (128*1024*1024) -#define MIN_GAP64 ((128 + 1024)*1024*1024UL) -#define MIN_GAP ((is_32bit_task()) ? MIN_GAP32 : MIN_GAP64) +#define MIN_GAP (128*1024*1024) #define MAX_GAP (TASK_SIZE/6*5) -static inline int mmap_is_legacy(void) -{ - if (current->personality & ADDR_COMPAT_LAYOUT) - return 1; - - if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) - return 1; - - return sysctl_legacy_va_layout; -} - -/* - * Since get_random_int() returns the same value within a 1 jiffy window, - * we will almost always get the same randomisation for the stack and mmap - * region. This will mean the relative distance between stack and mmap will - * be the same. - * - * To avoid this we can shift the randomness by 1 bit. - */ -static unsigned long mmap_rnd(void) -{ - unsigned long rnd = 0; - - if (current->flags & PF_RANDOMIZE) { - /* 8MB for 32bit, 1GB for 64bit */ - if (is_32bit_task()) - rnd = (long)(get_random_int() % (1<<(22-PAGE_SHIFT))); - else - rnd = (long)(get_random_int() % (1<<(29-PAGE_SHIFT))); - } - return (rnd << PAGE_SHIFT) * 2; -} - static inline unsigned long mmap_base(void) { unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; @@ -84,7 +43,24 @@ static inline unsigned long mmap_base(void) else if (gap > MAX_GAP) gap = MAX_GAP; - return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd()); + return TASK_SIZE - (gap & PAGE_MASK); +} + +static inline int mmap_is_legacy(void) +{ + /* + * Force standard allocation for 64 bit programs. + */ + if (!test_thread_flag(TIF_32BIT)) + return 1; + + if (current->personality & ADDR_COMPAT_LAYOUT) + return 1; + + if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) + return 1; + + return sysctl_legacy_va_layout; } /* diff --git a/trunk/arch/powerpc/mm/mmu_context_nohash.c b/trunk/arch/powerpc/mm/mmu_context_nohash.c index a70e311bd457..52a0cfc38b64 100644 --- a/trunk/arch/powerpc/mm/mmu_context_nohash.c +++ b/trunk/arch/powerpc/mm/mmu_context_nohash.c @@ -97,7 +97,7 @@ static unsigned int steal_context_smp(unsigned int id) mm->context.id = MMU_NO_CONTEXT; /* Mark it stale on all CPUs that used this mm */ - for_each_cpu(cpu, mm_cpumask(mm)) + for_each_cpu_mask_nr(cpu, mm->cpu_vm_mask) __set_bit(id, stale_map[cpu]); return id; } @@ -380,7 +380,7 @@ void __init mmu_context_init(void) #endif printk(KERN_INFO - "MMU: Allocated %zu bytes of context maps for %d contexts\n", + "MMU: Allocated %d bytes of context maps for %d contexts\n", 2 * CTX_MAP_SIZE + (sizeof(void *) * (last_context + 1)), last_context - first_context + 1); diff --git a/trunk/arch/powerpc/mm/numa.c b/trunk/arch/powerpc/mm/numa.c index 9047145095aa..5ac08b8ab654 100644 --- a/trunk/arch/powerpc/mm/numa.c +++ b/trunk/arch/powerpc/mm/numa.c @@ -158,6 +158,35 @@ static void unmap_cpu_from_node(unsigned long cpu) } #endif /* CONFIG_HOTPLUG_CPU */ +static struct device_node * __cpuinit find_cpu_node(unsigned int cpu) +{ + unsigned int hw_cpuid = get_hard_smp_processor_id(cpu); + struct device_node *cpu_node = NULL; + const unsigned int *interrupt_server, *reg; + int len; + + while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) { + /* Try interrupt server first */ + interrupt_server = of_get_property(cpu_node, + "ibm,ppc-interrupt-server#s", &len); + + len = len / sizeof(u32); + + if (interrupt_server && (len > 0)) { + while (len--) { + if (interrupt_server[len] == hw_cpuid) + return cpu_node; + } + } else { + reg = of_get_property(cpu_node, "reg", &len); + if (reg && (len > 0) && (reg[0] == hw_cpuid)) + return cpu_node; + } + } + + return NULL; +} + /* must hold reference to node during call */ static const int *of_get_associativity(struct device_node *dev) { @@ -261,7 +290,7 @@ static int __init find_min_common_depth(void) ref_points = of_get_property(rtas_root, "ibm,associativity-reference-points", &len); - if ((len >= 2 * sizeof(unsigned int)) && ref_points) { + if ((len >= 1) && ref_points) { depth = ref_points[1]; } else { dbg("NUMA: ibm,associativity-reference-points not found.\n"); @@ -441,7 +470,7 @@ static int of_drconf_to_nid_single(struct of_drconf_cell *drmem, static int __cpuinit numa_setup_cpu(unsigned long lcpu) { int nid = 0; - struct device_node *cpu = of_get_cpu_node(lcpu, NULL); + struct device_node *cpu = find_cpu_node(lcpu); if (!cpu) { WARN_ON(1); @@ -623,7 +652,7 @@ static int __init parse_numa_properties(void) for_each_present_cpu(i) { int nid; - cpu = of_get_cpu_node(i, NULL); + cpu = find_cpu_node(i); BUG_ON(!cpu); nid = of_node_to_nid_single(cpu); of_node_put(cpu); @@ -1012,32 +1041,57 @@ early_param("numa", early_numa); #ifdef CONFIG_MEMORY_HOTPLUG /* - * Find the node associated with a hot added memory section for - * memory represented in the device tree by the property - * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory. + * Validate the node associated with the memory section we are + * trying to add. + */ +int valid_hot_add_scn(int *nid, unsigned long start, u32 lmb_size, + unsigned long scn_addr) +{ + nodemask_t nodes; + + if (*nid < 0 || !node_online(*nid)) + *nid = any_online_node(NODE_MASK_ALL); + + if ((scn_addr >= start) && (scn_addr < (start + lmb_size))) { + nodes_setall(nodes); + while (NODE_DATA(*nid)->node_spanned_pages == 0) { + node_clear(*nid, nodes); + *nid = any_online_node(nodes); + } + + return 1; + } + + return 0; +} + +/* + * Find the node associated with a hot added memory section represented + * by the ibm,dynamic-reconfiguration-memory node. */ static int hot_add_drconf_scn_to_nid(struct device_node *memory, unsigned long scn_addr) { const u32 *dm; - unsigned int drconf_cell_cnt, rc; + unsigned int n, rc; unsigned long lmb_size; + int default_nid = any_online_node(NODE_MASK_ALL); + int nid; struct assoc_arrays aa; - int nid = -1; - drconf_cell_cnt = of_get_drconf_memory(memory, &dm); - if (!drconf_cell_cnt) - return -1; + n = of_get_drconf_memory(memory, &dm); + if (!n) + return default_nid;; lmb_size = of_get_lmb_size(memory); if (!lmb_size) - return -1; + return default_nid; rc = of_get_assoc_arrays(memory, &aa); if (rc) - return -1; + return default_nid; - for (; drconf_cell_cnt != 0; --drconf_cell_cnt) { + for (; n != 0; --n) { struct of_drconf_cell drmem; read_drconf_cell(&drmem, &dm); @@ -1048,57 +1102,15 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory, || !(drmem.flags & DRCONF_MEM_ASSIGNED)) continue; - if ((scn_addr < drmem.base_addr) - || (scn_addr >= (drmem.base_addr + lmb_size))) - continue; - nid = of_drconf_to_nid_single(&drmem, &aa); - break; - } - - return nid; -} -/* - * Find the node associated with a hot added memory section for memory - * represented in the device tree as a node (i.e. memory@XXXX) for - * each lmb. - */ -int hot_add_node_scn_to_nid(unsigned long scn_addr) -{ - struct device_node *memory = NULL; - int nid = -1; - - while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { - unsigned long start, size; - int ranges; - const unsigned int *memcell_buf; - unsigned int len; - - memcell_buf = of_get_property(memory, "reg", &len); - if (!memcell_buf || len <= 0) - continue; - - /* ranges in cell */ - ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells); - - while (ranges--) { - start = read_n_cells(n_mem_addr_cells, &memcell_buf); - size = read_n_cells(n_mem_size_cells, &memcell_buf); - - if ((scn_addr < start) || (scn_addr >= (start + size))) - continue; - - nid = of_node_to_nid_single(memory); - break; - } - - of_node_put(memory); - if (nid >= 0) - break; + if (valid_hot_add_scn(&nid, drmem.base_addr, lmb_size, + scn_addr)) + return nid; } - return nid; + BUG(); /* section address should be found above */ + return 0; } /* @@ -1109,7 +1121,7 @@ int hot_add_node_scn_to_nid(unsigned long scn_addr) int hot_add_scn_to_nid(unsigned long scn_addr) { struct device_node *memory = NULL; - int nid, found = 0; + int nid; if (!numa_enabled || (min_common_depth < 0)) return any_online_node(NODE_MASK_ALL); @@ -1118,25 +1130,35 @@ int hot_add_scn_to_nid(unsigned long scn_addr) if (memory) { nid = hot_add_drconf_scn_to_nid(memory, scn_addr); of_node_put(memory); - } else { - nid = hot_add_node_scn_to_nid(scn_addr); + return nid; } - if (nid < 0 || !node_online(nid)) - nid = any_online_node(NODE_MASK_ALL); + while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { + unsigned long start, size; + int ranges; + const unsigned int *memcell_buf; + unsigned int len; - if (NODE_DATA(nid)->node_spanned_pages) - return nid; + memcell_buf = of_get_property(memory, "reg", &len); + if (!memcell_buf || len <= 0) + continue; - for_each_online_node(nid) { - if (NODE_DATA(nid)->node_spanned_pages) { - found = 1; - break; + /* ranges in cell */ + ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells); +ha_new_range: + start = read_n_cells(n_mem_addr_cells, &memcell_buf); + size = read_n_cells(n_mem_size_cells, &memcell_buf); + nid = of_node_to_nid_single(memory); + + if (valid_hot_add_scn(&nid, start, size, scn_addr)) { + of_node_put(memory); + return nid; } - } - BUG_ON(!found); - return nid; + if (--ranges) /* process all ranges in cell */ + goto ha_new_range; + } + BUG(); /* section address should be found above */ + return 0; } - #endif /* CONFIG_MEMORY_HOTPLUG */ diff --git a/trunk/arch/powerpc/mm/pgtable.c b/trunk/arch/powerpc/mm/pgtable.c index f5c6fd42265c..6d94116fdea1 100644 --- a/trunk/arch/powerpc/mm/pgtable.c +++ b/trunk/arch/powerpc/mm/pgtable.c @@ -1,6 +1,5 @@ /* * This file contains common routines for dealing with free of page tables - * Along with common page table handling code * * Derived from arch/powerpc/mm/tlb_64.c: * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) @@ -82,10 +81,11 @@ static void pte_free_submit(struct pte_freelist_batch *batch) void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf) { /* This is safe since tlb_gather_mmu has disabled preemption */ + cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id()); struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur); if (atomic_read(&tlb->mm->mm_users) < 2 || - cpumask_equal(mm_cpumask(tlb->mm), cpumask_of(smp_processor_id()))){ + cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) { pgtable_free(pgf); return; } @@ -115,133 +115,3 @@ void pte_free_finish(void) pte_free_submit(*batchp); *batchp = NULL; } - -/* - * Handle i/d cache flushing, called from set_pte_at() or ptep_set_access_flags() - */ -static pte_t do_dcache_icache_coherency(pte_t pte) -{ - unsigned long pfn = pte_pfn(pte); - struct page *page; - - if (unlikely(!pfn_valid(pfn))) - return pte; - page = pfn_to_page(pfn); - - if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) { - pr_debug("do_dcache_icache_coherency... flushing\n"); - flush_dcache_icache_page(page); - set_bit(PG_arch_1, &page->flags); - } - else - pr_debug("do_dcache_icache_coherency... already clean\n"); - return __pte(pte_val(pte) | _PAGE_HWEXEC); -} - -static inline int is_exec_fault(void) -{ - return current->thread.regs && TRAP(current->thread.regs) == 0x400; -} - -/* We only try to do i/d cache coherency on stuff that looks like - * reasonably "normal" PTEs. We currently require a PTE to be present - * and we avoid _PAGE_SPECIAL and _PAGE_NO_CACHE - */ -static inline int pte_looks_normal(pte_t pte) -{ - return (pte_val(pte) & - (_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE)) == - (_PAGE_PRESENT); -} - -#if defined(CONFIG_PPC_STD_MMU) -/* Server-style MMU handles coherency when hashing if HW exec permission - * is supposed per page (currently 64-bit only). Else, we always flush - * valid PTEs in set_pte. - */ -static inline int pte_need_exec_flush(pte_t pte, int set_pte) -{ - return set_pte && pte_looks_normal(pte) && - !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) || - cpu_has_feature(CPU_FTR_NOEXECUTE)); -} -#elif _PAGE_HWEXEC == 0 -/* Embedded type MMU without HW exec support (8xx only so far), we flush - * the cache for any present PTE - */ -static inline int pte_need_exec_flush(pte_t pte, int set_pte) -{ - return set_pte && pte_looks_normal(pte); -} -#else -/* Other embedded CPUs with HW exec support per-page, we flush on exec - * fault if HWEXEC is not set - */ -static inline int pte_need_exec_flush(pte_t pte, int set_pte) -{ - return pte_looks_normal(pte) && is_exec_fault() && - !(pte_val(pte) & _PAGE_HWEXEC); -} -#endif - -/* - * set_pte stores a linux PTE into the linux page table. - */ -void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) -{ -#ifdef CONFIG_DEBUG_VM - WARN_ON(pte_present(*ptep)); -#endif - /* Note: mm->context.id might not yet have been assigned as - * this context might not have been activated yet when this - * is called. - */ - pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS); - if (pte_need_exec_flush(pte, 1)) - pte = do_dcache_icache_coherency(pte); - - /* Perform the setting of the PTE */ - __set_pte_at(mm, addr, ptep, pte, 0); -} - -/* - * This is called when relaxing access to a PTE. It's also called in the page - * fault path when we don't hit any of the major fault cases, ie, a minor - * update of _PAGE_ACCESSED, _PAGE_DIRTY, etc... The generic code will have - * handled those two for us, we additionally deal with missing execute - * permission here on some processors - */ -int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, - pte_t *ptep, pte_t entry, int dirty) -{ - int changed; - if (!dirty && pte_need_exec_flush(entry, 0)) - entry = do_dcache_icache_coherency(entry); - changed = !pte_same(*(ptep), entry); - if (changed) { - assert_pte_locked(vma->vm_mm, address); - __ptep_set_access_flags(ptep, entry); - flush_tlb_page_nohash(vma, address); - } - return changed; -} - -#ifdef CONFIG_DEBUG_VM -void assert_pte_locked(struct mm_struct *mm, unsigned long addr) -{ - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - - if (mm == &init_mm) - return; - pgd = mm->pgd + pgd_index(addr); - BUG_ON(pgd_none(*pgd)); - pud = pud_offset(pgd, addr); - BUG_ON(pud_none(*pud)); - pmd = pmd_offset(pud, addr); - BUG_ON(!pmd_present(*pmd)); - BUG_ON(!spin_is_locked(pte_lockptr(mm, pmd))); -} -#endif /* CONFIG_DEBUG_VM */ - diff --git a/trunk/arch/powerpc/mm/pgtable_32.c b/trunk/arch/powerpc/mm/pgtable_32.c index 430d0908fa50..58bcaeba728d 100644 --- a/trunk/arch/powerpc/mm/pgtable_32.c +++ b/trunk/arch/powerpc/mm/pgtable_32.c @@ -129,8 +129,7 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) void __iomem * ioremap(phys_addr_t addr, unsigned long size) { - return __ioremap_caller(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED, - __builtin_return_address(0)); + return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED); } EXPORT_SYMBOL(ioremap); @@ -144,19 +143,12 @@ ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags) /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */ flags &= ~(_PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC); - return __ioremap_caller(addr, size, flags, __builtin_return_address(0)); + return __ioremap(addr, size, flags); } EXPORT_SYMBOL(ioremap_flags); void __iomem * __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags) -{ - return __ioremap_caller(addr, size, flags, __builtin_return_address(0)); -} - -void __iomem * -__ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags, - void *caller) { unsigned long v, i; phys_addr_t p; @@ -164,7 +156,7 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags, /* Make sure we have the base flags */ if ((flags & _PAGE_PRESENT) == 0) - flags |= PAGE_KERNEL; + flags |= _PAGE_KERNEL; /* Non-cacheable page cannot be coherent */ if (flags & _PAGE_NO_CACHE) @@ -220,7 +212,7 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags, if (mem_init_done) { struct vm_struct *area; - area = get_vm_area_caller(size, VM_IOREMAP, caller); + area = get_vm_area(size, VM_IOREMAP); if (area == 0) return NULL; v = (unsigned long) area->addr; @@ -296,7 +288,7 @@ void __init mapin_ram(void) p = memstart_addr + s; for (; s < total_lowmem; s += PAGE_SIZE) { ktext = ((char *) v >= _stext && (char *) v < etext); - f = ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL; + f = ktext ?_PAGE_RAM_TEXT : _PAGE_RAM; map_page(v, p, f); #ifdef CONFIG_PPC_STD_MMU_32 if (ktext) diff --git a/trunk/arch/powerpc/mm/pgtable_64.c b/trunk/arch/powerpc/mm/pgtable_64.c index bfa7db6b2fd5..365e61ae5dbc 100644 --- a/trunk/arch/powerpc/mm/pgtable_64.c +++ b/trunk/arch/powerpc/mm/pgtable_64.c @@ -144,8 +144,8 @@ void __iounmap_at(void *ea, unsigned long size) unmap_kernel_range((unsigned long)ea, size); } -void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size, - unsigned long flags, void *caller) +void __iomem * __ioremap(phys_addr_t addr, unsigned long size, + unsigned long flags) { phys_addr_t paligned; void __iomem *ret; @@ -168,9 +168,8 @@ void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size, if (mem_init_done) { struct vm_struct *area; - area = __get_vm_area_caller(size, VM_IOREMAP, - ioremap_bot, IOREMAP_END, - caller); + area = __get_vm_area(size, VM_IOREMAP, + ioremap_bot, IOREMAP_END); if (area == NULL) return NULL; ret = __ioremap_at(paligned, area->addr, size, flags); @@ -187,27 +186,19 @@ void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size, return ret; } -void __iomem * __ioremap(phys_addr_t addr, unsigned long size, - unsigned long flags) -{ - return __ioremap_caller(addr, size, flags, __builtin_return_address(0)); -} void __iomem * ioremap(phys_addr_t addr, unsigned long size) { unsigned long flags = _PAGE_NO_CACHE | _PAGE_GUARDED; - void *caller = __builtin_return_address(0); if (ppc_md.ioremap) - return ppc_md.ioremap(addr, size, flags, caller); - return __ioremap_caller(addr, size, flags, caller); + return ppc_md.ioremap(addr, size, flags); + return __ioremap(addr, size, flags); } void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags) { - void *caller = __builtin_return_address(0); - /* writeable implies dirty for kernel addresses */ if (flags & _PAGE_RW) flags |= _PAGE_DIRTY; @@ -216,8 +207,8 @@ void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size, flags &= ~(_PAGE_USER | _PAGE_EXEC); if (ppc_md.ioremap) - return ppc_md.ioremap(addr, size, flags, caller); - return __ioremap_caller(addr, size, flags, caller); + return ppc_md.ioremap(addr, size, flags); + return __ioremap(addr, size, flags); } diff --git a/trunk/arch/powerpc/mm/ppc_mmu_32.c b/trunk/arch/powerpc/mm/ppc_mmu_32.c index 2d2a87e10154..fe65c405412c 100644 --- a/trunk/arch/powerpc/mm/ppc_mmu_32.c +++ b/trunk/arch/powerpc/mm/ppc_mmu_32.c @@ -74,6 +74,9 @@ unsigned long p_mapped_by_bats(phys_addr_t pa) unsigned long __init mmu_mapin_ram(void) { +#ifdef CONFIG_POWER4 + return 0; +#else unsigned long tot, bl, done; unsigned long max_size = (256<<20); @@ -92,7 +95,7 @@ unsigned long __init mmu_mapin_ram(void) break; } - setbat(2, PAGE_OFFSET, 0, bl, PAGE_KERNEL_X); + setbat(2, PAGE_OFFSET, 0, bl, _PAGE_RAM); done = (unsigned long)bat_addrs[2].limit - PAGE_OFFSET + 1; if ((done < tot) && !bat_addrs[3].limit) { /* use BAT3 to cover a bit more */ @@ -100,11 +103,12 @@ unsigned long __init mmu_mapin_ram(void) for (bl = 128<<10; bl < max_size; bl <<= 1) if (bl * 2 > tot) break; - setbat(3, PAGE_OFFSET+done, done, bl, PAGE_KERNEL_X); + setbat(3, PAGE_OFFSET+done, done, bl, _PAGE_RAM); done = (unsigned long)bat_addrs[3].limit - PAGE_OFFSET + 1; } return done; +#endif } /* @@ -132,7 +136,9 @@ void __init setbat(int index, unsigned long virt, phys_addr_t phys, wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX; bat[1].batu = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */ bat[1].batl = BAT_PHYS_ADDR(phys) | wimgxpp; +#ifndef CONFIG_KGDB /* want user access for breakpoints */ if (flags & _PAGE_USER) +#endif bat[1].batu |= 1; /* Vp = 1 */ if (flags & _PAGE_GUARDED) { /* G bit must be zero in IBATs */ diff --git a/trunk/arch/powerpc/mm/tlb_hash64.c b/trunk/arch/powerpc/mm/tlb_hash64.c index 1be1b5e59796..c931bc7d1079 100644 --- a/trunk/arch/powerpc/mm/tlb_hash64.c +++ b/trunk/arch/powerpc/mm/tlb_hash64.c @@ -139,12 +139,12 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, */ void __flush_tlb_pending(struct ppc64_tlb_batch *batch) { - const struct cpumask *tmp; + cpumask_t tmp; int i, local = 0; i = batch->index; - tmp = cpumask_of(smp_processor_id()); - if (cpumask_equal(mm_cpumask(batch->mm), tmp)) + tmp = cpumask_of_cpu(smp_processor_id()); + if (cpus_equal(batch->mm->cpu_vm_mask, tmp)) local = 1; if (i == 1) flush_hash_page(batch->vaddr[0], batch->pte[0], diff --git a/trunk/arch/powerpc/mm/tlb_nohash.c b/trunk/arch/powerpc/mm/tlb_nohash.c index 7af72970faed..39ac22b13c73 100644 --- a/trunk/arch/powerpc/mm/tlb_nohash.c +++ b/trunk/arch/powerpc/mm/tlb_nohash.c @@ -132,11 +132,11 @@ void flush_tlb_mm(struct mm_struct *mm) pid = mm->context.id; if (unlikely(pid == MMU_NO_CONTEXT)) goto no_context; - if (!cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) { + cpu_mask = mm->cpu_vm_mask; + cpu_clear(smp_processor_id(), cpu_mask); + if (!cpus_empty(cpu_mask)) { struct tlb_flush_param p = { .pid = pid }; - /* Ignores smp_processor_id() even if set. */ - smp_call_function_many(mm_cpumask(mm), - do_flush_tlb_mm_ipi, &p, 1); + smp_call_function_mask(cpu_mask, do_flush_tlb_mm_ipi, &p, 1); } _tlbil_pid(pid); no_context: @@ -146,15 +146,16 @@ EXPORT_SYMBOL(flush_tlb_mm); void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) { - struct cpumask *cpu_mask; + cpumask_t cpu_mask; unsigned int pid; preempt_disable(); pid = vma ? vma->vm_mm->context.id : 0; if (unlikely(pid == MMU_NO_CONTEXT)) goto bail; - cpu_mask = mm_cpumask(vma->vm_mm); - if (!cpumask_equal(cpu_mask, cpumask_of(smp_processor_id()))) { + cpu_mask = vma->vm_mm->cpu_vm_mask; + cpu_clear(smp_processor_id(), cpu_mask); + if (!cpus_empty(cpu_mask)) { /* If broadcast tlbivax is supported, use it */ if (mmu_has_feature(MMU_FTR_USE_TLBIVAX_BCAST)) { int lock = mmu_has_feature(MMU_FTR_LOCK_BCAST_INVAL); @@ -166,8 +167,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) goto bail; } else { struct tlb_flush_param p = { .pid = pid, .addr = vmaddr }; - /* Ignores smp_processor_id() even if set in cpu_mask */ - smp_call_function_many(cpu_mask, + smp_call_function_mask(cpu_mask, do_flush_tlb_page_ipi, &p, 1); } } diff --git a/trunk/arch/powerpc/mm/tlb_nohash_low.S b/trunk/arch/powerpc/mm/tlb_nohash_low.S index 788b87c36f77..f900a39e6ec4 100644 --- a/trunk/arch/powerpc/mm/tlb_nohash_low.S +++ b/trunk/arch/powerpc/mm/tlb_nohash_low.S @@ -118,50 +118,25 @@ _GLOBAL(_tlbil_pid) #elif defined(CONFIG_FSL_BOOKE) /* - * FSL BookE implementations. - * - * Since feature sections are using _SECTION_ELSE we need - * to have the larger code path before the _SECTION_ELSE + * FSL BookE implementations. Currently _pid and _all are the + * same. This will change when tlbilx is actually supported and + * performs invalidate-by-PID. This change will be driven by + * mmu_features conditional */ -#define MMUCSR0_TLBFI (MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \ - MMUCSR0_TLB2FI | MMUCSR0_TLB3FI) /* * Flush MMU TLB on the local processor */ -_GLOBAL(_tlbil_all) -BEGIN_MMU_FTR_SECTION - li r3,(MMUCSR0_TLBFI)@l - mtspr SPRN_MMUCSR0, r3 -1: - mfspr r3,SPRN_MMUCSR0 - andi. r3,r3,MMUCSR0_TLBFI@l - bne 1b -MMU_FTR_SECTION_ELSE - PPC_TLBILX_ALL(0,0) -ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX) - msync - isync - blr - _GLOBAL(_tlbil_pid) -BEGIN_MMU_FTR_SECTION - slwi r3,r3,16 - mfmsr r10 - wrteei 0 - mfspr r4,SPRN_MAS6 /* save MAS6 */ - mtspr SPRN_MAS6,r3 - PPC_TLBILX_PID(0,0) - mtspr SPRN_MAS6,r4 /* restore MAS6 */ - wrtee r10 -MMU_FTR_SECTION_ELSE +_GLOBAL(_tlbil_all) +#define MMUCSR0_TLBFI (MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \ + MMUCSR0_TLB2FI | MMUCSR0_TLB3FI) li r3,(MMUCSR0_TLBFI)@l mtspr SPRN_MMUCSR0, r3 1: mfspr r3,SPRN_MMUCSR0 andi. r3,r3,MMUCSR0_TLBFI@l bne 1b -ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBILX) msync isync blr @@ -174,9 +149,7 @@ _GLOBAL(_tlbil_va) mfmsr r10 wrteei 0 slwi r4,r4,16 - ori r4,r4,(MAS6_ISIZE(BOOK3E_PAGESZ_4K))@l mtspr SPRN_MAS6,r4 /* assume AS=0 for now */ -BEGIN_MMU_FTR_SECTION tlbsx 0,r3 mfspr r4,SPRN_MAS1 /* check valid */ andis. r3,r4,MAS1_VALID@h @@ -184,9 +157,6 @@ BEGIN_MMU_FTR_SECTION rlwinm r4,r4,0,1,31 mtspr SPRN_MAS1,r4 tlbwe -MMU_FTR_SECTION_ELSE - PPC_TLBILX_VA(0,r3) -ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX) msync isync 1: wrtee r10 diff --git a/trunk/arch/powerpc/oprofile/op_model_7450.c b/trunk/arch/powerpc/oprofile/op_model_7450.c index f8d36f940e88..cc599eb8768b 100644 --- a/trunk/arch/powerpc/oprofile/op_model_7450.c +++ b/trunk/arch/powerpc/oprofile/op_model_7450.c @@ -29,7 +29,7 @@ static unsigned long reset_value[OP_MAX_COUNTER]; static int oprofile_running; -static u32 mmcr0_val, mmcr1_val, mmcr2_val, num_pmcs; +static u32 mmcr0_val, mmcr1_val, mmcr2_val; #define MMCR0_PMC1_SHIFT 6 #define MMCR0_PMC2_SHIFT 0 @@ -88,12 +88,13 @@ static int fsl7450_cpu_setup(struct op_counter_config *ctr) mtspr(SPRN_MMCR0, mmcr0_val); mtspr(SPRN_MMCR1, mmcr1_val); - if (num_pmcs > 4) - mtspr(SPRN_MMCR2, mmcr2_val); + mtspr(SPRN_MMCR2, mmcr2_val); return 0; } +#define NUM_CTRS 6 + /* Configures the global settings for the countes on all CPUs. */ static int fsl7450_reg_setup(struct op_counter_config *ctr, struct op_system_config *sys, @@ -101,13 +102,12 @@ static int fsl7450_reg_setup(struct op_counter_config *ctr, { int i; - num_pmcs = num_ctrs; /* Our counters count up, and "count" refers to * how much before the next interrupt, and we interrupt * on overflow. So we calculate the starting value * which will give us "count" until overflow. * Then we set the events on the enabled counters */ - for (i = 0; i < num_ctrs; ++i) + for (i = 0; i < NUM_CTRS; ++i) reset_value[i] = 0x80000000UL - ctr[i].count; /* Set events for Counters 1 & 2 */ @@ -123,10 +123,9 @@ static int fsl7450_reg_setup(struct op_counter_config *ctr, /* Set events for Counters 3-6 */ mmcr1_val = mmcr1_event3(ctr[2].event) - | mmcr1_event4(ctr[3].event); - if (num_ctrs > 4) - mmcr1_val |= mmcr1_event5(ctr[4].event) - | mmcr1_event6(ctr[5].event); + | mmcr1_event4(ctr[3].event) + | mmcr1_event5(ctr[4].event) + | mmcr1_event6(ctr[5].event); mmcr2_val = 0; @@ -140,7 +139,7 @@ static int fsl7450_start(struct op_counter_config *ctr) mtmsr(mfmsr() | MSR_PMM); - for (i = 0; i < num_pmcs; ++i) { + for (i = 0; i < NUM_CTRS; ++i) { if (ctr[i].enabled) classic_ctr_write(i, reset_value[i]); else @@ -185,7 +184,7 @@ static void fsl7450_handle_interrupt(struct pt_regs *regs, pc = mfspr(SPRN_SIAR); is_kernel = is_kernel_addr(pc); - for (i = 0; i < num_pmcs; ++i) { + for (i = 0; i < NUM_CTRS; ++i) { val = classic_ctr_read(i); if (val < 0) { if (oprofile_running && ctr[i].enabled) { diff --git a/trunk/arch/powerpc/platforms/44x/Kconfig b/trunk/arch/powerpc/platforms/44x/Kconfig index bf5c7ff2e6e5..3496bc05058e 100644 --- a/trunk/arch/powerpc/platforms/44x/Kconfig +++ b/trunk/arch/powerpc/platforms/44x/Kconfig @@ -118,17 +118,6 @@ config GLACIER help This option enables support for the AMCC PPC460GT evaluation board. -config REDWOOD - bool "Redwood" - depends on 44x - default n - select PPC44x_SIMPLE - select 460SX - select PCI - select PPC4xx_PCI_EXPRESS - help - This option enables support for the AMCC PPC460SX Redwood board. - config YOSEMITE bool "Yosemite" depends on 44x @@ -231,14 +220,6 @@ config 460EX select IBM_NEW_EMAC_EMAC4 select IBM_NEW_EMAC_TAH -config 460SX - bool - select PPC_FPU - select IBM_NEW_EMAC_EMAC4 - select IBM_NEW_EMAC_RGMII - select IBM_NEW_EMAC_ZMII - select IBM_NEW_EMAC_TAH - # 44x errata/workaround config symbols, selected by the CPU models above config IBM440EP_ERR42 bool diff --git a/trunk/arch/powerpc/platforms/44x/ppc44x_simple.c b/trunk/arch/powerpc/platforms/44x/ppc44x_simple.c index 5bcd441885e8..76fdc51dac8b 100644 --- a/trunk/arch/powerpc/platforms/44x/ppc44x_simple.c +++ b/trunk/arch/powerpc/platforms/44x/ppc44x_simple.c @@ -57,7 +57,6 @@ static char *board[] __initdata = { "ibm,ebony", "amcc,katmai", "amcc,rainier", - "amcc,redwood", "amcc,sequoia", "amcc,taishan", "amcc,yosemite" diff --git a/trunk/arch/powerpc/platforms/512x/Kconfig b/trunk/arch/powerpc/platforms/512x/Kconfig index 4dac9b0525a4..326852c78b8f 100644 --- a/trunk/arch/powerpc/platforms/512x/Kconfig +++ b/trunk/arch/powerpc/platforms/512x/Kconfig @@ -12,7 +12,7 @@ config PPC_MPC5121 config MPC5121_ADS bool "Freescale MPC5121E ADS" - depends on 6xx + depends on PPC_MULTIPLATFORM && PPC32 select DEFAULT_UIMAGE select PPC_MPC5121 select MPC5121_ADS_CPLD @@ -21,7 +21,7 @@ config MPC5121_ADS config MPC5121_GENERIC bool "Generic support for simple MPC5121 based boards" - depends on 6xx + depends on PPC_MULTIPLATFORM && PPC32 select DEFAULT_UIMAGE select PPC_MPC5121 help diff --git a/trunk/arch/powerpc/platforms/52xx/Kconfig b/trunk/arch/powerpc/platforms/52xx/Kconfig index 8b8e9560a315..696a5ee4962d 100644 --- a/trunk/arch/powerpc/platforms/52xx/Kconfig +++ b/trunk/arch/powerpc/platforms/52xx/Kconfig @@ -1,6 +1,6 @@ config PPC_MPC52xx bool "52xx-based boards" - depends on 6xx + depends on PPC_MULTIPLATFORM && PPC32 select PPC_CLOCK select PPC_PCI_CHOICE @@ -21,13 +21,7 @@ config PPC_MPC5200_SIMPLE and if there is a PCI bus node defined in the device tree. Boards that are compatible with this generic platform support - are: - intercontrol,digsy-mtc - phytec,pcm030 - phytec,pcm032 - promess,motionpro - schindler,cm5200 - tqc,tqm5200 + are: 'tqc,tqm5200', 'promess,motionpro', 'schindler,cm5200'. config PPC_EFIKA bool "bPlan Efika 5k2. MPC5200B based computer" @@ -41,11 +35,6 @@ config PPC_LITE5200 depends on PPC_MPC52xx select DEFAULT_UIMAGE -config PPC_MEDIA5200 - bool "Freescale Media5200 Eval Board" - depends on PPC_MPC52xx - select DEFAULT_UIMAGE - config PPC_MPC5200_BUGFIX bool "MPC5200 (L25R) bugfix support" depends on PPC_MPC52xx diff --git a/trunk/arch/powerpc/platforms/52xx/Makefile b/trunk/arch/powerpc/platforms/52xx/Makefile index bfd4f52cf3dd..b8a52062738a 100644 --- a/trunk/arch/powerpc/platforms/52xx/Makefile +++ b/trunk/arch/powerpc/platforms/52xx/Makefile @@ -1,13 +1,12 @@ # # Makefile for 52xx based boards # -obj-y += mpc52xx_pic.o mpc52xx_common.o mpc52xx_gpt.o +obj-y += mpc52xx_pic.o mpc52xx_common.o obj-$(CONFIG_PCI) += mpc52xx_pci.o obj-$(CONFIG_PPC_MPC5200_SIMPLE) += mpc5200_simple.o obj-$(CONFIG_PPC_EFIKA) += efika.o obj-$(CONFIG_PPC_LITE5200) += lite5200.o -obj-$(CONFIG_PPC_MEDIA5200) += media5200.o obj-$(CONFIG_PM) += mpc52xx_sleep.o mpc52xx_pm.o ifeq ($(CONFIG_PPC_LITE5200),y) diff --git a/trunk/arch/powerpc/platforms/52xx/media5200.c b/trunk/arch/powerpc/platforms/52xx/media5200.c deleted file mode 100644 index 68e4f1696d14..000000000000 --- a/trunk/arch/powerpc/platforms/52xx/media5200.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Support for 'media5200-platform' compatible boards. - * - * Copyright (C) 2008 Secret Lab Technologies Ltd. - * - * 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. - * - * Description: - * This code implements support for the Freescape Media5200 platform - * (built around the MPC5200 SoC). - * - * Notable characteristic of the Media5200 is the presence of an FPGA - * that has all external IRQ lines routed through it. This file implements - * a cascaded interrupt controller driver which attaches itself to the - * Virtual IRQ subsystem after the primary mpc5200 interrupt controller - * is initialized. - * - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include - -static struct of_device_id mpc5200_gpio_ids[] __initdata = { - { .compatible = "fsl,mpc5200-gpio", }, - { .compatible = "mpc5200-gpio", }, - {} -}; - -/* FPGA register set */ -#define MEDIA5200_IRQ_ENABLE (0x40c) -#define MEDIA5200_IRQ_STATUS (0x410) -#define MEDIA5200_NUM_IRQS (6) -#define MEDIA5200_IRQ_SHIFT (32 - MEDIA5200_NUM_IRQS) - -struct media5200_irq { - void __iomem *regs; - spinlock_t lock; - struct irq_host *irqhost; -}; -struct media5200_irq media5200_irq; - -static void media5200_irq_unmask(unsigned int virq) -{ - unsigned long flags; - u32 val; - - spin_lock_irqsave(&media5200_irq.lock, flags); - val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE); - val |= 1 << (MEDIA5200_IRQ_SHIFT + irq_map[virq].hwirq); - out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val); - spin_unlock_irqrestore(&media5200_irq.lock, flags); -} - -static void media5200_irq_mask(unsigned int virq) -{ - unsigned long flags; - u32 val; - - spin_lock_irqsave(&media5200_irq.lock, flags); - val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE); - val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irq_map[virq].hwirq)); - out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val); - spin_unlock_irqrestore(&media5200_irq.lock, flags); -} - -static struct irq_chip media5200_irq_chip = { - .typename = "Media5200 FPGA", - .unmask = media5200_irq_unmask, - .mask = media5200_irq_mask, - .mask_ack = media5200_irq_mask, -}; - -void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc) -{ - int sub_virq, val; - u32 status, enable; - - /* Mask off the cascaded IRQ */ - spin_lock(&desc->lock); - desc->chip->mask(virq); - spin_unlock(&desc->lock); - - /* Ask the FPGA for IRQ status. If 'val' is 0, then no irqs - * are pending. 'ffs()' is 1 based */ - status = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE); - enable = in_be32(media5200_irq.regs + MEDIA5200_IRQ_STATUS); - val = ffs((status & enable) >> MEDIA5200_IRQ_SHIFT); - if (val) { - sub_virq = irq_linear_revmap(media5200_irq.irqhost, val - 1); - /* pr_debug("%s: virq=%i s=%.8x e=%.8x hwirq=%i subvirq=%i\n", - * __func__, virq, status, enable, val - 1, sub_virq); - */ - generic_handle_irq(sub_virq); - } - - /* Processing done; can reenable the cascade now */ - spin_lock(&desc->lock); - desc->chip->ack(virq); - if (!(desc->status & IRQ_DISABLED)) - desc->chip->unmask(virq); - spin_unlock(&desc->lock); -} - -static int media5200_irq_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t hw) -{ - struct irq_desc *desc = get_irq_desc(virq); - - pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw); - set_irq_chip_data(virq, &media5200_irq); - set_irq_chip_and_handler(virq, &media5200_irq_chip, handle_level_irq); - set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); - desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); - desc->status |= IRQ_TYPE_LEVEL_LOW | IRQ_LEVEL; - - return 0; -} - -static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct, - u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, - unsigned int *out_flags) -{ - if (intsize != 2) - return -1; - - pr_debug("%s: bank=%i, number=%i\n", __func__, intspec[0], intspec[1]); - *out_hwirq = intspec[1]; - *out_flags = IRQ_TYPE_NONE; - return 0; -} - -static struct irq_host_ops media5200_irq_ops = { - .map = media5200_irq_map, - .xlate = media5200_irq_xlate, -}; - -/* - * Setup Media5200 IRQ mapping - */ -static void __init media5200_init_irq(void) -{ - struct device_node *fpga_np; - int cascade_virq; - - /* First setup the regular MPC5200 interrupt controller */ - mpc52xx_init_irq(); - - /* Now find the FPGA IRQ */ - fpga_np = of_find_compatible_node(NULL, NULL, "fsl,media5200-fpga"); - if (!fpga_np) - goto out; - pr_debug("%s: found fpga node: %s\n", __func__, fpga_np->full_name); - - media5200_irq.regs = of_iomap(fpga_np, 0); - if (!media5200_irq.regs) - goto out; - pr_debug("%s: mapped to %p\n", __func__, media5200_irq.regs); - - cascade_virq = irq_of_parse_and_map(fpga_np, 0); - if (!cascade_virq) - goto out; - pr_debug("%s: cascaded on virq=%i\n", __func__, cascade_virq); - - /* Disable all FPGA IRQs */ - out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, 0); - - spin_lock_init(&media5200_irq.lock); - - media5200_irq.irqhost = irq_alloc_host(fpga_np, IRQ_HOST_MAP_LINEAR, - MEDIA5200_NUM_IRQS, - &media5200_irq_ops, -1); - if (!media5200_irq.irqhost) - goto out; - pr_debug("%s: allocated irqhost\n", __func__); - - media5200_irq.irqhost->host_data = &media5200_irq; - - set_irq_data(cascade_virq, &media5200_irq); - set_irq_chained_handler(cascade_virq, media5200_irq_cascade); - - return; - - out: - pr_err("Could not find Media5200 FPGA; PCI interrupts will not work\n"); -} - -/* - * Setup the architecture - */ -static void __init media5200_setup_arch(void) -{ - - struct device_node *np; - struct mpc52xx_gpio __iomem *gpio; - u32 port_config; - - if (ppc_md.progress) - ppc_md.progress("media5200_setup_arch()", 0); - - /* Map important registers from the internal memory map */ - mpc52xx_map_common_devices(); - - /* Some mpc5200 & mpc5200b related configuration */ - mpc5200_setup_xlb_arbiter(); - - mpc52xx_setup_pci(); - - np = of_find_matching_node(NULL, mpc5200_gpio_ids); - gpio = of_iomap(np, 0); - of_node_put(np); - if (!gpio) { - printk(KERN_ERR "%s() failed. expect abnormal behavior\n", - __func__); - return; - } - - /* Set port config */ - port_config = in_be32(&gpio->port_config); - - port_config &= ~0x03000000; /* ATA CS is on csb_4/5 */ - port_config |= 0x01000000; - - out_be32(&gpio->port_config, port_config); - - /* Unmap zone */ - iounmap(gpio); - -} - -/* list of the supported boards */ -static char *board[] __initdata = { - "fsl,media5200", - NULL -}; - -/* - * Called very early, MMU is off, device-tree isn't unflattened - */ -static int __init media5200_probe(void) -{ - unsigned long node = of_get_flat_dt_root(); - int i = 0; - - while (board[i]) { - if (of_flat_dt_is_compatible(node, board[i])) - break; - i++; - } - - return (board[i] != NULL); -} - -define_machine(media5200_platform) { - .name = "media5200-platform", - .probe = media5200_probe, - .setup_arch = media5200_setup_arch, - .init = mpc52xx_declare_of_platform_devices, - .init_IRQ = media5200_init_irq, - .get_irq = mpc52xx_get_irq, - .restart = mpc52xx_restart, - .calibrate_decr = generic_calibrate_decr, -}; diff --git a/trunk/arch/powerpc/platforms/52xx/mpc5200_simple.c b/trunk/arch/powerpc/platforms/52xx/mpc5200_simple.c index c31e5b534f0a..a3bda0b9f1ff 100644 --- a/trunk/arch/powerpc/platforms/52xx/mpc5200_simple.c +++ b/trunk/arch/powerpc/platforms/52xx/mpc5200_simple.c @@ -50,10 +50,8 @@ static void __init mpc5200_simple_setup_arch(void) /* list of the supported boards */ static char *board[] __initdata = { - "intercontrol,digsy-mtc", - "phytec,pcm030", - "phytec,pcm032", "promess,motionpro", + "phytec,pcm030", "schindler,cm5200", "tqc,tqm5200", NULL diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c index 8e3dd5a0f228..98367a0255f3 100644 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c @@ -28,10 +28,9 @@ static struct of_device_id mpc52xx_xlb_ids[] __initdata = { static struct of_device_id mpc52xx_bus_ids[] __initdata = { { .compatible = "fsl,mpc5200-immr", }, { .compatible = "fsl,mpc5200b-immr", }, - { .compatible = "simple-bus", }, + { .compatible = "fsl,lpb", }, /* depreciated matches; shouldn't be used in new device trees */ - { .compatible = "fsl,lpb", }, { .type = "builtin", .compatible = "mpc5200", }, /* efika */ { .type = "soc", .compatible = "mpc5200", }, /* lite5200 */ {} @@ -205,43 +204,6 @@ int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv) } EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv); -/** - * mpc52xx_get_xtal_freq - Get SYS_XTAL_IN frequency for a device - * - * @node: device node - * - * Returns the frequency of the external oscillator clock connected - * to the SYS_XTAL_IN pin, or 0 if it cannot be determined. - */ -unsigned int mpc52xx_get_xtal_freq(struct device_node *node) -{ - u32 val; - unsigned int freq; - - if (!mpc52xx_cdm) - return 0; - - freq = mpc52xx_find_ipb_freq(node); - if (!freq) - return 0; - - if (in_8(&mpc52xx_cdm->ipb_clk_sel) & 0x1) - freq *= 2; - - val = in_be32(&mpc52xx_cdm->rstcfg); - if (val & (1 << 5)) - freq *= 8; - else - freq *= 4; - if (val & (1 << 6)) - freq /= 12; - else - freq /= 16; - - return freq; -} -EXPORT_SYMBOL(mpc52xx_get_xtal_freq); - /** * mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer */ diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index 2b8d8ef32e4e..07f89ae46d04 100644 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -354,6 +354,88 @@ static struct of_platform_driver mpc52xx_simple_gpiochip_driver = { .remove = mpc52xx_gpiochip_remove, }; +/* + * GPIO LIB API implementation for gpt GPIOs. + * + * Each gpt only has a single GPIO. + */ +static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct mpc52xx_gpt __iomem *regs = mm_gc->regs; + + return (in_be32(®s->status) & (1 << (31 - 23))) ? 1 : 0; +} + +static void +mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct mpc52xx_gpt __iomem *regs = mm_gc->regs; + + if (val) + out_be32(®s->mode, 0x34); + else + out_be32(®s->mode, 0x24); + + pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); +} + +static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct mpc52xx_gpt __iomem *regs = mm_gc->regs; + + out_be32(®s->mode, 0x04); + + return 0; +} + +static int +mpc52xx_gpt_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) +{ + mpc52xx_gpt_gpio_set(gc, gpio, val); + pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); + + return 0; +} + +static int __devinit mpc52xx_gpt_gpiochip_probe(struct of_device *ofdev, + const struct of_device_id *match) +{ + struct of_mm_gpio_chip *mmchip; + struct of_gpio_chip *chip; + + mmchip = kzalloc(sizeof(*mmchip), GFP_KERNEL); + if (!mmchip) + return -ENOMEM; + + chip = &mmchip->of_gc; + + chip->gpio_cells = 2; + chip->gc.ngpio = 1; + chip->gc.direction_input = mpc52xx_gpt_gpio_dir_in; + chip->gc.direction_output = mpc52xx_gpt_gpio_dir_out; + chip->gc.get = mpc52xx_gpt_gpio_get; + chip->gc.set = mpc52xx_gpt_gpio_set; + + return of_mm_gpiochip_add(ofdev->node, mmchip); +} + +static const struct of_device_id mpc52xx_gpt_gpiochip_match[] = { + { + .compatible = "fsl,mpc5200-gpt-gpio", + }, + {} +}; + +static struct of_platform_driver mpc52xx_gpt_gpiochip_driver = { + .name = "gpio_gpt", + .match_table = mpc52xx_gpt_gpiochip_match, + .probe = mpc52xx_gpt_gpiochip_probe, + .remove = mpc52xx_gpiochip_remove, +}; + static int __init mpc52xx_gpio_init(void) { if (of_register_platform_driver(&mpc52xx_wkup_gpiochip_driver)) @@ -362,6 +444,9 @@ static int __init mpc52xx_gpio_init(void) if (of_register_platform_driver(&mpc52xx_simple_gpiochip_driver)) printk(KERN_ERR "Unable to register simple GPIO driver\n"); + if (of_register_platform_driver(&mpc52xx_gpt_gpiochip_driver)) + printk(KERN_ERR "Unable to register gpt GPIO driver\n"); + return 0; } diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpt.c deleted file mode 100644 index bfbcd418e690..000000000000 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * MPC5200 General Purpose Timer device driver - * - * Copyright (c) 2009 Secret Lab Technologies Ltd. - * Copyright (c) 2008 Sascha Hauer , Pengutronix - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This file is a driver for the the General Purpose Timer (gpt) devices - * found on the MPC5200 SoC. Each timer has an IO pin which can be used - * for GPIO or can be used to raise interrupts. The timer function can - * be used independently from the IO pin, or it can be used to control - * output signals or measure input signals. - * - * This driver supports the GPIO and IRQ controller functions of the GPT - * device. Timer functions are not yet supported, nor is the watchdog - * timer. - * - * To use the GPIO function, the following two properties must be added - * to the device tree node for the gpt device (typically in the .dts file - * for the board): - * gpio-controller; - * #gpio-cells = < 2 >; - * This driver will register the GPIO pin if it finds the gpio-controller - * property in the device tree. - * - * To use the IRQ controller function, the following two properties must - * be added to the device tree node for the gpt device: - * interrupt-controller; - * #interrupt-cells = < 1 >; - * The IRQ controller binding only uses one cell to specify the interrupt, - * and the IRQ flags are encoded in the cell. A cell is not used to encode - * the IRQ number because the GPT only has a single IRQ source. For flags, - * a value of '1' means rising edge sensitive and '2' means falling edge. - * - * The GPIO and the IRQ controller functions can be used at the same time, - * but in this use case the IO line will only work as an input. Trying to - * use it as a GPIO output will not work. - * - * When using the GPIO line as an output, it can either be driven as normal - * IO, or it can be an Open Collector (OC) output. At the moment it is the - * responsibility of either the bootloader or the platform setup code to set - * the output mode. This driver does not change the output mode setting. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_DESCRIPTION("Freescale MPC52xx gpt driver"); -MODULE_AUTHOR("Sascha Hauer, Grant Likely"); -MODULE_LICENSE("GPL"); - -/** - * struct mpc52xx_gpt - Private data structure for MPC52xx GPT driver - * @dev: pointer to device structure - * @regs: virtual address of GPT registers - * @lock: spinlock to coordinate between different functions. - * @of_gc: of_gpio_chip instance structure; used when GPIO is enabled - * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported - */ -struct mpc52xx_gpt_priv { - struct device *dev; - struct mpc52xx_gpt __iomem *regs; - spinlock_t lock; - struct irq_host *irqhost; - -#if defined(CONFIG_GPIOLIB) - struct of_gpio_chip of_gc; -#endif -}; - -#define MPC52xx_GPT_MODE_MS_MASK (0x07) -#define MPC52xx_GPT_MODE_MS_IC (0x01) -#define MPC52xx_GPT_MODE_MS_OC (0x02) -#define MPC52xx_GPT_MODE_MS_PWM (0x03) -#define MPC52xx_GPT_MODE_MS_GPIO (0x04) - -#define MPC52xx_GPT_MODE_GPIO_MASK (0x30) -#define MPC52xx_GPT_MODE_GPIO_OUT_LOW (0x20) -#define MPC52xx_GPT_MODE_GPIO_OUT_HIGH (0x30) - -#define MPC52xx_GPT_MODE_IRQ_EN (0x0100) - -#define MPC52xx_GPT_MODE_ICT_MASK (0x030000) -#define MPC52xx_GPT_MODE_ICT_RISING (0x010000) -#define MPC52xx_GPT_MODE_ICT_FALLING (0x020000) -#define MPC52xx_GPT_MODE_ICT_TOGGLE (0x030000) - -#define MPC52xx_GPT_STATUS_IRQMASK (0x000f) - -/* --------------------------------------------------------------------- - * Cascaded interrupt controller hooks - */ - -static void mpc52xx_gpt_irq_unmask(unsigned int virq) -{ - struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq); - unsigned long flags; - - spin_lock_irqsave(&gpt->lock, flags); - setbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN); - spin_unlock_irqrestore(&gpt->lock, flags); -} - -static void mpc52xx_gpt_irq_mask(unsigned int virq) -{ - struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq); - unsigned long flags; - - spin_lock_irqsave(&gpt->lock, flags); - clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN); - spin_unlock_irqrestore(&gpt->lock, flags); -} - -static void mpc52xx_gpt_irq_ack(unsigned int virq) -{ - struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq); - - out_be32(&gpt->regs->status, MPC52xx_GPT_STATUS_IRQMASK); -} - -static int mpc52xx_gpt_irq_set_type(unsigned int virq, unsigned int flow_type) -{ - struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq); - unsigned long flags; - u32 reg; - - dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, virq, flow_type); - - spin_lock_irqsave(&gpt->lock, flags); - reg = in_be32(&gpt->regs->mode) & ~MPC52xx_GPT_MODE_ICT_MASK; - if (flow_type & IRQF_TRIGGER_RISING) - reg |= MPC52xx_GPT_MODE_ICT_RISING; - if (flow_type & IRQF_TRIGGER_FALLING) - reg |= MPC52xx_GPT_MODE_ICT_FALLING; - out_be32(&gpt->regs->mode, reg); - spin_unlock_irqrestore(&gpt->lock, flags); - - return 0; -} - -static struct irq_chip mpc52xx_gpt_irq_chip = { - .typename = "MPC52xx GPT", - .unmask = mpc52xx_gpt_irq_unmask, - .mask = mpc52xx_gpt_irq_mask, - .ack = mpc52xx_gpt_irq_ack, - .set_type = mpc52xx_gpt_irq_set_type, -}; - -void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc) -{ - struct mpc52xx_gpt_priv *gpt = get_irq_data(virq); - int sub_virq; - u32 status; - - status = in_be32(&gpt->regs->status) & MPC52xx_GPT_STATUS_IRQMASK; - if (status) { - sub_virq = irq_linear_revmap(gpt->irqhost, 0); - generic_handle_irq(sub_virq); - } -} - -static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t hw) -{ - struct mpc52xx_gpt_priv *gpt = h->host_data; - - dev_dbg(gpt->dev, "%s: h=%p, virq=%i\n", __func__, h, virq); - set_irq_chip_data(virq, gpt); - set_irq_chip_and_handler(virq, &mpc52xx_gpt_irq_chip, handle_edge_irq); - - return 0; -} - -static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct, - u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, - unsigned int *out_flags) -{ - struct mpc52xx_gpt_priv *gpt = h->host_data; - - dev_dbg(gpt->dev, "%s: flags=%i\n", __func__, intspec[0]); - - if ((intsize < 1) || (intspec[0] < 1) || (intspec[0] > 3)) { - dev_err(gpt->dev, "bad irq specifier in %s\n", ct->full_name); - return -EINVAL; - } - - *out_hwirq = 0; /* The GPT only has 1 IRQ line */ - *out_flags = intspec[0]; - - return 0; -} - -static struct irq_host_ops mpc52xx_gpt_irq_ops = { - .map = mpc52xx_gpt_irq_map, - .xlate = mpc52xx_gpt_irq_xlate, -}; - -static void -mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) -{ - int cascade_virq; - unsigned long flags; - - /* Only setup cascaded IRQ if device tree claims the GPT is - * an interrupt controller */ - if (!of_find_property(node, "interrupt-controller", NULL)) - return; - - cascade_virq = irq_of_parse_and_map(node, 0); - - gpt->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 1, - &mpc52xx_gpt_irq_ops, -1); - if (!gpt->irqhost) { - dev_err(gpt->dev, "irq_alloc_host() failed\n"); - return; - } - - gpt->irqhost->host_data = gpt; - - set_irq_data(cascade_virq, gpt); - set_irq_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade); - - /* Set to Input Capture mode */ - spin_lock_irqsave(&gpt->lock, flags); - clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK, - MPC52xx_GPT_MODE_MS_IC); - spin_unlock_irqrestore(&gpt->lock, flags); - - dev_dbg(gpt->dev, "%s() complete. virq=%i\n", __func__, cascade_virq); -} - - -/* --------------------------------------------------------------------- - * GPIOLIB hooks - */ -#if defined(CONFIG_GPIOLIB) -static inline struct mpc52xx_gpt_priv *gc_to_mpc52xx_gpt(struct gpio_chip *gc) -{ - return container_of(to_of_gpio_chip(gc), struct mpc52xx_gpt_priv,of_gc); -} - -static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio) -{ - struct mpc52xx_gpt_priv *gpt = gc_to_mpc52xx_gpt(gc); - - return (in_be32(&gpt->regs->status) >> 8) & 1; -} - -static void -mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int v) -{ - struct mpc52xx_gpt_priv *gpt = gc_to_mpc52xx_gpt(gc); - unsigned long flags; - u32 r; - - dev_dbg(gpt->dev, "%s: gpio:%d v:%d\n", __func__, gpio, v); - r = v ? MPC52xx_GPT_MODE_GPIO_OUT_HIGH : MPC52xx_GPT_MODE_GPIO_OUT_LOW; - - spin_lock_irqsave(&gpt->lock, flags); - clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK, r); - spin_unlock_irqrestore(&gpt->lock, flags); -} - -static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) -{ - struct mpc52xx_gpt_priv *gpt = gc_to_mpc52xx_gpt(gc); - unsigned long flags; - - dev_dbg(gpt->dev, "%s: gpio:%d\n", __func__, gpio); - - spin_lock_irqsave(&gpt->lock, flags); - clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK); - spin_unlock_irqrestore(&gpt->lock, flags); - - return 0; -} - -static int -mpc52xx_gpt_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) -{ - mpc52xx_gpt_gpio_set(gc, gpio, val); - return 0; -} - -static void -mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) -{ - int rc; - - /* Only setup GPIO if the device tree claims the GPT is - * a GPIO controller */ - if (!of_find_property(node, "gpio-controller", NULL)) - return; - - gpt->of_gc.gc.label = kstrdup(node->full_name, GFP_KERNEL); - if (!gpt->of_gc.gc.label) { - dev_err(gpt->dev, "out of memory\n"); - return; - } - - gpt->of_gc.gpio_cells = 2; - gpt->of_gc.gc.ngpio = 1; - gpt->of_gc.gc.direction_input = mpc52xx_gpt_gpio_dir_in; - gpt->of_gc.gc.direction_output = mpc52xx_gpt_gpio_dir_out; - gpt->of_gc.gc.get = mpc52xx_gpt_gpio_get; - gpt->of_gc.gc.set = mpc52xx_gpt_gpio_set; - gpt->of_gc.gc.base = -1; - gpt->of_gc.xlate = of_gpio_simple_xlate; - node->data = &gpt->of_gc; - of_node_get(node); - - /* Setup external pin in GPIO mode */ - clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK, - MPC52xx_GPT_MODE_MS_GPIO); - - rc = gpiochip_add(&gpt->of_gc.gc); - if (rc) - dev_err(gpt->dev, "gpiochip_add() failed; rc=%i\n", rc); - - dev_dbg(gpt->dev, "%s() complete.\n", __func__); -} -#else /* defined(CONFIG_GPIOLIB) */ -static void -mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *p, struct device_node *np) { } -#endif /* defined(CONFIG_GPIOLIB) */ - -/* --------------------------------------------------------------------- - * of_platform bus binding code - */ -static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, - const struct of_device_id *match) -{ - struct mpc52xx_gpt_priv *gpt; - - gpt = kzalloc(sizeof *gpt, GFP_KERNEL); - if (!gpt) - return -ENOMEM; - - spin_lock_init(&gpt->lock); - gpt->dev = &ofdev->dev; - gpt->regs = of_iomap(ofdev->node, 0); - if (!gpt->regs) { - kfree(gpt); - return -ENOMEM; - } - - dev_set_drvdata(&ofdev->dev, gpt); - - mpc52xx_gpt_gpio_setup(gpt, ofdev->node); - mpc52xx_gpt_irq_setup(gpt, ofdev->node); - - return 0; -} - -static int mpc52xx_gpt_remove(struct of_device *ofdev) -{ - return -EBUSY; -} - -static const struct of_device_id mpc52xx_gpt_match[] = { - { .compatible = "fsl,mpc5200-gpt", }, - - /* Depreciated compatible values; don't use for new dts files */ - { .compatible = "fsl,mpc5200-gpt-gpio", }, - { .compatible = "mpc5200-gpt", }, - {} -}; - -static struct of_platform_driver mpc52xx_gpt_driver = { - .name = "mpc52xx-gpt", - .match_table = mpc52xx_gpt_match, - .probe = mpc52xx_gpt_probe, - .remove = mpc52xx_gpt_remove, -}; - -static int __init mpc52xx_gpt_init(void) -{ - if (of_register_platform_driver(&mpc52xx_gpt_driver)) - pr_err("error registering MPC52xx GPT driver\n"); - - return 0; -} - -/* Make sure GPIOs and IRQs get set up before anyone tries to use them */ -subsys_initcall(mpc52xx_gpt_init); diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_pic.c index 480f806fd0a9..0a093f03c758 100644 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/trunk/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -163,6 +163,8 @@ static void mpc52xx_extirq_mask(unsigned int virq) irq = irq_map[virq].hwirq; l2irq = irq & MPC52xx_IRQ_L2_MASK; + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + io_be_clrbit(&intr->ctrl, 11 - l2irq); } @@ -174,6 +176,8 @@ static void mpc52xx_extirq_unmask(unsigned int virq) irq = irq_map[virq].hwirq; l2irq = irq & MPC52xx_IRQ_L2_MASK; + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + io_be_setbit(&intr->ctrl, 11 - l2irq); } @@ -185,15 +189,17 @@ static void mpc52xx_extirq_ack(unsigned int virq) irq = irq_map[virq].hwirq; l2irq = irq & MPC52xx_IRQ_L2_MASK; + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + io_be_setbit(&intr->ctrl, 27-l2irq); } static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type) { + struct irq_desc *desc = get_irq_desc(virq); u32 ctrl_reg, type; int irq; int l2irq; - void *handler = handle_level_irq; irq = irq_map[virq].hwirq; l2irq = irq & MPC52xx_IRQ_L2_MASK; @@ -201,21 +207,32 @@ static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type) pr_debug("%s: irq=%x. l2=%d flow_type=%d\n", __func__, irq, l2irq, flow_type); switch (flow_type) { - case IRQF_TRIGGER_HIGH: type = 0; break; - case IRQF_TRIGGER_RISING: type = 1; handler = handle_edge_irq; break; - case IRQF_TRIGGER_FALLING: type = 2; handler = handle_edge_irq; break; - case IRQF_TRIGGER_LOW: type = 3; break; + case IRQF_TRIGGER_HIGH: + type = 0; + break; + case IRQF_TRIGGER_RISING: + type = 1; + break; + case IRQF_TRIGGER_FALLING: + type = 2; + break; + case IRQF_TRIGGER_LOW: + type = 3; + break; default: type = 0; } + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; + if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) + desc->status |= IRQ_LEVEL; + ctrl_reg = in_be32(&intr->ctrl); ctrl_reg &= ~(0x3 << (22 - (l2irq * 2))); ctrl_reg |= (type << (22 - (l2irq * 2))); out_be32(&intr->ctrl, ctrl_reg); - __set_irq_handler_unlocked(virq, handler); - return 0; } @@ -230,11 +247,6 @@ static struct irq_chip mpc52xx_extirq_irqchip = { /* * Main interrupt irq_chip */ -static int mpc52xx_null_set_type(unsigned int virq, unsigned int flow_type) -{ - return 0; /* Do nothing so that the sense mask will get updated */ -} - static void mpc52xx_main_mask(unsigned int virq) { int irq; @@ -243,6 +255,8 @@ static void mpc52xx_main_mask(unsigned int virq) irq = irq_map[virq].hwirq; l2irq = irq & MPC52xx_IRQ_L2_MASK; + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + io_be_setbit(&intr->main_mask, 16 - l2irq); } @@ -254,6 +268,8 @@ static void mpc52xx_main_unmask(unsigned int virq) irq = irq_map[virq].hwirq; l2irq = irq & MPC52xx_IRQ_L2_MASK; + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + io_be_clrbit(&intr->main_mask, 16 - l2irq); } @@ -262,7 +278,6 @@ static struct irq_chip mpc52xx_main_irqchip = { .mask = mpc52xx_main_mask, .mask_ack = mpc52xx_main_mask, .unmask = mpc52xx_main_unmask, - .set_type = mpc52xx_null_set_type, }; /* @@ -276,6 +291,8 @@ static void mpc52xx_periph_mask(unsigned int virq) irq = irq_map[virq].hwirq; l2irq = irq & MPC52xx_IRQ_L2_MASK; + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + io_be_setbit(&intr->per_mask, 31 - l2irq); } @@ -287,6 +304,8 @@ static void mpc52xx_periph_unmask(unsigned int virq) irq = irq_map[virq].hwirq; l2irq = irq & MPC52xx_IRQ_L2_MASK; + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + io_be_clrbit(&intr->per_mask, 31 - l2irq); } @@ -295,7 +314,6 @@ static struct irq_chip mpc52xx_periph_irqchip = { .mask = mpc52xx_periph_mask, .mask_ack = mpc52xx_periph_mask, .unmask = mpc52xx_periph_unmask, - .set_type = mpc52xx_null_set_type, }; /* @@ -309,6 +327,8 @@ static void mpc52xx_sdma_mask(unsigned int virq) irq = irq_map[virq].hwirq; l2irq = irq & MPC52xx_IRQ_L2_MASK; + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + io_be_setbit(&sdma->IntMask, l2irq); } @@ -320,6 +340,8 @@ static void mpc52xx_sdma_unmask(unsigned int virq) irq = irq_map[virq].hwirq; l2irq = irq & MPC52xx_IRQ_L2_MASK; + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + io_be_clrbit(&sdma->IntMask, l2irq); } @@ -331,6 +353,8 @@ static void mpc52xx_sdma_ack(unsigned int virq) irq = irq_map[virq].hwirq; l2irq = irq & MPC52xx_IRQ_L2_MASK; + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + out_be32(&sdma->IntPend, 1 << l2irq); } @@ -339,18 +363,8 @@ static struct irq_chip mpc52xx_sdma_irqchip = { .mask = mpc52xx_sdma_mask, .unmask = mpc52xx_sdma_unmask, .ack = mpc52xx_sdma_ack, - .set_type = mpc52xx_null_set_type, }; -/** - * mpc52xx_is_extirq - Returns true if hwirq number is for an external IRQ - */ -static int mpc52xx_is_extirq(int l1, int l2) -{ - return ((l1 == 0) && (l2 == 0)) || - ((l1 == 1) && (l2 >= 1) && (l2 <= 3)); -} - /** * mpc52xx_irqhost_xlate - translate virq# from device tree interrupts property */ @@ -369,22 +383,37 @@ static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct, intrvect_l1 = (int)intspec[0]; intrvect_l2 = (int)intspec[1]; - intrvect_type = (int)intspec[2] & 0x3; + intrvect_type = (int)intspec[2]; intrvect_linux = (intrvect_l1 << MPC52xx_IRQ_L1_OFFSET) & MPC52xx_IRQ_L1_MASK; intrvect_linux |= intrvect_l2 & MPC52xx_IRQ_L2_MASK; - *out_hwirq = intrvect_linux; - *out_flags = IRQ_TYPE_LEVEL_LOW; - if (mpc52xx_is_extirq(intrvect_l1, intrvect_l2)) - *out_flags = mpc52xx_map_senses[intrvect_type]; - pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1, intrvect_l2); + + *out_hwirq = intrvect_linux; + *out_flags = mpc52xx_map_senses[intrvect_type]; + return 0; } +/** + * mpc52xx_irqx_gettype - determine the IRQ sense type (level/edge) + * + * Only external IRQs need this. + */ +static int mpc52xx_irqx_gettype(int irq) +{ + int type; + u32 ctrl_reg; + + ctrl_reg = in_be32(&intr->ctrl); + type = (ctrl_reg >> (22 - irq * 2)) & 0x3; + + return mpc52xx_map_senses[type]; +} + /** * mpc52xx_irqhost_map - Hook to map from virq to an irq_chip structure */ @@ -393,46 +422,68 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq, { int l1irq; int l2irq; - struct irq_chip *irqchip; - void *hndlr; + struct irq_chip *good_irqchip; + void *good_handle; int type; - u32 reg; l1irq = (irq & MPC52xx_IRQ_L1_MASK) >> MPC52xx_IRQ_L1_OFFSET; l2irq = irq & MPC52xx_IRQ_L2_MASK; /* - * External IRQs are handled differently by the hardware so they are - * handled by a dedicated irq_chip structure. + * Most of ours IRQs will be level low + * Only external IRQs on some platform may be others */ - if (mpc52xx_is_extirq(l1irq, l2irq)) { - reg = in_be32(&intr->ctrl); - type = mpc52xx_map_senses[(reg >> (22 - l2irq * 2)) & 0x3]; - if ((type == IRQ_TYPE_EDGE_FALLING) || - (type == IRQ_TYPE_EDGE_RISING)) - hndlr = handle_edge_irq; - else - hndlr = handle_level_irq; - - set_irq_chip_and_handler(virq, &mpc52xx_extirq_irqchip, hndlr); - pr_debug("%s: External IRQ%i virq=%x, hw=%x. type=%x\n", - __func__, l2irq, virq, (int)irq, type); - return 0; - } + type = IRQ_TYPE_LEVEL_LOW; - /* It is an internal SOC irq. Choose the correct irq_chip */ switch (l1irq) { - case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break; - case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break; - case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break; + case MPC52xx_IRQ_L1_CRIT: + pr_debug("%s: Critical. l2=%x\n", __func__, l2irq); + + BUG_ON(l2irq != 0); + + type = mpc52xx_irqx_gettype(l2irq); + good_irqchip = &mpc52xx_extirq_irqchip; + break; + + case MPC52xx_IRQ_L1_MAIN: + pr_debug("%s: Main IRQ[1-3] l2=%x\n", __func__, l2irq); + + if ((l2irq >= 1) && (l2irq <= 3)) { + type = mpc52xx_irqx_gettype(l2irq); + good_irqchip = &mpc52xx_extirq_irqchip; + } else { + good_irqchip = &mpc52xx_main_irqchip; + } + break; + + case MPC52xx_IRQ_L1_PERP: + pr_debug("%s: Peripherals. l2=%x\n", __func__, l2irq); + good_irqchip = &mpc52xx_periph_irqchip; + break; + + case MPC52xx_IRQ_L1_SDMA: + pr_debug("%s: SDMA. l2=%x\n", __func__, l2irq); + good_irqchip = &mpc52xx_sdma_irqchip; + break; + default: - pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n", - __func__, virq, l1irq, l2irq); + pr_err("%s: invalid virq requested (0x%x)\n", __func__, virq); return -EINVAL; } - set_irq_chip_and_handler(virq, irqchip, handle_level_irq); - pr_debug("%s: virq=%x, l1=%i, l2=%i\n", __func__, virq, l1irq, l2irq); + switch (type) { + case IRQ_TYPE_EDGE_FALLING: + case IRQ_TYPE_EDGE_RISING: + good_handle = handle_edge_irq; + break; + default: + good_handle = handle_level_irq; + } + + set_irq_chip_and_handler(virq, good_irqchip, good_handle); + + pr_debug("%s: virq=%x, hw=%x. type=%x\n", __func__, virq, + (int)irq, type); return 0; } @@ -471,8 +522,6 @@ void __init mpc52xx_init_irq(void) panic(__FILE__ ": find_and_map failed on 'mpc5200-bestcomm'. " "Check node !"); - pr_debug("MPC5200 IRQ controller mapped to 0x%p\n", intr); - /* Disable all interrupt sources. */ out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */ out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */ @@ -564,5 +613,8 @@ unsigned int mpc52xx_get_irq(void) } } + pr_debug("%s: irq=%x. virq=%d\n", __func__, irq, + irq_linear_revmap(mpc52xx_irqhost, irq)); + return irq_linear_revmap(mpc52xx_irqhost, irq); } diff --git a/trunk/arch/powerpc/platforms/82xx/Kconfig b/trunk/arch/powerpc/platforms/82xx/Kconfig index 7c7df4003820..30f008b2f92e 100644 --- a/trunk/arch/powerpc/platforms/82xx/Kconfig +++ b/trunk/arch/powerpc/platforms/82xx/Kconfig @@ -1,6 +1,6 @@ menuconfig PPC_82xx bool "82xx-based boards (PQ II)" - depends on 6xx + depends on 6xx && PPC_MULTIPLATFORM if PPC_82xx diff --git a/trunk/arch/powerpc/platforms/83xx/Kconfig b/trunk/arch/powerpc/platforms/83xx/Kconfig index 437d29a59d72..83c664afc897 100644 --- a/trunk/arch/powerpc/platforms/83xx/Kconfig +++ b/trunk/arch/powerpc/platforms/83xx/Kconfig @@ -1,6 +1,6 @@ menuconfig PPC_83xx bool "83xx-based boards" - depends on 6xx + depends on 6xx && PPC_MULTIPLATFORM select PPC_UDBG_16550 select PPC_PCI_CHOICE select FSL_PCI if PCI diff --git a/trunk/arch/powerpc/platforms/83xx/asp834x.c b/trunk/arch/powerpc/platforms/83xx/asp834x.c index aa0d84d22585..bb30d67ad0a2 100644 --- a/trunk/arch/powerpc/platforms/83xx/asp834x.c +++ b/trunk/arch/powerpc/platforms/83xx/asp834x.c @@ -58,7 +58,6 @@ static struct __initdata of_device_id asp8347_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/83xx/mpc831x_rdb.c b/trunk/arch/powerpc/platforms/83xx/mpc831x_rdb.c index 0b4f883b20eb..91a2c80b9d72 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc831x_rdb.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc831x_rdb.c @@ -38,8 +38,6 @@ static void __init mpc831x_rdb_setup_arch(void) #ifdef CONFIG_PCI for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") mpc83xx_add_bridge(np); - for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") - mpc83xx_add_bridge(np); #endif mpc831x_usb_cfg(); } diff --git a/trunk/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/trunk/arch/powerpc/platforms/83xx/mpc832x_rdb.c index 567ded7c3b9b..2a1295f19832 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -40,116 +39,16 @@ #endif #ifdef CONFIG_QUICC_ENGINE -static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk, - struct spi_board_info *board_infos, - unsigned int num_board_infos, - void (*cs_control)(struct spi_device *dev, - bool on)) +static void mpc83xx_spi_activate_cs(u8 cs, u8 polarity) { - struct device_node *np; - unsigned int i = 0; - - for_each_compatible_node(np, type, compatible) { - int ret; - unsigned int j; - const void *prop; - struct resource res[2]; - struct platform_device *pdev; - struct fsl_spi_platform_data pdata = { - .cs_control = cs_control, - }; - - memset(res, 0, sizeof(res)); - - pdata.sysclk = sysclk; - - prop = of_get_property(np, "reg", NULL); - if (!prop) - goto err; - pdata.bus_num = *(u32 *)prop; - - prop = of_get_property(np, "cell-index", NULL); - if (prop) - i = *(u32 *)prop; - - prop = of_get_property(np, "mode", NULL); - if (prop && !strcmp(prop, "cpu-qe")) - pdata.qe_mode = 1; - - for (j = 0; j < num_board_infos; j++) { - if (board_infos[j].bus_num == pdata.bus_num) - pdata.max_chipselect++; - } - - if (!pdata.max_chipselect) - continue; - - ret = of_address_to_resource(np, 0, &res[0]); - if (ret) - goto err; - - ret = of_irq_to_resource(np, 0, &res[1]); - if (ret == NO_IRQ) - goto err; - - pdev = platform_device_alloc("mpc83xx_spi", i); - if (!pdev) - goto err; - - ret = platform_device_add_data(pdev, &pdata, sizeof(pdata)); - if (ret) - goto unreg; - - ret = platform_device_add_resources(pdev, res, - ARRAY_SIZE(res)); - if (ret) - goto unreg; - - ret = platform_device_add(pdev); - if (ret) - goto unreg; - - goto next; -unreg: - platform_device_del(pdev); -err: - pr_err("%s: registration failed\n", np->full_name); -next: - i++; - } - - return i; + pr_debug("%s %d %d\n", __func__, cs, polarity); + par_io_data_set(3, 13, polarity); } -static int __init fsl_spi_init(struct spi_board_info *board_infos, - unsigned int num_board_infos, - void (*cs_control)(struct spi_device *spi, - bool on)) +static void mpc83xx_spi_deactivate_cs(u8 cs, u8 polarity) { - u32 sysclk = -1; - int ret; - - /* SPI controller is either clocked from QE or SoC clock */ - sysclk = get_brgfreq(); - if (sysclk == -1) { - sysclk = fsl_get_sys_freq(); - if (sysclk == -1) - return -ENODEV; - } - - ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos, - num_board_infos, cs_control); - if (!ret) - of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos, - num_board_infos, cs_control); - - return spi_register_board_info(board_infos, num_board_infos); -} - -static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on) -{ - pr_debug("%s %d %d\n", __func__, spi->chip_select, on); - par_io_data_set(3, 13, on); + pr_debug("%s %d %d\n", __func__, cs, polarity); + par_io_data_set(3, 13, !polarity); } static struct mmc_spi_platform_data mpc832x_mmc_pdata = { @@ -175,13 +74,9 @@ static int __init mpc832x_spi_init(void) par_io_config_pin(3, 14, 2, 0, 0, 0); /* SD_INSERT, I */ par_io_config_pin(3, 15, 2, 0, 0, 0); /* SD_PROTECT,I */ - /* - * Don't bother with legacy stuff when device tree contains - * mmc-spi-slot node. - */ - if (of_find_compatible_node(NULL, NULL, "mmc-spi-slot")) - return 0; - return fsl_spi_init(&mpc832x_spi_boardinfo, 1, mpc83xx_spi_cs_control); + return fsl_spi_init(&mpc832x_spi_boardinfo, 1, + mpc83xx_spi_activate_cs, + mpc83xx_spi_deactivate_cs); } machine_device_initcall(mpc832x_rdb, mpc832x_spi_init); #endif /* CONFIG_QUICC_ENGINE */ diff --git a/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c b/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c index 81e44fa1c644..76092d37c7d9 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c @@ -42,7 +42,6 @@ static struct of_device_id __initdata mpc834x_itx_ids[] = { { .compatible = "fsl,pq2pro-localbus", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/83xx/mpc834x_mds.c b/trunk/arch/powerpc/platforms/83xx/mpc834x_mds.c index d0a634b056ca..fc3f2ed1f3e9 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc834x_mds.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc834x_mds.c @@ -112,7 +112,6 @@ static struct of_device_id mpc834x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/83xx/mpc837x_mds.c b/trunk/arch/powerpc/platforms/83xx/mpc837x_mds.c index 51df7e754698..530ef990ca7c 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc837x_mds.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc837x_mds.c @@ -84,10 +84,14 @@ static void __init mpc837x_mds_setup_arch(void) ppc_md.progress("mpc837x_mds_setup_arch()", 0); #ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") - mpc83xx_add_bridge(np); - for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") + for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") { + if (!of_device_is_available(np)) { + pr_warning("%s: disabled by the firmware.\n", + np->full_name); + continue; + } mpc83xx_add_bridge(np); + } #endif mpc837xmds_usb_cfg(); } @@ -96,7 +100,6 @@ static struct of_device_id mpc837x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/trunk/arch/powerpc/platforms/83xx/mpc837x_rdb.c index 76f3b32a155e..1d096545322b 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc837x_rdb.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc837x_rdb.c @@ -38,8 +38,6 @@ static void __init mpc837x_rdb_setup_arch(void) #ifdef CONFIG_PCI for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") mpc83xx_add_bridge(np); - for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") - mpc83xx_add_bridge(np); #endif mpc837x_usb_cfg(); } @@ -48,7 +46,6 @@ static struct of_device_id mpc837x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/83xx/sbc834x.c b/trunk/arch/powerpc/platforms/83xx/sbc834x.c index 49023dbe1576..156c4e218009 100644 --- a/trunk/arch/powerpc/platforms/83xx/sbc834x.c +++ b/trunk/arch/powerpc/platforms/83xx/sbc834x.c @@ -84,7 +84,6 @@ static struct __initdata of_device_id sbc834x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/83xx/usb.c b/trunk/arch/powerpc/platforms/83xx/usb.c index 11e1fac17c7f..cc99c280aad9 100644 --- a/trunk/arch/powerpc/platforms/83xx/usb.c +++ b/trunk/arch/powerpc/platforms/83xx/usb.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -211,7 +210,7 @@ int mpc837x_usb_cfg(void) int ret = 0; np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr"); - if (!np || !of_device_is_available(np)) + if (!np) return -ENODEV; prop = of_get_property(np, "phy_type", NULL); diff --git a/trunk/arch/powerpc/platforms/85xx/Kconfig b/trunk/arch/powerpc/platforms/85xx/Kconfig index 7f066adc068c..b79dc710ed34 100644 --- a/trunk/arch/powerpc/platforms/85xx/Kconfig +++ b/trunk/arch/powerpc/platforms/85xx/Kconfig @@ -51,12 +51,6 @@ config MPC85xx_DS help This option enables support for the MPC85xx DS (MPC8544 DS) board -config SOCRATES - bool "Socrates" - select DEFAULT_UIMAGE - help - This option enables support for the Socrates board. - config KSI8560 bool "Emerson KSI8560" select DEFAULT_UIMAGE diff --git a/trunk/arch/powerpc/platforms/85xx/Makefile b/trunk/arch/powerpc/platforms/85xx/Makefile index a857b35b9828..f0798c09980f 100644 --- a/trunk/arch/powerpc/platforms/85xx/Makefile +++ b/trunk/arch/powerpc/platforms/85xx/Makefile @@ -13,5 +13,4 @@ obj-$(CONFIG_STX_GP3) += stx_gp3.o obj-$(CONFIG_TQM85xx) += tqm85xx.o obj-$(CONFIG_SBC8560) += sbc8560.o obj-$(CONFIG_SBC8548) += sbc8548.o -obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o obj-$(CONFIG_KSI8560) += ksi8560.o diff --git a/trunk/arch/powerpc/platforms/85xx/ksi8560.c b/trunk/arch/powerpc/platforms/85xx/ksi8560.c index f4d36b5a2e00..81cee7bbf2d2 100644 --- a/trunk/arch/powerpc/platforms/85xx/ksi8560.c +++ b/trunk/arch/powerpc/platforms/85xx/ksi8560.c @@ -106,6 +106,8 @@ static void __init ksi8560_pic_init(void) cpm2_pic_init(np); of_node_put(np); set_irq_chained_handler(irq, cpm2_cascade); + + setup_irq(0, NULL); #endif } @@ -219,7 +221,6 @@ static struct of_device_id __initdata of_bus_ids[] = { { .type = "simple-bus", }, { .name = "cpm", }, { .name = "localbus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/mpc8536_ds.c b/trunk/arch/powerpc/platforms/85xx/mpc8536_ds.c index 63efca20d7bd..1bf5aefdfeb1 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc8536_ds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc8536_ds.c @@ -92,7 +92,6 @@ static struct of_device_id __initdata mpc8536_ds_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 9438a892afc4..21f009023e26 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c @@ -226,7 +226,6 @@ static struct of_device_id __initdata of_bus_ids[] = { { .name = "cpm", }, { .name = "localbus", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 458d91fba91d..aeb6a5bc5522 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -179,6 +179,7 @@ static irqreturn_t mpc85xx_8259_cascade_action(int irq, void *dev_id) static struct irqaction mpc85xxcds_8259_irqaction = { .handler = mpc85xx_8259_cascade_action, .flags = IRQF_SHARED, + .mask = CPU_MASK_NONE, .name = "8259 cascade", }; #endif /* PPC_I8259 */ @@ -335,7 +336,6 @@ static struct of_device_id __initdata of_bus_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ds.c index de66de7a9ca2..7326d904202c 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ds.c @@ -204,7 +204,6 @@ static struct of_device_id __initdata mpc85xxds_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 7dd029034aec..658a36fab3ab 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -265,7 +265,6 @@ static struct of_device_id mpc85xx_ids[] = { { .compatible = "simple-bus", }, { .type = "qe", }, { .compatible = "fsl,qe", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/sbc8548.c b/trunk/arch/powerpc/platforms/85xx/sbc8548.c index ecdd8c09e4ed..7ec77ce12dad 100644 --- a/trunk/arch/powerpc/platforms/85xx/sbc8548.c +++ b/trunk/arch/powerpc/platforms/85xx/sbc8548.c @@ -154,7 +154,6 @@ static struct of_device_id __initdata of_bus_ids[] = { { .name = "soc", }, { .type = "soc", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/sbc8560.c b/trunk/arch/powerpc/platforms/85xx/sbc8560.c index cc27807a8b64..472f254a19d2 100644 --- a/trunk/arch/powerpc/platforms/85xx/sbc8560.c +++ b/trunk/arch/powerpc/platforms/85xx/sbc8560.c @@ -213,7 +213,6 @@ static struct of_device_id __initdata of_bus_ids[] = { { .name = "cpm", }, { .name = "localbus", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/smp.c b/trunk/arch/powerpc/platforms/85xx/smp.c index cc0b0db8a6f3..79a0df17078b 100644 --- a/trunk/arch/powerpc/platforms/85xx/smp.c +++ b/trunk/arch/powerpc/platforms/85xx/smp.c @@ -21,7 +21,6 @@ #include #include #include -#include #include @@ -81,8 +80,10 @@ smp_85xx_kick_cpu(int nr) } static void __init -smp_85xx_basic_setup(int cpu_nr) +smp_85xx_setup_cpu(int cpu_nr) { + mpic_setup_this_cpu(); + /* Clear any pending timer interrupts */ mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); @@ -90,43 +91,15 @@ smp_85xx_basic_setup(int cpu_nr) mtspr(SPRN_TCR, TCR_DIE); } -static void __init -smp_85xx_setup_cpu(int cpu_nr) -{ - mpic_setup_this_cpu(); - - smp_85xx_basic_setup(cpu_nr); -} - struct smp_ops_t smp_85xx_ops = { + .message_pass = smp_mpic_message_pass, + .probe = smp_mpic_probe, .kick_cpu = smp_85xx_kick_cpu, + .setup_cpu = smp_85xx_setup_cpu, }; -static int __init smp_dummy_probe(void) +void __init +mpc85xx_smp_init(void) { - return NR_CPUS; -} - -void __init mpc85xx_smp_init(void) -{ - struct device_node *np; - - smp_85xx_ops.message_pass = NULL; - - np = of_find_node_by_type(NULL, "open-pic"); - if (np) { - smp_85xx_ops.probe = smp_mpic_probe; - smp_85xx_ops.setup_cpu = smp_85xx_setup_cpu; - smp_85xx_ops.message_pass = smp_mpic_message_pass; - } else { - smp_85xx_ops.probe = smp_dummy_probe; - smp_85xx_ops.setup_cpu = smp_85xx_basic_setup; - } - - if (cpu_has_feature(CPU_FTR_DBELL)) - smp_85xx_ops.message_pass = smp_dbell_message_pass; - - BUG_ON(!smp_85xx_ops.message_pass); - smp_ops = &smp_85xx_ops; } diff --git a/trunk/arch/powerpc/platforms/85xx/socrates.c b/trunk/arch/powerpc/platforms/85xx/socrates.c deleted file mode 100644 index d0e8443b12c6..000000000000 --- a/trunk/arch/powerpc/platforms/85xx/socrates.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2008 Emcraft Systems - * Sergei Poselenov - * - * Based on MPC8560 ADS and arch/ppc tqm85xx ports - * - * Maintained by Kumar Gala (see MAINTAINERS for contact information) - * - * Copyright 2008 Freescale Semiconductor Inc. - * - * Copyright (c) 2005-2006 DENX Software Engineering - * Stefan Roese - * - * Based on original work by - * Kumar Gala - * Copyright 2004 Freescale Semiconductor Inc. - * - * 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 "socrates_fpga_pic.h" - -static void __init socrates_pic_init(void) -{ - struct mpic *mpic; - struct resource r; - struct device_node *np; - - np = of_find_node_by_type(NULL, "open-pic"); - if (!np) { - printk(KERN_ERR "Could not find open-pic node\n"); - return; - } - - if (of_address_to_resource(np, 0, &r)) { - printk(KERN_ERR "Could not map mpic register space\n"); - of_node_put(np); - return; - } - - mpic = mpic_alloc(np, r.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, - 0, 256, " OpenPIC "); - BUG_ON(mpic == NULL); - of_node_put(np); - - mpic_init(mpic); - - np = of_find_compatible_node(NULL, NULL, "abb,socrates-fpga-pic"); - if (!np) { - printk(KERN_ERR "Could not find socrates-fpga-pic node\n"); - return; - } - socrates_fpga_pic_init(np); - of_node_put(np); -} - -/* - * Setup the architecture - */ -static void __init socrates_setup_arch(void) -{ -#ifdef CONFIG_PCI - struct device_node *np; -#endif - - if (ppc_md.progress) - ppc_md.progress("socrates_setup_arch()", 0); - -#ifdef CONFIG_PCI - for_each_compatible_node(np, "pci", "fsl,mpc8540-pci") - fsl_add_bridge(np, 1); -#endif -} - -static struct of_device_id __initdata socrates_of_bus_ids[] = { - { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, - {}, -}; - -static void __init socrates_init(void) -{ - of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL); -} - -/* - * Called very early, device-tree isn't unflattened - */ -static int __init socrates_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); - - if (of_flat_dt_is_compatible(root, "abb,socrates")) - return 1; - - return 0; -} - -define_machine(socrates) { - .name = "Socrates", - .probe = socrates_probe, - .setup_arch = socrates_setup_arch, - .init = socrates_init, - .init_IRQ = socrates_pic_init, - .get_irq = mpic_get_irq, - .restart = fsl_rstcr_restart, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, -}; diff --git a/trunk/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/trunk/arch/powerpc/platforms/85xx/socrates_fpga_pic.c deleted file mode 100644 index 60edf63d0157..000000000000 --- a/trunk/arch/powerpc/platforms/85xx/socrates_fpga_pic.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (C) 2008 Ilya Yanok, Emcraft Systems - * - * - * 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 - -/* - * The FPGA supports 9 interrupt sources, which can be routed to 3 - * interrupt request lines of the MPIC. The line to be used can be - * specified through the third cell of FDT property "interrupts". - */ - -#define SOCRATES_FPGA_NUM_IRQS 9 - -#define FPGA_PIC_IRQCFG (0x0) -#define FPGA_PIC_IRQMASK(n) (0x4 + 0x4 * (n)) - -#define SOCRATES_FPGA_IRQ_MASK ((1 << SOCRATES_FPGA_NUM_IRQS) - 1) - -struct socrates_fpga_irq_info { - unsigned int irq_line; - int type; -}; - -/* - * Interrupt routing and type table - * - * IRQ_TYPE_NONE means the interrupt type is configurable, - * otherwise it's fixed to the specified value. - */ -static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = { - [0] = {0, IRQ_TYPE_NONE}, - [1] = {0, IRQ_TYPE_LEVEL_HIGH}, - [2] = {0, IRQ_TYPE_LEVEL_LOW}, - [3] = {0, IRQ_TYPE_NONE}, - [4] = {0, IRQ_TYPE_NONE}, - [5] = {0, IRQ_TYPE_NONE}, - [6] = {0, IRQ_TYPE_NONE}, - [7] = {0, IRQ_TYPE_NONE}, - [8] = {0, IRQ_TYPE_LEVEL_HIGH}, -}; - -#define socrates_fpga_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq) - -static DEFINE_SPINLOCK(socrates_fpga_pic_lock); - -static void __iomem *socrates_fpga_pic_iobase; -static struct irq_host *socrates_fpga_pic_irq_host; -static unsigned int socrates_fpga_irqs[3]; - -static inline uint32_t socrates_fpga_pic_read(int reg) -{ - return in_be32(socrates_fpga_pic_iobase + reg); -} - -static inline void socrates_fpga_pic_write(int reg, uint32_t val) -{ - out_be32(socrates_fpga_pic_iobase + reg, val); -} - -static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq) -{ - uint32_t cause; - unsigned long flags; - int i; - - /* Check irq line routed to the MPIC */ - for (i = 0; i < 3; i++) { - if (irq == socrates_fpga_irqs[i]) - break; - } - if (i == 3) - return NO_IRQ; - - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); - cause = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(i)); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); - for (i = SOCRATES_FPGA_NUM_IRQS - 1; i >= 0; i--) { - if (cause >> (i + 16)) - break; - } - return irq_linear_revmap(socrates_fpga_pic_irq_host, - (irq_hw_number_t)i); -} - -void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc) -{ - unsigned int cascade_irq; - - /* - * See if we actually have an interrupt, call generic handling code if - * we do. - */ - cascade_irq = socrates_fpga_pic_get_irq(irq); - - if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq); - desc->chip->eoi(irq); - -} - -static void socrates_fpga_pic_ack(unsigned int virq) -{ - unsigned long flags; - unsigned int hwirq, irq_line; - uint32_t mask; - - hwirq = socrates_fpga_irq_to_hw(virq); - - irq_line = fpga_irqs[hwirq].irq_line; - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); - mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) - & SOCRATES_FPGA_IRQ_MASK; - mask |= (1 << (hwirq + 16)); - socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); -} - -static void socrates_fpga_pic_mask(unsigned int virq) -{ - unsigned long flags; - unsigned int hwirq; - int irq_line; - u32 mask; - - hwirq = socrates_fpga_irq_to_hw(virq); - - irq_line = fpga_irqs[hwirq].irq_line; - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); - mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) - & SOCRATES_FPGA_IRQ_MASK; - mask &= ~(1 << hwirq); - socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); -} - -static void socrates_fpga_pic_mask_ack(unsigned int virq) -{ - unsigned long flags; - unsigned int hwirq; - int irq_line; - u32 mask; - - hwirq = socrates_fpga_irq_to_hw(virq); - - irq_line = fpga_irqs[hwirq].irq_line; - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); - mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) - & SOCRATES_FPGA_IRQ_MASK; - mask &= ~(1 << hwirq); - mask |= (1 << (hwirq + 16)); - socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); -} - -static void socrates_fpga_pic_unmask(unsigned int virq) -{ - unsigned long flags; - unsigned int hwirq; - int irq_line; - u32 mask; - - hwirq = socrates_fpga_irq_to_hw(virq); - - irq_line = fpga_irqs[hwirq].irq_line; - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); - mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) - & SOCRATES_FPGA_IRQ_MASK; - mask |= (1 << hwirq); - socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); -} - -static void socrates_fpga_pic_eoi(unsigned int virq) -{ - unsigned long flags; - unsigned int hwirq; - int irq_line; - u32 mask; - - hwirq = socrates_fpga_irq_to_hw(virq); - - irq_line = fpga_irqs[hwirq].irq_line; - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); - mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) - & SOCRATES_FPGA_IRQ_MASK; - mask |= (1 << (hwirq + 16)); - socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); -} - -static int socrates_fpga_pic_set_type(unsigned int virq, - unsigned int flow_type) -{ - unsigned long flags; - unsigned int hwirq; - int polarity; - u32 mask; - - hwirq = socrates_fpga_irq_to_hw(virq); - - if (fpga_irqs[hwirq].type != IRQ_TYPE_NONE) - return -EINVAL; - - switch (flow_type & IRQ_TYPE_SENSE_MASK) { - case IRQ_TYPE_LEVEL_HIGH: - polarity = 1; - break; - case IRQ_TYPE_LEVEL_LOW: - polarity = 0; - break; - default: - return -EINVAL; - } - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); - mask = socrates_fpga_pic_read(FPGA_PIC_IRQCFG); - if (polarity) - mask |= (1 << hwirq); - else - mask &= ~(1 << hwirq); - socrates_fpga_pic_write(FPGA_PIC_IRQCFG, mask); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); - return 0; -} - -static struct irq_chip socrates_fpga_pic_chip = { - .typename = " FPGA-PIC ", - .ack = socrates_fpga_pic_ack, - .mask = socrates_fpga_pic_mask, - .mask_ack = socrates_fpga_pic_mask_ack, - .unmask = socrates_fpga_pic_unmask, - .eoi = socrates_fpga_pic_eoi, - .set_type = socrates_fpga_pic_set_type, -}; - -static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t hwirq) -{ - /* All interrupts are LEVEL sensitive */ - get_irq_desc(virq)->status |= IRQ_LEVEL; - set_irq_chip_and_handler(virq, &socrates_fpga_pic_chip, - handle_fasteoi_irq); - - return 0; -} - -static int socrates_fpga_pic_host_xlate(struct irq_host *h, - struct device_node *ct, u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_flags) -{ - struct socrates_fpga_irq_info *fpga_irq = &fpga_irqs[intspec[0]]; - - *out_hwirq = intspec[0]; - if (fpga_irq->type == IRQ_TYPE_NONE) { - /* type is configurable */ - if (intspec[1] != IRQ_TYPE_LEVEL_LOW && - intspec[1] != IRQ_TYPE_LEVEL_HIGH) { - pr_warning("FPGA PIC: invalid irq type, " - "setting default active low\n"); - *out_flags = IRQ_TYPE_LEVEL_LOW; - } else { - *out_flags = intspec[1]; - } - } else { - /* type is fixed */ - *out_flags = fpga_irq->type; - } - - /* Use specified interrupt routing */ - if (intspec[2] <= 2) - fpga_irq->irq_line = intspec[2]; - else - pr_warning("FPGA PIC: invalid irq routing\n"); - - return 0; -} - -static struct irq_host_ops socrates_fpga_pic_host_ops = { - .map = socrates_fpga_pic_host_map, - .xlate = socrates_fpga_pic_host_xlate, -}; - -void socrates_fpga_pic_init(struct device_node *pic) -{ - unsigned long flags; - int i; - - /* Setup an irq_host structure */ - socrates_fpga_pic_irq_host = irq_alloc_host(pic, IRQ_HOST_MAP_LINEAR, - SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, - SOCRATES_FPGA_NUM_IRQS); - if (socrates_fpga_pic_irq_host == NULL) { - pr_err("FPGA PIC: Unable to allocate host\n"); - return; - } - - for (i = 0; i < 3; i++) { - socrates_fpga_irqs[i] = irq_of_parse_and_map(pic, i); - if (socrates_fpga_irqs[i] == NO_IRQ) { - pr_warning("FPGA PIC: can't get irq%d.\n", i); - continue; - } - set_irq_chained_handler(socrates_fpga_irqs[i], - socrates_fpga_pic_cascade); - } - - socrates_fpga_pic_iobase = of_iomap(pic, 0); - - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); - socrates_fpga_pic_write(FPGA_PIC_IRQMASK(0), - SOCRATES_FPGA_IRQ_MASK << 16); - socrates_fpga_pic_write(FPGA_PIC_IRQMASK(1), - SOCRATES_FPGA_IRQ_MASK << 16); - socrates_fpga_pic_write(FPGA_PIC_IRQMASK(2), - SOCRATES_FPGA_IRQ_MASK << 16); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); - - pr_info("FPGA PIC: Setting up Socrates FPGA PIC\n"); -} diff --git a/trunk/arch/powerpc/platforms/85xx/socrates_fpga_pic.h b/trunk/arch/powerpc/platforms/85xx/socrates_fpga_pic.h deleted file mode 100644 index 21d7d8e42199..000000000000 --- a/trunk/arch/powerpc/platforms/85xx/socrates_fpga_pic.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2008 Ilya Yanok, Emcraft Systems - * - * - * 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 SOCRATES_FPGA_PIC_H -#define SOCRATES_FPGA_PIC_H - -void socrates_fpga_pic_init(struct device_node *pic); - -#endif diff --git a/trunk/arch/powerpc/platforms/85xx/stx_gp3.c b/trunk/arch/powerpc/platforms/85xx/stx_gp3.c index f559918f3c6f..0cca8f5cb272 100644 --- a/trunk/arch/powerpc/platforms/85xx/stx_gp3.c +++ b/trunk/arch/powerpc/platforms/85xx/stx_gp3.c @@ -145,7 +145,6 @@ static void stx_gp3_show_cpuinfo(struct seq_file *m) static struct of_device_id __initdata of_bus_ids[] = { { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/tqm85xx.c b/trunk/arch/powerpc/platforms/85xx/tqm85xx.c index 5b0ab9966e90..2933a8e827d9 100644 --- a/trunk/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/trunk/arch/powerpc/platforms/85xx/tqm85xx.c @@ -153,7 +153,6 @@ static void tqm85xx_show_cpuinfo(struct seq_file *m) static struct of_device_id __initdata of_bus_ids[] = { { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/86xx/Kconfig b/trunk/arch/powerpc/platforms/86xx/Kconfig index fdaf4ddaa955..8e5693935975 100644 --- a/trunk/arch/powerpc/platforms/86xx/Kconfig +++ b/trunk/arch/powerpc/platforms/86xx/Kconfig @@ -1,7 +1,7 @@ config PPC_86xx menuconfig PPC_86xx bool "86xx-based boards" - depends on 6xx + depends on 6xx && PPC_MULTIPLATFORM select FSL_SOC select ALTIVEC help @@ -31,22 +31,6 @@ config MPC8610_HPCD help This option enables support for the MPC8610 HPCD board. -config GEF_PPC9A - bool "GE Fanuc PPC9A" - select DEFAULT_UIMAGE - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB - help - This option enables support for GE Fanuc's PPC9A. - -config GEF_SBC310 - bool "GE Fanuc SBC310" - select DEFAULT_UIMAGE - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB - help - This option enables support for GE Fanuc's SBC310. - config GEF_SBC610 bool "GE Fanuc SBC610" select DEFAULT_UIMAGE @@ -64,7 +48,7 @@ config MPC8641 select FSL_PCI if PCI select PPC_UDBG_16550 select MPIC - default y if MPC8641_HPCN || SBC8641D || GEF_SBC610 || GEF_SBC310 || GEF_PPC9A + default y if MPC8641_HPCN || SBC8641D || GEF_SBC610 config MPC8610 bool diff --git a/trunk/arch/powerpc/platforms/86xx/Makefile b/trunk/arch/powerpc/platforms/86xx/Makefile index 4b0d7b1aa005..31e540c2ebbc 100644 --- a/trunk/arch/powerpc/platforms/86xx/Makefile +++ b/trunk/arch/powerpc/platforms/86xx/Makefile @@ -9,5 +9,3 @@ obj-$(CONFIG_SBC8641D) += sbc8641d.o obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o gef-gpio-$(CONFIG_GPIOLIB) += gef_gpio.o obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o gef_pic.o $(gef-gpio-y) -obj-$(CONFIG_GEF_SBC310) += gef_sbc310.o gef_pic.o $(gef-gpio-y) -obj-$(CONFIG_GEF_PPC9A) += gef_ppc9a.o gef_pic.o $(gef-gpio-y) diff --git a/trunk/arch/powerpc/platforms/86xx/gef_gpio.c b/trunk/arch/powerpc/platforms/86xx/gef_gpio.c index b2ea8875adba..85b2800f4cb7 100644 --- a/trunk/arch/powerpc/platforms/86xx/gef_gpio.c +++ b/trunk/arch/powerpc/platforms/86xx/gef_gpio.c @@ -37,6 +37,8 @@ #define GEF_GPIO_OVERRUN 0x1C #define GEF_GPIO_MODE 0x20 +#define NUM_GPIO 19 + static void _gef_gpio_set(void __iomem *reg, unsigned int offset, int value) { unsigned int data; @@ -101,10 +103,10 @@ static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value) static int __init gef_gpio_init(void) { struct device_node *np; - int retval; - struct of_mm_gpio_chip *gef_gpio_chip; for_each_compatible_node(np, NULL, "gef,sbc610-gpio") { + int retval; + struct of_mm_gpio_chip *gef_gpio_chip; pr_debug("%s: Initialising GEF GPIO\n", np->full_name); @@ -118,35 +120,7 @@ static int __init gef_gpio_init(void) /* Setup pointers to chip functions */ gef_gpio_chip->of_gc.gpio_cells = 2; - gef_gpio_chip->of_gc.gc.ngpio = 19; - gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in; - gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out; - gef_gpio_chip->of_gc.gc.get = gef_gpio_get; - gef_gpio_chip->of_gc.gc.set = gef_gpio_set; - - /* This function adds a memory mapped GPIO chip */ - retval = of_mm_gpiochip_add(np, gef_gpio_chip); - if (retval) { - kfree(gef_gpio_chip); - pr_err("%s: Unable to add GPIO\n", np->full_name); - } - } - - for_each_compatible_node(np, NULL, "gef,sbc310-gpio") { - - pr_debug("%s: Initialising GEF GPIO\n", np->full_name); - - /* Allocate chip structure */ - gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL); - if (!gef_gpio_chip) { - pr_err("%s: Unable to allocate structure\n", - np->full_name); - continue; - } - - /* Setup pointers to chip functions */ - gef_gpio_chip->of_gc.gpio_cells = 2; - gef_gpio_chip->of_gc.gc.ngpio = 6; + gef_gpio_chip->of_gc.gc.ngpio = NUM_GPIO; gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in; gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out; gef_gpio_chip->of_gc.gc.get = gef_gpio_get; diff --git a/trunk/arch/powerpc/platforms/86xx/gef_ppc9a.c b/trunk/arch/powerpc/platforms/86xx/gef_ppc9a.c deleted file mode 100644 index d79104669cdc..000000000000 --- a/trunk/arch/powerpc/platforms/86xx/gef_ppc9a.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * GE Fanuc PPC9A board support - * - * Author: Martyn Welch - * - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Based on: mpc86xx_hpcn.c (MPC86xx HPCN board specific routines) - * Copyright 2006 Freescale Semiconductor Inc. - * - * NEC fixup adapted from arch/mips/pci/fixup-lm2e.c - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "mpc86xx.h" -#include "gef_pic.h" - -#undef DEBUG - -#ifdef DEBUG -#define DBG (fmt...) do { printk(KERN_ERR "PPC9A: " fmt); } while (0) -#else -#define DBG (fmt...) do { } while (0) -#endif - -void __iomem *ppc9a_regs; - -static void __init gef_ppc9a_init_irq(void) -{ - struct device_node *cascade_node = NULL; - - mpc86xx_init_irq(); - - /* - * There is a simple interrupt handler in the main FPGA, this needs - * to be cascaded into the MPIC - */ - cascade_node = of_find_compatible_node(NULL, NULL, "gef,fpga-pic-1.00"); - if (!cascade_node) { - printk(KERN_WARNING "PPC9A: No FPGA PIC\n"); - return; - } - - gef_pic_init(cascade_node); - of_node_put(cascade_node); -} - -static void __init gef_ppc9a_setup_arch(void) -{ - struct device_node *regs; -#ifdef CONFIG_PCI - struct device_node *np; - - for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") { - fsl_add_bridge(np, 1); - } -#endif - - printk(KERN_INFO "GE Fanuc Intelligent Platforms PPC9A 6U VME SBC\n"); - -#ifdef CONFIG_SMP - mpc86xx_smp_init(); -#endif - - /* Remap basic board registers */ - regs = of_find_compatible_node(NULL, NULL, "gef,ppc9a-fpga-regs"); - if (regs) { - ppc9a_regs = of_iomap(regs, 0); - if (ppc9a_regs == NULL) - printk(KERN_WARNING "Unable to map board registers\n"); - of_node_put(regs); - } -} - -/* Return the PCB revision */ -static unsigned int gef_ppc9a_get_pcb_rev(void) -{ - unsigned int reg; - - reg = ioread32(ppc9a_regs); - return (reg >> 8) & 0xff; -} - -/* Return the board (software) revision */ -static unsigned int gef_ppc9a_get_board_rev(void) -{ - unsigned int reg; - - reg = ioread32(ppc9a_regs); - return (reg >> 16) & 0xff; -} - -/* Return the FPGA revision */ -static unsigned int gef_ppc9a_get_fpga_rev(void) -{ - unsigned int reg; - - reg = ioread32(ppc9a_regs); - return (reg >> 24) & 0xf; -} - -static void gef_ppc9a_show_cpuinfo(struct seq_file *m) -{ - uint svid = mfspr(SPRN_SVR); - - seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n"); - - seq_printf(m, "Revision\t: %u%c\n", gef_ppc9a_get_pcb_rev(), - ('A' + gef_ppc9a_get_board_rev() - 1)); - seq_printf(m, "FPGA Revision\t: %u\n", gef_ppc9a_get_fpga_rev()); - - seq_printf(m, "SVR\t\t: 0x%x\n", svid); -} - -static void __init gef_ppc9a_nec_fixup(struct pci_dev *pdev) -{ - unsigned int val; - - /* Do not do the fixup on other platforms! */ - if (!machine_is(gef_ppc9a)) - return; - - printk(KERN_INFO "Running NEC uPD720101 Fixup\n"); - - /* Ensure ports 1, 2, 3, 4 & 5 are enabled */ - pci_read_config_dword(pdev, 0xe0, &val); - pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x5); - - /* System clock is 48-MHz Oscillator and EHCI Enabled. */ - pci_write_config_dword(pdev, 0xe4, 1 << 5); -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB, - gef_ppc9a_nec_fixup); - -/* - * Called very early, device-tree isn't unflattened - * - * This function is called to determine whether the BSP is compatible with the - * supplied device-tree, which is assumed to be the correct one for the actual - * board. It is expected thati, in the future, a kernel may support multiple - * boards. - */ -static int __init gef_ppc9a_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); - - if (of_flat_dt_is_compatible(root, "gef,ppc9a")) - return 1; - - return 0; -} - -static long __init mpc86xx_time_init(void) -{ - unsigned int temp; - - /* Set the time base to zero */ - mtspr(SPRN_TBWL, 0); - mtspr(SPRN_TBWU, 0); - - temp = mfspr(SPRN_HID0); - temp |= HID0_TBEN; - mtspr(SPRN_HID0, temp); - asm volatile("isync"); - - return 0; -} - -static __initdata struct of_device_id of_bus_ids[] = { - { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, - {}, -}; - -static int __init declare_of_platform_devices(void) -{ - printk(KERN_DEBUG "Probe platform devices\n"); - of_platform_bus_probe(NULL, of_bus_ids, NULL); - - return 0; -} -machine_device_initcall(gef_ppc9a, declare_of_platform_devices); - -define_machine(gef_ppc9a) { - .name = "GE Fanuc PPC9A", - .probe = gef_ppc9a_probe, - .setup_arch = gef_ppc9a_setup_arch, - .init_IRQ = gef_ppc9a_init_irq, - .show_cpuinfo = gef_ppc9a_show_cpuinfo, - .get_irq = mpic_get_irq, - .restart = fsl_rstcr_restart, - .time_init = mpc86xx_time_init, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, -#ifdef CONFIG_PCI - .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -#endif -}; diff --git a/trunk/arch/powerpc/platforms/86xx/gef_sbc310.c b/trunk/arch/powerpc/platforms/86xx/gef_sbc310.c deleted file mode 100644 index af14f852d747..000000000000 --- a/trunk/arch/powerpc/platforms/86xx/gef_sbc310.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * GE Fanuc SBC310 board support - * - * Author: Martyn Welch - * - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Based on: mpc86xx_hpcn.c (MPC86xx HPCN board specific routines) - * Copyright 2006 Freescale Semiconductor Inc. - * - * NEC fixup adapted from arch/mips/pci/fixup-lm2e.c - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "mpc86xx.h" -#include "gef_pic.h" - -#undef DEBUG - -#ifdef DEBUG -#define DBG (fmt...) do { printk(KERN_ERR "SBC310: " fmt); } while (0) -#else -#define DBG (fmt...) do { } while (0) -#endif - -void __iomem *sbc310_regs; - -static void __init gef_sbc310_init_irq(void) -{ - struct device_node *cascade_node = NULL; - - mpc86xx_init_irq(); - - /* - * There is a simple interrupt handler in the main FPGA, this needs - * to be cascaded into the MPIC - */ - cascade_node = of_find_compatible_node(NULL, NULL, "gef,fpga-pic"); - if (!cascade_node) { - printk(KERN_WARNING "SBC310: No FPGA PIC\n"); - return; - } - - gef_pic_init(cascade_node); - of_node_put(cascade_node); -} - -static void __init gef_sbc310_setup_arch(void) -{ - struct device_node *regs; -#ifdef CONFIG_PCI - struct device_node *np; - - for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") { - fsl_add_bridge(np, 1); - } -#endif - - printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC310 6U VPX SBC\n"); - -#ifdef CONFIG_SMP - mpc86xx_smp_init(); -#endif - - /* Remap basic board registers */ - regs = of_find_compatible_node(NULL, NULL, "gef,fpga-regs"); - if (regs) { - sbc310_regs = of_iomap(regs, 0); - if (sbc310_regs == NULL) - printk(KERN_WARNING "Unable to map board registers\n"); - of_node_put(regs); - } -} - -/* Return the PCB revision */ -static unsigned int gef_sbc310_get_board_id(void) -{ - unsigned int reg; - - reg = ioread32(sbc310_regs); - return reg & 0xff; -} - -/* Return the PCB revision */ -static unsigned int gef_sbc310_get_pcb_rev(void) -{ - unsigned int reg; - - reg = ioread32(sbc310_regs); - return (reg >> 8) & 0xff; -} - -/* Return the board (software) revision */ -static unsigned int gef_sbc310_get_board_rev(void) -{ - unsigned int reg; - - reg = ioread32(sbc310_regs); - return (reg >> 16) & 0xff; -} - -/* Return the FPGA revision */ -static unsigned int gef_sbc310_get_fpga_rev(void) -{ - unsigned int reg; - - reg = ioread32(sbc310_regs); - return (reg >> 24) & 0xf; -} - -static void gef_sbc310_show_cpuinfo(struct seq_file *m) -{ - uint svid = mfspr(SPRN_SVR); - - seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n"); - - seq_printf(m, "Board ID\t: 0x%2.2x\n", gef_sbc310_get_board_id()); - seq_printf(m, "Revision\t: %u%c\n", gef_sbc310_get_pcb_rev(), - ('A' + gef_sbc310_get_board_rev() - 1)); - seq_printf(m, "FPGA Revision\t: %u\n", gef_sbc310_get_fpga_rev()); - - seq_printf(m, "SVR\t\t: 0x%x\n", svid); - -} - -static void __init gef_sbc310_nec_fixup(struct pci_dev *pdev) -{ - unsigned int val; - - /* Do not do the fixup on other platforms! */ - if (!machine_is(gef_sbc310)) - return; - - printk(KERN_INFO "Running NEC uPD720101 Fixup\n"); - - /* Ensure only ports 1 & 2 are enabled */ - pci_read_config_dword(pdev, 0xe0, &val); - pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x2); - - /* System clock is 48-MHz Oscillator and EHCI Enabled. */ - pci_write_config_dword(pdev, 0xe4, 1 << 5); -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB, - gef_sbc310_nec_fixup); - -/* - * Called very early, device-tree isn't unflattened - * - * This function is called to determine whether the BSP is compatible with the - * supplied device-tree, which is assumed to be the correct one for the actual - * board. It is expected thati, in the future, a kernel may support multiple - * boards. - */ -static int __init gef_sbc310_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); - - if (of_flat_dt_is_compatible(root, "gef,sbc310")) - return 1; - - return 0; -} - -static long __init mpc86xx_time_init(void) -{ - unsigned int temp; - - /* Set the time base to zero */ - mtspr(SPRN_TBWL, 0); - mtspr(SPRN_TBWU, 0); - - temp = mfspr(SPRN_HID0); - temp |= HID0_TBEN; - mtspr(SPRN_HID0, temp); - asm volatile("isync"); - - return 0; -} - -static __initdata struct of_device_id of_bus_ids[] = { - { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, - {}, -}; - -static int __init declare_of_platform_devices(void) -{ - printk(KERN_DEBUG "Probe platform devices\n"); - of_platform_bus_probe(NULL, of_bus_ids, NULL); - - return 0; -} -machine_device_initcall(gef_sbc310, declare_of_platform_devices); - -define_machine(gef_sbc310) { - .name = "GE Fanuc SBC310", - .probe = gef_sbc310_probe, - .setup_arch = gef_sbc310_setup_arch, - .init_IRQ = gef_sbc310_init_irq, - .show_cpuinfo = gef_sbc310_show_cpuinfo, - .get_irq = mpic_get_irq, - .restart = fsl_rstcr_restart, - .time_init = mpc86xx_time_init, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, -#ifdef CONFIG_PCI - .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -#endif -}; diff --git a/trunk/arch/powerpc/platforms/86xx/gef_sbc610.c b/trunk/arch/powerpc/platforms/86xx/gef_sbc610.c index ea2360639652..d6b772ba3b8f 100644 --- a/trunk/arch/powerpc/platforms/86xx/gef_sbc610.c +++ b/trunk/arch/powerpc/platforms/86xx/gef_sbc610.c @@ -194,7 +194,6 @@ static long __init mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c index 3f49a6f893a3..e8d54ac5292c 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c +++ b/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c @@ -46,7 +46,6 @@ static unsigned char *pixis_bdcfg0, *pixis_arch; static struct of_device_id __initdata mpc8610_ids[] = { { .compatible = "fsl,mpc8610-immr", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {} }; diff --git a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index c4ec49b5f7f8..27e0e682d8e1 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -148,7 +148,6 @@ mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, { .compatible = "fsl,rapidio-delta", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/86xx/sbc8641d.c b/trunk/arch/powerpc/platforms/86xx/sbc8641d.c index 2886a36fc085..5fd7ed40986f 100644 --- a/trunk/arch/powerpc/platforms/86xx/sbc8641d.c +++ b/trunk/arch/powerpc/platforms/86xx/sbc8641d.c @@ -103,7 +103,6 @@ mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/8xx/m8xx_setup.c b/trunk/arch/powerpc/platforms/8xx/m8xx_setup.c index 385acfc48397..0d9f75c74f8c 100644 --- a/trunk/arch/powerpc/platforms/8xx/m8xx_setup.c +++ b/trunk/arch/powerpc/platforms/8xx/m8xx_setup.c @@ -44,6 +44,7 @@ static irqreturn_t timebase_interrupt(int irq, void *dev) static struct irqaction tbint_irqaction = { .handler = timebase_interrupt, + .mask = CPU_MASK_NONE, .name = "tbint", }; diff --git a/trunk/arch/powerpc/platforms/Kconfig b/trunk/arch/powerpc/platforms/Kconfig index ffa2a9fd53d0..200b9cb900ea 100644 --- a/trunk/arch/powerpc/platforms/Kconfig +++ b/trunk/arch/powerpc/platforms/Kconfig @@ -1,5 +1,14 @@ menu "Platform support" +config PPC_MULTIPLATFORM + bool + depends on PPC64 || 6xx + default y + +config CLASSIC32 + def_bool y + depends on 6xx && PPC_MULTIPLATFORM + source "arch/powerpc/platforms/pseries/Kconfig" source "arch/powerpc/platforms/iseries/Kconfig" source "arch/powerpc/platforms/chrp/Kconfig" @@ -19,28 +28,15 @@ source "arch/powerpc/platforms/86xx/Kconfig" source "arch/powerpc/platforms/embedded6xx/Kconfig" source "arch/powerpc/platforms/44x/Kconfig" source "arch/powerpc/platforms/40x/Kconfig" -source "arch/powerpc/platforms/amigaone/Kconfig" config PPC_NATIVE bool - depends on 6xx || PPC64 + depends on PPC_MULTIPLATFORM help Support for running natively on the hardware, i.e. without a hypervisor. This option is not user-selectable but should be selected by all platforms that need it. -config PPC_OF_BOOT_TRAMPOLINE - bool "Support booting from Open Firmware or yaboot" - depends on 6xx || PPC64 - default y - help - Support from booting from Open Firmware or yaboot using an - Open Firmware client interface. This enables the kernel to - communicate with open firmware to retrieve system informations - such as the device tree. - - In case of doubt, say Y - config UDBG_RTAS_CONSOLE bool "RTAS based debug console" depends on PPC_RTAS @@ -74,7 +70,7 @@ config PPC_I8259 config U3_DART bool - depends on PPC64 + depends on PPC_MULTIPLATFORM && PPC64 default n config PPC_RTAS @@ -95,6 +91,15 @@ config RTAS_FLASH tristate "Firmware flash interface" depends on PPC64 && RTAS_PROC +config PPC_PMI + tristate "Support for PMI" + depends on PPC_IBM_CELL_BLADE + help + PMI (Platform Management Interrupt) is a way to + communicate with the BMC (Baseboard Management Controller). + It is used in some IBM Cell blades. + default m + config MMIO_NVRAM bool default n @@ -191,7 +196,7 @@ config PPC601_SYNC_FIX config TAU bool "On-chip CPU temperature sensor support" - depends on 6xx + depends on CLASSIC32 help G3 and G4 processors have an on-chip temperature sensor called the 'Thermal Assist Unit (TAU)', which, in theory, can measure the on-die @@ -269,7 +274,7 @@ config CPM2 config AXON_RAM tristate "Axon DDR2 memory device driver" - depends on PPC_IBM_CELL_BLADE && BLOCK + depends on PPC_IBM_CELL_BLADE default m help It registers one block device per Axon's DDR2 memory bank found diff --git a/trunk/arch/powerpc/platforms/Kconfig.cputype b/trunk/arch/powerpc/platforms/Kconfig.cputype index 9da795e49337..e868b5c50723 100644 --- a/trunk/arch/powerpc/platforms/Kconfig.cputype +++ b/trunk/arch/powerpc/platforms/Kconfig.cputype @@ -57,17 +57,9 @@ config E200 endchoice -# Until we have a choice of exclusive CPU types on 64-bit, we always -# use PPC_BOOK3S. On 32-bit, this is equivalent to 6xx which is -# "classic" MMU - -config PPC_BOOK3S - def_bool y - depends on PPC64 || 6xx - config POWER4_ONLY bool "Optimize for POWER4" - depends on PPC64 && PPC_BOOK3S + depends on PPC64 default n ---help--- Cause the compiler to optimize for POWER4/POWER5/PPC970 processors. @@ -76,16 +68,16 @@ config POWER4_ONLY config POWER3 bool - depends on PPC64 && PPC_BOOK3S + depends on PPC64 default y if !POWER4_ONLY config POWER4 - depends on PPC64 && PPC_BOOK3S + depends on PPC64 def_bool y config TUNE_CELL bool "Optimize for Cell Broadband Engine" - depends on PPC64 && PPC_BOOK3S + depends on PPC64 help Cause the compiler to optimize for the PPE of the Cell Broadband Engine. This will make the code run considerably faster on Cell @@ -155,7 +147,7 @@ config PHYS_64BIT config ALTIVEC bool "AltiVec Support" - depends on 6xx || POWER4 + depends on CLASSIC32 || POWER4 ---help--- This option enables kernel support for the Altivec extensions to the PowerPC processor. The kernel currently supports saving and restoring @@ -218,10 +210,6 @@ config PPC_MMU_NOHASH def_bool y depends on !PPC_STD_MMU -config PPC_BOOK3E_MMU - def_bool y - depends on FSL_BOOKE - config PPC_MM_SLICES bool default y if HUGETLB_PAGE || (PPC_STD_MMU_64 && PPC_64K_PAGES) diff --git a/trunk/arch/powerpc/platforms/Makefile b/trunk/arch/powerpc/platforms/Makefile index f7419198e635..8079e0b4fd69 100644 --- a/trunk/arch/powerpc/platforms/Makefile +++ b/trunk/arch/powerpc/platforms/Makefile @@ -19,4 +19,3 @@ obj-$(CONFIG_PPC_PASEMI) += pasemi/ obj-$(CONFIG_PPC_CELL) += cell/ obj-$(CONFIG_PPC_PS3) += ps3/ obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ -obj-$(CONFIG_AMIGAONE) += amigaone/ diff --git a/trunk/arch/powerpc/platforms/amigaone/Kconfig b/trunk/arch/powerpc/platforms/amigaone/Kconfig deleted file mode 100644 index 022476717718..000000000000 --- a/trunk/arch/powerpc/platforms/amigaone/Kconfig +++ /dev/null @@ -1,18 +0,0 @@ -config AMIGAONE - bool "Eyetech AmigaOne/MAI Teron" - depends on 6xx && BROKEN_ON_SMP - select PPC_I8259 - select PPC_INDIRECT_PCI - select PPC_UDBG_16550 - select PCI - select NOT_COHERENT_CACHE - select CHECK_CACHE_COHERENCY - select DEFAULT_UIMAGE - select PCSPKR_PLATFORM - help - Select AmigaOne for the following machines: - - AmigaOne SE/Teron CX (G3 only) - - AmigaOne XE/Teron PX - - uA1/Teron mini - More information is available at: - . diff --git a/trunk/arch/powerpc/platforms/amigaone/Makefile b/trunk/arch/powerpc/platforms/amigaone/Makefile deleted file mode 100644 index e6885b3b2ee7..000000000000 --- a/trunk/arch/powerpc/platforms/amigaone/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-y += setup.o diff --git a/trunk/arch/powerpc/platforms/amigaone/setup.c b/trunk/arch/powerpc/platforms/amigaone/setup.c deleted file mode 100644 index 443035366c12..000000000000 --- a/trunk/arch/powerpc/platforms/amigaone/setup.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * AmigaOne platform setup - * - * Copyright 2008 Gerhard Pircher (gerhard_pircher@gmx.net) - * - * Based on original amigaone_setup.c source code - * Copyright 2003 by Hans-Joerg Frieden and Thomas Frieden - * - * 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 - -extern void __flush_disable_L1(void); - -void amigaone_show_cpuinfo(struct seq_file *m) -{ - seq_printf(m, "vendor\t\t: Eyetech Ltd.\n"); -} - -static int __init amigaone_add_bridge(struct device_node *dev) -{ - const u32 *cfg_addr, *cfg_data; - int len; - const int *bus_range; - struct pci_controller *hose; - - printk(KERN_INFO "Adding PCI host bridge %s\n", dev->full_name); - - cfg_addr = of_get_address(dev, 0, NULL, NULL); - cfg_data = of_get_address(dev, 1, NULL, NULL); - if ((cfg_addr == NULL) || (cfg_data == NULL)) - return -ENODEV; - - bus_range = of_get_property(dev, "bus-range", &len); - if ((bus_range == NULL) || (len < 2 * sizeof(int))) - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); - - hose = pcibios_alloc_controller(dev); - if (hose == NULL) - return -ENOMEM; - - hose->first_busno = bus_range ? bus_range[0] : 0; - hose->last_busno = bus_range ? bus_range[1] : 0xff; - - setup_indirect_pci(hose, cfg_addr[0], cfg_data[0], 0); - - /* Interpret the "ranges" property */ - /* This also maps the I/O region and sets isa_io/mem_base */ - pci_process_bridge_OF_ranges(hose, dev, 1); - - return 0; -} - -void __init amigaone_setup_arch(void) -{ - struct device_node *np; - int phb = -ENODEV; - - /* Lookup PCI host bridges. */ - for_each_compatible_node(np, "pci", "mai-logic,articia-s") - phb = amigaone_add_bridge(np); - - BUG_ON(phb != 0); - - if (ppc_md.progress) - ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0); -} - -void __init amigaone_init_IRQ(void) -{ - struct device_node *pic, *np = NULL; - const unsigned long *prop = NULL; - unsigned long int_ack = 0; - - /* Search for ISA interrupt controller. */ - pic = of_find_compatible_node(NULL, "interrupt-controller", - "pnpPNP,000"); - BUG_ON(pic == NULL); - - /* Look for interrupt acknowledge address in the PCI root node. */ - np = of_find_compatible_node(NULL, "pci", "mai-logic,articia-s"); - if (np) { - prop = of_get_property(np, "8259-interrupt-acknowledge", NULL); - if (prop) - int_ack = prop[0]; - of_node_put(np); - } - - if (int_ack == 0) - printk(KERN_WARNING "Cannot find PCI interrupt acknowledge" - " address, polling\n"); - - i8259_init(pic, int_ack); - ppc_md.get_irq = i8259_irq; - irq_set_default_host(i8259_get_host()); -} - -void __init amigaone_init(void) -{ - request_region(0x00, 0x20, "dma1"); - request_region(0x40, 0x20, "timer"); - request_region(0x80, 0x10, "dma page reg"); - request_region(0xc0, 0x20, "dma2"); -} - -void amigaone_restart(char *cmd) -{ - local_irq_disable(); - - /* Flush and disable caches. */ - __flush_disable_L1(); - - /* Set SRR0 to the reset vector and turn on MSR_IP. */ - mtspr(SPRN_SRR0, 0xfff00100); - mtspr(SPRN_SRR1, MSR_IP); - - /* Do an rfi to jump back to firmware. */ - __asm__ __volatile__("rfi" : : : "memory"); - - /* Not reached. */ - while (1); -} - -static int __init amigaone_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); - - if (of_flat_dt_is_compatible(root, "eyetech,amigaone")) { - /* - * Coherent memory access cause complete system lockup! Thus - * disable this CPU feature, even if the CPU needs it. - */ - cur_cpu_spec->cpu_features &= ~CPU_FTR_NEED_COHERENT; - - ISA_DMA_THRESHOLD = 0x00ffffff; - DMA_MODE_READ = 0x44; - DMA_MODE_WRITE = 0x48; - - return 1; - } - - return 0; -} - -define_machine(amigaone) { - .name = "AmigaOne", - .probe = amigaone_probe, - .setup_arch = amigaone_setup_arch, - .init = amigaone_init, - .show_cpuinfo = amigaone_show_cpuinfo, - .init_IRQ = amigaone_init_IRQ, - .restart = amigaone_restart, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, -}; diff --git a/trunk/arch/powerpc/platforms/cell/Kconfig b/trunk/arch/powerpc/platforms/cell/Kconfig index 40e24c39ad06..5cc3279559a4 100644 --- a/trunk/arch/powerpc/platforms/cell/Kconfig +++ b/trunk/arch/powerpc/platforms/cell/Kconfig @@ -23,7 +23,7 @@ config PPC_CELL_NATIVE config PPC_IBM_CELL_BLADE bool "IBM Cell Blade" - depends on PPC64 && PPC_BOOK3S + depends on PPC_MULTIPLATFORM && PPC64 select PPC_CELL_NATIVE select MMIO_NVRAM select PPC_UDBG_16550 @@ -31,7 +31,7 @@ config PPC_IBM_CELL_BLADE config PPC_CELLEB bool "Toshiba's Cell Reference Set 'Celleb' Architecture" - depends on PPC64 && PPC_BOOK3S + depends on PPC_MULTIPLATFORM && PPC64 select PPC_CELL_NATIVE select HAS_TXX9_SERIAL select PPC_UDBG_BEAT @@ -40,14 +40,9 @@ config PPC_CELLEB config PPC_CELL_QPACE bool "IBM Cell - QPACE" - depends on PPC64 && PPC_BOOK3S + depends on PPC_MULTIPLATFORM && PPC64 select PPC_CELL_COMMON -config AXON_MSI - bool - depends on PPC_IBM_CELL_BLADE && PCI_MSI - default y - menu "Cell Broadband Engine options" depends on PPC_CELL @@ -103,7 +98,7 @@ config PPC_IBM_CELL_RESETBUTTON config PPC_IBM_CELL_POWERBUTTON tristate "IBM Cell Blade power button" - depends on PPC_IBM_CELL_BLADE && INPUT_EVDEV + depends on PPC_IBM_CELL_BLADE && PPC_PMI && INPUT_EVDEV default y help Support Powerbutton on IBM Cell blades. @@ -123,9 +118,9 @@ config CBE_CPUFREQ For details, take a look at . If you don't have such processor, say N -config CBE_CPUFREQ_PMI_ENABLE - bool "CBE frequency scaling using PMI interface" - depends on CBE_CPUFREQ && EXPERIMENTAL +config CBE_CPUFREQ_PMI + tristate "CBE frequency scaling using PMI interface" + depends on CBE_CPUFREQ && PPC_PMI && EXPERIMENTAL default n help Select this, if you want to use the PMI interface @@ -133,20 +128,6 @@ config CBE_CPUFREQ_PMI_ENABLE processor will not only be able to run at lower speed, but also at lower core voltage. -config CBE_CPUFREQ_PMI - tristate - depends on CBE_CPUFREQ_PMI_ENABLE - default CBE_CPUFREQ - -config PPC_PMI - tristate - default y - depends on CBE_CPUFREQ_PMI || PPC_IBM_CELL_POWERBUTTON - help - PMI (Platform Management Interrupt) is a way to - communicate with the BMC (Baseboard Management Controller). - It is used in some IBM Cell blades. - config CBE_CPUFREQ_SPU_GOVERNOR tristate "CBE frequency scaling based on SPU usage" depends on SPU_FS && CPU_FREQ diff --git a/trunk/arch/powerpc/platforms/cell/Makefile b/trunk/arch/powerpc/platforms/cell/Makefile index 83fafe922641..43eccb270301 100644 --- a/trunk/arch/powerpc/platforms/cell/Makefile +++ b/trunk/arch/powerpc/platforms/cell/Makefile @@ -28,7 +28,7 @@ obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \ $(spu-manage-y) \ spufs/ -obj-$(CONFIG_AXON_MSI) += axon_msi.o +obj-$(CONFIG_PCI_MSI) += axon_msi.o # qpace setup obj-$(CONFIG_PPC_CELL_QPACE) += qpace_setup.o diff --git a/trunk/arch/powerpc/platforms/cell/io-workarounds.c b/trunk/arch/powerpc/platforms/cell/io-workarounds.c index 5c1118e31940..059cad6c3f69 100644 --- a/trunk/arch/powerpc/platforms/cell/io-workarounds.c +++ b/trunk/arch/powerpc/platforms/cell/io-workarounds.c @@ -131,10 +131,10 @@ static const struct ppc_pci_io __devinitconst iowa_pci_io = { }; static void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size, - unsigned long flags, void *caller) + unsigned long flags) { struct iowa_bus *bus; - void __iomem *res = __ioremap_caller(addr, size, flags, caller); + void __iomem *res = __ioremap(addr, size, flags); int busno; bus = iowa_pci_find(0, (unsigned long)addr); diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c index 5744527a7f2a..ee5033eddf01 100644 --- a/trunk/arch/powerpc/platforms/cell/iommu.c +++ b/trunk/arch/powerpc/platforms/cell/iommu.c @@ -74,7 +74,7 @@ #define IOC_IO_ExcpStat_V 0x8000000000000000ul #define IOC_IO_ExcpStat_SPF_Mask 0x6000000000000000ul #define IOC_IO_ExcpStat_SPF_S 0x6000000000000000ul -#define IOC_IO_ExcpStat_SPF_P 0x2000000000000000ul +#define IOC_IO_ExcpStat_SPF_P 0x4000000000000000ul #define IOC_IO_ExcpStat_ADDR_Mask 0x00000007fffff000ul #define IOC_IO_ExcpStat_RW_Mask 0x0000000000000800ul #define IOC_IO_ExcpStat_IOID_Mask 0x00000000000007fful @@ -247,18 +247,17 @@ static void tce_free_cell(struct iommu_table *tbl, long index, long npages) static irqreturn_t ioc_interrupt(int irq, void *data) { - unsigned long stat, spf; + unsigned long stat; struct cbe_iommu *iommu = data; stat = in_be64(iommu->xlate_regs + IOC_IO_ExcpStat); - spf = stat & IOC_IO_ExcpStat_SPF_Mask; /* Might want to rate limit it */ printk(KERN_ERR "iommu: DMA exception 0x%016lx\n", stat); printk(KERN_ERR " V=%d, SPF=[%c%c], RW=%s, IOID=0x%04x\n", !!(stat & IOC_IO_ExcpStat_V), - (spf == IOC_IO_ExcpStat_SPF_S) ? 'S' : ' ', - (spf == IOC_IO_ExcpStat_SPF_P) ? 'P' : ' ', + (stat & IOC_IO_ExcpStat_SPF_S) ? 'S' : ' ', + (stat & IOC_IO_ExcpStat_SPF_P) ? 'P' : ' ', (stat & IOC_IO_ExcpStat_RW_Mask) ? "Read" : "Write", (unsigned int)(stat & IOC_IO_ExcpStat_IOID_Mask)); printk(KERN_ERR " page=0x%016lx\n", diff --git a/trunk/arch/powerpc/platforms/cell/qpace_setup.c b/trunk/arch/powerpc/platforms/cell/qpace_setup.c index c5ce02e84c8e..be84e6a16b30 100644 --- a/trunk/arch/powerpc/platforms/cell/qpace_setup.c +++ b/trunk/arch/powerpc/platforms/cell/qpace_setup.c @@ -81,6 +81,16 @@ static int __init qpace_publish_devices(void) } machine_subsys_initcall(qpace, qpace_publish_devices); +extern int qpace_notify(struct device *dev) +{ + /* set dma_ops for of_platform bus */ + if (dev->bus && dev->bus->name + && !strcmp(dev->bus->name, "of_platform")) + set_dma_ops(dev, &dma_direct_ops); + + return 0; +} + static void __init qpace_setup_arch(void) { #ifdef CONFIG_SPU_BASE @@ -105,6 +115,9 @@ static void __init qpace_setup_arch(void) #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif + + /* set notifier function */ + platform_notify = &qpace_notify; } static int __init qpace_probe(void) @@ -128,8 +141,6 @@ define_machine(qpace) { .power_off = rtas_power_off, .halt = rtas_halt, .get_boot_time = rtas_get_boot_time, - .get_rtc_time = rtas_get_rtc_time, - .set_rtc_time = rtas_set_rtc_time, .calibrate_decr = generic_calibrate_decr, .progress = qpace_progress, .init_IRQ = iic_init_IRQ, diff --git a/trunk/arch/powerpc/platforms/cell/spu_base.c b/trunk/arch/powerpc/platforms/cell/spu_base.c index 9abd210d87c1..e487ad68ac11 100644 --- a/trunk/arch/powerpc/platforms/cell/spu_base.c +++ b/trunk/arch/powerpc/platforms/cell/spu_base.c @@ -114,7 +114,7 @@ static inline void mm_needs_global_tlbie(struct mm_struct *mm) int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1; /* Global TLBIE broadcast required with SPEs. */ - bitmap_fill(cpumask_bits(mm_cpumask(mm)), nr); + __cpus_setall(&mm->cpu_vm_mask, nr); } void spu_associate_mm(struct spu *spu, struct mm_struct *mm) diff --git a/trunk/arch/powerpc/platforms/cell/spu_fault.c b/trunk/arch/powerpc/platforms/cell/spu_fault.c index 95d8dadf2d87..c8b1cd42905d 100644 --- a/trunk/arch/powerpc/platforms/cell/spu_fault.c +++ b/trunk/arch/powerpc/platforms/cell/spu_fault.c @@ -39,56 +39,60 @@ int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea, unsigned long is_write; int ret; - if (mm == NULL) +#if 0 + if (!IS_VALID_EA(ea)) { return -EFAULT; - - if (mm->pgd == NULL) + } +#endif /* XXX */ + if (mm == NULL) { + return -EFAULT; + } + if (mm->pgd == NULL) { return -EFAULT; + } down_read(&mm->mmap_sem); - ret = -EFAULT; vma = find_vma(mm, ea); if (!vma) - goto out_unlock; - - if (ea < vma->vm_start) { - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto out_unlock; - if (expand_stack(vma, ea)) - goto out_unlock; - } - + goto bad_area; + if (vma->vm_start <= ea) + goto good_area; + if (!(vma->vm_flags & VM_GROWSDOWN)) + goto bad_area; + if (expand_stack(vma, ea)) + goto bad_area; +good_area: is_write = dsisr & MFC_DSISR_ACCESS_PUT; if (is_write) { if (!(vma->vm_flags & VM_WRITE)) - goto out_unlock; + goto bad_area; } else { if (dsisr & MFC_DSISR_ACCESS_DENIED) - goto out_unlock; + goto bad_area; if (!(vma->vm_flags & (VM_READ | VM_EXEC))) - goto out_unlock; + goto bad_area; } - ret = 0; *flt = handle_mm_fault(mm, vma, ea, is_write); if (unlikely(*flt & VM_FAULT_ERROR)) { if (*flt & VM_FAULT_OOM) { ret = -ENOMEM; - goto out_unlock; + goto bad_area; } else if (*flt & VM_FAULT_SIGBUS) { ret = -EFAULT; - goto out_unlock; + goto bad_area; } BUG(); } - if (*flt & VM_FAULT_MAJOR) current->maj_flt++; else current->min_flt++; - -out_unlock: up_read(&mm->mmap_sem); return ret; + +bad_area: + up_read(&mm->mmap_sem); + return -EFAULT; } EXPORT_SYMBOL_GPL(spu_handle_mm_fault); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/context.c b/trunk/arch/powerpc/platforms/cell/spufs/context.c index db5398c0339f..6653ddbed048 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/context.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/context.c @@ -35,8 +35,6 @@ atomic_t nr_spu_contexts = ATOMIC_INIT(0); struct spu_context *alloc_spu_context(struct spu_gang *gang) { struct spu_context *ctx; - struct timespec ts; - ctx = kzalloc(sizeof *ctx, GFP_KERNEL); if (!ctx) goto out; @@ -66,8 +64,6 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang) __spu_update_sched_info(ctx); spu_set_timeslice(ctx); ctx->stats.util_state = SPU_UTIL_IDLE_LOADED; - ktime_get_ts(&ts); - ctx->stats.tstamp = timespec_to_ns(&ts); atomic_inc(&nr_spu_contexts); goto out; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/file.c b/trunk/arch/powerpc/platforms/cell/spufs/file.c index d6a519e6e1c1..0da7f2bf5ee1 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/file.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/file.c @@ -568,17 +568,16 @@ spufs_regs_write(struct file *file, const char __user *buffer, struct spu_lscsa *lscsa = ctx->csa.lscsa; int ret; - if (*pos >= sizeof(lscsa->gprs)) + size = min_t(ssize_t, sizeof lscsa->gprs - *pos, size); + if (size <= 0) return -EFBIG; - - size = min_t(ssize_t, sizeof(lscsa->gprs) - *pos, size); *pos += size; ret = spu_acquire_saved(ctx); if (ret) return ret; - ret = copy_from_user((char *)lscsa->gprs + *pos - size, + ret = copy_from_user(lscsa->gprs + *pos - size, buffer, size) ? -EFAULT : size; spu_release_saved(ctx); @@ -624,10 +623,9 @@ spufs_fpcr_write(struct file *file, const char __user * buffer, struct spu_lscsa *lscsa = ctx->csa.lscsa; int ret; - if (*pos >= sizeof(lscsa->fpcr)) - return -EFBIG; - size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size); + if (size <= 0) + return -EFBIG; ret = spu_acquire_saved(ctx); if (ret) @@ -2667,7 +2665,7 @@ static const struct file_operations spufs_ctx_fops = { .release = single_release, }; -const struct spufs_tree_descr spufs_dir_contents[] = { +struct spufs_tree_descr spufs_dir_contents[] = { { "capabilities", &spufs_caps_fops, 0444, }, { "mem", &spufs_mem_fops, 0666, LS_SIZE, }, { "regs", &spufs_regs_fops, 0666, sizeof(struct spu_reg128[128]), }, @@ -2708,7 +2706,7 @@ const struct spufs_tree_descr spufs_dir_contents[] = { {}, }; -const struct spufs_tree_descr spufs_dir_nosched_contents[] = { +struct spufs_tree_descr spufs_dir_nosched_contents[] = { { "capabilities", &spufs_caps_fops, 0444, }, { "mem", &spufs_mem_fops, 0666, LS_SIZE, }, { "mbox", &spufs_mbox_fops, 0444, }, @@ -2733,12 +2731,12 @@ const struct spufs_tree_descr spufs_dir_nosched_contents[] = { {}, }; -const struct spufs_tree_descr spufs_dir_debug_contents[] = { +struct spufs_tree_descr spufs_dir_debug_contents[] = { { ".ctx", &spufs_ctx_fops, 0444, }, {}, }; -const struct spufs_coredump_reader spufs_coredump_read[] = { +struct spufs_coredump_reader spufs_coredump_read[] = { { "regs", __spufs_regs_read, NULL, sizeof(struct spu_reg128[128])}, { "fpcr", __spufs_fpcr_read, NULL, sizeof(struct spu_reg128) }, { "lslr", NULL, spufs_lslr_get, 19 }, diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index 64f068540d0d..e309ef70a531 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -186,9 +186,8 @@ static int spufs_rmdir(struct inode *parent, struct dentry *dir) return simple_rmdir(parent, dir); } -static int spufs_fill_dir(struct dentry *dir, - const struct spufs_tree_descr *files, int mode, - struct spu_context *ctx) +static int spufs_fill_dir(struct dentry *dir, struct spufs_tree_descr *files, + int mode, struct spu_context *ctx) { struct dentry *dentry, *tmp; int ret; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/run.c b/trunk/arch/powerpc/platforms/cell/spufs/run.c index 4ddf769a64e5..c58bd36b0c5b 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/run.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/run.c @@ -117,9 +117,6 @@ static int spu_setup_isolated(struct spu_context *ctx) cond_resched(); } - /* clear purge status */ - out_be64(mfc_cntl, 0); - /* put the SPE in kernel mode to allow access to the loader */ sr1 = spu_mfc_sr1_get(ctx->spu); sr1 &= ~MFC_STATE1_PROBLEM_STATE_MASK; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spufs.h b/trunk/arch/powerpc/platforms/cell/spufs/spufs.h index ae31573bea4a..3bf908e2873a 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/trunk/arch/powerpc/platforms/cell/spufs/spufs.h @@ -241,9 +241,9 @@ struct spufs_tree_descr { size_t size; }; -extern const struct spufs_tree_descr spufs_dir_contents[]; -extern const struct spufs_tree_descr spufs_dir_nosched_contents[]; -extern const struct spufs_tree_descr spufs_dir_debug_contents[]; +extern struct spufs_tree_descr spufs_dir_contents[]; +extern struct spufs_tree_descr spufs_dir_nosched_contents[]; +extern struct spufs_tree_descr spufs_dir_debug_contents[]; /* system call implementation */ extern struct spufs_calls spufs_calls; @@ -358,7 +358,7 @@ struct spufs_coredump_reader { u64 (*get)(struct spu_context *ctx); size_t size; }; -extern const struct spufs_coredump_reader spufs_coredump_read[]; +extern struct spufs_coredump_reader spufs_coredump_read[]; extern int spufs_coredump_num_notes; extern int spu_init_csa(struct spu_state *csa); diff --git a/trunk/arch/powerpc/platforms/chrp/Kconfig b/trunk/arch/powerpc/platforms/chrp/Kconfig index 37d438bd5b7a..22b4b4e3b6f0 100644 --- a/trunk/arch/powerpc/platforms/chrp/Kconfig +++ b/trunk/arch/powerpc/platforms/chrp/Kconfig @@ -1,6 +1,6 @@ config PPC_CHRP bool "Common Hardware Reference Platform (CHRP) based machines" - depends on 6xx + depends on PPC_MULTIPLATFORM && PPC32 select MPIC select PPC_I8259 select PPC_INDIRECT_PCI diff --git a/trunk/arch/powerpc/platforms/chrp/pegasos_eth.c b/trunk/arch/powerpc/platforms/chrp/pegasos_eth.c index 039fc8e82199..130ff72d99dd 100644 --- a/trunk/arch/powerpc/platforms/chrp/pegasos_eth.c +++ b/trunk/arch/powerpc/platforms/chrp/pegasos_eth.c @@ -21,8 +21,8 @@ #define PEGASOS2_SRAM_BASE (0xf2000000) #define PEGASOS2_SRAM_SIZE (256*1024) -#define PEGASOS2_SRAM_BASE_ETH_PORT0 (PEGASOS2_SRAM_BASE) -#define PEGASOS2_SRAM_BASE_ETH_PORT1 (PEGASOS2_SRAM_BASE_ETH_PORT0 + (PEGASOS2_SRAM_SIZE / 2) ) +#define PEGASOS2_SRAM_BASE_ETH0 (PEGASOS2_SRAM_BASE) +#define PEGASOS2_SRAM_BASE_ETH1 (PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) ) #define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4) @@ -47,42 +47,75 @@ static struct platform_device mv643xx_eth_shared_device = { .resource = mv643xx_eth_shared_resources, }; -static struct resource mv643xx_eth_port1_resources[] = { +static struct resource mv643xx_eth0_resources[] = { [0] = { - .name = "eth port1 irq", + .name = "eth0 irq", .start = 9, .end = 9, .flags = IORESOURCE_IRQ, }, }; -static struct mv643xx_eth_platform_data eth_port1_pd = { + +static struct mv643xx_eth_platform_data eth0_pd = { + .shared = &mv643xx_eth_shared_device, + .port_number = 0, + + .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0, + .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, + .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, + + .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE, + .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE, + .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16, +}; + +static struct platform_device eth0_device = { + .name = MV643XX_ETH_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv643xx_eth0_resources), + .resource = mv643xx_eth0_resources, + .dev = { + .platform_data = ð0_pd, + }, +}; + +static struct resource mv643xx_eth1_resources[] = { + [0] = { + .name = "eth1 irq", + .start = 9, + .end = 9, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mv643xx_eth_platform_data eth1_pd = { .shared = &mv643xx_eth_shared_device, .port_number = 1, - .phy_addr = MV643XX_ETH_PHY_ADDR(7), - .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH_PORT1, + .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1, .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, - .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH_PORT1 + PEGASOS2_SRAM_TXRING_SIZE, + .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE, .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE, .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16, }; -static struct platform_device eth_port1_device = { +static struct platform_device eth1_device = { .name = MV643XX_ETH_NAME, .id = 1, - .num_resources = ARRAY_SIZE(mv643xx_eth_port1_resources), - .resource = mv643xx_eth_port1_resources, + .num_resources = ARRAY_SIZE(mv643xx_eth1_resources), + .resource = mv643xx_eth1_resources, .dev = { - .platform_data = ð_port1_pd, + .platform_data = ð1_pd, }, }; static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { &mv643xx_eth_shared_device, - ð_port1_device, + ð0_device, + ð1_device, }; /***********/ @@ -158,10 +191,15 @@ static int __init mv643xx_eth_add_pds(void) if ( Enable_SRAM() < 0) { - eth_port1_pd.tx_sram_addr = 0; - eth_port1_pd.tx_sram_size = 0; - eth_port1_pd.rx_sram_addr = 0; - eth_port1_pd.rx_sram_size = 0; + eth0_pd.tx_sram_addr = 0; + eth0_pd.tx_sram_size = 0; + eth0_pd.rx_sram_addr = 0; + eth0_pd.rx_sram_size = 0; + + eth1_pd.tx_sram_addr = 0; + eth1_pd.tx_sram_size = 0; + eth1_pd.rx_sram_addr = 0; + eth1_pd.rx_sram_size = 0; #ifdef BE_VERBOSE printk("Pegasos II/Marvell MV64361: Can't enable the " diff --git a/trunk/arch/powerpc/platforms/chrp/setup.c b/trunk/arch/powerpc/platforms/chrp/setup.c index cd4ad9aea760..272d79a8d289 100644 --- a/trunk/arch/powerpc/platforms/chrp/setup.c +++ b/trunk/arch/powerpc/platforms/chrp/setup.c @@ -472,6 +472,7 @@ static void __init chrp_find_openpic(void) #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_XMON) static struct irqaction xmon_irqaction = { .handler = xmon_irq, + .mask = CPU_MASK_NONE, .name = "XMON break", }; #endif diff --git a/trunk/arch/powerpc/platforms/embedded6xx/Kconfig b/trunk/arch/powerpc/platforms/embedded6xx/Kconfig index 291ac9d8cbee..4f9f8184d164 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/trunk/arch/powerpc/platforms/embedded6xx/Kconfig @@ -1,6 +1,6 @@ config EMBEDDED6xx bool "Embedded 6xx/7xx/7xxx-based boards" - depends on 6xx && BROKEN_ON_SMP + depends on PPC32 && BROKEN_ON_SMP && PPC_MULTIPLATFORM config LINKSTATION bool "Linkstation / Kurobox(HG) from Buffalo" diff --git a/trunk/arch/powerpc/platforms/iseries/Kconfig b/trunk/arch/powerpc/platforms/iseries/Kconfig index 647e87787437..7ddd0a2c8027 100644 --- a/trunk/arch/powerpc/platforms/iseries/Kconfig +++ b/trunk/arch/powerpc/platforms/iseries/Kconfig @@ -1,6 +1,6 @@ config PPC_ISERIES bool "IBM Legacy iSeries" - depends on PPC64 && PPC_BOOK3S + depends on PPC_MULTIPLATFORM && PPC64 select PPC_INDIRECT_IO select PPC_PCI_CHOICE if EMBEDDED diff --git a/trunk/arch/powerpc/platforms/iseries/irq.c b/trunk/arch/powerpc/platforms/iseries/irq.c index 94f444758836..701d9297c207 100644 --- a/trunk/arch/powerpc/platforms/iseries/irq.c +++ b/trunk/arch/powerpc/platforms/iseries/irq.c @@ -214,7 +214,7 @@ void __init iSeries_activate_IRQs() unsigned long flags; for_each_irq (irq) { - struct irq_desc *desc = get_irq_desc(irq); + irq_desc_t *desc = get_irq_desc(irq); if (desc && desc->chip && desc->chip->startup) { spin_lock_irqsave(&desc->lock, flags); diff --git a/trunk/arch/powerpc/platforms/iseries/setup.c b/trunk/arch/powerpc/platforms/iseries/setup.c index a6cd3394feaa..24519b96d6ad 100644 --- a/trunk/arch/powerpc/platforms/iseries/setup.c +++ b/trunk/arch/powerpc/platforms/iseries/setup.c @@ -617,7 +617,7 @@ static void iseries_dedicated_idle(void) } static void __iomem *iseries_ioremap(phys_addr_t address, unsigned long size, - unsigned long flags, void *caller) + unsigned long flags) { return (void __iomem *)address; } diff --git a/trunk/arch/powerpc/platforms/maple/Kconfig b/trunk/arch/powerpc/platforms/maple/Kconfig index 1ea621a94c3b..a6467a5591fa 100644 --- a/trunk/arch/powerpc/platforms/maple/Kconfig +++ b/trunk/arch/powerpc/platforms/maple/Kconfig @@ -1,5 +1,5 @@ config PPC_MAPLE - depends on PPC64 && PPC_BOOK3S + depends on PPC_MULTIPLATFORM && PPC64 bool "Maple 970FX Evaluation Board" select PCI select MPIC diff --git a/trunk/arch/powerpc/platforms/pasemi/Kconfig b/trunk/arch/powerpc/platforms/pasemi/Kconfig index a2aeb327d185..348e0619e3e5 100644 --- a/trunk/arch/powerpc/platforms/pasemi/Kconfig +++ b/trunk/arch/powerpc/platforms/pasemi/Kconfig @@ -1,5 +1,5 @@ config PPC_PASEMI - depends on PPC64 && PPC_BOOK3S + depends on PPC_MULTIPLATFORM && PPC64 bool "PA Semi SoC-based platforms" default n select MPIC diff --git a/trunk/arch/powerpc/platforms/powermac/Kconfig b/trunk/arch/powerpc/platforms/powermac/Kconfig index 1e1a0873e1dd..055990ca8ce6 100644 --- a/trunk/arch/powerpc/platforms/powermac/Kconfig +++ b/trunk/arch/powerpc/platforms/powermac/Kconfig @@ -1,6 +1,6 @@ config PPC_PMAC bool "Apple PowerMac based machines" - depends on PPC_BOOK3S + depends on PPC_MULTIPLATFORM select MPIC select PCI select PPC_INDIRECT_PCI if PPC32 diff --git a/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c b/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c index 22ecfbe7183d..beb38333b6d2 100644 --- a/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c +++ b/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c @@ -86,7 +86,6 @@ static int (*g5_query_freq)(void); static DEFINE_MUTEX(g5_switch_mutex); -static unsigned long transition_latency; #ifdef CONFIG_PMAC_SMU @@ -358,7 +357,7 @@ static unsigned int g5_cpufreq_get_speed(unsigned int cpu) static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy) { - policy->cpuinfo.transition_latency = transition_latency; + policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = g5_cpu_freqs[g5_query_freq()].frequency; /* secondary CPUs are tied to the primary one by the * cpufreq core if in the secondary policy we tell it that @@ -501,7 +500,6 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) g5_cpu_freqs[1].frequency = max_freq/2; /* Set callbacks */ - transition_latency = 12000; g5_switch_freq = g5_scom_switch_freq; g5_query_freq = g5_scom_query_freq; freq_method = "SCOM"; @@ -677,7 +675,6 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) g5_cpu_freqs[1].frequency = min_freq; /* Set callbacks */ - transition_latency = CPUFREQ_ETERNAL; g5_switch_volt = g5_pfunc_switch_volt; g5_switch_freq = g5_pfunc_switch_freq; g5_query_freq = g5_pfunc_query_freq; diff --git a/trunk/arch/powerpc/platforms/powermac/pic.c b/trunk/arch/powerpc/platforms/powermac/pic.c index 7039d8f1d3ba..6d149ae8ffa7 100644 --- a/trunk/arch/powerpc/platforms/powermac/pic.c +++ b/trunk/arch/powerpc/platforms/powermac/pic.c @@ -266,6 +266,7 @@ static unsigned int pmac_pic_get_irq(void) static struct irqaction xmon_action = { .handler = xmon_irq, .flags = 0, + .mask = CPU_MASK_NONE, .name = "NMI - XMON" }; #endif @@ -273,6 +274,7 @@ static struct irqaction xmon_action = { static struct irqaction gatwick_cascade_action = { .handler = gatwick_action, .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, .name = "cascade", }; diff --git a/trunk/arch/powerpc/platforms/powermac/pic.h b/trunk/arch/powerpc/platforms/powermac/pic.h index d622a8345aaa..c44c89f5e532 100644 --- a/trunk/arch/powerpc/platforms/powermac/pic.h +++ b/trunk/arch/powerpc/platforms/powermac/pic.h @@ -3,7 +3,7 @@ #include -extern struct irq_chip pmac_pic; +extern struct hw_interrupt_type pmac_pic; extern void pmac_pic_init(void); extern int pmac_get_irq(void); diff --git a/trunk/arch/powerpc/platforms/powermac/setup.c b/trunk/arch/powerpc/platforms/powermac/setup.c index 45936c9ed0ec..9b78f5300c24 100644 --- a/trunk/arch/powerpc/platforms/powermac/setup.c +++ b/trunk/arch/powerpc/platforms/powermac/setup.c @@ -746,7 +746,4 @@ define_machine(powermac) { #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) .cpu_die = pmac_cpu_die, #endif -#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) - .cpu_die = generic_mach_cpu_die, -#endif }; diff --git a/trunk/arch/powerpc/platforms/powermac/smp.c b/trunk/arch/powerpc/platforms/powermac/smp.c index cf1dbe758890..bd8817b00fa4 100644 --- a/trunk/arch/powerpc/platforms/powermac/smp.c +++ b/trunk/arch/powerpc/platforms/powermac/smp.c @@ -385,6 +385,7 @@ static void __init psurge_dual_sync_tb(int cpu_nr) static struct irqaction psurge_irqaction = { .handler = psurge_primary_intr, .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, .name = "primary IPI", }; diff --git a/trunk/arch/powerpc/platforms/prep/Kconfig b/trunk/arch/powerpc/platforms/prep/Kconfig index bf8330ef2e76..29d411279b0c 100644 --- a/trunk/arch/powerpc/platforms/prep/Kconfig +++ b/trunk/arch/powerpc/platforms/prep/Kconfig @@ -1,6 +1,6 @@ config PPC_PREP bool "PowerPC Reference Platform (PReP) based machines" - depends on 6xx && BROKEN + depends on PPC_MULTIPLATFORM && PPC32 && BROKEN select MPIC select PPC_I8259 select PPC_INDIRECT_PCI diff --git a/trunk/arch/powerpc/platforms/ps3/Kconfig b/trunk/arch/powerpc/platforms/ps3/Kconfig index dfe316b161a9..740ef56a1550 100644 --- a/trunk/arch/powerpc/platforms/ps3/Kconfig +++ b/trunk/arch/powerpc/platforms/ps3/Kconfig @@ -1,6 +1,6 @@ config PPC_PS3 bool "Sony PS3" - depends on PPC64 && PPC_BOOK3S + depends on PPC_MULTIPLATFORM && PPC64 select PPC_CELL select USB_ARCH_HAS_OHCI select USB_OHCI_LITTLE_ENDIAN diff --git a/trunk/arch/powerpc/platforms/ps3/mm.c b/trunk/arch/powerpc/platforms/ps3/mm.c index 9a2b6d948610..d281cc0bca71 100644 --- a/trunk/arch/powerpc/platforms/ps3/mm.c +++ b/trunk/arch/powerpc/platforms/ps3/mm.c @@ -311,7 +311,7 @@ static int __init ps3_mm_add_memory(void) result = add_memory(0, start_addr, map.r1.size); if (result) { - pr_err("%s:%d: add_memory failed: (%d)\n", + DBG("%s:%d: add_memory failed: (%d)\n", __func__, __LINE__, result); return result; } @@ -322,7 +322,7 @@ static int __init ps3_mm_add_memory(void) result = online_pages(start_pfn, nr_pages); if (result) - pr_err("%s:%d: online_pages failed: (%d)\n", + DBG("%s:%d: online_pages failed: (%d)\n", __func__, __LINE__, result); return result; diff --git a/trunk/arch/powerpc/platforms/pseries/Kconfig b/trunk/arch/powerpc/platforms/pseries/Kconfig index f0e6f28427bd..ddc2a307cd50 100644 --- a/trunk/arch/powerpc/platforms/pseries/Kconfig +++ b/trunk/arch/powerpc/platforms/pseries/Kconfig @@ -1,5 +1,5 @@ config PPC_PSERIES - depends on PPC64 && PPC_BOOK3S + depends on PPC_MULTIPLATFORM && PPC64 bool "IBM pSeries & new (POWER5-based) iSeries" select MPIC select PPC_I8259 @@ -25,11 +25,6 @@ config EEH depends on PPC_PSERIES && PCI default y if !EMBEDDED -config PSERIES_MSI - bool - depends on PCI_MSI && EEH - default y - config SCANLOG tristate "Scanlog dump interface" depends on RTAS_PROC && PPC_PSERIES @@ -68,13 +63,3 @@ config CMM makes sense for a system running in an LPAR where the unused pages will be reused for other LPARs. The interface allows firmware to balance memory across many LPARs. - -config DTL - bool "Dispatch Trace Log" - depends on PPC_SPLPAR && DEBUG_FS - help - SPLPAR machines can log hypervisor preempt & dispatch events to a - kernel buffer. Saying Y here will enable logging these events, - which are accessible through a debugfs file. - - Say N if you are unsure. diff --git a/trunk/arch/powerpc/platforms/pseries/Makefile b/trunk/arch/powerpc/platforms/pseries/Makefile index 790c0b872d4f..dfe574af2dc0 100644 --- a/trunk/arch/powerpc/platforms/pseries/Makefile +++ b/trunk/arch/powerpc/platforms/pseries/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_SCANLOG) += scanlog.o obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o eeh_sysfs.o obj-$(CONFIG_KEXEC) += kexec.o obj-$(CONFIG_PCI) += pci.o pci_dlpar.o -obj-$(CONFIG_PSERIES_MSI) += msi.o +obj-$(CONFIG_PCI_MSI) += msi.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o @@ -25,4 +25,3 @@ obj-$(CONFIG_HVCS) += hvcserver.o obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o obj-$(CONFIG_CMM) += cmm.o -obj-$(CONFIG_DTL) += dtl.o diff --git a/trunk/arch/powerpc/platforms/pseries/dtl.c b/trunk/arch/powerpc/platforms/pseries/dtl.c deleted file mode 100644 index fafcaa0e81ef..000000000000 --- a/trunk/arch/powerpc/platforms/pseries/dtl.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Virtual Processor Dispatch Trace Log - * - * (C) Copyright IBM Corporation 2009 - * - * Author: Jeremy Kerr - * - * 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, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include - -#include "plpar_wrappers.h" - -/* - * Layout of entries in the hypervisor's DTL buffer. Although we don't - * actually access the internals of an entry (we only need to know the size), - * we might as well define it here for reference. - */ -struct dtl_entry { - u8 dispatch_reason; - u8 preempt_reason; - u16 processor_id; - u32 enqueue_to_dispatch_time; - u32 ready_to_enqueue_time; - u32 waiting_to_ready_time; - u64 timebase; - u64 fault_addr; - u64 srr0; - u64 srr1; -}; - -struct dtl { - struct dtl_entry *buf; - struct dentry *file; - int cpu; - int buf_entries; - u64 last_idx; -}; -static DEFINE_PER_CPU(struct dtl, dtl); - -/* - * Dispatch trace log event mask: - * 0x7: 0x1: voluntary virtual processor waits - * 0x2: time-slice preempts - * 0x4: virtual partition memory page faults - */ -static u8 dtl_event_mask = 0x7; - - -/* - * Size of per-cpu log buffers. Default is just under 16 pages worth. - */ -static int dtl_buf_entries = (16 * 85); - - -static int dtl_enable(struct dtl *dtl) -{ - unsigned long addr; - int ret, hwcpu; - - /* only allow one reader */ - if (dtl->buf) - return -EBUSY; - - /* we need to store the original allocation size for use during read */ - dtl->buf_entries = dtl_buf_entries; - - dtl->buf = kmalloc_node(dtl->buf_entries * sizeof(struct dtl_entry), - GFP_KERNEL, cpu_to_node(dtl->cpu)); - if (!dtl->buf) { - printk(KERN_WARNING "%s: buffer alloc failed for cpu %d\n", - __func__, dtl->cpu); - return -ENOMEM; - } - - /* Register our dtl buffer with the hypervisor. The HV expects the - * buffer size to be passed in the second word of the buffer */ - ((u32 *)dtl->buf)[1] = dtl->buf_entries * sizeof(struct dtl_entry); - - hwcpu = get_hard_smp_processor_id(dtl->cpu); - addr = __pa(dtl->buf); - ret = register_dtl(hwcpu, addr); - if (ret) { - printk(KERN_WARNING "%s: DTL registration for cpu %d (hw %d) " - "failed with %d\n", __func__, dtl->cpu, hwcpu, ret); - kfree(dtl->buf); - return -EIO; - } - - /* set our initial buffer indices */ - dtl->last_idx = lppaca[dtl->cpu].dtl_idx = 0; - - /* ensure that our updates to the lppaca fields have occurred before - * we actually enable the logging */ - smp_wmb(); - - /* enable event logging */ - lppaca[dtl->cpu].dtl_enable_mask = dtl_event_mask; - - return 0; -} - -static void dtl_disable(struct dtl *dtl) -{ - int hwcpu = get_hard_smp_processor_id(dtl->cpu); - - lppaca[dtl->cpu].dtl_enable_mask = 0x0; - - unregister_dtl(hwcpu, __pa(dtl->buf)); - - kfree(dtl->buf); - dtl->buf = NULL; - dtl->buf_entries = 0; -} - -/* file interface */ - -static int dtl_file_open(struct inode *inode, struct file *filp) -{ - struct dtl *dtl = inode->i_private; - int rc; - - rc = dtl_enable(dtl); - if (rc) - return rc; - - filp->private_data = dtl; - return 0; -} - -static int dtl_file_release(struct inode *inode, struct file *filp) -{ - struct dtl *dtl = inode->i_private; - dtl_disable(dtl); - return 0; -} - -static ssize_t dtl_file_read(struct file *filp, char __user *buf, size_t len, - loff_t *pos) -{ - int rc, cur_idx, last_idx, n_read, n_req, read_size; - struct dtl *dtl; - - if ((len % sizeof(struct dtl_entry)) != 0) - return -EINVAL; - - dtl = filp->private_data; - - /* requested number of entries to read */ - n_req = len / sizeof(struct dtl_entry); - - /* actual number of entries read */ - n_read = 0; - - cur_idx = lppaca[dtl->cpu].dtl_idx; - last_idx = dtl->last_idx; - - if (cur_idx - last_idx > dtl->buf_entries) { - pr_debug("%s: hv buffer overflow for cpu %d, samples lost\n", - __func__, dtl->cpu); - } - - cur_idx %= dtl->buf_entries; - last_idx %= dtl->buf_entries; - - /* read the tail of the buffer if we've wrapped */ - if (last_idx > cur_idx) { - read_size = min(n_req, dtl->buf_entries - last_idx); - - rc = copy_to_user(buf, &dtl->buf[last_idx], - read_size * sizeof(struct dtl_entry)); - if (rc) - return -EFAULT; - - last_idx = 0; - n_req -= read_size; - n_read += read_size; - buf += read_size * sizeof(struct dtl_entry); - } - - /* .. and now the head */ - read_size = min(n_req, cur_idx - last_idx); - rc = copy_to_user(buf, &dtl->buf[last_idx], - read_size * sizeof(struct dtl_entry)); - if (rc) - return -EFAULT; - - n_read += read_size; - dtl->last_idx += n_read; - - return n_read * sizeof(struct dtl_entry); -} - -static struct file_operations dtl_fops = { - .open = dtl_file_open, - .release = dtl_file_release, - .read = dtl_file_read, - .llseek = no_llseek, -}; - -static struct dentry *dtl_dir; - -static int dtl_setup_file(struct dtl *dtl) -{ - char name[10]; - - sprintf(name, "cpu-%d", dtl->cpu); - - dtl->file = debugfs_create_file(name, 0400, dtl_dir, dtl, &dtl_fops); - if (!dtl->file) - return -ENOMEM; - - return 0; -} - -static int dtl_init(void) -{ - struct dentry *event_mask_file, *buf_entries_file; - int rc, i; - - if (!firmware_has_feature(FW_FEATURE_SPLPAR)) - return -ENODEV; - - /* set up common debugfs structure */ - - rc = -ENOMEM; - dtl_dir = debugfs_create_dir("dtl", powerpc_debugfs_root); - if (!dtl_dir) { - printk(KERN_WARNING "%s: can't create dtl root dir\n", - __func__); - goto err; - } - - event_mask_file = debugfs_create_x8("dtl_event_mask", 0600, - dtl_dir, &dtl_event_mask); - buf_entries_file = debugfs_create_u32("dtl_buf_entries", 0600, - dtl_dir, &dtl_buf_entries); - - if (!event_mask_file || !buf_entries_file) { - printk(KERN_WARNING "%s: can't create dtl files\n", __func__); - goto err_remove_dir; - } - - /* set up the per-cpu log structures */ - for_each_possible_cpu(i) { - struct dtl *dtl = &per_cpu(dtl, i); - dtl->cpu = i; - - rc = dtl_setup_file(dtl); - if (rc) - goto err_remove_dir; - } - - return 0; - -err_remove_dir: - debugfs_remove_recursive(dtl_dir); -err: - return rc; -} -arch_initcall(dtl_init); diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c index 380420f8c400..0ad56ff7b4a0 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c @@ -79,40 +79,6 @@ static int irq_in_use(unsigned int irq) return rc; } -/** - * eeh_disable_irq - disable interrupt for the recovering device - */ -static void eeh_disable_irq(struct pci_dev *dev) -{ - struct device_node *dn = pci_device_to_OF_node(dev); - - /* Don't disable MSI and MSI-X interrupts. They are - * effectively disabled by the DMA Stopped state - * when an EEH error occurs. - */ - if (dev->msi_enabled || dev->msix_enabled) - return; - - if (!irq_in_use(dev->irq)) - return; - - PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED; - disable_irq_nosync(dev->irq); -} - -/** - * eeh_enable_irq - enable interrupt for the recovering device - */ -static void eeh_enable_irq(struct pci_dev *dev) -{ - struct device_node *dn = pci_device_to_OF_node(dev); - - if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) { - PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED; - enable_irq(dev->irq); - } -} - /* ------------------------------------------------------- */ /** * eeh_report_error - report pci error to each device driver @@ -132,8 +98,11 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata) if (!driver) return; - eeh_disable_irq(dev); - + if (irq_in_use (dev->irq)) { + struct device_node *dn = pci_device_to_OF_node(dev); + PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED; + disable_irq_nosync(dev->irq); + } if (!driver->err_handler || !driver->err_handler->error_detected) return; @@ -178,12 +147,15 @@ static void eeh_report_reset(struct pci_dev *dev, void *userdata) { enum pci_ers_result rc, *res = userdata; struct pci_driver *driver = dev->driver; + struct device_node *dn = pci_device_to_OF_node(dev); if (!driver) return; - eeh_enable_irq(dev); - + if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) { + PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED; + enable_irq(dev->irq); + } if (!driver->err_handler || !driver->err_handler->slot_reset) return; @@ -202,14 +174,17 @@ static void eeh_report_reset(struct pci_dev *dev, void *userdata) static void eeh_report_resume(struct pci_dev *dev, void *userdata) { struct pci_driver *driver = dev->driver; + struct device_node *dn = pci_device_to_OF_node(dev); dev->error_state = pci_channel_io_normal; if (!driver) return; - eeh_enable_irq(dev); - + if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) { + PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED; + enable_irq(dev->irq); + } if (!driver->err_handler || !driver->err_handler->resume) return; @@ -233,12 +208,15 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata) if (!driver) return; - eeh_disable_irq(dev); - - if (!driver->err_handler || - !driver->err_handler->error_detected) + if (irq_in_use (dev->irq)) { + struct device_node *dn = pci_device_to_OF_node(dev); + PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED; + disable_irq_nosync(dev->irq); + } + if (!driver->err_handler) + return; + if (!driver->err_handler->error_detected) return; - driver->err_handler->error_detected(dev, pci_channel_io_perm_failure); } diff --git a/trunk/arch/powerpc/platforms/pseries/msi.c b/trunk/arch/powerpc/platforms/pseries/msi.c index bf2e1ac41308..f15222bbe136 100644 --- a/trunk/arch/powerpc/platforms/pseries/msi.c +++ b/trunk/arch/powerpc/platforms/pseries/msi.c @@ -71,13 +71,11 @@ static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs) } while (rtas_busy_delay(rc)); /* - * If the RTAS call succeeded, return the number of irqs allocated. - * If not, make sure we return a negative error code. + * If the RTAS call succeeded, check the number of irqs is actually + * what we asked for. If not, return an error. */ - if (rc == 0) - rc = rtas_ret[0]; - else if (rc > 0) - rc = -rc; + if (rc == 0 && rtas_ret[0] != num_irqs) + rc = -ENOSPC; pr_debug("rtas_msi: ibm,change_msi(func=%d,num=%d), got %d rc = %d\n", func, num_irqs, rtas_ret[0], rc); @@ -93,7 +91,7 @@ static void rtas_disable_msi(struct pci_dev *pdev) if (!pdn) return; - if (rtas_change_msi(pdn, RTAS_CHANGE_FN, 0) != 0) + if (rtas_change_msi(pdn, RTAS_CHANGE_FN, 0)) pr_debug("rtas_msi: Setting MSIs to 0 failed!\n"); } @@ -134,7 +132,7 @@ static void rtas_teardown_msi_irqs(struct pci_dev *pdev) rtas_disable_msi(pdev); } -static int check_req(struct pci_dev *pdev, int nvec, char *prop_name) +static int check_req_msi(struct pci_dev *pdev, int nvec) { struct device_node *dn; struct pci_dn *pdn; @@ -146,235 +144,26 @@ static int check_req(struct pci_dev *pdev, int nvec, char *prop_name) dn = pdn->node; - req_msi = of_get_property(dn, prop_name, NULL); + req_msi = of_get_property(dn, "ibm,req#msi", NULL); if (!req_msi) { - pr_debug("rtas_msi: No %s on %s\n", prop_name, dn->full_name); + pr_debug("rtas_msi: No ibm,req#msi on %s\n", dn->full_name); return -ENOENT; } if (*req_msi < nvec) { - pr_debug("rtas_msi: %s requests < %d MSIs\n", prop_name, nvec); - - if (*req_msi == 0) /* Be paranoid */ - return -ENOSPC; - - return *req_msi; + pr_debug("rtas_msi: ibm,req#msi requests < %d MSIs\n", nvec); + return -ENOSPC; } return 0; } -static int check_req_msi(struct pci_dev *pdev, int nvec) -{ - return check_req(pdev, nvec, "ibm,req#msi"); -} - -static int check_req_msix(struct pci_dev *pdev, int nvec) -{ - return check_req(pdev, nvec, "ibm,req#msi-x"); -} - -/* Quota calculation */ - -static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total) -{ - struct device_node *dn; - const u32 *p; - - dn = of_node_get(pci_device_to_OF_node(dev)); - while (dn) { - p = of_get_property(dn, "ibm,pe-total-#msi", NULL); - if (p) { - pr_debug("rtas_msi: found prop on dn %s\n", - dn->full_name); - *total = *p; - return dn; - } - - dn = of_get_next_parent(dn); - } - - return NULL; -} - -static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) -{ - struct device_node *dn; - - /* Found our PE and assume 8 at that point. */ - - dn = pci_device_to_OF_node(dev); - if (!dn) - return NULL; - - dn = find_device_pe(dn); - if (!dn) - return NULL; - - /* We actually want the parent */ - dn = of_get_parent(dn); - if (!dn) - return NULL; - - /* Hardcode of 8 for old firmwares */ - *total = 8; - pr_debug("rtas_msi: using PE dn %s\n", dn->full_name); - - return dn; -} - -struct msi_counts { - struct device_node *requestor; - int num_devices; - int request; - int quota; - int spare; - int over_quota; -}; - -static void *count_non_bridge_devices(struct device_node *dn, void *data) -{ - struct msi_counts *counts = data; - const u32 *p; - u32 class; - - pr_debug("rtas_msi: counting %s\n", dn->full_name); - - p = of_get_property(dn, "class-code", NULL); - class = p ? *p : 0; - - if ((class >> 8) != PCI_CLASS_BRIDGE_PCI) - counts->num_devices++; - - return NULL; -} - -static void *count_spare_msis(struct device_node *dn, void *data) -{ - struct msi_counts *counts = data; - const u32 *p; - int req; - - if (dn == counts->requestor) - req = counts->request; - else { - /* We don't know if a driver will try to use MSI or MSI-X, - * so we just have to punt and use the larger of the two. */ - req = 0; - p = of_get_property(dn, "ibm,req#msi", NULL); - if (p) - req = *p; - - p = of_get_property(dn, "ibm,req#msi-x", NULL); - if (p) - req = max(req, (int)*p); - } - - if (req < counts->quota) - counts->spare += counts->quota - req; - else if (req > counts->quota) - counts->over_quota++; - - return NULL; -} - -static int msi_quota_for_device(struct pci_dev *dev, int request) -{ - struct device_node *pe_dn; - struct msi_counts counts; - int total; - - pr_debug("rtas_msi: calc quota for %s, request %d\n", pci_name(dev), - request); - - pe_dn = find_pe_total_msi(dev, &total); - if (!pe_dn) - pe_dn = find_pe_dn(dev, &total); - - if (!pe_dn) { - pr_err("rtas_msi: couldn't find PE for %s\n", pci_name(dev)); - goto out; - } - - pr_debug("rtas_msi: found PE %s\n", pe_dn->full_name); - - memset(&counts, 0, sizeof(struct msi_counts)); - - /* Work out how many devices we have below this PE */ - traverse_pci_devices(pe_dn, count_non_bridge_devices, &counts); - - if (counts.num_devices == 0) { - pr_err("rtas_msi: found 0 devices under PE for %s\n", - pci_name(dev)); - goto out; - } - - counts.quota = total / counts.num_devices; - if (request <= counts.quota) - goto out; - - /* else, we have some more calculating to do */ - counts.requestor = pci_device_to_OF_node(dev); - counts.request = request; - traverse_pci_devices(pe_dn, count_spare_msis, &counts); - - /* If the quota isn't an integer multiple of the total, we can - * use the remainder as spare MSIs for anyone that wants them. */ - counts.spare += total % counts.num_devices; - - /* Divide any spare by the number of over-quota requestors */ - if (counts.over_quota) - counts.quota += counts.spare / counts.over_quota; - - /* And finally clamp the request to the possibly adjusted quota */ - request = min(counts.quota, request); - - pr_debug("rtas_msi: request clamped to quota %d\n", request); -out: - of_node_put(pe_dn); - - return request; -} - static int rtas_msi_check_device(struct pci_dev *pdev, int nvec, int type) { - int quota, rc; - if (type == PCI_CAP_ID_MSIX) - rc = check_req_msix(pdev, nvec); - else - rc = check_req_msi(pdev, nvec); - - if (rc) - return rc; - - quota = msi_quota_for_device(pdev, nvec); + pr_debug("rtas_msi: MSI-X untested, trying anyway.\n"); - if (quota && quota < nvec) - return quota; - - return 0; -} - -static int check_msix_entries(struct pci_dev *pdev) -{ - struct msi_desc *entry; - int expected; - - /* There's no way for us to express to firmware that we want - * a discontiguous, or non-zero based, range of MSI-X entries. - * So we must reject such requests. */ - - expected = 0; - list_for_each_entry(entry, &pdev->msi_list, list) { - if (entry->msi_attrib.entry_nr != expected) { - pr_debug("rtas_msi: bad MSI-X entries.\n"); - return -EINVAL; - } - expected++; - } - - return 0; + return check_req_msi(pdev, nvec); } static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) @@ -388,9 +177,6 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) if (!pdn) return -ENODEV; - if (type == PCI_CAP_ID_MSIX && check_msix_entries(pdev)) - return -EINVAL; - /* * Try the new more explicit firmware interface, if that fails fall * back to the old interface. The old interface is known to never @@ -399,21 +185,21 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) if (type == PCI_CAP_ID_MSI) { rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec); - if (rc < 0) { + if (rc) { pr_debug("rtas_msi: trying the old firmware call.\n"); rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec); } } else rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec); - if (rc != nvec) { + if (rc) { pr_debug("rtas_msi: rtas_change_msi() failed\n"); return rc; } i = 0; list_for_each_entry(entry, &pdev->msi_list, list) { - hwirq = rtas_query_irq_number(pdn, i++); + hwirq = rtas_query_irq_number(pdn, i); if (hwirq < 0) { pr_debug("rtas_msi: error (%d) getting hwirq\n", rc); return hwirq; @@ -448,8 +234,8 @@ static void rtas_msi_pci_irq_fixup(struct pci_dev *pdev) } /* No MSI -> MSIs can't have been assigned by fw, leave LSI */ - if (check_req_msi(pdev, 1) && check_req_msix(pdev, 1)) { - dev_dbg(&pdev->dev, "rtas_msi: no req#msi/x, nothing to do.\n"); + if (check_req_msi(pdev, 1)) { + dev_dbg(&pdev->dev, "rtas_msi: no req#msi, nothing to do.\n"); return; } diff --git a/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c b/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c index ad152a0e3946..5e1ed3d60ee5 100644 --- a/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -137,9 +137,11 @@ EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) { struct pci_controller *phb; + int primary; pr_debug("PCI: Initializing new hotplug PHB %s\n", dn->full_name); + primary = list_empty(&hose_list); phb = pcibios_alloc_controller(dn); if (!phb) return NULL; diff --git a/trunk/arch/powerpc/platforms/pseries/plpar_wrappers.h b/trunk/arch/powerpc/platforms/pseries/plpar_wrappers.h index a24a6b2333b2..d967c1893ab5 100644 --- a/trunk/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/trunk/arch/powerpc/platforms/pseries/plpar_wrappers.h @@ -43,16 +43,6 @@ 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, unsigned long vpa) -{ - return vpa_call(0x6, cpu, vpa); -} - -static inline long register_dtl(unsigned long cpu, unsigned long vpa) -{ - return vpa_call(0x2, cpu, vpa); -} - static inline long plpar_page_set_loaned(unsigned long vpa) { unsigned long cmo_page_sz = cmo_get_page_size(); diff --git a/trunk/arch/powerpc/platforms/pseries/reconfig.c b/trunk/arch/powerpc/platforms/pseries/reconfig.c index b6f1b137d427..c591a25b0b0d 100644 --- a/trunk/arch/powerpc/platforms/pseries/reconfig.c +++ b/trunk/arch/powerpc/platforms/pseries/reconfig.c @@ -468,13 +468,9 @@ static int do_update_property(char *buf, size_t bufsize) rc = blocking_notifier_call_chain(&pSeries_reconfig_chain, action, value); - if (rc == NOTIFY_BAD) { - rc = prom_update_property(np, oldprop, newprop); - return -ENOMEM; - } } - return 0; + return rc; } /** diff --git a/trunk/arch/powerpc/sysdev/cpm1.c b/trunk/arch/powerpc/sysdev/cpm1.c index 82424cd7e128..490473ce8103 100644 --- a/trunk/arch/powerpc/sysdev/cpm1.c +++ b/trunk/arch/powerpc/sysdev/cpm1.c @@ -119,6 +119,7 @@ static irqreturn_t cpm_error_interrupt(int irq, void *dev) static struct irqaction cpm_error_irqaction = { .handler = cpm_error_interrupt, + .mask = CPU_MASK_NONE, .name = "error", }; diff --git a/trunk/arch/powerpc/sysdev/cpm2.c b/trunk/arch/powerpc/sysdev/cpm2.c index fd969f0e3121..f1c3395633b9 100644 --- a/trunk/arch/powerpc/sysdev/cpm2.c +++ b/trunk/arch/powerpc/sysdev/cpm2.c @@ -52,7 +52,6 @@ cpm_cpm2_t __iomem *cpmp; /* Pointer to comm processor space */ * the communication processor devices. */ cpm2_map_t __iomem *cpm2_immr; -EXPORT_SYMBOL(cpm2_immr); #define CPM_MAP_SIZE (0x40000) /* 256k - the PQ3 reserve this amount of space for CPM as it is larger @@ -130,8 +129,7 @@ void __cpm2_setbrg(uint brg, uint rate, uint clk, int div16, int src) brg -= 4; } bp += brg; - /* Round the clock divider to the nearest integer. */ - val = (((clk * 2 / rate) - 1) & ~1) | CPM_BRG_EN | src; + val = (((clk / rate) - 1) << 1) | CPM_BRG_EN | src; if (div16) val |= CPM_BRG_DIV16; diff --git a/trunk/arch/powerpc/sysdev/cpm_common.c b/trunk/arch/powerpc/sysdev/cpm_common.c index e4b6d66d93de..00d3d17c84a3 100644 --- a/trunk/arch/powerpc/sysdev/cpm_common.c +++ b/trunk/arch/powerpc/sysdev/cpm_common.c @@ -56,7 +56,7 @@ void __init udbg_init_cpm(void) { if (cpm_udbg_txdesc) { #ifdef CONFIG_CPM2 - setbat(1, 0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG); + setbat(1, 0xf0000000, 0xf0000000, 1024*1024, _PAGE_IO); #endif udbg_putc = udbg_putc_cpm; } diff --git a/trunk/arch/powerpc/sysdev/fsl_pci.c b/trunk/arch/powerpc/sysdev/fsl_pci.c index 78021d8afc53..9817f63723dd 100644 --- a/trunk/arch/powerpc/sysdev/fsl_pci.c +++ b/trunk/arch/powerpc/sysdev/fsl_pci.c @@ -1,16 +1,12 @@ /* * MPC83xx/85xx/86xx PCI/PCIE support routing. * - * Copyright 2007-2009 Freescale Semiconductor, Inc. - * Copyright 2008-2009 MontaVista Software, Inc. + * Copyright 2007,2008 Freescale Semiconductor, Inc * * Initial author: Xianghua Xiao * Recode: ZHANG WEI * Rewrite the routing for Frescale PCI and PCI Express * Roy Zang - * MPC83xx PCI-Express support: - * Tony Li - * Anton Vorontsov * * 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 @@ -31,29 +27,6 @@ #include #include -static int fsl_pcie_bus_fixup; - -static void __init quirk_fsl_pcie_header(struct pci_dev *dev) -{ - /* if we aren't a PCIe don't bother */ - if (!pci_find_capability(dev, PCI_CAP_ID_EXP)) - return; - - dev->class = PCI_CLASS_BRIDGE_PCI << 8; - fsl_pcie_bus_fixup = 1; - return; -} - -static int __init fsl_pcie_check_link(struct pci_controller *hose) -{ - u32 val; - - early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val); - if (val < PCIE_LTSSM_L0) - return 1; - return 0; -} - #if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx) static int __init setup_one_atmu(struct ccsr_pci __iomem *pci, unsigned int index, const struct resource *res, @@ -186,6 +159,28 @@ static void __init setup_pci_pcsrbar(struct pci_controller *hose) #endif } +static int fsl_pcie_bus_fixup; + +static void __init quirk_fsl_pcie_header(struct pci_dev *dev) +{ + /* if we aren't a PCIe don't bother */ + if (!pci_find_capability(dev, PCI_CAP_ID_EXP)) + return ; + + dev->class = PCI_CLASS_BRIDGE_PCI << 8; + fsl_pcie_bus_fixup = 1; + return ; +} + +static int __init fsl_pcie_check_link(struct pci_controller *hose) +{ + u32 val; + early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val); + if (val < PCIE_LTSSM_L0) + return 1; + return 0; +} + void fsl_pcibios_fixup_bus(struct pci_bus *bus) { struct pci_controller *hose = (struct pci_controller *) bus->sysdata; @@ -299,184 +294,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header); #endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */ #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) -DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314E, quirk_fsl_pcie_header); -DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314, quirk_fsl_pcie_header); -DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8315E, quirk_fsl_pcie_header); -DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8315, quirk_fsl_pcie_header); -DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8377E, quirk_fsl_pcie_header); -DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8377, quirk_fsl_pcie_header); -DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8378E, quirk_fsl_pcie_header); -DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8378, quirk_fsl_pcie_header); - -struct mpc83xx_pcie_priv { - void __iomem *cfg_type0; - void __iomem *cfg_type1; - u32 dev_base; -}; - -/* - * With the convention of u-boot, the PCIE outbound window 0 serves - * as configuration transactions outbound. - */ -#define PEX_OUTWIN0_BAR 0xCA4 -#define PEX_OUTWIN0_TAL 0xCA8 -#define PEX_OUTWIN0_TAH 0xCAC - -static int mpc83xx_pcie_exclude_device(struct pci_bus *bus, unsigned int devfn) -{ - struct pci_controller *hose = bus->sysdata; - - if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Workaround for the HW bug: for Type 0 configure transactions the - * PCI-E controller does not check the device number bits and just - * assumes that the device number bits are 0. - */ - if (bus->number == hose->first_busno || - bus->primary == hose->first_busno) { - if (devfn & 0xf8) - return PCIBIOS_DEVICE_NOT_FOUND; - } - - if (ppc_md.pci_exclude_device) { - if (ppc_md.pci_exclude_device(hose, bus->number, devfn)) - return PCIBIOS_DEVICE_NOT_FOUND; - } - - return PCIBIOS_SUCCESSFUL; -} - -static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus, - unsigned int devfn, int offset) -{ - struct pci_controller *hose = bus->sysdata; - struct mpc83xx_pcie_priv *pcie = hose->dn->data; - u8 bus_no = bus->number - hose->first_busno; - u32 dev_base = bus_no << 24 | devfn << 16; - int ret; - - ret = mpc83xx_pcie_exclude_device(bus, devfn); - if (ret) - return NULL; - - offset &= 0xfff; - - /* Type 0 */ - if (bus->number == hose->first_busno) - return pcie->cfg_type0 + offset; - - if (pcie->dev_base == dev_base) - goto mapped; - - out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, dev_base); - - pcie->dev_base = dev_base; -mapped: - return pcie->cfg_type1 + offset; -} - -static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 *val) -{ - void __iomem *cfg_addr; - - cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset); - if (!cfg_addr) - return PCIBIOS_DEVICE_NOT_FOUND; - - switch (len) { - case 1: - *val = in_8(cfg_addr); - break; - case 2: - *val = in_le16(cfg_addr); - break; - default: - *val = in_le32(cfg_addr); - break; - } - - return PCIBIOS_SUCCESSFUL; -} - -static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 val) -{ - void __iomem *cfg_addr; - - cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset); - if (!cfg_addr) - return PCIBIOS_DEVICE_NOT_FOUND; - - switch (len) { - case 1: - out_8(cfg_addr, val); - break; - case 2: - out_le16(cfg_addr, val); - break; - default: - out_le32(cfg_addr, val); - break; - } - - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops mpc83xx_pcie_ops = { - .read = mpc83xx_pcie_read_config, - .write = mpc83xx_pcie_write_config, -}; - -static int __init mpc83xx_pcie_setup(struct pci_controller *hose, - struct resource *reg) -{ - struct mpc83xx_pcie_priv *pcie; - u32 cfg_bar; - int ret = -ENOMEM; - - pcie = zalloc_maybe_bootmem(sizeof(*pcie), GFP_KERNEL); - if (!pcie) - return ret; - - pcie->cfg_type0 = ioremap(reg->start, resource_size(reg)); - if (!pcie->cfg_type0) - goto err0; - - cfg_bar = in_le32(pcie->cfg_type0 + PEX_OUTWIN0_BAR); - if (!cfg_bar) { - /* PCI-E isn't configured. */ - ret = -ENODEV; - goto err1; - } - - pcie->cfg_type1 = ioremap(cfg_bar, 0x1000); - if (!pcie->cfg_type1) - goto err1; - - WARN_ON(hose->dn->data); - hose->dn->data = pcie; - hose->ops = &mpc83xx_pcie_ops; - - out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAH, 0); - out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0); - - if (fsl_pcie_check_link(hose)) - hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK; - - return 0; -err1: - iounmap(pcie->cfg_type0); -err0: - kfree(pcie); - return ret; - -} - int __init mpc83xx_add_bridge(struct device_node *dev) { - int ret; int len; struct pci_controller *hose; struct resource rsrc_reg; @@ -484,11 +303,6 @@ int __init mpc83xx_add_bridge(struct device_node *dev) const int *bus_range; int primary; - if (!of_device_is_available(dev)) { - pr_warning("%s: disabled by the firmware.\n", - dev->full_name); - return -ENODEV; - } pr_debug("Adding PCI host bridge %s\n", dev->full_name); /* Fetch host bridge registers address */ @@ -536,14 +350,7 @@ int __init mpc83xx_add_bridge(struct device_node *dev) hose->first_busno = bus_range ? bus_range[0] : 0; hose->last_busno = bus_range ? bus_range[1] : 0xff; - if (of_device_is_compatible(dev, "fsl,mpc8314-pcie")) { - ret = mpc83xx_pcie_setup(hose, &rsrc_reg); - if (ret) - goto err0; - } else { - setup_indirect_pci(hose, rsrc_cfg.start, - rsrc_cfg.start + 4, 0); - } + setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 4, 0); printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n", @@ -558,8 +365,5 @@ int __init mpc83xx_add_bridge(struct device_node *dev) pci_process_bridge_OF_ranges(hose, dev, primary); return 0; -err0: - pcibios_free_controller(hose); - return ret; } #endif /* CONFIG_PPC_83xx */ diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.c b/trunk/arch/powerpc/sysdev/fsl_soc.c index afe8dbc964aa..115cb16351fd 100644 --- a/trunk/arch/powerpc/sysdev/fsl_soc.c +++ b/trunk/arch/powerpc/sysdev/fsl_soc.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -329,9 +328,6 @@ static int __init fsl_usb_of_init(void) struct fsl_usb2_platform_data usb_data; const unsigned char *prop = NULL; - if (!of_device_is_available(np)) - continue; - memset(&r, 0, sizeof(r)); memset(&usb_data, 0, sizeof(usb_data)); @@ -417,6 +413,115 @@ static int __init fsl_usb_of_init(void) arch_initcall(fsl_usb_of_init); +static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk, + struct spi_board_info *board_infos, + unsigned int num_board_infos, + void (*activate_cs)(u8 cs, u8 polarity), + void (*deactivate_cs)(u8 cs, u8 polarity)) +{ + struct device_node *np; + unsigned int i = 0; + + for_each_compatible_node(np, type, compatible) { + int ret; + unsigned int j; + const void *prop; + struct resource res[2]; + struct platform_device *pdev; + struct fsl_spi_platform_data pdata = { + .activate_cs = activate_cs, + .deactivate_cs = deactivate_cs, + }; + + memset(res, 0, sizeof(res)); + + pdata.sysclk = sysclk; + + prop = of_get_property(np, "reg", NULL); + if (!prop) + goto err; + pdata.bus_num = *(u32 *)prop; + + prop = of_get_property(np, "cell-index", NULL); + if (prop) + i = *(u32 *)prop; + + prop = of_get_property(np, "mode", NULL); + if (prop && !strcmp(prop, "cpu-qe")) + pdata.qe_mode = 1; + + for (j = 0; j < num_board_infos; j++) { + if (board_infos[j].bus_num == pdata.bus_num) + pdata.max_chipselect++; + } + + if (!pdata.max_chipselect) + continue; + + ret = of_address_to_resource(np, 0, &res[0]); + if (ret) + goto err; + + ret = of_irq_to_resource(np, 0, &res[1]); + if (ret == NO_IRQ) + goto err; + + pdev = platform_device_alloc("mpc83xx_spi", i); + if (!pdev) + goto err; + + ret = platform_device_add_data(pdev, &pdata, sizeof(pdata)); + if (ret) + goto unreg; + + ret = platform_device_add_resources(pdev, res, + ARRAY_SIZE(res)); + if (ret) + goto unreg; + + ret = platform_device_add(pdev); + if (ret) + goto unreg; + + goto next; +unreg: + platform_device_del(pdev); +err: + pr_err("%s: registration failed\n", np->full_name); +next: + i++; + } + + return i; +} + +int __init fsl_spi_init(struct spi_board_info *board_infos, + unsigned int num_board_infos, + void (*activate_cs)(u8 cs, u8 polarity), + void (*deactivate_cs)(u8 cs, u8 polarity)) +{ + u32 sysclk = -1; + int ret; + +#ifdef CONFIG_QUICC_ENGINE + /* SPI controller is either clocked from QE or SoC clock */ + sysclk = get_brgfreq(); +#endif + if (sysclk == -1) { + sysclk = fsl_get_sys_freq(); + if (sysclk == -1) + return -ENODEV; + } + + ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos, + num_board_infos, activate_cs, deactivate_cs); + if (!ret) + of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos, + num_board_infos, activate_cs, deactivate_cs); + + return spi_register_board_info(board_infos, num_board_infos); +} + #if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx) static __be32 __iomem *rstcr; diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.h b/trunk/arch/powerpc/sysdev/fsl_soc.h index 42381bb6cd51..9c744e4285a0 100644 --- a/trunk/arch/powerpc/sysdev/fsl_soc.h +++ b/trunk/arch/powerpc/sysdev/fsl_soc.h @@ -4,8 +4,6 @@ #include -struct spi_device; - extern phys_addr_t get_immrbase(void); #if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx) extern u32 get_brgfreq(void); @@ -19,6 +17,11 @@ extern u32 fsl_get_sys_freq(void); struct spi_board_info; struct device_node; +extern int fsl_spi_init(struct spi_board_info *board_infos, + unsigned int num_board_infos, + void (*activate_cs)(u8 cs, u8 polarity), + void (*deactivate_cs)(u8 cs, u8 polarity)); + extern void fsl_rstcr_restart(char *cmd); #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) diff --git a/trunk/arch/powerpc/sysdev/ipic.c b/trunk/arch/powerpc/sysdev/ipic.c index a86d3ce01ead..9a89cd3e80a2 100644 --- a/trunk/arch/powerpc/sysdev/ipic.c +++ b/trunk/arch/powerpc/sysdev/ipic.c @@ -568,7 +568,8 @@ static void ipic_ack_irq(unsigned int virq) spin_lock_irqsave(&ipic_lock, flags); - temp = 1 << (31 - ipic_info[src].bit); + temp = ipic_read(ipic->regs, ipic_info[src].ack); + temp |= (1 << (31 - ipic_info[src].bit)); ipic_write(ipic->regs, ipic_info[src].ack, temp); /* mb() can't guarantee that ack is finished. But it does finish @@ -591,7 +592,8 @@ static void ipic_mask_irq_and_ack(unsigned int virq) temp &= ~(1 << (31 - ipic_info[src].bit)); ipic_write(ipic->regs, ipic_info[src].mask, temp); - temp = 1 << (31 - ipic_info[src].bit); + temp = ipic_read(ipic->regs, ipic_info[src].ack); + temp |= (1 << (31 - ipic_info[src].bit)); ipic_write(ipic->regs, ipic_info[src].ack, temp); /* mb() can't guarantee that ack is finished. But it does finish diff --git a/trunk/arch/powerpc/sysdev/msi_bitmap.c b/trunk/arch/powerpc/sysdev/msi_bitmap.c index 5a32cbef9b6c..f84217b8863a 100644 --- a/trunk/arch/powerpc/sysdev/msi_bitmap.c +++ b/trunk/arch/powerpc/sysdev/msi_bitmap.c @@ -141,7 +141,7 @@ void msi_bitmap_free(struct msi_bitmap *bmp) #define check(x) \ if (!(x)) printk("msi_bitmap: test failed at line %d\n", __LINE__); -void __init test_basics(void) +void test_basics(void) { struct msi_bitmap bmp; int i, size = 512; @@ -186,7 +186,7 @@ void __init test_basics(void) kfree(bmp.bitmap); } -void __init test_of_node(void) +void test_of_node(void) { u32 prop_data[] = { 10, 10, 25, 3, 40, 1, 100, 100, 200, 20 }; const char *expected_str = "0-9,20-24,28-39,41-99,220-255"; @@ -234,7 +234,7 @@ void __init test_of_node(void) kfree(bmp.bitmap); } -int __init msi_bitmap_selftest(void) +int msi_bitmap_selftest(void) { printk(KERN_DEBUG "Running MSI bitmap self-tests ...\n"); diff --git a/trunk/arch/powerpc/sysdev/pmi.c b/trunk/arch/powerpc/sysdev/pmi.c index aaa915998eb6..c858749263e0 100644 --- a/trunk/arch/powerpc/sysdev/pmi.c +++ b/trunk/arch/powerpc/sysdev/pmi.c @@ -50,7 +50,7 @@ struct pmi_data { static struct pmi_data *data; -static irqreturn_t pmi_irq_handler(int irq, void *dev_id) +static int pmi_irq_handler(int irq, void *dev_id) { u8 type; int rc; diff --git a/trunk/arch/powerpc/sysdev/ppc4xx_pci.c b/trunk/arch/powerpc/sysdev/ppc4xx_pci.c index 6a2d473c345a..5558d932b4d5 100644 --- a/trunk/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/trunk/arch/powerpc/sysdev/ppc4xx_pci.c @@ -1839,8 +1839,6 @@ static int __init ppc4xx_pci_find_bridges(void) { struct device_node *np; - ppc_pci_flags |= PPC_PCI_ENABLE_PROC_DOMAINS | PPC_PCI_COMPAT_DOMAIN_0; - #ifdef CONFIG_PPC4xx_PCI_EXPRESS for_each_compatible_node(np, NULL, "ibm,plb-pciex") ppc4xx_probe_pciex_bridge(np); diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index dcb667c4375a..2a8af5e16345 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -72,9 +72,6 @@ config PGSTE config VIRT_CPU_ACCOUNTING def_bool y -config ARCH_SUPPORTS_DEBUG_PAGEALLOC - def_bool y - mainmenu "Linux Kernel Configuration" config S390 diff --git a/trunk/arch/s390/Kconfig.debug b/trunk/arch/s390/Kconfig.debug index 2283933a9a93..4599fa06bd82 100644 --- a/trunk/arch/s390/Kconfig.debug +++ b/trunk/arch/s390/Kconfig.debug @@ -6,4 +6,12 @@ config TRACE_IRQFLAGS_SUPPORT source "lib/Kconfig.debug" +config DEBUG_PAGEALLOC + bool "Debug page memory allocations" + depends on DEBUG_KERNEL + help + Unmap pages from the kernel linear mapping after free_pages(). + This results in a slowdown, but helps to find certain types of + memory corruptions. + endmenu diff --git a/trunk/arch/s390/hypfs/hypfs_diag.c b/trunk/arch/s390/hypfs/hypfs_diag.c index 704dd396257b..b1e892a43816 100644 --- a/trunk/arch/s390/hypfs/hypfs_diag.c +++ b/trunk/arch/s390/hypfs/hypfs_diag.c @@ -12,8 +12,6 @@ #include #include -#include -#include #include #include #include diff --git a/trunk/arch/s390/include/asm/cio.h b/trunk/arch/s390/include/asm/cio.h index 619bf94b11f1..6dccb071aec3 100644 --- a/trunk/arch/s390/include/asm/cio.h +++ b/trunk/arch/s390/include/asm/cio.h @@ -456,8 +456,6 @@ struct ciw { #define CIO_OPER 0x0004 /* Sick revalidation of device. */ #define CIO_REVALIDATE 0x0008 -/* Device did not respond in time. */ -#define CIO_BOXED 0x0010 /** * struct ccw_dev_id - unique identifier for ccw devices diff --git a/trunk/arch/s390/include/asm/spinlock.h b/trunk/arch/s390/include/asm/spinlock.h index f3861b09ebb0..df84ae96915f 100644 --- a/trunk/arch/s390/include/asm/spinlock.h +++ b/trunk/arch/s390/include/asm/spinlock.h @@ -172,9 +172,6 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) return _raw_write_trylock_retry(rw); } -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) - #define _raw_read_relax(lock) cpu_relax() #define _raw_write_relax(lock) cpu_relax() diff --git a/trunk/arch/s390/kernel/process.c b/trunk/arch/s390/kernel/process.c index a3acd8e60aff..b48e961a38f6 100644 --- a/trunk/arch/s390/kernel/process.c +++ b/trunk/arch/s390/kernel/process.c @@ -160,7 +160,7 @@ void release_thread(struct task_struct *dead_task) { } -int copy_thread(unsigned long clone_flags, unsigned long new_stackp, +int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { diff --git a/trunk/arch/sh/boards/board-ap325rxa.c b/trunk/arch/sh/boards/board-ap325rxa.c index e27655b8a98d..a64e38841c49 100644 --- a/trunk/arch/sh/boards/board-ap325rxa.c +++ b/trunk/arch/sh/boards/board-ap325rxa.c @@ -310,8 +310,7 @@ static struct platform_device camera_device = { static struct sh_mobile_ceu_info sh_mobile_ceu_info = { .flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | - SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER | - SOCAM_DATAWIDTH_8, + SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8, }; static struct resource ceu_resources[] = { diff --git a/trunk/arch/sh/boards/mach-migor/setup.c b/trunk/arch/sh/boards/mach-migor/setup.c index 4fd6a727873c..bc35b4cae6b3 100644 --- a/trunk/arch/sh/boards/mach-migor/setup.c +++ b/trunk/arch/sh/boards/mach-migor/setup.c @@ -352,9 +352,8 @@ static int tw9910_power(struct device *dev, int mode) } static struct sh_mobile_ceu_info sh_mobile_ceu_info = { - .flags = SOCAM_MASTER | SOCAM_DATAWIDTH_8 | SOCAM_PCLK_SAMPLE_RISING - | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH - | SOCAM_DATA_ACTIVE_HIGH, + .flags = SOCAM_MASTER | SOCAM_DATAWIDTH_8 | SOCAM_PCLK_SAMPLE_RISING \ + | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH, }; static struct resource migor_ceu_resources[] = { diff --git a/trunk/arch/sh/include/asm/spinlock.h b/trunk/arch/sh/include/asm/spinlock.h index 60283565f89b..e793181d64da 100644 --- a/trunk/arch/sh/include/asm/spinlock.h +++ b/trunk/arch/sh/include/asm/spinlock.h @@ -216,9 +216,6 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) return (oldval > (RW_LOCK_BIAS - 1)); } -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) - #define _raw_spin_relax(lock) cpu_relax() #define _raw_read_relax(lock) cpu_relax() #define _raw_write_relax(lock) cpu_relax() diff --git a/trunk/arch/sh/include/asm/topology.h b/trunk/arch/sh/include/asm/topology.h index a3f239545897..066f0fba590e 100644 --- a/trunk/arch/sh/include/asm/topology.h +++ b/trunk/arch/sh/include/asm/topology.h @@ -33,6 +33,7 @@ #define node_to_cpumask(node) ((void)node, cpu_online_map) #define cpumask_of_node(node) ((void)node, cpu_online_mask) +#define node_to_first_cpu(node) ((void)(node),0) #define pcibus_to_node(bus) ((void)(bus), -1) #define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ? \ diff --git a/trunk/arch/sh/kernel/process_32.c b/trunk/arch/sh/kernel/process_32.c index 694bc15f84fd..ddafbbbab2ab 100644 --- a/trunk/arch/sh/kernel/process_32.c +++ b/trunk/arch/sh/kernel/process_32.c @@ -170,7 +170,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) asmlinkage void ret_from_fork(void); -int copy_thread(unsigned long clone_flags, unsigned long usp, +int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { diff --git a/trunk/arch/sh/kernel/process_64.c b/trunk/arch/sh/kernel/process_64.c index 96be839040f8..c90c7e5e5fee 100644 --- a/trunk/arch/sh/kernel/process_64.c +++ b/trunk/arch/sh/kernel/process_64.c @@ -425,7 +425,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) asmlinkage void ret_from_fork(void); -int copy_thread(unsigned long clone_flags, unsigned long usp, +int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { diff --git a/trunk/arch/sh/kernel/time_64.c b/trunk/arch/sh/kernel/time_64.c index 988c77c37231..59d2a03e8b3c 100644 --- a/trunk/arch/sh/kernel/time_64.c +++ b/trunk/arch/sh/kernel/time_64.c @@ -284,6 +284,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) static struct irqaction irq0 = { .handler = timer_interrupt, .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, .name = "timer", }; diff --git a/trunk/arch/sh/kernel/timers/timer-cmt.c b/trunk/arch/sh/kernel/timers/timer-cmt.c index 9aa348658ae3..c127293271e1 100644 --- a/trunk/arch/sh/kernel/timers/timer-cmt.c +++ b/trunk/arch/sh/kernel/timers/timer-cmt.c @@ -109,6 +109,7 @@ static struct irqaction cmt_irq = { .name = "timer", .handler = cmt_timer_interrupt, .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .mask = CPU_MASK_NONE, }; static void cmt_clk_init(struct clk *clk) diff --git a/trunk/arch/sh/kernel/timers/timer-mtu2.c b/trunk/arch/sh/kernel/timers/timer-mtu2.c index 9b0ef0126479..9a77ae86b403 100644 --- a/trunk/arch/sh/kernel/timers/timer-mtu2.c +++ b/trunk/arch/sh/kernel/timers/timer-mtu2.c @@ -115,6 +115,7 @@ static struct irqaction mtu2_irq = { .name = "timer", .handler = mtu2_timer_interrupt, .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .mask = CPU_MASK_NONE, }; static unsigned int divisors[] = { 1, 4, 16, 64, 1, 1, 256 }; diff --git a/trunk/arch/sh/kernel/timers/timer-tmu.c b/trunk/arch/sh/kernel/timers/timer-tmu.c index c5d3396f5960..10b5a6f17cc0 100644 --- a/trunk/arch/sh/kernel/timers/timer-tmu.c +++ b/trunk/arch/sh/kernel/timers/timer-tmu.c @@ -162,6 +162,7 @@ static struct irqaction tmu0_irq = { .name = "periodic/oneshot timer", .handler = tmu_timer_interrupt, .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .mask = CPU_MASK_NONE, }; static void __init tmu_clk_init(struct clk *clk) diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index cc12cd48bbc5..c3ea215334f6 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -124,9 +124,6 @@ config ARCH_NO_VIRT_TO_BUS config OF def_bool y -config ARCH_SUPPORTS_DEBUG_PAGEALLOC - def_bool y if SPARC64 - source "init/Kconfig" source "kernel/Kconfig.freezer" diff --git a/trunk/arch/sparc/Kconfig.debug b/trunk/arch/sparc/Kconfig.debug index 90d5fe223a74..b8a15e271bfa 100644 --- a/trunk/arch/sparc/Kconfig.debug +++ b/trunk/arch/sparc/Kconfig.debug @@ -22,6 +22,14 @@ config DEBUG_DCFLUSH config STACK_DEBUG bool "Stack Overflow Detection Support" +config DEBUG_PAGEALLOC + bool "Debug page memory allocations" + depends on SPARC64 && DEBUG_KERNEL && !HIBERNATION + help + Unmap pages from the kernel linear mapping after free_pages(). + This results in a large slowdown, but helps to find certain types + of memory corruptions. + config MCOUNT bool depends on SPARC64 diff --git a/trunk/arch/sparc/include/asm/mmu_context_64.h b/trunk/arch/sparc/include/asm/mmu_context_64.h index 666a73fef28d..5693ab482606 100644 --- a/trunk/arch/sparc/include/asm/mmu_context_64.h +++ b/trunk/arch/sparc/include/asm/mmu_context_64.h @@ -121,8 +121,8 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str * local TLB. */ cpu = smp_processor_id(); - if (!ctx_valid || !cpumask_test_cpu(cpu, mm_cpumask(mm))) { - cpumask_set_cpu(cpu, mm_cpumask(mm)); + if (!ctx_valid || !cpu_isset(cpu, mm->cpu_vm_mask)) { + cpu_set(cpu, mm->cpu_vm_mask); __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT); } @@ -141,8 +141,8 @@ static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm if (!CTX_VALID(mm->context)) get_new_mmu_context(mm); cpu = smp_processor_id(); - if (!cpumask_test_cpu(cpu, mm_cpumask(mm))) - cpumask_set_cpu(cpu, mm_cpumask(mm)); + if (!cpu_isset(cpu, mm->cpu_vm_mask)) + cpu_set(cpu, mm->cpu_vm_mask); load_secondary_context(mm); __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT); diff --git a/trunk/arch/sparc/include/asm/smp_64.h b/trunk/arch/sparc/include/asm/smp_64.h index becb6bf353a9..57224dd37b3a 100644 --- a/trunk/arch/sparc/include/asm/smp_64.h +++ b/trunk/arch/sparc/include/asm/smp_64.h @@ -35,8 +35,7 @@ extern cpumask_t cpu_core_map[NR_CPUS]; extern int sparc64_multi_core; extern void arch_send_call_function_single_ipi(int cpu); -extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); -#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask +extern void arch_send_call_function_ipi(cpumask_t mask); /* * General functions that each host system must provide. diff --git a/trunk/arch/sparc/include/asm/spinlock_32.h b/trunk/arch/sparc/include/asm/spinlock_32.h index 46f91ab66a50..bf2d532593e3 100644 --- a/trunk/arch/sparc/include/asm/spinlock_32.h +++ b/trunk/arch/sparc/include/asm/spinlock_32.h @@ -177,8 +177,6 @@ static inline int __read_trylock(raw_rwlock_t *rw) #define __raw_write_unlock(rw) do { (rw)->lock = 0; } while(0) #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) -#define __raw_read_lock_flags(rw, flags) __raw_read_lock(rw) -#define __raw_write_lock_flags(rw, flags) __raw_write_lock(rw) #define _raw_spin_relax(lock) cpu_relax() #define _raw_read_relax(lock) cpu_relax() diff --git a/trunk/arch/sparc/include/asm/spinlock_64.h b/trunk/arch/sparc/include/asm/spinlock_64.h index f6b2b92ad8d2..c4d274d330e9 100644 --- a/trunk/arch/sparc/include/asm/spinlock_64.h +++ b/trunk/arch/sparc/include/asm/spinlock_64.h @@ -211,11 +211,9 @@ static int inline __write_trylock(raw_rwlock_t *lock) } #define __raw_read_lock(p) __read_lock(p) -#define __raw_read_lock_flags(p, f) __read_lock(p) #define __raw_read_trylock(p) __read_trylock(p) #define __raw_read_unlock(p) __read_unlock(p) #define __raw_write_lock(p) __write_lock(p) -#define __raw_write_lock_flags(p, f) __write_lock(p) #define __raw_write_unlock(p) __write_unlock(p) #define __raw_write_trylock(p) __write_trylock(p) diff --git a/trunk/arch/sparc/include/asm/system_32.h b/trunk/arch/sparc/include/asm/system_32.h index 751c8c17f5a0..79c1ae2b42a3 100644 --- a/trunk/arch/sparc/include/asm/system_32.h +++ b/trunk/arch/sparc/include/asm/system_32.h @@ -126,7 +126,7 @@ extern void flushw_all(void); #define switch_to(prev, next, last) do { \ SWITCH_ENTER(prev); \ SWITCH_DO_LAZY_FPU(next); \ - cpumask_set_cpu(smp_processor_id(), mm_cpumask(next->active_mm)); \ + cpu_set(smp_processor_id(), next->active_mm->cpu_vm_mask); \ __asm__ __volatile__( \ "sethi %%hi(here - 0x8), %%o7\n\t" \ "mov %%g6, %%g3\n\t" \ diff --git a/trunk/arch/sparc/include/asm/topology_64.h b/trunk/arch/sparc/include/asm/topology_64.h index e5ea8d332421..5bc0b8fd6374 100644 --- a/trunk/arch/sparc/include/asm/topology_64.h +++ b/trunk/arch/sparc/include/asm/topology_64.h @@ -28,6 +28,11 @@ static inline cpumask_t node_to_cpumask(int node) #define node_to_cpumask_ptr_next(v, node) \ v = &(numa_cpumask_lookup_table[node]) +static inline int node_to_first_cpu(int node) +{ + return cpumask_first(cpumask_of_node(node)); +} + struct pci_bus; #ifdef CONFIG_PCI extern int pcibus_to_node(struct pci_bus *pbus); @@ -38,9 +43,13 @@ static inline int pcibus_to_node(struct pci_bus *pbus) } #endif +#define pcibus_to_cpumask(bus) \ + (pcibus_to_node(bus) == -1 ? \ + CPU_MASK_ALL : \ + node_to_cpumask(pcibus_to_node(bus))) #define cpumask_of_pcibus(bus) \ (pcibus_to_node(bus) == -1 ? \ - cpu_all_mask : \ + CPU_MASK_ALL_PTR : \ cpumask_of_node(pcibus_to_node(bus))) #define SD_NODE_INIT (struct sched_domain) { \ @@ -80,6 +89,7 @@ static inline int pcibus_to_node(struct pci_bus *pbus) #define smt_capable() (sparc64_multi_core) #endif /* CONFIG_SMP */ +#define cpu_coregroup_map(cpu) (cpu_core_map[cpu]) #define cpu_coregroup_mask(cpu) (&cpu_core_map[cpu]) #endif /* _ASM_SPARC64_TOPOLOGY_H */ diff --git a/trunk/arch/sparc/kernel/ds.c b/trunk/arch/sparc/kernel/ds.c index 90350f838f05..57c39843fb2a 100644 --- a/trunk/arch/sparc/kernel/ds.c +++ b/trunk/arch/sparc/kernel/ds.c @@ -653,7 +653,7 @@ static void __cpuinit dr_cpu_data(struct ds_info *dp, if (cpu_list[i] == CPU_SENTINEL) continue; - if (cpu_list[i] < nr_cpu_ids) + if (cpu_list[i] < NR_CPUS) cpu_set(cpu_list[i], mask); } diff --git a/trunk/arch/sparc/kernel/irq_32.c b/trunk/arch/sparc/kernel/irq_32.c index ad800b80c718..44dd5ee64339 100644 --- a/trunk/arch/sparc/kernel/irq_32.c +++ b/trunk/arch/sparc/kernel/irq_32.c @@ -439,6 +439,7 @@ static int request_fast_irq(unsigned int irq, flush_cache_all(); action->flags = irqflags; + cpus_clear(action->mask); action->name = devname; action->dev_id = NULL; action->next = NULL; @@ -573,6 +574,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/trunk/arch/sparc/kernel/irq_64.c b/trunk/arch/sparc/kernel/irq_64.c index 5deabe921a47..d0d6a515499a 100644 --- a/trunk/arch/sparc/kernel/irq_64.c +++ b/trunk/arch/sparc/kernel/irq_64.c @@ -266,12 +266,12 @@ static int irq_choose_cpu(unsigned int virt_irq) spin_lock_irqsave(&irq_rover_lock, flags); while (!cpu_online(irq_rover)) { - if (++irq_rover >= nr_cpu_ids) + if (++irq_rover >= NR_CPUS) irq_rover = 0; } cpuid = irq_rover; do { - if (++irq_rover >= nr_cpu_ids) + if (++irq_rover >= NR_CPUS) irq_rover = 0; } while (!cpu_online(irq_rover)); diff --git a/trunk/arch/sparc/kernel/led.c b/trunk/arch/sparc/kernel/led.c index 00d034ea2164..adaaed4ea2fb 100644 --- a/trunk/arch/sparc/kernel/led.c +++ b/trunk/arch/sparc/kernel/led.c @@ -126,6 +126,7 @@ static int __init led_init(void) led = proc_create("led", 0, NULL, &led_proc_fops); if (!led) return -ENOMEM; + led->owner = THIS_MODULE; printk(KERN_INFO "led: version %s, Lars Kotthoff \n", diff --git a/trunk/arch/sparc/kernel/mdesc.c b/trunk/arch/sparc/kernel/mdesc.c index f0e6ed23a468..3f79f0c23a08 100644 --- a/trunk/arch/sparc/kernel/mdesc.c +++ b/trunk/arch/sparc/kernel/mdesc.c @@ -567,7 +567,7 @@ static void __init report_platform_properties(void) max_cpu = NR_CPUS; } for (i = 0; i < max_cpu; i++) - set_cpu_possible(i, true); + cpu_set(i, cpu_possible_map); } #endif diff --git a/trunk/arch/sparc/kernel/nmi.c b/trunk/arch/sparc/kernel/nmi.c index 2c0cc72d295b..f3577223c863 100644 --- a/trunk/arch/sparc/kernel/nmi.c +++ b/trunk/arch/sparc/kernel/nmi.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -207,33 +206,13 @@ void nmi_adjust_hz(unsigned int new_hz) } EXPORT_SYMBOL_GPL(nmi_adjust_hz); -static int nmi_shutdown(struct notifier_block *nb, unsigned long cmd, void *p) -{ - on_each_cpu(stop_watchdog, NULL, 1); - return 0; -} - -static struct notifier_block nmi_reboot_notifier = { - .notifier_call = nmi_shutdown, -}; - int __init nmi_init(void) { - int err; - nmi_usable = 1; on_each_cpu(start_watchdog, NULL, 1); - err = check_nmi_watchdog(); - if (!err) { - err = register_reboot_notifier(&nmi_reboot_notifier); - if (err) { - nmi_usable = 0; - on_each_cpu(stop_watchdog, NULL, 1); - } - } - return err; + return check_nmi_watchdog(); } static int __init setup_nmi_watchdog(char *str) diff --git a/trunk/arch/sparc/kernel/process_32.c b/trunk/arch/sparc/kernel/process_32.c index 2830b415e214..f4bee35a1b46 100644 --- a/trunk/arch/sparc/kernel/process_32.c +++ b/trunk/arch/sparc/kernel/process_32.c @@ -455,7 +455,7 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags, */ extern void ret_from_fork(void); -int copy_thread(unsigned long clone_flags, unsigned long sp, +int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { diff --git a/trunk/arch/sparc/kernel/process_64.c b/trunk/arch/sparc/kernel/process_64.c index 4041f94e7724..a73954b87f0a 100644 --- a/trunk/arch/sparc/kernel/process_64.c +++ b/trunk/arch/sparc/kernel/process_64.c @@ -561,7 +561,7 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags, * Parent --> %o0 == childs pid, %o1 == 0 * Child --> %o0 == parents pid, %o1 == 1 */ -int copy_thread(unsigned long clone_flags, unsigned long sp, +int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { diff --git a/trunk/arch/sparc/kernel/prom_64.c b/trunk/arch/sparc/kernel/prom_64.c index ca55c7012f77..edecca7b8116 100644 --- a/trunk/arch/sparc/kernel/prom_64.c +++ b/trunk/arch/sparc/kernel/prom_64.c @@ -518,8 +518,8 @@ void __init of_fill_in_cpu_data(void) } #ifdef CONFIG_SMP - set_cpu_present(cpuid, true); - set_cpu_possible(cpuid, true); + cpu_set(cpuid, cpu_present_map); + cpu_set(cpuid, cpu_possible_map); #endif } diff --git a/trunk/arch/sparc/kernel/smp_32.c b/trunk/arch/sparc/kernel/smp_32.c index 132d81fb2616..1e5ac4e282e1 100644 --- a/trunk/arch/sparc/kernel/smp_32.c +++ b/trunk/arch/sparc/kernel/smp_32.c @@ -70,12 +70,13 @@ void __init smp_cpus_done(unsigned int max_cpus) extern void smp4m_smp_done(void); extern void smp4d_smp_done(void); unsigned long bogosum = 0; - int cpu, num = 0; + int cpu, num; - for_each_online_cpu(cpu) { - num++; - bogosum += cpu_data(cpu).udelay_val; - } + for (cpu = 0, num = 0; cpu < NR_CPUS; cpu++) + if (cpu_online(cpu)) { + num++; + bogosum += cpu_data(cpu).udelay_val; + } printk("Total of %d processors activated (%lu.%02lu BogoMIPS).\n", num, bogosum/(500000/HZ), @@ -143,7 +144,7 @@ void smp_flush_tlb_all(void) void smp_flush_cache_mm(struct mm_struct *mm) { if(mm->context != NO_CONTEXT) { - cpumask_t cpu_mask = *mm_cpumask(mm); + cpumask_t cpu_mask = mm->cpu_vm_mask; cpu_clear(smp_processor_id(), cpu_mask); if (!cpus_empty(cpu_mask)) xc1((smpfunc_t) BTFIXUP_CALL(local_flush_cache_mm), (unsigned long) mm); @@ -154,13 +155,12 @@ void smp_flush_cache_mm(struct mm_struct *mm) void smp_flush_tlb_mm(struct mm_struct *mm) { if(mm->context != NO_CONTEXT) { - cpumask_t cpu_mask = *mm_cpumask(mm); + cpumask_t cpu_mask = mm->cpu_vm_mask; cpu_clear(smp_processor_id(), cpu_mask); if (!cpus_empty(cpu_mask)) { xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm); if(atomic_read(&mm->mm_users) == 1 && current->active_mm == mm) - cpumask_copy(mm_cpumask(mm), - cpumask_of(smp_processor_id())); + mm->cpu_vm_mask = cpumask_of_cpu(smp_processor_id()); } local_flush_tlb_mm(mm); } @@ -172,7 +172,7 @@ void smp_flush_cache_range(struct vm_area_struct *vma, unsigned long start, struct mm_struct *mm = vma->vm_mm; if (mm->context != NO_CONTEXT) { - cpumask_t cpu_mask = *mm_cpumask(mm); + cpumask_t cpu_mask = mm->cpu_vm_mask; cpu_clear(smp_processor_id(), cpu_mask); if (!cpus_empty(cpu_mask)) xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) vma, start, end); @@ -186,7 +186,7 @@ void smp_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, struct mm_struct *mm = vma->vm_mm; if (mm->context != NO_CONTEXT) { - cpumask_t cpu_mask = *mm_cpumask(mm); + cpumask_t cpu_mask = mm->cpu_vm_mask; cpu_clear(smp_processor_id(), cpu_mask); if (!cpus_empty(cpu_mask)) xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) vma, start, end); @@ -199,7 +199,7 @@ void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page) struct mm_struct *mm = vma->vm_mm; if(mm->context != NO_CONTEXT) { - cpumask_t cpu_mask = *mm_cpumask(mm); + cpumask_t cpu_mask = mm->cpu_vm_mask; cpu_clear(smp_processor_id(), cpu_mask); if (!cpus_empty(cpu_mask)) xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), (unsigned long) vma, page); @@ -212,7 +212,7 @@ void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) struct mm_struct *mm = vma->vm_mm; if(mm->context != NO_CONTEXT) { - cpumask_t cpu_mask = *mm_cpumask(mm); + cpumask_t cpu_mask = mm->cpu_vm_mask; cpu_clear(smp_processor_id(), cpu_mask); if (!cpus_empty(cpu_mask)) xc2((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_page), (unsigned long) vma, page); @@ -241,7 +241,7 @@ void smp_flush_page_to_ram(unsigned long page) void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) { - cpumask_t cpu_mask = *mm_cpumask(mm); + cpumask_t cpu_mask = mm->cpu_vm_mask; cpu_clear(smp_processor_id(), cpu_mask); if (!cpus_empty(cpu_mask)) xc2((smpfunc_t) BTFIXUP_CALL(local_flush_sig_insns), (unsigned long) mm, insn_addr); @@ -332,8 +332,8 @@ void __init smp_setup_cpu_possible_map(void) instance = 0; while (!cpu_find_by_instance(instance, NULL, &mid)) { if (mid < NR_CPUS) { - set_cpu_possible(mid, true); - set_cpu_present(mid, true); + cpu_set(mid, cpu_possible_map); + cpu_set(mid, cpu_present_map); } instance++; } @@ -351,8 +351,8 @@ void __init smp_prepare_boot_cpu(void) printk("boot cpu id != 0, this could work but is untested\n"); current_thread_info()->cpu = cpuid; - set_cpu_online(cpuid, true); - set_cpu_possible(cpuid, true); + cpu_set(cpuid, cpu_online_map); + cpu_set(cpuid, cpu_possible_map); } int __cpuinit __cpu_up(unsigned int cpu) diff --git a/trunk/arch/sparc/kernel/smp_64.c b/trunk/arch/sparc/kernel/smp_64.c index 708e12a26b05..79457f682b5a 100644 --- a/trunk/arch/sparc/kernel/smp_64.c +++ b/trunk/arch/sparc/kernel/smp_64.c @@ -808,9 +808,9 @@ static void smp_start_sync_tick_client(int cpu) extern unsigned long xcall_call_function; -void arch_send_call_function_ipi_mask(const struct cpumask *mask) +void arch_send_call_function_ipi(cpumask_t mask) { - xcall_deliver((u64) &xcall_call_function, 0, 0, mask); + xcall_deliver((u64) &xcall_call_function, 0, 0, &mask); } extern unsigned long xcall_call_function_single; @@ -850,7 +850,7 @@ static void tsb_sync(void *info) void smp_tsb_sync(struct mm_struct *mm) { - smp_call_function_many(mm_cpumask(mm), tsb_sync, mm, 1); + smp_call_function_mask(mm->cpu_vm_mask, tsb_sync, mm, 1); } extern unsigned long xcall_flush_tlb_mm; @@ -1055,13 +1055,13 @@ void smp_flush_tlb_mm(struct mm_struct *mm) int cpu = get_cpu(); if (atomic_read(&mm->mm_users) == 1) { - cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); + mm->cpu_vm_mask = cpumask_of_cpu(cpu); goto local_flush_and_out; } smp_cross_call_masked(&xcall_flush_tlb_mm, ctx, 0, 0, - mm_cpumask(mm)); + &mm->cpu_vm_mask); local_flush_and_out: __flush_tlb_mm(ctx, SECONDARY_CONTEXT); @@ -1075,11 +1075,11 @@ void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long int cpu = get_cpu(); if (mm == current->mm && atomic_read(&mm->mm_users) == 1) - cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); + mm->cpu_vm_mask = cpumask_of_cpu(cpu); else smp_cross_call_masked(&xcall_flush_tlb_pending, ctx, nr, (unsigned long) vaddrs, - mm_cpumask(mm)); + &mm->cpu_vm_mask); __flush_tlb_pending(ctx, nr, vaddrs); diff --git a/trunk/arch/sparc/kernel/sun4d_irq.c b/trunk/arch/sparc/kernel/sun4d_irq.c index ab036a72de5a..3369fef5b4b3 100644 --- a/trunk/arch/sparc/kernel/sun4d_irq.c +++ b/trunk/arch/sparc/kernel/sun4d_irq.c @@ -326,6 +326,7 @@ int sun4d_request_irq(unsigned int irq, action->handler = handler; action->flags = irqflags; + cpus_clear(action->mask); action->name = devname; action->next = NULL; action->dev_id = dev_id; diff --git a/trunk/arch/sparc/kernel/sun4d_smp.c b/trunk/arch/sparc/kernel/sun4d_smp.c index 54fb02468f0d..50afaed99c8a 100644 --- a/trunk/arch/sparc/kernel/sun4d_smp.c +++ b/trunk/arch/sparc/kernel/sun4d_smp.c @@ -150,7 +150,7 @@ void __cpuinit smp4d_callin(void) spin_lock_irqsave(&sun4d_imsk_lock, flags); cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */ spin_unlock_irqrestore(&sun4d_imsk_lock, flags); - set_cpu_online(cpuid, true); + cpu_set(cpuid, cpu_online_map); } @@ -228,10 +228,11 @@ void __init smp4d_smp_done(void) /* setup cpu list for irq rotation */ first = 0; prev = &first; - for_each_online_cpu(i) { - *prev = i; - prev = &cpu_data(i).next; - } + for (i = 0; i < NR_CPUS; i++) + if (cpu_online(i)) { + *prev = i; + prev = &cpu_data(i).next; + } *prev = first; local_flush_cache_all(); diff --git a/trunk/arch/sparc/kernel/sun4m_smp.c b/trunk/arch/sparc/kernel/sun4m_smp.c index 960b113d0006..8040376c4890 100644 --- a/trunk/arch/sparc/kernel/sun4m_smp.c +++ b/trunk/arch/sparc/kernel/sun4m_smp.c @@ -113,7 +113,7 @@ void __cpuinit smp4m_callin(void) local_irq_enable(); - set_cpu_online(cpuid, true); + cpu_set(cpuid, cpu_online_map); } /* @@ -186,9 +186,11 @@ void __init smp4m_smp_done(void) /* setup cpu list for irq rotation */ first = 0; prev = &first; - for_each_online_cpu(i) { - *prev = i; - prev = &cpu_data(i).next; + for (i = 0; i < NR_CPUS; i++) { + if (cpu_online(i)) { + *prev = i; + prev = &cpu_data(i).next; + } } *prev = first; local_flush_cache_all(); diff --git a/trunk/arch/sparc/mm/highmem.c b/trunk/arch/sparc/mm/highmem.c index 7916feba6e4a..752d0c9fb544 100644 --- a/trunk/arch/sparc/mm/highmem.c +++ b/trunk/arch/sparc/mm/highmem.c @@ -39,7 +39,6 @@ void *kmap_atomic(struct page *page, enum km_type type) if (!PageHighMem(page)) return page_address(page); - debug_kmap_atomic(type); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); diff --git a/trunk/arch/sparc/mm/init_64.c b/trunk/arch/sparc/mm/init_64.c index 2c8dfeb7ab04..00373ce2d8fb 100644 --- a/trunk/arch/sparc/mm/init_64.c +++ b/trunk/arch/sparc/mm/init_64.c @@ -1092,7 +1092,7 @@ static void __init numa_parse_mdesc_group_cpus(struct mdesc_handle *md, if (strcmp(name, "cpu")) continue; id = mdesc_get_property(md, target, "id", NULL); - if (*id < nr_cpu_ids) + if (*id < NR_CPUS) cpu_set(*id, *mask); } } diff --git a/trunk/arch/sparc/mm/srmmu.c b/trunk/arch/sparc/mm/srmmu.c index 06c9a7d98206..fe7ed08390bb 100644 --- a/trunk/arch/sparc/mm/srmmu.c +++ b/trunk/arch/sparc/mm/srmmu.c @@ -1425,7 +1425,7 @@ static void __init init_vac_layout(void) min_line_size = vac_line_size; //FIXME: cpus not contiguous!! cpu++; - if (cpu >= nr_cpu_ids || !cpu_online(cpu)) + if (cpu >= NR_CPUS || !cpu_online(cpu)) break; #else break; diff --git a/trunk/arch/um/drivers/net_kern.c b/trunk/arch/um/drivers/net_kern.c index 434ba121e3c5..434224e2229f 100644 --- a/trunk/arch/um/drivers/net_kern.c +++ b/trunk/arch/um/drivers/net_kern.c @@ -757,7 +757,7 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event, void (*proc)(unsigned char *, unsigned char *, void *); unsigned char addr_buf[4], netmask_buf[4]; - if (dev->netdev_ops->ndo_open != uml_net_open) + if (dev->open != uml_net_open) return NOTIFY_DONE; lp = netdev_priv(dev); diff --git a/trunk/arch/um/drivers/pcap_user.h b/trunk/arch/um/drivers/pcap_user.h index d8ba6153f912..96b80b565eeb 100644 --- a/trunk/arch/um/drivers/pcap_user.h +++ b/trunk/arch/um/drivers/pcap_user.h @@ -19,3 +19,13 @@ extern const struct net_user_info pcap_user_info; extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri); +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/port.h b/trunk/arch/um/drivers/port.h index 372a80c0556a..9117609a575d 100644 --- a/trunk/arch/um/drivers/port.h +++ b/trunk/arch/um/drivers/port.h @@ -18,3 +18,13 @@ extern void port_remove_dev(void *d); #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/ssl.h b/trunk/arch/um/drivers/ssl.h index 314d17725ce6..98412aa66607 100644 --- a/trunk/arch/um/drivers/ssl.h +++ b/trunk/arch/um/drivers/ssl.h @@ -11,3 +11,13 @@ extern void ssl_receive_char(int line, char ch); #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/stdio_console.h b/trunk/arch/um/drivers/stdio_console.h index 6d8275f71fd4..505a3d5bea5e 100644 --- a/trunk/arch/um/drivers/stdio_console.h +++ b/trunk/arch/um/drivers/stdio_console.h @@ -9,3 +9,13 @@ extern void save_console_flags(void); #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/ubd_kern.c b/trunk/arch/um/drivers/ubd_kern.c index d42f826a8ab9..0a868118cf06 100644 --- a/trunk/arch/um/drivers/ubd_kern.c +++ b/trunk/arch/um/drivers/ubd_kern.c @@ -17,6 +17,7 @@ * James McMechan */ +#define MAJOR_NR UBD_MAJOR #define UBD_SHIFT 4 #include "linux/kernel.h" @@ -114,7 +115,7 @@ static struct block_device_operations ubd_blops = { }; /* Protected by ubd_lock */ -static int fake_major = UBD_MAJOR; +static int fake_major = MAJOR_NR; static struct gendisk *ubd_gendisk[MAX_DEV]; static struct gendisk *fake_gendisk[MAX_DEV]; @@ -298,7 +299,7 @@ static int ubd_setup_common(char *str, int *index_out, char **error_out) } mutex_lock(&ubd_lock); - if (fake_major != UBD_MAJOR) { + if(fake_major != MAJOR_NR){ *error_out = "Can't assign a fake major twice"; goto out1; } @@ -817,13 +818,13 @@ static int ubd_disk_register(int major, u64 size, int unit, disk->first_minor = unit << UBD_SHIFT; disk->fops = &ubd_blops; set_capacity(disk, size / 512); - if (major == UBD_MAJOR) + if(major == MAJOR_NR) sprintf(disk->disk_name, "ubd%c", 'a' + unit); else sprintf(disk->disk_name, "ubd_fake%d", unit); /* sysfs register (not for ide fake devices) */ - if (major == UBD_MAJOR) { + if (major == MAJOR_NR) { ubd_devs[unit].pdev.id = unit; ubd_devs[unit].pdev.name = DRIVER_NAME; ubd_devs[unit].pdev.dev.release = ubd_device_release; @@ -870,13 +871,13 @@ static int ubd_add(int n, char **error_out) ubd_dev->queue->queuedata = ubd_dev; blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG); - err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]); + err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); if(err){ *error_out = "Failed to register device"; goto out_cleanup; } - if (fake_major != UBD_MAJOR) + if(fake_major != MAJOR_NR) ubd_disk_register(fake_major, ubd_dev->size, n, &fake_gendisk[n]); @@ -1058,10 +1059,10 @@ static int __init ubd_init(void) char *error; int i, err; - if (register_blkdev(UBD_MAJOR, "ubd")) + if (register_blkdev(MAJOR_NR, "ubd")) return -1; - if (fake_major != UBD_MAJOR) { + if (fake_major != MAJOR_NR) { char name[sizeof("ubd_nnn\0")]; snprintf(name, sizeof(name), "ubd_%d", fake_major); diff --git a/trunk/arch/um/drivers/xterm.h b/trunk/arch/um/drivers/xterm.h index 56b9c4aba423..f33a6e77b186 100644 --- a/trunk/arch/um/drivers/xterm.h +++ b/trunk/arch/um/drivers/xterm.h @@ -10,3 +10,13 @@ extern int xterm_fd(int socket, int *pid_out); #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/asm/irq_vectors.h b/trunk/arch/um/include/asm/irq_vectors.h index 272a81e0ce14..62ddba6fc733 100644 --- a/trunk/arch/um/include/asm/irq_vectors.h +++ b/trunk/arch/um/include/asm/irq_vectors.h @@ -8,3 +8,13 @@ #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/asm/mmu.h b/trunk/arch/um/include/asm/mmu.h index cf259de51531..2cf35c21d694 100644 --- a/trunk/arch/um/include/asm/mmu.h +++ b/trunk/arch/um/include/asm/mmu.h @@ -10,3 +10,13 @@ #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/asm/pda.h b/trunk/arch/um/include/asm/pda.h index ddcd774fc2a0..0d8bf33ffd42 100644 --- a/trunk/arch/um/include/asm/pda.h +++ b/trunk/arch/um/include/asm/pda.h @@ -19,3 +19,13 @@ extern struct foo me; #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/asm/pgalloc.h b/trunk/arch/um/include/asm/pgalloc.h index 718984359f8c..9062a6e72241 100644 --- a/trunk/arch/um/include/asm/pgalloc.h +++ b/trunk/arch/um/include/asm/pgalloc.h @@ -60,3 +60,13 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/asm/pgtable-3level.h b/trunk/arch/um/include/asm/pgtable-3level.h index 084de4a9fc70..0446f456b428 100644 --- a/trunk/arch/um/include/asm/pgtable-3level.h +++ b/trunk/arch/um/include/asm/pgtable-3level.h @@ -134,3 +134,13 @@ static inline pmd_t pfn_pmd(pfn_t page_nr, pgprot_t pgprot) #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/shared/frame_kern.h b/trunk/arch/um/include/shared/frame_kern.h index 76078490c258..ce9514f57211 100644 --- a/trunk/arch/um/include/shared/frame_kern.h +++ b/trunk/arch/um/include/shared/frame_kern.h @@ -20,3 +20,13 @@ extern int setup_signal_stack_si(unsigned long stack_top, int sig, #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/shared/initrd.h b/trunk/arch/um/include/shared/initrd.h index 22673bcc273d..439b9a814985 100644 --- a/trunk/arch/um/include/shared/initrd.h +++ b/trunk/arch/um/include/shared/initrd.h @@ -10,3 +10,13 @@ extern int load_initrd(char *filename, void *buf, int size); #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/shared/irq_kern.h b/trunk/arch/um/include/shared/irq_kern.h index b05d22f3d84e..fba3895274f9 100644 --- a/trunk/arch/um/include/shared/irq_kern.h +++ b/trunk/arch/um/include/shared/irq_kern.h @@ -16,3 +16,13 @@ extern int um_request_irq(unsigned int irq, int fd, int type, #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/shared/mem_kern.h b/trunk/arch/um/include/shared/mem_kern.h index 69be0fd0ce4b..cb7e196d366b 100644 --- a/trunk/arch/um/include/shared/mem_kern.h +++ b/trunk/arch/um/include/shared/mem_kern.h @@ -18,3 +18,13 @@ extern void register_remapper(struct remapper *info); #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/shared/ubd_user.h b/trunk/arch/um/include/shared/ubd_user.h index 3845051f1b10..bb66517f0739 100644 --- a/trunk/arch/um/include/shared/ubd_user.h +++ b/trunk/arch/um/include/shared/ubd_user.h @@ -14,3 +14,13 @@ extern int kernel_fd; #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/kernel/Makefile b/trunk/arch/um/kernel/Makefile index 388ec0a3ea9b..499e5e95e609 100644 --- a/trunk/arch/um/kernel/Makefile +++ b/trunk/arch/um/kernel/Makefile @@ -28,7 +28,7 @@ $(obj)/config.tmp: $(objtree)/.config FORCE $(call if_changed,quote1) quiet_cmd_quote1 = QUOTE $@ - cmd_quote1 = sed -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n",/' \ + cmd_quote1 = sed -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n"/' \ $< > $@ $(obj)/config.c: $(src)/config.c.in $(obj)/config.tmp FORCE @@ -36,9 +36,9 @@ $(obj)/config.c: $(src)/config.c.in $(obj)/config.tmp FORCE quiet_cmd_quote2 = QUOTE $@ cmd_quote2 = sed -e '/CONFIG/{' \ - -e 's/"CONFIG"//' \ + -e 's/"CONFIG"\;/""/' \ -e 'r $(obj)/config.tmp' \ -e 'a \' \ - -e '""' \ + -e '""\;' \ -e '}' \ $< > $@ diff --git a/trunk/arch/um/kernel/config.c.in b/trunk/arch/um/kernel/config.c.in index b7a43feafde7..c062cbfe386e 100644 --- a/trunk/arch/um/kernel/config.c.in +++ b/trunk/arch/um/kernel/config.c.in @@ -7,15 +7,11 @@ #include #include "init.h" -static __initdata const char *config[] = { -"CONFIG" -}; +static __initdata char *config = "CONFIG"; static int __init print_config(char *line, int *add) { - int i; - for (i = 0; i < sizeof(config)/sizeof(config[0]); i++) - printf("%s", config[i]); + printf("%s", config); exit(0); } @@ -24,3 +20,13 @@ __uml_setup("--showconfig", print_config, " Prints the config file that this UML binary was generated from.\n\n" ); +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/kernel/process.c b/trunk/arch/um/kernel/process.c index 4a28a1568d85..a1c6d07cac3e 100644 --- a/trunk/arch/um/kernel/process.c +++ b/trunk/arch/um/kernel/process.c @@ -179,7 +179,7 @@ void fork_handler(void) userspace(¤t->thread.regs.regs); } -int copy_thread(unsigned long clone_flags, unsigned long sp, +int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, unsigned long stack_top, struct task_struct * p, struct pt_regs *regs) { diff --git a/trunk/arch/um/kernel/syscall.c b/trunk/arch/um/kernel/syscall.c index a4625c7b2bf9..c4df705b8359 100644 --- a/trunk/arch/um/kernel/syscall.c +++ b/trunk/arch/um/kernel/syscall.c @@ -127,8 +127,7 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]) fs = get_fs(); set_fs(KERNEL_DS); - ret = um_execve((char *)filename, (char __user *__user *)argv, - (char __user *__user *) envp); + ret = um_execve(filename, argv, envp); set_fs(fs); return ret; diff --git a/trunk/arch/um/os-Linux/start_up.c b/trunk/arch/um/os-Linux/start_up.c index 02ee9adff54a..183db26d01bf 100644 --- a/trunk/arch/um/os-Linux/start_up.c +++ b/trunk/arch/um/os-Linux/start_up.c @@ -244,7 +244,7 @@ static void __init check_sysemu(void) if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *) PTRACE_O_TRACESYSGOOD) < 0)) - fatal_perror("check_sysemu: PTRACE_OLDSETOPTIONS failed"); + fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed"); while (1) { count++; @@ -252,12 +252,12 @@ static void __init check_sysemu(void) goto fail; CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if (n < 0) - fatal_perror("check_sysemu: wait failed"); + fatal_perror("check_ptrace : wait failed"); if (WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))) { if (!count) { - non_fatal("check_sysemu: SYSEMU_SINGLESTEP " + non_fatal("check_ptrace : SYSEMU_SINGLESTEP " "doesn't singlestep"); goto fail; } @@ -271,7 +271,7 @@ static void __init check_sysemu(void) else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) count++; else { - non_fatal("check_sysemu: expected SIGTRAP or " + non_fatal("check_ptrace : expected SIGTRAP or " "(SIGTRAP | 0x80), got status = %d\n", status); goto fail; diff --git a/trunk/arch/um/sys-i386/asm/archparam.h b/trunk/arch/um/sys-i386/asm/archparam.h index 2a18a884ca1b..93fd723344e5 100644 --- a/trunk/arch/um/sys-i386/asm/archparam.h +++ b/trunk/arch/um/sys-i386/asm/archparam.h @@ -14,3 +14,13 @@ #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-i386/shared/sysdep/checksum.h b/trunk/arch/um/sys-i386/shared/sysdep/checksum.h index ed47445f3905..0cb4645cbeb8 100644 --- a/trunk/arch/um/sys-i386/shared/sysdep/checksum.h +++ b/trunk/arch/um/sys-i386/shared/sysdep/checksum.h @@ -199,3 +199,13 @@ static __inline__ __wsum csum_and_copy_to_user(const void *src, #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-i386/sys_call_table.S b/trunk/arch/um/sys-i386/sys_call_table.S index c6260dd6ebb9..00e5f5203eea 100644 --- a/trunk/arch/um/sys-i386/sys_call_table.S +++ b/trunk/arch/um/sys-i386/sys_call_table.S @@ -9,17 +9,6 @@ #define old_mmap old_mmap_i386 -#define ptregs_fork sys_fork -#define ptregs_execve sys_execve -#define ptregs_iopl sys_iopl -#define ptregs_vm86old sys_vm86old -#define ptregs_sigreturn sys_sigreturn -#define ptregs_clone sys_clone -#define ptregs_vm86 sys_vm86 -#define ptregs_rt_sigreturn sys_rt_sigreturn -#define ptregs_sigaltstack sys_sigaltstack -#define ptregs_vfork sys_vfork - .section .rodata,"a" #include "../../x86/kernel/syscall_table_32.S" diff --git a/trunk/arch/um/sys-ia64/sysdep/ptrace.h b/trunk/arch/um/sys-ia64/sysdep/ptrace.h index 0f0f4e6fd334..42dd8fb6f2f9 100644 --- a/trunk/arch/um/sys-ia64/sysdep/ptrace.h +++ b/trunk/arch/um/sys-ia64/sysdep/ptrace.h @@ -14,3 +14,13 @@ struct sys_pt_regs { #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ia64/sysdep/sigcontext.h b/trunk/arch/um/sys-ia64/sysdep/sigcontext.h index 76b43161e779..f15fb25260ba 100644 --- a/trunk/arch/um/sys-ia64/sysdep/sigcontext.h +++ b/trunk/arch/um/sys-ia64/sysdep/sigcontext.h @@ -8,3 +8,13 @@ #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ia64/sysdep/syscalls.h b/trunk/arch/um/sys-ia64/sysdep/syscalls.h index 5f6700c41558..4a1f46ef1ebc 100644 --- a/trunk/arch/um/sys-ia64/sysdep/syscalls.h +++ b/trunk/arch/um/sys-ia64/sysdep/syscalls.h @@ -8,3 +8,13 @@ #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ppc/miscthings.c b/trunk/arch/um/sys-ppc/miscthings.c index 1c11aed9c719..373061c50129 100644 --- a/trunk/arch/um/sys-ppc/miscthings.c +++ b/trunk/arch/um/sys-ppc/miscthings.c @@ -40,3 +40,14 @@ void shove_aux_table(unsigned long sp) } /* END stuff taken from arch/ppc/kernel/process.c */ + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ppc/ptrace.c b/trunk/arch/um/sys-ppc/ptrace.c index 66ef155248f1..8e71b47f2b8e 100644 --- a/trunk/arch/um/sys-ppc/ptrace.c +++ b/trunk/arch/um/sys-ppc/ptrace.c @@ -56,3 +56,13 @@ int peek_user(struct task_struct *child, long addr, long data) return put_user(tmp, (unsigned long *) data); } +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ppc/ptrace_user.c b/trunk/arch/um/sys-ppc/ptrace_user.c index 224d2403c37b..ff0b9c077a13 100644 --- a/trunk/arch/um/sys-ppc/ptrace_user.c +++ b/trunk/arch/um/sys-ppc/ptrace_user.c @@ -27,3 +27,13 @@ int ptrace_setregs(long pid, unsigned long *regs_in) } return 0; } +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ppc/shared/sysdep/ptrace.h b/trunk/arch/um/sys-ppc/shared/sysdep/ptrace.h index 0e3230e937e1..df2397dba3e5 100644 --- a/trunk/arch/um/sys-ppc/shared/sysdep/ptrace.h +++ b/trunk/arch/um/sys-ppc/shared/sysdep/ptrace.h @@ -91,3 +91,13 @@ extern void shove_aux_table(unsigned long sp); #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ppc/shared/sysdep/sigcontext.h b/trunk/arch/um/sys-ppc/shared/sysdep/sigcontext.h index b7286f0a1e00..f20d965de9c7 100644 --- a/trunk/arch/um/sys-ppc/shared/sysdep/sigcontext.h +++ b/trunk/arch/um/sys-ppc/shared/sysdep/sigcontext.h @@ -50,3 +50,13 @@ #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ppc/shared/sysdep/syscalls.h b/trunk/arch/um/sys-ppc/shared/sysdep/syscalls.h index 1ff81552251c..679df351e19b 100644 --- a/trunk/arch/um/sys-ppc/shared/sysdep/syscalls.h +++ b/trunk/arch/um/sys-ppc/shared/sysdep/syscalls.h @@ -41,3 +41,13 @@ int old_mmap(unsigned long addr, unsigned long len, #define LAST_ARCH_SYSCALL __NR_fadvise64 +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-ppc/sigcontext.c b/trunk/arch/um/sys-ppc/sigcontext.c index 40694d0f3d15..4bdc15c89edd 100644 --- a/trunk/arch/um/sys-ppc/sigcontext.c +++ b/trunk/arch/um/sys-ppc/sigcontext.c @@ -2,3 +2,13 @@ #include "asm/sigcontext.h" #include "sysdep/ptrace.h" +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-x86_64/asm/archparam.h b/trunk/arch/um/sys-x86_64/asm/archparam.h index 6c083663b8d9..270ed9586b68 100644 --- a/trunk/arch/um/sys-x86_64/asm/archparam.h +++ b/trunk/arch/um/sys-x86_64/asm/archparam.h @@ -14,3 +14,13 @@ #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-x86_64/asm/module.h b/trunk/arch/um/sys-x86_64/asm/module.h index 8eb79c2d07d5..35b5491d3e96 100644 --- a/trunk/arch/um/sys-x86_64/asm/module.h +++ b/trunk/arch/um/sys-x86_64/asm/module.h @@ -18,3 +18,13 @@ struct mod_arch_specific #endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-x86_64/mem.c b/trunk/arch/um/sys-x86_64/mem.c index 3f8df8abf347..3f59a0a4f156 100644 --- a/trunk/arch/um/sys-x86_64/mem.c +++ b/trunk/arch/um/sys-x86_64/mem.c @@ -14,3 +14,12 @@ unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS; unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS; unsigned long vm_force_exec32 = PROT_EXEC; +/* Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 748e50a1a152..06c02c00d7d9 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -40,7 +40,6 @@ config X86 select HAVE_GENERIC_DMA_COHERENT if X86_32 select HAVE_EFFICIENT_UNALIGNED_ACCESS select USER_STACKTRACE_SUPPORT - select HAVE_DMA_API_DEBUG select HAVE_KERNEL_GZIP select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_LZMA @@ -165,9 +164,6 @@ config AUDIT_ARCH config ARCH_SUPPORTS_OPTIMIZED_INLINING def_bool y -config ARCH_SUPPORTS_DEBUG_PAGEALLOC - def_bool y - # Use the generic interrupt handling code in kernel/irq/: config GENERIC_HARDIRQS bool @@ -790,11 +786,6 @@ config X86_MCE_AMD Additional support for AMD specific MCE features such as the DRAM Error Threshold. -config X86_MCE_THRESHOLD - depends on X86_MCE_AMD || X86_MCE_INTEL - bool - default y - config X86_MCE_NONFATAL tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4" depends on X86_32 && X86_MCE @@ -938,12 +929,6 @@ config X86_CPUID with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to /dev/cpu/31/cpuid. -config X86_CPU_DEBUG - tristate "/sys/kernel/debug/x86/cpu/* - CPU Debug support" - ---help--- - If you select this option, this will provide various x86 CPUs - information through debugfs. - choice prompt "High Memory Support" default HIGHMEM4G if !X86_NUMAQ @@ -1136,7 +1121,7 @@ config NUMA_EMU config NODES_SHIFT int "Maximum NUMA Nodes (as a power of 2)" if !MAXSMP - range 1 9 + range 1 9 if X86_64 default "9" if MAXSMP default "6" if X86_64 default "4" if X86_NUMAQ @@ -1444,7 +1429,7 @@ config CRASH_DUMP config KEXEC_JUMP bool "kexec jump (EXPERIMENTAL)" depends on EXPERIMENTAL - depends on KEXEC && HIBERNATION + depends on KEXEC && HIBERNATION && X86_32 ---help--- Jump between original kernel and kexeced kernel and invoke code in physical address mode via KEXEC diff --git a/trunk/arch/x86/Kconfig.cpu b/trunk/arch/x86/Kconfig.cpu index 924e156a85ab..a95eaf0e582a 100644 --- a/trunk/arch/x86/Kconfig.cpu +++ b/trunk/arch/x86/Kconfig.cpu @@ -456,9 +456,24 @@ config CPU_SUP_AMD If unsure, say N. -config CPU_SUP_CENTAUR +config CPU_SUP_CENTAUR_32 default y bool "Support Centaur processors" if PROCESSOR_SELECT + depends on !64BIT + ---help--- + This enables detection, tunings and quirks for Centaur processors + + You need this enabled if you want your kernel to run on a + Centaur CPU. Disabling this option on other types of CPUs + makes the kernel a tiny bit smaller. Disabling it on a Centaur + CPU might render the kernel unbootable. + + If unsure, say N. + +config CPU_SUP_CENTAUR_64 + default y + bool "Support Centaur processors" if PROCESSOR_SELECT + depends on 64BIT ---help--- This enables detection, tunings and quirks for Centaur processors diff --git a/trunk/arch/x86/Kconfig.debug b/trunk/arch/x86/Kconfig.debug index d8359e73317f..fdb45df608b6 100644 --- a/trunk/arch/x86/Kconfig.debug +++ b/trunk/arch/x86/Kconfig.debug @@ -72,6 +72,14 @@ config DEBUG_STACK_USAGE This option will slow down process creation somewhat. +config DEBUG_PAGEALLOC + bool "Debug page memory allocations" + depends on DEBUG_KERNEL + ---help--- + Unmap pages from the kernel linear mapping after free_pages(). + This results in a large slowdown, but helps to find certain types + of memory corruptions. + config DEBUG_PER_CPU_MAPS bool "Debug access to per_cpu maps" depends on DEBUG_KERNEL diff --git a/trunk/arch/x86/Makefile b/trunk/arch/x86/Makefile index f05d8c91d9e5..1836191839ee 100644 --- a/trunk/arch/x86/Makefile +++ b/trunk/arch/x86/Makefile @@ -153,23 +153,34 @@ endif boot := arch/x86/boot -BOOT_TARGETS = bzlilo bzdisk fdimage fdimage144 fdimage288 isoimage install - -PHONY += bzImage $(BOOT_TARGETS) +PHONY += zImage bzImage compressed zlilo bzlilo \ + zdisk bzdisk fdimage fdimage144 fdimage288 isoimage install # Default kernel to build all: bzImage # KBUILD_IMAGE specify target image being built -KBUILD_IMAGE := $(boot)/bzImage + KBUILD_IMAGE := $(boot)/bzImage +zImage zlilo zdisk: KBUILD_IMAGE := $(boot)/zImage -bzImage: vmlinux +zImage bzImage: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE) $(Q)mkdir -p $(objtree)/arch/$(UTS_MACHINE)/boot $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/$(UTS_MACHINE)/boot/$@ -$(BOOT_TARGETS): vmlinux - $(Q)$(MAKE) $(build)=$(boot) $@ +compressed: zImage + +zlilo bzlilo: vmlinux + $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zlilo + +zdisk bzdisk: vmlinux + $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zdisk + +fdimage fdimage144 fdimage288 isoimage: vmlinux + $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ + +install: + $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install PHONY += vdso_install vdso_install: @@ -194,3 +205,7 @@ define archhelp echo ' FDARGS="..." arguments for the booted kernel' echo ' FDINITRD=file initrd for the booted kernel' endef + +CLEAN_FILES += arch/x86/boot/fdimage \ + arch/x86/boot/image.iso \ + arch/x86/boot/mtools.conf diff --git a/trunk/arch/x86/boot/Makefile b/trunk/arch/x86/boot/Makefile index fb737ce5888d..c70eff69a1fb 100644 --- a/trunk/arch/x86/boot/Makefile +++ b/trunk/arch/x86/boot/Makefile @@ -6,24 +6,26 @@ # for more details. # # Copyright (C) 1994 by Linus Torvalds -# Changed by many, many contributors over the years. # # ROOT_DEV specifies the default root-device when making the image. # This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case # the default of FLOPPY is used by 'build'. -ROOT_DEV := CURRENT +ROOT_DEV := CURRENT # If you want to preset the SVGA mode, uncomment the next line and # set SVGA_MODE to whatever number you want. # Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode. # The number is the same as you would ordinarily press at bootup. -SVGA_MODE := -DSVGA_MODE=NORMAL_VGA +SVGA_MODE := -DSVGA_MODE=NORMAL_VGA -targets := vmlinux.bin setup.bin setup.elf bzImage -targets += fdimage fdimage144 fdimage288 image.iso mtools.conf +# If you want the RAM disk device, define this to be the size in blocks. + +#RAMDISK := -DRAMDISK=512 + +targets := vmlinux.bin setup.bin setup.elf zImage bzImage subdir- := compressed setup-y += a20.o cmdline.o copy.o cpu.o cpucheck.o edd.o @@ -69,13 +71,17 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \ KBUILD_CFLAGS += $(call cc-option,-m32) KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ -$(obj)/bzImage: asflags-y := $(SVGA_MODE) +$(obj)/zImage: asflags-y := $(SVGA_MODE) $(RAMDISK) +$(obj)/bzImage: ccflags-y := -D__BIG_KERNEL__ +$(obj)/bzImage: asflags-y := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ +$(obj)/bzImage: BUILDFLAGS := -b quiet_cmd_image = BUILD $@ -cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin \ - $(ROOT_DEV) > $@ +cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/setup.bin \ + $(obj)/vmlinux.bin $(ROOT_DEV) > $@ -$(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE +$(obj)/zImage $(obj)/bzImage: $(obj)/setup.bin \ + $(obj)/vmlinux.bin $(obj)/tools/build FORCE $(call if_changed,image) @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' @@ -110,11 +116,9 @@ $(obj)/setup.bin: $(obj)/setup.elf FORCE $(obj)/compressed/vmlinux: FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed $@ -# Set this if you want to pass append arguments to the -# bzdisk/fdimage/isoimage kernel +# Set this if you want to pass append arguments to the zdisk/fdimage/isoimage kernel FDARGS = -# Set this if you want an initrd included with the -# bzdisk/fdimage/isoimage kernel +# Set this if you want an initrd included with the zdisk/fdimage/isoimage kernel FDINITRD = image_cmdline = default linux $(FDARGS) $(if $(FDINITRD),initrd=initrd.img,) @@ -123,7 +127,7 @@ $(obj)/mtools.conf: $(src)/mtools.conf.in sed -e 's|@OBJ@|$(obj)|g' < $< > $@ # This requires write access to /dev/fd0 -bzdisk: $(obj)/bzImage $(obj)/mtools.conf +zdisk: $(BOOTIMAGE) $(obj)/mtools.conf MTOOLSRC=$(obj)/mtools.conf mformat a: ; sync syslinux /dev/fd0 ; sync echo '$(image_cmdline)' | \ @@ -131,10 +135,10 @@ bzdisk: $(obj)/bzImage $(obj)/mtools.conf if [ -f '$(FDINITRD)' ] ; then \ MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' a:initrd.img ; \ fi - MTOOLSRC=$(obj)/mtools.conf mcopy $(obj)/bzImage a:linux ; sync + MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux ; sync # These require being root or having syslinux 2.02 or higher installed -fdimage fdimage144: $(obj)/bzImage $(obj)/mtools.conf +fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440 MTOOLSRC=$(obj)/mtools.conf mformat v: ; sync syslinux $(obj)/fdimage ; sync @@ -143,9 +147,9 @@ fdimage fdimage144: $(obj)/bzImage $(obj)/mtools.conf if [ -f '$(FDINITRD)' ] ; then \ MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' v:initrd.img ; \ fi - MTOOLSRC=$(obj)/mtools.conf mcopy $(obj)/bzImage v:linux ; sync + MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux ; sync -fdimage288: $(obj)/bzImage $(obj)/mtools.conf +fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880 MTOOLSRC=$(obj)/mtools.conf mformat w: ; sync syslinux $(obj)/fdimage ; sync @@ -154,9 +158,9 @@ fdimage288: $(obj)/bzImage $(obj)/mtools.conf if [ -f '$(FDINITRD)' ] ; then \ MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' w:initrd.img ; \ fi - MTOOLSRC=$(obj)/mtools.conf mcopy $(obj)/bzImage w:linux ; sync + MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux ; sync -isoimage: $(obj)/bzImage +isoimage: $(BOOTIMAGE) -rm -rf $(obj)/isoimage mkdir $(obj)/isoimage for i in lib lib64 share end ; do \ @@ -166,7 +170,7 @@ isoimage: $(obj)/bzImage fi ; \ if [ $$i = end ] ; then exit 1 ; fi ; \ done - cp $(obj)/bzImage $(obj)/isoimage/linux + cp $(BOOTIMAGE) $(obj)/isoimage/linux echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg if [ -f '$(FDINITRD)' ] ; then \ cp '$(FDINITRD)' $(obj)/isoimage/initrd.img ; \ @@ -177,13 +181,12 @@ isoimage: $(obj)/bzImage isohybrid $(obj)/image.iso 2>/dev/null || true rm -rf $(obj)/isoimage -bzlilo: $(obj)/bzImage +zlilo: $(BOOTIMAGE) if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi - cat $(obj)/bzImage > $(INSTALL_PATH)/vmlinuz + cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz cp System.map $(INSTALL_PATH)/ if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi install: - sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(obj)/bzImage \ - System.map "$(INSTALL_PATH)" + sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)" diff --git a/trunk/arch/x86/boot/header.S b/trunk/arch/x86/boot/header.S index 5d84d1c74e4c..7ccff4884a23 100644 --- a/trunk/arch/x86/boot/header.S +++ b/trunk/arch/x86/boot/header.S @@ -24,8 +24,12 @@ #include "boot.h" #include "offsets.h" +SETUPSECTS = 4 /* default nr of setup-sectors */ BOOTSEG = 0x07C0 /* original address of boot-sector */ -SYSSEG = 0x1000 /* historical load address >> 4 */ +SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */ +SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */ + /* to be loaded */ +ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */ #ifndef SVGA_MODE #define SVGA_MODE ASK_VGA @@ -93,12 +97,12 @@ bugger_off_msg: .section ".header", "a" .globl hdr hdr: -setup_sects: .byte 0 /* Filled in by build.c */ +setup_sects: .byte SETUPSECTS root_flags: .word ROOT_RDONLY -syssize: .long 0 /* Filled in by build.c */ -ram_size: .word 0 /* Obsolete */ +syssize: .long SYSSIZE +ram_size: .word RAMDISK vid_mode: .word SVGA_MODE -root_dev: .word 0 /* Filled in by build.c */ +root_dev: .word ROOT_DEV boot_flag: .word 0xAA55 # offset 512, entry point @@ -119,15 +123,14 @@ _start: # or else old loadlin-1.5 will fail) .globl realmode_swtch realmode_swtch: .word 0, 0 # default_switch, SETUPSEG -start_sys_seg: .word SYSSEG # obsolete and meaningless, but just - # in case something decided to "use" it +start_sys_seg: .word SYSSEG .word kernel_version-512 # pointing to kernel version string # above section of header is compatible # with loadlin-1.5 (header v1.5). Don't # change it. -type_of_loader: .byte 0 # 0 means ancient bootloader, newer - # bootloaders know to change this. +type_of_loader: .byte 0 # = 0, old one (LILO, Loadlin, + # Bootlin, SYSLX, bootsect...) # See Documentation/i386/boot.txt for # assigned ids @@ -139,7 +142,11 @@ CAN_USE_HEAP = 0x80 # If set, the loader also has set # space behind setup.S can be used for # heap purposes. # Only the loader knows what is free +#ifndef __BIG_KERNEL__ + .byte 0 +#else .byte LOADED_HIGH +#endif setup_move_size: .word 0x8000 # size to move, when setup is not # loaded at 0x90000. We will move setup @@ -150,7 +157,11 @@ setup_move_size: .word 0x8000 # size to move, when setup is not code32_start: # here loaders can put a different # start address for 32-bit code. +#ifndef __BIG_KERNEL__ + .long 0x1000 # 0x1000 = default for zImage +#else .long 0x100000 # 0x100000 = default for big kernel +#endif ramdisk_image: .long 0 # address of loaded ramdisk image # Here the loader puts the 32-bit diff --git a/trunk/arch/x86/boot/memory.c b/trunk/arch/x86/boot/memory.c index 5054c2ddd1a0..8c3c25f35578 100644 --- a/trunk/arch/x86/boot/memory.c +++ b/trunk/arch/x86/boot/memory.c @@ -2,7 +2,6 @@ * * Copyright (C) 1991, 1992 Linus Torvalds * Copyright 2007 rPath, Inc. - All Rights Reserved - * Copyright 2009 Intel Corporation; author H. Peter Anvin * * This file is part of the Linux kernel, and is made available under * the terms of the GNU General Public License version 2. @@ -17,38 +16,24 @@ #define SMAP 0x534d4150 /* ASCII "SMAP" */ -struct e820_ext_entry { - struct e820entry std; - u32 ext_flags; -} __attribute__((packed)); - static int detect_memory_e820(void) { int count = 0; u32 next = 0; - u32 size, id, edi; + u32 size, id; u8 err; struct e820entry *desc = boot_params.e820_map; - static struct e820_ext_entry buf; /* static so it is zeroed */ - - /* - * Set this here so that if the BIOS doesn't change this field - * but still doesn't change %ecx, we're still okay... - */ - buf.ext_flags = 1; do { - size = sizeof buf; + size = sizeof(struct e820entry); - /* Important: %edx and %esi are clobbered by some BIOSes, - so they must be either used for the error output - or explicitly marked clobbered. Given that, assume there - is something out there clobbering %ebp and %edi, too. */ - asm("pushl %%ebp; int $0x15; popl %%ebp; setc %0" + /* Important: %edx is clobbered by some BIOSes, + so it must be either used for the error output + or explicitly marked clobbered. */ + asm("int $0x15; setc %0" : "=d" (err), "+b" (next), "=a" (id), "+c" (size), - "=D" (edi), "+m" (buf) - : "D" (&buf), "d" (SMAP), "a" (0xe820) - : "esi"); + "=m" (*desc) + : "D" (desc), "d" (SMAP), "a" (0xe820)); /* BIOSes which terminate the chain with CF = 1 as opposed to %ebx = 0 don't always report the SMAP signature on @@ -66,14 +51,8 @@ static int detect_memory_e820(void) break; } - /* ACPI 3.0 added the extended flags support. If bit 0 - in the extended flags is zero, we're supposed to simply - ignore the entry -- a backwards incompatible change! */ - if (size > 20 && !(buf.ext_flags & 1)) - continue; - - *desc++ = buf.std; count++; + desc++; } while (next && count < ARRAY_SIZE(boot_params.e820_map)); return boot_params.e820_entries = count; diff --git a/trunk/arch/x86/boot/pm.c b/trunk/arch/x86/boot/pm.c index 8062f8915250..85a1cd8a8ff8 100644 --- a/trunk/arch/x86/boot/pm.c +++ b/trunk/arch/x86/boot/pm.c @@ -32,6 +32,47 @@ static void realmode_switch_hook(void) } } +/* + * A zImage kernel is loaded at 0x10000 but wants to run at 0x1000. + * A bzImage kernel is loaded and runs at 0x100000. + */ +static void move_kernel_around(void) +{ + /* Note: rely on the compile-time option here rather than + the LOADED_HIGH flag. The Qemu kernel loader unconditionally + sets the loadflags to zero. */ +#ifndef __BIG_KERNEL__ + u16 dst_seg, src_seg; + u32 syssize; + + dst_seg = 0x1000 >> 4; + src_seg = 0x10000 >> 4; + syssize = boot_params.hdr.syssize; /* Size in 16-byte paragraphs */ + + while (syssize) { + int paras = (syssize >= 0x1000) ? 0x1000 : syssize; + int dwords = paras << 2; + + asm volatile("pushw %%es ; " + "pushw %%ds ; " + "movw %1,%%es ; " + "movw %2,%%ds ; " + "xorw %%di,%%di ; " + "xorw %%si,%%si ; " + "rep;movsl ; " + "popw %%ds ; " + "popw %%es" + : "+c" (dwords) + : "r" (dst_seg), "r" (src_seg) + : "esi", "edi"); + + syssize -= paras; + dst_seg += paras; + src_seg += paras; + } +#endif +} + /* * Disable all interrupts at the legacy PIC. */ @@ -106,6 +147,9 @@ void go_to_protected_mode(void) /* Hook before leaving real mode, also disables interrupts */ realmode_switch_hook(); + /* Move the kernel/setup to their final resting places */ + move_kernel_around(); + /* Enable the A20 gate */ if (enable_a20()) { puts("A20 gate not responding, unable to boot...\n"); diff --git a/trunk/arch/x86/boot/pmjump.S b/trunk/arch/x86/boot/pmjump.S index 3e0edc6d2a20..019c17a75851 100644 --- a/trunk/arch/x86/boot/pmjump.S +++ b/trunk/arch/x86/boot/pmjump.S @@ -47,7 +47,6 @@ GLOBAL(protected_mode_jump) ENDPROC(protected_mode_jump) .code32 - .section ".text32","ax" GLOBAL(in_pm32) # Set up data segments for flat 32-bit mode movl %ecx, %ds diff --git a/trunk/arch/x86/boot/setup.ld b/trunk/arch/x86/boot/setup.ld index bb8dc2de7969..df9234b3a5e0 100644 --- a/trunk/arch/x86/boot/setup.ld +++ b/trunk/arch/x86/boot/setup.ld @@ -17,8 +17,7 @@ SECTIONS .header : { *(.header) } .inittext : { *(.inittext) } .initdata : { *(.initdata) } - .text : { *(.text) } - .text32 : { *(.text32) } + .text : { *(.text*) } . = ALIGN(16); .rodata : { *(.rodata*) } diff --git a/trunk/arch/x86/boot/tools/build.c b/trunk/arch/x86/boot/tools/build.c index ee3a4ea923ac..44dc1923c0e3 100644 --- a/trunk/arch/x86/boot/tools/build.c +++ b/trunk/arch/x86/boot/tools/build.c @@ -130,7 +130,7 @@ static void die(const char * str, ...) static void usage(void) { - die("Usage: build setup system [rootdev] [> image]"); + die("Usage: build [-b] setup system [rootdev] [> image]"); } int main(int argc, char ** argv) @@ -145,6 +145,11 @@ int main(int argc, char ** argv) void *kernel; u32 crc = 0xffffffffUL; + if (argc > 2 && !strcmp(argv[1], "-b")) + { + is_big_kernel = 1; + argc--, argv++; + } if ((argc < 3) || (argc > 4)) usage(); if (argc > 3) { @@ -211,6 +216,8 @@ int main(int argc, char ** argv) die("Unable to mmap '%s': %m", argv[2]); /* Number of 16-byte paragraphs, including space for a 4-byte CRC */ sys_size = (sz + 15 + 4) / 16; + if (!is_big_kernel && sys_size > DEF_SYSSIZE) + die("System is too big. Try using bzImage or modules."); /* Patch the setup code with the appropriate size parameters */ buf[0x1f1] = setup_sectors-1; diff --git a/trunk/arch/x86/boot/video-vga.c b/trunk/arch/x86/boot/video-vga.c index 95d86ce0421c..5d4742ed4aa2 100644 --- a/trunk/arch/x86/boot/video-vga.c +++ b/trunk/arch/x86/boot/video-vga.c @@ -129,45 +129,41 @@ u16 vga_crtc(void) return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4; } -static void vga_set_480_scanlines(int lines) +static void vga_set_480_scanlines(int end) { - u16 crtc; /* CRTC base address */ - u8 csel; /* CRTC miscellaneous output register */ - u8 ovfw; /* CRTC overflow register */ - int end = lines-1; + u16 crtc; + u8 csel; crtc = vga_crtc(); - ovfw = 0x3c | ((end >> (8-1)) & 0x02) | ((end >> (9-6)) & 0x40); - out_idx(0x0c, crtc, 0x11); /* Vertical sync end, unlock CR0-7 */ out_idx(0x0b, crtc, 0x06); /* Vertical total */ - out_idx(ovfw, crtc, 0x07); /* Vertical overflow */ + out_idx(0x3e, crtc, 0x07); /* Vertical overflow */ out_idx(0xea, crtc, 0x10); /* Vertical sync start */ - out_idx(end, crtc, 0x12); /* Vertical display end */ + out_idx(end, crtc, 0x12); /* Vertical display end */ out_idx(0xe7, crtc, 0x15); /* Vertical blank start */ out_idx(0x04, crtc, 0x16); /* Vertical blank end */ csel = inb(0x3cc); csel &= 0x0d; csel |= 0xe2; - outb(csel, 0x3c2); + outb(csel, 0x3cc); } static void vga_set_80x30(void) { - vga_set_480_scanlines(30*16); + vga_set_480_scanlines(0xdf); } static void vga_set_80x34(void) { vga_set_14font(); - vga_set_480_scanlines(34*14); + vga_set_480_scanlines(0xdb); } static void vga_set_80x60(void) { vga_set_8font(); - vga_set_480_scanlines(60*8); + vga_set_480_scanlines(0xdf); } static int vga_set_mode(struct mode_info *mode) diff --git a/trunk/arch/x86/ia32/ia32entry.S b/trunk/arch/x86/ia32/ia32entry.S index a505202086e8..db0c803170ab 100644 --- a/trunk/arch/x86/ia32/ia32entry.S +++ b/trunk/arch/x86/ia32/ia32entry.S @@ -828,6 +828,4 @@ ia32_sys_call_table: .quad sys_dup3 /* 330 */ .quad sys_pipe2 .quad sys_inotify_init1 - .quad compat_sys_preadv - .quad compat_sys_pwritev ia32_syscall_end: diff --git a/trunk/arch/x86/include/asm/apic.h b/trunk/arch/x86/include/asm/apic.h index df8a300dfe6c..4ef949c1972e 100644 --- a/trunk/arch/x86/include/asm/apic.h +++ b/trunk/arch/x86/include/asm/apic.h @@ -75,7 +75,7 @@ static inline void default_inquire_remote_apic(int apicid) #define setup_secondary_clock setup_secondary_APIC_clock #endif -#ifdef CONFIG_X86_64 +#ifdef CONFIG_X86_VSMP extern int is_vsmp_box(void); #else static inline int is_vsmp_box(void) @@ -108,16 +108,6 @@ extern void native_apic_icr_write(u32 low, u32 id); extern u64 native_apic_icr_read(void); #ifdef CONFIG_X86_X2APIC -/* - * Make previous memory operations globally visible before - * sending the IPI through x2apic wrmsr. We need a serializing instruction or - * mfence for this. - */ -static inline void x2apic_wrmsr_fence(void) -{ - asm volatile("mfence" : : : "memory"); -} - static inline void native_apic_msr_write(u32 reg, u32 v) { if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR || @@ -194,9 +184,6 @@ static inline int x2apic_enabled(void) { return 0; } - -#define x2apic 0 - #endif extern int get_physical_broadcast(void); @@ -392,7 +379,6 @@ static inline u32 safe_apic_wait_icr_idle(void) static inline void ack_APIC_irq(void) { -#ifdef CONFIG_X86_LOCAL_APIC /* * ack_APIC_irq() actually gets compiled as a single instruction * ... yummie. @@ -400,7 +386,6 @@ static inline void ack_APIC_irq(void) /* Docs say use 0 for future compatibility */ apic_write(APIC_EOI, 0); -#endif } static inline unsigned default_get_apic_id(unsigned long x) @@ -489,19 +474,10 @@ static inline int default_apic_id_registered(void) return physid_isset(read_apic_id(), phys_cpu_present_map); } -static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) -{ - return cpuid_apic >> index_msb; -} - -extern int default_apicid_to_node(int logical_apicid); - -#endif - static inline unsigned int default_cpu_mask_to_apicid(const struct cpumask *cpumask) { - return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; + return cpumask_bits(cpumask)[0]; } static inline unsigned int @@ -515,6 +491,15 @@ default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, return (unsigned int)(mask1 & mask2 & mask3); } +static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) +{ + return cpuid_apic >> index_msb; +} + +extern int default_apicid_to_node(int logical_apicid); + +#endif + static inline unsigned long default_check_apicid_used(physid_mask_t bitmap, int apicid) { return physid_isset(apicid, bitmap); diff --git a/trunk/arch/x86/include/asm/apicdef.h b/trunk/arch/x86/include/asm/apicdef.h index bc9514fb3b13..63134e31e8b9 100644 --- a/trunk/arch/x86/include/asm/apicdef.h +++ b/trunk/arch/x86/include/asm/apicdef.h @@ -53,7 +53,6 @@ #define APIC_ESR_SENDILL 0x00020 #define APIC_ESR_RECVILL 0x00040 #define APIC_ESR_ILLREGA 0x00080 -#define APIC_LVTCMCI 0x2f0 #define APIC_ICR 0x300 #define APIC_DEST_SELF 0x40000 #define APIC_DEST_ALLINC 0x80000 diff --git a/trunk/arch/x86/include/asm/boot.h b/trunk/arch/x86/include/asm/boot.h index 6ba23dd9fc92..6526cf08b0e4 100644 --- a/trunk/arch/x86/include/asm/boot.h +++ b/trunk/arch/x86/include/asm/boot.h @@ -1,6 +1,10 @@ #ifndef _ASM_X86_BOOT_H #define _ASM_X86_BOOT_H +/* Don't touch these, unless you really know what you're doing. */ +#define DEF_SYSSEG 0x1000 +#define DEF_SYSSIZE 0x7F00 + /* Internal svga startup constants */ #define NORMAL_VGA 0xffff /* 80x25 mode */ #define EXTENDED_VGA 0xfffe /* 80x50 mode */ diff --git a/trunk/arch/x86/include/asm/cacheflush.h b/trunk/arch/x86/include/asm/cacheflush.h index b3894bf52fcd..5b301b7ff5f4 100644 --- a/trunk/arch/x86/include/asm/cacheflush.h +++ b/trunk/arch/x86/include/asm/cacheflush.h @@ -90,9 +90,6 @@ int set_memory_4k(unsigned long addr, int numpages); int set_memory_array_uc(unsigned long *addr, int addrinarray); int set_memory_array_wb(unsigned long *addr, int addrinarray); -int set_pages_array_uc(struct page **pages, int addrinarray); -int set_pages_array_wb(struct page **pages, int addrinarray); - /* * For legacy compatibility with the old APIs, a few functions * are provided that work on a "struct page". diff --git a/trunk/arch/x86/include/asm/cpu_debug.h b/trunk/arch/x86/include/asm/cpu_debug.h deleted file mode 100755 index 222802029fa6..000000000000 --- a/trunk/arch/x86/include/asm/cpu_debug.h +++ /dev/null @@ -1,226 +0,0 @@ -#ifndef _ASM_X86_CPU_DEBUG_H -#define _ASM_X86_CPU_DEBUG_H - -/* - * CPU x86 architecture debug - * - * Copyright(C) 2009 Jaswinder Singh Rajput - */ - -/* Register flags */ -enum cpu_debug_bit { -/* Model Specific Registers (MSRs) */ - CPU_MC_BIT, /* Machine Check */ - CPU_MONITOR_BIT, /* Monitor */ - CPU_TIME_BIT, /* Time */ - CPU_PMC_BIT, /* Performance Monitor */ - CPU_PLATFORM_BIT, /* Platform */ - CPU_APIC_BIT, /* APIC */ - CPU_POWERON_BIT, /* Power-on */ - CPU_CONTROL_BIT, /* Control */ - CPU_FEATURES_BIT, /* Features control */ - CPU_LBRANCH_BIT, /* Last Branch */ - CPU_BIOS_BIT, /* BIOS */ - CPU_FREQ_BIT, /* Frequency */ - CPU_MTTR_BIT, /* MTRR */ - CPU_PERF_BIT, /* Performance */ - CPU_CACHE_BIT, /* Cache */ - CPU_SYSENTER_BIT, /* Sysenter */ - CPU_THERM_BIT, /* Thermal */ - CPU_MISC_BIT, /* Miscellaneous */ - CPU_DEBUG_BIT, /* Debug */ - CPU_PAT_BIT, /* PAT */ - CPU_VMX_BIT, /* VMX */ - CPU_CALL_BIT, /* System Call */ - CPU_BASE_BIT, /* BASE Address */ - CPU_VER_BIT, /* Version ID */ - CPU_CONF_BIT, /* Configuration */ - CPU_SMM_BIT, /* System mgmt mode */ - CPU_SVM_BIT, /*Secure Virtual Machine*/ - CPU_OSVM_BIT, /* OS-Visible Workaround*/ -/* Standard Registers */ - CPU_TSS_BIT, /* Task Stack Segment */ - CPU_CR_BIT, /* Control Registers */ - CPU_DT_BIT, /* Descriptor Table */ -/* End of Registers flags */ - CPU_REG_ALL_BIT, /* Select all Registers */ -}; - -#define CPU_REG_ALL (~0) /* Select all Registers */ - -#define CPU_MC (1 << CPU_MC_BIT) -#define CPU_MONITOR (1 << CPU_MONITOR_BIT) -#define CPU_TIME (1 << CPU_TIME_BIT) -#define CPU_PMC (1 << CPU_PMC_BIT) -#define CPU_PLATFORM (1 << CPU_PLATFORM_BIT) -#define CPU_APIC (1 << CPU_APIC_BIT) -#define CPU_POWERON (1 << CPU_POWERON_BIT) -#define CPU_CONTROL (1 << CPU_CONTROL_BIT) -#define CPU_FEATURES (1 << CPU_FEATURES_BIT) -#define CPU_LBRANCH (1 << CPU_LBRANCH_BIT) -#define CPU_BIOS (1 << CPU_BIOS_BIT) -#define CPU_FREQ (1 << CPU_FREQ_BIT) -#define CPU_MTRR (1 << CPU_MTTR_BIT) -#define CPU_PERF (1 << CPU_PERF_BIT) -#define CPU_CACHE (1 << CPU_CACHE_BIT) -#define CPU_SYSENTER (1 << CPU_SYSENTER_BIT) -#define CPU_THERM (1 << CPU_THERM_BIT) -#define CPU_MISC (1 << CPU_MISC_BIT) -#define CPU_DEBUG (1 << CPU_DEBUG_BIT) -#define CPU_PAT (1 << CPU_PAT_BIT) -#define CPU_VMX (1 << CPU_VMX_BIT) -#define CPU_CALL (1 << CPU_CALL_BIT) -#define CPU_BASE (1 << CPU_BASE_BIT) -#define CPU_VER (1 << CPU_VER_BIT) -#define CPU_CONF (1 << CPU_CONF_BIT) -#define CPU_SMM (1 << CPU_SMM_BIT) -#define CPU_SVM (1 << CPU_SVM_BIT) -#define CPU_OSVM (1 << CPU_OSVM_BIT) -#define CPU_TSS (1 << CPU_TSS_BIT) -#define CPU_CR (1 << CPU_CR_BIT) -#define CPU_DT (1 << CPU_DT_BIT) - -/* Register file flags */ -enum cpu_file_bit { - CPU_INDEX_BIT, /* index */ - CPU_VALUE_BIT, /* value */ -}; - -#define CPU_FILE_VALUE (1 << CPU_VALUE_BIT) - -/* - * DisplayFamily_DisplayModel Processor Families/Processor Number Series - * -------------------------- ------------------------------------------ - * 05_01, 05_02, 05_04 Pentium, Pentium with MMX - * - * 06_01 Pentium Pro - * 06_03, 06_05 Pentium II Xeon, Pentium II - * 06_07, 06_08, 06_0A, 06_0B Pentium III Xeon, Pentum III - * - * 06_09, 060D Pentium M - * - * 06_0E Core Duo, Core Solo - * - * 06_0F Xeon 3000, 3200, 5100, 5300, 7300 series, - * Core 2 Quad, Core 2 Extreme, Core 2 Duo, - * Pentium dual-core - * 06_17 Xeon 5200, 5400 series, Core 2 Quad Q9650 - * - * 06_1C Atom - * - * 0F_00, 0F_01, 0F_02 Xeon, Xeon MP, Pentium 4 - * 0F_03, 0F_04 Xeon, Xeon MP, Pentium 4, Pentium D - * - * 0F_06 Xeon 7100, 5000 Series, Xeon MP, - * Pentium 4, Pentium D - */ - -/* Register processors bits */ -enum cpu_processor_bit { - CPU_NONE, -/* Intel */ - CPU_INTEL_PENTIUM_BIT, - CPU_INTEL_P6_BIT, - CPU_INTEL_PENTIUM_M_BIT, - CPU_INTEL_CORE_BIT, - CPU_INTEL_CORE2_BIT, - CPU_INTEL_ATOM_BIT, - CPU_INTEL_XEON_P4_BIT, - CPU_INTEL_XEON_MP_BIT, -/* AMD */ - CPU_AMD_K6_BIT, - CPU_AMD_K7_BIT, - CPU_AMD_K8_BIT, - CPU_AMD_0F_BIT, - CPU_AMD_10_BIT, - CPU_AMD_11_BIT, -}; - -#define CPU_INTEL_PENTIUM (1 << CPU_INTEL_PENTIUM_BIT) -#define CPU_INTEL_P6 (1 << CPU_INTEL_P6_BIT) -#define CPU_INTEL_PENTIUM_M (1 << CPU_INTEL_PENTIUM_M_BIT) -#define CPU_INTEL_CORE (1 << CPU_INTEL_CORE_BIT) -#define CPU_INTEL_CORE2 (1 << CPU_INTEL_CORE2_BIT) -#define CPU_INTEL_ATOM (1 << CPU_INTEL_ATOM_BIT) -#define CPU_INTEL_XEON_P4 (1 << CPU_INTEL_XEON_P4_BIT) -#define CPU_INTEL_XEON_MP (1 << CPU_INTEL_XEON_MP_BIT) - -#define CPU_INTEL_PX (CPU_INTEL_P6 | CPU_INTEL_PENTIUM_M) -#define CPU_INTEL_COREX (CPU_INTEL_CORE | CPU_INTEL_CORE2) -#define CPU_INTEL_XEON (CPU_INTEL_XEON_P4 | CPU_INTEL_XEON_MP) -#define CPU_CO_AT (CPU_INTEL_CORE | CPU_INTEL_ATOM) -#define CPU_C2_AT (CPU_INTEL_CORE2 | CPU_INTEL_ATOM) -#define CPU_CX_AT (CPU_INTEL_COREX | CPU_INTEL_ATOM) -#define CPU_CX_XE (CPU_INTEL_COREX | CPU_INTEL_XEON) -#define CPU_P6_XE (CPU_INTEL_P6 | CPU_INTEL_XEON) -#define CPU_PM_CO_AT (CPU_INTEL_PENTIUM_M | CPU_CO_AT) -#define CPU_C2_AT_XE (CPU_C2_AT | CPU_INTEL_XEON) -#define CPU_CX_AT_XE (CPU_CX_AT | CPU_INTEL_XEON) -#define CPU_P6_CX_AT (CPU_INTEL_P6 | CPU_CX_AT) -#define CPU_P6_CX_XE (CPU_P6_XE | CPU_INTEL_COREX) -#define CPU_P6_CX_AT_XE (CPU_INTEL_P6 | CPU_CX_AT_XE) -#define CPU_PM_CX_AT_XE (CPU_INTEL_PENTIUM_M | CPU_CX_AT_XE) -#define CPU_PM_CX_AT (CPU_INTEL_PENTIUM_M | CPU_CX_AT) -#define CPU_PM_CX_XE (CPU_INTEL_PENTIUM_M | CPU_CX_XE) -#define CPU_PX_CX_AT (CPU_INTEL_PX | CPU_CX_AT) -#define CPU_PX_CX_AT_XE (CPU_INTEL_PX | CPU_CX_AT_XE) - -/* Select all supported Intel CPUs */ -#define CPU_INTEL_ALL (CPU_INTEL_PENTIUM | CPU_PX_CX_AT_XE) - -#define CPU_AMD_K6 (1 << CPU_AMD_K6_BIT) -#define CPU_AMD_K7 (1 << CPU_AMD_K7_BIT) -#define CPU_AMD_K8 (1 << CPU_AMD_K8_BIT) -#define CPU_AMD_0F (1 << CPU_AMD_0F_BIT) -#define CPU_AMD_10 (1 << CPU_AMD_10_BIT) -#define CPU_AMD_11 (1 << CPU_AMD_11_BIT) - -#define CPU_K10_PLUS (CPU_AMD_10 | CPU_AMD_11) -#define CPU_K0F_PLUS (CPU_AMD_0F | CPU_K10_PLUS) -#define CPU_K8_PLUS (CPU_AMD_K8 | CPU_K0F_PLUS) -#define CPU_K7_PLUS (CPU_AMD_K7 | CPU_K8_PLUS) - -/* Select all supported AMD CPUs */ -#define CPU_AMD_ALL (CPU_AMD_K6 | CPU_K7_PLUS) - -/* Select all supported CPUs */ -#define CPU_ALL (CPU_INTEL_ALL | CPU_AMD_ALL) - -#define MAX_CPU_FILES 512 - -struct cpu_private { - unsigned cpu; - unsigned type; - unsigned reg; - unsigned file; -}; - -struct cpu_debug_base { - char *name; /* Register name */ - unsigned flag; /* Register flag */ - unsigned write; /* Register write flag */ -}; - -/* - * Currently it looks similar to cpu_debug_base but once we add more files - * cpu_file_base will go in different direction - */ -struct cpu_file_base { - char *name; /* Register file name */ - unsigned flag; /* Register file flag */ - unsigned write; /* Register write flag */ -}; - -struct cpu_cpuX_base { - struct dentry *dentry; /* Register dentry */ - int init; /* Register index file */ -}; - -struct cpu_debug_range { - unsigned min; /* Register range min */ - unsigned max; /* Register range max */ - unsigned flag; /* Supported flags */ - unsigned model; /* Supported models */ -}; - -#endif /* _ASM_X86_CPU_DEBUG_H */ diff --git a/trunk/arch/x86/include/asm/desc.h b/trunk/arch/x86/include/asm/desc.h index 5623c50d67b2..dc27705f5443 100644 --- a/trunk/arch/x86/include/asm/desc.h +++ b/trunk/arch/x86/include/asm/desc.h @@ -91,6 +91,7 @@ static inline int desc_empty(const void *ptr) #define store_gdt(dtr) native_store_gdt(dtr) #define store_idt(dtr) native_store_idt(dtr) #define store_tr(tr) (tr = native_store_tr()) +#define store_ldt(ldt) asm("sldt %0":"=m" (ldt)) #define load_TLS(t, cpu) native_load_tls(t, cpu) #define set_ldt native_set_ldt @@ -111,8 +112,6 @@ static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries) } #endif /* CONFIG_PARAVIRT */ -#define store_ldt(ldt) asm("sldt %0" : "=m"(ldt)) - static inline void native_write_idt_entry(gate_desc *idt, int entry, const gate_desc *gate) { diff --git a/trunk/arch/x86/include/asm/device.h b/trunk/arch/x86/include/asm/device.h index 4994a20acbcb..3c034f48fdb0 100644 --- a/trunk/arch/x86/include/asm/device.h +++ b/trunk/arch/x86/include/asm/device.h @@ -6,7 +6,7 @@ struct dev_archdata { void *acpi_handle; #endif #ifdef CONFIG_X86_64 -struct dma_map_ops *dma_ops; +struct dma_mapping_ops *dma_ops; #endif #ifdef CONFIG_DMAR void *iommu; /* hook for IOMMU specific extension */ diff --git a/trunk/arch/x86/include/asm/dma-mapping.h b/trunk/arch/x86/include/asm/dma-mapping.h index cea7b74963e9..132a134d12f2 100644 --- a/trunk/arch/x86/include/asm/dma-mapping.h +++ b/trunk/arch/x86/include/asm/dma-mapping.h @@ -7,8 +7,6 @@ */ #include -#include -#include #include #include #include @@ -18,9 +16,47 @@ extern int iommu_merge; extern struct device x86_dma_fallback_dev; extern int panic_on_overflow; -extern struct dma_map_ops *dma_ops; - -static inline struct dma_map_ops *get_dma_ops(struct device *dev) +struct dma_mapping_ops { + int (*mapping_error)(struct device *dev, + dma_addr_t dma_addr); + void* (*alloc_coherent)(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp); + void (*free_coherent)(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle); + dma_addr_t (*map_single)(struct device *hwdev, phys_addr_t ptr, + size_t size, int direction); + void (*unmap_single)(struct device *dev, dma_addr_t addr, + size_t size, int direction); + void (*sync_single_for_cpu)(struct device *hwdev, + dma_addr_t dma_handle, size_t size, + int direction); + void (*sync_single_for_device)(struct device *hwdev, + dma_addr_t dma_handle, size_t size, + int direction); + void (*sync_single_range_for_cpu)(struct device *hwdev, + dma_addr_t dma_handle, unsigned long offset, + size_t size, int direction); + void (*sync_single_range_for_device)(struct device *hwdev, + dma_addr_t dma_handle, unsigned long offset, + size_t size, int direction); + void (*sync_sg_for_cpu)(struct device *hwdev, + struct scatterlist *sg, int nelems, + int direction); + void (*sync_sg_for_device)(struct device *hwdev, + struct scatterlist *sg, int nelems, + int direction); + int (*map_sg)(struct device *hwdev, struct scatterlist *sg, + int nents, int direction); + void (*unmap_sg)(struct device *hwdev, + struct scatterlist *sg, int nents, + int direction); + int (*dma_supported)(struct device *hwdev, u64 mask); + int is_phys; +}; + +extern struct dma_mapping_ops *dma_ops; + +static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) { #ifdef CONFIG_X86_32 return dma_ops; @@ -35,7 +71,7 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev) /* Make sure we keep the same behaviour */ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { - struct dma_map_ops *ops = get_dma_ops(dev); + struct dma_mapping_ops *ops = get_dma_ops(dev); if (ops->mapping_error) return ops->mapping_error(dev, dma_addr); @@ -54,167 +90,137 @@ extern void *dma_generic_alloc_coherent(struct device *dev, size_t size, static inline dma_addr_t dma_map_single(struct device *hwdev, void *ptr, size_t size, - enum dma_data_direction dir) + int direction) { - struct dma_map_ops *ops = get_dma_ops(hwdev); - dma_addr_t addr; - - BUG_ON(!valid_dma_direction(dir)); - addr = ops->map_page(hwdev, virt_to_page(ptr), - (unsigned long)ptr & ~PAGE_MASK, size, - dir, NULL); - debug_dma_map_page(hwdev, virt_to_page(ptr), - (unsigned long)ptr & ~PAGE_MASK, size, - dir, addr, true); - return addr; + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + + BUG_ON(!valid_dma_direction(direction)); + return ops->map_single(hwdev, virt_to_phys(ptr), size, direction); } static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size, - enum dma_data_direction dir) + int direction) { - struct dma_map_ops *ops = get_dma_ops(dev); + struct dma_mapping_ops *ops = get_dma_ops(dev); - BUG_ON(!valid_dma_direction(dir)); - if (ops->unmap_page) - ops->unmap_page(dev, addr, size, dir, NULL); - debug_dma_unmap_page(dev, addr, size, dir, true); + BUG_ON(!valid_dma_direction(direction)); + if (ops->unmap_single) + ops->unmap_single(dev, addr, size, direction); } static inline int dma_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, enum dma_data_direction dir) + int nents, int direction) { - struct dma_map_ops *ops = get_dma_ops(hwdev); - int ents; - - BUG_ON(!valid_dma_direction(dir)); - ents = ops->map_sg(hwdev, sg, nents, dir, NULL); - debug_dma_map_sg(hwdev, sg, nents, ents, dir); + struct dma_mapping_ops *ops = get_dma_ops(hwdev); - return ents; + BUG_ON(!valid_dma_direction(direction)); + return ops->map_sg(hwdev, sg, nents, direction); } static inline void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, - enum dma_data_direction dir) + int direction) { - struct dma_map_ops *ops = get_dma_ops(hwdev); + struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(dir)); - debug_dma_unmap_sg(hwdev, sg, nents, dir); + BUG_ON(!valid_dma_direction(direction)); if (ops->unmap_sg) - ops->unmap_sg(hwdev, sg, nents, dir, NULL); + ops->unmap_sg(hwdev, sg, nents, direction); } static inline void dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle, - size_t size, enum dma_data_direction dir) + size_t size, int direction) { - struct dma_map_ops *ops = get_dma_ops(hwdev); + struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(dir)); + BUG_ON(!valid_dma_direction(direction)); if (ops->sync_single_for_cpu) - ops->sync_single_for_cpu(hwdev, dma_handle, size, dir); - debug_dma_sync_single_for_cpu(hwdev, dma_handle, size, dir); + ops->sync_single_for_cpu(hwdev, dma_handle, size, direction); flush_write_buffers(); } static inline void dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle, - size_t size, enum dma_data_direction dir) + size_t size, int direction) { - struct dma_map_ops *ops = get_dma_ops(hwdev); + struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(dir)); + BUG_ON(!valid_dma_direction(direction)); if (ops->sync_single_for_device) - ops->sync_single_for_device(hwdev, dma_handle, size, dir); - debug_dma_sync_single_for_device(hwdev, dma_handle, size, dir); + ops->sync_single_for_device(hwdev, dma_handle, size, direction); flush_write_buffers(); } static inline void dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle, - unsigned long offset, size_t size, - enum dma_data_direction dir) + unsigned long offset, size_t size, int direction) { - struct dma_map_ops *ops = get_dma_ops(hwdev); + struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(dir)); + BUG_ON(!valid_dma_direction(direction)); if (ops->sync_single_range_for_cpu) ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, - size, dir); - debug_dma_sync_single_range_for_cpu(hwdev, dma_handle, - offset, size, dir); + size, direction); flush_write_buffers(); } static inline void dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, size_t size, - enum dma_data_direction dir) + int direction) { - struct dma_map_ops *ops = get_dma_ops(hwdev); + struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(dir)); + BUG_ON(!valid_dma_direction(direction)); if (ops->sync_single_range_for_device) ops->sync_single_range_for_device(hwdev, dma_handle, - offset, size, dir); - debug_dma_sync_single_range_for_device(hwdev, dma_handle, - offset, size, dir); + offset, size, direction); flush_write_buffers(); } static inline void dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, - int nelems, enum dma_data_direction dir) + int nelems, int direction) { - struct dma_map_ops *ops = get_dma_ops(hwdev); + struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(dir)); + BUG_ON(!valid_dma_direction(direction)); if (ops->sync_sg_for_cpu) - ops->sync_sg_for_cpu(hwdev, sg, nelems, dir); - debug_dma_sync_sg_for_cpu(hwdev, sg, nelems, dir); + ops->sync_sg_for_cpu(hwdev, sg, nelems, direction); flush_write_buffers(); } static inline void dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, - int nelems, enum dma_data_direction dir) + int nelems, int direction) { - struct dma_map_ops *ops = get_dma_ops(hwdev); + struct dma_mapping_ops *ops = get_dma_ops(hwdev); - BUG_ON(!valid_dma_direction(dir)); + BUG_ON(!valid_dma_direction(direction)); if (ops->sync_sg_for_device) - ops->sync_sg_for_device(hwdev, sg, nelems, dir); - debug_dma_sync_sg_for_device(hwdev, sg, nelems, dir); + ops->sync_sg_for_device(hwdev, sg, nelems, direction); flush_write_buffers(); } static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, size_t offset, size_t size, - enum dma_data_direction dir) + int direction) { - struct dma_map_ops *ops = get_dma_ops(dev); - dma_addr_t addr; + struct dma_mapping_ops *ops = get_dma_ops(dev); - BUG_ON(!valid_dma_direction(dir)); - addr = ops->map_page(dev, page, offset, size, dir, NULL); - debug_dma_map_page(dev, page, offset, size, dir, addr, false); - - return addr; + BUG_ON(!valid_dma_direction(direction)); + return ops->map_single(dev, page_to_phys(page) + offset, + size, direction); } static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, - size_t size, enum dma_data_direction dir) + size_t size, int direction) { - struct dma_map_ops *ops = get_dma_ops(dev); - - BUG_ON(!valid_dma_direction(dir)); - if (ops->unmap_page) - ops->unmap_page(dev, addr, size, dir, NULL); - debug_dma_unmap_page(dev, addr, size, dir, false); + dma_unmap_single(dev, addr, size, direction); } static inline void @@ -260,7 +266,7 @@ static inline void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp) { - struct dma_map_ops *ops = get_dma_ops(dev); + struct dma_mapping_ops *ops = get_dma_ops(dev); void *memory; gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); @@ -279,24 +285,20 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, if (!ops->alloc_coherent) return NULL; - memory = ops->alloc_coherent(dev, size, dma_handle, - dma_alloc_coherent_gfp_flags(dev, gfp)); - debug_dma_alloc_coherent(dev, size, *dma_handle, memory); - - return memory; + return ops->alloc_coherent(dev, size, dma_handle, + dma_alloc_coherent_gfp_flags(dev, gfp)); } static inline void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t bus) { - struct dma_map_ops *ops = get_dma_ops(dev); + struct dma_mapping_ops *ops = get_dma_ops(dev); WARN_ON(irqs_disabled()); /* for portability */ if (dma_release_from_coherent(dev, get_order(size), vaddr)) return; - debug_dma_free_coherent(dev, size, vaddr, bus); if (ops->free_coherent) ops->free_coherent(dev, size, vaddr, bus); } diff --git a/trunk/arch/x86/include/asm/dmi.h b/trunk/arch/x86/include/asm/dmi.h index fd8f9e2ca35f..bc68212c6bc0 100644 --- a/trunk/arch/x86/include/asm/dmi.h +++ b/trunk/arch/x86/include/asm/dmi.h @@ -1,15 +1,22 @@ #ifndef _ASM_X86_DMI_H #define _ASM_X86_DMI_H -#include -#include - #include -#include -static __always_inline __init void *dmi_alloc(unsigned len) +#define DMI_MAX_DATA 2048 + +extern int dmi_alloc_index; +extern char dmi_alloc_data[DMI_MAX_DATA]; + +/* This is so early that there is no good way to allocate dynamic memory. + Allocate data in an BSS array. */ +static inline void *dmi_alloc(unsigned len) { - return extend_brk(len, sizeof(int)); + int idx = dmi_alloc_index; + if ((dmi_alloc_index + len) > DMI_MAX_DATA) + return NULL; + dmi_alloc_index += len; + return dmi_alloc_data + idx; } /* Use early IO mappings for DMI because it's initialized early */ diff --git a/trunk/arch/x86/include/asm/e820.h b/trunk/arch/x86/include/asm/e820.h index 7ecba4d85089..00d41ce4c844 100644 --- a/trunk/arch/x86/include/asm/e820.h +++ b/trunk/arch/x86/include/asm/e820.h @@ -72,7 +72,7 @@ extern int e820_all_mapped(u64 start, u64 end, unsigned type); extern void e820_add_region(u64 start, u64 size, int type); extern void e820_print_map(char *who); extern int -sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, u32 *pnr_map); +sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, int *pnr_map); extern u64 e820_update_range(u64 start, u64 size, unsigned old_type, unsigned new_type); extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type, diff --git a/trunk/arch/x86/include/asm/entry_arch.h b/trunk/arch/x86/include/asm/entry_arch.h index c2e6bedaf258..854d538ae857 100644 --- a/trunk/arch/x86/include/asm/entry_arch.h +++ b/trunk/arch/x86/include/asm/entry_arch.h @@ -33,8 +33,6 @@ BUILD_INTERRUPT3(invalidate_interrupt7,INVALIDATE_TLB_VECTOR_START+7, smp_invalidate_interrupt) #endif -BUILD_INTERRUPT(generic_interrupt, GENERIC_INTERRUPT_VECTOR) - /* * every pentium local APIC has two 'local interrupts', with a * soft-definable vector attached to both interrupts, one of diff --git a/trunk/arch/x86/include/asm/ftrace.h b/trunk/arch/x86/include/asm/ftrace.h index db24c2278be0..b55b4a7fbefd 100644 --- a/trunk/arch/x86/include/asm/ftrace.h +++ b/trunk/arch/x86/include/asm/ftrace.h @@ -55,4 +55,29 @@ struct dyn_arch_ftrace { #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_TRACER */ +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + +#ifndef __ASSEMBLY__ + +/* + * Stack of return addresses for functions + * of a thread. + * Used in struct thread_info + */ +struct ftrace_ret_stack { + unsigned long ret; + unsigned long func; + unsigned long long calltime; +}; + +/* + * Primary handler of a function return. + * It relays on ftrace_return_to_handler. + * Defined in entry_32/64.S + */ +extern void return_to_handler(void); + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ + #endif /* _ASM_X86_FTRACE_H */ diff --git a/trunk/arch/x86/include/asm/hardirq.h b/trunk/arch/x86/include/asm/hardirq.h index 039db6aa8e02..176f058e7159 100644 --- a/trunk/arch/x86/include/asm/hardirq.h +++ b/trunk/arch/x86/include/asm/hardirq.h @@ -12,7 +12,6 @@ typedef struct { unsigned int apic_timer_irqs; /* arch dependent */ unsigned int irq_spurious_count; #endif - unsigned int generic_irqs; /* arch dependent */ #ifdef CONFIG_SMP unsigned int irq_resched_count; unsigned int irq_call_count; diff --git a/trunk/arch/x86/include/asm/highmem.h b/trunk/arch/x86/include/asm/highmem.h index 014c2b85ae45..bf9276bea660 100644 --- a/trunk/arch/x86/include/asm/highmem.h +++ b/trunk/arch/x86/include/asm/highmem.h @@ -63,7 +63,6 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot); void *kmap_atomic(struct page *page, enum km_type type); void kunmap_atomic(void *kvaddr, enum km_type type); void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); -void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); struct page *kmap_atomic_to_page(void *ptr); #ifndef CONFIG_PARAVIRT diff --git a/trunk/arch/x86/include/asm/hw_irq.h b/trunk/arch/x86/include/asm/hw_irq.h index b762ea49bd70..370e1c83bb49 100644 --- a/trunk/arch/x86/include/asm/hw_irq.h +++ b/trunk/arch/x86/include/asm/hw_irq.h @@ -27,7 +27,6 @@ /* Interrupt handlers registered during init_IRQ */ extern void apic_timer_interrupt(void); -extern void generic_interrupt(void); extern void error_interrupt(void); extern void spurious_interrupt(void); extern void thermal_interrupt(void); diff --git a/trunk/arch/x86/include/asm/init.h b/trunk/arch/x86/include/asm/init.h deleted file mode 100644 index 36fb1a6a5109..000000000000 --- a/trunk/arch/x86/include/asm/init.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _ASM_X86_INIT_32_H -#define _ASM_X86_INIT_32_H - -#ifdef CONFIG_X86_32 -extern void __init early_ioremap_page_table_range_init(void); -#endif - -extern unsigned long __init -kernel_physical_mapping_init(unsigned long start, - unsigned long end, - unsigned long page_size_mask); - - -extern unsigned long __initdata e820_table_start; -extern unsigned long __meminitdata e820_table_end; -extern unsigned long __meminitdata e820_table_top; - -#endif /* _ASM_X86_INIT_32_H */ diff --git a/trunk/arch/x86/include/asm/io_apic.h b/trunk/arch/x86/include/asm/io_apic.h index 373cc2bbcad2..59cb4a1317b7 100644 --- a/trunk/arch/x86/include/asm/io_apic.h +++ b/trunk/arch/x86/include/asm/io_apic.h @@ -162,8 +162,7 @@ extern int (*ioapic_renumber_irq)(int ioapic, int irq); extern void ioapic_init_mappings(void); #ifdef CONFIG_X86_64 -extern int save_IO_APIC_setup(void); -extern void mask_IO_APIC_setup(void); +extern int save_mask_IO_APIC_setup(void); extern void restore_IO_APIC_setup(void); extern void reinit_intr_remapped_IO_APIC(int); #endif @@ -173,7 +172,7 @@ extern void probe_nr_irqs_gsi(void); extern int setup_ioapic_entry(int apic, int irq, struct IO_APIC_route_entry *entry, unsigned int destination, int trigger, - int polarity, int vector, int pin); + int polarity, int vector); extern void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e); #else /* !CONFIG_X86_IO_APIC */ diff --git a/trunk/arch/x86/include/asm/iommu.h b/trunk/arch/x86/include/asm/iommu.h index af326a2975b5..a6ee9e6f530f 100644 --- a/trunk/arch/x86/include/asm/iommu.h +++ b/trunk/arch/x86/include/asm/iommu.h @@ -3,7 +3,7 @@ extern void pci_iommu_shutdown(void); extern void no_iommu_init(void); -extern struct dma_map_ops nommu_dma_ops; +extern struct dma_mapping_ops nommu_dma_ops; extern int force_iommu, no_iommu; extern int iommu_detected; diff --git a/trunk/arch/x86/include/asm/irq.h b/trunk/arch/x86/include/asm/irq.h index f38481bcd455..107eb2196691 100644 --- a/trunk/arch/x86/include/asm/irq.h +++ b/trunk/arch/x86/include/asm/irq.h @@ -36,7 +36,6 @@ static inline int irq_canonicalize(int irq) extern void fixup_irqs(void); #endif -extern void (*generic_interrupt_extension)(void); extern void init_IRQ(void); extern void native_init_IRQ(void); extern bool handle_irq(unsigned irq, struct pt_regs *regs); diff --git a/trunk/arch/x86/include/asm/irq_remapping.h b/trunk/arch/x86/include/asm/irq_remapping.h index 0396760fccb8..20e1fd588dbf 100644 --- a/trunk/arch/x86/include/asm/irq_remapping.h +++ b/trunk/arch/x86/include/asm/irq_remapping.h @@ -1,6 +1,8 @@ #ifndef _ASM_X86_IRQ_REMAPPING_H #define _ASM_X86_IRQ_REMAPPING_H +extern int x2apic; + #define IRTE_DEST(dest) ((x2apic) ? dest : dest << 8) #endif /* _ASM_X86_IRQ_REMAPPING_H */ diff --git a/trunk/arch/x86/include/asm/irq_vectors.h b/trunk/arch/x86/include/asm/irq_vectors.h index 3cbd79bbb47c..8a285f356f8a 100644 --- a/trunk/arch/x86/include/asm/irq_vectors.h +++ b/trunk/arch/x86/include/asm/irq_vectors.h @@ -111,11 +111,6 @@ */ #define LOCAL_PERF_VECTOR 0xee -/* - * Generic system vector for platform specific use - */ -#define GENERIC_INTERRUPT_VECTOR 0xed - /* * First APIC vector available to drivers: (vectors 0x30-0xee) we * start at 0x31(0x41) to spread out vectors evenly between priority diff --git a/trunk/arch/x86/include/asm/kexec.h b/trunk/arch/x86/include/asm/kexec.h index 317ff1703d0b..0ceb6d19ed30 100644 --- a/trunk/arch/x86/include/asm/kexec.h +++ b/trunk/arch/x86/include/asm/kexec.h @@ -9,13 +9,13 @@ # define PAGES_NR 4 #else # define PA_CONTROL_PAGE 0 -# define VA_CONTROL_PAGE 1 -# define PA_TABLE_PAGE 2 -# define PA_SWAP_PAGE 3 -# define PAGES_NR 4 +# define PA_TABLE_PAGE 1 +# define PAGES_NR 2 #endif +#ifdef CONFIG_X86_32 # define KEXEC_CONTROL_CODE_MAX_SIZE 2048 +#endif #ifndef __ASSEMBLY__ @@ -136,11 +136,10 @@ relocate_kernel(unsigned long indirection_page, unsigned int has_pae, unsigned int preserve_context); #else -unsigned long +NORET_TYPE void relocate_kernel(unsigned long indirection_page, unsigned long page_list, - unsigned long start_address, - unsigned int preserve_context); + unsigned long start_address) ATTRIB_NORET; #endif #define ARCH_HAS_KIMAGE_ARCH diff --git a/trunk/arch/x86/include/asm/lguest_hcall.h b/trunk/arch/x86/include/asm/lguest_hcall.h index 0f4ee7148afe..43894428c3c2 100644 --- a/trunk/arch/x86/include/asm/lguest_hcall.h +++ b/trunk/arch/x86/include/asm/lguest_hcall.h @@ -26,20 +26,36 @@ #ifndef __ASSEMBLY__ #include -#include /*G:031 But first, how does our Guest contact the Host to ask for privileged * operations? There are two ways: the direct way is to make a "hypercall", * to make requests of the Host Itself. * - * We use the KVM hypercall mechanism. Eighteen hypercalls are + * Our hypercall mechanism uses the highest unused trap code (traps 32 and + * above are used by real hardware interrupts). Fifteen hypercalls are * available: the hypercall number is put in the %eax register, and the - * arguments (when required) are placed in %ebx, %ecx and %edx. If a return + * arguments (when required) are placed in %edx, %ebx and %ecx. If a return * value makes sense, it's returned in %eax. * * Grossly invalid calls result in Sudden Death at the hands of the vengeful * Host, rather than returning failure. This reflects Winston Churchill's * definition of a gentleman: "someone who is only rude intentionally". */ +static inline unsigned long +hcall(unsigned long call, + unsigned long arg1, unsigned long arg2, unsigned long arg3) +{ + /* "int" is the Intel instruction to trigger a trap. */ + asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY) + /* The call in %eax (aka "a") might be overwritten */ + : "=a"(call) + /* The arguments are in %eax, %edx, %ebx & %ecx */ + : "a"(call), "d"(arg1), "b"(arg2), "c"(arg3) + /* "memory" means this might write somewhere in memory. + * This isn't true for all calls, but it's safe to tell + * gcc that it might happen so it doesn't get clever. */ + : "memory"); + return call; +} /*:*/ /* Can't use our min() macro here: needs to be a constant */ @@ -48,7 +64,7 @@ #define LHCALL_RING_SIZE 64 struct hcall_args { /* These map directly onto eax, ebx, ecx, edx in struct lguest_regs */ - unsigned long arg0, arg1, arg2, arg3; + unsigned long arg0, arg2, arg3, arg1; }; #endif /* !__ASSEMBLY__ */ diff --git a/trunk/arch/x86/include/asm/linkage.h b/trunk/arch/x86/include/asm/linkage.h index 12d55e773eb6..9320e2a8a26a 100644 --- a/trunk/arch/x86/include/asm/linkage.h +++ b/trunk/arch/x86/include/asm/linkage.h @@ -1,11 +1,14 @@ #ifndef _ASM_X86_LINKAGE_H #define _ASM_X86_LINKAGE_H -#include - #undef notrace #define notrace __attribute__((no_instrument_function)) +#ifdef CONFIG_X86_64 +#define __ALIGN .p2align 4,,15 +#define __ALIGN_STR ".p2align 4,,15" +#endif + #ifdef CONFIG_X86_32 #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) /* @@ -47,20 +50,16 @@ __asmlinkage_protect_n(ret, "g" (arg1), "g" (arg2), "g" (arg3), \ "g" (arg4), "g" (arg5), "g" (arg6)) -#endif /* CONFIG_X86_32 */ - -#ifdef __ASSEMBLY__ +#endif #define GLOBAL(name) \ .globl name; \ name: -#if defined(CONFIG_X86_64) || defined(CONFIG_X86_ALIGNMENT_16) -#define __ALIGN .p2align 4, 0x90 -#define __ALIGN_STR __stringify(__ALIGN) +#ifdef CONFIG_X86_ALIGNMENT_16 +#define __ALIGN .align 16,0x90 +#define __ALIGN_STR ".align 16,0x90" #endif -#endif /* __ASSEMBLY__ */ - #endif /* _ASM_X86_LINKAGE_H */ diff --git a/trunk/arch/x86/include/asm/mce.h b/trunk/arch/x86/include/asm/mce.h index 563933e06a35..32c6e17b960b 100644 --- a/trunk/arch/x86/include/asm/mce.h +++ b/trunk/arch/x86/include/asm/mce.h @@ -11,8 +11,6 @@ */ #define MCG_CTL_P (1UL<<8) /* MCG_CAP register available */ -#define MCG_EXT_P (1ULL<<9) /* Extended registers available */ -#define MCG_CMCI_P (1ULL<<10) /* CMCI supported */ #define MCG_STATUS_RIPV (1UL<<0) /* restart ip valid */ #define MCG_STATUS_EIPV (1UL<<1) /* ip points to correct instruction */ @@ -92,29 +90,14 @@ extern int mce_disabled; #include -void mce_setup(struct mce *m); void mce_log(struct mce *m); DECLARE_PER_CPU(struct sys_device, device_mce); extern void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu); -/* - * To support more than 128 would need to escape the predefined - * Linux defined extended banks first. - */ -#define MAX_NR_BANKS (MCE_EXTENDED_BANK - 1) - #ifdef CONFIG_X86_MCE_INTEL void mce_intel_feature_init(struct cpuinfo_x86 *c); -void cmci_clear(void); -void cmci_reenable(void); -void cmci_rediscover(int dying); -void cmci_recheck(void); #else static inline void mce_intel_feature_init(struct cpuinfo_x86 *c) { } -static inline void cmci_clear(void) {} -static inline void cmci_reenable(void) {} -static inline void cmci_rediscover(int dying) {} -static inline void cmci_recheck(void) {} #endif #ifdef CONFIG_X86_MCE_AMD @@ -123,23 +106,11 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c); static inline void mce_amd_feature_init(struct cpuinfo_x86 *c) { } #endif -extern int mce_available(struct cpuinfo_x86 *c); - -void mce_log_therm_throt_event(__u64 status); +void mce_log_therm_throt_event(unsigned int cpu, __u64 status); extern atomic_t mce_entry; extern void do_machine_check(struct pt_regs *, long); - -typedef DECLARE_BITMAP(mce_banks_t, MAX_NR_BANKS); -DECLARE_PER_CPU(mce_banks_t, mce_poll_banks); - -enum mcp_flags { - MCP_TIMESTAMP = (1 << 0), /* log time stamp */ - MCP_UC = (1 << 1), /* log uncorrected errors */ -}; -extern void machine_check_poll(enum mcp_flags flags, mce_banks_t *b); - extern int mce_notify_user(void); #endif /* !CONFIG_X86_32 */ @@ -149,8 +120,8 @@ extern void mcheck_init(struct cpuinfo_x86 *c); #else #define mcheck_init(c) do { } while (0) #endif - -extern void (*mce_threshold_vector)(void); +extern void stop_mce(void); +extern void restart_mce(void); #endif /* __KERNEL__ */ #endif /* _ASM_X86_MCE_H */ diff --git a/trunk/arch/x86/include/asm/msidef.h b/trunk/arch/x86/include/asm/msidef.h index 4cc48af23fef..6706b3006f13 100644 --- a/trunk/arch/x86/include/asm/msidef.h +++ b/trunk/arch/x86/include/asm/msidef.h @@ -47,7 +47,6 @@ #define MSI_ADDR_DEST_ID_MASK 0x00ffff0 #define MSI_ADDR_DEST_ID(dest) (((dest) << MSI_ADDR_DEST_ID_SHIFT) & \ MSI_ADDR_DEST_ID_MASK) -#define MSI_ADDR_EXT_DEST_ID(dest) ((dest) & 0xffffff00) #define MSI_ADDR_IR_EXT_INT (1 << 4) #define MSI_ADDR_IR_SHV (1 << 3) diff --git a/trunk/arch/x86/include/asm/msr-index.h b/trunk/arch/x86/include/asm/msr-index.h index ec41fc16c167..f4e505f286bc 100644 --- a/trunk/arch/x86/include/asm/msr-index.h +++ b/trunk/arch/x86/include/asm/msr-index.h @@ -81,11 +81,6 @@ #define MSR_IA32_MC0_ADDR 0x00000402 #define MSR_IA32_MC0_MISC 0x00000403 -/* These are consecutive and not in the normal 4er MCE bank block */ -#define MSR_IA32_MC0_CTL2 0x00000280 -#define CMCI_EN (1ULL << 30) -#define CMCI_THRESHOLD_MASK 0xffffULL - #define MSR_P6_PERFCTR0 0x000000c1 #define MSR_P6_PERFCTR1 0x000000c2 #define MSR_P6_EVNTSEL0 0x00000186 diff --git a/trunk/arch/x86/include/asm/page_32_types.h b/trunk/arch/x86/include/asm/page_32_types.h index 0f915ae649a7..f1e4a79a6e41 100644 --- a/trunk/arch/x86/include/asm/page_32_types.h +++ b/trunk/arch/x86/include/asm/page_32_types.h @@ -39,11 +39,6 @@ #define __VIRTUAL_MASK_SHIFT 32 #endif /* CONFIG_X86_PAE */ -/* - * Kernel image size is limited to 512 MB (see in arch/x86/kernel/head_32.S) - */ -#define KERNEL_IMAGE_SIZE (512 * 1024 * 1024) - #ifndef __ASSEMBLY__ /* diff --git a/trunk/arch/x86/include/asm/page_types.h b/trunk/arch/x86/include/asm/page_types.h index 826ad37006ab..2d625da6603c 100644 --- a/trunk/arch/x86/include/asm/page_types.h +++ b/trunk/arch/x86/include/asm/page_types.h @@ -40,8 +40,14 @@ #ifndef __ASSEMBLY__ +struct pgprot; + extern int page_is_ram(unsigned long pagenr); extern int devmem_is_allowed(unsigned long pagenr); +extern void map_devmem(unsigned long pfn, unsigned long size, + struct pgprot vma_prot); +extern void unmap_devmem(unsigned long pfn, unsigned long size, + struct pgprot vma_prot); extern unsigned long max_low_pfn_mapped; extern unsigned long max_pfn_mapped; diff --git a/trunk/arch/x86/include/asm/paravirt.h b/trunk/arch/x86/include/asm/paravirt.h index 7727aa8b7dda..0617d5cc9712 100644 --- a/trunk/arch/x86/include/asm/paravirt.h +++ b/trunk/arch/x86/include/asm/paravirt.h @@ -317,6 +317,8 @@ struct pv_mmu_ops { #if PAGETABLE_LEVELS >= 3 #ifdef CONFIG_X86_PAE void (*set_pte_atomic)(pte_t *ptep, pte_t pteval); + void (*set_pte_present)(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte); void (*pte_clear)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); void (*pmd_clear)(pmd_t *pmdp); @@ -387,7 +389,7 @@ extern struct pv_lock_ops pv_lock_ops; #define paravirt_type(op) \ [paravirt_typenum] "i" (PARAVIRT_PATCH(op)), \ - [paravirt_opptr] "i" (&(op)) + [paravirt_opptr] "m" (op) #define paravirt_clobber(clobber) \ [paravirt_clobber] "i" (clobber) @@ -441,7 +443,7 @@ int paravirt_disable_iospace(void); * offset into the paravirt_patch_template structure, and can therefore be * freely converted back into a structure offset. */ -#define PARAVIRT_CALL "call *%c[paravirt_opptr];" +#define PARAVIRT_CALL "call *%[paravirt_opptr];" /* * These macros are intended to wrap calls through one of the paravirt @@ -1363,6 +1365,13 @@ static inline void set_pte_atomic(pte_t *ptep, pte_t pte) pte.pte, pte.pte >> 32); } +static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ + /* 5 arg words */ + pv_mmu_ops.set_pte_present(mm, addr, ptep, pte); +} + static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { @@ -1379,6 +1388,12 @@ static inline void set_pte_atomic(pte_t *ptep, pte_t pte) set_pte(ptep, pte); } +static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ + set_pte(ptep, pte); +} + static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { diff --git a/trunk/arch/x86/include/asm/pat.h b/trunk/arch/x86/include/asm/pat.h index 2cd07b9422f4..b0e70056838e 100644 --- a/trunk/arch/x86/include/asm/pat.h +++ b/trunk/arch/x86/include/asm/pat.h @@ -2,7 +2,6 @@ #define _ASM_X86_PAT_H #include -#include #ifdef CONFIG_X86_PAT extern int pat_enabled; @@ -18,9 +17,5 @@ extern int free_memtype(u64 start, u64 end); extern int kernel_map_sync_memtype(u64 base, unsigned long size, unsigned long flag); -extern void map_devmem(unsigned long pfn, unsigned long size, - struct pgprot vma_prot); -extern void unmap_devmem(unsigned long pfn, unsigned long size, - struct pgprot vma_prot); #endif /* _ASM_X86_PAT_H */ diff --git a/trunk/arch/x86/include/asm/pci.h b/trunk/arch/x86/include/asm/pci.h index a0301bfeb954..a977de23cb4d 100644 --- a/trunk/arch/x86/include/asm/pci.h +++ b/trunk/arch/x86/include/asm/pci.h @@ -86,9 +86,6 @@ static inline void early_quirks(void) { } extern void pci_iommu_alloc(void); -/* MSI arch hook */ -#define arch_setup_msi_irqs arch_setup_msi_irqs - #endif /* __KERNEL__ */ #ifdef CONFIG_X86_32 diff --git a/trunk/arch/x86/include/asm/pgtable-2level.h b/trunk/arch/x86/include/asm/pgtable-2level.h index 2334982b339e..c1774ac9da7a 100644 --- a/trunk/arch/x86/include/asm/pgtable-2level.h +++ b/trunk/arch/x86/include/asm/pgtable-2level.h @@ -26,6 +26,13 @@ static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) native_set_pte(ptep, pte); } +static inline void native_set_pte_present(struct mm_struct *mm, + unsigned long addr, + pte_t *ptep, pte_t pte) +{ + native_set_pte(ptep, pte); +} + static inline void native_pmd_clear(pmd_t *pmdp) { native_set_pmd(pmdp, __pmd(0)); diff --git a/trunk/arch/x86/include/asm/pgtable-3level.h b/trunk/arch/x86/include/asm/pgtable-3level.h index 177b0165ea01..3f13cdf61156 100644 --- a/trunk/arch/x86/include/asm/pgtable-3level.h +++ b/trunk/arch/x86/include/asm/pgtable-3level.h @@ -31,6 +31,23 @@ static inline void native_set_pte(pte_t *ptep, pte_t pte) ptep->pte_low = pte.pte_low; } +/* + * Since this is only called on user PTEs, and the page fault handler + * must handle the already racy situation of simultaneous page faults, + * we are justified in merely clearing the PTE present bit, followed + * by a set. The ordering here is important. + */ +static inline void native_set_pte_present(struct mm_struct *mm, + unsigned long addr, + pte_t *ptep, pte_t pte) +{ + ptep->pte_low = 0; + smp_wmb(); + ptep->pte_high = pte.pte_high; + smp_wmb(); + ptep->pte_low = pte.pte_low; +} + static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) { set_64bit((unsigned long long *)(ptep), native_pte_val(pte)); diff --git a/trunk/arch/x86/include/asm/pgtable.h b/trunk/arch/x86/include/asm/pgtable.h index 29d96d168bc0..d0812e155f1d 100644 --- a/trunk/arch/x86/include/asm/pgtable.h +++ b/trunk/arch/x86/include/asm/pgtable.h @@ -31,6 +31,8 @@ extern struct list_head pgd_list; #define set_pte(ptep, pte) native_set_pte(ptep, pte) #define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) +#define set_pte_present(mm, addr, ptep, pte) \ + native_set_pte_present(mm, addr, ptep, pte) #define set_pte_atomic(ptep, pte) \ native_set_pte_atomic(ptep, pte) diff --git a/trunk/arch/x86/include/asm/pgtable_32.h b/trunk/arch/x86/include/asm/pgtable_32.h index 31bd120cf2a2..97612fc7632f 100644 --- a/trunk/arch/x86/include/asm/pgtable_32.h +++ b/trunk/arch/x86/include/asm/pgtable_32.h @@ -42,6 +42,9 @@ extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t); */ #undef TEST_ACCESS_OK +/* The boot page tables (all created as a single array) */ +extern unsigned long pg0[]; + #ifdef CONFIG_X86_PAE # include #else diff --git a/trunk/arch/x86/include/asm/pgtable_32_types.h b/trunk/arch/x86/include/asm/pgtable_32_types.h index 2733fad45f98..bd8df3b2fe04 100644 --- a/trunk/arch/x86/include/asm/pgtable_32_types.h +++ b/trunk/arch/x86/include/asm/pgtable_32_types.h @@ -25,11 +25,6 @@ * area for the same reason. ;) */ #define VMALLOC_OFFSET (8 * 1024 * 1024) - -#ifndef __ASSEMBLER__ -extern bool __vmalloc_start_set; /* set once high_memory is set */ -#endif - #define VMALLOC_START ((unsigned long)high_memory + VMALLOC_OFFSET) #ifdef CONFIG_X86_PAE #define LAST_PKMAP 512 diff --git a/trunk/arch/x86/include/asm/pgtable_types.h b/trunk/arch/x86/include/asm/pgtable_types.h index b8238dc8786d..4d258ad76a0f 100644 --- a/trunk/arch/x86/include/asm/pgtable_types.h +++ b/trunk/arch/x86/include/asm/pgtable_types.h @@ -273,7 +273,6 @@ typedef struct page *pgtable_t; extern pteval_t __supported_pte_mask; extern int nx_enabled; -extern void set_nx(void); #define pgprot_writecombine pgprot_writecombine extern pgprot_t pgprot_writecombine(pgprot_t prot); diff --git a/trunk/arch/x86/include/asm/processor.h b/trunk/arch/x86/include/asm/processor.h index ae85a8d66a30..76139506c3e4 100644 --- a/trunk/arch/x86/include/asm/processor.h +++ b/trunk/arch/x86/include/asm/processor.h @@ -75,9 +75,9 @@ struct cpuinfo_x86 { #else /* Number of 4K pages in DTLB/ITLB combined(in pages): */ int x86_tlbsize; -#endif __u8 x86_virt_bits; __u8 x86_phys_bits; +#endif /* CPUID returned core id bits: */ __u8 x86_coreid_bits; /* Max extended CPUID function supported: */ @@ -391,9 +391,6 @@ DECLARE_PER_CPU(union irq_stack_union, irq_stack_union); DECLARE_INIT_PER_CPU(irq_stack_union); DECLARE_PER_CPU(char *, irq_stack_ptr); -DECLARE_PER_CPU(unsigned int, irq_count); -extern unsigned long kernel_eflags; -extern asmlinkage void ignore_sysret(void); #else /* X86_64 */ #ifdef CONFIG_CC_STACKPROTECTOR DECLARE_PER_CPU(unsigned long, stack_canary); diff --git a/trunk/arch/x86/include/asm/sections.h b/trunk/arch/x86/include/asm/sections.h index 1b7ee5d673c2..2b8c5160388f 100644 --- a/trunk/arch/x86/include/asm/sections.h +++ b/trunk/arch/x86/include/asm/sections.h @@ -1,8 +1 @@ -#ifndef _ASM_X86_SECTIONS_H -#define _ASM_X86_SECTIONS_H - #include - -extern char __brk_base[], __brk_limit[]; - -#endif /* _ASM_X86_SECTIONS_H */ diff --git a/trunk/arch/x86/include/asm/setup.h b/trunk/arch/x86/include/asm/setup.h index bdc2ada05ae0..05c6f6b11fd5 100644 --- a/trunk/arch/x86/include/asm/setup.h +++ b/trunk/arch/x86/include/asm/setup.h @@ -64,7 +64,7 @@ extern void x86_quirk_time_init(void); #include /* Interrupt control for vSMPowered x86_64 systems */ -#ifdef CONFIG_X86_64 +#ifdef CONFIG_X86_VSMP void vsmp_init(void); #else static inline void vsmp_init(void) { } @@ -100,51 +100,20 @@ extern struct boot_params boot_params; */ #define LOWMEMSIZE() (0x9f000) -/* exceedingly early brk-like allocator */ -extern unsigned long _brk_end; -void *extend_brk(size_t size, size_t align); - -/* - * Reserve space in the brk section. The name must be unique within - * the file, and somewhat descriptive. The size is in bytes. Must be - * used at file scope. - * - * (This uses a temp function to wrap the asm so we can pass it the - * size parameter; otherwise we wouldn't be able to. We can't use a - * "section" attribute on a normal variable because it always ends up - * being @progbits, which ends up allocating space in the vmlinux - * executable.) - */ -#define RESERVE_BRK(name,sz) \ - static void __section(.discard) __used \ - __brk_reservation_fn_##name##__(void) { \ - asm volatile ( \ - ".pushsection .brk_reservation,\"aw\",@nobits;" \ - ".brk." #name ":" \ - " 1:.skip %c0;" \ - " .size .brk." #name ", . - 1b;" \ - " .popsection" \ - : : "i" (sz)); \ - } - #ifdef __i386__ void __init i386_start_kernel(void); extern void probe_roms(void); +extern unsigned long init_pg_tables_start; +extern unsigned long init_pg_tables_end; + #else void __init x86_64_start_kernel(char *real_mode); void __init x86_64_start_reservations(char *real_mode_data); #endif /* __i386__ */ #endif /* _SETUP */ -#else -#define RESERVE_BRK(name,sz) \ - .pushsection .brk_reservation,"aw",@nobits; \ -.brk.name: \ -1: .skip sz; \ - .size .brk.name,.-1b; \ - .popsection #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/trunk/arch/x86/include/asm/spinlock.h b/trunk/arch/x86/include/asm/spinlock.h index e5e6caffec87..3a5696656680 100644 --- a/trunk/arch/x86/include/asm/spinlock.h +++ b/trunk/arch/x86/include/asm/spinlock.h @@ -295,9 +295,6 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory"); } -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) - #define _raw_spin_relax(lock) cpu_relax() #define _raw_read_relax(lock) cpu_relax() #define _raw_write_relax(lock) cpu_relax() diff --git a/trunk/arch/x86/include/asm/suspend_32.h b/trunk/arch/x86/include/asm/suspend_32.h index 48dcfa62ea07..a5074bd0f8be 100644 --- a/trunk/arch/x86/include/asm/suspend_32.h +++ b/trunk/arch/x86/include/asm/suspend_32.h @@ -24,4 +24,28 @@ struct saved_context { unsigned long return_address; } __attribute__((packed)); +#ifdef CONFIG_ACPI +extern unsigned long saved_eip; +extern unsigned long saved_esp; +extern unsigned long saved_ebp; +extern unsigned long saved_ebx; +extern unsigned long saved_esi; +extern unsigned long saved_edi; + +static inline void acpi_save_register_state(unsigned long return_point) +{ + saved_eip = return_point; + asm volatile("movl %%esp,%0" : "=m" (saved_esp)); + asm volatile("movl %%ebp,%0" : "=m" (saved_ebp)); + asm volatile("movl %%ebx,%0" : "=m" (saved_ebx)); + asm volatile("movl %%edi,%0" : "=m" (saved_edi)); + asm volatile("movl %%esi,%0" : "=m" (saved_esi)); +} + +#define acpi_restore_register_state() do {} while (0) + +/* routines for saving/restoring kernel state */ +extern int acpi_save_state_mem(void); +#endif + #endif /* _ASM_X86_SUSPEND_32_H */ diff --git a/trunk/arch/x86/include/asm/timer.h b/trunk/arch/x86/include/asm/timer.h index bd37ed444a21..a81195eaa2b3 100644 --- a/trunk/arch/x86/include/asm/timer.h +++ b/trunk/arch/x86/include/asm/timer.h @@ -12,9 +12,9 @@ unsigned long native_calibrate_tsc(void); #ifdef CONFIG_X86_32 extern int timer_ack; +extern int recalibrate_cpu_khz(void); extern irqreturn_t timer_interrupt(int irq, void *dev_id); #endif /* CONFIG_X86_32 */ -extern int recalibrate_cpu_khz(void); extern int no_timer_check; diff --git a/trunk/arch/x86/include/asm/topology.h b/trunk/arch/x86/include/asm/topology.h index 744299c0b774..77cfb2cfb386 100644 --- a/trunk/arch/x86/include/asm/topology.h +++ b/trunk/arch/x86/include/asm/topology.h @@ -217,6 +217,10 @@ static inline cpumask_t node_to_cpumask(int node) { return cpu_online_map; } +static inline int node_to_first_cpu(int node) +{ + return first_cpu(cpu_online_map); +} static inline void setup_node_to_cpumask_map(void) { } @@ -233,6 +237,14 @@ static inline void setup_node_to_cpumask_map(void) { } #include +#ifdef CONFIG_NUMA +/* Returns the number of the first CPU on Node 'node'. */ +static inline int node_to_first_cpu(int node) +{ + return cpumask_first(cpumask_of_node(node)); +} +#endif + extern cpumask_t cpu_coregroup_map(int cpu); extern const struct cpumask *cpu_coregroup_mask(int cpu); diff --git a/trunk/arch/x86/include/asm/unistd_32.h b/trunk/arch/x86/include/asm/unistd_32.h index 6e72d74cf8dc..f2bba78430a4 100644 --- a/trunk/arch/x86/include/asm/unistd_32.h +++ b/trunk/arch/x86/include/asm/unistd_32.h @@ -338,8 +338,6 @@ #define __NR_dup3 330 #define __NR_pipe2 331 #define __NR_inotify_init1 332 -#define __NR_preadv 333 -#define __NR_pwritev 334 #ifdef __KERNEL__ diff --git a/trunk/arch/x86/include/asm/unistd_64.h b/trunk/arch/x86/include/asm/unistd_64.h index f81829462325..d2e415e6666f 100644 --- a/trunk/arch/x86/include/asm/unistd_64.h +++ b/trunk/arch/x86/include/asm/unistd_64.h @@ -653,10 +653,6 @@ __SYSCALL(__NR_dup3, sys_dup3) __SYSCALL(__NR_pipe2, sys_pipe2) #define __NR_inotify_init1 294 __SYSCALL(__NR_inotify_init1, sys_inotify_init1) -#define __NR_preadv 295 -__SYSCALL(__NR_preadv, sys_preadv) -#define __NR_pwritev 296 -__SYSCALL(__NR_pwritev, sys_pwritev) #ifndef __NO_STUBS diff --git a/trunk/arch/x86/include/asm/uv/uv_hub.h b/trunk/arch/x86/include/asm/uv/uv_hub.h index d3a98ea1062e..777327ef05c1 100644 --- a/trunk/arch/x86/include/asm/uv/uv_hub.h +++ b/trunk/arch/x86/include/asm/uv/uv_hub.h @@ -11,13 +11,11 @@ #ifndef _ASM_X86_UV_UV_HUB_H #define _ASM_X86_UV_UV_HUB_H -#ifdef CONFIG_X86_64 #include #include #include #include #include -#include /* @@ -201,10 +199,6 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); #define SCIR_CPU_ACTIVITY 0x02 /* not idle */ #define SCIR_CPU_HB_INTERVAL (HZ) /* once per second */ -/* Loop through all installed blades */ -#define for_each_possible_blade(bid) \ - for ((bid) = 0; (bid) < uv_num_possible_blades(); (bid)++) - /* * Macros for converting between kernel virtual addresses, socket local physical * addresses, and UV global physical addresses. @@ -399,7 +393,6 @@ static inline void uv_set_scir_bits(unsigned char value) uv_write_local_mmr8(uv_hub_info->scir.offset, value); } } - static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value) { if (uv_cpu_hub_info(cpu)->scir.state != value) { @@ -408,15 +401,4 @@ static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value) } } -static inline void uv_hub_send_ipi(int pnode, int apicid, int vector) -{ - unsigned long val; - - val = (1UL << UVH_IPI_INT_SEND_SHFT) | - ((apicid & 0x3f) << UVH_IPI_INT_APIC_ID_SHFT) | - (vector << UVH_IPI_INT_VECTOR_SHFT); - uv_write_global_mmr64(pnode, UVH_IPI_INT, val); -} - -#endif /* CONFIG_X86_64 */ #endif /* _ASM_X86_UV_UV_HUB_H */ diff --git a/trunk/arch/x86/include/asm/uv/uv_mmrs.h b/trunk/arch/x86/include/asm/uv/uv_mmrs.h index db68ac8a5ac2..dd627793a234 100644 --- a/trunk/arch/x86/include/asm/uv/uv_mmrs.h +++ b/trunk/arch/x86/include/asm/uv/uv_mmrs.h @@ -1,4 +1,3 @@ - /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -243,158 +242,6 @@ union uvh_event_occurred0_u { #define UVH_EVENT_OCCURRED0_ALIAS 0x0000000000070008UL #define UVH_EVENT_OCCURRED0_ALIAS_32 0x005f0 -/* ========================================================================= */ -/* UVH_GR0_TLB_INT0_CONFIG */ -/* ========================================================================= */ -#define UVH_GR0_TLB_INT0_CONFIG 0x61b00UL - -#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_SHFT 0 -#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_GR0_TLB_INT0_CONFIG_DM_SHFT 8 -#define UVH_GR0_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_SHFT 11 -#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_GR0_TLB_INT0_CONFIG_STATUS_SHFT 12 -#define UVH_GR0_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_GR0_TLB_INT0_CONFIG_P_SHFT 13 -#define UVH_GR0_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_GR0_TLB_INT0_CONFIG_T_SHFT 15 -#define UVH_GR0_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_GR0_TLB_INT0_CONFIG_M_SHFT 16 -#define UVH_GR0_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_SHFT 32 -#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL - -union uvh_gr0_tlb_int0_config_u { - unsigned long v; - struct uvh_gr0_tlb_int0_config_s { - unsigned long vector_ : 8; /* RW */ - unsigned long dm : 3; /* RW */ - unsigned long destmode : 1; /* RW */ - unsigned long status : 1; /* RO */ - unsigned long p : 1; /* RO */ - unsigned long rsvd_14 : 1; /* */ - unsigned long t : 1; /* RO */ - unsigned long m : 1; /* RW */ - unsigned long rsvd_17_31: 15; /* */ - unsigned long apic_id : 32; /* RW */ - } s; -}; - -/* ========================================================================= */ -/* UVH_GR0_TLB_INT1_CONFIG */ -/* ========================================================================= */ -#define UVH_GR0_TLB_INT1_CONFIG 0x61b40UL - -#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_SHFT 0 -#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_GR0_TLB_INT1_CONFIG_DM_SHFT 8 -#define UVH_GR0_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_SHFT 11 -#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_GR0_TLB_INT1_CONFIG_STATUS_SHFT 12 -#define UVH_GR0_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_GR0_TLB_INT1_CONFIG_P_SHFT 13 -#define UVH_GR0_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_GR0_TLB_INT1_CONFIG_T_SHFT 15 -#define UVH_GR0_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_GR0_TLB_INT1_CONFIG_M_SHFT 16 -#define UVH_GR0_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_SHFT 32 -#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL - -union uvh_gr0_tlb_int1_config_u { - unsigned long v; - struct uvh_gr0_tlb_int1_config_s { - unsigned long vector_ : 8; /* RW */ - unsigned long dm : 3; /* RW */ - unsigned long destmode : 1; /* RW */ - unsigned long status : 1; /* RO */ - unsigned long p : 1; /* RO */ - unsigned long rsvd_14 : 1; /* */ - unsigned long t : 1; /* RO */ - unsigned long m : 1; /* RW */ - unsigned long rsvd_17_31: 15; /* */ - unsigned long apic_id : 32; /* RW */ - } s; -}; - -/* ========================================================================= */ -/* UVH_GR1_TLB_INT0_CONFIG */ -/* ========================================================================= */ -#define UVH_GR1_TLB_INT0_CONFIG 0x61f00UL - -#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_SHFT 0 -#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_GR1_TLB_INT0_CONFIG_DM_SHFT 8 -#define UVH_GR1_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_SHFT 11 -#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_GR1_TLB_INT0_CONFIG_STATUS_SHFT 12 -#define UVH_GR1_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_GR1_TLB_INT0_CONFIG_P_SHFT 13 -#define UVH_GR1_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_GR1_TLB_INT0_CONFIG_T_SHFT 15 -#define UVH_GR1_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_GR1_TLB_INT0_CONFIG_M_SHFT 16 -#define UVH_GR1_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_SHFT 32 -#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL - -union uvh_gr1_tlb_int0_config_u { - unsigned long v; - struct uvh_gr1_tlb_int0_config_s { - unsigned long vector_ : 8; /* RW */ - unsigned long dm : 3; /* RW */ - unsigned long destmode : 1; /* RW */ - unsigned long status : 1; /* RO */ - unsigned long p : 1; /* RO */ - unsigned long rsvd_14 : 1; /* */ - unsigned long t : 1; /* RO */ - unsigned long m : 1; /* RW */ - unsigned long rsvd_17_31: 15; /* */ - unsigned long apic_id : 32; /* RW */ - } s; -}; - -/* ========================================================================= */ -/* UVH_GR1_TLB_INT1_CONFIG */ -/* ========================================================================= */ -#define UVH_GR1_TLB_INT1_CONFIG 0x61f40UL - -#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_SHFT 0 -#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL -#define UVH_GR1_TLB_INT1_CONFIG_DM_SHFT 8 -#define UVH_GR1_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL -#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_SHFT 11 -#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL -#define UVH_GR1_TLB_INT1_CONFIG_STATUS_SHFT 12 -#define UVH_GR1_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL -#define UVH_GR1_TLB_INT1_CONFIG_P_SHFT 13 -#define UVH_GR1_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL -#define UVH_GR1_TLB_INT1_CONFIG_T_SHFT 15 -#define UVH_GR1_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL -#define UVH_GR1_TLB_INT1_CONFIG_M_SHFT 16 -#define UVH_GR1_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL -#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_SHFT 32 -#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL - -union uvh_gr1_tlb_int1_config_u { - unsigned long v; - struct uvh_gr1_tlb_int1_config_s { - unsigned long vector_ : 8; /* RW */ - unsigned long dm : 3; /* RW */ - unsigned long destmode : 1; /* RW */ - unsigned long status : 1; /* RO */ - unsigned long p : 1; /* RO */ - unsigned long rsvd_14 : 1; /* */ - unsigned long t : 1; /* RO */ - unsigned long m : 1; /* RW */ - unsigned long rsvd_17_31: 15; /* */ - unsigned long apic_id : 32; /* RW */ - } s; -}; - /* ========================================================================= */ /* UVH_INT_CMPB */ /* ========================================================================= */ diff --git a/trunk/arch/x86/include/asm/xen/hypercall.h b/trunk/arch/x86/include/asm/xen/hypercall.h index 9c371e4a9fa6..5e79ca694326 100644 --- a/trunk/arch/x86/include/asm/xen/hypercall.h +++ b/trunk/arch/x86/include/asm/xen/hypercall.h @@ -296,8 +296,6 @@ HYPERVISOR_get_debugreg(int reg) static inline int HYPERVISOR_update_descriptor(u64 ma, u64 desc) { - if (sizeof(u64) == sizeof(long)) - return _hypercall2(int, update_descriptor, ma, desc); return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32); } diff --git a/trunk/arch/x86/kernel/Makefile b/trunk/arch/x86/kernel/Makefile index c611ad64137f..95f216bbfaf1 100644 --- a/trunk/arch/x86/kernel/Makefile +++ b/trunk/arch/x86/kernel/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o +obj-$(CONFIG_X86_VSMP) += vsmp_64.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_MODULES) += module_$(BITS).o obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o @@ -105,12 +106,12 @@ obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o -obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o +obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o # NB rename without _64 ### # 64 bit specific files ifeq ($(CONFIG_X86_64),y) - obj-$(CONFIG_X86_UV) += tlb_uv.o bios_uv.o uv_irq.o uv_sysfs.o uv_time.o + obj-$(CONFIG_X86_UV) += tlb_uv.o bios_uv.o uv_irq.o uv_sysfs.o obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o obj-$(CONFIG_AUDIT) += audit_64.o @@ -119,5 +120,4 @@ ifeq ($(CONFIG_X86_64),y) obj-$(CONFIG_AMD_IOMMU) += amd_iommu_init.o amd_iommu.o obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o - obj-y += vsmp_64.o endif diff --git a/trunk/arch/x86/kernel/alternative.c b/trunk/arch/x86/kernel/alternative.c index 4c80f1557433..6907b8e85d52 100644 --- a/trunk/arch/x86/kernel/alternative.c +++ b/trunk/arch/x86/kernel/alternative.c @@ -414,17 +414,9 @@ void __init alternative_instructions(void) that might execute the to be patched code. Other CPUs are not running. */ stop_nmi(); - - /* - * Don't stop machine check exceptions while patching. - * MCEs only happen when something got corrupted and in this - * case we must do something about the corruption. - * Ignoring it is worse than a unlikely patching race. - * Also machine checks tend to be broadcast and if one CPU - * goes into machine check the others follow quickly, so we don't - * expect a machine check to cause undue problems during to code - * patching. - */ +#ifdef CONFIG_X86_MCE + stop_mce(); +#endif apply_alternatives(__alt_instructions, __alt_instructions_end); @@ -464,6 +456,9 @@ void __init alternative_instructions(void) (unsigned long)__smp_locks_end); restart_nmi(); +#ifdef CONFIG_X86_MCE + restart_mce(); +#endif } /** diff --git a/trunk/arch/x86/kernel/amd_iommu.c b/trunk/arch/x86/kernel/amd_iommu.c index c5962fe3796f..5113c080f0c4 100644 --- a/trunk/arch/x86/kernel/amd_iommu.c +++ b/trunk/arch/x86/kernel/amd_iommu.c @@ -22,9 +22,10 @@ #include #include #include -#include #include +#ifdef CONFIG_IOMMU_API #include +#endif #include #include #include @@ -1296,10 +1297,8 @@ static void __unmap_single(struct amd_iommu *iommu, /* * The exported map_single function for dma_ops. */ -static dma_addr_t map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) +static dma_addr_t map_single(struct device *dev, phys_addr_t paddr, + size_t size, int dir) { unsigned long flags; struct amd_iommu *iommu; @@ -1307,7 +1306,6 @@ static dma_addr_t map_page(struct device *dev, struct page *page, u16 devid; dma_addr_t addr; u64 dma_mask; - phys_addr_t paddr = page_to_phys(page) + offset; INC_STATS_COUNTER(cnt_map_single); @@ -1342,8 +1340,8 @@ static dma_addr_t map_page(struct device *dev, struct page *page, /* * The exported unmap_single function for dma_ops. */ -static void unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, - enum dma_data_direction dir, struct dma_attrs *attrs) +static void unmap_single(struct device *dev, dma_addr_t dma_addr, + size_t size, int dir) { unsigned long flags; struct amd_iommu *iommu; @@ -1392,8 +1390,7 @@ static int map_sg_no_iommu(struct device *dev, struct scatterlist *sglist, * lists). */ static int map_sg(struct device *dev, struct scatterlist *sglist, - int nelems, enum dma_data_direction dir, - struct dma_attrs *attrs) + int nelems, int dir) { unsigned long flags; struct amd_iommu *iommu; @@ -1460,8 +1457,7 @@ static int map_sg(struct device *dev, struct scatterlist *sglist, * lists). */ static void unmap_sg(struct device *dev, struct scatterlist *sglist, - int nelems, enum dma_data_direction dir, - struct dma_attrs *attrs) + int nelems, int dir) { unsigned long flags; struct amd_iommu *iommu; @@ -1648,11 +1644,11 @@ static void prealloc_protection_domains(void) } } -static struct dma_map_ops amd_iommu_dma_ops = { +static struct dma_mapping_ops amd_iommu_dma_ops = { .alloc_coherent = alloc_coherent, .free_coherent = free_coherent, - .map_page = map_page, - .unmap_page = unmap_page, + .map_single = map_single, + .unmap_single = unmap_single, .map_sg = map_sg, .unmap_sg = unmap_sg, .dma_supported = amd_iommu_dma_supported, diff --git a/trunk/arch/x86/kernel/apic/apic.c b/trunk/arch/x86/kernel/apic/apic.c index 85eb8e100818..f9cecdfd05c5 100644 --- a/trunk/arch/x86/kernel/apic/apic.c +++ b/trunk/arch/x86/kernel/apic/apic.c @@ -46,7 +46,6 @@ #include #include #include -#include unsigned int num_processors; @@ -809,7 +808,7 @@ void clear_local_APIC(void) u32 v; /* APIC hasn't been mapped yet */ - if (!x2apic && !apic_phys) + if (!apic_phys) return; maxlvt = lapic_get_maxlvt(); @@ -843,14 +842,6 @@ void clear_local_APIC(void) apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); } #endif -#ifdef CONFIG_X86_MCE_INTEL - if (maxlvt >= 6) { - v = apic_read(APIC_LVTCMCI); - if (!(v & APIC_LVT_MASKED)) - apic_write(APIC_LVTCMCI, v | APIC_LVT_MASKED); - } -#endif - /* * Clean APIC state for other OSs: */ @@ -1250,12 +1241,6 @@ void __cpuinit setup_local_APIC(void) apic_write(APIC_LVT1, value); preempt_enable(); - -#ifdef CONFIG_X86_MCE_INTEL - /* Recheck CMCI information after local APIC is up on CPU #0 */ - if (smp_processor_id() == 0) - cmci_recheck(); -#endif } void __cpuinit end_local_APIC_setup(void) @@ -1334,16 +1319,15 @@ void __init enable_IR_x2apic(void) return; } - ret = save_IO_APIC_setup(); + local_irq_save(flags); + mask_8259A(); + + ret = save_mask_IO_APIC_setup(); if (ret) { pr_info("Saving IO-APIC state failed: %d\n", ret); goto end; } - local_irq_save(flags); - mask_IO_APIC_setup(); - mask_8259A(); - ret = enable_intr_remapping(1); if (ret && x2apic_preenabled) { @@ -1368,10 +1352,10 @@ void __init enable_IR_x2apic(void) else reinit_intr_remapped_IO_APIC(x2apic_preenabled); +end: unmask_8259A(); local_irq_restore(flags); -end: if (!ret) { if (!x2apic_preenabled) pr_info("Enabled x2apic and interrupt-remapping\n"); @@ -1524,10 +1508,12 @@ void __init early_init_lapic_mapping(void) */ void __init init_apic_mappings(void) { +#ifdef CONFIG_X86_X2APIC if (x2apic) { boot_cpu_physical_apicid = read_apic_id(); return; } +#endif /* * If no local APIC can be found then set up a fake all @@ -1971,9 +1957,12 @@ static int lapic_resume(struct sys_device *dev) local_irq_save(flags); +#ifdef CONFIG_X86_X2APIC if (x2apic) enable_x2apic(); - else { + else +#endif + { /* * Make sure the APICBASE points to the right address * diff --git a/trunk/arch/x86/kernel/apic/apic_flat_64.c b/trunk/arch/x86/kernel/apic/apic_flat_64.c index 0014714ea97b..f933822dba18 100644 --- a/trunk/arch/x86/kernel/apic/apic_flat_64.c +++ b/trunk/arch/x86/kernel/apic/apic_flat_64.c @@ -159,6 +159,20 @@ static int flat_apic_id_registered(void) return physid_isset(read_xapic_id(), phys_cpu_present_map); } +static unsigned int flat_cpu_mask_to_apicid(const struct cpumask *cpumask) +{ + return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; +} + +static unsigned int flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + unsigned long mask1 = cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; + unsigned long mask2 = cpumask_bits(andmask)[0] & APIC_ALL_CPUS; + + return mask1 & mask2; +} + static int flat_phys_pkg_id(int initial_apic_id, int index_msb) { return hard_smp_processor_id() >> index_msb; @@ -199,8 +213,8 @@ struct apic apic_flat = { .set_apic_id = set_apic_id, .apic_id_mask = 0xFFu << 24, - .cpu_mask_to_apicid = default_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, + .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, .send_IPI_mask = flat_send_IPI_mask, .send_IPI_mask_allbutself = flat_send_IPI_mask_allbutself, diff --git a/trunk/arch/x86/kernel/apic/io_apic.c b/trunk/arch/x86/kernel/apic/io_apic.c index 1bb5c6cee3eb..00e6071cefc4 100644 --- a/trunk/arch/x86/kernel/apic/io_apic.c +++ b/trunk/arch/x86/kernel/apic/io_apic.c @@ -389,8 +389,6 @@ struct io_apic { unsigned int index; unsigned int unused[3]; unsigned int data; - unsigned int unused2[11]; - unsigned int eoi; }; static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) @@ -399,12 +397,6 @@ static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) + (mp_ioapics[idx].apicaddr & ~PAGE_MASK); } -static inline void io_apic_eoi(unsigned int apic, unsigned int vector) -{ - struct io_apic __iomem *io_apic = io_apic_base(apic); - writel(vector, &io_apic->eoi); -} - static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) { struct io_apic __iomem *io_apic = io_apic_base(apic); @@ -554,12 +546,16 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq apic = entry->apic; pin = entry->pin; +#ifdef CONFIG_INTR_REMAP /* * With interrupt-remapping, destination information comes * from interrupt-remapping table entry. */ if (!irq_remapped(irq)) io_apic_write(apic, 0x11 + pin*2, dest); +#else + io_apic_write(apic, 0x11 + pin*2, dest); +#endif reg = io_apic_read(apic, 0x10 + pin*2); reg &= ~IO_APIC_REDIR_VECTOR_MASK; reg |= vector; @@ -592,12 +588,10 @@ set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask) if (assign_irq_vector(irq, cfg, mask)) return BAD_APICID; - /* check that before desc->addinity get updated */ + cpumask_and(desc->affinity, cfg->domain, mask); set_extra_move_desc(desc, mask); - cpumask_copy(desc->affinity, mask); - - return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain); + return apic->cpu_mask_to_apicid_and(desc->affinity, cpu_online_mask); } static void @@ -855,9 +849,9 @@ __setup("pirq=", ioapic_pirq_setup); static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS]; /* - * Saves all the IO-APIC RTE's + * Saves and masks all the unmasked IO-APIC RTE's */ -int save_IO_APIC_setup(void) +int save_mask_IO_APIC_setup(void) { union IO_APIC_reg_01 reg_01; unsigned long flags; @@ -882,9 +876,16 @@ int save_IO_APIC_setup(void) } for (apic = 0; apic < nr_ioapics; apic++) - for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) - early_ioapic_entries[apic][pin] = + for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { + struct IO_APIC_route_entry entry; + + entry = early_ioapic_entries[apic][pin] = ioapic_read_entry(apic, pin); + if (!entry.mask) { + entry.mask = 1; + ioapic_write_entry(apic, pin, entry); + } + } return 0; @@ -897,25 +898,6 @@ int save_IO_APIC_setup(void) return -ENOMEM; } -void mask_IO_APIC_setup(void) -{ - int apic, pin; - - for (apic = 0; apic < nr_ioapics; apic++) { - if (!early_ioapic_entries[apic]) - break; - for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { - struct IO_APIC_route_entry entry; - - entry = early_ioapic_entries[apic][pin]; - if (!entry.mask) { - entry.mask = 1; - ioapic_write_entry(apic, pin, entry); - } - } - } -} - void restore_IO_APIC_setup(void) { int apic, pin; @@ -1429,7 +1411,9 @@ void __setup_vector_irq(int cpu) } static struct irq_chip ioapic_chip; +#ifdef CONFIG_INTR_REMAP static struct irq_chip ir_ioapic_chip; +#endif #define IOAPIC_AUTO -1 #define IOAPIC_EDGE 0 @@ -1468,6 +1452,7 @@ static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long t else desc->status &= ~IRQ_LEVEL; +#ifdef CONFIG_INTR_REMAP if (irq_remapped(irq)) { desc->status |= IRQ_MOVE_PCNTXT; if (trigger) @@ -1479,7 +1464,7 @@ static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long t handle_edge_irq, "edge"); return; } - +#endif if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || trigger == IOAPIC_LEVEL) set_irq_chip_and_handler_name(irq, &ioapic_chip, @@ -1493,13 +1478,14 @@ static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long t int setup_ioapic_entry(int apic_id, int irq, struct IO_APIC_route_entry *entry, unsigned int destination, int trigger, - int polarity, int vector, int pin) + int polarity, int vector) { /* * add it to the IO-APIC irq-routing table: */ memset(entry,0,sizeof(*entry)); +#ifdef CONFIG_INTR_REMAP if (intr_remapping_enabled) { struct intel_iommu *iommu = map_ioapic_to_ir(apic_id); struct irte irte; @@ -1518,14 +1504,7 @@ int setup_ioapic_entry(int apic_id, int irq, irte.present = 1; irte.dst_mode = apic->irq_dest_mode; - /* - * Trigger mode in the IRTE will always be edge, and the - * actual level or edge trigger will be setup in the IO-APIC - * RTE. This will help simplify level triggered irq migration. - * For more details, see the comments above explainig IO-APIC - * irq migration in the presence of interrupt-remapping. - */ - irte.trigger_mode = 0; + irte.trigger_mode = trigger; irte.dlvry_mode = apic->irq_delivery_mode; irte.vector = vector; irte.dest_id = IRTE_DEST(destination); @@ -1536,21 +1515,18 @@ int setup_ioapic_entry(int apic_id, int irq, ir_entry->zero = 0; ir_entry->format = 1; ir_entry->index = (index & 0x7fff); - /* - * IO-APIC RTE will be configured with virtual vector. - * irq handler will do the explicit EOI to the io-apic. - */ - ir_entry->vector = pin; - } else { + } else +#endif + { entry->delivery_mode = apic->irq_delivery_mode; entry->dest_mode = apic->irq_dest_mode; entry->dest = destination; - entry->vector = vector; } entry->mask = 0; /* enable IRQ */ entry->trigger = trigger; entry->polarity = polarity; + entry->vector = vector; /* Mask level triggered irqs. * Use IRQ_DELAYED_DISABLE for edge triggered irqs. @@ -1585,7 +1561,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq if (setup_ioapic_entry(mp_ioapics[apic_id].apicid, irq, &entry, - dest, trigger, polarity, cfg->vector, pin)) { + dest, trigger, polarity, cfg->vector)) { printk("Failed to setup ioapic entry for ioapic %d, pin %d\n", mp_ioapics[apic_id].apicid, pin); __clear_irq_vector(irq, cfg); @@ -1666,8 +1642,10 @@ static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin, { struct IO_APIC_route_entry entry; +#ifdef CONFIG_INTR_REMAP if (intr_remapping_enabled) return; +#endif memset(&entry, 0, sizeof(entry)); @@ -2062,13 +2040,8 @@ void disable_IO_APIC(void) * If the i8259 is routed through an IOAPIC * Put that IOAPIC in virtual wire mode * so legacy interrupts can be delivered. - * - * With interrupt-remapping, for now we will use virtual wire A mode, - * as virtual wire B is little complex (need to configure both - * IOAPIC RTE aswell as interrupt-remapping table entry). - * As this gets called during crash dump, keep this simple for now. */ - if (ioapic_i8259.pin != -1 && !intr_remapping_enabled) { + if (ioapic_i8259.pin != -1) { struct IO_APIC_route_entry entry; memset(&entry, 0, sizeof(entry)); @@ -2088,10 +2061,7 @@ void disable_IO_APIC(void) ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry); } - /* - * Use virtual wire A mode when interrupt remapping is enabled. - */ - disconnect_bsp_APIC(!intr_remapping_enabled && ioapic_i8259.pin != -1); + disconnect_bsp_APIC(ioapic_i8259.pin != -1); } #ifdef CONFIG_X86_32 @@ -2333,24 +2303,37 @@ static int ioapic_retrigger_irq(unsigned int irq) #ifdef CONFIG_SMP #ifdef CONFIG_INTR_REMAP +static void ir_irq_migration(struct work_struct *work); + +static DECLARE_DELAYED_WORK(ir_migration_work, ir_irq_migration); /* * Migrate the IO-APIC irq in the presence of intr-remapping. * - * For both level and edge triggered, irq migration is a simple atomic - * update(of vector and cpu destination) of IRTE and flush the hardware cache. + * For edge triggered, irq migration is a simple atomic update(of vector + * and cpu destination) of IRTE and flush the hardware cache. + * + * For level triggered, we need to modify the io-apic RTE aswell with the update + * vector information, along with modifying IRTE with vector and destination. + * So irq migration for level triggered is little bit more complex compared to + * edge triggered migration. But the good news is, we use the same algorithm + * for level triggered migration as we have today, only difference being, + * we now initiate the irq migration from process context instead of the + * interrupt context. * - * For level triggered, we eliminate the io-apic RTE modification (with the - * updated vector information), by using a virtual vector (io-apic pin number). - * Real vector that is used for interrupting cpu will be coming from - * the interrupt-remapping table entry. + * In future, when we do a directed EOI (combined with cpu EOI broadcast + * suppression) to the IO-APIC, level triggered irq migration will also be + * as simple as edge triggered migration and we can do the irq migration + * with a simple atomic update to IO-APIC RTE. */ static void migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask) { struct irq_cfg *cfg; struct irte irte; + int modify_ioapic_rte; unsigned int dest; + unsigned long flags; unsigned int irq; if (!cpumask_intersects(mask, cpu_online_mask)) @@ -2368,6 +2351,13 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask) dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); + modify_ioapic_rte = desc->status & IRQ_LEVEL; + if (modify_ioapic_rte) { + spin_lock_irqsave(&ioapic_lock, flags); + __target_IO_APIC_irq(irq, dest, cfg); + spin_unlock_irqrestore(&ioapic_lock, flags); + } + irte.vector = cfg->vector; irte.dest_id = IRTE_DEST(dest); @@ -2382,12 +2372,73 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask) cpumask_copy(desc->affinity, mask); } +static int migrate_irq_remapped_level_desc(struct irq_desc *desc) +{ + int ret = -1; + struct irq_cfg *cfg = desc->chip_data; + + mask_IO_APIC_irq_desc(desc); + + if (io_apic_level_ack_pending(cfg)) { + /* + * Interrupt in progress. Migrating irq now will change the + * vector information in the IO-APIC RTE and that will confuse + * the EOI broadcast performed by cpu. + * So, delay the irq migration to the next instance. + */ + schedule_delayed_work(&ir_migration_work, 1); + goto unmask; + } + + /* everthing is clear. we have right of way */ + migrate_ioapic_irq_desc(desc, desc->pending_mask); + + ret = 0; + desc->status &= ~IRQ_MOVE_PENDING; + cpumask_clear(desc->pending_mask); + +unmask: + unmask_IO_APIC_irq_desc(desc); + + return ret; +} + +static void ir_irq_migration(struct work_struct *work) +{ + unsigned int irq; + struct irq_desc *desc; + + for_each_irq_desc(irq, desc) { + if (desc->status & IRQ_MOVE_PENDING) { + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + if (!desc->chip->set_affinity || + !(desc->status & IRQ_MOVE_PENDING)) { + desc->status &= ~IRQ_MOVE_PENDING; + spin_unlock_irqrestore(&desc->lock, flags); + continue; + } + + desc->chip->set_affinity(irq, desc->pending_mask); + spin_unlock_irqrestore(&desc->lock, flags); + } + } +} + /* * Migrates the IRQ destination in the process context. */ static void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask) { + if (desc->status & IRQ_LEVEL) { + desc->status |= IRQ_MOVE_PENDING; + cpumask_copy(desc->pending_mask, mask); + migrate_irq_remapped_level_desc(desc); + return; + } + migrate_ioapic_irq_desc(desc, mask); } static void set_ir_ioapic_affinity_irq(unsigned int irq, @@ -2397,11 +2448,6 @@ static void set_ir_ioapic_affinity_irq(unsigned int irq, set_ir_ioapic_affinity_irq_desc(desc, mask); } -#else -static inline void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc, - const struct cpumask *mask) -{ -} #endif asmlinkage void smp_irq_move_cleanup_interrupt(void) @@ -2415,7 +2461,6 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) me = smp_processor_id(); for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { unsigned int irq; - unsigned int irr; struct irq_desc *desc; struct irq_cfg *cfg; irq = __get_cpu_var(vector_irq)[vector]; @@ -2435,18 +2480,6 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) goto unlock; - irr = apic_read(APIC_IRR + (vector / 32 * 0x10)); - /* - * Check if the vector that needs to be cleanedup is - * registered at the cpu's IRR. If so, then this is not - * the best time to clean it up. Lets clean it up in the - * next attempt by sending another IRQ_MOVE_CLEANUP_VECTOR - * to myself. - */ - if (irr & (1 << (vector % 32))) { - apic->send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR); - goto unlock; - } __get_cpu_var(vector_irq)[vector] = -1; cfg->move_cleanup_count--; unlock: @@ -2496,44 +2529,9 @@ static inline void irq_complete_move(struct irq_desc **descp) {} #endif #ifdef CONFIG_INTR_REMAP -static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) -{ - int apic, pin; - struct irq_pin_list *entry; - - entry = cfg->irq_2_pin; - for (;;) { - - if (!entry) - break; - - apic = entry->apic; - pin = entry->pin; - io_apic_eoi(apic, pin); - entry = entry->next; - } -} - -static void -eoi_ioapic_irq(struct irq_desc *desc) -{ - struct irq_cfg *cfg; - unsigned long flags; - unsigned int irq; - - irq = desc->irq; - cfg = desc->chip_data; - - spin_lock_irqsave(&ioapic_lock, flags); - __eoi_ioapic_irq(irq, cfg); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - static void ack_x2apic_level(unsigned int irq) { - struct irq_desc *desc = irq_to_desc(irq); ack_x2APIC_irq(); - eoi_ioapic_irq(desc); } static void ack_x2apic_edge(unsigned int irq) @@ -2664,20 +2662,20 @@ static struct irq_chip ioapic_chip __read_mostly = { .retrigger = ioapic_retrigger_irq, }; +#ifdef CONFIG_INTR_REMAP static struct irq_chip ir_ioapic_chip __read_mostly = { .name = "IR-IO-APIC", .startup = startup_ioapic_irq, .mask = mask_IO_APIC_irq, .unmask = unmask_IO_APIC_irq, -#ifdef CONFIG_INTR_REMAP .ack = ack_x2apic_edge, .eoi = ack_x2apic_level, #ifdef CONFIG_SMP .set_affinity = set_ir_ioapic_affinity_irq, -#endif #endif .retrigger = ioapic_retrigger_irq, }; +#endif static inline void init_IO_APIC_traps(void) { @@ -2903,8 +2901,10 @@ static inline void __init check_timer(void) * 8259A. */ if (pin1 == -1) { +#ifdef CONFIG_INTR_REMAP if (intr_remapping_enabled) panic("BIOS bug: timer not connected to IO-APIC"); +#endif pin1 = pin2; apic1 = apic2; no_pin1 = 1; @@ -2940,8 +2940,10 @@ static inline void __init check_timer(void) clear_IO_APIC_pin(0, pin1); goto out; } +#ifdef CONFIG_INTR_REMAP if (intr_remapping_enabled) panic("timer doesn't work through Interrupt-remapped IO-APIC"); +#endif local_irq_disable(); clear_IO_APIC_pin(apic1, pin1); if (!no_pin1) @@ -3235,7 +3237,9 @@ void destroy_irq(unsigned int irq) if (desc) desc->chip_data = cfg; +#ifdef CONFIG_INTR_REMAP free_irte(irq); +#endif spin_lock_irqsave(&vector_lock, flags); __clear_irq_vector(irq, cfg); spin_unlock_irqrestore(&vector_lock, flags); @@ -3261,6 +3265,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); +#ifdef CONFIG_INTR_REMAP if (irq_remapped(irq)) { struct irte irte; int ir_index; @@ -3286,13 +3291,10 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms MSI_ADDR_IR_SHV | MSI_ADDR_IR_INDEX1(ir_index) | MSI_ADDR_IR_INDEX2(ir_index); - } else { - if (x2apic_enabled()) - msg->address_hi = MSI_ADDR_BASE_HI | - MSI_ADDR_EXT_DEST_ID(dest); - else - msg->address_hi = MSI_ADDR_BASE_HI; - + } else +#endif + { + msg->address_hi = MSI_ADDR_BASE_HI; msg->address_lo = MSI_ADDR_BASE_LO | ((apic->irq_dest_mode == 0) ? @@ -3392,15 +3394,14 @@ static struct irq_chip msi_chip = { .retrigger = ioapic_retrigger_irq, }; +#ifdef CONFIG_INTR_REMAP static struct irq_chip msi_ir_chip = { .name = "IR-PCI-MSI", .unmask = unmask_msi_irq, .mask = mask_msi_irq, -#ifdef CONFIG_INTR_REMAP .ack = ack_x2apic_edge, #ifdef CONFIG_SMP .set_affinity = ir_set_msi_irq_affinity, -#endif #endif .retrigger = ioapic_retrigger_irq, }; @@ -3431,6 +3432,7 @@ static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec) } return index; } +#endif static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) { @@ -3444,6 +3446,7 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) set_irq_msi(irq, msidesc); write_msi_msg(irq, &msg); +#ifdef CONFIG_INTR_REMAP if (irq_remapped(irq)) { struct irq_desc *desc = irq_to_desc(irq); /* @@ -3452,6 +3455,7 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) desc->status |= IRQ_MOVE_PCNTXT; set_irq_chip_and_handler_name(irq, &msi_ir_chip, handle_edge_irq, "edge"); } else +#endif set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); dev_printk(KERN_DEBUG, &dev->dev, "irq %d for MSI/MSI-X\n", irq); @@ -3465,12 +3469,11 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) int ret, sub_handle; struct msi_desc *msidesc; unsigned int irq_want; - struct intel_iommu *iommu = NULL; - int index = 0; - /* x86 doesn't support multiple MSI yet */ - if (type == PCI_CAP_ID_MSI && nvec > 1) - return 1; +#ifdef CONFIG_INTR_REMAP + struct intel_iommu *iommu = 0; + int index = 0; +#endif irq_want = nr_irqs_gsi; sub_handle = 0; @@ -3479,6 +3482,7 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) if (irq == 0) return -1; irq_want = irq + 1; +#ifdef CONFIG_INTR_REMAP if (!intr_remapping_enabled) goto no_ir; @@ -3506,6 +3510,7 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) set_irte_irq(irq, iommu, index, sub_handle); } no_ir: +#endif ret = setup_msi_irq(dev, msidesc, irq); if (ret < 0) goto error; @@ -3523,7 +3528,7 @@ void arch_teardown_msi_irq(unsigned int irq) destroy_irq(irq); } -#if defined (CONFIG_DMAR) || defined (CONFIG_INTR_REMAP) +#ifdef CONFIG_DMAR #ifdef CONFIG_SMP static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask) { @@ -3604,7 +3609,7 @@ static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask) #endif /* CONFIG_SMP */ -static struct irq_chip hpet_msi_type = { +struct irq_chip hpet_msi_type = { .name = "HPET_MSI", .unmask = hpet_msi_unmask, .mask = hpet_msi_mask, @@ -4040,9 +4045,11 @@ void __init setup_ioapic_dest(void) else mask = apic->target_cpus(); +#ifdef CONFIG_INTR_REMAP if (intr_remapping_enabled) set_ir_ioapic_affinity_irq_desc(desc, mask); else +#endif set_ioapic_affinity_irq_desc(desc, mask); } @@ -4135,12 +4142,9 @@ static int __init ioapic_insert_resources(void) struct resource *r = ioapic_resources; if (!r) { - if (nr_ioapics > 0) { - printk(KERN_ERR - "IO APIC resources couldn't be allocated.\n"); - return -1; - } - return 0; + printk(KERN_ERR + "IO APIC resources could be not be allocated.\n"); + return -1; } for (i = 0; i < nr_ioapics; i++) { diff --git a/trunk/arch/x86/kernel/apic/probe_64.c b/trunk/arch/x86/kernel/apic/probe_64.c index 1783652bb0e5..8d7748efe6a8 100644 --- a/trunk/arch/x86/kernel/apic/probe_64.c +++ b/trunk/arch/x86/kernel/apic/probe_64.c @@ -68,13 +68,6 @@ void __init default_setup_apic_routing(void) apic = &apic_physflat; printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); } - - /* - * Now that apic routing model is selected, configure the - * fault handling for intr remapping. - */ - if (intr_remapping_enabled) - enable_drhd_fault_handling(); } /* Same for both flat and physical. */ diff --git a/trunk/arch/x86/kernel/apic/x2apic_cluster.c b/trunk/arch/x86/kernel/apic/x2apic_cluster.c index 4a903e2f0d17..8fb87b6dd633 100644 --- a/trunk/arch/x86/kernel/apic/x2apic_cluster.c +++ b/trunk/arch/x86/kernel/apic/x2apic_cluster.c @@ -57,8 +57,6 @@ static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) unsigned long query_cpu; unsigned long flags; - x2apic_wrmsr_fence(); - local_irq_save(flags); for_each_cpu(query_cpu, mask) { __x2apic_send_IPI_dest( @@ -75,8 +73,6 @@ static void unsigned long query_cpu; unsigned long flags; - x2apic_wrmsr_fence(); - local_irq_save(flags); for_each_cpu(query_cpu, mask) { if (query_cpu == this_cpu) @@ -94,8 +90,6 @@ static void x2apic_send_IPI_allbutself(int vector) unsigned long query_cpu; unsigned long flags; - x2apic_wrmsr_fence(); - local_irq_save(flags); for_each_online_cpu(query_cpu) { if (query_cpu == this_cpu) diff --git a/trunk/arch/x86/kernel/apic/x2apic_phys.c b/trunk/arch/x86/kernel/apic/x2apic_phys.c index a284359627e7..23625b9f98b2 100644 --- a/trunk/arch/x86/kernel/apic/x2apic_phys.c +++ b/trunk/arch/x86/kernel/apic/x2apic_phys.c @@ -58,8 +58,6 @@ static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) unsigned long query_cpu; unsigned long flags; - x2apic_wrmsr_fence(); - local_irq_save(flags); for_each_cpu(query_cpu, mask) { __x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu), @@ -75,8 +73,6 @@ static void unsigned long query_cpu; unsigned long flags; - x2apic_wrmsr_fence(); - local_irq_save(flags); for_each_cpu(query_cpu, mask) { if (query_cpu != this_cpu) @@ -93,8 +89,6 @@ static void x2apic_send_IPI_allbutself(int vector) unsigned long query_cpu; unsigned long flags; - x2apic_wrmsr_fence(); - local_irq_save(flags); for_each_online_cpu(query_cpu) { if (query_cpu == this_cpu) diff --git a/trunk/arch/x86/kernel/apic/x2apic_uv_x.c b/trunk/arch/x86/kernel/apic/x2apic_uv_x.c index 1248318436e8..1bd6da1f8fad 100644 --- a/trunk/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/trunk/arch/x86/kernel/apic/x2apic_uv_x.c @@ -118,12 +118,17 @@ static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip) static void uv_send_IPI_one(int cpu, int vector) { - unsigned long apicid; + unsigned long val, apicid; int pnode; apicid = per_cpu(x86_cpu_to_apicid, cpu); pnode = uv_apicid_to_pnode(apicid); - uv_hub_send_ipi(pnode, apicid, vector); + + val = (1UL << UVH_IPI_INT_SEND_SHFT) | + (apicid << UVH_IPI_INT_APIC_ID_SHFT) | + (vector << UVH_IPI_INT_VECTOR_SHFT); + + uv_write_global_mmr64(pnode, UVH_IPI_INT, val); } static void uv_send_IPI_mask(const struct cpumask *mask, int vector) diff --git a/trunk/arch/x86/kernel/apm_32.c b/trunk/arch/x86/kernel/apm_32.c index ac7783a67432..10033fe718e0 100644 --- a/trunk/arch/x86/kernel/apm_32.c +++ b/trunk/arch/x86/kernel/apm_32.c @@ -1190,10 +1190,8 @@ static int suspend(int vetoable) struct apm_user *as; device_suspend(PMSG_SUSPEND); - - device_power_down(PMSG_SUSPEND); - local_irq_disable(); + device_power_down(PMSG_SUSPEND); sysdev_suspend(PMSG_SUSPEND); local_irq_enable(); @@ -1211,12 +1209,9 @@ static int suspend(int vetoable) if (err != APM_SUCCESS) apm_error("suspend", err); err = (err == APM_SUCCESS) ? 0 : -EIO; - sysdev_resume(); - local_irq_enable(); - device_power_up(PMSG_RESUME); - + local_irq_enable(); device_resume(PMSG_RESUME); queue_event(APM_NORMAL_RESUME, NULL); spin_lock(&user_list_lock); @@ -1233,9 +1228,8 @@ static void standby(void) { int err; - device_power_down(PMSG_SUSPEND); - local_irq_disable(); + device_power_down(PMSG_SUSPEND); sysdev_suspend(PMSG_SUSPEND); local_irq_enable(); @@ -1245,9 +1239,8 @@ static void standby(void) local_irq_disable(); sysdev_resume(); - local_irq_enable(); - device_power_up(PMSG_RESUME); + local_irq_enable(); } static apm_event_t get_event(void) diff --git a/trunk/arch/x86/kernel/asm-offsets_32.c b/trunk/arch/x86/kernel/asm-offsets_32.c index 5a6aa1c1162f..fbf2f33e3080 100644 --- a/trunk/arch/x86/kernel/asm-offsets_32.c +++ b/trunk/arch/x86/kernel/asm-offsets_32.c @@ -18,7 +18,6 @@ #include #include #include -#include #include diff --git a/trunk/arch/x86/kernel/asm-offsets_64.c b/trunk/arch/x86/kernel/asm-offsets_64.c index e72f062fb4b5..8793ab33e2c1 100644 --- a/trunk/arch/x86/kernel/asm-offsets_64.c +++ b/trunk/arch/x86/kernel/asm-offsets_64.c @@ -16,7 +16,6 @@ #include #include #include -#include #include diff --git a/trunk/arch/x86/kernel/check.c b/trunk/arch/x86/kernel/check.c index fc999e6fc46a..2ac0ab71412a 100644 --- a/trunk/arch/x86/kernel/check.c +++ b/trunk/arch/x86/kernel/check.c @@ -83,15 +83,15 @@ void __init setup_bios_corruption_check(void) u64 size; addr = find_e820_area_size(addr, &size, PAGE_SIZE); - if (!(addr + 1)) - break; - - if (addr >= corruption_check_size) + if (addr == 0) break; if ((addr + size) > corruption_check_size) size = corruption_check_size - addr; + if (size == 0) + break; + e820_update_range(addr, size, E820_RAM, E820_RESERVED); scan_areas[num_scan_areas].addr = addr; scan_areas[num_scan_areas].size = size; diff --git a/trunk/arch/x86/kernel/cpu/Makefile b/trunk/arch/x86/kernel/cpu/Makefile index 4e242f9a06e4..82db7f45e2de 100644 --- a/trunk/arch/x86/kernel/cpu/Makefile +++ b/trunk/arch/x86/kernel/cpu/Makefile @@ -14,12 +14,11 @@ obj-y += vmware.o hypervisor.o obj-$(CONFIG_X86_32) += bugs.o cmpxchg.o obj-$(CONFIG_X86_64) += bugs_64.o -obj-$(CONFIG_X86_CPU_DEBUG) += cpu_debug.o - obj-$(CONFIG_CPU_SUP_INTEL) += intel.o obj-$(CONFIG_CPU_SUP_AMD) += amd.o obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o -obj-$(CONFIG_CPU_SUP_CENTAUR) += centaur.o +obj-$(CONFIG_CPU_SUP_CENTAUR_32) += centaur.o +obj-$(CONFIG_CPU_SUP_CENTAUR_64) += centaur_64.o obj-$(CONFIG_CPU_SUP_TRANSMETA_32) += transmeta.o obj-$(CONFIG_CPU_SUP_UMC_32) += umc.o diff --git a/trunk/arch/x86/kernel/cpu/addon_cpuid_features.c b/trunk/arch/x86/kernel/cpu/addon_cpuid_features.c index 8220ae69849d..6882a735d9c0 100644 --- a/trunk/arch/x86/kernel/cpu/addon_cpuid_features.c +++ b/trunk/arch/x86/kernel/cpu/addon_cpuid_features.c @@ -29,7 +29,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) u32 regs[4]; const struct cpuid_bit *cb; - static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { + static const struct cpuid_bit cpuid_bits[] = { { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 }, { 0, 0, 0, 0 } }; diff --git a/trunk/arch/x86/kernel/cpu/amd.c b/trunk/arch/x86/kernel/cpu/amd.c index 7e4a459daa64..25423a5b80ed 100644 --- a/trunk/arch/x86/kernel/cpu/amd.c +++ b/trunk/arch/x86/kernel/cpu/amd.c @@ -5,7 +5,6 @@ #include #include #include -#include #ifdef CONFIG_X86_64 # include @@ -142,55 +141,6 @@ static void __cpuinit init_amd_k6(struct cpuinfo_x86 *c) } } -static void __cpuinit amd_k7_smp_check(struct cpuinfo_x86 *c) -{ -#ifdef CONFIG_SMP - /* calling is from identify_secondary_cpu() ? */ - if (c->cpu_index == boot_cpu_id) - return; - - /* - * Certain Athlons might work (for various values of 'work') in SMP - * but they are not certified as MP capable. - */ - /* Athlon 660/661 is valid. */ - if ((c->x86_model == 6) && ((c->x86_mask == 0) || - (c->x86_mask == 1))) - goto valid_k7; - - /* Duron 670 is valid */ - if ((c->x86_model == 7) && (c->x86_mask == 0)) - goto valid_k7; - - /* - * Athlon 662, Duron 671, and Athlon >model 7 have capability - * bit. It's worth noting that the A5 stepping (662) of some - * Athlon XP's have the MP bit set. - * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for - * more. - */ - if (((c->x86_model == 6) && (c->x86_mask >= 2)) || - ((c->x86_model == 7) && (c->x86_mask >= 1)) || - (c->x86_model > 7)) - if (cpu_has_mp) - goto valid_k7; - - /* If we get here, not a certified SMP capable AMD system. */ - - /* - * Don't taint if we are running SMP kernel on a single non-MP - * approved Athlon - */ - WARN_ONCE(1, "WARNING: This combination of AMD" - "processors is not suitable for SMP.\n"); - if (!test_taint(TAINT_UNSAFE_SMP)) - add_taint(TAINT_UNSAFE_SMP); - -valid_k7: - ; -#endif -} - static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c) { u32 l, h; @@ -225,8 +175,6 @@ static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c) } set_cpu_cap(c, X86_FEATURE_K7); - - amd_k7_smp_check(c); } #endif @@ -502,7 +450,7 @@ static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c, unsigned int } #endif -static const struct cpu_dev __cpuinitconst amd_cpu_dev = { +static struct cpu_dev amd_cpu_dev __cpuinitdata = { .c_vendor = "AMD", .c_ident = { "AuthenticAMD" }, #ifdef CONFIG_X86_32 diff --git a/trunk/arch/x86/kernel/cpu/centaur.c b/trunk/arch/x86/kernel/cpu/centaur.c index c95e831bb095..89bfdd9cacc6 100644 --- a/trunk/arch/x86/kernel/cpu/centaur.c +++ b/trunk/arch/x86/kernel/cpu/centaur.c @@ -1,11 +1,11 @@ -#include #include #include +#include #include +#include #include #include -#include #include "cpu.h" @@ -276,7 +276,7 @@ static void __cpuinit init_c3(struct cpuinfo_x86 *c) */ c->x86_capability[5] = cpuid_edx(0xC0000001); } -#ifdef CONFIG_X86_32 + /* Cyrix III family needs CX8 & PGE explicitly enabled. */ if (c->x86_model >= 6 && c->x86_model <= 9) { rdmsr(MSR_VIA_FCR, lo, hi); @@ -288,11 +288,6 @@ static void __cpuinit init_c3(struct cpuinfo_x86 *c) /* Before Nehemiah, the C3's had 3dNOW! */ if (c->x86_model >= 6 && c->x86_model < 9) set_cpu_cap(c, X86_FEATURE_3DNOW); -#endif - if (c->x86 == 0x6 && c->x86_model >= 0xf) { - c->x86_cache_alignment = c->x86_clflush_size * 2; - set_cpu_cap(c, X86_FEATURE_REP_GOOD); - } display_cacheinfo(c); } @@ -321,25 +316,16 @@ enum { static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c) { switch (c->x86) { -#ifdef CONFIG_X86_32 case 5: /* Emulate MTRRs using Centaur's MCR. */ set_cpu_cap(c, X86_FEATURE_CENTAUR_MCR); break; -#endif - case 6: - if (c->x86_model >= 0xf) - set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); - break; } -#ifdef CONFIG_X86_64 - set_cpu_cap(c, X86_FEATURE_SYSENTER32); -#endif } static void __cpuinit init_centaur(struct cpuinfo_x86 *c) { -#ifdef CONFIG_X86_32 + char *name; u32 fcr_set = 0; u32 fcr_clr = 0; @@ -351,10 +337,8 @@ static void __cpuinit init_centaur(struct cpuinfo_x86 *c) * 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */ clear_cpu_cap(c, 0*32+31); -#endif - early_init_centaur(c); + switch (c->x86) { -#ifdef CONFIG_X86_32 case 5: switch (c->x86_model) { case 4: @@ -458,20 +442,16 @@ static void __cpuinit init_centaur(struct cpuinfo_x86 *c) } sprintf(c->x86_model_id, "WinChip %s", name); break; -#endif + case 6: init_c3(c); break; } -#ifdef CONFIG_X86_64 - set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); -#endif } static unsigned int __cpuinit centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size) { -#ifdef CONFIG_X86_32 /* VIA C3 CPUs (670-68F) need further shifting. */ if ((c->x86 == 6) && ((c->x86_model == 7) || (c->x86_model == 8))) size >>= 8; @@ -484,11 +464,11 @@ centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size) if ((c->x86 == 6) && (c->x86_model == 9) && (c->x86_mask == 1) && (size == 65)) size -= 1; -#endif + return size; } -static const struct cpu_dev __cpuinitconst centaur_cpu_dev = { +static struct cpu_dev centaur_cpu_dev __cpuinitdata = { .c_vendor = "Centaur", .c_ident = { "CentaurHauls" }, .c_early_init = early_init_centaur, diff --git a/trunk/arch/x86/kernel/cpu/centaur_64.c b/trunk/arch/x86/kernel/cpu/centaur_64.c new file mode 100644 index 000000000000..a1625f5a1e78 --- /dev/null +++ b/trunk/arch/x86/kernel/cpu/centaur_64.c @@ -0,0 +1,37 @@ +#include +#include + +#include +#include + +#include "cpu.h" + +static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c) +{ + if (c->x86 == 0x6 && c->x86_model >= 0xf) + set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); + + set_cpu_cap(c, X86_FEATURE_SYSENTER32); +} + +static void __cpuinit init_centaur(struct cpuinfo_x86 *c) +{ + early_init_centaur(c); + + if (c->x86 == 0x6 && c->x86_model >= 0xf) { + c->x86_cache_alignment = c->x86_clflush_size * 2; + set_cpu_cap(c, X86_FEATURE_REP_GOOD); + } + set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); +} + +static struct cpu_dev centaur_cpu_dev __cpuinitdata = { + .c_vendor = "Centaur", + .c_ident = { "CentaurHauls" }, + .c_early_init = early_init_centaur, + .c_init = init_centaur, + .c_x86_vendor = X86_VENDOR_CENTAUR, +}; + +cpu_dev_register(centaur_cpu_dev); + diff --git a/trunk/arch/x86/kernel/cpu/common.c b/trunk/arch/x86/kernel/cpu/common.c index e2962cc1e27b..826d5c876278 100644 --- a/trunk/arch/x86/kernel/cpu/common.c +++ b/trunk/arch/x86/kernel/cpu/common.c @@ -1,52 +1,52 @@ +#include +#include +#include +#include #include -#include #include -#include #include -#include -#include -#include -#include -#include #include +#include +#include #include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include +#include +#include +#include +#include #include -#include -#include -#include #include -#include #include +#include +#include #include +#include +#include +#include #ifdef CONFIG_X86_LOCAL_APIC #include #endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "cpu.h" #ifdef CONFIG_X86_64 /* all of these masks are initialized in setup_cpu_local_masks() */ -cpumask_var_t cpu_initialized_mask; -cpumask_var_t cpu_callout_mask; cpumask_var_t cpu_callin_mask; +cpumask_var_t cpu_callout_mask; +cpumask_var_t cpu_initialized_mask; /* representing cpus for which sibling maps can be computed */ cpumask_var_t cpu_sibling_setup_mask; @@ -62,15 +62,15 @@ void __init setup_cpu_local_masks(void) #else /* CONFIG_X86_32 */ -cpumask_t cpu_sibling_setup_map; +cpumask_t cpu_callin_map; cpumask_t cpu_callout_map; cpumask_t cpu_initialized; -cpumask_t cpu_callin_map; +cpumask_t cpu_sibling_setup_map; #endif /* CONFIG_X86_32 */ -static const struct cpu_dev *this_cpu __cpuinitdata; +static struct cpu_dev *this_cpu __cpuinitdata; DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { #ifdef CONFIG_X86_64 @@ -79,48 +79,48 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { * IRET will check the segment types kkeil 2000/10/28 * Also sysret mandates a special GDT layout * - * TLS descriptors are currently at a different place compared to i386. + * The TLS descriptors are currently at a different place compared to i386. * Hopefully nobody expects them at a fixed place (Wine?) */ - [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } }, - [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } }, - [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } }, - [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } }, - [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } }, - [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } }, + [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } }, + [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } }, + [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } }, + [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } }, + [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } }, + [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } }, #else - [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } }, - [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } }, - [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } }, - [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } }, + [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } }, + [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } }, + [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } }, + [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } }, /* * Segments used for calling PnP BIOS have byte granularity. * They code segments and data segments have fixed 64k limits, * the transfer segment sizes are set at run time. */ /* 32-bit code */ - [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } }, + [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } }, /* 16-bit code */ - [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } }, + [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } }, /* 16-bit data */ - [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } }, + [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } }, /* 16-bit data */ - [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } }, + [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } }, /* 16-bit data */ - [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } }, + [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } }, /* * The APM segments have byte granularity and their bases * are set at run time. All have 64k limits. */ /* 32-bit code */ - [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } }, + [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } }, /* 16-bit code */ - [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } }, + [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } }, /* data */ - [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } }, + [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } }, - [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } }, - [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } }, + [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } }, + [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } }, GDT_STACK_CANARY_INIT #endif } }; @@ -164,17 +164,16 @@ static inline int flag_is_changeable_p(u32 flag) * the CPUID. Add "volatile" to not allow gcc to * optimize the subsequent calls to this function. */ - asm volatile ("pushfl \n\t" - "pushfl \n\t" - "popl %0 \n\t" - "movl %0, %1 \n\t" - "xorl %2, %0 \n\t" - "pushl %0 \n\t" - "popfl \n\t" - "pushfl \n\t" - "popl %0 \n\t" - "popfl \n\t" - + asm volatile ("pushfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "movl %0,%1\n\t" + "xorl %2,%0\n\t" + "pushl %0\n\t" + "popfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "popfl\n\t" : "=&r" (f1), "=&r" (f2) : "ir" (flag)); @@ -189,22 +188,18 @@ static int __cpuinit have_cpuid_p(void) static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c) { - unsigned long lo, hi; - - if (!cpu_has(c, X86_FEATURE_PN) || !disable_x86_serial_nr) - return; - - /* Disable processor serial number: */ - - rdmsr(MSR_IA32_BBL_CR_CTL, lo, hi); - lo |= 0x200000; - wrmsr(MSR_IA32_BBL_CR_CTL, lo, hi); - - printk(KERN_NOTICE "CPU serial number disabled.\n"); - clear_cpu_cap(c, X86_FEATURE_PN); - - /* Disabling the serial number may affect the cpuid level */ - c->cpuid_level = cpuid_eax(0); + if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr) { + /* Disable processor serial number */ + unsigned long lo, hi; + rdmsr(MSR_IA32_BBL_CR_CTL, lo, hi); + lo |= 0x200000; + wrmsr(MSR_IA32_BBL_CR_CTL, lo, hi); + printk(KERN_NOTICE "CPU serial number disabled.\n"); + clear_cpu_cap(c, X86_FEATURE_PN); + + /* Disabling the serial number may affect the cpuid level */ + c->cpuid_level = cpuid_eax(0); + } } static int __init x86_serial_nr_setup(char *s) @@ -237,7 +232,6 @@ struct cpuid_dependent_feature { u32 feature; u32 level; }; - static const struct cpuid_dependent_feature __cpuinitconst cpuid_dependent_features[] = { { X86_FEATURE_MWAIT, 0x00000005 }, @@ -249,11 +243,7 @@ cpuid_dependent_features[] = { static void __cpuinit filter_cpuid_features(struct cpuinfo_x86 *c, bool warn) { const struct cpuid_dependent_feature *df; - for (df = cpuid_dependent_features; df->feature; df++) { - - if (!cpu_has(c, df->feature)) - continue; /* * Note: cpuid_level is set to -1 if unavailable, but * extended_extended_level is set to 0 if unavailable @@ -261,32 +251,32 @@ static void __cpuinit filter_cpuid_features(struct cpuinfo_x86 *c, bool warn) * when signed; hence the weird messing around with * signs here... */ - if (!((s32)df->level < 0 ? + if (cpu_has(c, df->feature) && + ((s32)df->level < 0 ? (u32)df->level > (u32)c->extended_cpuid_level : - (s32)df->level > (s32)c->cpuid_level)) - continue; - - clear_cpu_cap(c, df->feature); - if (!warn) - continue; - - printk(KERN_WARNING - "CPU: CPU feature %s disabled, no CPUID level 0x%x\n", - x86_cap_flags[df->feature], df->level); + (s32)df->level > (s32)c->cpuid_level)) { + clear_cpu_cap(c, df->feature); + if (warn) + printk(KERN_WARNING + "CPU: CPU feature %s disabled " + "due to lack of CPUID level 0x%x\n", + x86_cap_flags[df->feature], + df->level); + } } } /* * Naming convention should be: [()] * This table only is used unless init_() below doesn't set it; - * in particular, if CPUID levels 0x80000002..4 are supported, this - * isn't used + * in particular, if CPUID levels 0x80000002..4 are supported, this isn't used + * */ /* Look up CPU names by table lookup. */ -static const char *__cpuinit table_lookup_model(struct cpuinfo_x86 *c) +static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c) { - const struct cpu_model_info *info; + struct cpu_model_info *info; if (c->x86_model >= 16) return NULL; /* Range check */ @@ -317,10 +307,8 @@ void load_percpu_segment(int cpu) load_stack_canary_segment(); } -/* - * Current gdt points %fs at the "master" per-cpu area: after this, - * it's on the real one. - */ +/* Current gdt points %fs at the "master" per-cpu area: after this, + * it's on the real one. */ void switch_to_new_gdt(int cpu) { struct desc_ptr gdt_descr; @@ -333,7 +321,7 @@ void switch_to_new_gdt(int cpu) load_percpu_segment(cpu); } -static const struct cpu_dev *__cpuinitdata cpu_devs[X86_VENDOR_NUM] = {}; +static struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {}; static void __cpuinit default_init(struct cpuinfo_x86 *c) { @@ -352,7 +340,7 @@ static void __cpuinit default_init(struct cpuinfo_x86 *c) #endif } -static const struct cpu_dev __cpuinitconst default_cpu = { +static struct cpu_dev __cpuinitdata default_cpu = { .c_init = default_init, .c_vendor = "Unknown", .c_x86_vendor = X86_VENDOR_UNKNOWN, @@ -366,24 +354,22 @@ static void __cpuinit get_model_name(struct cpuinfo_x86 *c) if (c->extended_cpuid_level < 0x80000004) return; - v = (unsigned int *)c->x86_model_id; + v = (unsigned int *) c->x86_model_id; cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]); cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]); cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]); c->x86_model_id[48] = 0; - /* - * Intel chips right-justify this string for some dumb reason; - * undo that brain damage: - */ + /* Intel chips right-justify this string for some dumb reason; + undo that brain damage */ p = q = &c->x86_model_id[0]; while (*p == ' ') - p++; + p++; if (p != q) { - while (*p) - *q++ = *p++; - while (q <= &c->x86_model_id[48]) - *q++ = '\0'; /* Zero-pad the rest */ + while (*p) + *q++ = *p++; + while (q <= &c->x86_model_id[48]) + *q++ = '\0'; /* Zero-pad the rest */ } } @@ -452,30 +438,27 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) if (smp_num_siblings == 1) { printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); - goto out; - } - - if (smp_num_siblings <= 1) - goto out; + } else if (smp_num_siblings > 1) { - if (smp_num_siblings > nr_cpu_ids) { - pr_warning("CPU: Unsupported number of siblings %d", - smp_num_siblings); - smp_num_siblings = 1; - return; - } + if (smp_num_siblings > nr_cpu_ids) { + printk(KERN_WARNING "CPU: Unsupported number of siblings %d", + smp_num_siblings); + smp_num_siblings = 1; + return; + } - index_msb = get_count_order(smp_num_siblings); - c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, index_msb); + index_msb = get_count_order(smp_num_siblings); + c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, index_msb); - smp_num_siblings = smp_num_siblings / c->x86_max_cores; + smp_num_siblings = smp_num_siblings / c->x86_max_cores; - index_msb = get_count_order(smp_num_siblings); + index_msb = get_count_order(smp_num_siblings); - core_bits = get_count_order(c->x86_max_cores); + core_bits = get_count_order(c->x86_max_cores); - c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, index_msb) & - ((1 << core_bits) - 1); + c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, index_msb) & + ((1 << core_bits) - 1); + } out: if ((c->x86_max_cores * smp_num_siblings) > 1) { @@ -490,8 +473,8 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c) { char *v = c->x86_vendor_id; - static int printed; int i; + static int printed; for (i = 0; i < X86_VENDOR_NUM; i++) { if (!cpu_devs[i]) @@ -500,7 +483,6 @@ static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c) if (!strcmp(v, cpu_devs[i]->c_ident[0]) || (cpu_devs[i]->c_ident[1] && !strcmp(v, cpu_devs[i]->c_ident[1]))) { - this_cpu = cpu_devs[i]; c->x86_vendor = this_cpu->c_x86_vendor; return; @@ -509,9 +491,7 @@ static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c) if (!printed) { printed++; - printk(KERN_ERR - "CPU: vendor_id '%s' unknown, using generic init.\n", v); - + printk(KERN_ERR "CPU: vendor_id '%s' unknown, using generic init.\n", v); printk(KERN_ERR "CPU: Your system may be unstable.\n"); } @@ -531,17 +511,14 @@ void __cpuinit cpu_detect(struct cpuinfo_x86 *c) /* Intel-defined flags: level 0x00000001 */ if (c->cpuid_level >= 0x00000001) { u32 junk, tfms, cap0, misc; - cpuid(0x00000001, &tfms, &misc, &junk, &cap0); c->x86 = (tfms >> 8) & 0xf; c->x86_model = (tfms >> 4) & 0xf; c->x86_mask = tfms & 0xf; - if (c->x86 == 0xf) c->x86 += (tfms >> 20) & 0xff; if (c->x86 >= 0x6) c->x86_model += ((tfms >> 16) & 0xf) << 4; - if (cap0 & (1<<19)) { c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; c->x86_cache_alignment = c->x86_clflush_size; @@ -557,7 +534,6 @@ static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) /* Intel-defined flags: level 0x00000001 */ if (c->cpuid_level >= 0x00000001) { u32 capability, excap; - cpuid(0x00000001, &tfms, &ebx, &excap, &capability); c->x86_capability[0] = capability; c->x86_capability[4] = excap; @@ -566,7 +542,6 @@ static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) /* AMD-defined flags: level 0x80000001 */ xlvl = cpuid_eax(0x80000000); c->extended_cpuid_level = xlvl; - if ((xlvl & 0xffff0000) == 0x80000000) { if (xlvl >= 0x80000001) { c->x86_capability[1] = cpuid_edx(0x80000001); @@ -574,15 +549,13 @@ static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) } } +#ifdef CONFIG_X86_64 if (c->extended_cpuid_level >= 0x80000008) { u32 eax = cpuid_eax(0x80000008); c->x86_virt_bits = (eax >> 8) & 0xff; c->x86_phys_bits = eax & 0xff; } -#ifdef CONFIG_X86_32 - else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36)) - c->x86_phys_bits = 36; #endif if (c->extended_cpuid_level >= 0x80000007) @@ -629,12 +602,8 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) { #ifdef CONFIG_X86_64 c->x86_clflush_size = 64; - c->x86_phys_bits = 36; - c->x86_virt_bits = 48; #else c->x86_clflush_size = 32; - c->x86_phys_bits = 32; - c->x86_virt_bits = 32; #endif c->x86_cache_alignment = c->x86_clflush_size; @@ -665,12 +634,12 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) void __init early_cpu_init(void) { - const struct cpu_dev *const *cdev; + struct cpu_dev **cdev; int count = 0; - printk(KERN_INFO "KERNEL supported cpus:\n"); + printk("KERNEL supported cpus:\n"); for (cdev = __x86_cpu_dev_start; cdev < __x86_cpu_dev_end; cdev++) { - const struct cpu_dev *cpudev = *cdev; + struct cpu_dev *cpudev = *cdev; unsigned int j; if (count >= X86_VENDOR_NUM) @@ -681,7 +650,7 @@ void __init early_cpu_init(void) for (j = 0; j < 2; j++) { if (!cpudev->c_ident[j]) continue; - printk(KERN_INFO " %s %s\n", cpudev->c_vendor, + printk(" %s %s\n", cpudev->c_vendor, cpudev->c_ident[j]); } } @@ -757,13 +726,9 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) c->x86_coreid_bits = 0; #ifdef CONFIG_X86_64 c->x86_clflush_size = 64; - c->x86_phys_bits = 36; - c->x86_virt_bits = 48; #else c->cpuid_level = -1; /* CPUID not detected */ c->x86_clflush_size = 32; - c->x86_phys_bits = 32; - c->x86_virt_bits = 32; #endif c->x86_cache_alignment = c->x86_clflush_size; memset(&c->x86_capability, 0, sizeof c->x86_capability); @@ -794,8 +759,8 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) squash_the_stupid_serial_number(c); /* - * The vendor-specific functions might have changed features. - * Now we do "generic changes." + * The vendor-specific functions might have changed features. Now + * we do "generic changes." */ /* Filter out anything that depends on CPUID levels we don't have */ @@ -803,7 +768,7 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) /* If the model name is still unset, do table lookup. */ if (!c->x86_model_id[0]) { - const char *p; + char *p; p = table_lookup_model(c); if (p) strcpy(c->x86_model_id, p); @@ -878,11 +843,11 @@ void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) } struct msr_range { - unsigned min; - unsigned max; + unsigned min; + unsigned max; }; -static const struct msr_range msr_range_array[] __cpuinitconst = { +static struct msr_range msr_range_array[] __cpuinitdata = { { 0x00000000, 0x00000418}, { 0xc0000000, 0xc000040b}, { 0xc0010000, 0xc0010142}, @@ -891,15 +856,14 @@ static const struct msr_range msr_range_array[] __cpuinitconst = { static void __cpuinit print_cpu_msr(void) { - unsigned index_min, index_max; unsigned index; u64 val; int i; + unsigned index_min, index_max; for (i = 0; i < ARRAY_SIZE(msr_range_array); i++) { index_min = msr_range_array[i].min; index_max = msr_range_array[i].max; - for (index = index_min; index < index_max; index++) { if (rdmsrl_amd_safe(index, &val)) continue; @@ -909,7 +873,6 @@ static void __cpuinit print_cpu_msr(void) } static int show_msr __cpuinitdata; - static __init int setup_show_msr(char *arg) { int num; @@ -931,14 +894,12 @@ __setup("noclflush", setup_noclflush); void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) { - const char *vendor = NULL; + char *vendor = NULL; - if (c->x86_vendor < X86_VENDOR_NUM) { + if (c->x86_vendor < X86_VENDOR_NUM) vendor = this_cpu->c_vendor; - } else { - if (c->cpuid_level >= 0) - vendor = c->x86_vendor_id; - } + else if (c->cpuid_level >= 0) + vendor = c->x86_vendor_id; if (vendor && !strstr(c->x86_model_id, vendor)) printk(KERN_CONT "%s ", vendor); @@ -965,12 +926,10 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) static __init int setup_disablecpuid(char *arg) { int bit; - if (get_option(&arg, &bit) && bit < NCAPINTS*32) setup_clear_cpu_cap(bit); else return 0; - return 1; } __setup("clearcpuid=", setup_disablecpuid); @@ -980,7 +939,6 @@ struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; DEFINE_PER_CPU_FIRST(union irq_stack_union, irq_stack_union) __aligned(PAGE_SIZE); - DEFINE_PER_CPU(char *, irq_stack_ptr) = init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64; @@ -990,21 +948,12 @@ EXPORT_PER_CPU_SYMBOL(kernel_stack); DEFINE_PER_CPU(unsigned int, irq_count) = -1; -/* - * Special IST stacks which the CPU switches to when it calls - * an IST-marked descriptor entry. Up to 7 stacks (hardware - * limit), all of them are 4K, except the debug stack which - * is 8K. - */ -static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = { - [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, - [DEBUG_STACK - 1] = DEBUG_STKSZ -}; - static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]) __aligned(PAGE_SIZE); +extern asmlinkage void ignore_sysret(void); + /* May not be marked __init: used by software suspend */ void syscall_init(void) { @@ -1034,7 +983,7 @@ unsigned long kernel_eflags; */ DEFINE_PER_CPU(struct orig_ist, orig_ist); -#else /* CONFIG_X86_64 */ +#else /* x86_64 */ #ifdef CONFIG_CC_STACKPROTECTOR DEFINE_PER_CPU(unsigned long, stack_canary); @@ -1046,26 +995,9 @@ struct pt_regs * __cpuinit idle_regs(struct pt_regs *regs) memset(regs, 0, sizeof(struct pt_regs)); regs->fs = __KERNEL_PERCPU; regs->gs = __KERNEL_STACK_CANARY; - return regs; } -#endif /* CONFIG_X86_64 */ - -/* - * Clear all 6 debug registers: - */ -static void clear_all_debug_regs(void) -{ - int i; - - for (i = 0; i < 8; i++) { - /* Ignore db4, db5 */ - if ((i == 4) || (i == 5)) - continue; - - set_debugreg(0, i); - } -} +#endif /* x86_64 */ /* * cpu_init() initializes state that is per-CPU. Some data is already @@ -1075,20 +1007,15 @@ static void clear_all_debug_regs(void) * A lot of state is already set up in PDA init for 64 bit */ #ifdef CONFIG_X86_64 - void __cpuinit cpu_init(void) { - struct orig_ist *orig_ist; - struct task_struct *me; - struct tss_struct *t; + int cpu = stack_smp_processor_id(); + struct tss_struct *t = &per_cpu(init_tss, cpu); + struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu); unsigned long v; - int cpu; + struct task_struct *me; int i; - cpu = stack_smp_processor_id(); - t = &per_cpu(init_tss, cpu); - orig_ist = &per_cpu(orig_ist, cpu); - #ifdef CONFIG_NUMA if (cpu != 0 && percpu_read(node_number) == 0 && cpu_to_node(cpu) != NUMA_NO_NODE) @@ -1129,17 +1056,19 @@ void __cpuinit cpu_init(void) * set up and load the per-CPU TSS */ if (!orig_ist->ist[0]) { + static const unsigned int sizes[N_EXCEPTION_STACKS] = { + [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, + [DEBUG_STACK - 1] = DEBUG_STKSZ + }; char *estacks = per_cpu(exception_stacks, cpu); - for (v = 0; v < N_EXCEPTION_STACKS; v++) { - estacks += exception_stack_sizes[v]; + estacks += sizes[v]; orig_ist->ist[v] = t->x86_tss.ist[v] = (unsigned long)estacks; } } t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap); - /* * <= is required because the CPU will access up to * 8 bits beyond the end of the IO permission bitmap. @@ -1149,7 +1078,8 @@ void __cpuinit cpu_init(void) atomic_inc(&init_mm.mm_count); me->active_mm = &init_mm; - BUG_ON(me->mm); + if (me->mm) + BUG(); enter_lazy_tlb(&init_mm, me); load_sp0(t, ¤t->thread); @@ -1168,7 +1098,17 @@ void __cpuinit cpu_init(void) arch_kgdb_ops.correct_hw_break(); else #endif - clear_all_debug_regs(); + { + /* + * Clear all 6 debug registers: + */ + set_debugreg(0UL, 0); + set_debugreg(0UL, 1); + set_debugreg(0UL, 2); + set_debugreg(0UL, 3); + set_debugreg(0UL, 6); + set_debugreg(0UL, 7); + } fpu_init(); @@ -1189,8 +1129,7 @@ void __cpuinit cpu_init(void) if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) { printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); - for (;;) - local_irq_enable(); + for (;;) local_irq_enable(); } printk(KERN_INFO "Initializing CPU#%d\n", cpu); @@ -1206,7 +1145,8 @@ void __cpuinit cpu_init(void) */ atomic_inc(&init_mm.mm_count); curr->active_mm = &init_mm; - BUG_ON(curr->mm); + if (curr->mm) + BUG(); enter_lazy_tlb(&init_mm, curr); load_sp0(t, thread); @@ -1219,7 +1159,13 @@ void __cpuinit cpu_init(void) __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss); #endif - clear_all_debug_regs(); + /* Clear all 6 debug registers: */ + set_debugreg(0, 0); + set_debugreg(0, 1); + set_debugreg(0, 2); + set_debugreg(0, 3); + set_debugreg(0, 6); + set_debugreg(0, 7); /* * Force FPU initialization: @@ -1239,4 +1185,6 @@ void __cpuinit cpu_init(void) xsave_init(); } + + #endif diff --git a/trunk/arch/x86/kernel/cpu/cpu.h b/trunk/arch/x86/kernel/cpu/cpu.h index 6de9a908e400..de4094a39210 100644 --- a/trunk/arch/x86/kernel/cpu/cpu.h +++ b/trunk/arch/x86/kernel/cpu/cpu.h @@ -3,34 +3,33 @@ #define ARCH_X86_CPU_H struct cpu_model_info { - int vendor; - int family; - const char *model_names[16]; + int vendor; + int family; + char *model_names[16]; }; /* attempt to consolidate cpu attributes */ struct cpu_dev { - const char *c_vendor; + char * c_vendor; /* some have two possibilities for cpuid string */ - const char *c_ident[2]; + char * c_ident[2]; struct cpu_model_info c_models[4]; - void (*c_early_init)(struct cpuinfo_x86 *); - void (*c_init)(struct cpuinfo_x86 *); - void (*c_identify)(struct cpuinfo_x86 *); - unsigned int (*c_size_cache)(struct cpuinfo_x86 *, unsigned int); - int c_x86_vendor; + void (*c_early_init)(struct cpuinfo_x86 *c); + void (*c_init)(struct cpuinfo_x86 * c); + void (*c_identify)(struct cpuinfo_x86 * c); + unsigned int (*c_size_cache)(struct cpuinfo_x86 * c, unsigned int size); + int c_x86_vendor; }; #define cpu_dev_register(cpu_devX) \ - static const struct cpu_dev *const __cpu_dev_##cpu_devX __used \ + static struct cpu_dev *__cpu_dev_##cpu_devX __used \ __attribute__((__section__(".x86_cpu_dev.init"))) = \ &cpu_devX; -extern const struct cpu_dev *const __x86_cpu_dev_start[], - *const __x86_cpu_dev_end[]; +extern struct cpu_dev *__x86_cpu_dev_start[], *__x86_cpu_dev_end[]; extern void display_cacheinfo(struct cpuinfo_x86 *c); diff --git a/trunk/arch/x86/kernel/cpu/cpu_debug.c b/trunk/arch/x86/kernel/cpu/cpu_debug.c deleted file mode 100755 index 46e29ab96c6a..000000000000 --- a/trunk/arch/x86/kernel/cpu/cpu_debug.c +++ /dev/null @@ -1,901 +0,0 @@ -/* - * CPU x86 architecture debug code - * - * Copyright(C) 2009 Jaswinder Singh Rajput - * - * For licencing details see kernel-base/COPYING - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -static DEFINE_PER_CPU(struct cpu_cpuX_base, cpu_arr[CPU_REG_ALL_BIT]); -static DEFINE_PER_CPU(struct cpu_private *, priv_arr[MAX_CPU_FILES]); -static DEFINE_PER_CPU(unsigned, cpu_modelflag); -static DEFINE_PER_CPU(int, cpu_priv_count); -static DEFINE_PER_CPU(unsigned, cpu_model); - -static DEFINE_MUTEX(cpu_debug_lock); - -static struct dentry *cpu_debugfs_dir; - -static struct cpu_debug_base cpu_base[] = { - { "mc", CPU_MC, 0 }, - { "monitor", CPU_MONITOR, 0 }, - { "time", CPU_TIME, 0 }, - { "pmc", CPU_PMC, 1 }, - { "platform", CPU_PLATFORM, 0 }, - { "apic", CPU_APIC, 0 }, - { "poweron", CPU_POWERON, 0 }, - { "control", CPU_CONTROL, 0 }, - { "features", CPU_FEATURES, 0 }, - { "lastbranch", CPU_LBRANCH, 0 }, - { "bios", CPU_BIOS, 0 }, - { "freq", CPU_FREQ, 0 }, - { "mtrr", CPU_MTRR, 0 }, - { "perf", CPU_PERF, 0 }, - { "cache", CPU_CACHE, 0 }, - { "sysenter", CPU_SYSENTER, 0 }, - { "therm", CPU_THERM, 0 }, - { "misc", CPU_MISC, 0 }, - { "debug", CPU_DEBUG, 0 }, - { "pat", CPU_PAT, 0 }, - { "vmx", CPU_VMX, 0 }, - { "call", CPU_CALL, 0 }, - { "base", CPU_BASE, 0 }, - { "ver", CPU_VER, 0 }, - { "conf", CPU_CONF, 0 }, - { "smm", CPU_SMM, 0 }, - { "svm", CPU_SVM, 0 }, - { "osvm", CPU_OSVM, 0 }, - { "tss", CPU_TSS, 0 }, - { "cr", CPU_CR, 0 }, - { "dt", CPU_DT, 0 }, - { "registers", CPU_REG_ALL, 0 }, -}; - -static struct cpu_file_base cpu_file[] = { - { "index", CPU_REG_ALL, 0 }, - { "value", CPU_REG_ALL, 1 }, -}; - -/* Intel Registers Range */ -static struct cpu_debug_range cpu_intel_range[] = { - { 0x00000000, 0x00000001, CPU_MC, CPU_INTEL_ALL }, - { 0x00000006, 0x00000007, CPU_MONITOR, CPU_CX_AT_XE }, - { 0x00000010, 0x00000010, CPU_TIME, CPU_INTEL_ALL }, - { 0x00000011, 0x00000013, CPU_PMC, CPU_INTEL_PENTIUM }, - { 0x00000017, 0x00000017, CPU_PLATFORM, CPU_PX_CX_AT_XE }, - { 0x0000001B, 0x0000001B, CPU_APIC, CPU_P6_CX_AT_XE }, - - { 0x0000002A, 0x0000002A, CPU_POWERON, CPU_PX_CX_AT_XE }, - { 0x0000002B, 0x0000002B, CPU_POWERON, CPU_INTEL_XEON }, - { 0x0000002C, 0x0000002C, CPU_FREQ, CPU_INTEL_XEON }, - { 0x0000003A, 0x0000003A, CPU_CONTROL, CPU_CX_AT_XE }, - - { 0x00000040, 0x00000043, CPU_LBRANCH, CPU_PM_CX_AT_XE }, - { 0x00000044, 0x00000047, CPU_LBRANCH, CPU_PM_CO_AT }, - { 0x00000060, 0x00000063, CPU_LBRANCH, CPU_C2_AT }, - { 0x00000064, 0x00000067, CPU_LBRANCH, CPU_INTEL_ATOM }, - - { 0x00000079, 0x00000079, CPU_BIOS, CPU_P6_CX_AT_XE }, - { 0x00000088, 0x0000008A, CPU_CACHE, CPU_INTEL_P6 }, - { 0x0000008B, 0x0000008B, CPU_BIOS, CPU_P6_CX_AT_XE }, - { 0x0000009B, 0x0000009B, CPU_MONITOR, CPU_INTEL_XEON }, - - { 0x000000C1, 0x000000C2, CPU_PMC, CPU_P6_CX_AT }, - { 0x000000CD, 0x000000CD, CPU_FREQ, CPU_CX_AT }, - { 0x000000E7, 0x000000E8, CPU_PERF, CPU_CX_AT }, - { 0x000000FE, 0x000000FE, CPU_MTRR, CPU_P6_CX_XE }, - - { 0x00000116, 0x00000116, CPU_CACHE, CPU_INTEL_P6 }, - { 0x00000118, 0x00000118, CPU_CACHE, CPU_INTEL_P6 }, - { 0x00000119, 0x00000119, CPU_CACHE, CPU_INTEL_PX }, - { 0x0000011A, 0x0000011B, CPU_CACHE, CPU_INTEL_P6 }, - { 0x0000011E, 0x0000011E, CPU_CACHE, CPU_PX_CX_AT }, - - { 0x00000174, 0x00000176, CPU_SYSENTER, CPU_P6_CX_AT_XE }, - { 0x00000179, 0x0000017A, CPU_MC, CPU_PX_CX_AT_XE }, - { 0x0000017B, 0x0000017B, CPU_MC, CPU_P6_XE }, - { 0x00000186, 0x00000187, CPU_PMC, CPU_P6_CX_AT }, - { 0x00000198, 0x00000199, CPU_PERF, CPU_PM_CX_AT_XE }, - { 0x0000019A, 0x0000019A, CPU_TIME, CPU_PM_CX_AT_XE }, - { 0x0000019B, 0x0000019D, CPU_THERM, CPU_PM_CX_AT_XE }, - { 0x000001A0, 0x000001A0, CPU_MISC, CPU_PM_CX_AT_XE }, - - { 0x000001C9, 0x000001C9, CPU_LBRANCH, CPU_PM_CX_AT }, - { 0x000001D7, 0x000001D8, CPU_LBRANCH, CPU_INTEL_XEON }, - { 0x000001D9, 0x000001D9, CPU_DEBUG, CPU_CX_AT_XE }, - { 0x000001DA, 0x000001DA, CPU_LBRANCH, CPU_INTEL_XEON }, - { 0x000001DB, 0x000001DB, CPU_LBRANCH, CPU_P6_XE }, - { 0x000001DC, 0x000001DC, CPU_LBRANCH, CPU_INTEL_P6 }, - { 0x000001DD, 0x000001DE, CPU_LBRANCH, CPU_PX_CX_AT_XE }, - { 0x000001E0, 0x000001E0, CPU_LBRANCH, CPU_INTEL_P6 }, - - { 0x00000200, 0x0000020F, CPU_MTRR, CPU_P6_CX_XE }, - { 0x00000250, 0x00000250, CPU_MTRR, CPU_P6_CX_XE }, - { 0x00000258, 0x00000259, CPU_MTRR, CPU_P6_CX_XE }, - { 0x00000268, 0x0000026F, CPU_MTRR, CPU_P6_CX_XE }, - { 0x00000277, 0x00000277, CPU_PAT, CPU_C2_AT_XE }, - { 0x000002FF, 0x000002FF, CPU_MTRR, CPU_P6_CX_XE }, - - { 0x00000300, 0x00000308, CPU_PMC, CPU_INTEL_XEON }, - { 0x00000309, 0x0000030B, CPU_PMC, CPU_C2_AT_XE }, - { 0x0000030C, 0x00000311, CPU_PMC, CPU_INTEL_XEON }, - { 0x00000345, 0x00000345, CPU_PMC, CPU_C2_AT }, - { 0x00000360, 0x00000371, CPU_PMC, CPU_INTEL_XEON }, - { 0x0000038D, 0x00000390, CPU_PMC, CPU_C2_AT }, - { 0x000003A0, 0x000003BE, CPU_PMC, CPU_INTEL_XEON }, - { 0x000003C0, 0x000003CD, CPU_PMC, CPU_INTEL_XEON }, - { 0x000003E0, 0x000003E1, CPU_PMC, CPU_INTEL_XEON }, - { 0x000003F0, 0x000003F0, CPU_PMC, CPU_INTEL_XEON }, - { 0x000003F1, 0x000003F1, CPU_PMC, CPU_C2_AT_XE }, - { 0x000003F2, 0x000003F2, CPU_PMC, CPU_INTEL_XEON }, - - { 0x00000400, 0x00000402, CPU_MC, CPU_PM_CX_AT_XE }, - { 0x00000403, 0x00000403, CPU_MC, CPU_INTEL_XEON }, - { 0x00000404, 0x00000406, CPU_MC, CPU_PM_CX_AT_XE }, - { 0x00000407, 0x00000407, CPU_MC, CPU_INTEL_XEON }, - { 0x00000408, 0x0000040A, CPU_MC, CPU_PM_CX_AT_XE }, - { 0x0000040B, 0x0000040B, CPU_MC, CPU_INTEL_XEON }, - { 0x0000040C, 0x0000040E, CPU_MC, CPU_PM_CX_XE }, - { 0x0000040F, 0x0000040F, CPU_MC, CPU_INTEL_XEON }, - { 0x00000410, 0x00000412, CPU_MC, CPU_PM_CX_AT_XE }, - { 0x00000413, 0x00000417, CPU_MC, CPU_CX_AT_XE }, - { 0x00000480, 0x0000048B, CPU_VMX, CPU_CX_AT_XE }, - - { 0x00000600, 0x00000600, CPU_DEBUG, CPU_PM_CX_AT_XE }, - { 0x00000680, 0x0000068F, CPU_LBRANCH, CPU_INTEL_XEON }, - { 0x000006C0, 0x000006CF, CPU_LBRANCH, CPU_INTEL_XEON }, - - { 0x000107CC, 0x000107D3, CPU_PMC, CPU_INTEL_XEON_MP }, - - { 0xC0000080, 0xC0000080, CPU_FEATURES, CPU_INTEL_XEON }, - { 0xC0000081, 0xC0000082, CPU_CALL, CPU_INTEL_XEON }, - { 0xC0000084, 0xC0000084, CPU_CALL, CPU_INTEL_XEON }, - { 0xC0000100, 0xC0000102, CPU_BASE, CPU_INTEL_XEON }, -}; - -/* AMD Registers Range */ -static struct cpu_debug_range cpu_amd_range[] = { - { 0x00000000, 0x00000001, CPU_MC, CPU_K10_PLUS, }, - { 0x00000010, 0x00000010, CPU_TIME, CPU_K8_PLUS, }, - { 0x0000001B, 0x0000001B, CPU_APIC, CPU_K8_PLUS, }, - { 0x0000002A, 0x0000002A, CPU_POWERON, CPU_K7_PLUS }, - { 0x0000008B, 0x0000008B, CPU_VER, CPU_K8_PLUS }, - { 0x000000FE, 0x000000FE, CPU_MTRR, CPU_K8_PLUS, }, - - { 0x00000174, 0x00000176, CPU_SYSENTER, CPU_K8_PLUS, }, - { 0x00000179, 0x0000017B, CPU_MC, CPU_K8_PLUS, }, - { 0x000001D9, 0x000001D9, CPU_DEBUG, CPU_K8_PLUS, }, - { 0x000001DB, 0x000001DE, CPU_LBRANCH, CPU_K8_PLUS, }, - - { 0x00000200, 0x0000020F, CPU_MTRR, CPU_K8_PLUS, }, - { 0x00000250, 0x00000250, CPU_MTRR, CPU_K8_PLUS, }, - { 0x00000258, 0x00000259, CPU_MTRR, CPU_K8_PLUS, }, - { 0x00000268, 0x0000026F, CPU_MTRR, CPU_K8_PLUS, }, - { 0x00000277, 0x00000277, CPU_PAT, CPU_K8_PLUS, }, - { 0x000002FF, 0x000002FF, CPU_MTRR, CPU_K8_PLUS, }, - - { 0x00000400, 0x00000413, CPU_MC, CPU_K8_PLUS, }, - - { 0xC0000080, 0xC0000080, CPU_FEATURES, CPU_AMD_ALL, }, - { 0xC0000081, 0xC0000084, CPU_CALL, CPU_K8_PLUS, }, - { 0xC0000100, 0xC0000102, CPU_BASE, CPU_K8_PLUS, }, - { 0xC0000103, 0xC0000103, CPU_TIME, CPU_K10_PLUS, }, - - { 0xC0010000, 0xC0010007, CPU_PMC, CPU_K8_PLUS, }, - { 0xC0010010, 0xC0010010, CPU_CONF, CPU_K7_PLUS, }, - { 0xC0010015, 0xC0010015, CPU_CONF, CPU_K7_PLUS, }, - { 0xC0010016, 0xC001001A, CPU_MTRR, CPU_K8_PLUS, }, - { 0xC001001D, 0xC001001D, CPU_MTRR, CPU_K8_PLUS, }, - { 0xC001001F, 0xC001001F, CPU_CONF, CPU_K8_PLUS, }, - { 0xC0010030, 0xC0010035, CPU_BIOS, CPU_K8_PLUS, }, - { 0xC0010044, 0xC0010048, CPU_MC, CPU_K8_PLUS, }, - { 0xC0010050, 0xC0010056, CPU_SMM, CPU_K0F_PLUS, }, - { 0xC0010058, 0xC0010058, CPU_CONF, CPU_K10_PLUS, }, - { 0xC0010060, 0xC0010060, CPU_CACHE, CPU_AMD_11, }, - { 0xC0010061, 0xC0010068, CPU_SMM, CPU_K10_PLUS, }, - { 0xC0010069, 0xC001006B, CPU_SMM, CPU_AMD_11, }, - { 0xC0010070, 0xC0010071, CPU_SMM, CPU_K10_PLUS, }, - { 0xC0010111, 0xC0010113, CPU_SMM, CPU_K8_PLUS, }, - { 0xC0010114, 0xC0010118, CPU_SVM, CPU_K10_PLUS, }, - { 0xC0010140, 0xC0010141, CPU_OSVM, CPU_K10_PLUS, }, - { 0xC0011022, 0xC0011023, CPU_CONF, CPU_K10_PLUS, }, -}; - - -/* Intel */ -static int get_intel_modelflag(unsigned model) -{ - int flag; - - switch (model) { - case 0x0501: - case 0x0502: - case 0x0504: - flag = CPU_INTEL_PENTIUM; - break; - case 0x0601: - case 0x0603: - case 0x0605: - case 0x0607: - case 0x0608: - case 0x060A: - case 0x060B: - flag = CPU_INTEL_P6; - break; - case 0x0609: - case 0x060D: - flag = CPU_INTEL_PENTIUM_M; - break; - case 0x060E: - flag = CPU_INTEL_CORE; - break; - case 0x060F: - case 0x0617: - flag = CPU_INTEL_CORE2; - break; - case 0x061C: - flag = CPU_INTEL_ATOM; - break; - case 0x0F00: - case 0x0F01: - case 0x0F02: - case 0x0F03: - case 0x0F04: - flag = CPU_INTEL_XEON_P4; - break; - case 0x0F06: - flag = CPU_INTEL_XEON_MP; - break; - default: - flag = CPU_NONE; - break; - } - - return flag; -} - -/* AMD */ -static int get_amd_modelflag(unsigned model) -{ - int flag; - - switch (model >> 8) { - case 0x6: - flag = CPU_AMD_K6; - break; - case 0x7: - flag = CPU_AMD_K7; - break; - case 0x8: - flag = CPU_AMD_K8; - break; - case 0xf: - flag = CPU_AMD_0F; - break; - case 0x10: - flag = CPU_AMD_10; - break; - case 0x11: - flag = CPU_AMD_11; - break; - default: - flag = CPU_NONE; - break; - } - - return flag; -} - -static int get_cpu_modelflag(unsigned cpu) -{ - int flag; - - flag = per_cpu(cpu_model, cpu); - - switch (flag >> 16) { - case X86_VENDOR_INTEL: - flag = get_intel_modelflag(flag); - break; - case X86_VENDOR_AMD: - flag = get_amd_modelflag(flag & 0xffff); - break; - default: - flag = CPU_NONE; - break; - } - - return flag; -} - -static int get_cpu_range_count(unsigned cpu) -{ - int index; - - switch (per_cpu(cpu_model, cpu) >> 16) { - case X86_VENDOR_INTEL: - index = ARRAY_SIZE(cpu_intel_range); - break; - case X86_VENDOR_AMD: - index = ARRAY_SIZE(cpu_amd_range); - break; - default: - index = 0; - break; - } - - return index; -} - -static int is_typeflag_valid(unsigned cpu, unsigned flag) -{ - unsigned vendor, modelflag; - int i, index; - - /* Standard Registers should be always valid */ - if (flag >= CPU_TSS) - return 1; - - modelflag = per_cpu(cpu_modelflag, cpu); - vendor = per_cpu(cpu_model, cpu) >> 16; - index = get_cpu_range_count(cpu); - - for (i = 0; i < index; i++) { - switch (vendor) { - case X86_VENDOR_INTEL: - if ((cpu_intel_range[i].model & modelflag) && - (cpu_intel_range[i].flag & flag)) - return 1; - break; - case X86_VENDOR_AMD: - if ((cpu_amd_range[i].model & modelflag) && - (cpu_amd_range[i].flag & flag)) - return 1; - break; - } - } - - /* Invalid */ - return 0; -} - -static unsigned get_cpu_range(unsigned cpu, unsigned *min, unsigned *max, - int index, unsigned flag) -{ - unsigned modelflag; - - modelflag = per_cpu(cpu_modelflag, cpu); - *max = 0; - switch (per_cpu(cpu_model, cpu) >> 16) { - case X86_VENDOR_INTEL: - if ((cpu_intel_range[index].model & modelflag) && - (cpu_intel_range[index].flag & flag)) { - *min = cpu_intel_range[index].min; - *max = cpu_intel_range[index].max; - } - break; - case X86_VENDOR_AMD: - if ((cpu_amd_range[index].model & modelflag) && - (cpu_amd_range[index].flag & flag)) { - *min = cpu_amd_range[index].min; - *max = cpu_amd_range[index].max; - } - break; - } - - return *max; -} - -/* This function can also be called with seq = NULL for printk */ -static void print_cpu_data(struct seq_file *seq, unsigned type, - u32 low, u32 high) -{ - struct cpu_private *priv; - u64 val = high; - - if (seq) { - priv = seq->private; - if (priv->file) { - val = (val << 32) | low; - seq_printf(seq, "0x%llx\n", val); - } else - seq_printf(seq, " %08x: %08x_%08x\n", - type, high, low); - } else - printk(KERN_INFO " %08x: %08x_%08x\n", type, high, low); -} - -/* This function can also be called with seq = NULL for printk */ -static void print_msr(struct seq_file *seq, unsigned cpu, unsigned flag) -{ - unsigned msr, msr_min, msr_max; - struct cpu_private *priv; - u32 low, high; - int i, range; - - if (seq) { - priv = seq->private; - if (priv->file) { - if (!rdmsr_safe_on_cpu(priv->cpu, priv->reg, - &low, &high)) - print_cpu_data(seq, priv->reg, low, high); - return; - } - } - - range = get_cpu_range_count(cpu); - - for (i = 0; i < range; i++) { - if (!get_cpu_range(cpu, &msr_min, &msr_max, i, flag)) - continue; - - for (msr = msr_min; msr <= msr_max; msr++) { - if (rdmsr_safe_on_cpu(cpu, msr, &low, &high)) - continue; - print_cpu_data(seq, msr, low, high); - } - } -} - -static void print_tss(void *arg) -{ - struct pt_regs *regs = task_pt_regs(current); - struct seq_file *seq = arg; - unsigned int seg; - - seq_printf(seq, " RAX\t: %016lx\n", regs->ax); - seq_printf(seq, " RBX\t: %016lx\n", regs->bx); - seq_printf(seq, " RCX\t: %016lx\n", regs->cx); - seq_printf(seq, " RDX\t: %016lx\n", regs->dx); - - seq_printf(seq, " RSI\t: %016lx\n", regs->si); - seq_printf(seq, " RDI\t: %016lx\n", regs->di); - seq_printf(seq, " RBP\t: %016lx\n", regs->bp); - seq_printf(seq, " ESP\t: %016lx\n", regs->sp); - -#ifdef CONFIG_X86_64 - seq_printf(seq, " R08\t: %016lx\n", regs->r8); - seq_printf(seq, " R09\t: %016lx\n", regs->r9); - seq_printf(seq, " R10\t: %016lx\n", regs->r10); - seq_printf(seq, " R11\t: %016lx\n", regs->r11); - seq_printf(seq, " R12\t: %016lx\n", regs->r12); - seq_printf(seq, " R13\t: %016lx\n", regs->r13); - seq_printf(seq, " R14\t: %016lx\n", regs->r14); - seq_printf(seq, " R15\t: %016lx\n", regs->r15); -#endif - - asm("movl %%cs,%0" : "=r" (seg)); - seq_printf(seq, " CS\t: %04x\n", seg); - asm("movl %%ds,%0" : "=r" (seg)); - seq_printf(seq, " DS\t: %04x\n", seg); - seq_printf(seq, " SS\t: %04lx\n", regs->ss & 0xffff); - asm("movl %%es,%0" : "=r" (seg)); - seq_printf(seq, " ES\t: %04x\n", seg); - asm("movl %%fs,%0" : "=r" (seg)); - seq_printf(seq, " FS\t: %04x\n", seg); - asm("movl %%gs,%0" : "=r" (seg)); - seq_printf(seq, " GS\t: %04x\n", seg); - - seq_printf(seq, " EFLAGS\t: %016lx\n", regs->flags); - - seq_printf(seq, " EIP\t: %016lx\n", regs->ip); -} - -static void print_cr(void *arg) -{ - struct seq_file *seq = arg; - - seq_printf(seq, " cr0\t: %016lx\n", read_cr0()); - seq_printf(seq, " cr2\t: %016lx\n", read_cr2()); - seq_printf(seq, " cr3\t: %016lx\n", read_cr3()); - seq_printf(seq, " cr4\t: %016lx\n", read_cr4_safe()); -#ifdef CONFIG_X86_64 - seq_printf(seq, " cr8\t: %016lx\n", read_cr8()); -#endif -} - -static void print_desc_ptr(char *str, struct seq_file *seq, struct desc_ptr dt) -{ - seq_printf(seq, " %s\t: %016llx\n", str, (u64)(dt.address | dt.size)); -} - -static void print_dt(void *seq) -{ - struct desc_ptr dt; - unsigned long ldt; - - /* IDT */ - store_idt((struct desc_ptr *)&dt); - print_desc_ptr("IDT", seq, dt); - - /* GDT */ - store_gdt((struct desc_ptr *)&dt); - print_desc_ptr("GDT", seq, dt); - - /* LDT */ - store_ldt(ldt); - seq_printf(seq, " LDT\t: %016lx\n", ldt); - - /* TR */ - store_tr(ldt); - seq_printf(seq, " TR\t: %016lx\n", ldt); -} - -static void print_dr(void *arg) -{ - struct seq_file *seq = arg; - unsigned long dr; - int i; - - for (i = 0; i < 8; i++) { - /* Ignore db4, db5 */ - if ((i == 4) || (i == 5)) - continue; - get_debugreg(dr, i); - seq_printf(seq, " dr%d\t: %016lx\n", i, dr); - } - - seq_printf(seq, "\n MSR\t:\n"); -} - -static void print_apic(void *arg) -{ - struct seq_file *seq = arg; - -#ifdef CONFIG_X86_LOCAL_APIC - seq_printf(seq, " LAPIC\t:\n"); - seq_printf(seq, " ID\t\t: %08x\n", apic_read(APIC_ID) >> 24); - seq_printf(seq, " LVR\t\t: %08x\n", apic_read(APIC_LVR)); - seq_printf(seq, " TASKPRI\t: %08x\n", apic_read(APIC_TASKPRI)); - seq_printf(seq, " ARBPRI\t\t: %08x\n", apic_read(APIC_ARBPRI)); - seq_printf(seq, " PROCPRI\t: %08x\n", apic_read(APIC_PROCPRI)); - seq_printf(seq, " LDR\t\t: %08x\n", apic_read(APIC_LDR)); - seq_printf(seq, " DFR\t\t: %08x\n", apic_read(APIC_DFR)); - seq_printf(seq, " SPIV\t\t: %08x\n", apic_read(APIC_SPIV)); - seq_printf(seq, " ISR\t\t: %08x\n", apic_read(APIC_ISR)); - seq_printf(seq, " ESR\t\t: %08x\n", apic_read(APIC_ESR)); - seq_printf(seq, " ICR\t\t: %08x\n", apic_read(APIC_ICR)); - seq_printf(seq, " ICR2\t\t: %08x\n", apic_read(APIC_ICR2)); - seq_printf(seq, " LVTT\t\t: %08x\n", apic_read(APIC_LVTT)); - seq_printf(seq, " LVTTHMR\t: %08x\n", apic_read(APIC_LVTTHMR)); - seq_printf(seq, " LVTPC\t\t: %08x\n", apic_read(APIC_LVTPC)); - seq_printf(seq, " LVT0\t\t: %08x\n", apic_read(APIC_LVT0)); - seq_printf(seq, " LVT1\t\t: %08x\n", apic_read(APIC_LVT1)); - seq_printf(seq, " LVTERR\t\t: %08x\n", apic_read(APIC_LVTERR)); - seq_printf(seq, " TMICT\t\t: %08x\n", apic_read(APIC_TMICT)); - seq_printf(seq, " TMCCT\t\t: %08x\n", apic_read(APIC_TMCCT)); - seq_printf(seq, " TDCR\t\t: %08x\n", apic_read(APIC_TDCR)); -#endif /* CONFIG_X86_LOCAL_APIC */ - - seq_printf(seq, "\n MSR\t:\n"); -} - -static int cpu_seq_show(struct seq_file *seq, void *v) -{ - struct cpu_private *priv = seq->private; - - if (priv == NULL) - return -EINVAL; - - switch (cpu_base[priv->type].flag) { - case CPU_TSS: - smp_call_function_single(priv->cpu, print_tss, seq, 1); - break; - case CPU_CR: - smp_call_function_single(priv->cpu, print_cr, seq, 1); - break; - case CPU_DT: - smp_call_function_single(priv->cpu, print_dt, seq, 1); - break; - case CPU_DEBUG: - if (priv->file == CPU_INDEX_BIT) - smp_call_function_single(priv->cpu, print_dr, seq, 1); - print_msr(seq, priv->cpu, cpu_base[priv->type].flag); - break; - case CPU_APIC: - if (priv->file == CPU_INDEX_BIT) - smp_call_function_single(priv->cpu, print_apic, seq, 1); - print_msr(seq, priv->cpu, cpu_base[priv->type].flag); - break; - - default: - print_msr(seq, priv->cpu, cpu_base[priv->type].flag); - break; - } - seq_printf(seq, "\n"); - - return 0; -} - -static void *cpu_seq_start(struct seq_file *seq, loff_t *pos) -{ - if (*pos == 0) /* One time is enough ;-) */ - return seq; - - return NULL; -} - -static void *cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - (*pos)++; - - return cpu_seq_start(seq, pos); -} - -static void cpu_seq_stop(struct seq_file *seq, void *v) -{ -} - -static const struct seq_operations cpu_seq_ops = { - .start = cpu_seq_start, - .next = cpu_seq_next, - .stop = cpu_seq_stop, - .show = cpu_seq_show, -}; - -static int cpu_seq_open(struct inode *inode, struct file *file) -{ - struct cpu_private *priv = inode->i_private; - struct seq_file *seq; - int err; - - err = seq_open(file, &cpu_seq_ops); - if (!err) { - seq = file->private_data; - seq->private = priv; - } - - return err; -} - -static int write_msr(struct cpu_private *priv, u64 val) -{ - u32 low, high; - - high = (val >> 32) & 0xffffffff; - low = val & 0xffffffff; - - if (!wrmsr_safe_on_cpu(priv->cpu, priv->reg, low, high)) - return 0; - - return -EPERM; -} - -static int write_cpu_register(struct cpu_private *priv, const char *buf) -{ - int ret = -EPERM; - u64 val; - - ret = strict_strtoull(buf, 0, &val); - if (ret < 0) - return ret; - - /* Supporting only MSRs */ - if (priv->type < CPU_TSS_BIT) - return write_msr(priv, val); - - return ret; -} - -static ssize_t cpu_write(struct file *file, const char __user *ubuf, - size_t count, loff_t *off) -{ - struct seq_file *seq = file->private_data; - struct cpu_private *priv = seq->private; - char buf[19]; - - if ((priv == NULL) || (count >= sizeof(buf))) - return -EINVAL; - - if (copy_from_user(&buf, ubuf, count)) - return -EFAULT; - - buf[count] = 0; - - if ((cpu_base[priv->type].write) && (cpu_file[priv->file].write)) - if (!write_cpu_register(priv, buf)) - return count; - - return -EACCES; -} - -static const struct file_operations cpu_fops = { - .owner = THIS_MODULE, - .open = cpu_seq_open, - .read = seq_read, - .write = cpu_write, - .llseek = seq_lseek, - .release = seq_release, -}; - -static int cpu_create_file(unsigned cpu, unsigned type, unsigned reg, - unsigned file, struct dentry *dentry) -{ - struct cpu_private *priv = NULL; - - /* Already intialized */ - if (file == CPU_INDEX_BIT) - if (per_cpu(cpu_arr[type].init, cpu)) - return 0; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (priv == NULL) - return -ENOMEM; - - priv->cpu = cpu; - priv->type = type; - priv->reg = reg; - priv->file = file; - mutex_lock(&cpu_debug_lock); - per_cpu(priv_arr[type], cpu) = priv; - per_cpu(cpu_priv_count, cpu)++; - mutex_unlock(&cpu_debug_lock); - - if (file) - debugfs_create_file(cpu_file[file].name, S_IRUGO, - dentry, (void *)priv, &cpu_fops); - else { - debugfs_create_file(cpu_base[type].name, S_IRUGO, - per_cpu(cpu_arr[type].dentry, cpu), - (void *)priv, &cpu_fops); - mutex_lock(&cpu_debug_lock); - per_cpu(cpu_arr[type].init, cpu) = 1; - mutex_unlock(&cpu_debug_lock); - } - - return 0; -} - -static int cpu_init_regfiles(unsigned cpu, unsigned int type, unsigned reg, - struct dentry *dentry) -{ - unsigned file; - int err = 0; - - for (file = 0; file < ARRAY_SIZE(cpu_file); file++) { - err = cpu_create_file(cpu, type, reg, file, dentry); - if (err) - return err; - } - - return err; -} - -static int cpu_init_msr(unsigned cpu, unsigned type, struct dentry *dentry) -{ - struct dentry *cpu_dentry = NULL; - unsigned reg, reg_min, reg_max; - int i, range, err = 0; - char reg_dir[12]; - u32 low, high; - - range = get_cpu_range_count(cpu); - - for (i = 0; i < range; i++) { - if (!get_cpu_range(cpu, ®_min, ®_max, i, - cpu_base[type].flag)) - continue; - - for (reg = reg_min; reg <= reg_max; reg++) { - if (rdmsr_safe_on_cpu(cpu, reg, &low, &high)) - continue; - - sprintf(reg_dir, "0x%x", reg); - cpu_dentry = debugfs_create_dir(reg_dir, dentry); - err = cpu_init_regfiles(cpu, type, reg, cpu_dentry); - if (err) - return err; - } - } - - return err; -} - -static int cpu_init_allreg(unsigned cpu, struct dentry *dentry) -{ - struct dentry *cpu_dentry = NULL; - unsigned type; - int err = 0; - - for (type = 0; type < ARRAY_SIZE(cpu_base) - 1; type++) { - if (!is_typeflag_valid(cpu, cpu_base[type].flag)) - continue; - cpu_dentry = debugfs_create_dir(cpu_base[type].name, dentry); - per_cpu(cpu_arr[type].dentry, cpu) = cpu_dentry; - - if (type < CPU_TSS_BIT) - err = cpu_init_msr(cpu, type, cpu_dentry); - else - err = cpu_create_file(cpu, type, 0, CPU_INDEX_BIT, - cpu_dentry); - if (err) - return err; - } - - return err; -} - -static int cpu_init_cpu(void) -{ - struct dentry *cpu_dentry = NULL; - struct cpuinfo_x86 *cpui; - char cpu_dir[12]; - unsigned cpu; - int err = 0; - - for (cpu = 0; cpu < nr_cpu_ids; cpu++) { - cpui = &cpu_data(cpu); - if (!cpu_has(cpui, X86_FEATURE_MSR)) - continue; - per_cpu(cpu_model, cpu) = ((cpui->x86_vendor << 16) | - (cpui->x86 << 8) | - (cpui->x86_model)); - per_cpu(cpu_modelflag, cpu) = get_cpu_modelflag(cpu); - - sprintf(cpu_dir, "cpu%d", cpu); - cpu_dentry = debugfs_create_dir(cpu_dir, cpu_debugfs_dir); - err = cpu_init_allreg(cpu, cpu_dentry); - - pr_info("cpu%d(%d) debug files %d\n", - cpu, nr_cpu_ids, per_cpu(cpu_priv_count, cpu)); - if (per_cpu(cpu_priv_count, cpu) > MAX_CPU_FILES) { - pr_err("Register files count %d exceeds limit %d\n", - per_cpu(cpu_priv_count, cpu), MAX_CPU_FILES); - per_cpu(cpu_priv_count, cpu) = MAX_CPU_FILES; - err = -ENFILE; - } - if (err) - return err; - } - - return err; -} - -static int __init cpu_debug_init(void) -{ - cpu_debugfs_dir = debugfs_create_dir("cpu", arch_debugfs_dir); - - return cpu_init_cpu(); -} - -static void __exit cpu_debug_exit(void) -{ - int i, cpu; - - if (cpu_debugfs_dir) - debugfs_remove_recursive(cpu_debugfs_dir); - - for (cpu = 0; cpu < nr_cpu_ids; cpu++) - for (i = 0; i < per_cpu(cpu_priv_count, cpu); i++) - kfree(per_cpu(priv_arr[i], cpu)); -} - -module_init(cpu_debug_init); -module_exit(cpu_debug_exit); - -MODULE_AUTHOR("Jaswinder Singh Rajput"); -MODULE_DESCRIPTION("CPU Debug module"); -MODULE_LICENSE("GPL"); diff --git a/trunk/arch/x86/kernel/cpu/cyrix.c b/trunk/arch/x86/kernel/cpu/cyrix.c index 593171e967ef..ffd0f5ed071a 100644 --- a/trunk/arch/x86/kernel/cpu/cyrix.c +++ b/trunk/arch/x86/kernel/cpu/cyrix.c @@ -61,23 +61,23 @@ static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1) */ static unsigned char Cx86_dir0_msb __cpuinitdata = 0; -static const char __cpuinitconst Cx86_model[][9] = { +static char Cx86_model[][9] __cpuinitdata = { "Cx486", "Cx486", "5x86 ", "6x86", "MediaGX ", "6x86MX ", "M II ", "Unknown" }; -static const char __cpuinitconst Cx486_name[][5] = { +static char Cx486_name[][5] __cpuinitdata = { "SLC", "DLC", "SLC2", "DLC2", "SRx", "DRx", "SRx2", "DRx2" }; -static const char __cpuinitconst Cx486S_name[][4] = { +static char Cx486S_name[][4] __cpuinitdata = { "S", "S2", "Se", "S2e" }; -static const char __cpuinitconst Cx486D_name[][4] = { +static char Cx486D_name[][4] __cpuinitdata = { "DX", "DX2", "?", "?", "?", "DX4" }; static char Cx86_cb[] __cpuinitdata = "?.5x Core/Bus Clock"; -static const char __cpuinitconst cyrix_model_mult1[] = "12??43"; -static const char __cpuinitconst cyrix_model_mult2[] = "12233445"; +static char cyrix_model_mult1[] __cpuinitdata = "12??43"; +static char cyrix_model_mult2[] __cpuinitdata = "12233445"; /* * Reset the slow-loop (SLOP) bit on the 686(L) which is set by some old @@ -435,7 +435,7 @@ static void __cpuinit cyrix_identify(struct cpuinfo_x86 *c) } } -static const struct cpu_dev __cpuinitconst cyrix_cpu_dev = { +static struct cpu_dev cyrix_cpu_dev __cpuinitdata = { .c_vendor = "Cyrix", .c_ident = { "CyrixInstead" }, .c_early_init = early_init_cyrix, @@ -446,7 +446,7 @@ static const struct cpu_dev __cpuinitconst cyrix_cpu_dev = { cpu_dev_register(cyrix_cpu_dev); -static const struct cpu_dev __cpuinitconst nsc_cpu_dev = { +static struct cpu_dev nsc_cpu_dev __cpuinitdata = { .c_vendor = "NSC", .c_ident = { "Geode by NSC" }, .c_init = init_nsc, diff --git a/trunk/arch/x86/kernel/cpu/intel.c b/trunk/arch/x86/kernel/cpu/intel.c index 7437fa133c02..1a89a2b68d15 100644 --- a/trunk/arch/x86/kernel/cpu/intel.c +++ b/trunk/arch/x86/kernel/cpu/intel.c @@ -14,7 +14,6 @@ #include #include #include -#include #ifdef CONFIG_X86_64 #include @@ -55,11 +54,6 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) c->x86_cache_alignment = 128; #endif - /* CPUID workaround for 0F33/0F34 CPU */ - if (c->x86 == 0xF && c->x86_model == 0x3 - && (c->x86_mask == 0x3 || c->x86_mask == 0x4)) - c->x86_phys_bits = 36; - /* * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate * with P/T states and does not stop in deep C-states. @@ -122,28 +116,6 @@ static void __cpuinit trap_init_f00f_bug(void) } #endif -static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c) -{ -#ifdef CONFIG_SMP - /* calling is from identify_secondary_cpu() ? */ - if (c->cpu_index == boot_cpu_id) - return; - - /* - * Mask B, Pentium, but not Pentium MMX - */ - if (c->x86 == 5 && - c->x86_mask >= 1 && c->x86_mask <= 4 && - c->x86_model <= 3) { - /* - * Remember we have B step Pentia with bugs - */ - WARN_ONCE(1, "WARNING: SMP operation may be unreliable" - "with B stepping processors.\n"); - } -#endif -} - static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c) { unsigned long lo, hi; @@ -220,8 +192,6 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c) #ifdef CONFIG_X86_NUMAQ numaq_tsc_disable(); #endif - - intel_smp_check(c); } #else static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c) @@ -421,7 +391,7 @@ static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 *c, unsigned i } #endif -static const struct cpu_dev __cpuinitconst intel_cpu_dev = { +static struct cpu_dev intel_cpu_dev __cpuinitdata = { .c_vendor = "Intel", .c_ident = { "GenuineIntel" }, #ifdef CONFIG_X86_32 diff --git a/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c b/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c index c471eb1a389c..7293508d8f5c 100644 --- a/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -32,7 +32,7 @@ struct _cache_table }; /* all the cache descriptor types we care about (no TLB or trace cache entries) */ -static const struct _cache_table __cpuinitconst cache_table[] = +static struct _cache_table cache_table[] __cpuinitdata = { { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */ @@ -206,15 +206,15 @@ union l3_cache { unsigned val; }; -static const unsigned short __cpuinitconst assocs[] = { +static unsigned short assocs[] __cpuinitdata = { [1] = 1, [2] = 2, [4] = 4, [6] = 8, [8] = 16, [0xa] = 32, [0xb] = 48, [0xc] = 64, [0xf] = 0xffff // ?? }; -static const unsigned char __cpuinitconst levels[] = { 1, 1, 2, 3 }; -static const unsigned char __cpuinitconst types[] = { 1, 2, 3, 3 }; +static unsigned char levels[] __cpuinitdata = { 1, 1, 2, 3 }; +static unsigned char types[] __cpuinitdata = { 1, 2, 3, 3 }; static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, diff --git a/trunk/arch/x86/kernel/cpu/mcheck/Makefile b/trunk/arch/x86/kernel/cpu/mcheck/Makefile index b2f89829bbe8..d7d2323bbb69 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/Makefile +++ b/trunk/arch/x86/kernel/cpu/mcheck/Makefile @@ -4,4 +4,3 @@ obj-$(CONFIG_X86_32) += k7.o p4.o p5.o p6.o winchip.o obj-$(CONFIG_X86_MCE_INTEL) += mce_intel_64.o obj-$(CONFIG_X86_MCE_AMD) += mce_amd_64.o obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o -obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce_32.c b/trunk/arch/x86/kernel/cpu/mcheck/mce_32.c index 3552119b091d..dfaebce3633e 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce_32.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce_32.c @@ -60,6 +60,20 @@ void mcheck_init(struct cpuinfo_x86 *c) } } +static unsigned long old_cr4 __initdata; + +void __init stop_mce(void) +{ + old_cr4 = read_cr4(); + clear_in_cr4(X86_CR4_MCE); +} + +void __init restart_mce(void) +{ + if (old_cr4 & X86_CR4_MCE) + set_in_cr4(X86_CR4_MCE); +} + static int __init mcheck_disable(char *str) { mce_disabled = 1; diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c b/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c index ca14604611ec..fe79985ce0f2 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -3,8 +3,6 @@ * K8 parts Copyright 2002,2003 Andi Kleen, SuSE Labs. * Rest from unknown author(s). * 2004 Andi Kleen. Rewrote most of it. - * Copyright 2008 Intel Corporation - * Author: Andi Kleen */ #include @@ -26,9 +24,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -37,6 +32,7 @@ #include #define MISC_MCELOG_MINOR 227 +#define NR_SYSFS_BANKS 6 atomic_t mce_entry; @@ -51,7 +47,7 @@ static int mce_dont_init; */ static int tolerant = 1; static int banks; -static u64 *bank; +static unsigned long bank[NR_SYSFS_BANKS] = { [0 ... NR_SYSFS_BANKS-1] = ~0UL }; static unsigned long notify_user; static int rip_msr; static int mce_bootlog = -1; @@ -62,19 +58,6 @@ static char *trigger_argv[2] = { trigger, NULL }; static DECLARE_WAIT_QUEUE_HEAD(mce_wait); -/* MCA banks polled by the period polling timer for corrected events */ -DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = { - [0 ... BITS_TO_LONGS(MAX_NR_BANKS)-1] = ~0UL -}; - -/* Do initial initialization of a struct mce */ -void mce_setup(struct mce *m) -{ - memset(m, 0, sizeof(struct mce)); - m->cpu = smp_processor_id(); - rdtscll(m->tsc); -} - /* * Lockless MCE logging infrastructure. * This avoids deadlocks on printk locks without having to break locks. Also @@ -136,11 +119,11 @@ static void print_mce(struct mce *m) print_symbol("{%s}", m->ip); printk("\n"); } - printk(KERN_EMERG "TSC %llx ", m->tsc); + printk(KERN_EMERG "TSC %Lx ", m->tsc); if (m->addr) - printk("ADDR %llx ", m->addr); + printk("ADDR %Lx ", m->addr); if (m->misc) - printk("MISC %llx ", m->misc); + printk("MISC %Lx ", m->misc); printk("\n"); printk(KERN_EMERG "This is not a software problem!\n"); printk(KERN_EMERG "Run through mcelog --ascii to decode " @@ -166,10 +149,8 @@ static void mce_panic(char *msg, struct mce *backup, unsigned long start) panic(msg); } -int mce_available(struct cpuinfo_x86 *c) +static int mce_available(struct cpuinfo_x86 *c) { - if (mce_dont_init) - return 0; return cpu_has(c, X86_FEATURE_MCE) && cpu_has(c, X86_FEATURE_MCA); } @@ -191,77 +172,7 @@ static inline void mce_get_rip(struct mce *m, struct pt_regs *regs) } /* - * Poll for corrected events or events that happened before reset. - * Those are just logged through /dev/mcelog. - * - * This is executed in standard interrupt context. - */ -void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) -{ - struct mce m; - int i; - - mce_setup(&m); - - rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus); - for (i = 0; i < banks; i++) { - if (!bank[i] || !test_bit(i, *b)) - continue; - - m.misc = 0; - m.addr = 0; - m.bank = i; - m.tsc = 0; - - barrier(); - rdmsrl(MSR_IA32_MC0_STATUS + i*4, m.status); - if (!(m.status & MCI_STATUS_VAL)) - continue; - - /* - * Uncorrected events are handled by the exception handler - * when it is enabled. But when the exception is disabled log - * everything. - * - * TBD do the same check for MCI_STATUS_EN here? - */ - if ((m.status & MCI_STATUS_UC) && !(flags & MCP_UC)) - continue; - - if (m.status & MCI_STATUS_MISCV) - rdmsrl(MSR_IA32_MC0_MISC + i*4, m.misc); - if (m.status & MCI_STATUS_ADDRV) - rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr); - - if (!(flags & MCP_TIMESTAMP)) - m.tsc = 0; - /* - * Don't get the IP here because it's unlikely to - * have anything to do with the actual error location. - */ - - mce_log(&m); - add_taint(TAINT_MACHINE_CHECK); - - /* - * Clear state for this bank. - */ - wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0); - } - - /* - * Don't clear MCG_STATUS here because it's only defined for - * exceptions. - */ -} - -/* - * The actual machine check handler. This only handles real - * exceptions when something got corrupted coming in through int 18. - * - * This is executed in NMI context not subject to normal locking rules. This - * implies that most kernel services cannot be safely used. Don't even - * think about putting a printk in there! + * The actual machine check handler */ void do_machine_check(struct pt_regs * regs, long error_code) { @@ -279,18 +190,17 @@ void do_machine_check(struct pt_regs * regs, long error_code) * error. */ int kill_it = 0; - DECLARE_BITMAP(toclear, MAX_NR_BANKS); atomic_inc(&mce_entry); - if (notify_die(DIE_NMI, "machine check", regs, error_code, + if ((regs + && notify_die(DIE_NMI, "machine check", regs, error_code, 18, SIGKILL) == NOTIFY_STOP) - goto out2; - if (!banks) + || !banks) goto out2; - mce_setup(&m); - + memset(&m, 0, sizeof(struct mce)); + m.cpu = smp_processor_id(); rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus); /* if the restart IP is not valid, we're done for */ if (!(m.mcgstatus & MCG_STATUS_RIPV)) @@ -300,32 +210,18 @@ void do_machine_check(struct pt_regs * regs, long error_code) barrier(); for (i = 0; i < banks; i++) { - __clear_bit(i, toclear); - if (!bank[i]) + if (i < NR_SYSFS_BANKS && !bank[i]) continue; m.misc = 0; m.addr = 0; m.bank = i; + m.tsc = 0; rdmsrl(MSR_IA32_MC0_STATUS + i*4, m.status); if ((m.status & MCI_STATUS_VAL) == 0) continue; - /* - * Non uncorrected errors are handled by machine_check_poll - * Leave them alone. - */ - if ((m.status & MCI_STATUS_UC) == 0) - continue; - - /* - * Set taint even when machine check was not enabled. - */ - add_taint(TAINT_MACHINE_CHECK); - - __set_bit(i, toclear); - if (m.status & MCI_STATUS_EN) { /* if PCC was set, there's no way out */ no_way_out |= !!(m.status & MCI_STATUS_PCC); @@ -339,12 +235,6 @@ void do_machine_check(struct pt_regs * regs, long error_code) no_way_out = 1; kill_it = 1; } - } else { - /* - * Machine check event was not enabled. Clear, but - * ignore. - */ - continue; } if (m.status & MCI_STATUS_MISCV) @@ -353,7 +243,10 @@ void do_machine_check(struct pt_regs * regs, long error_code) rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr); mce_get_rip(&m, regs); - mce_log(&m); + if (error_code >= 0) + rdtscll(m.tsc); + if (error_code != -2) + mce_log(&m); /* Did this bank cause the exception? */ /* Assume that the bank with uncorrectable errors did it, @@ -362,8 +255,14 @@ void do_machine_check(struct pt_regs * regs, long error_code) panicm = m; panicm_found = 1; } + + add_taint(TAINT_MACHINE_CHECK); } + /* Never do anything final in the polling timer */ + if (!regs) + goto out; + /* If we didn't find an uncorrectable error, pick the last one (shouldn't happen, just being safe). */ if (!panicm_found) @@ -410,11 +309,10 @@ void do_machine_check(struct pt_regs * regs, long error_code) /* notify userspace ASAP */ set_thread_flag(TIF_MCE_NOTIFY); + out: /* the last thing we do is clear state */ - for (i = 0; i < banks; i++) { - if (test_bit(i, toclear)) - wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0); - } + for (i = 0; i < banks; i++) + wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0); wrmsrl(MSR_IA32_MCG_STATUS, 0); out2: atomic_dec(&mce_entry); @@ -434,13 +332,15 @@ void do_machine_check(struct pt_regs * regs, long error_code) * and historically has been the register value of the * MSR_IA32_THERMAL_STATUS (Intel) msr. */ -void mce_log_therm_throt_event(__u64 status) +void mce_log_therm_throt_event(unsigned int cpu, __u64 status) { struct mce m; - mce_setup(&m); + memset(&m, 0, sizeof(m)); + m.cpu = cpu; m.bank = MCE_THERMAL_BANK; m.status = status; + rdtscll(m.tsc); mce_log(&m); } #endif /* CONFIG_X86_MCE_INTEL */ @@ -453,18 +353,18 @@ void mce_log_therm_throt_event(__u64 status) static int check_interval = 5 * 60; /* 5 minutes */ static int next_interval; /* in jiffies */ -static void mcheck_timer(unsigned long); -static DEFINE_PER_CPU(struct timer_list, mce_timer); +static void mcheck_timer(struct work_struct *work); +static DECLARE_DELAYED_WORK(mcheck_work, mcheck_timer); -static void mcheck_timer(unsigned long data) +static void mcheck_check_cpu(void *info) { - struct timer_list *t = &per_cpu(mce_timer, data); - - WARN_ON(smp_processor_id() != data); - if (mce_available(¤t_cpu_data)) - machine_check_poll(MCP_TIMESTAMP, - &__get_cpu_var(mce_poll_banks)); + do_machine_check(NULL, 0); +} + +static void mcheck_timer(struct work_struct *work) +{ + on_each_cpu(mcheck_check_cpu, NULL, 1); /* * Alert userspace if needed. If we logged an MCE, reduce the @@ -477,41 +377,31 @@ static void mcheck_timer(unsigned long data) (int)round_jiffies_relative(check_interval*HZ)); } - t->expires = jiffies + next_interval; - add_timer(t); -} - -static void mce_do_trigger(struct work_struct *work) -{ - call_usermodehelper(trigger, trigger_argv, NULL, UMH_NO_WAIT); + schedule_delayed_work(&mcheck_work, next_interval); } -static DECLARE_WORK(mce_trigger_work, mce_do_trigger); - /* - * Notify the user(s) about new machine check events. - * Can be called from interrupt context, but not from machine check/NMI - * context. + * This is only called from process context. This is where we do + * anything we need to alert userspace about new MCEs. This is called + * directly from the poller and also from entry.S and idle, thanks to + * TIF_MCE_NOTIFY. */ int mce_notify_user(void) { - /* Not more than two messages every minute */ - static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2); - clear_thread_flag(TIF_MCE_NOTIFY); if (test_and_clear_bit(0, ¬ify_user)) { - wake_up_interruptible(&mce_wait); + static unsigned long last_print; + unsigned long now = jiffies; - /* - * There is no risk of missing notifications because - * work_pending is always cleared before the function is - * executed. - */ - if (trigger[0] && !work_pending(&mce_trigger_work)) - schedule_work(&mce_trigger_work); + wake_up_interruptible(&mce_wait); + if (trigger[0]) + call_usermodehelper(trigger, trigger_argv, NULL, + UMH_NO_WAIT); - if (__ratelimit(&ratelimit)) + if (time_after_eq(now, last_print + (check_interval*HZ))) { + last_print = now; printk(KERN_INFO "Machine check events logged\n"); + } return 1; } @@ -535,78 +425,63 @@ static struct notifier_block mce_idle_notifier = { static __init int periodic_mcheck_init(void) { - idle_notifier_register(&mce_idle_notifier); - return 0; + next_interval = check_interval * HZ; + if (next_interval) + schedule_delayed_work(&mcheck_work, + round_jiffies_relative(next_interval)); + idle_notifier_register(&mce_idle_notifier); + return 0; } __initcall(periodic_mcheck_init); + /* * Initialize Machine Checks for a CPU. */ -static int mce_cap_init(void) +static void mce_init(void *dummy) { u64 cap; - unsigned b; + int i; rdmsrl(MSR_IA32_MCG_CAP, cap); - b = cap & 0xff; - if (b > MAX_NR_BANKS) { - printk(KERN_WARNING - "MCE: Using only %u machine check banks out of %u\n", - MAX_NR_BANKS, b); - b = MAX_NR_BANKS; + banks = cap & 0xff; + if (banks > MCE_EXTENDED_BANK) { + banks = MCE_EXTENDED_BANK; + printk(KERN_INFO "MCE: warning: using only %d banks\n", + MCE_EXTENDED_BANK); } - - /* Don't support asymmetric configurations today */ - WARN_ON(banks != 0 && b != banks); - banks = b; - if (!bank) { - bank = kmalloc(banks * sizeof(u64), GFP_KERNEL); - if (!bank) - return -ENOMEM; - memset(bank, 0xff, banks * sizeof(u64)); - } - /* Use accurate RIP reporting if available. */ if ((cap & (1<<9)) && ((cap >> 16) & 0xff) >= 9) rip_msr = MSR_IA32_MCG_EIP; - return 0; -} - -static void mce_init(void *dummy) -{ - u64 cap; - int i; - mce_banks_t all_banks; - - /* - * Log the machine checks left over from the previous reset. - */ - bitmap_fill(all_banks, MAX_NR_BANKS); - machine_check_poll(MCP_UC, &all_banks); + /* Log the machine checks left over from the previous reset. + This also clears all registers */ + do_machine_check(NULL, mce_bootlog ? -1 : -2); set_in_cr4(X86_CR4_MCE); - rdmsrl(MSR_IA32_MCG_CAP, cap); if (cap & MCG_CTL_P) wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff); for (i = 0; i < banks; i++) { - wrmsrl(MSR_IA32_MC0_CTL+4*i, bank[i]); + if (i < NR_SYSFS_BANKS) + wrmsrl(MSR_IA32_MC0_CTL+4*i, bank[i]); + else + wrmsrl(MSR_IA32_MC0_CTL+4*i, ~0UL); + wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0); } } /* Add per CPU specific workarounds here */ -static void mce_cpu_quirks(struct cpuinfo_x86 *c) +static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c) { /* This should be disabled by the BIOS, but isn't always */ if (c->x86_vendor == X86_VENDOR_AMD) { - if (c->x86 == 15 && banks > 4) + if(c->x86 == 15) /* disable GART TBL walk error reporting, which trips off incorrectly with the IOMMU & 3ware & Cerberus. */ - clear_bit(10, (unsigned long *)&bank[4]); + clear_bit(10, &bank[4]); if(c->x86 <= 17 && mce_bootlog < 0) /* Lots of broken BIOS around that don't clear them by default and leave crap in there. Don't log. */ @@ -629,38 +504,20 @@ static void mce_cpu_features(struct cpuinfo_x86 *c) } } -static void mce_init_timer(void) -{ - struct timer_list *t = &__get_cpu_var(mce_timer); - - /* data race harmless because everyone sets to the same value */ - if (!next_interval) - next_interval = check_interval * HZ; - if (!next_interval) - return; - setup_timer(t, mcheck_timer, smp_processor_id()); - t->expires = round_jiffies(jiffies + next_interval); - add_timer(t); -} - /* * Called for each booted CPU to set up machine checks. * Must be called with preempt off. */ void __cpuinit mcheck_init(struct cpuinfo_x86 *c) { - if (!mce_available(c)) - return; + mce_cpu_quirks(c); - if (mce_cap_init() < 0) { - mce_dont_init = 1; + if (mce_dont_init || + !mce_available(c)) return; - } - mce_cpu_quirks(c); mce_init(NULL); mce_cpu_features(c); - mce_init_timer(); } /* @@ -716,7 +573,7 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, { unsigned long *cpu_tsc; static DEFINE_MUTEX(mce_read_mutex); - unsigned prev, next; + unsigned next; char __user *buf = ubuf; int i, err; @@ -735,32 +592,25 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, } err = 0; - prev = 0; - do { - for (i = prev; i < next; i++) { - unsigned long start = jiffies; - - while (!mcelog.entry[i].finished) { - if (time_after_eq(jiffies, start + 2)) { - memset(mcelog.entry + i, 0, - sizeof(struct mce)); - goto timeout; - } - cpu_relax(); + for (i = 0; i < next; i++) { + unsigned long start = jiffies; + + while (!mcelog.entry[i].finished) { + if (time_after_eq(jiffies, start + 2)) { + memset(mcelog.entry + i,0, sizeof(struct mce)); + goto timeout; } - smp_rmb(); - err |= copy_to_user(buf, mcelog.entry + i, - sizeof(struct mce)); - buf += sizeof(struct mce); -timeout: - ; + cpu_relax(); } + smp_rmb(); + err |= copy_to_user(buf, mcelog.entry + i, sizeof(struct mce)); + buf += sizeof(struct mce); + timeout: + ; + } - memset(mcelog.entry + prev, 0, - (next - prev) * sizeof(struct mce)); - prev = next; - next = cmpxchg(&mcelog.next, prev, 0); - } while (next != prev); + memset(mcelog.entry, 0, next * sizeof(struct mce)); + mcelog.next = 0; synchronize_sched(); @@ -830,6 +680,20 @@ static struct miscdevice mce_log_device = { &mce_chrdev_ops, }; +static unsigned long old_cr4 __initdata; + +void __init stop_mce(void) +{ + old_cr4 = read_cr4(); + clear_in_cr4(X86_CR4_MCE); +} + +void __init restart_mce(void) +{ + if (old_cr4 & X86_CR4_MCE) + set_in_cr4(X86_CR4_MCE); +} + /* * Old style boot options parsing. Only for compatibility. */ @@ -839,7 +703,8 @@ static int __init mcheck_disable(char *str) return 1; } -/* mce=off disables machine check. +/* mce=off disables machine check. Note you can re-enable it later + using sysfs. mce=TOLERANCELEVEL (number, see above) mce=bootlog Log MCEs from before booting. Disabled by default on AMD. mce=nobootlog Don't log MCEs from before booting. */ @@ -863,29 +728,6 @@ __setup("mce=", mcheck_enable); * Sysfs support */ -/* - * Disable machine checks on suspend and shutdown. We can't really handle - * them later. - */ -static int mce_disable(void) -{ - int i; - - for (i = 0; i < banks; i++) - wrmsrl(MSR_IA32_MC0_CTL + i*4, 0); - return 0; -} - -static int mce_suspend(struct sys_device *dev, pm_message_t state) -{ - return mce_disable(); -} - -static int mce_shutdown(struct sys_device *dev) -{ - return mce_disable(); -} - /* On resume clear all MCE state. Don't want to see leftovers from the BIOS. Only one CPU is active at this time, the others get readded later using CPU hotplug. */ @@ -896,24 +738,20 @@ static int mce_resume(struct sys_device *dev) return 0; } -static void mce_cpu_restart(void *data) -{ - del_timer_sync(&__get_cpu_var(mce_timer)); - if (mce_available(¤t_cpu_data)) - mce_init(NULL); - mce_init_timer(); -} - /* Reinit MCEs after user configuration changes */ static void mce_restart(void) { + if (next_interval) + cancel_delayed_work(&mcheck_work); + /* Timer race is harmless here */ + on_each_cpu(mce_init, NULL, 1); next_interval = check_interval * HZ; - on_each_cpu(mce_cpu_restart, NULL, 1); + if (next_interval) + schedule_delayed_work(&mcheck_work, + round_jiffies_relative(next_interval)); } static struct sysdev_class mce_sysclass = { - .suspend = mce_suspend, - .shutdown = mce_shutdown, .resume = mce_resume, .name = "machinecheck", }; @@ -940,26 +778,16 @@ void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu) __cpuinit } \ static SYSDEV_ATTR(name, 0644, show_ ## name, set_ ## name); -static struct sysdev_attribute *bank_attrs; - -static ssize_t show_bank(struct sys_device *s, struct sysdev_attribute *attr, - char *buf) -{ - u64 b = bank[attr - bank_attrs]; - return sprintf(buf, "%llx\n", b); -} - -static ssize_t set_bank(struct sys_device *s, struct sysdev_attribute *attr, - const char *buf, size_t siz) -{ - char *end; - u64 new = simple_strtoull(buf, &end, 0); - if (end == buf) - return -EINVAL; - bank[attr - bank_attrs] = new; - mce_restart(); - return end-buf; -} +/* + * TBD should generate these dynamically based on number of available banks. + * Have only 6 contol banks in /sysfs until then. + */ +ACCESSOR(bank0ctl,bank[0],mce_restart()) +ACCESSOR(bank1ctl,bank[1],mce_restart()) +ACCESSOR(bank2ctl,bank[2],mce_restart()) +ACCESSOR(bank3ctl,bank[3],mce_restart()) +ACCESSOR(bank4ctl,bank[4],mce_restart()) +ACCESSOR(bank5ctl,bank[5],mce_restart()) static ssize_t show_trigger(struct sys_device *s, struct sysdev_attribute *attr, char *buf) @@ -986,6 +814,8 @@ static SYSDEV_ATTR(trigger, 0644, show_trigger, set_trigger); static SYSDEV_INT_ATTR(tolerant, 0644, tolerant); ACCESSOR(check_interval,check_interval,mce_restart()) static struct sysdev_attribute *mce_attributes[] = { + &attr_bank0ctl, &attr_bank1ctl, &attr_bank2ctl, + &attr_bank3ctl, &attr_bank4ctl, &attr_bank5ctl, &attr_tolerant.attr, &attr_check_interval, &attr_trigger, NULL }; @@ -1015,22 +845,11 @@ static __cpuinit int mce_create_device(unsigned int cpu) if (err) goto error; } - for (i = 0; i < banks; i++) { - err = sysdev_create_file(&per_cpu(device_mce, cpu), - &bank_attrs[i]); - if (err) - goto error2; - } cpu_set(cpu, mce_device_initialized); return 0; -error2: - while (--i >= 0) { - sysdev_remove_file(&per_cpu(device_mce, cpu), - &bank_attrs[i]); - } error: - while (--i >= 0) { + while (i--) { sysdev_remove_file(&per_cpu(device_mce,cpu), mce_attributes[i]); } @@ -1049,46 +868,15 @@ static __cpuinit void mce_remove_device(unsigned int cpu) for (i = 0; mce_attributes[i]; i++) sysdev_remove_file(&per_cpu(device_mce,cpu), mce_attributes[i]); - for (i = 0; i < banks; i++) - sysdev_remove_file(&per_cpu(device_mce, cpu), - &bank_attrs[i]); sysdev_unregister(&per_cpu(device_mce,cpu)); cpu_clear(cpu, mce_device_initialized); } -/* Make sure there are no machine checks on offlined CPUs. */ -static void mce_disable_cpu(void *h) -{ - int i; - unsigned long action = *(unsigned long *)h; - - if (!mce_available(¤t_cpu_data)) - return; - if (!(action & CPU_TASKS_FROZEN)) - cmci_clear(); - for (i = 0; i < banks; i++) - wrmsrl(MSR_IA32_MC0_CTL + i*4, 0); -} - -static void mce_reenable_cpu(void *h) -{ - int i; - unsigned long action = *(unsigned long *)h; - - if (!mce_available(¤t_cpu_data)) - return; - if (!(action & CPU_TASKS_FROZEN)) - cmci_reenable(); - for (i = 0; i < banks; i++) - wrmsrl(MSR_IA32_MC0_CTL + i*4, bank[i]); -} - /* Get notified when a cpu comes on/off. Be hotplug friendly. */ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; - struct timer_list *t = &per_cpu(mce_timer, cpu); switch (action) { case CPU_ONLINE: @@ -1103,21 +891,6 @@ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb, threshold_cpu_callback(action, cpu); mce_remove_device(cpu); break; - case CPU_DOWN_PREPARE: - case CPU_DOWN_PREPARE_FROZEN: - del_timer_sync(t); - smp_call_function_single(cpu, mce_disable_cpu, &action, 1); - break; - case CPU_DOWN_FAILED: - case CPU_DOWN_FAILED_FROZEN: - t->expires = round_jiffies(jiffies + next_interval); - add_timer_on(t, cpu); - smp_call_function_single(cpu, mce_reenable_cpu, &action, 1); - break; - case CPU_POST_DEAD: - /* intentionally ignoring frozen here */ - cmci_rediscover(cpu); - break; } return NOTIFY_OK; } @@ -1126,34 +899,6 @@ static struct notifier_block mce_cpu_notifier __cpuinitdata = { .notifier_call = mce_cpu_callback, }; -static __init int mce_init_banks(void) -{ - int i; - - bank_attrs = kzalloc(sizeof(struct sysdev_attribute) * banks, - GFP_KERNEL); - if (!bank_attrs) - return -ENOMEM; - - for (i = 0; i < banks; i++) { - struct sysdev_attribute *a = &bank_attrs[i]; - a->attr.name = kasprintf(GFP_KERNEL, "bank%d", i); - if (!a->attr.name) - goto nomem; - a->attr.mode = 0644; - a->show = show_bank; - a->store = set_bank; - } - return 0; - -nomem: - while (--i >= 0) - kfree(bank_attrs[i].attr.name); - kfree(bank_attrs); - bank_attrs = NULL; - return -ENOMEM; -} - static __init int mce_init_device(void) { int err; @@ -1161,11 +906,6 @@ static __init int mce_init_device(void) if (!mce_available(&boot_cpu_data)) return -EIO; - - err = mce_init_banks(); - if (err) - return err; - err = sysdev_class_register(&mce_sysclass); if (err) return err; diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/trunk/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index 7d01be868870..9817506dd469 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce_amd_64.c @@ -79,8 +79,6 @@ static unsigned char shared_bank[NR_BANKS] = { static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */ -static void amd_threshold_interrupt(void); - /* * CPU Initialization */ @@ -92,8 +90,7 @@ struct thresh_restart { }; /* must be called with correct cpu affinity */ -/* Called via smp_call_function_single() */ -static void threshold_restart_bank(void *_tr) +static long threshold_restart_bank(void *_tr) { struct thresh_restart *tr = _tr; u32 mci_misc_hi, mci_misc_lo; @@ -120,6 +117,7 @@ static void threshold_restart_bank(void *_tr) mci_misc_hi |= MASK_COUNT_EN_HI; wrmsr(tr->b->address, mci_misc_lo, mci_misc_hi); + return 0; } /* cpu init entry point, called from mce.c with preempt off */ @@ -176,8 +174,6 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) tr.reset = 0; tr.old_limit = 0; threshold_restart_bank(&tr); - - mce_threshold_vector = amd_threshold_interrupt; } } } @@ -191,13 +187,19 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) * the interrupt goes off when error_count reaches threshold_limit. * the handler will simply log mcelog w/ software defined bank number. */ -static void amd_threshold_interrupt(void) +asmlinkage void mce_threshold_interrupt(void) { unsigned int bank, block; struct mce m; u32 low = 0, high = 0, address = 0; - mce_setup(&m); + ack_APIC_irq(); + exit_idle(); + irq_enter(); + + memset(&m, 0, sizeof(m)); + rdtscll(m.tsc); + m.cpu = smp_processor_id(); /* assume first bank caused it */ for (bank = 0; bank < NR_BANKS; ++bank) { @@ -231,8 +233,7 @@ static void amd_threshold_interrupt(void) /* Log the machine check that caused the threshold event. */ - machine_check_poll(MCP_TIMESTAMP, - &__get_cpu_var(mce_poll_banks)); + do_machine_check(NULL, 0); if (high & MASK_OVERFLOW_HI) { rdmsrl(address, m.misc); @@ -242,10 +243,13 @@ static void amd_threshold_interrupt(void) + bank * NR_BLOCKS + block; mce_log(&m); - return; + goto out; } } } +out: + inc_irq_stat(irq_threshold_count); + irq_exit(); } /* @@ -279,7 +283,7 @@ static ssize_t store_interrupt_enable(struct threshold_block *b, tr.b = b; tr.reset = 0; tr.old_limit = 0; - smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1); + work_on_cpu(b->cpu, threshold_restart_bank, &tr); return end - buf; } @@ -301,32 +305,23 @@ static ssize_t store_threshold_limit(struct threshold_block *b, tr.b = b; tr.reset = 0; - smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1); + work_on_cpu(b->cpu, threshold_restart_bank, &tr); return end - buf; } -struct threshold_block_cross_cpu { - struct threshold_block *tb; - long retval; -}; - -static void local_error_count_handler(void *_tbcc) +static long local_error_count(void *_b) { - struct threshold_block_cross_cpu *tbcc = _tbcc; - struct threshold_block *b = tbcc->tb; + struct threshold_block *b = _b; u32 low, high; rdmsr(b->address, low, high); - tbcc->retval = (high & 0xFFF) - (THRESHOLD_MAX - b->threshold_limit); + return (high & 0xFFF) - (THRESHOLD_MAX - b->threshold_limit); } static ssize_t show_error_count(struct threshold_block *b, char *buf) { - struct threshold_block_cross_cpu tbcc = { .tb = b, }; - - smp_call_function_single(b->cpu, local_error_count_handler, &tbcc, 1); - return sprintf(buf, "%lx\n", tbcc.retval); + return sprintf(buf, "%lx\n", work_on_cpu(b->cpu, local_error_count, b)); } static ssize_t store_error_count(struct threshold_block *b, @@ -334,7 +329,7 @@ static ssize_t store_error_count(struct threshold_block *b, { struct thresh_restart tr = { .b = b, .reset = 1, .old_limit = 0 }; - smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1); + work_on_cpu(b->cpu, threshold_restart_bank, &tr); return 1; } @@ -403,7 +398,7 @@ static __cpuinit int allocate_threshold_blocks(unsigned int cpu, if ((bank >= NR_BANKS) || (block >= NR_BLOCKS)) return 0; - if (rdmsr_safe_on_cpu(cpu, address, &low, &high)) + if (rdmsr_safe(address, &low, &high)) return 0; if (!(high & MASK_VALID_HI)) { @@ -467,11 +462,12 @@ static __cpuinit int allocate_threshold_blocks(unsigned int cpu, return err; } -static __cpuinit long -local_allocate_threshold_blocks(int cpu, unsigned int bank) +static __cpuinit long local_allocate_threshold_blocks(void *_bank) { - return allocate_threshold_blocks(cpu, bank, 0, - MSR_IA32_MC0_MISC + bank * 4); + unsigned int *bank = _bank; + + return allocate_threshold_blocks(smp_processor_id(), *bank, 0, + MSR_IA32_MC0_MISC + *bank * 4); } /* symlinks sibling shared banks to first core. first core owns dir/files. */ @@ -534,7 +530,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) per_cpu(threshold_banks, cpu)[bank] = b; - err = local_allocate_threshold_blocks(cpu, bank); + err = work_on_cpu(cpu, local_allocate_threshold_blocks, &bank); if (err) goto out_free; diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/trunk/arch/x86/kernel/cpu/mcheck/mce_intel_64.c index 57df3d383470..aa5e287c98e0 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce_intel_64.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce_intel_64.c @@ -1,8 +1,6 @@ /* * Intel specific MCE features. * Copyright 2004 Zwane Mwaikambo - * Copyright (C) 2008, 2009 Intel Corporation - * Author: Andi Kleen */ #include @@ -15,7 +13,6 @@ #include #include #include -#include asmlinkage void smp_thermal_interrupt(void) { @@ -28,7 +25,7 @@ asmlinkage void smp_thermal_interrupt(void) rdmsrl(MSR_IA32_THERM_STATUS, msr_val); if (therm_throt_process(msr_val & 1)) - mce_log_therm_throt_event(msr_val); + mce_log_therm_throt_event(smp_processor_id(), msr_val); inc_irq_stat(irq_thermal_count); irq_exit(); @@ -88,209 +85,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) return; } -/* - * Support for Intel Correct Machine Check Interrupts. This allows - * the CPU to raise an interrupt when a corrected machine check happened. - * Normally we pick those up using a regular polling timer. - * Also supports reliable discovery of shared banks. - */ - -static DEFINE_PER_CPU(mce_banks_t, mce_banks_owned); - -/* - * cmci_discover_lock protects against parallel discovery attempts - * which could race against each other. - */ -static DEFINE_SPINLOCK(cmci_discover_lock); - -#define CMCI_THRESHOLD 1 - -static int cmci_supported(int *banks) -{ - u64 cap; - - /* - * Vendor check is not strictly needed, but the initial - * initialization is vendor keyed and this - * makes sure none of the backdoors are entered otherwise. - */ - if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) - return 0; - if (!cpu_has_apic || lapic_get_maxlvt() < 6) - return 0; - rdmsrl(MSR_IA32_MCG_CAP, cap); - *banks = min_t(unsigned, MAX_NR_BANKS, cap & 0xff); - return !!(cap & MCG_CMCI_P); -} - -/* - * The interrupt handler. This is called on every event. - * Just call the poller directly to log any events. - * This could in theory increase the threshold under high load, - * but doesn't for now. - */ -static void intel_threshold_interrupt(void) -{ - machine_check_poll(MCP_TIMESTAMP, &__get_cpu_var(mce_banks_owned)); - mce_notify_user(); -} - -static void print_update(char *type, int *hdr, int num) -{ - if (*hdr == 0) - printk(KERN_INFO "CPU %d MCA banks", smp_processor_id()); - *hdr = 1; - printk(KERN_CONT " %s:%d", type, num); -} - -/* - * Enable CMCI (Corrected Machine Check Interrupt) for available MCE banks - * on this CPU. Use the algorithm recommended in the SDM to discover shared - * banks. - */ -static void cmci_discover(int banks, int boot) -{ - unsigned long *owned = (void *)&__get_cpu_var(mce_banks_owned); - int hdr = 0; - int i; - - spin_lock(&cmci_discover_lock); - for (i = 0; i < banks; i++) { - u64 val; - - if (test_bit(i, owned)) - continue; - - rdmsrl(MSR_IA32_MC0_CTL2 + i, val); - - /* Already owned by someone else? */ - if (val & CMCI_EN) { - if (test_and_clear_bit(i, owned) || boot) - print_update("SHD", &hdr, i); - __clear_bit(i, __get_cpu_var(mce_poll_banks)); - continue; - } - - val |= CMCI_EN | CMCI_THRESHOLD; - wrmsrl(MSR_IA32_MC0_CTL2 + i, val); - rdmsrl(MSR_IA32_MC0_CTL2 + i, val); - - /* Did the enable bit stick? -- the bank supports CMCI */ - if (val & CMCI_EN) { - if (!test_and_set_bit(i, owned) || boot) - print_update("CMCI", &hdr, i); - __clear_bit(i, __get_cpu_var(mce_poll_banks)); - } else { - WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks))); - } - } - spin_unlock(&cmci_discover_lock); - if (hdr) - printk(KERN_CONT "\n"); -} - -/* - * Just in case we missed an event during initialization check - * all the CMCI owned banks. - */ -void cmci_recheck(void) -{ - unsigned long flags; - int banks; - - if (!mce_available(¤t_cpu_data) || !cmci_supported(&banks)) - return; - local_irq_save(flags); - machine_check_poll(MCP_TIMESTAMP, &__get_cpu_var(mce_banks_owned)); - local_irq_restore(flags); -} - -/* - * Disable CMCI on this CPU for all banks it owns when it goes down. - * This allows other CPUs to claim the banks on rediscovery. - */ -void cmci_clear(void) -{ - int i; - int banks; - u64 val; - - if (!cmci_supported(&banks)) - return; - spin_lock(&cmci_discover_lock); - for (i = 0; i < banks; i++) { - if (!test_bit(i, __get_cpu_var(mce_banks_owned))) - continue; - /* Disable CMCI */ - rdmsrl(MSR_IA32_MC0_CTL2 + i, val); - val &= ~(CMCI_EN|CMCI_THRESHOLD_MASK); - wrmsrl(MSR_IA32_MC0_CTL2 + i, val); - __clear_bit(i, __get_cpu_var(mce_banks_owned)); - } - spin_unlock(&cmci_discover_lock); -} - -/* - * After a CPU went down cycle through all the others and rediscover - * Must run in process context. - */ -void cmci_rediscover(int dying) -{ - int banks; - int cpu; - cpumask_var_t old; - - if (!cmci_supported(&banks)) - return; - if (!alloc_cpumask_var(&old, GFP_KERNEL)) - return; - cpumask_copy(old, ¤t->cpus_allowed); - - for_each_online_cpu (cpu) { - if (cpu == dying) - continue; - if (set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu))) - continue; - /* Recheck banks in case CPUs don't all have the same */ - if (cmci_supported(&banks)) - cmci_discover(banks, 0); - } - - set_cpus_allowed_ptr(current, old); - free_cpumask_var(old); -} - -/* - * Reenable CMCI on this CPU in case a CPU down failed. - */ -void cmci_reenable(void) -{ - int banks; - if (cmci_supported(&banks)) - cmci_discover(banks, 0); -} - -static void intel_init_cmci(void) -{ - int banks; - - if (!cmci_supported(&banks)) - return; - - mce_threshold_vector = intel_threshold_interrupt; - cmci_discover(banks, 1); - /* - * For CPU #0 this runs with still disabled APIC, but that's - * ok because only the vector is set up. We still do another - * check for the banks later for CPU #0 just to make sure - * to not miss any events. - */ - apic_write(APIC_LVTCMCI, THRESHOLD_APIC_VECTOR|APIC_DM_FIXED); - cmci_recheck(); -} - void mce_intel_feature_init(struct cpuinfo_x86 *c) { intel_init_thermal(c); - intel_init_cmci(); } diff --git a/trunk/arch/x86/kernel/cpu/mcheck/threshold.c b/trunk/arch/x86/kernel/cpu/mcheck/threshold.c deleted file mode 100644 index 23ee9e730f78..000000000000 --- a/trunk/arch/x86/kernel/cpu/mcheck/threshold.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Common corrected MCE threshold handler code: - */ -#include -#include - -#include -#include -#include -#include - -static void default_threshold_interrupt(void) -{ - printk(KERN_ERR "Unexpected threshold interrupt at vector %x\n", - THRESHOLD_APIC_VECTOR); -} - -void (*mce_threshold_vector)(void) = default_threshold_interrupt; - -asmlinkage void mce_threshold_interrupt(void) -{ - exit_idle(); - irq_enter(); - inc_irq_stat(irq_threshold_count); - mce_threshold_vector(); - irq_exit(); - /* Ack only at the end to avoid potential reentry */ - ack_APIC_irq(); -} diff --git a/trunk/arch/x86/kernel/cpu/mtrr/Makefile b/trunk/arch/x86/kernel/cpu/mtrr/Makefile index f4361b56f8e9..191fc0533649 100644 --- a/trunk/arch/x86/kernel/cpu/mtrr/Makefile +++ b/trunk/arch/x86/kernel/cpu/mtrr/Makefile @@ -1,3 +1,3 @@ -obj-y := main.o if.o generic.o state.o cleanup.o +obj-y := main.o if.o generic.o state.o obj-$(CONFIG_X86_32) += amd.o cyrix.o centaur.o diff --git a/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c b/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c deleted file mode 100644 index ce0fe4b5c04f..000000000000 --- a/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c +++ /dev/null @@ -1,1101 +0,0 @@ -/* MTRR (Memory Type Range Register) cleanup - - Copyright (C) 2009 Yinghai Lu - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include "mtrr.h" - -/* should be related to MTRR_VAR_RANGES nums */ -#define RANGE_NUM 256 - -struct res_range { - unsigned long start; - unsigned long end; -}; - -static int __init -add_range(struct res_range *range, int nr_range, unsigned long start, - unsigned long end) -{ - /* out of slots */ - if (nr_range >= RANGE_NUM) - return nr_range; - - range[nr_range].start = start; - range[nr_range].end = end; - - nr_range++; - - return nr_range; -} - -static int __init -add_range_with_merge(struct res_range *range, int nr_range, unsigned long start, - unsigned long end) -{ - int i; - - /* try to merge it with old one */ - for (i = 0; i < nr_range; i++) { - unsigned long final_start, final_end; - unsigned long common_start, common_end; - - if (!range[i].end) - continue; - - common_start = max(range[i].start, start); - common_end = min(range[i].end, end); - if (common_start > common_end + 1) - continue; - - final_start = min(range[i].start, start); - final_end = max(range[i].end, end); - - range[i].start = final_start; - range[i].end = final_end; - return nr_range; - } - - /* need to add that */ - return add_range(range, nr_range, start, end); -} - -static void __init -subtract_range(struct res_range *range, unsigned long start, unsigned long end) -{ - int i, j; - - for (j = 0; j < RANGE_NUM; j++) { - if (!range[j].end) - continue; - - if (start <= range[j].start && end >= range[j].end) { - range[j].start = 0; - range[j].end = 0; - continue; - } - - if (start <= range[j].start && end < range[j].end && - range[j].start < end + 1) { - range[j].start = end + 1; - continue; - } - - - if (start > range[j].start && end >= range[j].end && - range[j].end > start - 1) { - range[j].end = start - 1; - continue; - } - - if (start > range[j].start && end < range[j].end) { - /* find the new spare */ - for (i = 0; i < RANGE_NUM; i++) { - if (range[i].end == 0) - break; - } - if (i < RANGE_NUM) { - range[i].end = range[j].end; - range[i].start = end + 1; - } else { - printk(KERN_ERR "run of slot in ranges\n"); - } - range[j].end = start - 1; - continue; - } - } -} - -static int __init cmp_range(const void *x1, const void *x2) -{ - const struct res_range *r1 = x1; - const struct res_range *r2 = x2; - long start1, start2; - - start1 = r1->start; - start2 = r2->start; - - return start1 - start2; -} - -struct var_mtrr_range_state { - unsigned long base_pfn; - unsigned long size_pfn; - mtrr_type type; -}; - -static struct var_mtrr_range_state __initdata range_state[RANGE_NUM]; -static int __initdata debug_print; - -static int __init -x86_get_mtrr_mem_range(struct res_range *range, int nr_range, - unsigned long extra_remove_base, - unsigned long extra_remove_size) -{ - unsigned long base, size; - mtrr_type type; - int i; - - for (i = 0; i < num_var_ranges; i++) { - type = range_state[i].type; - if (type != MTRR_TYPE_WRBACK) - continue; - base = range_state[i].base_pfn; - size = range_state[i].size_pfn; - nr_range = add_range_with_merge(range, nr_range, base, - base + size - 1); - } - if (debug_print) { - printk(KERN_DEBUG "After WB checking\n"); - for (i = 0; i < nr_range; i++) - printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n", - range[i].start, range[i].end + 1); - } - - /* take out UC ranges */ - for (i = 0; i < num_var_ranges; i++) { - type = range_state[i].type; - if (type != MTRR_TYPE_UNCACHABLE && - type != MTRR_TYPE_WRPROT) - continue; - size = range_state[i].size_pfn; - if (!size) - continue; - base = range_state[i].base_pfn; - if (base < (1<<(20-PAGE_SHIFT)) && mtrr_state.have_fixed && - (mtrr_state.enabled & 1)) { - /* Var MTRR contains UC entry below 1M? Skip it: */ - printk(KERN_WARNING "WARNING: BIOS bug: VAR MTRR %d " - "contains strange UC entry under 1M, check " - "with your system vendor!\n", i); - if (base + size <= (1<<(20-PAGE_SHIFT))) - continue; - size -= (1<<(20-PAGE_SHIFT)) - base; - base = 1<<(20-PAGE_SHIFT); - } - subtract_range(range, base, base + size - 1); - } - if (extra_remove_size) - subtract_range(range, extra_remove_base, - extra_remove_base + extra_remove_size - 1); - - /* get new range num */ - nr_range = 0; - for (i = 0; i < RANGE_NUM; i++) { - if (!range[i].end) - continue; - nr_range++; - } - if (debug_print) { - printk(KERN_DEBUG "After UC checking\n"); - for (i = 0; i < nr_range; i++) - printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n", - range[i].start, range[i].end + 1); - } - - /* sort the ranges */ - sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL); - if (debug_print) { - printk(KERN_DEBUG "After sorting\n"); - for (i = 0; i < nr_range; i++) - printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n", - range[i].start, range[i].end + 1); - } - - /* clear those is not used */ - for (i = nr_range; i < RANGE_NUM; i++) - memset(&range[i], 0, sizeof(range[i])); - - return nr_range; -} - -static struct res_range __initdata range[RANGE_NUM]; -static int __initdata nr_range; - -#ifdef CONFIG_MTRR_SANITIZER - -static unsigned long __init sum_ranges(struct res_range *range, int nr_range) -{ - unsigned long sum; - int i; - - sum = 0; - for (i = 0; i < nr_range; i++) - sum += range[i].end + 1 - range[i].start; - - return sum; -} - -static int enable_mtrr_cleanup __initdata = - CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT; - -static int __init disable_mtrr_cleanup_setup(char *str) -{ - enable_mtrr_cleanup = 0; - return 0; -} -early_param("disable_mtrr_cleanup", disable_mtrr_cleanup_setup); - -static int __init enable_mtrr_cleanup_setup(char *str) -{ - enable_mtrr_cleanup = 1; - return 0; -} -early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup); - -static int __init mtrr_cleanup_debug_setup(char *str) -{ - debug_print = 1; - return 0; -} -early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup); - -struct var_mtrr_state { - unsigned long range_startk; - unsigned long range_sizek; - unsigned long chunk_sizek; - unsigned long gran_sizek; - unsigned int reg; -}; - -static void __init -set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, - unsigned char type, unsigned int address_bits) -{ - u32 base_lo, base_hi, mask_lo, mask_hi; - u64 base, mask; - - if (!sizek) { - fill_mtrr_var_range(reg, 0, 0, 0, 0); - return; - } - - mask = (1ULL << address_bits) - 1; - mask &= ~((((u64)sizek) << 10) - 1); - - base = ((u64)basek) << 10; - - base |= type; - mask |= 0x800; - - base_lo = base & ((1ULL<<32) - 1); - base_hi = base >> 32; - - mask_lo = mask & ((1ULL<<32) - 1); - mask_hi = mask >> 32; - - fill_mtrr_var_range(reg, base_lo, base_hi, mask_lo, mask_hi); -} - -static void __init -save_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, - unsigned char type) -{ - range_state[reg].base_pfn = basek >> (PAGE_SHIFT - 10); - range_state[reg].size_pfn = sizek >> (PAGE_SHIFT - 10); - range_state[reg].type = type; -} - -static void __init -set_var_mtrr_all(unsigned int address_bits) -{ - unsigned long basek, sizek; - unsigned char type; - unsigned int reg; - - for (reg = 0; reg < num_var_ranges; reg++) { - basek = range_state[reg].base_pfn << (PAGE_SHIFT - 10); - sizek = range_state[reg].size_pfn << (PAGE_SHIFT - 10); - type = range_state[reg].type; - - set_var_mtrr(reg, basek, sizek, type, address_bits); - } -} - -static unsigned long to_size_factor(unsigned long sizek, char *factorp) -{ - char factor; - unsigned long base = sizek; - - if (base & ((1<<10) - 1)) { - /* not MB alignment */ - factor = 'K'; - } else if (base & ((1<<20) - 1)) { - factor = 'M'; - base >>= 10; - } else { - factor = 'G'; - base >>= 20; - } - - *factorp = factor; - - return base; -} - -static unsigned int __init -range_to_mtrr(unsigned int reg, unsigned long range_startk, - unsigned long range_sizek, unsigned char type) -{ - if (!range_sizek || (reg >= num_var_ranges)) - return reg; - - while (range_sizek) { - unsigned long max_align, align; - unsigned long sizek; - - /* Compute the maximum size I can make a range */ - if (range_startk) - max_align = ffs(range_startk) - 1; - else - max_align = 32; - align = fls(range_sizek) - 1; - if (align > max_align) - align = max_align; - - sizek = 1 << align; - if (debug_print) { - char start_factor = 'K', size_factor = 'K'; - unsigned long start_base, size_base; - - start_base = to_size_factor(range_startk, - &start_factor), - size_base = to_size_factor(sizek, &size_factor), - - printk(KERN_DEBUG "Setting variable MTRR %d, " - "base: %ld%cB, range: %ld%cB, type %s\n", - reg, start_base, start_factor, - size_base, size_factor, - (type == MTRR_TYPE_UNCACHABLE) ? "UC" : - ((type == MTRR_TYPE_WRBACK) ? "WB" : "Other") - ); - } - save_var_mtrr(reg++, range_startk, sizek, type); - range_startk += sizek; - range_sizek -= sizek; - if (reg >= num_var_ranges) - break; - } - return reg; -} - -static unsigned __init -range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek, - unsigned long sizek) -{ - unsigned long hole_basek, hole_sizek; - unsigned long second_basek, second_sizek; - unsigned long range0_basek, range0_sizek; - unsigned long range_basek, range_sizek; - unsigned long chunk_sizek; - unsigned long gran_sizek; - - hole_basek = 0; - hole_sizek = 0; - second_basek = 0; - second_sizek = 0; - chunk_sizek = state->chunk_sizek; - gran_sizek = state->gran_sizek; - - /* align with gran size, prevent small block used up MTRRs */ - range_basek = ALIGN(state->range_startk, gran_sizek); - if ((range_basek > basek) && basek) - return second_sizek; - state->range_sizek -= (range_basek - state->range_startk); - range_sizek = ALIGN(state->range_sizek, gran_sizek); - - while (range_sizek > state->range_sizek) { - range_sizek -= gran_sizek; - if (!range_sizek) - return 0; - } - state->range_sizek = range_sizek; - - /* try to append some small hole */ - range0_basek = state->range_startk; - range0_sizek = ALIGN(state->range_sizek, chunk_sizek); - - /* no increase */ - if (range0_sizek == state->range_sizek) { - if (debug_print) - printk(KERN_DEBUG "rangeX: %016lx - %016lx\n", - range0_basek<<10, - (range0_basek + state->range_sizek)<<10); - state->reg = range_to_mtrr(state->reg, range0_basek, - state->range_sizek, MTRR_TYPE_WRBACK); - return 0; - } - - /* only cut back, when it is not the last */ - if (sizek) { - while (range0_basek + range0_sizek > (basek + sizek)) { - if (range0_sizek >= chunk_sizek) - range0_sizek -= chunk_sizek; - else - range0_sizek = 0; - - if (!range0_sizek) - break; - } - } - -second_try: - range_basek = range0_basek + range0_sizek; - - /* one hole in the middle */ - if (range_basek > basek && range_basek <= (basek + sizek)) - second_sizek = range_basek - basek; - - if (range0_sizek > state->range_sizek) { - - /* one hole in middle or at end */ - hole_sizek = range0_sizek - state->range_sizek - second_sizek; - - /* hole size should be less than half of range0 size */ - if (hole_sizek >= (range0_sizek >> 1) && - range0_sizek >= chunk_sizek) { - range0_sizek -= chunk_sizek; - second_sizek = 0; - hole_sizek = 0; - - goto second_try; - } - } - - if (range0_sizek) { - if (debug_print) - printk(KERN_DEBUG "range0: %016lx - %016lx\n", - range0_basek<<10, - (range0_basek + range0_sizek)<<10); - state->reg = range_to_mtrr(state->reg, range0_basek, - range0_sizek, MTRR_TYPE_WRBACK); - } - - if (range0_sizek < state->range_sizek) { - /* need to handle left over */ - range_sizek = state->range_sizek - range0_sizek; - - if (debug_print) - printk(KERN_DEBUG "range: %016lx - %016lx\n", - range_basek<<10, - (range_basek + range_sizek)<<10); - state->reg = range_to_mtrr(state->reg, range_basek, - range_sizek, MTRR_TYPE_WRBACK); - } - - if (hole_sizek) { - hole_basek = range_basek - hole_sizek - second_sizek; - if (debug_print) - printk(KERN_DEBUG "hole: %016lx - %016lx\n", - hole_basek<<10, - (hole_basek + hole_sizek)<<10); - state->reg = range_to_mtrr(state->reg, hole_basek, - hole_sizek, MTRR_TYPE_UNCACHABLE); - } - - return second_sizek; -} - -static void __init -set_var_mtrr_range(struct var_mtrr_state *state, unsigned long base_pfn, - unsigned long size_pfn) -{ - unsigned long basek, sizek; - unsigned long second_sizek = 0; - - if (state->reg >= num_var_ranges) - return; - - basek = base_pfn << (PAGE_SHIFT - 10); - sizek = size_pfn << (PAGE_SHIFT - 10); - - /* See if I can merge with the last range */ - if ((basek <= 1024) || - (state->range_startk + state->range_sizek == basek)) { - unsigned long endk = basek + sizek; - state->range_sizek = endk - state->range_startk; - return; - } - /* Write the range mtrrs */ - if (state->range_sizek != 0) - second_sizek = range_to_mtrr_with_hole(state, basek, sizek); - - /* Allocate an msr */ - state->range_startk = basek + second_sizek; - state->range_sizek = sizek - second_sizek; -} - -/* mininum size of mtrr block that can take hole */ -static u64 mtrr_chunk_size __initdata = (256ULL<<20); - -static int __init parse_mtrr_chunk_size_opt(char *p) -{ - if (!p) - return -EINVAL; - mtrr_chunk_size = memparse(p, &p); - return 0; -} -early_param("mtrr_chunk_size", parse_mtrr_chunk_size_opt); - -/* granity of mtrr of block */ -static u64 mtrr_gran_size __initdata; - -static int __init parse_mtrr_gran_size_opt(char *p) -{ - if (!p) - return -EINVAL; - mtrr_gran_size = memparse(p, &p); - return 0; -} -early_param("mtrr_gran_size", parse_mtrr_gran_size_opt); - -static int nr_mtrr_spare_reg __initdata = - CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT; - -static int __init parse_mtrr_spare_reg(char *arg) -{ - if (arg) - nr_mtrr_spare_reg = simple_strtoul(arg, NULL, 0); - return 0; -} - -early_param("mtrr_spare_reg_nr", parse_mtrr_spare_reg); - -static int __init -x86_setup_var_mtrrs(struct res_range *range, int nr_range, - u64 chunk_size, u64 gran_size) -{ - struct var_mtrr_state var_state; - int i; - int num_reg; - - var_state.range_startk = 0; - var_state.range_sizek = 0; - var_state.reg = 0; - var_state.chunk_sizek = chunk_size >> 10; - var_state.gran_sizek = gran_size >> 10; - - memset(range_state, 0, sizeof(range_state)); - - /* Write the range etc */ - for (i = 0; i < nr_range; i++) - set_var_mtrr_range(&var_state, range[i].start, - range[i].end - range[i].start + 1); - - /* Write the last range */ - if (var_state.range_sizek != 0) - range_to_mtrr_with_hole(&var_state, 0, 0); - - num_reg = var_state.reg; - /* Clear out the extra MTRR's */ - while (var_state.reg < num_var_ranges) { - save_var_mtrr(var_state.reg, 0, 0, 0); - var_state.reg++; - } - - return num_reg; -} - -struct mtrr_cleanup_result { - unsigned long gran_sizek; - unsigned long chunk_sizek; - unsigned long lose_cover_sizek; - unsigned int num_reg; - int bad; -}; - -/* - * gran_size: 64K, 128K, 256K, 512K, 1M, 2M, ..., 2G - * chunk size: gran_size, ..., 2G - * so we need (1+16)*8 - */ -#define NUM_RESULT 136 -#define PSHIFT (PAGE_SHIFT - 10) - -static struct mtrr_cleanup_result __initdata result[NUM_RESULT]; -static unsigned long __initdata min_loss_pfn[RANGE_NUM]; - -static void __init print_out_mtrr_range_state(void) -{ - int i; - char start_factor = 'K', size_factor = 'K'; - unsigned long start_base, size_base; - mtrr_type type; - - for (i = 0; i < num_var_ranges; i++) { - - size_base = range_state[i].size_pfn << (PAGE_SHIFT - 10); - if (!size_base) - continue; - - size_base = to_size_factor(size_base, &size_factor), - start_base = range_state[i].base_pfn << (PAGE_SHIFT - 10); - start_base = to_size_factor(start_base, &start_factor), - type = range_state[i].type; - - printk(KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n", - i, start_base, start_factor, - size_base, size_factor, - (type == MTRR_TYPE_UNCACHABLE) ? "UC" : - ((type == MTRR_TYPE_WRPROT) ? "WP" : - ((type == MTRR_TYPE_WRBACK) ? "WB" : "Other")) - ); - } -} - -static int __init mtrr_need_cleanup(void) -{ - int i; - mtrr_type type; - unsigned long size; - /* extra one for all 0 */ - int num[MTRR_NUM_TYPES + 1]; - - /* check entries number */ - memset(num, 0, sizeof(num)); - for (i = 0; i < num_var_ranges; i++) { - type = range_state[i].type; - size = range_state[i].size_pfn; - if (type >= MTRR_NUM_TYPES) - continue; - if (!size) - type = MTRR_NUM_TYPES; - if (type == MTRR_TYPE_WRPROT) - type = MTRR_TYPE_UNCACHABLE; - num[type]++; - } - - /* check if we got UC entries */ - if (!num[MTRR_TYPE_UNCACHABLE]) - return 0; - - /* check if we only had WB and UC */ - if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] != - num_var_ranges - num[MTRR_NUM_TYPES]) - return 0; - - return 1; -} - -static unsigned long __initdata range_sums; -static void __init mtrr_calc_range_state(u64 chunk_size, u64 gran_size, - unsigned long extra_remove_base, - unsigned long extra_remove_size, - int i) -{ - int num_reg; - static struct res_range range_new[RANGE_NUM]; - static int nr_range_new; - unsigned long range_sums_new; - - /* convert ranges to var ranges state */ - num_reg = x86_setup_var_mtrrs(range, nr_range, - chunk_size, gran_size); - - /* we got new setting in range_state, check it */ - memset(range_new, 0, sizeof(range_new)); - nr_range_new = x86_get_mtrr_mem_range(range_new, 0, - extra_remove_base, extra_remove_size); - range_sums_new = sum_ranges(range_new, nr_range_new); - - result[i].chunk_sizek = chunk_size >> 10; - result[i].gran_sizek = gran_size >> 10; - result[i].num_reg = num_reg; - if (range_sums < range_sums_new) { - result[i].lose_cover_sizek = - (range_sums_new - range_sums) << PSHIFT; - result[i].bad = 1; - } else - result[i].lose_cover_sizek = - (range_sums - range_sums_new) << PSHIFT; - - /* double check it */ - if (!result[i].bad && !result[i].lose_cover_sizek) { - if (nr_range_new != nr_range || - memcmp(range, range_new, sizeof(range))) - result[i].bad = 1; - } - - if (!result[i].bad && (range_sums - range_sums_new < - min_loss_pfn[num_reg])) { - min_loss_pfn[num_reg] = - range_sums - range_sums_new; - } -} - -static void __init mtrr_print_out_one_result(int i) -{ - char gran_factor, chunk_factor, lose_factor; - unsigned long gran_base, chunk_base, lose_base; - - gran_base = to_size_factor(result[i].gran_sizek, &gran_factor), - chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor), - lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor), - printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t", - result[i].bad ? "*BAD*" : " ", - gran_base, gran_factor, chunk_base, chunk_factor); - printk(KERN_CONT "num_reg: %d \tlose cover RAM: %s%ld%c\n", - result[i].num_reg, result[i].bad ? "-" : "", - lose_base, lose_factor); -} - -static int __init mtrr_search_optimal_index(void) -{ - int i; - int num_reg_good; - int index_good; - - if (nr_mtrr_spare_reg >= num_var_ranges) - nr_mtrr_spare_reg = num_var_ranges - 1; - num_reg_good = -1; - for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) { - if (!min_loss_pfn[i]) - num_reg_good = i; - } - - index_good = -1; - if (num_reg_good != -1) { - for (i = 0; i < NUM_RESULT; i++) { - if (!result[i].bad && - result[i].num_reg == num_reg_good && - !result[i].lose_cover_sizek) { - index_good = i; - break; - } - } - } - - return index_good; -} - - -int __init mtrr_cleanup(unsigned address_bits) -{ - unsigned long extra_remove_base, extra_remove_size; - unsigned long base, size, def, dummy; - mtrr_type type; - u64 chunk_size, gran_size; - int index_good; - int i; - - if (!is_cpu(INTEL) || enable_mtrr_cleanup < 1) - return 0; - rdmsr(MTRRdefType_MSR, def, dummy); - def &= 0xff; - if (def != MTRR_TYPE_UNCACHABLE) - return 0; - - /* get it and store it aside */ - memset(range_state, 0, sizeof(range_state)); - for (i = 0; i < num_var_ranges; i++) { - mtrr_if->get(i, &base, &size, &type); - range_state[i].base_pfn = base; - range_state[i].size_pfn = size; - range_state[i].type = type; - } - - /* check if we need handle it and can handle it */ - if (!mtrr_need_cleanup()) - return 0; - - /* print original var MTRRs at first, for debugging: */ - printk(KERN_DEBUG "original variable MTRRs\n"); - print_out_mtrr_range_state(); - - memset(range, 0, sizeof(range)); - extra_remove_size = 0; - extra_remove_base = 1 << (32 - PAGE_SHIFT); - if (mtrr_tom2) - extra_remove_size = - (mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base; - nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base, - extra_remove_size); - /* - * [0, 1M) should always be coverred by var mtrr with WB - * and fixed mtrrs should take effective before var mtrr for it - */ - nr_range = add_range_with_merge(range, nr_range, 0, - (1ULL<<(20 - PAGE_SHIFT)) - 1); - /* sort the ranges */ - sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL); - - range_sums = sum_ranges(range, nr_range); - printk(KERN_INFO "total RAM coverred: %ldM\n", - range_sums >> (20 - PAGE_SHIFT)); - - if (mtrr_chunk_size && mtrr_gran_size) { - i = 0; - mtrr_calc_range_state(mtrr_chunk_size, mtrr_gran_size, - extra_remove_base, extra_remove_size, i); - - mtrr_print_out_one_result(i); - - if (!result[i].bad) { - set_var_mtrr_all(address_bits); - printk(KERN_DEBUG "New variable MTRRs\n"); - print_out_mtrr_range_state(); - return 1; - } - printk(KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, " - "will find optimal one\n"); - } - - i = 0; - memset(min_loss_pfn, 0xff, sizeof(min_loss_pfn)); - memset(result, 0, sizeof(result)); - for (gran_size = (1ULL<<16); gran_size < (1ULL<<32); gran_size <<= 1) { - - for (chunk_size = gran_size; chunk_size < (1ULL<<32); - chunk_size <<= 1) { - - if (i >= NUM_RESULT) - continue; - - mtrr_calc_range_state(chunk_size, gran_size, - extra_remove_base, extra_remove_size, i); - if (debug_print) { - mtrr_print_out_one_result(i); - printk(KERN_INFO "\n"); - } - - i++; - } - } - - /* try to find the optimal index */ - index_good = mtrr_search_optimal_index(); - - if (index_good != -1) { - printk(KERN_INFO "Found optimal setting for mtrr clean up\n"); - i = index_good; - mtrr_print_out_one_result(i); - - /* convert ranges to var ranges state */ - chunk_size = result[i].chunk_sizek; - chunk_size <<= 10; - gran_size = result[i].gran_sizek; - gran_size <<= 10; - x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size); - set_var_mtrr_all(address_bits); - printk(KERN_DEBUG "New variable MTRRs\n"); - print_out_mtrr_range_state(); - return 1; - } else { - /* print out all */ - for (i = 0; i < NUM_RESULT; i++) - mtrr_print_out_one_result(i); - } - - printk(KERN_INFO "mtrr_cleanup: can not find optimal value\n"); - printk(KERN_INFO "please specify mtrr_gran_size/mtrr_chunk_size\n"); - - return 0; -} -#else -int __init mtrr_cleanup(unsigned address_bits) -{ - return 0; -} -#endif - -static int disable_mtrr_trim; - -static int __init disable_mtrr_trim_setup(char *str) -{ - disable_mtrr_trim = 1; - return 0; -} -early_param("disable_mtrr_trim", disable_mtrr_trim_setup); - -/* - * Newer AMD K8s and later CPUs have a special magic MSR way to force WB - * for memory >4GB. Check for that here. - * Note this won't check if the MTRRs < 4GB where the magic bit doesn't - * apply to are wrong, but so far we don't know of any such case in the wild. - */ -#define Tom2Enabled (1U << 21) -#define Tom2ForceMemTypeWB (1U << 22) - -int __init amd_special_default_mtrr(void) -{ - u32 l, h; - - if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) - return 0; - if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11) - return 0; - /* In case some hypervisor doesn't pass SYSCFG through */ - if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0) - return 0; - /* - * Memory between 4GB and top of mem is forced WB by this magic bit. - * Reserved before K8RevF, but should be zero there. - */ - if ((l & (Tom2Enabled | Tom2ForceMemTypeWB)) == - (Tom2Enabled | Tom2ForceMemTypeWB)) - return 1; - return 0; -} - -static u64 __init real_trim_memory(unsigned long start_pfn, - unsigned long limit_pfn) -{ - u64 trim_start, trim_size; - trim_start = start_pfn; - trim_start <<= PAGE_SHIFT; - trim_size = limit_pfn; - trim_size <<= PAGE_SHIFT; - trim_size -= trim_start; - - return e820_update_range(trim_start, trim_size, E820_RAM, - E820_RESERVED); -} -/** - * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs - * @end_pfn: ending page frame number - * - * Some buggy BIOSes don't setup the MTRRs properly for systems with certain - * memory configurations. This routine checks that the highest MTRR matches - * the end of memory, to make sure the MTRRs having a write back type cover - * all of the memory the kernel is intending to use. If not, it'll trim any - * memory off the end by adjusting end_pfn, removing it from the kernel's - * allocation pools, warning the user with an obnoxious message. - */ -int __init mtrr_trim_uncached_memory(unsigned long end_pfn) -{ - unsigned long i, base, size, highest_pfn = 0, def, dummy; - mtrr_type type; - u64 total_trim_size; - - /* extra one for all 0 */ - int num[MTRR_NUM_TYPES + 1]; - /* - * Make sure we only trim uncachable memory on machines that - * support the Intel MTRR architecture: - */ - if (!is_cpu(INTEL) || disable_mtrr_trim) - return 0; - rdmsr(MTRRdefType_MSR, def, dummy); - def &= 0xff; - if (def != MTRR_TYPE_UNCACHABLE) - return 0; - - /* get it and store it aside */ - memset(range_state, 0, sizeof(range_state)); - for (i = 0; i < num_var_ranges; i++) { - mtrr_if->get(i, &base, &size, &type); - range_state[i].base_pfn = base; - range_state[i].size_pfn = size; - range_state[i].type = type; - } - - /* Find highest cached pfn */ - for (i = 0; i < num_var_ranges; i++) { - type = range_state[i].type; - if (type != MTRR_TYPE_WRBACK) - continue; - base = range_state[i].base_pfn; - size = range_state[i].size_pfn; - if (highest_pfn < base + size) - highest_pfn = base + size; - } - - /* kvm/qemu doesn't have mtrr set right, don't trim them all */ - if (!highest_pfn) { - printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n"); - return 0; - } - - /* check entries number */ - memset(num, 0, sizeof(num)); - for (i = 0; i < num_var_ranges; i++) { - type = range_state[i].type; - if (type >= MTRR_NUM_TYPES) - continue; - size = range_state[i].size_pfn; - if (!size) - type = MTRR_NUM_TYPES; - num[type]++; - } - - /* no entry for WB? */ - if (!num[MTRR_TYPE_WRBACK]) - return 0; - - /* check if we only had WB and UC */ - if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] != - num_var_ranges - num[MTRR_NUM_TYPES]) - return 0; - - memset(range, 0, sizeof(range)); - nr_range = 0; - if (mtrr_tom2) { - range[nr_range].start = (1ULL<<(32 - PAGE_SHIFT)); - range[nr_range].end = (mtrr_tom2 >> PAGE_SHIFT) - 1; - if (highest_pfn < range[nr_range].end + 1) - highest_pfn = range[nr_range].end + 1; - nr_range++; - } - nr_range = x86_get_mtrr_mem_range(range, nr_range, 0, 0); - - total_trim_size = 0; - /* check the head */ - if (range[0].start) - total_trim_size += real_trim_memory(0, range[0].start); - /* check the holes */ - for (i = 0; i < nr_range - 1; i++) { - if (range[i].end + 1 < range[i+1].start) - total_trim_size += real_trim_memory(range[i].end + 1, - range[i+1].start); - } - /* check the top */ - i = nr_range - 1; - if (range[i].end + 1 < end_pfn) - total_trim_size += real_trim_memory(range[i].end + 1, - end_pfn); - - if (total_trim_size) { - printk(KERN_WARNING "WARNING: BIOS bug: CPU MTRRs don't cover" - " all of memory, losing %lluMB of RAM.\n", - total_trim_size >> 20); - - if (!changed_by_mtrr_cleanup) - WARN_ON(1); - - printk(KERN_INFO "update e820 for mtrr\n"); - update_e820(); - - return 1; - } - - return 0; -} - diff --git a/trunk/arch/x86/kernel/cpu/mtrr/generic.c b/trunk/arch/x86/kernel/cpu/mtrr/generic.c index 37f28fc7cf95..0c0a455fe95c 100644 --- a/trunk/arch/x86/kernel/cpu/mtrr/generic.c +++ b/trunk/arch/x86/kernel/cpu/mtrr/generic.c @@ -33,31 +33,13 @@ u64 mtrr_tom2; struct mtrr_state_type mtrr_state = {}; EXPORT_SYMBOL_GPL(mtrr_state); -/** - * BIOS is expected to clear MtrrFixDramModEn bit, see for example - * "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD - * Opteron Processors" (26094 Rev. 3.30 February 2006), section - * "13.2.1.2 SYSCFG Register": "The MtrrFixDramModEn bit should be set - * to 1 during BIOS initalization of the fixed MTRRs, then cleared to - * 0 for operation." - */ -static inline void k8_check_syscfg_dram_mod_en(void) +static int __initdata mtrr_show; +static int __init mtrr_debug(char *opt) { - u32 lo, hi; - - if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && - (boot_cpu_data.x86 >= 0x0f))) - return; - - rdmsr(MSR_K8_SYSCFG, lo, hi); - if (lo & K8_MTRRFIXRANGE_DRAM_MODIFY) { - printk(KERN_ERR FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]" - " not cleared by BIOS, clearing this bit\n", - smp_processor_id()); - lo &= ~K8_MTRRFIXRANGE_DRAM_MODIFY; - mtrr_wrmsr(MSR_K8_SYSCFG, lo, hi); - } + mtrr_show = 1; + return 0; } +early_param("mtrr.show", mtrr_debug); /* * Returns the effective MTRR type for the region @@ -192,8 +174,6 @@ get_fixed_ranges(mtrr_type * frs) unsigned int *p = (unsigned int *) frs; int i; - k8_check_syscfg_dram_mod_en(); - rdmsr(MTRRfix64K_00000_MSR, p[0], p[1]); for (i = 0; i < 2; i++) @@ -208,94 +188,18 @@ void mtrr_save_fixed_ranges(void *info) get_fixed_ranges(mtrr_state.fixed_ranges); } -static unsigned __initdata last_fixed_start; -static unsigned __initdata last_fixed_end; -static mtrr_type __initdata last_fixed_type; - -static void __init print_fixed_last(void) -{ - if (!last_fixed_end) - return; - - printk(KERN_DEBUG " %05X-%05X %s\n", last_fixed_start, - last_fixed_end - 1, mtrr_attrib_to_str(last_fixed_type)); - - last_fixed_end = 0; -} - -static void __init update_fixed_last(unsigned base, unsigned end, - mtrr_type type) -{ - last_fixed_start = base; - last_fixed_end = end; - last_fixed_type = type; -} - -static void __init print_fixed(unsigned base, unsigned step, - const mtrr_type *types) +static void print_fixed(unsigned base, unsigned step, const mtrr_type*types) { unsigned i; - for (i = 0; i < 8; ++i, ++types, base += step) { - if (last_fixed_end == 0) { - update_fixed_last(base, base + step, *types); - continue; - } - if (last_fixed_end == base && last_fixed_type == *types) { - last_fixed_end = base + step; - continue; - } - /* new segments: gap or different type */ - print_fixed_last(); - update_fixed_last(base, base + step, *types); - } + for (i = 0; i < 8; ++i, ++types, base += step) + printk(KERN_INFO "MTRR %05X-%05X %s\n", + base, base + step - 1, mtrr_attrib_to_str(*types)); } static void prepare_set(void); static void post_set(void); -static void __init print_mtrr_state(void) -{ - unsigned int i; - int high_width; - - printk(KERN_DEBUG "MTRR default type: %s\n", - mtrr_attrib_to_str(mtrr_state.def_type)); - if (mtrr_state.have_fixed) { - printk(KERN_DEBUG "MTRR fixed ranges %sabled:\n", - mtrr_state.enabled & 1 ? "en" : "dis"); - print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0); - for (i = 0; i < 2; ++i) - print_fixed(0x80000 + i * 0x20000, 0x04000, mtrr_state.fixed_ranges + (i + 1) * 8); - for (i = 0; i < 8; ++i) - print_fixed(0xC0000 + i * 0x08000, 0x01000, mtrr_state.fixed_ranges + (i + 3) * 8); - - /* tail */ - print_fixed_last(); - } - printk(KERN_DEBUG "MTRR variable ranges %sabled:\n", - mtrr_state.enabled & 2 ? "en" : "dis"); - high_width = ((size_or_mask ? ffs(size_or_mask) - 1 : 32) - (32 - PAGE_SHIFT) + 3) / 4; - for (i = 0; i < num_var_ranges; ++i) { - if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) - printk(KERN_DEBUG " %u base %0*X%05X000 mask %0*X%05X000 %s\n", - i, - high_width, - mtrr_state.var_ranges[i].base_hi, - mtrr_state.var_ranges[i].base_lo >> 12, - high_width, - mtrr_state.var_ranges[i].mask_hi, - mtrr_state.var_ranges[i].mask_lo >> 12, - mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff)); - else - printk(KERN_DEBUG " %u disabled\n", i); - } - if (mtrr_tom2) { - printk(KERN_DEBUG "TOM2: %016llx aka %lldM\n", - mtrr_tom2, mtrr_tom2>>20); - } -} - /* Grab all of the MTRR state for this CPU into *state */ void __init get_mtrr_state(void) { @@ -327,9 +231,41 @@ void __init get_mtrr_state(void) mtrr_tom2 |= low; mtrr_tom2 &= 0xffffff800000ULL; } - - print_mtrr_state(); - + if (mtrr_show) { + int high_width; + + printk(KERN_INFO "MTRR default type: %s\n", mtrr_attrib_to_str(mtrr_state.def_type)); + if (mtrr_state.have_fixed) { + printk(KERN_INFO "MTRR fixed ranges %sabled:\n", + mtrr_state.enabled & 1 ? "en" : "dis"); + print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0); + for (i = 0; i < 2; ++i) + print_fixed(0x80000 + i * 0x20000, 0x04000, mtrr_state.fixed_ranges + (i + 1) * 8); + for (i = 0; i < 8; ++i) + print_fixed(0xC0000 + i * 0x08000, 0x01000, mtrr_state.fixed_ranges + (i + 3) * 8); + } + printk(KERN_INFO "MTRR variable ranges %sabled:\n", + mtrr_state.enabled & 2 ? "en" : "dis"); + high_width = ((size_or_mask ? ffs(size_or_mask) - 1 : 32) - (32 - PAGE_SHIFT) + 3) / 4; + for (i = 0; i < num_var_ranges; ++i) { + if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) + printk(KERN_INFO "MTRR %u base %0*X%05X000 mask %0*X%05X000 %s\n", + i, + high_width, + mtrr_state.var_ranges[i].base_hi, + mtrr_state.var_ranges[i].base_lo >> 12, + high_width, + mtrr_state.var_ranges[i].mask_hi, + mtrr_state.var_ranges[i].mask_lo >> 12, + mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff)); + else + printk(KERN_INFO "MTRR %u disabled\n", i); + } + if (mtrr_tom2) { + printk(KERN_INFO "TOM2: %016llx aka %lldM\n", + mtrr_tom2, mtrr_tom2>>20); + } + } mtrr_state_set = 1; /* PAT setup for BP. We need to go through sync steps here */ @@ -371,11 +307,28 @@ void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b) smp_processor_id(), msr, a, b); } +/** + * Enable and allow read/write of extended fixed-range MTRR bits on K8 CPUs + * see AMD publication no. 24593, chapter 3.2.1 for more information + */ +static inline void k8_enable_fixed_iorrs(void) +{ + unsigned lo, hi; + + rdmsr(MSR_K8_SYSCFG, lo, hi); + mtrr_wrmsr(MSR_K8_SYSCFG, lo + | K8_MTRRFIXRANGE_DRAM_ENABLE + | K8_MTRRFIXRANGE_DRAM_MODIFY, hi); +} + /** * set_fixed_range - checks & updates a fixed-range MTRR if it differs from the value it should have * @msr: MSR address of the MTTR which should be checked and updated * @changed: pointer which indicates whether the MTRR needed to be changed * @msrwords: pointer to the MSR values which the MSR should have + * + * If K8 extentions are wanted, update the K8 SYSCFG MSR also. + * See AMD publication no. 24593, chapter 7.8.1, page 233 for more information. */ static void set_fixed_range(int msr, bool *changed, unsigned int *msrwords) { @@ -384,6 +337,10 @@ static void set_fixed_range(int msr, bool *changed, unsigned int *msrwords) rdmsr(msr, lo, hi); if (lo != msrwords[0] || hi != msrwords[1]) { + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && + (boot_cpu_data.x86 >= 0x0f && boot_cpu_data.x86 <= 0x11) && + ((msrwords[0] | msrwords[1]) & K8_MTRR_RDMEM_WRMEM_MASK)) + k8_enable_fixed_iorrs(); mtrr_wrmsr(msr, msrwords[0], msrwords[1]); *changed = true; } @@ -419,31 +376,22 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, { unsigned int mask_lo, mask_hi, base_lo, base_hi; unsigned int tmp, hi; - int cpu; - - /* - * get_mtrr doesn't need to update mtrr_state, also it could be called - * from any cpu, so try to print it out directly. - */ - cpu = get_cpu(); rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi); - if ((mask_lo & 0x800) == 0) { /* Invalid (i.e. free) range */ *base = 0; *size = 0; *type = 0; - goto out_put_cpu; + return; } rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi); - /* Work out the shifted address mask: */ + /* Work out the shifted address mask. */ tmp = mask_hi << (32 - PAGE_SHIFT) | mask_lo >> PAGE_SHIFT; mask_lo = size_or_mask | tmp; - - /* Expand tmp with high bits to all 1s: */ + /* Expand tmp with high bits to all 1s*/ hi = fls(tmp); if (hi > 0) { tmp |= ~((1<<(hi - 1)) - 1); @@ -454,19 +402,11 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, } } - /* - * This works correctly if size is a power of two, i.e. a - * contiguous range: - */ + /* This works correctly if size is a power of two, i.e. a + contiguous range. */ *size = -mask_lo; *base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT; *type = base_lo & 0xff; - - printk(KERN_DEBUG " get_mtrr: cpu%d reg%02d base=%010lx size=%010lx %s\n", - cpu, reg, *base, *size, - mtrr_attrib_to_str(*type & 0xff)); -out_put_cpu: - put_cpu(); } /** @@ -479,8 +419,6 @@ static int set_fixed_ranges(mtrr_type * frs) bool changed = false; int block=-1, range; - k8_check_syscfg_dram_mod_en(); - while (fixed_range_blocks[++block].ranges) for (range=0; range < fixed_range_blocks[block].ranges; range++) set_fixed_range(fixed_range_blocks[block].base_msr + range, diff --git a/trunk/arch/x86/kernel/cpu/mtrr/if.c b/trunk/arch/x86/kernel/cpu/mtrr/if.c index fb73a52913a4..4c4214690dd1 100644 --- a/trunk/arch/x86/kernel/cpu/mtrr/if.c +++ b/trunk/arch/x86/kernel/cpu/mtrr/if.c @@ -377,6 +377,10 @@ static const struct file_operations mtrr_fops = { .release = mtrr_close, }; + +static struct proc_dir_entry *proc_root_mtrr; + + static int mtrr_seq_show(struct seq_file *seq, void *offset) { char factor; @@ -419,7 +423,11 @@ static int __init mtrr_if_init(void) (!cpu_has(c, X86_FEATURE_CENTAUR_MCR))) return -ENODEV; - proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops); + proc_root_mtrr = + proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops); + + if (proc_root_mtrr) + proc_root_mtrr->owner = THIS_MODULE; return 0; } diff --git a/trunk/arch/x86/kernel/cpu/mtrr/main.c b/trunk/arch/x86/kernel/cpu/mtrr/main.c index 03cda01f57c7..236a401b8259 100644 --- a/trunk/arch/x86/kernel/cpu/mtrr/main.c +++ b/trunk/arch/x86/kernel/cpu/mtrr/main.c @@ -574,7 +574,7 @@ struct mtrr_value { unsigned long lsize; }; -static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES]; +static struct mtrr_value mtrr_state[MTRR_MAX_VAR_RANGES]; static int mtrr_save(struct sys_device * sysdev, pm_message_t state) { @@ -582,9 +582,9 @@ static int mtrr_save(struct sys_device * sysdev, pm_message_t state) for (i = 0; i < num_var_ranges; i++) { mtrr_if->get(i, - &mtrr_value[i].lbase, - &mtrr_value[i].lsize, - &mtrr_value[i].ltype); + &mtrr_state[i].lbase, + &mtrr_state[i].lsize, + &mtrr_state[i].ltype); } return 0; } @@ -594,11 +594,11 @@ static int mtrr_restore(struct sys_device * sysdev) int i; for (i = 0; i < num_var_ranges; i++) { - if (mtrr_value[i].lsize) + if (mtrr_state[i].lsize) set_mtrr(i, - mtrr_value[i].lbase, - mtrr_value[i].lsize, - mtrr_value[i].ltype); + mtrr_state[i].lbase, + mtrr_state[i].lsize, + mtrr_state[i].ltype); } return 0; } @@ -610,7 +610,1058 @@ static struct sysdev_driver mtrr_sysdev_driver = { .resume = mtrr_restore, }; -int __initdata changed_by_mtrr_cleanup; +/* should be related to MTRR_VAR_RANGES nums */ +#define RANGE_NUM 256 + +struct res_range { + unsigned long start; + unsigned long end; +}; + +static int __init +add_range(struct res_range *range, int nr_range, unsigned long start, + unsigned long end) +{ + /* out of slots */ + if (nr_range >= RANGE_NUM) + return nr_range; + + range[nr_range].start = start; + range[nr_range].end = end; + + nr_range++; + + return nr_range; +} + +static int __init +add_range_with_merge(struct res_range *range, int nr_range, unsigned long start, + unsigned long end) +{ + int i; + + /* try to merge it with old one */ + for (i = 0; i < nr_range; i++) { + unsigned long final_start, final_end; + unsigned long common_start, common_end; + + if (!range[i].end) + continue; + + common_start = max(range[i].start, start); + common_end = min(range[i].end, end); + if (common_start > common_end + 1) + continue; + + final_start = min(range[i].start, start); + final_end = max(range[i].end, end); + + range[i].start = final_start; + range[i].end = final_end; + return nr_range; + } + + /* need to add that */ + return add_range(range, nr_range, start, end); +} + +static void __init +subtract_range(struct res_range *range, unsigned long start, unsigned long end) +{ + int i, j; + + for (j = 0; j < RANGE_NUM; j++) { + if (!range[j].end) + continue; + + if (start <= range[j].start && end >= range[j].end) { + range[j].start = 0; + range[j].end = 0; + continue; + } + + if (start <= range[j].start && end < range[j].end && + range[j].start < end + 1) { + range[j].start = end + 1; + continue; + } + + + if (start > range[j].start && end >= range[j].end && + range[j].end > start - 1) { + range[j].end = start - 1; + continue; + } + + if (start > range[j].start && end < range[j].end) { + /* find the new spare */ + for (i = 0; i < RANGE_NUM; i++) { + if (range[i].end == 0) + break; + } + if (i < RANGE_NUM) { + range[i].end = range[j].end; + range[i].start = end + 1; + } else { + printk(KERN_ERR "run of slot in ranges\n"); + } + range[j].end = start - 1; + continue; + } + } +} + +static int __init cmp_range(const void *x1, const void *x2) +{ + const struct res_range *r1 = x1; + const struct res_range *r2 = x2; + long start1, start2; + + start1 = r1->start; + start2 = r2->start; + + return start1 - start2; +} + +struct var_mtrr_range_state { + unsigned long base_pfn; + unsigned long size_pfn; + mtrr_type type; +}; + +static struct var_mtrr_range_state __initdata range_state[RANGE_NUM]; +static int __initdata debug_print; + +static int __init +x86_get_mtrr_mem_range(struct res_range *range, int nr_range, + unsigned long extra_remove_base, + unsigned long extra_remove_size) +{ + unsigned long i, base, size; + mtrr_type type; + + for (i = 0; i < num_var_ranges; i++) { + type = range_state[i].type; + if (type != MTRR_TYPE_WRBACK) + continue; + base = range_state[i].base_pfn; + size = range_state[i].size_pfn; + nr_range = add_range_with_merge(range, nr_range, base, + base + size - 1); + } + if (debug_print) { + printk(KERN_DEBUG "After WB checking\n"); + for (i = 0; i < nr_range; i++) + printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n", + range[i].start, range[i].end + 1); + } + + /* take out UC ranges */ + for (i = 0; i < num_var_ranges; i++) { + type = range_state[i].type; + if (type != MTRR_TYPE_UNCACHABLE && + type != MTRR_TYPE_WRPROT) + continue; + size = range_state[i].size_pfn; + if (!size) + continue; + base = range_state[i].base_pfn; + subtract_range(range, base, base + size - 1); + } + if (extra_remove_size) + subtract_range(range, extra_remove_base, + extra_remove_base + extra_remove_size - 1); + + /* get new range num */ + nr_range = 0; + for (i = 0; i < RANGE_NUM; i++) { + if (!range[i].end) + continue; + nr_range++; + } + if (debug_print) { + printk(KERN_DEBUG "After UC checking\n"); + for (i = 0; i < nr_range; i++) + printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n", + range[i].start, range[i].end + 1); + } + + /* sort the ranges */ + sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL); + if (debug_print) { + printk(KERN_DEBUG "After sorting\n"); + for (i = 0; i < nr_range; i++) + printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n", + range[i].start, range[i].end + 1); + } + + /* clear those is not used */ + for (i = nr_range; i < RANGE_NUM; i++) + memset(&range[i], 0, sizeof(range[i])); + + return nr_range; +} + +static struct res_range __initdata range[RANGE_NUM]; +static int __initdata nr_range; + +#ifdef CONFIG_MTRR_SANITIZER + +static unsigned long __init sum_ranges(struct res_range *range, int nr_range) +{ + unsigned long sum; + int i; + + sum = 0; + for (i = 0; i < nr_range; i++) + sum += range[i].end + 1 - range[i].start; + + return sum; +} + +static int enable_mtrr_cleanup __initdata = + CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT; + +static int __init disable_mtrr_cleanup_setup(char *str) +{ + enable_mtrr_cleanup = 0; + return 0; +} +early_param("disable_mtrr_cleanup", disable_mtrr_cleanup_setup); + +static int __init enable_mtrr_cleanup_setup(char *str) +{ + enable_mtrr_cleanup = 1; + return 0; +} +early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup); + +static int __init mtrr_cleanup_debug_setup(char *str) +{ + debug_print = 1; + return 0; +} +early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup); + +struct var_mtrr_state { + unsigned long range_startk; + unsigned long range_sizek; + unsigned long chunk_sizek; + unsigned long gran_sizek; + unsigned int reg; +}; + +static void __init +set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, + unsigned char type, unsigned int address_bits) +{ + u32 base_lo, base_hi, mask_lo, mask_hi; + u64 base, mask; + + if (!sizek) { + fill_mtrr_var_range(reg, 0, 0, 0, 0); + return; + } + + mask = (1ULL << address_bits) - 1; + mask &= ~((((u64)sizek) << 10) - 1); + + base = ((u64)basek) << 10; + + base |= type; + mask |= 0x800; + + base_lo = base & ((1ULL<<32) - 1); + base_hi = base >> 32; + + mask_lo = mask & ((1ULL<<32) - 1); + mask_hi = mask >> 32; + + fill_mtrr_var_range(reg, base_lo, base_hi, mask_lo, mask_hi); +} + +static void __init +save_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, + unsigned char type) +{ + range_state[reg].base_pfn = basek >> (PAGE_SHIFT - 10); + range_state[reg].size_pfn = sizek >> (PAGE_SHIFT - 10); + range_state[reg].type = type; +} + +static void __init +set_var_mtrr_all(unsigned int address_bits) +{ + unsigned long basek, sizek; + unsigned char type; + unsigned int reg; + + for (reg = 0; reg < num_var_ranges; reg++) { + basek = range_state[reg].base_pfn << (PAGE_SHIFT - 10); + sizek = range_state[reg].size_pfn << (PAGE_SHIFT - 10); + type = range_state[reg].type; + + set_var_mtrr(reg, basek, sizek, type, address_bits); + } +} + +static unsigned long to_size_factor(unsigned long sizek, char *factorp) +{ + char factor; + unsigned long base = sizek; + + if (base & ((1<<10) - 1)) { + /* not MB alignment */ + factor = 'K'; + } else if (base & ((1<<20) - 1)){ + factor = 'M'; + base >>= 10; + } else { + factor = 'G'; + base >>= 20; + } + + *factorp = factor; + + return base; +} + +static unsigned int __init +range_to_mtrr(unsigned int reg, unsigned long range_startk, + unsigned long range_sizek, unsigned char type) +{ + if (!range_sizek || (reg >= num_var_ranges)) + return reg; + + while (range_sizek) { + unsigned long max_align, align; + unsigned long sizek; + + /* Compute the maximum size I can make a range */ + if (range_startk) + max_align = ffs(range_startk) - 1; + else + max_align = 32; + align = fls(range_sizek) - 1; + if (align > max_align) + align = max_align; + + sizek = 1 << align; + if (debug_print) { + char start_factor = 'K', size_factor = 'K'; + unsigned long start_base, size_base; + + start_base = to_size_factor(range_startk, &start_factor), + size_base = to_size_factor(sizek, &size_factor), + + printk(KERN_DEBUG "Setting variable MTRR %d, " + "base: %ld%cB, range: %ld%cB, type %s\n", + reg, start_base, start_factor, + size_base, size_factor, + (type == MTRR_TYPE_UNCACHABLE)?"UC": + ((type == MTRR_TYPE_WRBACK)?"WB":"Other") + ); + } + save_var_mtrr(reg++, range_startk, sizek, type); + range_startk += sizek; + range_sizek -= sizek; + if (reg >= num_var_ranges) + break; + } + return reg; +} + +static unsigned __init +range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek, + unsigned long sizek) +{ + unsigned long hole_basek, hole_sizek; + unsigned long second_basek, second_sizek; + unsigned long range0_basek, range0_sizek; + unsigned long range_basek, range_sizek; + unsigned long chunk_sizek; + unsigned long gran_sizek; + + hole_basek = 0; + hole_sizek = 0; + second_basek = 0; + second_sizek = 0; + chunk_sizek = state->chunk_sizek; + gran_sizek = state->gran_sizek; + + /* align with gran size, prevent small block used up MTRRs */ + range_basek = ALIGN(state->range_startk, gran_sizek); + if ((range_basek > basek) && basek) + return second_sizek; + state->range_sizek -= (range_basek - state->range_startk); + range_sizek = ALIGN(state->range_sizek, gran_sizek); + + while (range_sizek > state->range_sizek) { + range_sizek -= gran_sizek; + if (!range_sizek) + return 0; + } + state->range_sizek = range_sizek; + + /* try to append some small hole */ + range0_basek = state->range_startk; + range0_sizek = ALIGN(state->range_sizek, chunk_sizek); + + /* no increase */ + if (range0_sizek == state->range_sizek) { + if (debug_print) + printk(KERN_DEBUG "rangeX: %016lx - %016lx\n", + range0_basek<<10, + (range0_basek + state->range_sizek)<<10); + state->reg = range_to_mtrr(state->reg, range0_basek, + state->range_sizek, MTRR_TYPE_WRBACK); + return 0; + } + + /* only cut back, when it is not the last */ + if (sizek) { + while (range0_basek + range0_sizek > (basek + sizek)) { + if (range0_sizek >= chunk_sizek) + range0_sizek -= chunk_sizek; + else + range0_sizek = 0; + + if (!range0_sizek) + break; + } + } + +second_try: + range_basek = range0_basek + range0_sizek; + + /* one hole in the middle */ + if (range_basek > basek && range_basek <= (basek + sizek)) + second_sizek = range_basek - basek; + + if (range0_sizek > state->range_sizek) { + + /* one hole in middle or at end */ + hole_sizek = range0_sizek - state->range_sizek - second_sizek; + + /* hole size should be less than half of range0 size */ + if (hole_sizek >= (range0_sizek >> 1) && + range0_sizek >= chunk_sizek) { + range0_sizek -= chunk_sizek; + second_sizek = 0; + hole_sizek = 0; + + goto second_try; + } + } + + if (range0_sizek) { + if (debug_print) + printk(KERN_DEBUG "range0: %016lx - %016lx\n", + range0_basek<<10, + (range0_basek + range0_sizek)<<10); + state->reg = range_to_mtrr(state->reg, range0_basek, + range0_sizek, MTRR_TYPE_WRBACK); + } + + if (range0_sizek < state->range_sizek) { + /* need to handle left over */ + range_sizek = state->range_sizek - range0_sizek; + + if (debug_print) + printk(KERN_DEBUG "range: %016lx - %016lx\n", + range_basek<<10, + (range_basek + range_sizek)<<10); + state->reg = range_to_mtrr(state->reg, range_basek, + range_sizek, MTRR_TYPE_WRBACK); + } + + if (hole_sizek) { + hole_basek = range_basek - hole_sizek - second_sizek; + if (debug_print) + printk(KERN_DEBUG "hole: %016lx - %016lx\n", + hole_basek<<10, + (hole_basek + hole_sizek)<<10); + state->reg = range_to_mtrr(state->reg, hole_basek, + hole_sizek, MTRR_TYPE_UNCACHABLE); + } + + return second_sizek; +} + +static void __init +set_var_mtrr_range(struct var_mtrr_state *state, unsigned long base_pfn, + unsigned long size_pfn) +{ + unsigned long basek, sizek; + unsigned long second_sizek = 0; + + if (state->reg >= num_var_ranges) + return; + + basek = base_pfn << (PAGE_SHIFT - 10); + sizek = size_pfn << (PAGE_SHIFT - 10); + + /* See if I can merge with the last range */ + if ((basek <= 1024) || + (state->range_startk + state->range_sizek == basek)) { + unsigned long endk = basek + sizek; + state->range_sizek = endk - state->range_startk; + return; + } + /* Write the range mtrrs */ + if (state->range_sizek != 0) + second_sizek = range_to_mtrr_with_hole(state, basek, sizek); + + /* Allocate an msr */ + state->range_startk = basek + second_sizek; + state->range_sizek = sizek - second_sizek; +} + +/* mininum size of mtrr block that can take hole */ +static u64 mtrr_chunk_size __initdata = (256ULL<<20); + +static int __init parse_mtrr_chunk_size_opt(char *p) +{ + if (!p) + return -EINVAL; + mtrr_chunk_size = memparse(p, &p); + return 0; +} +early_param("mtrr_chunk_size", parse_mtrr_chunk_size_opt); + +/* granity of mtrr of block */ +static u64 mtrr_gran_size __initdata; + +static int __init parse_mtrr_gran_size_opt(char *p) +{ + if (!p) + return -EINVAL; + mtrr_gran_size = memparse(p, &p); + return 0; +} +early_param("mtrr_gran_size", parse_mtrr_gran_size_opt); + +static int nr_mtrr_spare_reg __initdata = + CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT; + +static int __init parse_mtrr_spare_reg(char *arg) +{ + if (arg) + nr_mtrr_spare_reg = simple_strtoul(arg, NULL, 0); + return 0; +} + +early_param("mtrr_spare_reg_nr", parse_mtrr_spare_reg); + +static int __init +x86_setup_var_mtrrs(struct res_range *range, int nr_range, + u64 chunk_size, u64 gran_size) +{ + struct var_mtrr_state var_state; + int i; + int num_reg; + + var_state.range_startk = 0; + var_state.range_sizek = 0; + var_state.reg = 0; + var_state.chunk_sizek = chunk_size >> 10; + var_state.gran_sizek = gran_size >> 10; + + memset(range_state, 0, sizeof(range_state)); + + /* Write the range etc */ + for (i = 0; i < nr_range; i++) + set_var_mtrr_range(&var_state, range[i].start, + range[i].end - range[i].start + 1); + + /* Write the last range */ + if (var_state.range_sizek != 0) + range_to_mtrr_with_hole(&var_state, 0, 0); + + num_reg = var_state.reg; + /* Clear out the extra MTRR's */ + while (var_state.reg < num_var_ranges) { + save_var_mtrr(var_state.reg, 0, 0, 0); + var_state.reg++; + } + + return num_reg; +} + +struct mtrr_cleanup_result { + unsigned long gran_sizek; + unsigned long chunk_sizek; + unsigned long lose_cover_sizek; + unsigned int num_reg; + int bad; +}; + +/* + * gran_size: 64K, 128K, 256K, 512K, 1M, 2M, ..., 2G + * chunk size: gran_size, ..., 2G + * so we need (1+16)*8 + */ +#define NUM_RESULT 136 +#define PSHIFT (PAGE_SHIFT - 10) + +static struct mtrr_cleanup_result __initdata result[NUM_RESULT]; +static unsigned long __initdata min_loss_pfn[RANGE_NUM]; + +static void __init print_out_mtrr_range_state(void) +{ + int i; + char start_factor = 'K', size_factor = 'K'; + unsigned long start_base, size_base; + mtrr_type type; + + for (i = 0; i < num_var_ranges; i++) { + + size_base = range_state[i].size_pfn << (PAGE_SHIFT - 10); + if (!size_base) + continue; + + size_base = to_size_factor(size_base, &size_factor), + start_base = range_state[i].base_pfn << (PAGE_SHIFT - 10); + start_base = to_size_factor(start_base, &start_factor), + type = range_state[i].type; + + printk(KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n", + i, start_base, start_factor, + size_base, size_factor, + (type == MTRR_TYPE_UNCACHABLE) ? "UC" : + ((type == MTRR_TYPE_WRPROT) ? "WP" : + ((type == MTRR_TYPE_WRBACK) ? "WB" : "Other")) + ); + } +} + +static int __init mtrr_need_cleanup(void) +{ + int i; + mtrr_type type; + unsigned long size; + /* extra one for all 0 */ + int num[MTRR_NUM_TYPES + 1]; + + /* check entries number */ + memset(num, 0, sizeof(num)); + for (i = 0; i < num_var_ranges; i++) { + type = range_state[i].type; + size = range_state[i].size_pfn; + if (type >= MTRR_NUM_TYPES) + continue; + if (!size) + type = MTRR_NUM_TYPES; + if (type == MTRR_TYPE_WRPROT) + type = MTRR_TYPE_UNCACHABLE; + num[type]++; + } + + /* check if we got UC entries */ + if (!num[MTRR_TYPE_UNCACHABLE]) + return 0; + + /* check if we only had WB and UC */ + if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] != + num_var_ranges - num[MTRR_NUM_TYPES]) + return 0; + + return 1; +} + +static unsigned long __initdata range_sums; +static void __init mtrr_calc_range_state(u64 chunk_size, u64 gran_size, + unsigned long extra_remove_base, + unsigned long extra_remove_size, + int i) +{ + int num_reg; + static struct res_range range_new[RANGE_NUM]; + static int nr_range_new; + unsigned long range_sums_new; + + /* convert ranges to var ranges state */ + num_reg = x86_setup_var_mtrrs(range, nr_range, + chunk_size, gran_size); + + /* we got new setting in range_state, check it */ + memset(range_new, 0, sizeof(range_new)); + nr_range_new = x86_get_mtrr_mem_range(range_new, 0, + extra_remove_base, extra_remove_size); + range_sums_new = sum_ranges(range_new, nr_range_new); + + result[i].chunk_sizek = chunk_size >> 10; + result[i].gran_sizek = gran_size >> 10; + result[i].num_reg = num_reg; + if (range_sums < range_sums_new) { + result[i].lose_cover_sizek = + (range_sums_new - range_sums) << PSHIFT; + result[i].bad = 1; + } else + result[i].lose_cover_sizek = + (range_sums - range_sums_new) << PSHIFT; + + /* double check it */ + if (!result[i].bad && !result[i].lose_cover_sizek) { + if (nr_range_new != nr_range || + memcmp(range, range_new, sizeof(range))) + result[i].bad = 1; + } + + if (!result[i].bad && (range_sums - range_sums_new < + min_loss_pfn[num_reg])) { + min_loss_pfn[num_reg] = + range_sums - range_sums_new; + } +} + +static void __init mtrr_print_out_one_result(int i) +{ + char gran_factor, chunk_factor, lose_factor; + unsigned long gran_base, chunk_base, lose_base; + + gran_base = to_size_factor(result[i].gran_sizek, &gran_factor), + chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor), + lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor), + printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t", + result[i].bad ? "*BAD*" : " ", + gran_base, gran_factor, chunk_base, chunk_factor); + printk(KERN_CONT "num_reg: %d \tlose cover RAM: %s%ld%c\n", + result[i].num_reg, result[i].bad ? "-" : "", + lose_base, lose_factor); +} + +static int __init mtrr_search_optimal_index(void) +{ + int i; + int num_reg_good; + int index_good; + + if (nr_mtrr_spare_reg >= num_var_ranges) + nr_mtrr_spare_reg = num_var_ranges - 1; + num_reg_good = -1; + for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) { + if (!min_loss_pfn[i]) + num_reg_good = i; + } + + index_good = -1; + if (num_reg_good != -1) { + for (i = 0; i < NUM_RESULT; i++) { + if (!result[i].bad && + result[i].num_reg == num_reg_good && + !result[i].lose_cover_sizek) { + index_good = i; + break; + } + } + } + + return index_good; +} + + +static int __init mtrr_cleanup(unsigned address_bits) +{ + unsigned long extra_remove_base, extra_remove_size; + unsigned long base, size, def, dummy; + mtrr_type type; + u64 chunk_size, gran_size; + int index_good; + int i; + + if (!is_cpu(INTEL) || enable_mtrr_cleanup < 1) + return 0; + rdmsr(MTRRdefType_MSR, def, dummy); + def &= 0xff; + if (def != MTRR_TYPE_UNCACHABLE) + return 0; + + /* get it and store it aside */ + memset(range_state, 0, sizeof(range_state)); + for (i = 0; i < num_var_ranges; i++) { + mtrr_if->get(i, &base, &size, &type); + range_state[i].base_pfn = base; + range_state[i].size_pfn = size; + range_state[i].type = type; + } + + /* check if we need handle it and can handle it */ + if (!mtrr_need_cleanup()) + return 0; + + /* print original var MTRRs at first, for debugging: */ + printk(KERN_DEBUG "original variable MTRRs\n"); + print_out_mtrr_range_state(); + + memset(range, 0, sizeof(range)); + extra_remove_size = 0; + extra_remove_base = 1 << (32 - PAGE_SHIFT); + if (mtrr_tom2) + extra_remove_size = + (mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base; + nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base, + extra_remove_size); + /* + * [0, 1M) should always be coverred by var mtrr with WB + * and fixed mtrrs should take effective before var mtrr for it + */ + nr_range = add_range_with_merge(range, nr_range, 0, + (1ULL<<(20 - PAGE_SHIFT)) - 1); + /* sort the ranges */ + sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL); + + range_sums = sum_ranges(range, nr_range); + printk(KERN_INFO "total RAM coverred: %ldM\n", + range_sums >> (20 - PAGE_SHIFT)); + + if (mtrr_chunk_size && mtrr_gran_size) { + i = 0; + mtrr_calc_range_state(mtrr_chunk_size, mtrr_gran_size, + extra_remove_base, extra_remove_size, i); + + mtrr_print_out_one_result(i); + + if (!result[i].bad) { + set_var_mtrr_all(address_bits); + return 1; + } + printk(KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, " + "will find optimal one\n"); + } + + i = 0; + memset(min_loss_pfn, 0xff, sizeof(min_loss_pfn)); + memset(result, 0, sizeof(result)); + for (gran_size = (1ULL<<16); gran_size < (1ULL<<32); gran_size <<= 1) { + + for (chunk_size = gran_size; chunk_size < (1ULL<<32); + chunk_size <<= 1) { + + if (i >= NUM_RESULT) + continue; + + mtrr_calc_range_state(chunk_size, gran_size, + extra_remove_base, extra_remove_size, i); + if (debug_print) { + mtrr_print_out_one_result(i); + printk(KERN_INFO "\n"); + } + + i++; + } + } + + /* try to find the optimal index */ + index_good = mtrr_search_optimal_index(); + + if (index_good != -1) { + printk(KERN_INFO "Found optimal setting for mtrr clean up\n"); + i = index_good; + mtrr_print_out_one_result(i); + + /* convert ranges to var ranges state */ + chunk_size = result[i].chunk_sizek; + chunk_size <<= 10; + gran_size = result[i].gran_sizek; + gran_size <<= 10; + x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size); + set_var_mtrr_all(address_bits); + printk(KERN_DEBUG "New variable MTRRs\n"); + print_out_mtrr_range_state(); + return 1; + } else { + /* print out all */ + for (i = 0; i < NUM_RESULT; i++) + mtrr_print_out_one_result(i); + } + + printk(KERN_INFO "mtrr_cleanup: can not find optimal value\n"); + printk(KERN_INFO "please specify mtrr_gran_size/mtrr_chunk_size\n"); + + return 0; +} +#else +static int __init mtrr_cleanup(unsigned address_bits) +{ + return 0; +} +#endif + +static int __initdata changed_by_mtrr_cleanup; + +static int disable_mtrr_trim; + +static int __init disable_mtrr_trim_setup(char *str) +{ + disable_mtrr_trim = 1; + return 0; +} +early_param("disable_mtrr_trim", disable_mtrr_trim_setup); + +/* + * Newer AMD K8s and later CPUs have a special magic MSR way to force WB + * for memory >4GB. Check for that here. + * Note this won't check if the MTRRs < 4GB where the magic bit doesn't + * apply to are wrong, but so far we don't know of any such case in the wild. + */ +#define Tom2Enabled (1U << 21) +#define Tom2ForceMemTypeWB (1U << 22) + +int __init amd_special_default_mtrr(void) +{ + u32 l, h; + + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) + return 0; + if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11) + return 0; + /* In case some hypervisor doesn't pass SYSCFG through */ + if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0) + return 0; + /* + * Memory between 4GB and top of mem is forced WB by this magic bit. + * Reserved before K8RevF, but should be zero there. + */ + if ((l & (Tom2Enabled | Tom2ForceMemTypeWB)) == + (Tom2Enabled | Tom2ForceMemTypeWB)) + return 1; + return 0; +} + +static u64 __init real_trim_memory(unsigned long start_pfn, + unsigned long limit_pfn) +{ + u64 trim_start, trim_size; + trim_start = start_pfn; + trim_start <<= PAGE_SHIFT; + trim_size = limit_pfn; + trim_size <<= PAGE_SHIFT; + trim_size -= trim_start; + + return e820_update_range(trim_start, trim_size, E820_RAM, + E820_RESERVED); +} +/** + * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs + * @end_pfn: ending page frame number + * + * Some buggy BIOSes don't setup the MTRRs properly for systems with certain + * memory configurations. This routine checks that the highest MTRR matches + * the end of memory, to make sure the MTRRs having a write back type cover + * all of the memory the kernel is intending to use. If not, it'll trim any + * memory off the end by adjusting end_pfn, removing it from the kernel's + * allocation pools, warning the user with an obnoxious message. + */ +int __init mtrr_trim_uncached_memory(unsigned long end_pfn) +{ + unsigned long i, base, size, highest_pfn = 0, def, dummy; + mtrr_type type; + u64 total_trim_size; + + /* extra one for all 0 */ + int num[MTRR_NUM_TYPES + 1]; + /* + * Make sure we only trim uncachable memory on machines that + * support the Intel MTRR architecture: + */ + if (!is_cpu(INTEL) || disable_mtrr_trim) + return 0; + rdmsr(MTRRdefType_MSR, def, dummy); + def &= 0xff; + if (def != MTRR_TYPE_UNCACHABLE) + return 0; + + /* get it and store it aside */ + memset(range_state, 0, sizeof(range_state)); + for (i = 0; i < num_var_ranges; i++) { + mtrr_if->get(i, &base, &size, &type); + range_state[i].base_pfn = base; + range_state[i].size_pfn = size; + range_state[i].type = type; + } + + /* Find highest cached pfn */ + for (i = 0; i < num_var_ranges; i++) { + type = range_state[i].type; + if (type != MTRR_TYPE_WRBACK) + continue; + base = range_state[i].base_pfn; + size = range_state[i].size_pfn; + if (highest_pfn < base + size) + highest_pfn = base + size; + } + + /* kvm/qemu doesn't have mtrr set right, don't trim them all */ + if (!highest_pfn) { + printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n"); + return 0; + } + + /* check entries number */ + memset(num, 0, sizeof(num)); + for (i = 0; i < num_var_ranges; i++) { + type = range_state[i].type; + if (type >= MTRR_NUM_TYPES) + continue; + size = range_state[i].size_pfn; + if (!size) + type = MTRR_NUM_TYPES; + num[type]++; + } + + /* no entry for WB? */ + if (!num[MTRR_TYPE_WRBACK]) + return 0; + + /* check if we only had WB and UC */ + if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] != + num_var_ranges - num[MTRR_NUM_TYPES]) + return 0; + + memset(range, 0, sizeof(range)); + nr_range = 0; + if (mtrr_tom2) { + range[nr_range].start = (1ULL<<(32 - PAGE_SHIFT)); + range[nr_range].end = (mtrr_tom2 >> PAGE_SHIFT) - 1; + if (highest_pfn < range[nr_range].end + 1) + highest_pfn = range[nr_range].end + 1; + nr_range++; + } + nr_range = x86_get_mtrr_mem_range(range, nr_range, 0, 0); + + total_trim_size = 0; + /* check the head */ + if (range[0].start) + total_trim_size += real_trim_memory(0, range[0].start); + /* check the holes */ + for (i = 0; i < nr_range - 1; i++) { + if (range[i].end + 1 < range[i+1].start) + total_trim_size += real_trim_memory(range[i].end + 1, + range[i+1].start); + } + /* check the top */ + i = nr_range - 1; + if (range[i].end + 1 < end_pfn) + total_trim_size += real_trim_memory(range[i].end + 1, + end_pfn); + + if (total_trim_size) { + printk(KERN_WARNING "WARNING: BIOS bug: CPU MTRRs don't cover" + " all of memory, losing %lluMB of RAM.\n", + total_trim_size >> 20); + + if (!changed_by_mtrr_cleanup) + WARN_ON(1); + + printk(KERN_INFO "update e820 for mtrr\n"); + update_e820(); + + return 1; + } + + return 0; +} /** * mtrr_bp_init - initialize mtrrs on the boot CPU diff --git a/trunk/arch/x86/kernel/cpu/mtrr/mtrr.h b/trunk/arch/x86/kernel/cpu/mtrr/mtrr.h index 77f67f7b347a..ffd60409cc6d 100644 --- a/trunk/arch/x86/kernel/cpu/mtrr/mtrr.h +++ b/trunk/arch/x86/kernel/cpu/mtrr/mtrr.h @@ -79,7 +79,6 @@ extern struct mtrr_ops * mtrr_if; extern unsigned int num_var_ranges; extern u64 mtrr_tom2; -extern struct mtrr_state_type mtrr_state; void mtrr_state_warn(void); const char *mtrr_attrib_to_str(int x); @@ -89,6 +88,3 @@ void mtrr_wrmsr(unsigned, unsigned, unsigned); int amd_init_mtrr(void); int cyrix_init_mtrr(void); int centaur_init_mtrr(void); - -extern int changed_by_mtrr_cleanup; -extern int mtrr_cleanup(unsigned address_bits); diff --git a/trunk/arch/x86/kernel/cpu/transmeta.c b/trunk/arch/x86/kernel/cpu/transmeta.c index bb62b3e5caad..52b3fefbd5af 100644 --- a/trunk/arch/x86/kernel/cpu/transmeta.c +++ b/trunk/arch/x86/kernel/cpu/transmeta.c @@ -98,7 +98,7 @@ static void __cpuinit init_transmeta(struct cpuinfo_x86 *c) #endif } -static const struct cpu_dev __cpuinitconst transmeta_cpu_dev = { +static struct cpu_dev transmeta_cpu_dev __cpuinitdata = { .c_vendor = "Transmeta", .c_ident = { "GenuineTMx86", "TransmetaCPU" }, .c_early_init = early_init_transmeta, diff --git a/trunk/arch/x86/kernel/cpu/umc.c b/trunk/arch/x86/kernel/cpu/umc.c index fd2c37bf7acb..e777f79e0960 100644 --- a/trunk/arch/x86/kernel/cpu/umc.c +++ b/trunk/arch/x86/kernel/cpu/umc.c @@ -8,7 +8,7 @@ * so no special init takes place. */ -static const struct cpu_dev __cpuinitconst umc_cpu_dev = { +static struct cpu_dev umc_cpu_dev __cpuinitdata = { .c_vendor = "UMC", .c_ident = { "UMC UMC UMC" }, .c_models = { diff --git a/trunk/arch/x86/kernel/dumpstack.c b/trunk/arch/x86/kernel/dumpstack.c index dd2130b0fb3e..87d103ded1c3 100644 --- a/trunk/arch/x86/kernel/dumpstack.c +++ b/trunk/arch/x86/kernel/dumpstack.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/x86/kernel/e820.c b/trunk/arch/x86/kernel/e820.c index ef2c3563357d..508bec1cee27 100644 --- a/trunk/arch/x86/kernel/e820.c +++ b/trunk/arch/x86/kernel/e820.c @@ -110,50 +110,19 @@ int __init e820_all_mapped(u64 start, u64 end, unsigned type) /* * Add a memory region to the kernel e820 map. */ -static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size, - int type) +void __init e820_add_region(u64 start, u64 size, int type) { - int x = e820x->nr_map; + int x = e820.nr_map; - if (x == ARRAY_SIZE(e820x->map)) { + if (x == ARRAY_SIZE(e820.map)) { printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); return; } - e820x->map[x].addr = start; - e820x->map[x].size = size; - e820x->map[x].type = type; - e820x->nr_map++; -} - -void __init e820_add_region(u64 start, u64 size, int type) -{ - __e820_add_region(&e820, start, size, type); -} - -static void __init e820_print_type(u32 type) -{ - switch (type) { - case E820_RAM: - case E820_RESERVED_KERN: - printk(KERN_CONT "(usable)"); - break; - case E820_RESERVED: - printk(KERN_CONT "(reserved)"); - break; - case E820_ACPI: - printk(KERN_CONT "(ACPI data)"); - break; - case E820_NVS: - printk(KERN_CONT "(ACPI NVS)"); - break; - case E820_UNUSABLE: - printk(KERN_CONT "(unusable)"); - break; - default: - printk(KERN_CONT "type %u", type); - break; - } + e820.map[x].addr = start; + e820.map[x].size = size; + e820.map[x].type = type; + e820.nr_map++; } void __init e820_print_map(char *who) @@ -165,8 +134,27 @@ void __init e820_print_map(char *who) (unsigned long long) e820.map[i].addr, (unsigned long long) (e820.map[i].addr + e820.map[i].size)); - e820_print_type(e820.map[i].type); - printk(KERN_CONT "\n"); + switch (e820.map[i].type) { + case E820_RAM: + case E820_RESERVED_KERN: + printk(KERN_CONT "(usable)\n"); + break; + case E820_RESERVED: + printk(KERN_CONT "(reserved)\n"); + break; + case E820_ACPI: + printk(KERN_CONT "(ACPI data)\n"); + break; + case E820_NVS: + printk(KERN_CONT "(ACPI NVS)\n"); + break; + case E820_UNUSABLE: + printk("(unusable)\n"); + break; + default: + printk(KERN_CONT "type %u\n", e820.map[i].type); + break; + } } } @@ -233,7 +221,7 @@ void __init e820_print_map(char *who) */ int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, - u32 *pnr_map) + int *pnr_map) { struct change_member { struct e820entry *pbios; /* pointer to original bios entry */ @@ -429,12 +417,11 @@ static int __init append_e820_map(struct e820entry *biosmap, int nr_map) return __append_e820_map(biosmap, nr_map); } -static u64 __init __e820_update_range(struct e820map *e820x, u64 start, +static u64 __init e820_update_range_map(struct e820map *e820x, u64 start, u64 size, unsigned old_type, unsigned new_type) { - u64 end; - unsigned int i; + int i; u64 real_updated_size = 0; BUG_ON(old_type == new_type); @@ -442,55 +429,27 @@ static u64 __init __e820_update_range(struct e820map *e820x, u64 start, if (size > (ULLONG_MAX - start)) size = ULLONG_MAX - start; - end = start + size; - printk(KERN_DEBUG "e820 update range: %016Lx - %016Lx ", - (unsigned long long) start, - (unsigned long long) end); - e820_print_type(old_type); - printk(KERN_CONT " ==> "); - e820_print_type(new_type); - printk(KERN_CONT "\n"); - - for (i = 0; i < e820x->nr_map; i++) { + for (i = 0; i < e820.nr_map; i++) { struct e820entry *ei = &e820x->map[i]; u64 final_start, final_end; - u64 ei_end; - if (ei->type != old_type) continue; - - ei_end = ei->addr + ei->size; - /* totally covered by new range? */ - if (ei->addr >= start && ei_end <= end) { + /* totally covered? */ + if (ei->addr >= start && + (ei->addr + ei->size) <= (start + size)) { ei->type = new_type; real_updated_size += ei->size; continue; } - - /* new range is totally covered? */ - if (ei->addr < start && ei_end > end) { - __e820_add_region(e820x, start, size, new_type); - __e820_add_region(e820x, end, ei_end - end, ei->type); - ei->size = start - ei->addr; - real_updated_size += size; - continue; - } - /* partially covered */ final_start = max(start, ei->addr); - final_end = min(end, ei_end); + final_end = min(start + size, ei->addr + ei->size); if (final_start >= final_end) continue; - - __e820_add_region(e820x, final_start, final_end - final_start, - new_type); - + e820_add_region(final_start, final_end - final_start, + new_type); real_updated_size += final_end - final_start; - /* - * left range could be head or tail, so need to update - * size at first. - */ ei->size -= final_end - final_start; if (ei->addr < final_start) continue; @@ -502,13 +461,13 @@ static u64 __init __e820_update_range(struct e820map *e820x, u64 start, u64 __init e820_update_range(u64 start, u64 size, unsigned old_type, unsigned new_type) { - return __e820_update_range(&e820, start, size, old_type, new_type); + return e820_update_range_map(&e820, start, size, old_type, new_type); } static u64 __init e820_update_range_saved(u64 start, u64 size, unsigned old_type, unsigned new_type) { - return __e820_update_range(&e820_saved, start, size, old_type, + return e820_update_range_map(&e820_saved, start, size, old_type, new_type); } @@ -552,7 +511,7 @@ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type, void __init update_e820(void) { - u32 nr_map; + int nr_map; nr_map = e820.nr_map; if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr_map)) @@ -563,7 +522,7 @@ void __init update_e820(void) } static void __init update_e820_saved(void) { - u32 nr_map; + int nr_map; nr_map = e820_saved.nr_map; if (sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map), &nr_map)) @@ -1061,8 +1020,8 @@ u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align) continue; return addr; } + return -1UL; - return -1ULL; } /* @@ -1075,22 +1034,13 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align) u64 start; start = startt; - while (size < sizet && (start + 1)) + while (size < sizet) start = find_e820_area_size(start, &size, align); if (size < sizet) return 0; -#ifdef CONFIG_X86_32 - if (start >= MAXMEM) - return 0; - if (start + size > MAXMEM) - size = MAXMEM - start; -#endif - addr = round_down(start + size - sizet, align); - if (addr < start) - return 0; e820_update_range(addr, sizet, E820_RAM, E820_RESERVED); e820_update_range_saved(addr, sizet, E820_RAM, E820_RESERVED); printk(KERN_INFO "update e820 for early_reserve_e820\n"); @@ -1303,7 +1253,7 @@ early_param("memmap", parse_memmap_opt); void __init finish_e820_parsing(void) { if (userdef) { - u32 nr = e820.nr_map; + int nr = e820.nr_map; if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0) early_panic("Invalid user supplied memory map"); @@ -1386,7 +1336,7 @@ void __init e820_reserve_resources_late(void) char *__init default_machine_specific_memory_setup(void) { char *who = "BIOS-e820"; - u32 new_nr; + int new_nr; /* * Try to copy the BIOS-supplied E820-map. * diff --git a/trunk/arch/x86/kernel/early_printk.c b/trunk/arch/x86/kernel/early_printk.c index 335f049d110f..639ad98238a2 100644 --- a/trunk/arch/x86/kernel/early_printk.c +++ b/trunk/arch/x86/kernel/early_printk.c @@ -250,7 +250,7 @@ static int dbgp_wait_until_complete(void) return (ctrl & DBGP_ERROR) ? -DBGP_ERRCODE(ctrl) : DBGP_LEN(ctrl); } -static void __init dbgp_mdelay(int ms) +static void dbgp_mdelay(int ms) { int i; @@ -311,7 +311,7 @@ static void dbgp_set_data(const void *buf, int size) writel(hi, &ehci_debug->data47); } -static void __init dbgp_get_data(void *buf, int size) +static void dbgp_get_data(void *buf, int size) { unsigned char *bytes = buf; u32 lo, hi; @@ -355,7 +355,7 @@ static int dbgp_bulk_write(unsigned devnum, unsigned endpoint, return ret; } -static int __init dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data, +static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data, int size) { u32 pids, addr, ctrl; @@ -386,8 +386,8 @@ static int __init dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data, return ret; } -static int __init dbgp_control_msg(unsigned devnum, int requesttype, - int request, int value, int index, void *data, int size) +static int dbgp_control_msg(unsigned devnum, int requesttype, int request, + int value, int index, void *data, int size) { u32 pids, addr, ctrl; struct usb_ctrlrequest req; @@ -489,7 +489,7 @@ static u32 __init find_dbgp(int ehci_num, u32 *rbus, u32 *rslot, u32 *rfunc) return 0; } -static int __init ehci_reset_port(int port) +static int ehci_reset_port(int port) { u32 portsc; u32 delay_time, delay; @@ -532,7 +532,7 @@ static int __init ehci_reset_port(int port) return -EBUSY; } -static int __init ehci_wait_for_port(int port) +static int ehci_wait_for_port(int port) { u32 status; int ret, reps; @@ -557,13 +557,13 @@ static inline void dbgp_printk(const char *fmt, ...) { } typedef void (*set_debug_port_t)(int port); -static void __init default_set_debug_port(int port) +static void default_set_debug_port(int port) { } -static set_debug_port_t __initdata set_debug_port = default_set_debug_port; +static set_debug_port_t set_debug_port = default_set_debug_port; -static void __init nvidia_set_debug_port(int port) +static void nvidia_set_debug_port(int port) { u32 dword; dword = read_pci_config(ehci_dev.bus, ehci_dev.slot, ehci_dev.func, diff --git a/trunk/arch/x86/kernel/entry_32.S b/trunk/arch/x86/kernel/entry_32.S index c929add475c9..899e8938e79f 100644 --- a/trunk/arch/x86/kernel/entry_32.S +++ b/trunk/arch/x86/kernel/entry_32.S @@ -442,7 +442,8 @@ sysenter_past_esp: GET_THREAD_INFO(%ebp) - testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) + /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ + testw $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) jnz sysenter_audit sysenter_do_call: cmpl $(nr_syscalls), %eax @@ -453,7 +454,7 @@ sysenter_do_call: DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF movl TI_flags(%ebp), %ecx - testl $_TIF_ALLWORK_MASK, %ecx + testw $_TIF_ALLWORK_MASK, %cx jne sysexit_audit sysenter_exit: /* if something modifies registers it must also disable sysexit */ @@ -467,7 +468,7 @@ sysenter_exit: #ifdef CONFIG_AUDITSYSCALL sysenter_audit: - testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp) + testw $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp) jnz syscall_trace_entry addl $4,%esp CFI_ADJUST_CFA_OFFSET -4 @@ -484,7 +485,7 @@ sysenter_audit: jmp sysenter_do_call sysexit_audit: - testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %ecx + testw $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %cx jne syscall_exit_work TRACE_IRQS_ON ENABLE_INTERRUPTS(CLBR_ANY) @@ -497,7 +498,7 @@ sysexit_audit: DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF movl TI_flags(%ebp), %ecx - testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %ecx + testw $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %cx jne syscall_exit_work movl PT_EAX(%esp),%eax /* reload syscall return value */ jmp sysenter_exit @@ -522,7 +523,8 @@ ENTRY(system_call) SAVE_ALL GET_THREAD_INFO(%ebp) # system call tracing in operation / emulation - testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) + /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ + testw $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) jnz syscall_trace_entry cmpl $(nr_syscalls), %eax jae syscall_badsys @@ -536,7 +538,7 @@ syscall_exit: # between sampling and the iret TRACE_IRQS_OFF movl TI_flags(%ebp), %ecx - testl $_TIF_ALLWORK_MASK, %ecx # current->work + testw $_TIF_ALLWORK_MASK, %cx # current->work jne syscall_exit_work restore_all: @@ -671,7 +673,7 @@ END(syscall_trace_entry) # perform syscall exit tracing ALIGN syscall_exit_work: - testl $_TIF_WORK_SYSCALL_EXIT, %ecx + testb $_TIF_WORK_SYSCALL_EXIT, %cl jz work_pending TRACE_IRQS_ON ENABLE_INTERRUPTS(CLBR_ANY) # could let syscall_trace_leave() call diff --git a/trunk/arch/x86/kernel/entry_64.S b/trunk/arch/x86/kernel/entry_64.S index a331ec38af9e..83d1836b9467 100644 --- a/trunk/arch/x86/kernel/entry_64.S +++ b/trunk/arch/x86/kernel/entry_64.S @@ -368,7 +368,6 @@ ENTRY(save_rest) END(save_rest) /* save complete stack frame */ - .pushsection .kprobes.text, "ax" ENTRY(save_paranoid) XCPT_FRAME 1 RDI+8 cld @@ -397,7 +396,6 @@ ENTRY(save_paranoid) 1: ret CFI_ENDPROC END(save_paranoid) - .popsection /* * A newly forked process directly context switches into this address. @@ -418,6 +416,7 @@ ENTRY(ret_from_fork) GET_THREAD_INFO(%rcx) + CFI_REMEMBER_STATE RESTORE_REST testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread? @@ -429,6 +428,7 @@ ENTRY(ret_from_fork) RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET jmp ret_from_sys_call # go to the SYSRET fastpath + CFI_RESTORE_STATE CFI_ENDPROC END(ret_from_fork) @@ -984,8 +984,6 @@ apicinterrupt UV_BAU_MESSAGE \ #endif apicinterrupt LOCAL_TIMER_VECTOR \ apic_timer_interrupt smp_apic_timer_interrupt -apicinterrupt GENERIC_INTERRUPT_VECTOR \ - generic_interrupt smp_generic_interrupt #ifdef CONFIG_SMP apicinterrupt INVALIDATE_TLB_VECTOR_START+0 \ diff --git a/trunk/arch/x86/kernel/ftrace.c b/trunk/arch/x86/kernel/ftrace.c index 76f7141e0f91..231bdd3c5b1c 100644 --- a/trunk/arch/x86/kernel/ftrace.c +++ b/trunk/arch/x86/kernel/ftrace.c @@ -389,6 +389,79 @@ void ftrace_nmi_exit(void) #endif /* !CONFIG_DYNAMIC_FTRACE */ +/* Add a function return address to the trace stack on thread info.*/ +static int push_return_trace(unsigned long ret, unsigned long long time, + unsigned long func, int *depth) +{ + int index; + + if (!current->ret_stack) + return -EBUSY; + + /* The return trace stack is full */ + if (current->curr_ret_stack == FTRACE_RETFUNC_DEPTH - 1) { + atomic_inc(¤t->trace_overrun); + return -EBUSY; + } + + index = ++current->curr_ret_stack; + barrier(); + current->ret_stack[index].ret = ret; + current->ret_stack[index].func = func; + current->ret_stack[index].calltime = time; + *depth = index; + + return 0; +} + +/* Retrieve a function return address to the trace stack on thread info.*/ +static void pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret) +{ + int index; + + index = current->curr_ret_stack; + + if (unlikely(index < 0)) { + ftrace_graph_stop(); + WARN_ON(1); + /* Might as well panic, otherwise we have no where to go */ + *ret = (unsigned long)panic; + return; + } + + *ret = current->ret_stack[index].ret; + trace->func = current->ret_stack[index].func; + trace->calltime = current->ret_stack[index].calltime; + trace->overrun = atomic_read(¤t->trace_overrun); + trace->depth = index; + barrier(); + current->curr_ret_stack--; + +} + +/* + * Send the trace to the ring-buffer. + * @return the original return address. + */ +unsigned long ftrace_return_to_handler(void) +{ + struct ftrace_graph_ret trace; + unsigned long ret; + + pop_return_trace(&trace, &ret); + trace.rettime = cpu_clock(raw_smp_processor_id()); + ftrace_graph_return(&trace); + + if (unlikely(!ret)) { + ftrace_graph_stop(); + WARN_ON(1); + /* Might as well panic. What else to do? */ + ret = (unsigned long)panic; + } + + return ret; +} + /* * Hook the return address and push it in the stack of return addrs * in current thread info. @@ -448,7 +521,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) calltime = cpu_clock(raw_smp_processor_id()); - if (ftrace_push_return_trace(old, calltime, + if (push_return_trace(old, calltime, self_addr, &trace.depth) == -EBUSY) { *parent = old; return; diff --git a/trunk/arch/x86/kernel/head32.c b/trunk/arch/x86/kernel/head32.c index 3f8579f8d42c..ac108d1fe182 100644 --- a/trunk/arch/x86/kernel/head32.c +++ b/trunk/arch/x86/kernel/head32.c @@ -18,7 +18,7 @@ void __init i386_start_kernel(void) { reserve_trampoline_memory(); - reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS"); + reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS"); #ifdef CONFIG_BLK_DEV_INITRD /* Reserve INITRD */ @@ -29,6 +29,9 @@ void __init i386_start_kernel(void) reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); } #endif + reserve_early(init_pg_tables_start, init_pg_tables_end, + "INIT_PG_TABLE"); + reserve_ebda_region(); /* diff --git a/trunk/arch/x86/kernel/head64.c b/trunk/arch/x86/kernel/head64.c index 70eaa852c732..f5b272247690 100644 --- a/trunk/arch/x86/kernel/head64.c +++ b/trunk/arch/x86/kernel/head64.c @@ -100,7 +100,7 @@ void __init x86_64_start_reservations(char *real_mode_data) reserve_trampoline_memory(); - reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS"); + reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS"); #ifdef CONFIG_BLK_DEV_INITRD /* Reserve INITRD */ diff --git a/trunk/arch/x86/kernel/head_32.S b/trunk/arch/x86/kernel/head_32.S index 30683883e0cd..c32ca19d591a 100644 --- a/trunk/arch/x86/kernel/head_32.S +++ b/trunk/arch/x86/kernel/head_32.S @@ -38,40 +38,42 @@ #define X86_VENDOR_ID new_cpu_data+CPUINFO_x86_vendor_id /* - * This is how much memory in addition to the memory covered up to - * and including _end we need mapped initially. + * This is how much memory *in addition to the memory covered up to + * and including _end* we need mapped initially. * We need: - * (KERNEL_IMAGE_SIZE/4096) / 1024 pages (worst case, non PAE) - * (KERNEL_IMAGE_SIZE/4096) / 512 + 4 pages (worst case for PAE) + * - one bit for each possible page, but only in low memory, which means + * 2^32/4096/8 = 128K worst case (4G/4G split.) + * - enough space to map all low memory, which means + * (2^32/4096) / 1024 pages (worst case, non PAE) + * (2^32/4096) / 512 + 4 pages (worst case for PAE) + * - a few pages for allocator use before the kernel pagetable has + * been set up * * Modulo rounding, each megabyte assigned here requires a kilobyte of * memory, which is currently unreclaimed. * * This should be a multiple of a page. - * - * KERNEL_IMAGE_SIZE should be greater than pa(_end) - * and small than max_low_pfn, otherwise will waste some page table entries */ +LOW_PAGES = 1<<(32-PAGE_SHIFT_asm) + +/* + * To preserve the DMA pool in PAGEALLOC kernels, we'll allocate + * pagetables from above the 16MB DMA limit, so we'll have to set + * up pagetables 16MB more (worst-case): + */ +#ifdef CONFIG_DEBUG_PAGEALLOC +LOW_PAGES = LOW_PAGES + 0x1000000 +#endif #if PTRS_PER_PMD > 1 -#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD) +PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD #else -#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) +PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD) #endif +BOOTBITMAP_SIZE = LOW_PAGES / 8 +ALLOCATOR_SLOP = 4 -/* Enough space to fit pagetables for the low memory linear map */ -MAPPING_BEYOND_END = \ - PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT - -/* - * Worst-case size of the kernel mapping we need to make: - * the worst-case size of the kernel itself, plus the extra we need - * to map for the linear map. - */ -KERNEL_PAGES = (KERNEL_IMAGE_SIZE + MAPPING_BEYOND_END)>>PAGE_SHIFT - -INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm -RESERVE_BRK(pagetables, INIT_MAP_SIZE) +INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm /* * 32-bit kernel entrypoint; only used by the boot CPU. On entry, @@ -164,10 +166,10 @@ num_subarch_entries = (. - subarch_entries) / 4 /* * Initialize page tables. This creates a PDE and a set of page - * tables, which are located immediately beyond __brk_base. The variable - * _brk_end is set up to point to the first "safe" location. + * tables, which are located immediately beyond _end. The variable + * init_pg_tables_end is set up to point to the first "safe" location. * Mappings are created both at virtual address 0 (identity mapping) - * and PAGE_OFFSET for up to _end. + * and PAGE_OFFSET for up to _end+sizeof(page tables)+INIT_MAP_BEYOND_END. * * Note that the stack is not yet set up! */ @@ -188,7 +190,8 @@ default_entry: xorl %ebx,%ebx /* %ebx is kept at zero */ - movl $pa(__brk_base), %edi + movl $pa(pg0), %edi + movl %edi, pa(init_pg_tables_start) movl $pa(swapper_pg_pmd), %edx movl $PTE_IDENT_ATTR, %eax 10: @@ -206,14 +209,14 @@ default_entry: loop 11b /* - * End condition: we must map up to the end + MAPPING_BEYOND_END. + * End condition: we must map up to and including INIT_MAP_BEYOND_END + * bytes beyond the end of our own page tables. */ - movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp + leal (INIT_MAP_BEYOND_END+PTE_IDENT_ATTR)(%edi),%ebp cmpl %ebp,%eax jb 10b 1: - addl $__PAGE_OFFSET, %edi - movl %edi, pa(_brk_end) + movl %edi,pa(init_pg_tables_end) shrl $12, %eax movl %eax, pa(max_pfn_mapped) @@ -224,7 +227,8 @@ default_entry: page_pde_offset = (__PAGE_OFFSET >> 20); - movl $pa(__brk_base), %edi + movl $pa(pg0), %edi + movl %edi, pa(init_pg_tables_start) movl $pa(swapper_pg_dir), %edx movl $PTE_IDENT_ATTR, %eax 10: @@ -238,13 +242,14 @@ page_pde_offset = (__PAGE_OFFSET >> 20); addl $0x1000,%eax loop 11b /* - * End condition: we must map up to the end + MAPPING_BEYOND_END. + * End condition: we must map up to and including INIT_MAP_BEYOND_END + * bytes beyond the end of our own page tables; the +0x007 is + * the attribute bits */ - movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp + leal (INIT_MAP_BEYOND_END+PTE_IDENT_ATTR)(%edi),%ebp cmpl %ebp,%eax jb 10b - addl $__PAGE_OFFSET, %edi - movl %edi, pa(_brk_end) + movl %edi,pa(init_pg_tables_end) shrl $12, %eax movl %eax, pa(max_pfn_mapped) @@ -631,7 +636,6 @@ swapper_pg_fixmap: .fill 1024,4,0 ENTRY(empty_zero_page) .fill 4096,1,0 - /* * This starts the data section. */ diff --git a/trunk/arch/x86/kernel/i8253.c b/trunk/arch/x86/kernel/i8253.c index 3475440baa54..10f92fb532f3 100644 --- a/trunk/arch/x86/kernel/i8253.c +++ b/trunk/arch/x86/kernel/i8253.c @@ -3,17 +3,17 @@ * */ #include +#include #include -#include #include #include -#include -#include -#include +#include +#include +#include #include +#include #include -#include DEFINE_SPINLOCK(i8253_lock); EXPORT_SYMBOL(i8253_lock); @@ -40,7 +40,7 @@ static void init_pit_timer(enum clock_event_mode mode, { spin_lock(&i8253_lock); - switch (mode) { + switch(mode) { case CLOCK_EVT_MODE_PERIODIC: /* binary, mode 2, LSB/MSB, ch 0 */ outb_pit(0x34, PIT_MODE); @@ -95,7 +95,7 @@ static int pit_next_event(unsigned long delta, struct clock_event_device *evt) * registered. This mechanism replaces the previous #ifdef LOCAL_APIC - * !using_apic_timer decisions in do_timer_interrupt_hook() */ -static struct clock_event_device pit_ce = { +static struct clock_event_device pit_clockevent = { .name = "pit", .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .set_mode = init_pit_timer, @@ -114,13 +114,15 @@ void __init setup_pit_timer(void) * Start pit with the boot cpu mask and make it global after the * IO_APIC has been initialized. */ - pit_ce.cpumask = cpumask_of(smp_processor_id()); - pit_ce.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, pit_ce.shift); - pit_ce.max_delta_ns = clockevent_delta2ns(0x7FFF, &pit_ce); - pit_ce.min_delta_ns = clockevent_delta2ns(0xF, &pit_ce); - - clockevents_register_device(&pit_ce); - global_clock_event = &pit_ce; + pit_clockevent.cpumask = cpumask_of(smp_processor_id()); + pit_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, + pit_clockevent.shift); + pit_clockevent.max_delta_ns = + clockevent_delta2ns(0x7FFF, &pit_clockevent); + pit_clockevent.min_delta_ns = + clockevent_delta2ns(0xF, &pit_clockevent); + clockevents_register_device(&pit_clockevent); + global_clock_event = &pit_clockevent; } #ifndef CONFIG_X86_64 @@ -131,11 +133,11 @@ void __init setup_pit_timer(void) */ static cycle_t pit_read(void) { - static int old_count; - static u32 old_jifs; unsigned long flags; int count; u32 jifs; + static int old_count; + static u32 old_jifs; spin_lock_irqsave(&i8253_lock, flags); /* @@ -177,9 +179,9 @@ static cycle_t pit_read(void) * Previous attempts to handle these cases intelligently were * buggy, so we just do the simple thing now. */ - if (count > old_count && jifs == old_jifs) + if (count > old_count && jifs == old_jifs) { count = old_count; - + } old_count = count; old_jifs = jifs; @@ -190,13 +192,13 @@ static cycle_t pit_read(void) return (cycle_t)(jifs * LATCH) + count; } -static struct clocksource pit_cs = { - .name = "pit", - .rating = 110, - .read = pit_read, - .mask = CLOCKSOURCE_MASK(32), - .mult = 0, - .shift = 20, +static struct clocksource clocksource_pit = { + .name = "pit", + .rating = 110, + .read = pit_read, + .mask = CLOCKSOURCE_MASK(32), + .mult = 0, + .shift = 20, }; static void pit_disable_clocksource(void) @@ -204,9 +206,9 @@ static void pit_disable_clocksource(void) /* * Use mult to check whether it is registered or not */ - if (pit_cs.mult) { - clocksource_unregister(&pit_cs); - pit_cs.mult = 0; + if (clocksource_pit.mult) { + clocksource_unregister(&clocksource_pit); + clocksource_pit.mult = 0; } } @@ -220,13 +222,13 @@ static int __init init_pit_clocksource(void) * - when local APIC timer is active (PIT is switched off) */ if (num_possible_cpus() > 1 || is_hpet_enabled() || - pit_ce.mode != CLOCK_EVT_MODE_PERIODIC) + pit_clockevent.mode != CLOCK_EVT_MODE_PERIODIC) return 0; - pit_cs.mult = clocksource_hz2mult(CLOCK_TICK_RATE, pit_cs.shift); - - return clocksource_register(&pit_cs); + clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, + clocksource_pit.shift); + return clocksource_register(&clocksource_pit); } arch_initcall(init_pit_clocksource); -#endif /* !CONFIG_X86_64 */ +#endif diff --git a/trunk/arch/x86/kernel/io_delay.c b/trunk/arch/x86/kernel/io_delay.c index a979b5bd2fc0..720d2607aacb 100644 --- a/trunk/arch/x86/kernel/io_delay.c +++ b/trunk/arch/x86/kernel/io_delay.c @@ -7,10 +7,10 @@ */ #include #include -#include #include +#include #include -#include +#include int io_delay_type __read_mostly = CONFIG_DEFAULT_IO_DELAY_TYPE; @@ -47,7 +47,8 @@ EXPORT_SYMBOL(native_io_delay); static int __init dmi_io_delay_0xed_port(const struct dmi_system_id *id) { if (io_delay_type == CONFIG_IO_DELAY_TYPE_0X80) { - pr_notice("%s: using 0xed I/O delay port\n", id->ident); + printk(KERN_NOTICE "%s: using 0xed I/O delay port\n", + id->ident); io_delay_type = CONFIG_IO_DELAY_TYPE_0XED; } @@ -63,40 +64,40 @@ static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = { .callback = dmi_io_delay_0xed_port, .ident = "Compaq Presario V6000", .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), - DMI_MATCH(DMI_BOARD_NAME, "30B7") + DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), + DMI_MATCH(DMI_BOARD_NAME, "30B7") } }, { .callback = dmi_io_delay_0xed_port, .ident = "HP Pavilion dv9000z", .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), - DMI_MATCH(DMI_BOARD_NAME, "30B9") + DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), + DMI_MATCH(DMI_BOARD_NAME, "30B9") } }, { .callback = dmi_io_delay_0xed_port, .ident = "HP Pavilion dv6000", .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), - DMI_MATCH(DMI_BOARD_NAME, "30B8") + DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), + DMI_MATCH(DMI_BOARD_NAME, "30B8") } }, { .callback = dmi_io_delay_0xed_port, .ident = "HP Pavilion tx1000", .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), - DMI_MATCH(DMI_BOARD_NAME, "30BF") + DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), + DMI_MATCH(DMI_BOARD_NAME, "30BF") } }, { .callback = dmi_io_delay_0xed_port, .ident = "Presario F700", .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), - DMI_MATCH(DMI_BOARD_NAME, "30D3") + DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), + DMI_MATCH(DMI_BOARD_NAME, "30D3") } }, { } diff --git a/trunk/arch/x86/kernel/irq.c b/trunk/arch/x86/kernel/irq.c index 3aaf7b9e3a8b..f13ca1650aaf 100644 --- a/trunk/arch/x86/kernel/irq.c +++ b/trunk/arch/x86/kernel/irq.c @@ -15,9 +15,6 @@ atomic_t irq_err_count; -/* Function pointer for generic interrupt vector handling */ -void (*generic_interrupt_extension)(void) = NULL; - /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. @@ -45,60 +42,55 @@ void ack_bad_irq(unsigned int irq) /* * /proc/interrupts printing: */ -static int show_other_interrupts(struct seq_file *p, int prec) +static int show_other_interrupts(struct seq_file *p) { int j; - seq_printf(p, "%*s: ", prec, "NMI"); + seq_printf(p, "NMI: "); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->__nmi_count); seq_printf(p, " Non-maskable interrupts\n"); #ifdef CONFIG_X86_LOCAL_APIC - seq_printf(p, "%*s: ", prec, "LOC"); + seq_printf(p, "LOC: "); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->apic_timer_irqs); seq_printf(p, " Local timer interrupts\n"); - - seq_printf(p, "%*s: ", prec, "SPU"); - for_each_online_cpu(j) - seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count); - seq_printf(p, " Spurious interrupts\n"); #endif - if (generic_interrupt_extension) { - seq_printf(p, "PLT: "); - for_each_online_cpu(j) - seq_printf(p, "%10u ", irq_stats(j)->generic_irqs); - seq_printf(p, " Platform interrupts\n"); - } #ifdef CONFIG_SMP - seq_printf(p, "%*s: ", prec, "RES"); + seq_printf(p, "RES: "); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count); seq_printf(p, " Rescheduling interrupts\n"); - seq_printf(p, "%*s: ", prec, "CAL"); + seq_printf(p, "CAL: "); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_call_count); seq_printf(p, " Function call interrupts\n"); - seq_printf(p, "%*s: ", prec, "TLB"); + seq_printf(p, "TLB: "); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count); seq_printf(p, " TLB shootdowns\n"); #endif #ifdef CONFIG_X86_MCE - seq_printf(p, "%*s: ", prec, "TRM"); + seq_printf(p, "TRM: "); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_thermal_count); seq_printf(p, " Thermal event interrupts\n"); # ifdef CONFIG_X86_64 - seq_printf(p, "%*s: ", prec, "THR"); + seq_printf(p, "THR: "); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_threshold_count); seq_printf(p, " Threshold APIC interrupts\n"); # endif #endif - seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); +#ifdef CONFIG_X86_LOCAL_APIC + seq_printf(p, "SPU: "); + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count); + seq_printf(p, " Spurious interrupts\n"); +#endif + seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); #if defined(CONFIG_X86_IO_APIC) - seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count)); + seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); #endif return 0; } @@ -106,22 +98,19 @@ static int show_other_interrupts(struct seq_file *p, int prec) int show_interrupts(struct seq_file *p, void *v) { unsigned long flags, any_count = 0; - int i = *(loff_t *) v, j, prec; + int i = *(loff_t *) v, j; struct irqaction *action; struct irq_desc *desc; if (i > nr_irqs) return 0; - for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec) - j *= 10; - if (i == nr_irqs) - return show_other_interrupts(p, prec); + return show_other_interrupts(p); /* print header */ if (i == 0) { - seq_printf(p, "%*s", prec + 8, ""); + seq_printf(p, " "); for_each_online_cpu(j) seq_printf(p, "CPU%-8d", j); seq_putc(p, '\n'); @@ -132,15 +121,23 @@ int show_interrupts(struct seq_file *p, void *v) return 0; spin_lock_irqsave(&desc->lock, flags); +#ifndef CONFIG_SMP + any_count = kstat_irqs(i); +#else for_each_online_cpu(j) any_count |= kstat_irqs_cpu(i, j); +#endif action = desc->action; if (!action && !any_count) goto out; - seq_printf(p, "%*d: ", prec, i); + seq_printf(p, "%3d: ", i); +#ifndef CONFIG_SMP + seq_printf(p, "%10u ", kstat_irqs(i)); +#else for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); +#endif seq_printf(p, " %8s", desc->chip->name); seq_printf(p, "-%-8s", desc->name); @@ -165,10 +162,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu) #ifdef CONFIG_X86_LOCAL_APIC sum += irq_stats(cpu)->apic_timer_irqs; - sum += irq_stats(cpu)->irq_spurious_count; #endif - if (generic_interrupt_extension) - sum += irq_stats(cpu)->generic_irqs; #ifdef CONFIG_SMP sum += irq_stats(cpu)->irq_resched_count; sum += irq_stats(cpu)->irq_call_count; @@ -179,6 +173,9 @@ u64 arch_irq_stat_cpu(unsigned int cpu) # ifdef CONFIG_X86_64 sum += irq_stats(cpu)->irq_threshold_count; #endif +#endif +#ifdef CONFIG_X86_LOCAL_APIC + sum += irq_stats(cpu)->irq_spurious_count; #endif return sum; } @@ -229,27 +226,4 @@ unsigned int __irq_entry do_IRQ(struct pt_regs *regs) return 1; } -/* - * Handler for GENERIC_INTERRUPT_VECTOR. - */ -void smp_generic_interrupt(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - - ack_APIC_irq(); - - exit_idle(); - - irq_enter(); - - inc_irq_stat(generic_irqs); - - if (generic_interrupt_extension) - generic_interrupt_extension(); - - irq_exit(); - - set_irq_regs(old_regs); -} - EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); diff --git a/trunk/arch/x86/kernel/irqinit_32.c b/trunk/arch/x86/kernel/irqinit_32.c index 368b0a8836f9..50b8c3a3006c 100644 --- a/trunk/arch/x86/kernel/irqinit_32.c +++ b/trunk/arch/x86/kernel/irqinit_32.c @@ -50,6 +50,7 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id) */ static struct irqaction fpu_irq = { .handler = math_error_irq, + .mask = CPU_MASK_NONE, .name = "fpu", }; @@ -82,6 +83,7 @@ void __init init_ISA_irqs(void) */ static struct irqaction irq2 = { .handler = no_action, + .mask = CPU_MASK_NONE, .name = "cascade", }; @@ -173,9 +175,6 @@ void __init native_init_IRQ(void) /* self generated IPI for local APIC timer */ alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); - /* generic IPI for platform specific use */ - alloc_intr_gate(GENERIC_INTERRUPT_VECTOR, generic_interrupt); - /* IPI vectors for APIC spurious and error interrupts */ alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); diff --git a/trunk/arch/x86/kernel/irqinit_64.c b/trunk/arch/x86/kernel/irqinit_64.c index 8cd10537fd46..da481a1e3f30 100644 --- a/trunk/arch/x86/kernel/irqinit_64.c +++ b/trunk/arch/x86/kernel/irqinit_64.c @@ -45,6 +45,7 @@ static struct irqaction irq2 = { .handler = no_action, + .mask = CPU_MASK_NONE, .name = "cascade", }; DEFINE_PER_CPU(vector_irq_t, vector_irq) = { @@ -146,9 +147,6 @@ static void __init apic_intr_init(void) /* self generated IPI for local APIC timer */ alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); - /* generic IPI for platform specific use */ - alloc_intr_gate(GENERIC_INTERRUPT_VECTOR, generic_interrupt); - /* IPI vectors for APIC spurious and error interrupts */ alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); diff --git a/trunk/arch/x86/kernel/kdebugfs.c b/trunk/arch/x86/kernel/kdebugfs.c index e444357375ce..ff7d3b0124f1 100644 --- a/trunk/arch/x86/kernel/kdebugfs.c +++ b/trunk/arch/x86/kernel/kdebugfs.c @@ -8,11 +8,11 @@ */ #include #include -#include -#include #include +#include #include #include +#include #include @@ -26,8 +26,9 @@ struct setup_data_node { u32 len; }; -static ssize_t setup_data_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t +setup_data_read(struct file *file, char __user *user_buf, size_t count, + loff_t *ppos) { struct setup_data_node *node = file->private_data; unsigned long remain; @@ -38,21 +39,20 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf, if (pos < 0) return -EINVAL; - if (pos >= node->len) return 0; if (count > node->len - pos) count = node->len - pos; - pa = node->paddr + sizeof(struct setup_data) + pos; pg = pfn_to_page((pa + count - 1) >> PAGE_SHIFT); if (PageHighMem(pg)) { p = ioremap_cache(pa, count); if (!p) return -ENXIO; - } else + } else { p = __va(pa); + } remain = copy_to_user(user_buf, p, count); @@ -70,13 +70,12 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf, static int setup_data_open(struct inode *inode, struct file *file) { file->private_data = inode->i_private; - return 0; } static const struct file_operations fops_setup_data = { - .read = setup_data_read, - .open = setup_data_open, + .read = setup_data_read, + .open = setup_data_open, }; static int __init @@ -85,50 +84,57 @@ create_setup_data_node(struct dentry *parent, int no, { struct dentry *d, *type, *data; char buf[16]; + int error; sprintf(buf, "%d", no); d = debugfs_create_dir(buf, parent); - if (!d) - return -ENOMEM; - + if (!d) { + error = -ENOMEM; + goto err_return; + } type = debugfs_create_x32("type", S_IRUGO, d, &node->type); - if (!type) + if (!type) { + error = -ENOMEM; goto err_dir; - + } data = debugfs_create_file("data", S_IRUGO, d, node, &fops_setup_data); - if (!data) + if (!data) { + error = -ENOMEM; goto err_type; - + } return 0; err_type: debugfs_remove(type); err_dir: debugfs_remove(d); - return -ENOMEM; +err_return: + return error; } static int __init create_setup_data_nodes(struct dentry *parent) { struct setup_data_node *node; struct setup_data *data; - int error = -ENOMEM; + int error, no = 0; struct dentry *d; struct page *pg; u64 pa_data; - int no = 0; d = debugfs_create_dir("setup_data", parent); - if (!d) - return -ENOMEM; + if (!d) { + error = -ENOMEM; + goto err_return; + } pa_data = boot_params.hdr.setup_data; while (pa_data) { node = kmalloc(sizeof(*node), GFP_KERNEL); - if (!node) + if (!node) { + error = -ENOMEM; goto err_dir; - + } pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT); if (PageHighMem(pg)) { data = ioremap_cache(pa_data, sizeof(*data)); @@ -137,8 +143,9 @@ static int __init create_setup_data_nodes(struct dentry *parent) error = -ENXIO; goto err_dir; } - } else + } else { data = __va(pa_data); + } node->paddr = pa_data; node->type = data->type; @@ -152,11 +159,11 @@ static int __init create_setup_data_nodes(struct dentry *parent) goto err_dir; no++; } - return 0; err_dir: debugfs_remove(d); +err_return: return error; } @@ -168,26 +175,28 @@ static struct debugfs_blob_wrapper boot_params_blob = { static int __init boot_params_kdebugfs_init(void) { struct dentry *dbp, *version, *data; - int error = -ENOMEM; + int error; dbp = debugfs_create_dir("boot_params", NULL); - if (!dbp) - return -ENOMEM; - + if (!dbp) { + error = -ENOMEM; + goto err_return; + } version = debugfs_create_x16("version", S_IRUGO, dbp, &boot_params.hdr.version); - if (!version) + if (!version) { + error = -ENOMEM; goto err_dir; - + } data = debugfs_create_blob("data", S_IRUGO, dbp, &boot_params_blob); - if (!data) + if (!data) { + error = -ENOMEM; goto err_version; - + } error = create_setup_data_nodes(dbp); if (error) goto err_data; - return 0; err_data: @@ -196,9 +205,10 @@ static int __init boot_params_kdebugfs_init(void) debugfs_remove(version); err_dir: debugfs_remove(dbp); +err_return: return error; } -#endif /* CONFIG_DEBUG_BOOT_PARAMS */ +#endif static int __init arch_kdebugfs_init(void) { diff --git a/trunk/arch/x86/kernel/kprobes.c b/trunk/arch/x86/kernel/kprobes.c index 55b94614e348..4558dd3918cf 100644 --- a/trunk/arch/x86/kernel/kprobes.c +++ b/trunk/arch/x86/kernel/kprobes.c @@ -193,7 +193,7 @@ static int __kprobes can_boost(kprobe_opcode_t *opcodes) kprobe_opcode_t opcode; kprobe_opcode_t *orig_opcodes = opcodes; - if (search_exception_tables((unsigned long)opcodes)) + if (search_exception_tables(opcodes)) return 0; /* Page fault may occur on this address. */ retry: diff --git a/trunk/arch/x86/kernel/kvm.c b/trunk/arch/x86/kernel/kvm.c index 33019ddb56b4..478bca986eca 100644 --- a/trunk/arch/x86/kernel/kvm.c +++ b/trunk/arch/x86/kernel/kvm.c @@ -138,6 +138,12 @@ static void kvm_set_pte_atomic(pte_t *ptep, pte_t pte) kvm_mmu_write(ptep, pte_val(pte)); } +static void kvm_set_pte_present(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ + kvm_mmu_write(ptep, pte_val(pte)); +} + static void kvm_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { @@ -214,6 +220,7 @@ static void paravirt_ops_setup(void) #if PAGETABLE_LEVELS >= 3 #ifdef CONFIG_X86_PAE pv_mmu_ops.set_pte_atomic = kvm_set_pte_atomic; + pv_mmu_ops.set_pte_present = kvm_set_pte_present; pv_mmu_ops.pte_clear = kvm_pte_clear; pv_mmu_ops.pmd_clear = kvm_pmd_clear; #endif diff --git a/trunk/arch/x86/kernel/machine_kexec_32.c b/trunk/arch/x86/kernel/machine_kexec_32.c index e7368c1da01d..f5fc8c781a62 100644 --- a/trunk/arch/x86/kernel/machine_kexec_32.c +++ b/trunk/arch/x86/kernel/machine_kexec_32.c @@ -14,12 +14,12 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -63,7 +63,7 @@ static void load_segments(void) "\tmovl %%eax,%%fs\n" "\tmovl %%eax,%%gs\n" "\tmovl %%eax,%%ss\n" - : : : "eax", "memory"); + ::: "eax", "memory"); #undef STR #undef __STR } @@ -205,8 +205,7 @@ void machine_kexec(struct kimage *image) if (image->preserve_context) { #ifdef CONFIG_X86_IO_APIC - /* - * We need to put APICs in legacy mode so that we can + /* We need to put APICs in legacy mode so that we can * get timer interrupts in second kernel. kexec/kdump * paths already have calls to disable_IO_APIC() in * one form or other. kexec jump path also need @@ -228,8 +227,7 @@ void machine_kexec(struct kimage *image) page_list[PA_SWAP_PAGE] = (page_to_pfn(image->swap_page) << PAGE_SHIFT); - /* - * The segment registers are funny things, they have both a + /* The segment registers are funny things, they have both a * visible and an invisible part. Whenever the visible part is * set to a specific selector, the invisible part is loaded * with from a table in memory. At no other time is the @@ -239,12 +237,11 @@ void machine_kexec(struct kimage *image) * segments, before I zap the gdt with an invalid value. */ load_segments(); - /* - * The gdt & idt are now invalid. + /* The gdt & idt are now invalid. * If you want to load them you must set up your own idt & gdt. */ - set_gdt(phys_to_virt(0), 0); - set_idt(phys_to_virt(0), 0); + set_gdt(phys_to_virt(0),0); + set_idt(phys_to_virt(0),0); /* now call it */ image->start = relocate_kernel_ptr((unsigned long)image->head, diff --git a/trunk/arch/x86/kernel/machine_kexec_64.c b/trunk/arch/x86/kernel/machine_kexec_64.c index 89cea4d44679..6993d51b7fd8 100644 --- a/trunk/arch/x86/kernel/machine_kexec_64.c +++ b/trunk/arch/x86/kernel/machine_kexec_64.c @@ -12,47 +12,11 @@ #include #include #include -#include -#include #include #include #include - -static int init_one_level2_page(struct kimage *image, pgd_t *pgd, - unsigned long addr) -{ - pud_t *pud; - pmd_t *pmd; - struct page *page; - int result = -ENOMEM; - - addr &= PMD_MASK; - pgd += pgd_index(addr); - if (!pgd_present(*pgd)) { - page = kimage_alloc_control_pages(image, 0); - if (!page) - goto out; - pud = (pud_t *)page_address(page); - memset(pud, 0, PAGE_SIZE); - set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE)); - } - pud = pud_offset(pgd, addr); - if (!pud_present(*pud)) { - page = kimage_alloc_control_pages(image, 0); - if (!page) - goto out; - pmd = (pmd_t *)page_address(page); - memset(pmd, 0, PAGE_SIZE); - set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE)); - } - pmd = pmd_offset(pud, addr); - if (!pmd_present(*pmd)) - set_pmd(pmd, __pmd(addr | __PAGE_KERNEL_LARGE_EXEC)); - result = 0; -out: - return result; -} +#include static void init_level2_page(pmd_t *level2p, unsigned long addr) { @@ -119,8 +83,9 @@ static int init_level4_page(struct kimage *image, pgd_t *level4p, } level3p = (pud_t *)page_address(page); result = init_level3_page(image, level3p, addr, last_addr); - if (result) + if (result) { goto out; + } set_pgd(level4p++, __pgd(__pa(level3p) | _KERNPG_TABLE)); addr += PGDIR_SIZE; } @@ -189,13 +154,6 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable) int result; level4p = (pgd_t *)__va(start_pgtable); result = init_level4_page(image, level4p, 0, max_pfn << PAGE_SHIFT); - if (result) - return result; - /* - * image->start may be outside 0 ~ max_pfn, for example when - * jump back to original kernel from kexeced kernel - */ - result = init_one_level2_page(image, level4p, image->start); if (result) return result; return init_transition_pgtable(image, level4p); @@ -271,45 +229,20 @@ void machine_kexec(struct kimage *image) { unsigned long page_list[PAGES_NR]; void *control_page; - int save_ftrace_enabled; -#ifdef CONFIG_KEXEC_JUMP - if (kexec_image->preserve_context) - save_processor_state(); -#endif - - save_ftrace_enabled = __ftrace_enabled_save(); + tracer_disable(); /* Interrupts aren't acceptable while we reboot */ local_irq_disable(); - if (image->preserve_context) { -#ifdef CONFIG_X86_IO_APIC - /* - * We need to put APICs in legacy mode so that we can - * get timer interrupts in second kernel. kexec/kdump - * paths already have calls to disable_IO_APIC() in - * one form or other. kexec jump path also need - * one. - */ - disable_IO_APIC(); -#endif - } - control_page = page_address(image->control_code_page) + PAGE_SIZE; - memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE); + memcpy(control_page, relocate_kernel, PAGE_SIZE); page_list[PA_CONTROL_PAGE] = virt_to_phys(control_page); - page_list[VA_CONTROL_PAGE] = (unsigned long)control_page; page_list[PA_TABLE_PAGE] = (unsigned long)__pa(page_address(image->control_code_page)); - if (image->type == KEXEC_TYPE_DEFAULT) - page_list[PA_SWAP_PAGE] = (page_to_pfn(image->swap_page) - << PAGE_SHIFT); - - /* - * The segment registers are funny things, they have both a + /* The segment registers are funny things, they have both a * visible and an invisible part. Whenever the visible part is * set to a specific selector, the invisible part is loaded * with from a table in memory. At no other time is the @@ -319,25 +252,15 @@ void machine_kexec(struct kimage *image) * segments, before I zap the gdt with an invalid value. */ load_segments(); - /* - * The gdt & idt are now invalid. + /* The gdt & idt are now invalid. * If you want to load them you must set up your own idt & gdt. */ - set_gdt(phys_to_virt(0), 0); - set_idt(phys_to_virt(0), 0); + set_gdt(phys_to_virt(0),0); + set_idt(phys_to_virt(0),0); /* now call it */ - image->start = relocate_kernel((unsigned long)image->head, - (unsigned long)page_list, - image->start, - image->preserve_context); - -#ifdef CONFIG_KEXEC_JUMP - if (kexec_image->preserve_context) - restore_processor_state(); -#endif - - __ftrace_enabled_restore(save_ftrace_enabled); + relocate_kernel((unsigned long)image->head, (unsigned long)page_list, + image->start); } void arch_crash_save_vmcoreinfo(void) diff --git a/trunk/arch/x86/kernel/mfgpt_32.c b/trunk/arch/x86/kernel/mfgpt_32.c index 846510b78a09..8815f3c7fec7 100644 --- a/trunk/arch/x86/kernel/mfgpt_32.c +++ b/trunk/arch/x86/kernel/mfgpt_32.c @@ -348,6 +348,7 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id) static struct irqaction mfgptirq = { .handler = mfgpt_tick, .flags = IRQF_DISABLED | IRQF_NOBALANCING, + .mask = CPU_MASK_NONE, .name = "mfgpt-timer" }; diff --git a/trunk/arch/x86/kernel/mmconf-fam10h_64.c b/trunk/arch/x86/kernel/mmconf-fam10h_64.c index 712d15fdc416..666e43df51f9 100644 --- a/trunk/arch/x86/kernel/mmconf-fam10h_64.c +++ b/trunk/arch/x86/kernel/mmconf-fam10h_64.c @@ -226,7 +226,7 @@ static int __devinit set_check_enable_amd_mmconf(const struct dmi_system_id *d) return 0; } -static const struct dmi_system_id __cpuinitconst mmconf_dmi_table[] = { +static struct dmi_system_id __devinitdata mmconf_dmi_table[] = { { .callback = set_check_enable_amd_mmconf, .ident = "Sun Microsystems Machine", diff --git a/trunk/arch/x86/kernel/mpparse.c b/trunk/arch/x86/kernel/mpparse.c index dce99dca6cf8..37cb1bda1baf 100644 --- a/trunk/arch/x86/kernel/mpparse.c +++ b/trunk/arch/x86/kernel/mpparse.c @@ -109,6 +109,9 @@ static void __init MP_bus_info(struct mpc_bus *m) } else printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str); } +#endif + +#ifdef CONFIG_X86_IO_APIC static int bad_ioapic(unsigned long address) { @@ -221,12 +224,8 @@ static void __init MP_intsrc_info(struct mpc_intsrc *m) if (++mp_irq_entries == MAX_IRQ_SOURCES) panic("Max # of irq sources exceeded!!\n"); } -#else /* CONFIG_X86_IO_APIC */ -static inline void __init MP_bus_info(struct mpc_bus *m) {} -static inline void __init MP_ioapic_info(struct mpc_ioapic *m) {} -static inline void __init MP_intsrc_info(struct mpc_intsrc *m) {} -#endif /* CONFIG_X86_IO_APIC */ +#endif static void __init MP_lintsrc_info(struct mpc_lintsrc *m) { @@ -276,20 +275,6 @@ static int __init smp_check_mpc(struct mpc_table *mpc, char *oem, char *str) return 1; } -static void skip_entry(unsigned char **ptr, int *count, int size) -{ - *ptr += size; - *count += size; -} - -static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt) -{ - printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n" - "type %x\n", *mpt); - print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_ADDRESS, 16, - 1, mpc, mpc->length, 1); -} - static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) { char str[16]; @@ -325,30 +310,61 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) while (count < mpc->length) { switch (*mpt) { case MP_PROCESSOR: - /* ACPI may have already provided this data */ - if (!acpi_lapic) - MP_processor_info((struct mpc_cpu *)mpt); - skip_entry(&mpt, &count, sizeof(struct mpc_cpu)); - break; + { + struct mpc_cpu *m = (struct mpc_cpu *)mpt; + /* ACPI may have already provided this data */ + if (!acpi_lapic) + MP_processor_info(m); + mpt += sizeof(*m); + count += sizeof(*m); + break; + } case MP_BUS: - MP_bus_info((struct mpc_bus *)mpt); - skip_entry(&mpt, &count, sizeof(struct mpc_bus)); - break; + { + struct mpc_bus *m = (struct mpc_bus *)mpt; +#ifdef CONFIG_X86_IO_APIC + MP_bus_info(m); +#endif + mpt += sizeof(*m); + count += sizeof(*m); + break; + } case MP_IOAPIC: - MP_ioapic_info((struct mpc_ioapic *)mpt); - skip_entry(&mpt, &count, sizeof(struct mpc_ioapic)); - break; + { +#ifdef CONFIG_X86_IO_APIC + struct mpc_ioapic *m = (struct mpc_ioapic *)mpt; + MP_ioapic_info(m); +#endif + mpt += sizeof(struct mpc_ioapic); + count += sizeof(struct mpc_ioapic); + break; + } case MP_INTSRC: - MP_intsrc_info((struct mpc_intsrc *)mpt); - skip_entry(&mpt, &count, sizeof(struct mpc_intsrc)); - break; + { +#ifdef CONFIG_X86_IO_APIC + struct mpc_intsrc *m = (struct mpc_intsrc *)mpt; + + MP_intsrc_info(m); +#endif + mpt += sizeof(struct mpc_intsrc); + count += sizeof(struct mpc_intsrc); + break; + } case MP_LINTSRC: - MP_lintsrc_info((struct mpc_lintsrc *)mpt); - skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc)); - break; + { + struct mpc_lintsrc *m = + (struct mpc_lintsrc *)mpt; + MP_lintsrc_info(m); + mpt += sizeof(*m); + count += sizeof(*m); + break; + } default: /* wrong mptable */ - smp_dump_mptable(mpc, mpt); + printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n"); + printk(KERN_ERR "type %x\n", *mpt); + print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_ADDRESS, 16, + 1, mpc, mpc->length, 1); count = mpc->length; break; } @@ -542,68 +558,6 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) static struct mpf_intel *mpf_found; -static unsigned long __init get_mpc_size(unsigned long physptr) -{ - struct mpc_table *mpc; - unsigned long size; - - mpc = early_ioremap(physptr, PAGE_SIZE); - size = mpc->length; - early_iounmap(mpc, PAGE_SIZE); - apic_printk(APIC_VERBOSE, " mpc: %lx-%lx\n", physptr, physptr + size); - - return size; -} - -static int __init check_physptr(struct mpf_intel *mpf, unsigned int early) -{ - struct mpc_table *mpc; - unsigned long size; - - size = get_mpc_size(mpf->physptr); - mpc = early_ioremap(mpf->physptr, size); - /* - * Read the physical hardware table. Anything here will - * override the defaults. - */ - if (!smp_read_mpc(mpc, early)) { -#ifdef CONFIG_X86_LOCAL_APIC - smp_found_config = 0; -#endif - printk(KERN_ERR "BIOS bug, MP table errors detected!...\n" - "... disabling SMP support. (tell your hw vendor)\n"); - early_iounmap(mpc, size); - return -1; - } - early_iounmap(mpc, size); - - if (early) - return -1; - -#ifdef CONFIG_X86_IO_APIC - /* - * If there are no explicit MP IRQ entries, then we are - * broken. We set up most of the low 16 IO-APIC pins to - * ISA defaults and hope it will work. - */ - if (!mp_irq_entries) { - struct mpc_bus bus; - - printk(KERN_ERR "BIOS bug, no explicit IRQ entries, " - "using default mptable. (tell your hw vendor)\n"); - - bus.type = MP_BUS; - bus.busid = 0; - memcpy(bus.bustype, "ISA ", 6); - MP_bus_info(&bus); - - construct_default_ioirq_mptable(0); - } -#endif - - return 0; -} - /* * Scan the memory blocks for an SMP configuration block. */ @@ -657,8 +611,45 @@ static void __init __get_smp_config(unsigned int early) construct_default_ISA_mptable(mpf->feature1); } else if (mpf->physptr) { - if (check_physptr(mpf, early)) + + /* + * Read the physical hardware table. Anything here will + * override the defaults. + */ + if (!smp_read_mpc(phys_to_virt(mpf->physptr), early)) { +#ifdef CONFIG_X86_LOCAL_APIC + smp_found_config = 0; +#endif + printk(KERN_ERR + "BIOS bug, MP table errors detected!...\n"); + printk(KERN_ERR "... disabling SMP support. " + "(tell your hw vendor)\n"); + return; + } + + if (early) return; +#ifdef CONFIG_X86_IO_APIC + /* + * If there are no explicit MP IRQ entries, then we are + * broken. We set up most of the low 16 IO-APIC pins to + * ISA defaults and hope it will work. + */ + if (!mp_irq_entries) { + struct mpc_bus bus; + + printk(KERN_ERR "BIOS bug, no explicit IRQ entries, " + "using default mptable. " + "(tell your hw vendor)\n"); + + bus.type = MP_BUS; + bus.busid = 0; + memcpy(bus.bustype, "ISA ", 6); + MP_bus_info(&bus); + + construct_default_ioirq_mptable(0); + } +#endif } else BUG(); @@ -679,31 +670,6 @@ void __init get_smp_config(void) __get_smp_config(0); } -static void smp_reserve_bootmem(struct mpf_intel *mpf) -{ - unsigned long size = get_mpc_size(mpf->physptr); -#ifdef CONFIG_X86_32 - /* - * We cannot access to MPC table to compute table size yet, - * as only few megabytes from the bottom is mapped now. - * PC-9800's MPC table places on the very last of physical - * memory; so that simply reserving PAGE_SIZE from mpf->physptr - * yields BUG() in reserve_bootmem. - * also need to make sure physptr is below than max_low_pfn - * we don't need reserve the area above max_low_pfn - */ - unsigned long end = max_low_pfn * PAGE_SIZE; - - if (mpf->physptr < end) { - if (mpf->physptr + size > end) - size = end - mpf->physptr; - reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT); - } -#else - reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT); -#endif -} - static int __init smp_scan_config(unsigned long base, unsigned long length, unsigned reserve) { @@ -731,10 +697,36 @@ static int __init smp_scan_config(unsigned long base, unsigned long length, if (!reserve) return 1; - reserve_bootmem_generic(virt_to_phys(mpf), sizeof(*mpf), + reserve_bootmem_generic(virt_to_phys(mpf), PAGE_SIZE, + BOOTMEM_DEFAULT); + if (mpf->physptr) { + unsigned long size = PAGE_SIZE; +#ifdef CONFIG_X86_32 + /* + * We cannot access to MPC table to compute + * table size yet, as only few megabytes from + * the bottom is mapped now. + * PC-9800's MPC table places on the very last + * of physical memory; so that simply reserving + * PAGE_SIZE from mpf->physptr yields BUG() + * in reserve_bootmem. + * also need to make sure physptr is below than + * max_low_pfn + * we don't need reserve the area above max_low_pfn + */ + unsigned long end = max_low_pfn * PAGE_SIZE; + + if (mpf->physptr < end) { + if (mpf->physptr + size > end) + size = end - mpf->physptr; + reserve_bootmem_generic(mpf->physptr, size, + BOOTMEM_DEFAULT); + } +#else + reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT); - if (mpf->physptr) - smp_reserve_bootmem(mpf); +#endif + } return 1; } @@ -837,57 +829,7 @@ static int __init get_MP_intsrc_index(struct mpc_intsrc *m) #define SPARE_SLOT_NUM 20 static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM]; - -static void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) -{ - int i; - - apic_printk(APIC_VERBOSE, "OLD "); - print_MP_intsrc_info(m); - - i = get_MP_intsrc_index(m); - if (i > 0) { - assign_to_mpc_intsrc(&mp_irqs[i], m); - apic_printk(APIC_VERBOSE, "NEW "); - print_mp_irq_info(&mp_irqs[i]); - return; - } - if (!i) { - /* legacy, do nothing */ - return; - } - if (*nr_m_spare < SPARE_SLOT_NUM) { - /* - * not found (-1), or duplicated (-2) are invalid entries, - * we need to use the slot later - */ - m_spare[*nr_m_spare] = m; - *nr_m_spare += 1; - } -} -#else /* CONFIG_X86_IO_APIC */ -static inline void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {} -#endif /* CONFIG_X86_IO_APIC */ - -static int check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, - int count) -{ - if (!mpc_new_phys) { - pr_info("No spare slots, try to append...take your risk, " - "new mpc_length %x\n", count); - } else { - if (count <= mpc_new_length) - pr_info("No spare slots, try to append..., " - "new mpc_length %x\n", count); - else { - pr_err("mpc_new_length %lx is too small\n", - mpc_new_length); - return -1; - } - } - - return 0; -} +#endif static int __init replace_intsrc_all(struct mpc_table *mpc, unsigned long mpc_new_phys, @@ -895,33 +837,77 @@ static int __init replace_intsrc_all(struct mpc_table *mpc, { #ifdef CONFIG_X86_IO_APIC int i; + int nr_m_spare = 0; #endif + int count = sizeof(*mpc); - int nr_m_spare = 0; unsigned char *mpt = ((unsigned char *)mpc) + count; printk(KERN_INFO "mpc_length %x\n", mpc->length); while (count < mpc->length) { switch (*mpt) { case MP_PROCESSOR: - skip_entry(&mpt, &count, sizeof(struct mpc_cpu)); - break; + { + struct mpc_cpu *m = (struct mpc_cpu *)mpt; + mpt += sizeof(*m); + count += sizeof(*m); + break; + } case MP_BUS: - skip_entry(&mpt, &count, sizeof(struct mpc_bus)); - break; + { + struct mpc_bus *m = (struct mpc_bus *)mpt; + mpt += sizeof(*m); + count += sizeof(*m); + break; + } case MP_IOAPIC: - skip_entry(&mpt, &count, sizeof(struct mpc_ioapic)); - break; + { + mpt += sizeof(struct mpc_ioapic); + count += sizeof(struct mpc_ioapic); + break; + } case MP_INTSRC: - check_irq_src((struct mpc_intsrc *)mpt, &nr_m_spare); - skip_entry(&mpt, &count, sizeof(struct mpc_intsrc)); - break; + { +#ifdef CONFIG_X86_IO_APIC + struct mpc_intsrc *m = (struct mpc_intsrc *)mpt; + + printk(KERN_INFO "OLD "); + print_MP_intsrc_info(m); + i = get_MP_intsrc_index(m); + if (i > 0) { + assign_to_mpc_intsrc(&mp_irqs[i], m); + printk(KERN_INFO "NEW "); + print_mp_irq_info(&mp_irqs[i]); + } else if (!i) { + /* legacy, do nothing */ + } else if (nr_m_spare < SPARE_SLOT_NUM) { + /* + * not found (-1), or duplicated (-2) + * are invalid entries, + * we need to use the slot later + */ + m_spare[nr_m_spare] = m; + nr_m_spare++; + } +#endif + mpt += sizeof(struct mpc_intsrc); + count += sizeof(struct mpc_intsrc); + break; + } case MP_LINTSRC: - skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc)); - break; + { + struct mpc_lintsrc *m = + (struct mpc_lintsrc *)mpt; + mpt += sizeof(*m); + count += sizeof(*m); + break; + } default: /* wrong mptable */ - smp_dump_mptable(mpc, mpt); + printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n"); + printk(KERN_ERR "type %x\n", *mpt); + print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_ADDRESS, 16, + 1, mpc, mpc->length, 1); goto out; } } @@ -938,15 +924,23 @@ static int __init replace_intsrc_all(struct mpc_table *mpc, continue; if (nr_m_spare > 0) { - apic_printk(APIC_VERBOSE, "*NEW* found\n"); + printk(KERN_INFO "*NEW* found "); nr_m_spare--; assign_to_mpc_intsrc(&mp_irqs[i], m_spare[nr_m_spare]); m_spare[nr_m_spare] = NULL; } else { struct mpc_intsrc *m = (struct mpc_intsrc *)mpt; count += sizeof(struct mpc_intsrc); - if (!check_slot(mpc_new_phys, mpc_new_length, count)) - goto out; + if (!mpc_new_phys) { + printk(KERN_INFO "No spare slots, try to append...take your risk, new mpc_length %x\n", count); + } else { + if (count <= mpc_new_length) + printk(KERN_INFO "No spare slots, try to append..., new mpc_length %x\n", count); + else { + printk(KERN_ERR "mpc_new_length %lx is too small\n", mpc_new_length); + goto out; + } + } assign_to_mpc_intsrc(&mp_irqs[i], m); mpc->length = count; mpt += sizeof(struct mpc_intsrc); diff --git a/trunk/arch/x86/kernel/paravirt.c b/trunk/arch/x86/kernel/paravirt.c index 8e45f4464880..63dd358d8ee1 100644 --- a/trunk/arch/x86/kernel/paravirt.c +++ b/trunk/arch/x86/kernel/paravirt.c @@ -470,6 +470,7 @@ struct pv_mmu_ops pv_mmu_ops = { #if PAGETABLE_LEVELS >= 3 #ifdef CONFIG_X86_PAE .set_pte_atomic = native_set_pte_atomic, + .set_pte_present = native_set_pte_present, .pte_clear = native_pte_clear, .pmd_clear = native_pmd_clear, #endif diff --git a/trunk/arch/x86/kernel/pci-calgary_64.c b/trunk/arch/x86/kernel/pci-calgary_64.c index 755c21e906f3..d28bbdc35e4e 100644 --- a/trunk/arch/x86/kernel/pci-calgary_64.c +++ b/trunk/arch/x86/kernel/pci-calgary_64.c @@ -380,9 +380,8 @@ static inline struct iommu_table *find_iommu_table(struct device *dev) return tbl; } -static void calgary_unmap_sg(struct device *dev, struct scatterlist *sglist, - int nelems,enum dma_data_direction dir, - struct dma_attrs *attrs) +static void calgary_unmap_sg(struct device *dev, + struct scatterlist *sglist, int nelems, int direction) { struct iommu_table *tbl = find_iommu_table(dev); struct scatterlist *s; @@ -405,8 +404,7 @@ static void calgary_unmap_sg(struct device *dev, struct scatterlist *sglist, } static int calgary_map_sg(struct device *dev, struct scatterlist *sg, - int nelems, enum dma_data_direction dir, - struct dma_attrs *attrs) + int nelems, int direction) { struct iommu_table *tbl = find_iommu_table(dev); struct scatterlist *s; @@ -431,14 +429,15 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, s->dma_address = (entry << PAGE_SHIFT) | s->offset; /* insert into HW table */ - tce_build(tbl, entry, npages, vaddr & PAGE_MASK, dir); + tce_build(tbl, entry, npages, vaddr & PAGE_MASK, + direction); s->dma_length = s->length; } return nelems; error: - calgary_unmap_sg(dev, sg, nelems, dir, NULL); + calgary_unmap_sg(dev, sg, nelems, direction); for_each_sg(sg, s, nelems, i) { sg->dma_address = bad_dma_address; sg->dma_length = 0; @@ -446,12 +445,10 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, return 0; } -static dma_addr_t calgary_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) +static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, + size_t size, int direction) { - void *vaddr = page_address(page) + offset; + void *vaddr = phys_to_virt(paddr); unsigned long uaddr; unsigned int npages; struct iommu_table *tbl = find_iommu_table(dev); @@ -459,18 +456,17 @@ static dma_addr_t calgary_map_page(struct device *dev, struct page *page, uaddr = (unsigned long)vaddr; npages = iommu_num_pages(uaddr, size, PAGE_SIZE); - return iommu_alloc(dev, tbl, vaddr, npages, dir); + return iommu_alloc(dev, tbl, vaddr, npages, direction); } -static void calgary_unmap_page(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction dir, - struct dma_attrs *attrs) +static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, + size_t size, int direction) { struct iommu_table *tbl = find_iommu_table(dev); unsigned int npages; - npages = iommu_num_pages(dma_addr, size, PAGE_SIZE); - iommu_free(tbl, dma_addr, npages); + npages = iommu_num_pages(dma_handle, size, PAGE_SIZE); + iommu_free(tbl, dma_handle, npages); } static void* calgary_alloc_coherent(struct device *dev, size_t size, @@ -519,13 +515,13 @@ static void calgary_free_coherent(struct device *dev, size_t size, free_pages((unsigned long)vaddr, get_order(size)); } -static struct dma_map_ops calgary_dma_ops = { +static struct dma_mapping_ops calgary_dma_ops = { .alloc_coherent = calgary_alloc_coherent, .free_coherent = calgary_free_coherent, + .map_single = calgary_map_single, + .unmap_single = calgary_unmap_single, .map_sg = calgary_map_sg, .unmap_sg = calgary_unmap_sg, - .map_page = calgary_map_page, - .unmap_page = calgary_unmap_page, }; static inline void __iomem * busno_to_bbar(unsigned char num) diff --git a/trunk/arch/x86/kernel/pci-dma.c b/trunk/arch/x86/kernel/pci-dma.c index 90f5b9ef5def..b25428533141 100644 --- a/trunk/arch/x86/kernel/pci-dma.c +++ b/trunk/arch/x86/kernel/pci-dma.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -13,7 +12,7 @@ static int forbid_dac __read_mostly; -struct dma_map_ops *dma_ops; +struct dma_mapping_ops *dma_ops; EXPORT_SYMBOL(dma_ops); static int iommu_sac_force __read_mostly; @@ -45,9 +44,6 @@ struct device x86_dma_fallback_dev = { }; EXPORT_SYMBOL(x86_dma_fallback_dev); -/* Number of entries preallocated for DMA-API debugging */ -#define PREALLOC_DMA_DEBUG_ENTRIES 32768 - int dma_set_mask(struct device *dev, u64 mask) { if (!dev->dma_mask || !dma_supported(dev, mask)) @@ -228,7 +224,7 @@ early_param("iommu", iommu_setup); int dma_supported(struct device *dev, u64 mask) { - struct dma_map_ops *ops = get_dma_ops(dev); + struct dma_mapping_ops *ops = get_dma_ops(dev); #ifdef CONFIG_PCI if (mask > 0xffffffff && forbid_dac > 0) { @@ -269,12 +265,6 @@ EXPORT_SYMBOL(dma_supported); static int __init pci_iommu_init(void) { - dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); - -#ifdef CONFIG_PCI - dma_debug_add_bus(&pci_bus_type); -#endif - calgary_iommu_init(); intel_iommu_init(); @@ -300,7 +290,8 @@ fs_initcall(pci_iommu_init); static __devinit void via_no_dac(struct pci_dev *dev) { if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { - dev_info(&dev->dev, "disabling DAC on VIA PCI bridge\n"); + printk(KERN_INFO + "PCI: VIA PCI bridge detected. Disabling DAC.\n"); forbid_dac = 1; } } diff --git a/trunk/arch/x86/kernel/pci-gart_64.c b/trunk/arch/x86/kernel/pci-gart_64.c index b284b58c035c..d5768b1af080 100644 --- a/trunk/arch/x86/kernel/pci-gart_64.c +++ b/trunk/arch/x86/kernel/pci-gart_64.c @@ -255,13 +255,10 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, } /* Map a single area into the IOMMU */ -static dma_addr_t gart_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) +static dma_addr_t +gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir) { unsigned long bus; - phys_addr_t paddr = page_to_phys(page) + offset; if (!dev) dev = &x86_dma_fallback_dev; @@ -278,9 +275,8 @@ static dma_addr_t gart_map_page(struct device *dev, struct page *page, /* * Free a DMA mapping. */ -static void gart_unmap_page(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction dir, - struct dma_attrs *attrs) +static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, + size_t size, int direction) { unsigned long iommu_page; int npages; @@ -302,8 +298,8 @@ static void gart_unmap_page(struct device *dev, dma_addr_t dma_addr, /* * Wrapper for pci_unmap_single working with scatterlists. */ -static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, - enum dma_data_direction dir, struct dma_attrs *attrs) +static void +gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) { struct scatterlist *s; int i; @@ -311,7 +307,7 @@ static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, for_each_sg(sg, s, nents, i) { if (!s->dma_length || !s->length) break; - gart_unmap_page(dev, s->dma_address, s->dma_length, dir, NULL); + gart_unmap_single(dev, s->dma_address, s->dma_length, dir); } } @@ -333,7 +329,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, addr = dma_map_area(dev, addr, s->length, dir, 0); if (addr == bad_dma_address) { if (i > 0) - gart_unmap_sg(dev, sg, i, dir, NULL); + gart_unmap_sg(dev, sg, i, dir); nents = 0; sg[0].dma_length = 0; break; @@ -404,8 +400,8 @@ dma_map_cont(struct device *dev, struct scatterlist *start, int nelems, * DMA map all entries in a scatterlist. * Merge chunks that have page aligned sizes into a continuous mapping. */ -static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, - enum dma_data_direction dir, struct dma_attrs *attrs) +static int +gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) { struct scatterlist *s, *ps, *start_sg, *sgmap; int need = 0, nextneed, i, out, start; @@ -472,7 +468,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, error: flush_gart(); - gart_unmap_sg(dev, sg, out, dir, NULL); + gart_unmap_sg(dev, sg, out, dir); /* When it was forced or merged try again in a dumb way */ if (force_iommu || iommu_merge) { @@ -525,7 +521,7 @@ static void gart_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_addr) { - gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL); + gart_unmap_single(dev, dma_addr, size, DMA_BIDIRECTIONAL); free_pages((unsigned long)vaddr, get_order(size)); } @@ -711,11 +707,11 @@ static __init int init_k8_gatt(struct agp_kern_info *info) return -1; } -static struct dma_map_ops gart_dma_ops = { +static struct dma_mapping_ops gart_dma_ops = { + .map_single = gart_map_single, + .unmap_single = gart_unmap_single, .map_sg = gart_map_sg, .unmap_sg = gart_unmap_sg, - .map_page = gart_map_page, - .unmap_page = gart_unmap_page, .alloc_coherent = gart_alloc_coherent, .free_coherent = gart_free_coherent, }; diff --git a/trunk/arch/x86/kernel/pci-nommu.c b/trunk/arch/x86/kernel/pci-nommu.c index c6d703b39326..c70ab5a5d4c8 100644 --- a/trunk/arch/x86/kernel/pci-nommu.c +++ b/trunk/arch/x86/kernel/pci-nommu.c @@ -1,14 +1,14 @@ /* Fallback functions when the main IOMMU code is not compiled in. This code is roughly equivalent to i386. */ -#include -#include -#include +#include #include #include -#include +#include +#include +#include -#include #include +#include #include static int @@ -25,19 +25,19 @@ check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) return 1; } -static dma_addr_t nommu_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) +static dma_addr_t +nommu_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, + int direction) { - dma_addr_t bus = page_to_phys(page) + offset; + dma_addr_t bus = paddr; WARN_ON(size == 0); - if (!check_addr("map_single", dev, bus, size)) - return bad_dma_address; + if (!check_addr("map_single", hwdev, bus, size)) + return bad_dma_address; flush_write_buffers(); return bus; } + /* Map a set of buffers described by scatterlist in streaming * mode for DMA. This is the scatter-gather version of the * above pci_map_single interface. Here the scatter gather list @@ -54,8 +54,7 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page, * the same here. */ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, enum dma_data_direction dir, - struct dma_attrs *attrs) + int nents, int direction) { struct scatterlist *s; int i; @@ -79,12 +78,12 @@ static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr, free_pages((unsigned long)vaddr, get_order(size)); } -struct dma_map_ops nommu_dma_ops = { - .alloc_coherent = dma_generic_alloc_coherent, - .free_coherent = nommu_free_coherent, - .map_sg = nommu_map_sg, - .map_page = nommu_map_page, - .is_phys = 1, +struct dma_mapping_ops nommu_dma_ops = { + .alloc_coherent = dma_generic_alloc_coherent, + .free_coherent = nommu_free_coherent, + .map_single = nommu_map_single, + .map_sg = nommu_map_sg, + .is_phys = 1, }; void __init no_iommu_init(void) diff --git a/trunk/arch/x86/kernel/pci-swiotlb.c b/trunk/arch/x86/kernel/pci-swiotlb_64.c similarity index 81% rename from trunk/arch/x86/kernel/pci-swiotlb.c rename to trunk/arch/x86/kernel/pci-swiotlb_64.c index 34f12e9996ed..d59c91747665 100644 --- a/trunk/arch/x86/kernel/pci-swiotlb.c +++ b/trunk/arch/x86/kernel/pci-swiotlb_64.c @@ -33,11 +33,18 @@ phys_addr_t swiotlb_bus_to_phys(dma_addr_t baddr) return baddr; } -int __weak swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size) +int __weak swiotlb_arch_range_needs_mapping(void *ptr, size_t size) { return 0; } +static dma_addr_t +swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size, + int direction) +{ + return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction); +} + static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t flags) { @@ -50,20 +57,20 @@ static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags); } -struct dma_map_ops swiotlb_dma_ops = { +struct dma_mapping_ops swiotlb_dma_ops = { .mapping_error = swiotlb_dma_mapping_error, .alloc_coherent = x86_swiotlb_alloc_coherent, .free_coherent = swiotlb_free_coherent, + .map_single = swiotlb_map_single_phys, + .unmap_single = swiotlb_unmap_single, .sync_single_for_cpu = swiotlb_sync_single_for_cpu, .sync_single_for_device = swiotlb_sync_single_for_device, .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu, .sync_single_range_for_device = swiotlb_sync_single_range_for_device, .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, .sync_sg_for_device = swiotlb_sync_sg_for_device, - .map_sg = swiotlb_map_sg_attrs, - .unmap_sg = swiotlb_unmap_sg_attrs, - .map_page = swiotlb_map_page, - .unmap_page = swiotlb_unmap_page, + .map_sg = swiotlb_map_sg, + .unmap_sg = swiotlb_unmap_sg, .dma_supported = NULL, }; diff --git a/trunk/arch/x86/kernel/process.c b/trunk/arch/x86/kernel/process.c index 156f87582c6c..6afa5232dbb7 100644 --- a/trunk/arch/x86/kernel/process.c +++ b/trunk/arch/x86/kernel/process.c @@ -65,11 +65,11 @@ void exit_thread(void) { struct task_struct *me = current; struct thread_struct *t = &me->thread; - unsigned long *bp = t->io_bitmap_ptr; - if (bp) { + if (me->thread.io_bitmap_ptr) { struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); + kfree(t->io_bitmap_ptr); t->io_bitmap_ptr = NULL; clear_thread_flag(TIF_IO_BITMAP); /* @@ -78,7 +78,6 @@ void exit_thread(void) memset(tss->io_bitmap, 0xff, t->io_bitmap_max); t->io_bitmap_max = 0; put_cpu(); - kfree(bp); } ds_exit_thread(current); diff --git a/trunk/arch/x86/kernel/process_32.c b/trunk/arch/x86/kernel/process_32.c index 76f8f84043a2..14014d766cad 100644 --- a/trunk/arch/x86/kernel/process_32.c +++ b/trunk/arch/x86/kernel/process_32.c @@ -245,7 +245,7 @@ void prepare_to_copy(struct task_struct *tsk) unlazy_fpu(tsk); } -int copy_thread(unsigned long clone_flags, unsigned long sp, +int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { diff --git a/trunk/arch/x86/kernel/process_64.c b/trunk/arch/x86/kernel/process_64.c index b751a41392b1..abb7e6a7f0c6 100644 --- a/trunk/arch/x86/kernel/process_64.c +++ b/trunk/arch/x86/kernel/process_64.c @@ -278,7 +278,7 @@ void prepare_to_copy(struct task_struct *tsk) unlazy_fpu(tsk); } -int copy_thread(unsigned long clone_flags, unsigned long sp, +int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { diff --git a/trunk/arch/x86/kernel/ptrace.c b/trunk/arch/x86/kernel/ptrace.c index b7cc21bc6ae0..3d9672e59c16 100644 --- a/trunk/arch/x86/kernel/ptrace.c +++ b/trunk/arch/x86/kernel/ptrace.c @@ -685,8 +685,9 @@ static int ptrace_bts_config(struct task_struct *child, if (!cfg.signal) return -EINVAL; - child->thread.bts_ovfl_signal = cfg.signal; return -EOPNOTSUPP; + + child->thread.bts_ovfl_signal = cfg.signal; } if ((cfg.flags & PTRACE_BTS_O_ALLOC) && @@ -1455,6 +1456,6 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs) * system call instruction. */ if (test_thread_flag(TIF_SINGLESTEP) && - tracehook_consider_fatal_signal(current, SIGTRAP)) + tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL)) send_sigtrap(current, regs, 0, TRAP_BRKPT); } diff --git a/trunk/arch/x86/kernel/quirks.c b/trunk/arch/x86/kernel/quirks.c index e95022e4f5d5..697d1b78cfbf 100644 --- a/trunk/arch/x86/kernel/quirks.c +++ b/trunk/arch/x86/kernel/quirks.c @@ -74,7 +74,8 @@ static void ich_force_hpet_resume(void) if (!force_hpet_address) return; - BUG_ON(rcba_base == NULL); + if (rcba_base == NULL) + BUG(); /* read the Function Disable register, dword mode only */ val = readl(rcba_base + 0x3404); diff --git a/trunk/arch/x86/kernel/relocate_kernel_32.S b/trunk/arch/x86/kernel/relocate_kernel_32.S index 41235531b11c..2064d0aa8d28 100644 --- a/trunk/arch/x86/kernel/relocate_kernel_32.S +++ b/trunk/arch/x86/kernel/relocate_kernel_32.S @@ -17,8 +17,7 @@ #define PTR(x) (x << 2) -/* - * control_page + KEXEC_CONTROL_CODE_MAX_SIZE +/* control_page + KEXEC_CONTROL_CODE_MAX_SIZE * ~ control_page + PAGE_SIZE are used as data storage and stack for * jumping back */ @@ -77,10 +76,8 @@ relocate_kernel: movl %eax, CP_PA_SWAP_PAGE(%edi) movl %ebx, CP_PA_BACKUP_PAGES_MAP(%edi) - /* - * get physical address of control page now - * this is impossible after page table switch - */ + /* get physical address of control page now */ + /* this is impossible after page table switch */ movl PTR(PA_CONTROL_PAGE)(%ebp), %edi /* switch to new set of page tables */ @@ -100,8 +97,7 @@ identity_mapped: /* store the start address on the stack */ pushl %edx - /* - * Set cr0 to a known state: + /* Set cr0 to a known state: * - Paging disabled * - Alignment check disabled * - Write protect disabled @@ -117,8 +113,7 @@ identity_mapped: /* clear cr4 if applicable */ testl %ecx, %ecx jz 1f - /* - * Set cr4 to a known state: + /* Set cr4 to a known state: * Setting everything to zero seems safe. */ xorl %eax, %eax @@ -137,18 +132,15 @@ identity_mapped: call swap_pages addl $8, %esp - /* - * To be certain of avoiding problems with self-modifying code + /* To be certain of avoiding problems with self-modifying code * I need to execute a serializing instruction here. * So I flush the TLB, it's handy, and not processor dependent. */ xorl %eax, %eax movl %eax, %cr3 - /* - * set all of the registers to known values - * leave %esp alone - */ + /* set all of the registers to known values */ + /* leave %esp alone */ testl %esi, %esi jnz 1f diff --git a/trunk/arch/x86/kernel/relocate_kernel_64.S b/trunk/arch/x86/kernel/relocate_kernel_64.S index 4de8f5b3d476..d32cfb27a479 100644 --- a/trunk/arch/x86/kernel/relocate_kernel_64.S +++ b/trunk/arch/x86/kernel/relocate_kernel_64.S @@ -19,77 +19,29 @@ #define PTR(x) (x << 3) #define PAGE_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) -/* - * control_page + KEXEC_CONTROL_CODE_MAX_SIZE - * ~ control_page + PAGE_SIZE are used as data storage and stack for - * jumping back - */ -#define DATA(offset) (KEXEC_CONTROL_CODE_MAX_SIZE+(offset)) - -/* Minimal CPU state */ -#define RSP DATA(0x0) -#define CR0 DATA(0x8) -#define CR3 DATA(0x10) -#define CR4 DATA(0x18) - -/* other data */ -#define CP_PA_TABLE_PAGE DATA(0x20) -#define CP_PA_SWAP_PAGE DATA(0x28) -#define CP_PA_BACKUP_PAGES_MAP DATA(0x30) - .text .align PAGE_SIZE .code64 .globl relocate_kernel relocate_kernel: - /* - * %rdi indirection_page + /* %rdi indirection_page * %rsi page_list * %rdx start address - * %rcx preserve_context */ - /* Save the CPU context, used for jumping back */ - pushq %rbx - pushq %rbp - pushq %r12 - pushq %r13 - pushq %r14 - pushq %r15 - pushf - - movq PTR(VA_CONTROL_PAGE)(%rsi), %r11 - movq %rsp, RSP(%r11) - movq %cr0, %rax - movq %rax, CR0(%r11) - movq %cr3, %rax - movq %rax, CR3(%r11) - movq %cr4, %rax - movq %rax, CR4(%r11) - /* zero out flags, and disable interrupts */ pushq $0 popfq - /* - * get physical address of control page now - * this is impossible after page table switch - */ + /* get physical address of control page now */ + /* this is impossible after page table switch */ movq PTR(PA_CONTROL_PAGE)(%rsi), %r8 /* get physical address of page table now too */ - movq PTR(PA_TABLE_PAGE)(%rsi), %r9 - - /* get physical address of swap page now */ - movq PTR(PA_SWAP_PAGE)(%rsi), %r10 - - /* save some information for jumping back */ - movq %r9, CP_PA_TABLE_PAGE(%r11) - movq %r10, CP_PA_SWAP_PAGE(%r11) - movq %rdi, CP_PA_BACKUP_PAGES_MAP(%r11) + movq PTR(PA_TABLE_PAGE)(%rsi), %rcx /* Switch to the identity mapped page tables */ - movq %r9, %cr3 + movq %rcx, %cr3 /* setup a new stack at the end of the physical control page */ lea PAGE_SIZE(%r8), %rsp @@ -103,8 +55,7 @@ identity_mapped: /* store the start address on the stack */ pushq %rdx - /* - * Set cr0 to a known state: + /* Set cr0 to a known state: * - Paging enabled * - Alignment check disabled * - Write protect disabled @@ -117,8 +68,7 @@ identity_mapped: orl $(X86_CR0_PG | X86_CR0_PE), %eax movq %rax, %cr0 - /* - * Set cr4 to a known state: + /* Set cr4 to a known state: * - physical address extension enabled */ movq $X86_CR4_PAE, %rax @@ -128,87 +78,9 @@ identity_mapped: 1: /* Flush the TLB (needed?) */ - movq %r9, %cr3 - - movq %rcx, %r11 - call swap_pages - - /* - * To be certain of avoiding problems with self-modifying code - * I need to execute a serializing instruction here. - * So I flush the TLB by reloading %cr3 here, it's handy, - * and not processor dependent. - */ - movq %cr3, %rax - movq %rax, %cr3 - - /* - * set all of the registers to known values - * leave %rsp alone - */ - - testq %r11, %r11 - jnz 1f - xorq %rax, %rax - xorq %rbx, %rbx - xorq %rcx, %rcx - xorq %rdx, %rdx - xorq %rsi, %rsi - xorq %rdi, %rdi - xorq %rbp, %rbp - xorq %r8, %r8 - xorq %r9, %r9 - xorq %r10, %r9 - xorq %r11, %r11 - xorq %r12, %r12 - xorq %r13, %r13 - xorq %r14, %r14 - xorq %r15, %r15 - - ret - -1: - popq %rdx - leaq PAGE_SIZE(%r10), %rsp - call *%rdx - - /* get the re-entry point of the peer system */ - movq 0(%rsp), %rbp - call 1f -1: - popq %r8 - subq $(1b - relocate_kernel), %r8 - movq CP_PA_SWAP_PAGE(%r8), %r10 - movq CP_PA_BACKUP_PAGES_MAP(%r8), %rdi - movq CP_PA_TABLE_PAGE(%r8), %rax - movq %rax, %cr3 - lea PAGE_SIZE(%r8), %rsp - call swap_pages - movq $virtual_mapped, %rax - pushq %rax - ret - -virtual_mapped: - movq RSP(%r8), %rsp - movq CR4(%r8), %rax - movq %rax, %cr4 - movq CR3(%r8), %rax - movq CR0(%r8), %r8 - movq %rax, %cr3 - movq %r8, %cr0 - movq %rbp, %rax - - popf - popq %r15 - popq %r14 - popq %r13 - popq %r12 - popq %rbp - popq %rbx - ret + movq %rcx, %cr3 /* Do the copies */ -swap_pages: movq %rdi, %rcx /* Put the page_list in %rcx */ xorq %rdi, %rdi xorq %rsi, %rsi @@ -240,27 +112,36 @@ swap_pages: movq %rcx, %rsi /* For ever source page do a copy */ andq $0xfffffffffffff000, %rsi - movq %rdi, %rdx - movq %rsi, %rax - - movq %r10, %rdi movq $512, %rcx rep ; movsq + jmp 0b +3: - movq %rax, %rdi - movq %rdx, %rsi - movq $512, %rcx - rep ; movsq + /* To be certain of avoiding problems with self-modifying code + * I need to execute a serializing instruction here. + * So I flush the TLB by reloading %cr3 here, it's handy, + * and not processor dependent. + */ + movq %cr3, %rax + movq %rax, %cr3 - movq %rdx, %rdi - movq %r10, %rsi - movq $512, %rcx - rep ; movsq + /* set all of the registers to known values */ + /* leave %rsp alone */ - lea PAGE_SIZE(%rax), %rsi - jmp 0b -3: - ret + xorq %rax, %rax + xorq %rbx, %rbx + xorq %rcx, %rcx + xorq %rdx, %rdx + xorq %rsi, %rsi + xorq %rdi, %rdi + xorq %rbp, %rbp + xorq %r8, %r8 + xorq %r9, %r9 + xorq %r10, %r9 + xorq %r11, %r11 + xorq %r12, %r12 + xorq %r13, %r13 + xorq %r14, %r14 + xorq %r15, %r15 - .globl kexec_control_code_size -.set kexec_control_code_size, . - relocate_kernel + ret diff --git a/trunk/arch/x86/kernel/rtc.c b/trunk/arch/x86/kernel/rtc.c index 5d465b207e72..dd6f2b71561b 100644 --- a/trunk/arch/x86/kernel/rtc.c +++ b/trunk/arch/x86/kernel/rtc.c @@ -1,14 +1,14 @@ /* * RTC related functions */ -#include -#include #include #include +#include +#include #include -#include #include +#include #ifdef CONFIG_X86_32 /* @@ -16,9 +16,9 @@ * register we are working with. It is required for NMI access to the * CMOS/RTC registers. See include/asm-i386/mc146818rtc.h for details. */ -volatile unsigned long cmos_lock; +volatile unsigned long cmos_lock = 0; EXPORT_SYMBOL(cmos_lock); -#endif /* CONFIG_X86_32 */ +#endif /* For two digit years assume time is always after that */ #define CMOS_YEARS_OFFS 2000 @@ -38,9 +38,9 @@ EXPORT_SYMBOL(rtc_lock); */ int mach_set_rtc_mmss(unsigned long nowtime) { + int retval = 0; int real_seconds, real_minutes, cmos_minutes; unsigned char save_control, save_freq_select; - int retval = 0; /* tell the clock it's being set */ save_control = CMOS_READ(RTC_CONTROL); @@ -72,8 +72,8 @@ int mach_set_rtc_mmss(unsigned long nowtime) real_seconds = bin2bcd(real_seconds); real_minutes = bin2bcd(real_minutes); } - CMOS_WRITE(real_seconds, RTC_SECONDS); - CMOS_WRITE(real_minutes, RTC_MINUTES); + CMOS_WRITE(real_seconds,RTC_SECONDS); + CMOS_WRITE(real_minutes,RTC_MINUTES); } else { printk(KERN_WARNING "set_rtc_mmss: can't update from %d to %d\n", @@ -151,7 +151,6 @@ unsigned char rtc_cmos_read(unsigned char addr) outb(addr, RTC_PORT(0)); val = inb(RTC_PORT(1)); lock_cmos_suffix(addr); - return val; } EXPORT_SYMBOL(rtc_cmos_read); @@ -167,8 +166,8 @@ EXPORT_SYMBOL(rtc_cmos_write); static int set_rtc_mmss(unsigned long nowtime) { - unsigned long flags; int retval; + unsigned long flags; spin_lock_irqsave(&rtc_lock, flags); retval = set_wallclock(nowtime); @@ -243,7 +242,6 @@ static __init int add_rtc_cmos(void) platform_device_register(&rtc_device); dev_info(&rtc_device.dev, "registered platform RTC device (no PNP device found)\n"); - return 0; } device_initcall(add_rtc_cmos); diff --git a/trunk/arch/x86/kernel/setup.c b/trunk/arch/x86/kernel/setup.c index b4158439bf63..b746deb9ebc6 100644 --- a/trunk/arch/x86/kernel/setup.c +++ b/trunk/arch/x86/kernel/setup.c @@ -112,13 +112,8 @@ #define ARCH_SETUP #endif -RESERVE_BRK(dmi_alloc, 65536); - unsigned int boot_cpu_id __read_mostly; -static __initdata unsigned long _brk_start = (unsigned long)__brk_base; -unsigned long _brk_end = (unsigned long)__brk_base; - #ifdef CONFIG_X86_64 int default_cpu_present_to_apicid(int mps_cpu) { @@ -163,6 +158,12 @@ static struct resource bss_resource = { #ifdef CONFIG_X86_32 +/* This value is set up by the early boot code to point to the value + immediately after the boot time page tables. It contains a *physical* + address, and must not be in the .bss segment! */ +unsigned long init_pg_tables_start __initdata = ~0UL; +unsigned long init_pg_tables_end __initdata = ~0UL; + static struct resource video_ram_resource = { .name = "Video RAM area", .start = 0xa0000, @@ -201,9 +202,7 @@ struct ist_info ist_info; #endif #else -struct cpuinfo_x86 boot_cpu_data __read_mostly = { - .x86_phys_bits = MAX_PHYSMEM_BITS, -}; +struct cpuinfo_x86 boot_cpu_data __read_mostly; EXPORT_SYMBOL(boot_cpu_data); #endif @@ -217,6 +216,12 @@ unsigned long mmu_cr4_features = X86_CR4_PAE; /* Boot loader ID as an integer, for the benefit of proc_dointvec */ int bootloader_type; +/* + * Early DMI memory + */ +int dmi_alloc_index; +char dmi_alloc_data[DMI_MAX_DATA]; + /* * Setup options */ @@ -262,35 +267,6 @@ static inline void copy_edd(void) } #endif -void * __init extend_brk(size_t size, size_t align) -{ - size_t mask = align - 1; - void *ret; - - BUG_ON(_brk_start == 0); - BUG_ON(align & mask); - - _brk_end = (_brk_end + mask) & ~mask; - BUG_ON((char *)(_brk_end + size) > __brk_limit); - - ret = (void *)_brk_end; - _brk_end += size; - - memset(ret, 0, size); - - return ret; -} - -static void __init reserve_brk(void) -{ - if (_brk_end > _brk_start) - reserve_early(__pa(_brk_start), __pa(_brk_end), "BRK"); - - /* Mark brk area as locked down and no longer taking any - new allocations */ - _brk_start = 0; -} - #ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_X86_32 @@ -739,7 +715,11 @@ void __init setup_arch(char **cmdline_p) init_mm.start_code = (unsigned long) _text; init_mm.end_code = (unsigned long) _etext; init_mm.end_data = (unsigned long) _edata; - init_mm.brk = _brk_end; +#ifdef CONFIG_X86_32 + init_mm.brk = init_pg_tables_end + PAGE_OFFSET; +#else + init_mm.brk = (unsigned long) &_end; +#endif code_resource.start = virt_to_phys(_text); code_resource.end = virt_to_phys(_etext)-1; @@ -860,8 +840,6 @@ void __init setup_arch(char **cmdline_p) setup_bios_corruption_check(); #endif - reserve_brk(); - /* max_pfn_mapped is updated here */ max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<sp; - int onsigstack = on_sig_stack(sp); #ifdef CONFIG_X86_64 /* redzone */ sp -= 128; #endif /* CONFIG_X86_64 */ - if (!onsigstack) { - /* This is the X/Open sanctioned signal stack switching. */ - if (ka->sa.sa_flags & SA_ONSTACK) { - if (sas_ss_flags(sp) == 0) - sp = current->sas_ss_sp + current->sas_ss_size; - } else { + /* + * If we are on the alternate signal stack and would overflow it, don't. + * Return an always-bogus address instead so we will die with SIGSEGV. + */ + if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) + return (void __user *) -1L; + + /* This is the X/Open sanctioned signal stack switching. */ + if (ka->sa.sa_flags & SA_ONSTACK) { + if (sas_ss_flags(sp) == 0) + sp = current->sas_ss_sp + current->sas_ss_size; + } else { #ifdef CONFIG_X86_32 - /* This is the legacy signal stack switching. */ - if ((regs->ss & 0xffff) != __USER_DS && - !(ka->sa.sa_flags & SA_RESTORER) && - ka->sa.sa_restorer) - sp = (unsigned long) ka->sa.sa_restorer; + /* This is the legacy signal stack switching. */ + if ((regs->ss & 0xffff) != __USER_DS && + !(ka->sa.sa_flags & SA_RESTORER) && + ka->sa.sa_restorer) + sp = (unsigned long) ka->sa.sa_restorer; #endif /* CONFIG_X86_32 */ - } } if (used_math()) { @@ -240,22 +244,12 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, sp = round_down(sp, 64); #endif /* CONFIG_X86_64 */ *fpstate = (void __user *)sp; - } - sp = align_sigframe(sp - frame_size); - - /* - * If we are on the alternate signal stack and would overflow it, don't. - * Return an always-bogus address instead so we will die with SIGSEGV. - */ - if (onsigstack && !likely(on_sig_stack(sp))) - return (void __user *)-1L; - - /* save i387 state */ - if (used_math() && save_i387_xstate(*fpstate) < 0) - return (void __user *)-1L; + if (save_i387_xstate(*fpstate) < 0) + return (void __user *)-1L; + } - return (void __user *)sp; + return (void __user *)align_sigframe(sp - frame_size); } #ifdef CONFIG_X86_32 diff --git a/trunk/arch/x86/kernel/smpboot.c b/trunk/arch/x86/kernel/smpboot.c index ef7d10170c30..249334f5080a 100644 --- a/trunk/arch/x86/kernel/smpboot.c +++ b/trunk/arch/x86/kernel/smpboot.c @@ -114,6 +114,10 @@ EXPORT_PER_CPU_SYMBOL(cpu_info); atomic_t init_deasserted; + +/* Set if we find a B stepping CPU */ +static int __cpuinitdata smp_b_stepping; + #if defined(CONFIG_NUMA) && defined(CONFIG_X86_32) /* which logical CPUs are on which nodes */ @@ -267,6 +271,8 @@ static void __cpuinit smp_callin(void) cpumask_set_cpu(cpuid, cpu_callin_mask); } +static int __cpuinitdata unsafe_smp; + /* * Activate a secondary processor. */ @@ -334,6 +340,76 @@ notrace static void __cpuinit start_secondary(void *unused) cpu_idle(); } +static void __cpuinit smp_apply_quirks(struct cpuinfo_x86 *c) +{ + /* + * Mask B, Pentium, but not Pentium MMX + */ + if (c->x86_vendor == X86_VENDOR_INTEL && + c->x86 == 5 && + c->x86_mask >= 1 && c->x86_mask <= 4 && + c->x86_model <= 3) + /* + * Remember we have B step Pentia with bugs + */ + smp_b_stepping = 1; + + /* + * Certain Athlons might work (for various values of 'work') in SMP + * but they are not certified as MP capable. + */ + if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) { + + if (num_possible_cpus() == 1) + goto valid_k7; + + /* Athlon 660/661 is valid. */ + if ((c->x86_model == 6) && ((c->x86_mask == 0) || + (c->x86_mask == 1))) + goto valid_k7; + + /* Duron 670 is valid */ + if ((c->x86_model == 7) && (c->x86_mask == 0)) + goto valid_k7; + + /* + * Athlon 662, Duron 671, and Athlon >model 7 have capability + * bit. It's worth noting that the A5 stepping (662) of some + * Athlon XP's have the MP bit set. + * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for + * more. + */ + if (((c->x86_model == 6) && (c->x86_mask >= 2)) || + ((c->x86_model == 7) && (c->x86_mask >= 1)) || + (c->x86_model > 7)) + if (cpu_has_mp) + goto valid_k7; + + /* If we get here, not a certified SMP capable AMD system. */ + unsafe_smp = 1; + } + +valid_k7: + ; +} + +static void __cpuinit smp_checks(void) +{ + if (smp_b_stepping) + printk(KERN_WARNING "WARNING: SMP operation may be unreliable" + "with B stepping processors.\n"); + + /* + * Don't taint if we are running SMP kernel on a single non-MP + * approved Athlon + */ + if (unsafe_smp && num_online_cpus() > 1) { + printk(KERN_INFO "WARNING: This combination of AMD" + "processors is not suitable for SMP.\n"); + add_taint(TAINT_UNSAFE_SMP); + } +} + /* * The bootstrap kernel entry code has set these up. Save them for * a given CPU @@ -347,6 +423,7 @@ void __cpuinit smp_store_cpu_info(int id) c->cpu_index = id; if (id != 0) identify_secondary_cpu(c); + smp_apply_quirks(c); } @@ -1116,6 +1193,7 @@ void __init native_smp_cpus_done(unsigned int max_cpus) pr_debug("Boot done.\n"); impress_friends(); + smp_checks(); #ifdef CONFIG_X86_IO_APIC setup_ioapic_dest(); #endif diff --git a/trunk/arch/x86/kernel/syscall_table_32.S b/trunk/arch/x86/kernel/syscall_table_32.S index ff5c8736b491..3bdb64829b82 100644 --- a/trunk/arch/x86/kernel/syscall_table_32.S +++ b/trunk/arch/x86/kernel/syscall_table_32.S @@ -332,5 +332,3 @@ ENTRY(sys_call_table) .long sys_dup3 /* 330 */ .long sys_pipe2 .long sys_inotify_init1 - .long sys_preadv - .long sys_pwritev diff --git a/trunk/arch/x86/kernel/time_64.c b/trunk/arch/x86/kernel/time_64.c index 5ba343e61844..241ec3923f61 100644 --- a/trunk/arch/x86/kernel/time_64.c +++ b/trunk/arch/x86/kernel/time_64.c @@ -116,6 +116,7 @@ unsigned long __init calibrate_cpu(void) static struct irqaction irq0 = { .handler = timer_interrupt, .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | IRQF_TIMER, + .mask = CPU_MASK_NONE, .name = "timer" }; @@ -124,6 +125,7 @@ void __init hpet_time_init(void) if (!hpet_enable()) setup_pit_timer(); + irq0.mask = cpumask_of_cpu(0); setup_irq(0, &irq0); } diff --git a/trunk/arch/x86/kernel/tlb_uv.c b/trunk/arch/x86/kernel/tlb_uv.c index 79c073247284..d038b9c45cf8 100644 --- a/trunk/arch/x86/kernel/tlb_uv.c +++ b/trunk/arch/x86/kernel/tlb_uv.c @@ -750,7 +750,7 @@ static int __init uv_bau_init(void) int node; int nblades; int last_blade; - int cur_cpu; + int cur_cpu = 0; if (!is_uv_system()) return 0; @@ -760,7 +760,6 @@ static int __init uv_bau_init(void) uv_mmask = (1UL << uv_hub_info->n_val) - 1; nblades = 0; last_blade = -1; - cur_cpu = 0; for_each_online_node(node) { blade = uv_node_to_blade_id(node); if (blade == last_blade) diff --git a/trunk/arch/x86/kernel/topology.c b/trunk/arch/x86/kernel/topology.c index 7e4515957a1c..0fcc95a354f7 100644 --- a/trunk/arch/x86/kernel/topology.c +++ b/trunk/arch/x86/kernel/topology.c @@ -25,10 +25,10 @@ * * Send feedback to */ -#include -#include #include #include +#include +#include #include static DEFINE_PER_CPU(struct x86_cpu, cpu_devices); @@ -47,7 +47,6 @@ int __ref arch_register_cpu(int num) */ if (num) per_cpu(cpu_devices, num).cpu.hotpluggable = 1; - return register_cpu(&per_cpu(cpu_devices, num).cpu, num); } EXPORT_SYMBOL(arch_register_cpu); @@ -57,13 +56,12 @@ void arch_unregister_cpu(int num) unregister_cpu(&per_cpu(cpu_devices, num).cpu); } EXPORT_SYMBOL(arch_unregister_cpu); -#else /* CONFIG_HOTPLUG_CPU */ - +#else static int __init arch_register_cpu(int num) { return register_cpu(&per_cpu(cpu_devices, num).cpu, num); } -#endif /* CONFIG_HOTPLUG_CPU */ +#endif /*CONFIG_HOTPLUG_CPU*/ static int __init topology_init(void) { @@ -72,11 +70,11 @@ static int __init topology_init(void) #ifdef CONFIG_NUMA for_each_online_node(i) register_one_node(i); -#endif +#endif /* CONFIG_NUMA */ for_each_present_cpu(i) arch_register_cpu(i); - return 0; } + subsys_initcall(topology_init); diff --git a/trunk/arch/x86/kernel/uv_time.c b/trunk/arch/x86/kernel/uv_time.c deleted file mode 100644 index 2ffb6c53326e..000000000000 --- a/trunk/arch/x86/kernel/uv_time.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * SGI RTC clock/timer routines. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Copyright (c) 2009 Silicon Graphics, Inc. All Rights Reserved. - * Copyright (c) Dimitri Sivanich - */ -#include - -#include -#include -#include -#include -#include -#include - -#define RTC_NAME "sgi_rtc" - -static cycle_t uv_read_rtc(void); -static int uv_rtc_next_event(unsigned long, struct clock_event_device *); -static void uv_rtc_timer_setup(enum clock_event_mode, - struct clock_event_device *); - -static struct clocksource clocksource_uv = { - .name = RTC_NAME, - .rating = 400, - .read = uv_read_rtc, - .mask = (cycle_t)UVH_RTC_REAL_TIME_CLOCK_MASK, - .shift = 10, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static struct clock_event_device clock_event_device_uv = { - .name = RTC_NAME, - .features = CLOCK_EVT_FEAT_ONESHOT, - .shift = 20, - .rating = 400, - .irq = -1, - .set_next_event = uv_rtc_next_event, - .set_mode = uv_rtc_timer_setup, - .event_handler = NULL, -}; - -static DEFINE_PER_CPU(struct clock_event_device, cpu_ced); - -/* There is one of these allocated per node */ -struct uv_rtc_timer_head { - spinlock_t lock; - /* next cpu waiting for timer, local node relative: */ - int next_cpu; - /* number of cpus on this node: */ - int ncpus; - struct { - int lcpu; /* systemwide logical cpu number */ - u64 expires; /* next timer expiration for this cpu */ - } cpu[1]; -}; - -/* - * Access to uv_rtc_timer_head via blade id. - */ -static struct uv_rtc_timer_head **blade_info __read_mostly; - -static int uv_rtc_enable; - -/* - * Hardware interface routines - */ - -/* Send IPIs to another node */ -static void uv_rtc_send_IPI(int cpu) -{ - unsigned long apicid, val; - int pnode; - - apicid = cpu_physical_id(cpu); - pnode = uv_apicid_to_pnode(apicid); - val = (1UL << UVH_IPI_INT_SEND_SHFT) | - (apicid << UVH_IPI_INT_APIC_ID_SHFT) | - (GENERIC_INTERRUPT_VECTOR << UVH_IPI_INT_VECTOR_SHFT); - - uv_write_global_mmr64(pnode, UVH_IPI_INT, val); -} - -/* Check for an RTC interrupt pending */ -static int uv_intr_pending(int pnode) -{ - return uv_read_global_mmr64(pnode, UVH_EVENT_OCCURRED0) & - UVH_EVENT_OCCURRED0_RTC1_MASK; -} - -/* Setup interrupt and return non-zero if early expiration occurred. */ -static int uv_setup_intr(int cpu, u64 expires) -{ - u64 val; - int pnode = uv_cpu_to_pnode(cpu); - - uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG, - UVH_RTC1_INT_CONFIG_M_MASK); - uv_write_global_mmr64(pnode, UVH_INT_CMPB, -1L); - - uv_write_global_mmr64(pnode, UVH_EVENT_OCCURRED0_ALIAS, - UVH_EVENT_OCCURRED0_RTC1_MASK); - - val = (GENERIC_INTERRUPT_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) | - ((u64)cpu_physical_id(cpu) << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT); - - /* Set configuration */ - uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG, val); - /* Initialize comparator value */ - uv_write_global_mmr64(pnode, UVH_INT_CMPB, expires); - - return (expires < uv_read_rtc() && !uv_intr_pending(pnode)); -} - -/* - * Per-cpu timer tracking routines - */ - -static __init void uv_rtc_deallocate_timers(void) -{ - int bid; - - for_each_possible_blade(bid) { - kfree(blade_info[bid]); - } - kfree(blade_info); -} - -/* Allocate per-node list of cpu timer expiration times. */ -static __init int uv_rtc_allocate_timers(void) -{ - int cpu; - - blade_info = kmalloc(uv_possible_blades * sizeof(void *), GFP_KERNEL); - if (!blade_info) - return -ENOMEM; - memset(blade_info, 0, uv_possible_blades * sizeof(void *)); - - for_each_present_cpu(cpu) { - int nid = cpu_to_node(cpu); - int bid = uv_cpu_to_blade_id(cpu); - int bcpu = uv_cpu_hub_info(cpu)->blade_processor_id; - struct uv_rtc_timer_head *head = blade_info[bid]; - - if (!head) { - head = kmalloc_node(sizeof(struct uv_rtc_timer_head) + - (uv_blade_nr_possible_cpus(bid) * - 2 * sizeof(u64)), - GFP_KERNEL, nid); - if (!head) { - uv_rtc_deallocate_timers(); - return -ENOMEM; - } - spin_lock_init(&head->lock); - head->ncpus = uv_blade_nr_possible_cpus(bid); - head->next_cpu = -1; - blade_info[bid] = head; - } - - head->cpu[bcpu].lcpu = cpu; - head->cpu[bcpu].expires = ULLONG_MAX; - } - - return 0; -} - -/* Find and set the next expiring timer. */ -static void uv_rtc_find_next_timer(struct uv_rtc_timer_head *head, int pnode) -{ - u64 lowest = ULLONG_MAX; - int c, bcpu = -1; - - head->next_cpu = -1; - for (c = 0; c < head->ncpus; c++) { - u64 exp = head->cpu[c].expires; - if (exp < lowest) { - bcpu = c; - lowest = exp; - } - } - if (bcpu >= 0) { - head->next_cpu = bcpu; - c = head->cpu[bcpu].lcpu; - if (uv_setup_intr(c, lowest)) - /* If we didn't set it up in time, trigger */ - uv_rtc_send_IPI(c); - } else { - uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG, - UVH_RTC1_INT_CONFIG_M_MASK); - } -} - -/* - * Set expiration time for current cpu. - * - * Returns 1 if we missed the expiration time. - */ -static int uv_rtc_set_timer(int cpu, u64 expires) -{ - int pnode = uv_cpu_to_pnode(cpu); - int bid = uv_cpu_to_blade_id(cpu); - struct uv_rtc_timer_head *head = blade_info[bid]; - int bcpu = uv_cpu_hub_info(cpu)->blade_processor_id; - u64 *t = &head->cpu[bcpu].expires; - unsigned long flags; - int next_cpu; - - spin_lock_irqsave(&head->lock, flags); - - next_cpu = head->next_cpu; - *t = expires; - /* Will this one be next to go off? */ - if (next_cpu < 0 || bcpu == next_cpu || - expires < head->cpu[next_cpu].expires) { - head->next_cpu = bcpu; - if (uv_setup_intr(cpu, expires)) { - *t = ULLONG_MAX; - uv_rtc_find_next_timer(head, pnode); - spin_unlock_irqrestore(&head->lock, flags); - return 1; - } - } - - spin_unlock_irqrestore(&head->lock, flags); - return 0; -} - -/* - * Unset expiration time for current cpu. - * - * Returns 1 if this timer was pending. - */ -static int uv_rtc_unset_timer(int cpu) -{ - int pnode = uv_cpu_to_pnode(cpu); - int bid = uv_cpu_to_blade_id(cpu); - struct uv_rtc_timer_head *head = blade_info[bid]; - int bcpu = uv_cpu_hub_info(cpu)->blade_processor_id; - u64 *t = &head->cpu[bcpu].expires; - unsigned long flags; - int rc = 0; - - spin_lock_irqsave(&head->lock, flags); - - if (head->next_cpu == bcpu && uv_read_rtc() >= *t) - rc = 1; - - *t = ULLONG_MAX; - - /* Was the hardware setup for this timer? */ - if (head->next_cpu == bcpu) - uv_rtc_find_next_timer(head, pnode); - - spin_unlock_irqrestore(&head->lock, flags); - - return rc; -} - - -/* - * Kernel interface routines. - */ - -/* - * Read the RTC. - */ -static cycle_t uv_read_rtc(void) -{ - return (cycle_t)uv_read_local_mmr(UVH_RTC); -} - -/* - * Program the next event, relative to now - */ -static int uv_rtc_next_event(unsigned long delta, - struct clock_event_device *ced) -{ - int ced_cpu = cpumask_first(ced->cpumask); - - return uv_rtc_set_timer(ced_cpu, delta + uv_read_rtc()); -} - -/* - * Setup the RTC timer in oneshot mode - */ -static void uv_rtc_timer_setup(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - int ced_cpu = cpumask_first(evt->cpumask); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - case CLOCK_EVT_MODE_ONESHOT: - case CLOCK_EVT_MODE_RESUME: - /* Nothing to do here yet */ - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - uv_rtc_unset_timer(ced_cpu); - break; - } -} - -static void uv_rtc_interrupt(void) -{ - struct clock_event_device *ced = &__get_cpu_var(cpu_ced); - int cpu = smp_processor_id(); - - if (!ced || !ced->event_handler) - return; - - if (uv_rtc_unset_timer(cpu) != 1) - return; - - ced->event_handler(ced); -} - -static int __init uv_enable_rtc(char *str) -{ - uv_rtc_enable = 1; - - return 1; -} -__setup("uvrtc", uv_enable_rtc); - -static __init void uv_rtc_register_clockevents(struct work_struct *dummy) -{ - struct clock_event_device *ced = &__get_cpu_var(cpu_ced); - - *ced = clock_event_device_uv; - ced->cpumask = cpumask_of(smp_processor_id()); - clockevents_register_device(ced); -} - -static __init int uv_rtc_setup_clock(void) -{ - int rc; - - if (!uv_rtc_enable || !is_uv_system() || generic_interrupt_extension) - return -ENODEV; - - generic_interrupt_extension = uv_rtc_interrupt; - - clocksource_uv.mult = clocksource_hz2mult(sn_rtc_cycles_per_second, - clocksource_uv.shift); - - rc = clocksource_register(&clocksource_uv); - if (rc) { - generic_interrupt_extension = NULL; - return rc; - } - - /* Setup and register clockevents */ - rc = uv_rtc_allocate_timers(); - if (rc) { - clocksource_unregister(&clocksource_uv); - generic_interrupt_extension = NULL; - return rc; - } - - clock_event_device_uv.mult = div_sc(sn_rtc_cycles_per_second, - NSEC_PER_SEC, clock_event_device_uv.shift); - - clock_event_device_uv.min_delta_ns = NSEC_PER_SEC / - sn_rtc_cycles_per_second; - - clock_event_device_uv.max_delta_ns = clocksource_uv.mask * - (NSEC_PER_SEC / sn_rtc_cycles_per_second); - - rc = schedule_on_each_cpu(uv_rtc_register_clockevents); - if (rc) { - clocksource_unregister(&clocksource_uv); - generic_interrupt_extension = NULL; - uv_rtc_deallocate_timers(); - } - - return rc; -} -arch_initcall(uv_rtc_setup_clock); diff --git a/trunk/arch/x86/kernel/visws_quirks.c b/trunk/arch/x86/kernel/visws_quirks.c index 31ffc24eec4d..191a876e9e87 100644 --- a/trunk/arch/x86/kernel/visws_quirks.c +++ b/trunk/arch/x86/kernel/visws_quirks.c @@ -578,7 +578,7 @@ static struct irq_chip piix4_virtual_irq_type = { static irqreturn_t piix4_master_intr(int irq, void *dev_id) { int realirq; - struct irq_desc *desc; + irq_desc_t *desc; unsigned long flags; spin_lock_irqsave(&i8259A_lock, flags); diff --git a/trunk/arch/x86/kernel/vmi_32.c b/trunk/arch/x86/kernel/vmi_32.c index 95deb9f2211e..2cc4a90e2cb3 100644 --- a/trunk/arch/x86/kernel/vmi_32.c +++ b/trunk/arch/x86/kernel/vmi_32.c @@ -395,6 +395,11 @@ static void vmi_set_pte_atomic(pte_t *ptep, pte_t pteval) vmi_ops.update_pte(ptep, VMI_PAGE_PT); } +static void vmi_set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) +{ + vmi_ops.set_pte(pte, ptep, vmi_flags_addr_defer(mm, addr, VMI_PAGE_PT, 1)); +} + static void vmi_set_pud(pud_t *pudp, pud_t pudval) { /* Um, eww */ @@ -745,6 +750,7 @@ static inline int __init activate_vmi(void) pv_mmu_ops.set_pmd = vmi_set_pmd; #ifdef CONFIG_X86_PAE pv_mmu_ops.set_pte_atomic = vmi_set_pte_atomic; + pv_mmu_ops.set_pte_present = vmi_set_pte_present; pv_mmu_ops.set_pud = vmi_set_pud; pv_mmu_ops.pte_clear = vmi_pte_clear; pv_mmu_ops.pmd_clear = vmi_pmd_clear; diff --git a/trunk/arch/x86/kernel/vmiclock_32.c b/trunk/arch/x86/kernel/vmiclock_32.c index d303369a7bad..33a788d5879c 100644 --- a/trunk/arch/x86/kernel/vmiclock_32.c +++ b/trunk/arch/x86/kernel/vmiclock_32.c @@ -202,6 +202,7 @@ static struct irqaction vmi_clock_action = { .name = "vmi-timer", .handler = vmi_timer_interrupt, .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, + .mask = CPU_MASK_ALL, }; static void __devinit vmi_time_init_clockevent(void) diff --git a/trunk/arch/x86/kernel/vmlinux_32.lds.S b/trunk/arch/x86/kernel/vmlinux_32.lds.S index 62ad500d55f3..0d860963f268 100644 --- a/trunk/arch/x86/kernel/vmlinux_32.lds.S +++ b/trunk/arch/x86/kernel/vmlinux_32.lds.S @@ -189,24 +189,15 @@ SECTIONS *(.bss) . = ALIGN(4); __bss_stop = .; - } - - .brk : AT(ADDR(.brk) - LOAD_OFFSET) { + _end = . ; + /* This is where the kernel creates the early boot page tables */ . = ALIGN(PAGE_SIZE); - __brk_base = . ; - . += 64 * 1024 ; /* 64k alignment slop space */ - *(.brk_reservation) /* areas brk users have reserved */ - __brk_limit = . ; - } - - .end : AT(ADDR(.end) - LOAD_OFFSET) { - _end = . ; + pg0 = . ; } /* Sections to be discarded */ /DISCARD/ : { *(.exitcall.exit) - *(.discard) } STABS_DEBUG @@ -214,12 +205,6 @@ SECTIONS DWARF_DEBUG } -/* - * Build-time check on the image size: - */ -ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE), - "kernel image bigger than KERNEL_IMAGE_SIZE") - #ifdef CONFIG_KEXEC /* Link time checks */ #include diff --git a/trunk/arch/x86/kernel/vmlinux_64.lds.S b/trunk/arch/x86/kernel/vmlinux_64.lds.S index c8742507b030..fbfced6f6800 100644 --- a/trunk/arch/x86/kernel/vmlinux_64.lds.S +++ b/trunk/arch/x86/kernel/vmlinux_64.lds.S @@ -29,8 +29,8 @@ SECTIONS { . = __START_KERNEL; phys_startup_64 = startup_64 - LOAD_OFFSET; + _text = .; /* Text and read-only data */ .text : AT(ADDR(.text) - LOAD_OFFSET) { - _text = .; /* Text and read-only data */ /* First the code that has to be first for bootstrapping */ *(.text.head) _stext = .; @@ -61,13 +61,13 @@ SECTIONS .data : AT(ADDR(.data) - LOAD_OFFSET) { DATA_DATA CONSTRUCTORS - _edata = .; /* End of data section */ } :data + _edata = .; /* End of data section */ + . = ALIGN(PAGE_SIZE); + . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { - . = ALIGN(PAGE_SIZE); - . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); *(.data.cacheline_aligned) } . = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES); @@ -125,29 +125,29 @@ SECTIONS #undef VVIRT_OFFSET #undef VVIRT + . = ALIGN(THREAD_SIZE); /* init_task */ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { - . = ALIGN(THREAD_SIZE); /* init_task */ *(.data.init_task) }:data.init + . = ALIGN(PAGE_SIZE); .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { - . = ALIGN(PAGE_SIZE); *(.data.page_aligned) } + /* might get freed after init */ + . = ALIGN(PAGE_SIZE); + __smp_alt_begin = .; + __smp_locks = .; .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { - /* might get freed after init */ - . = ALIGN(PAGE_SIZE); - __smp_alt_begin = .; - __smp_locks = .; *(.smp_locks) - __smp_locks_end = .; - . = ALIGN(PAGE_SIZE); - __smp_alt_end = .; } + __smp_locks_end = .; + . = ALIGN(PAGE_SIZE); + __smp_alt_end = .; . = ALIGN(PAGE_SIZE); /* Init code and data */ - __init_begin = .; /* paired with __init_end */ + __init_begin = .; .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { _sinittext = .; INIT_TEXT @@ -159,42 +159,40 @@ SECTIONS __initdata_end = .; } - .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { - . = ALIGN(16); - __setup_start = .; - *(.init.setup) - __setup_end = .; - } + . = ALIGN(16); + __setup_start = .; + .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) } + __setup_end = .; + __initcall_start = .; .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { - __initcall_start = .; INITCALLS - __initcall_end = .; } + __initcall_end = .; + __con_initcall_start = .; .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { - __con_initcall_start = .; *(.con_initcall.init) - __con_initcall_end = .; } + __con_initcall_end = .; + __x86_cpu_dev_start = .; .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) { - __x86_cpu_dev_start = .; *(.x86_cpu_dev.init) - __x86_cpu_dev_end = .; } + __x86_cpu_dev_end = .; SECURITY_INIT . = ALIGN(8); .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { - __parainstructions = .; + __parainstructions = .; *(.parainstructions) - __parainstructions_end = .; + __parainstructions_end = .; } + . = ALIGN(8); + __alt_instructions = .; .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { - . = ALIGN(8); - __alt_instructions = .; *(.altinstructions) - __alt_instructions_end = .; } + __alt_instructions_end = .; .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { *(.altinstr_replacement) } @@ -209,11 +207,9 @@ SECTIONS #ifdef CONFIG_BLK_DEV_INITRD . = ALIGN(PAGE_SIZE); - .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { - __initramfs_start = .; - *(.init.ramfs) - __initramfs_end = .; - } + __initramfs_start = .; + .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } + __initramfs_end = .; #endif #ifdef CONFIG_SMP @@ -233,29 +229,20 @@ SECTIONS . = ALIGN(PAGE_SIZE); __init_end = .; + . = ALIGN(PAGE_SIZE); + __nosave_begin = .; .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { - . = ALIGN(PAGE_SIZE); - __nosave_begin = .; - *(.data.nosave) - . = ALIGN(PAGE_SIZE); - __nosave_end = .; + *(.data.nosave) } :data.init2 /* use another section data.init2, see PERCPU_VADDR() above */ + . = ALIGN(PAGE_SIZE); + __nosave_end = .; + __bss_start = .; /* BSS */ .bss : AT(ADDR(.bss) - LOAD_OFFSET) { - . = ALIGN(PAGE_SIZE); - __bss_start = .; /* BSS */ *(.bss.page_aligned) *(.bss) - __bss_stop = .; - } - - .brk : AT(ADDR(.brk) - LOAD_OFFSET) { - . = ALIGN(PAGE_SIZE); - __brk_base = . ; - . += 64 * 1024 ; /* 64k alignment slop space */ - *(.brk_reservation) /* areas brk users have reserved */ - __brk_limit = . ; - } + } + __bss_stop = .; _end = . ; @@ -263,7 +250,6 @@ SECTIONS /DISCARD/ : { *(.exitcall.exit) *(.eh_frame) - *(.discard) } STABS_DEBUG @@ -289,10 +275,3 @@ ASSERT((_end - _text <= KERNEL_IMAGE_SIZE), ASSERT((per_cpu__irq_stack_union == 0), "irq_stack_union is not at start of per-cpu area"); #endif - -#ifdef CONFIG_KEXEC -#include - -ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE, - "kexec control code size is too big") -#endif diff --git a/trunk/arch/x86/kernel/vsmp_64.c b/trunk/arch/x86/kernel/vsmp_64.c index a1d804bcd483..74de562812cc 100644 --- a/trunk/arch/x86/kernel/vsmp_64.c +++ b/trunk/arch/x86/kernel/vsmp_64.c @@ -22,7 +22,7 @@ #include #include -#if defined CONFIG_PCI && defined CONFIG_PARAVIRT +#ifdef CONFIG_PARAVIRT /* * Interrupt control on vSMPowered systems: * ~AC is a shadow of IF. If IF is 'on' AC should be 'off' @@ -114,7 +114,6 @@ static void __init set_vsmp_pv_ops(void) } #endif -#ifdef CONFIG_PCI static int is_vsmp = -1; static void __init detect_vsmp_box(void) @@ -140,15 +139,6 @@ int is_vsmp_box(void) } } -#else -static void __init detect_vsmp_box(void) -{ -} -int is_vsmp_box(void) -{ - return 0; -} -#endif void __init vsmp_init(void) { detect_vsmp_box(); diff --git a/trunk/arch/x86/lguest/boot.c b/trunk/arch/x86/lguest/boot.c index e94a11e42f98..9fe4ddaa8f6f 100644 --- a/trunk/arch/x86/lguest/boot.c +++ b/trunk/arch/x86/lguest/boot.c @@ -107,7 +107,7 @@ static void async_hcall(unsigned long call, unsigned long arg1, local_irq_save(flags); if (lguest_data.hcall_status[next_call] != 0xFF) { /* Table full, so do normal hcall which will flush table. */ - kvm_hypercall3(call, arg1, arg2, arg3); + hcall(call, arg1, arg2, arg3); } else { lguest_data.hcalls[next_call].arg0 = call; lguest_data.hcalls[next_call].arg1 = arg1; @@ -134,32 +134,13 @@ static void async_hcall(unsigned long call, unsigned long arg1, * * So, when we're in lazy mode, we call async_hcall() to store the call for * future processing: */ -static void lazy_hcall1(unsigned long call, - unsigned long arg1) -{ - if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) - kvm_hypercall1(call, arg1); - else - async_hcall(call, arg1, 0, 0); -} - -static void lazy_hcall2(unsigned long call, - unsigned long arg1, - unsigned long arg2) -{ - if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) - kvm_hypercall2(call, arg1, arg2); - else - async_hcall(call, arg1, arg2, 0); -} - -static void lazy_hcall3(unsigned long call, +static void lazy_hcall(unsigned long call, unsigned long arg1, unsigned long arg2, unsigned long arg3) { if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) - kvm_hypercall3(call, arg1, arg2, arg3); + hcall(call, arg1, arg2, arg3); else async_hcall(call, arg1, arg2, arg3); } @@ -169,7 +150,7 @@ static void lazy_hcall3(unsigned long call, static void lguest_leave_lazy_mode(void) { paravirt_leave_lazy(paravirt_get_lazy_mode()); - kvm_hypercall0(LHCALL_FLUSH_ASYNC); + hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0); } /*G:033 @@ -248,7 +229,7 @@ static void lguest_write_idt_entry(gate_desc *dt, /* Keep the local copy up to date. */ native_write_idt_entry(dt, entrynum, g); /* Tell Host about this new entry. */ - kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]); + hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]); } /* Changing to a different IDT is very rare: we keep the IDT up-to-date every @@ -260,7 +241,7 @@ static void lguest_load_idt(const struct desc_ptr *desc) struct desc_struct *idt = (void *)desc->address; for (i = 0; i < (desc->size+1)/8; i++) - kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b); + hcall(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b); } /* @@ -280,8 +261,8 @@ static void lguest_load_idt(const struct desc_ptr *desc) */ static void lguest_load_gdt(const struct desc_ptr *desc) { - BUG_ON((desc->size + 1) / 8 != GDT_ENTRIES); - kvm_hypercall2(LHCALL_LOAD_GDT, __pa(desc->address), GDT_ENTRIES); + BUG_ON((desc->size+1)/8 != GDT_ENTRIES); + hcall(LHCALL_LOAD_GDT, __pa(desc->address), GDT_ENTRIES, 0); } /* For a single GDT entry which changes, we do the lazy thing: alter our GDT, @@ -291,7 +272,7 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, const void *desc, int type) { native_write_gdt_entry(dt, entrynum, desc, type); - kvm_hypercall2(LHCALL_LOAD_GDT, __pa(dt), GDT_ENTRIES); + hcall(LHCALL_LOAD_GDT, __pa(dt), GDT_ENTRIES, 0); } /* OK, I lied. There are three "thread local storage" GDT entries which change @@ -303,7 +284,7 @@ static void lguest_load_tls(struct thread_struct *t, unsigned int cpu) * can't handle us removing entries we're currently using. So we clear * the GS register here: if it's needed it'll be reloaded anyway. */ lazy_load_gs(0); - lazy_hcall2(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu); + lazy_hcall(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu, 0); } /*G:038 That's enough excitement for now, back to ploughing through each of @@ -401,7 +382,7 @@ static void lguest_cpuid(unsigned int *ax, unsigned int *bx, static unsigned long current_cr0; static void lguest_write_cr0(unsigned long val) { - lazy_hcall1(LHCALL_TS, val & X86_CR0_TS); + lazy_hcall(LHCALL_TS, val & X86_CR0_TS, 0, 0); current_cr0 = val; } @@ -415,7 +396,7 @@ static unsigned long lguest_read_cr0(void) * the vowels have been optimized out. */ static void lguest_clts(void) { - lazy_hcall1(LHCALL_TS, 0); + lazy_hcall(LHCALL_TS, 0, 0, 0); current_cr0 &= ~X86_CR0_TS; } @@ -437,7 +418,7 @@ static bool cr3_changed = false; static void lguest_write_cr3(unsigned long cr3) { lguest_data.pgdir = cr3; - lazy_hcall1(LHCALL_NEW_PGTABLE, cr3); + lazy_hcall(LHCALL_NEW_PGTABLE, cr3, 0, 0); cr3_changed = true; } @@ -509,17 +490,11 @@ static void lguest_write_cr4(unsigned long val) * into a process' address space. We set the entry then tell the Host the * toplevel and address this corresponds to. The Guest uses one pagetable per * process, so we need to tell the Host which one we're changing (mm->pgd). */ -static void lguest_pte_update(struct mm_struct *mm, unsigned long addr, - pte_t *ptep) -{ - lazy_hcall3(LHCALL_SET_PTE, __pa(mm->pgd), addr, ptep->pte_low); -} - static void lguest_set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval) { *ptep = pteval; - lguest_pte_update(mm, addr, ptep); + lazy_hcall(LHCALL_SET_PTE, __pa(mm->pgd), addr, pteval.pte_low); } /* The Guest calls this to set a top-level entry. Again, we set the entry then @@ -528,8 +503,8 @@ static void lguest_set_pte_at(struct mm_struct *mm, unsigned long addr, static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval) { *pmdp = pmdval; - lazy_hcall2(LHCALL_SET_PMD, __pa(pmdp) & PAGE_MASK, - (__pa(pmdp) & (PAGE_SIZE - 1)) / 4); + lazy_hcall(LHCALL_SET_PMD, __pa(pmdp)&PAGE_MASK, + (__pa(pmdp)&(PAGE_SIZE-1))/4, 0); } /* There are a couple of legacy places where the kernel sets a PTE, but we @@ -545,7 +520,7 @@ static void lguest_set_pte(pte_t *ptep, pte_t pteval) { *ptep = pteval; if (cr3_changed) - lazy_hcall1(LHCALL_FLUSH_TLB, 1); + lazy_hcall(LHCALL_FLUSH_TLB, 1, 0, 0); } /* Unfortunately for Lguest, the pv_mmu_ops for page tables were based on @@ -561,7 +536,7 @@ static void lguest_set_pte(pte_t *ptep, pte_t pteval) static void lguest_flush_tlb_single(unsigned long addr) { /* Simply set it to zero: if it was not, it will fault back in. */ - lazy_hcall3(LHCALL_SET_PTE, lguest_data.pgdir, addr, 0); + lazy_hcall(LHCALL_SET_PTE, lguest_data.pgdir, addr, 0); } /* This is what happens after the Guest has removed a large number of entries. @@ -569,7 +544,7 @@ static void lguest_flush_tlb_single(unsigned long addr) * have changed, ie. virtual addresses below PAGE_OFFSET. */ static void lguest_flush_tlb_user(void) { - lazy_hcall1(LHCALL_FLUSH_TLB, 0); + lazy_hcall(LHCALL_FLUSH_TLB, 0, 0, 0); } /* This is called when the kernel page tables have changed. That's not very @@ -577,7 +552,7 @@ static void lguest_flush_tlb_user(void) * slow), so it's worth separating this from the user flushing above. */ static void lguest_flush_tlb_kernel(void) { - lazy_hcall1(LHCALL_FLUSH_TLB, 1); + lazy_hcall(LHCALL_FLUSH_TLB, 1, 0, 0); } /* @@ -714,7 +689,7 @@ static int lguest_clockevent_set_next_event(unsigned long delta, } /* Please wake us this far in the future. */ - kvm_hypercall1(LHCALL_SET_CLOCKEVENT, delta); + hcall(LHCALL_SET_CLOCKEVENT, delta, 0, 0); return 0; } @@ -725,7 +700,7 @@ static void lguest_clockevent_set_mode(enum clock_event_mode mode, case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: /* A 0 argument shuts the clock down. */ - kvm_hypercall0(LHCALL_SET_CLOCKEVENT); + hcall(LHCALL_SET_CLOCKEVENT, 0, 0, 0); break; case CLOCK_EVT_MODE_ONESHOT: /* This is what we expect. */ @@ -800,8 +775,8 @@ static void lguest_time_init(void) static void lguest_load_sp0(struct tss_struct *tss, struct thread_struct *thread) { - lazy_hcall3(LHCALL_SET_STACK, __KERNEL_DS | 0x1, thread->sp0, - THREAD_SIZE / PAGE_SIZE); + lazy_hcall(LHCALL_SET_STACK, __KERNEL_DS|0x1, thread->sp0, + THREAD_SIZE/PAGE_SIZE); } /* Let's just say, I wouldn't do debugging under a Guest. */ @@ -874,7 +849,7 @@ static void set_lguest_basic_apic_ops(void) /* STOP! Until an interrupt comes in. */ static void lguest_safe_halt(void) { - kvm_hypercall0(LHCALL_HALT); + hcall(LHCALL_HALT, 0, 0, 0); } /* The SHUTDOWN hypercall takes a string to describe what's happening, and @@ -884,8 +859,7 @@ static void lguest_safe_halt(void) * rather than virtual addresses, so we use __pa() here. */ static void lguest_power_off(void) { - kvm_hypercall2(LHCALL_SHUTDOWN, __pa("Power down"), - LGUEST_SHUTDOWN_POWEROFF); + hcall(LHCALL_SHUTDOWN, __pa("Power down"), LGUEST_SHUTDOWN_POWEROFF, 0); } /* @@ -895,7 +869,7 @@ static void lguest_power_off(void) */ static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p) { - kvm_hypercall2(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF); + hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0); /* The hcall won't return, but to keep gcc happy, we're "done". */ return NOTIFY_DONE; } @@ -936,7 +910,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count) len = sizeof(scratch) - 1; scratch[len] = '\0'; memcpy(scratch, buf, len); - kvm_hypercall1(LHCALL_NOTIFY, __pa(scratch)); + hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0); /* This routine returns the number of bytes actually written. */ return len; @@ -946,7 +920,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count) * Launcher to reboot us. */ static void lguest_restart(char *reason) { - kvm_hypercall2(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART); + hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0); } /*G:050 @@ -1066,8 +1040,6 @@ __init void lguest_init(void) pv_mmu_ops.read_cr3 = lguest_read_cr3; pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu; pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mode; - pv_mmu_ops.pte_update = lguest_pte_update; - pv_mmu_ops.pte_update_defer = lguest_pte_update; #ifdef CONFIG_X86_LOCAL_APIC /* apic read/write intercepts */ @@ -1086,6 +1058,14 @@ __init void lguest_init(void) * lguest_init() where the rest of the fairly chaotic boot setup * occurs. */ + /* The native boot code sets up initial page tables immediately after + * the kernel itself, and sets init_pg_tables_end so they're not + * clobbered. The Launcher places our initial pagetables somewhere at + * the top of our physical memory, so we don't need extra space: set + * init_pg_tables_end to the end of the kernel. */ + init_pg_tables_start = __pa(pg0); + init_pg_tables_end = __pa(pg0); + /* As described in head_32.S, we map the first 128M of memory. */ max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT; diff --git a/trunk/arch/x86/lguest/i386_head.S b/trunk/arch/x86/lguest/i386_head.S index f79541989471..10b9bd35a8ff 100644 --- a/trunk/arch/x86/lguest/i386_head.S +++ b/trunk/arch/x86/lguest/i386_head.S @@ -27,8 +27,8 @@ ENTRY(lguest_entry) /* We make the "initialization" hypercall now to tell the Host about * us, and also find out where it put our page tables. */ movl $LHCALL_LGUEST_INIT, %eax - movl $lguest_data - __PAGE_OFFSET, %ebx - .byte 0x0f,0x01,0xc1 /* KVM_HYPERCALL */ + movl $lguest_data - __PAGE_OFFSET, %edx + int $LGUEST_TRAP_ENTRY /* Set up the initial stack so we can run C code. */ movl $(init_thread_union+THREAD_SIZE),%esp diff --git a/trunk/arch/x86/lib/memcpy_64.S b/trunk/arch/x86/lib/memcpy_64.S index ad5441ed1b57..c22981fa2f3a 100644 --- a/trunk/arch/x86/lib/memcpy_64.S +++ b/trunk/arch/x86/lib/memcpy_64.S @@ -1,38 +1,30 @@ /* Copyright 2002 Andi Kleen */ #include - -#include #include +#include /* * memcpy - Copy a memory block. * - * Input: - * rdi destination - * rsi source - * rdx count - * + * Input: + * rdi destination + * rsi source + * rdx count + * * Output: * rax original destination - */ + */ -/* - * memcpy_c() - fast string ops (REP MOVSQ) based variant. - * - * Calls to this get patched into the kernel image via the - * alternative instructions framework: - */ ALIGN memcpy_c: CFI_STARTPROC - movq %rdi, %rax - - movl %edx, %ecx - shrl $3, %ecx - andl $7, %edx + movq %rdi,%rax + movl %edx,%ecx + shrl $3,%ecx + andl $7,%edx rep movsq - movl %edx, %ecx + movl %edx,%ecx rep movsb ret CFI_ENDPROC @@ -41,110 +33,99 @@ ENDPROC(memcpy_c) ENTRY(__memcpy) ENTRY(memcpy) CFI_STARTPROC + pushq %rbx + CFI_ADJUST_CFA_OFFSET 8 + CFI_REL_OFFSET rbx, 0 + movq %rdi,%rax - /* - * Put the number of full 64-byte blocks into %ecx. - * Tail portion is handled at the end: - */ - movq %rdi, %rax - movl %edx, %ecx - shrl $6, %ecx + movl %edx,%ecx + shrl $6,%ecx jz .Lhandle_tail .p2align 4 .Lloop_64: - /* - * We decrement the loop index here - and the zero-flag is - * checked at the end of the loop (instructions inbetween do - * not change the zero flag): - */ decl %ecx - /* - * Move in blocks of 4x16 bytes: - */ - movq 0*8(%rsi), %r11 - movq 1*8(%rsi), %r8 - movq %r11, 0*8(%rdi) - movq %r8, 1*8(%rdi) + movq (%rsi),%r11 + movq 8(%rsi),%r8 - movq 2*8(%rsi), %r9 - movq 3*8(%rsi), %r10 - movq %r9, 2*8(%rdi) - movq %r10, 3*8(%rdi) + movq %r11,(%rdi) + movq %r8,1*8(%rdi) - movq 4*8(%rsi), %r11 - movq 5*8(%rsi), %r8 - movq %r11, 4*8(%rdi) - movq %r8, 5*8(%rdi) + movq 2*8(%rsi),%r9 + movq 3*8(%rsi),%r10 - movq 6*8(%rsi), %r9 - movq 7*8(%rsi), %r10 - movq %r9, 6*8(%rdi) - movq %r10, 7*8(%rdi) + movq %r9,2*8(%rdi) + movq %r10,3*8(%rdi) - leaq 64(%rsi), %rsi - leaq 64(%rdi), %rdi + movq 4*8(%rsi),%r11 + movq 5*8(%rsi),%r8 + movq %r11,4*8(%rdi) + movq %r8,5*8(%rdi) + + movq 6*8(%rsi),%r9 + movq 7*8(%rsi),%r10 + + movq %r9,6*8(%rdi) + movq %r10,7*8(%rdi) + + leaq 64(%rsi),%rsi + leaq 64(%rdi),%rdi jnz .Lloop_64 .Lhandle_tail: - movl %edx, %ecx - andl $63, %ecx - shrl $3, %ecx + movl %edx,%ecx + andl $63,%ecx + shrl $3,%ecx jz .Lhandle_7 - .p2align 4 .Lloop_8: decl %ecx - movq (%rsi), %r8 - movq %r8, (%rdi) - leaq 8(%rdi), %rdi - leaq 8(%rsi), %rsi + movq (%rsi),%r8 + movq %r8,(%rdi) + leaq 8(%rdi),%rdi + leaq 8(%rsi),%rsi jnz .Lloop_8 .Lhandle_7: - movl %edx, %ecx - andl $7, %ecx - jz .Lend - + movl %edx,%ecx + andl $7,%ecx + jz .Lende .p2align 4 .Lloop_1: - movb (%rsi), %r8b - movb %r8b, (%rdi) + movb (%rsi),%r8b + movb %r8b,(%rdi) incq %rdi incq %rsi decl %ecx jnz .Lloop_1 -.Lend: +.Lende: + popq %rbx + CFI_ADJUST_CFA_OFFSET -8 + CFI_RESTORE rbx ret +.Lfinal: CFI_ENDPROC ENDPROC(memcpy) ENDPROC(__memcpy) - /* - * Some CPUs run faster using the string copy instructions. - * It is also a lot simpler. Use this when possible: - */ + /* Some CPUs run faster using the string copy instructions. + It is also a lot simpler. Use this when possible */ - .section .altinstr_replacement, "ax" + .section .altinstr_replacement,"ax" 1: .byte 0xeb /* jmp */ .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */ 2: .previous - - .section .altinstructions, "a" + .section .altinstructions,"a" .align 8 .quad memcpy .quad 1b .byte X86_FEATURE_REP_GOOD - - /* - * Replace only beginning, memcpy is used to apply alternatives, - * so it is silly to overwrite itself with nops - reboot is the - * only outcome... - */ + /* Replace only beginning, memcpy is used to apply alternatives, so it + * is silly to overwrite itself with nops - reboot is only outcome... */ .byte 2b - 1b .byte 2b - 1b .previous diff --git a/trunk/arch/x86/mm/highmem_32.c b/trunk/arch/x86/mm/highmem_32.c index 5bc5d1688c1c..00f127c80b0e 100644 --- a/trunk/arch/x86/mm/highmem_32.c +++ b/trunk/arch/x86/mm/highmem_32.c @@ -19,6 +19,49 @@ void kunmap(struct page *page) kunmap_high(page); } +static void debug_kmap_atomic_prot(enum km_type type) +{ +#ifdef CONFIG_DEBUG_HIGHMEM + static unsigned warn_count = 10; + + if (unlikely(warn_count == 0)) + return; + + if (unlikely(in_interrupt())) { + if (in_irq()) { + if (type != KM_IRQ0 && type != KM_IRQ1 && + type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ && + type != KM_BOUNCE_READ) { + WARN_ON(1); + warn_count--; + } + } else if (!irqs_disabled()) { /* softirq */ + if (type != KM_IRQ0 && type != KM_IRQ1 && + type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 && + type != KM_SKB_SUNRPC_DATA && + type != KM_SKB_DATA_SOFTIRQ && + type != KM_BOUNCE_READ) { + WARN_ON(1); + warn_count--; + } + } + } + + if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ || + type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ) { + if (!irqs_disabled()) { + WARN_ON(1); + warn_count--; + } + } else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) { + if (irq_count() == 0 && !irqs_disabled()) { + WARN_ON(1); + warn_count--; + } + } +#endif +} + /* * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because * no global lock is needed and because the kmap code must perform a global TLB @@ -38,9 +81,8 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) if (!PageHighMem(page)) return page_address(page); - debug_kmap_atomic(type); + debug_kmap_atomic_prot(type); - debug_kmap_atomic(type); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); BUG_ON(!pte_none(*(kmap_pte-idx))); @@ -79,13 +121,22 @@ void kunmap_atomic(void *kvaddr, enum km_type type) pagefault_enable(); } -/* - * This is the same as kmap_atomic() but can map memory that doesn't +/* This is the same as kmap_atomic() but can map memory that doesn't * have a struct page associated with it. */ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) { - return kmap_atomic_prot_pfn(pfn, type, kmap_prot); + enum fixed_addresses idx; + unsigned long vaddr; + + pagefault_disable(); + + idx = type + KM_TYPE_NR*smp_processor_id(); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); + set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot)); + arch_flush_lazy_mmu_mode(); + + return (void*) vaddr; } EXPORT_SYMBOL_GPL(kmap_atomic_pfn); /* temporarily in use by i915 GEM until vmap */ @@ -107,6 +158,7 @@ EXPORT_SYMBOL(kunmap); EXPORT_SYMBOL(kmap_atomic); EXPORT_SYMBOL(kunmap_atomic); +#ifdef CONFIG_NUMA void __init set_highmem_pages_init(void) { struct zone *zone; @@ -130,3 +182,11 @@ void __init set_highmem_pages_init(void) } totalram_pages += totalhigh_pages; } +#else +void __init set_highmem_pages_init(void) +{ + add_highpages_with_active_regions(0, highstart_pfn, highend_pfn); + + totalram_pages += totalhigh_pages; +} +#endif /* CONFIG_NUMA */ diff --git a/trunk/arch/x86/mm/init.c b/trunk/arch/x86/mm/init.c index fd3da1dda1c9..ce6a722587d8 100644 --- a/trunk/arch/x86/mm/init.c +++ b/trunk/arch/x86/mm/init.c @@ -1,345 +1,8 @@ -#include #include - #include -#include -#include #include -#include #include #include -#include - -unsigned long __initdata e820_table_start; -unsigned long __meminitdata e820_table_end; -unsigned long __meminitdata e820_table_top; - -int after_bootmem; - -int direct_gbpages -#ifdef CONFIG_DIRECT_GBPAGES - = 1 -#endif -; - -static void __init find_early_table_space(unsigned long end, int use_pse, - int use_gbpages) -{ - unsigned long puds, pmds, ptes, tables, start; - - puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; - tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); - - if (use_gbpages) { - unsigned long extra; - - extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT); - pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT; - } else - pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; - - tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); - - if (use_pse) { - unsigned long extra; - - extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT); -#ifdef CONFIG_X86_32 - extra += PMD_SIZE; -#endif - ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; - } else - ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT; - - tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE); - -#ifdef CONFIG_X86_32 - /* for fixmap */ - tables += roundup(__end_of_fixed_addresses * sizeof(pte_t), PAGE_SIZE); -#endif - - /* - * RED-PEN putting page tables only on node 0 could - * cause a hotspot and fill up ZONE_DMA. The page tables - * need roughly 0.5KB per GB. - */ -#ifdef CONFIG_X86_32 - start = 0x7000; - e820_table_start = find_e820_area(start, max_pfn_mapped<>= PAGE_SHIFT; - e820_table_end = e820_table_start; - e820_table_top = e820_table_start + (tables >> PAGE_SHIFT); - - printk(KERN_DEBUG "kernel direct mapping tables up to %lx @ %lx-%lx\n", - end, e820_table_start << PAGE_SHIFT, e820_table_top << PAGE_SHIFT); -} - -struct map_range { - unsigned long start; - unsigned long end; - unsigned page_size_mask; -}; - -#ifdef CONFIG_X86_32 -#define NR_RANGE_MR 3 -#else /* CONFIG_X86_64 */ -#define NR_RANGE_MR 5 -#endif - -static int __meminit save_mr(struct map_range *mr, int nr_range, - unsigned long start_pfn, unsigned long end_pfn, - unsigned long page_size_mask) -{ - if (start_pfn < end_pfn) { - if (nr_range >= NR_RANGE_MR) - panic("run out of range for init_memory_mapping\n"); - mr[nr_range].start = start_pfn<> PAGE_SHIFT; - pos = start_pfn << PAGE_SHIFT; -#ifdef CONFIG_X86_32 - /* - * Don't use a large page for the first 2/4MB of memory - * because there are often fixed size MTRRs in there - * and overlapping MTRRs into large pages can cause - * slowdowns. - */ - if (pos == 0) - end_pfn = 1<<(PMD_SHIFT - PAGE_SHIFT); - else - end_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT) - << (PMD_SHIFT - PAGE_SHIFT); -#else /* CONFIG_X86_64 */ - end_pfn = ((pos + (PMD_SIZE - 1)) >> PMD_SHIFT) - << (PMD_SHIFT - PAGE_SHIFT); -#endif - if (end_pfn > (end >> PAGE_SHIFT)) - end_pfn = end >> PAGE_SHIFT; - if (start_pfn < end_pfn) { - nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); - pos = end_pfn << PAGE_SHIFT; - } - - /* big page (2M) range */ - start_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT) - << (PMD_SHIFT - PAGE_SHIFT); -#ifdef CONFIG_X86_32 - end_pfn = (end>>PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT); -#else /* CONFIG_X86_64 */ - end_pfn = ((pos + (PUD_SIZE - 1))>>PUD_SHIFT) - << (PUD_SHIFT - PAGE_SHIFT); - if (end_pfn > ((end>>PMD_SHIFT)<<(PMD_SHIFT - PAGE_SHIFT))) - end_pfn = ((end>>PMD_SHIFT)<<(PMD_SHIFT - PAGE_SHIFT)); -#endif - - if (start_pfn < end_pfn) { - nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, - page_size_mask & (1<>PUD_SHIFT) - << (PUD_SHIFT - PAGE_SHIFT); - end_pfn = (end >> PUD_SHIFT) << (PUD_SHIFT - PAGE_SHIFT); - if (start_pfn < end_pfn) { - nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, - page_size_mask & - ((1<>PMD_SHIFT) - << (PMD_SHIFT - PAGE_SHIFT); - end_pfn = (end >> PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT); - if (start_pfn < end_pfn) { - nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, - page_size_mask & (1<>PAGE_SHIFT; - end_pfn = end>>PAGE_SHIFT; - nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); - - /* try to merge same page size and continuous */ - for (i = 0; nr_range > 1 && i < nr_range - 1; i++) { - unsigned long old_start; - if (mr[i].end != mr[i+1].start || - mr[i].page_size_mask != mr[i+1].page_size_mask) - continue; - /* move it */ - old_start = mr[i].start; - memmove(&mr[i], &mr[i+1], - (nr_range - 1 - i) * sizeof(struct map_range)); - mr[i--].start = old_start; - nr_range--; - } - - for (i = 0; i < nr_range; i++) - printk(KERN_DEBUG " %010lx - %010lx page %s\n", - mr[i].start, mr[i].end, - (mr[i].page_size_mask & (1< e820_table_start) - reserve_early(e820_table_start << PAGE_SHIFT, - e820_table_end << PAGE_SHIFT, "PGTABLE"); - - if (!after_bootmem) - early_memtest(start, end); - - return ret >> PAGE_SHIFT; -} - - -/* - * devmem_is_allowed() checks to see if /dev/mem access to a certain address - * is valid. The argument is a physical page number. - * - * - * On x86, access has to be given to the first megabyte of ram because that area - * contains bios code and data regions used by X and dosemu and similar apps. - * Access has to be given to non-kernel-ram areas as well, these contain the PCI - * mmio resources as well as potential bios/acpi data regions. - */ -int devmem_is_allowed(unsigned long pagenr) -{ - if (pagenr <= 256) - return 1; - if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) - return 0; - if (!page_is_ram(pagenr)) - return 1; - return 0; -} void free_init_pages(char *what, unsigned long begin, unsigned long end) { @@ -384,10 +47,3 @@ void free_initmem(void) (unsigned long)(&__init_begin), (unsigned long)(&__init_end)); } - -#ifdef CONFIG_BLK_DEV_INITRD -void free_initrd_mem(unsigned long start, unsigned long end) -{ - free_init_pages("initrd memory", start, end); -} -#endif diff --git a/trunk/arch/x86/mm/init_32.c b/trunk/arch/x86/mm/init_32.c index db81e9a8556b..47df0e1bbeb9 100644 --- a/trunk/arch/x86/mm/init_32.c +++ b/trunk/arch/x86/mm/init_32.c @@ -49,7 +49,6 @@ #include #include #include -#include unsigned long max_low_pfn_mapped; unsigned long max_pfn_mapped; @@ -59,14 +58,19 @@ unsigned long highstart_pfn, highend_pfn; static noinline int do_test_wp_bit(void); -bool __read_mostly __vmalloc_start_set = false; + +static unsigned long __initdata table_start; +static unsigned long __meminitdata table_end; +static unsigned long __meminitdata table_top; + +static int __initdata after_init_bootmem; static __init void *alloc_low_page(void) { - unsigned long pfn = e820_table_end++; + unsigned long pfn = table_end++; void *adr; - if (pfn >= e820_table_top) + if (pfn >= table_top) panic("alloc_low_page: ran out of memory"); adr = __va(pfn * PAGE_SIZE); @@ -86,7 +90,7 @@ static pmd_t * __init one_md_table_init(pgd_t *pgd) #ifdef CONFIG_X86_PAE if (!(pgd_val(*pgd) & _PAGE_PRESENT)) { - if (after_bootmem) + if (after_init_bootmem) pmd_table = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE); else pmd_table = (pmd_t *)alloc_low_page(); @@ -113,7 +117,7 @@ static pte_t * __init one_page_table_init(pmd_t *pmd) if (!(pmd_val(*pmd) & _PAGE_PRESENT)) { pte_t *page_table = NULL; - if (after_bootmem) { + if (after_init_bootmem) { #ifdef CONFIG_DEBUG_PAGEALLOC page_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE); #endif @@ -164,12 +168,12 @@ static pte_t *__init page_table_kmap_check(pte_t *pte, pmd_t *pmd, if (pmd_idx_kmap_begin != pmd_idx_kmap_end && (vaddr >> PMD_SHIFT) >= pmd_idx_kmap_begin && (vaddr >> PMD_SHIFT) <= pmd_idx_kmap_end - && ((__pa(pte) >> PAGE_SHIFT) < e820_table_start - || (__pa(pte) >> PAGE_SHIFT) >= e820_table_end)) { + && ((__pa(pte) >> PAGE_SHIFT) < table_start + || (__pa(pte) >> PAGE_SHIFT) >= table_end)) { pte_t *newpte; int i; - BUG_ON(after_bootmem); + BUG_ON(after_init_bootmem); newpte = alloc_low_page(); for (i = 0; i < PTRS_PER_PTE; i++) set_pte(newpte + i, pte[i]); @@ -238,14 +242,11 @@ static inline int is_kernel_text(unsigned long addr) * of max_low_pfn pages, by creating page tables starting from address * PAGE_OFFSET: */ -unsigned long __init -kernel_physical_mapping_init(unsigned long start, - unsigned long end, - unsigned long page_size_mask) +static void __init kernel_physical_mapping_init(pgd_t *pgd_base, + unsigned long start_pfn, + unsigned long end_pfn, + int use_pse) { - int use_pse = page_size_mask == (1<> PAGE_SHIFT; - end_pfn = end >> PAGE_SHIFT; - /* * First iteration will setup identity mapping using large/small pages * based on use_pse, with other attributes same as set by @@ -371,6 +369,26 @@ kernel_physical_mapping_init(unsigned long start, mapping_iter = 2; goto repeat; } +} + +/* + * devmem_is_allowed() checks to see if /dev/mem access to a certain address + * is valid. The argument is a physical page number. + * + * + * On x86, access has to be given to the first megabyte of ram because that area + * contains bios code and data regions used by X and dosemu and similar apps. + * Access has to be given to non-kernel-ram areas as well, these contain the PCI + * mmio resources as well as potential bios/acpi data regions. + */ +int devmem_is_allowed(unsigned long pagenr) +{ + if (pagenr <= 256) + return 1; + if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) + return 0; + if (!page_is_ram(pagenr)) + return 1; return 0; } @@ -527,9 +545,8 @@ void __init native_pagetable_setup_done(pgd_t *base) * be partially populated, and so it avoids stomping on any existing * mappings. */ -void __init early_ioremap_page_table_range_init(void) +static void __init early_ioremap_page_table_range_init(pgd_t *pgd_base) { - pgd_t *pgd_base = swapper_pg_dir; unsigned long vaddr, end; /* @@ -624,7 +641,7 @@ static int __init noexec_setup(char *str) } early_param("noexec", noexec_setup); -void __init set_nx(void) +static void __init set_nx(void) { unsigned int v[4], l, h; @@ -776,8 +793,6 @@ void __init initmem_init(unsigned long start_pfn, #ifdef CONFIG_FLATMEM max_mapnr = num_physpages; #endif - __vmalloc_start_set = true; - printk(KERN_NOTICE "%ldMB LOWMEM available.\n", pages_to_mb(max_low_pfn)); @@ -799,66 +814,176 @@ static void __init zone_sizes_init(void) free_area_init_nodes(max_zone_pfns); } -static unsigned long __init setup_node_bootmem(int nodeid, - unsigned long start_pfn, - unsigned long end_pfn, - unsigned long bootmap) -{ - unsigned long bootmap_size; - - /* don't touch min_low_pfn */ - bootmap_size = init_bootmem_node(NODE_DATA(nodeid), - bootmap >> PAGE_SHIFT, - start_pfn, end_pfn); - printk(KERN_INFO " node %d low ram: %08lx - %08lx\n", - nodeid, start_pfn<> PAGE_SHIFT, + min_low_pfn, max_low_pfn); printk(KERN_INFO " mapped low ram: 0 - %08lx\n", max_pfn_mapped< max_low_pfn) - continue; - if (end_pfn > max_low_pfn) - end_pfn = max_low_pfn; + puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; + tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); + + pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; + tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); + + if (use_pse) { + unsigned long extra; + + extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT); + extra += PMD_SIZE; + ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; + } else + ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT; + + tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE); + + /* for fixmap */ + tables += roundup(__end_of_fixed_addresses * sizeof(pte_t), PAGE_SIZE); + + /* + * RED-PEN putting page tables only on node 0 could + * cause a hotspot and fill up ZONE_DMA. The page tables + * need roughly 0.5KB per GB. + */ + start = 0x7000; + table_start = find_e820_area(start, max_pfn_mapped<>= PAGE_SHIFT; + table_end = table_start; + table_top = table_start + (tables>>PAGE_SHIFT); + + printk(KERN_DEBUG "kernel direct mapping tables up to %lx @ %lx-%lx\n", + end, table_start << PAGE_SHIFT, + (table_start << PAGE_SHIFT) + tables); +} + +unsigned long __init_refok init_memory_mapping(unsigned long start, + unsigned long end) +{ + pgd_t *pgd_base = swapper_pg_dir; + unsigned long start_pfn, end_pfn; + unsigned long big_page_start; +#ifdef CONFIG_DEBUG_PAGEALLOC + /* + * For CONFIG_DEBUG_PAGEALLOC, identity mapping will use small pages. + * This will simplify cpa(), which otherwise needs to support splitting + * large pages into small in interrupt context, etc. + */ + int use_pse = 0; #else - start_pfn = 0; - end_pfn = max_low_pfn; + int use_pse = cpu_has_pse; #endif - bootmap = setup_node_bootmem(nodeid, start_pfn, end_pfn, - bootmap); + + /* + * Find space for the kernel direct mapping tables. + */ + if (!after_init_bootmem) + find_early_table_space(end, use_pse); + +#ifdef CONFIG_X86_PAE + set_nx(); + if (nx_enabled) + printk(KERN_INFO "NX (Execute Disable) protection: active\n"); +#endif + + /* Enable PSE if available */ + if (cpu_has_pse) + set_in_cr4(X86_CR4_PSE); + + /* Enable PGE if available */ + if (cpu_has_pge) { + set_in_cr4(X86_CR4_PGE); + __supported_pte_mask |= _PAGE_GLOBAL; + } + + /* + * Don't use a large page for the first 2/4MB of memory + * because there are often fixed size MTRRs in there + * and overlapping MTRRs into large pages can cause + * slowdowns. + */ + big_page_start = PMD_SIZE; + + if (start < big_page_start) { + start_pfn = start >> PAGE_SHIFT; + end_pfn = min(big_page_start>>PAGE_SHIFT, end>>PAGE_SHIFT); + } else { + /* head is not big page alignment ? */ + start_pfn = start >> PAGE_SHIFT; + end_pfn = ((start + (PMD_SIZE - 1))>>PMD_SHIFT) + << (PMD_SHIFT - PAGE_SHIFT); } + if (start_pfn < end_pfn) + kernel_physical_mapping_init(pgd_base, start_pfn, end_pfn, 0); + + /* big page range */ + start_pfn = ((start + (PMD_SIZE - 1))>>PMD_SHIFT) + << (PMD_SHIFT - PAGE_SHIFT); + if (start_pfn < (big_page_start >> PAGE_SHIFT)) + start_pfn = big_page_start >> PAGE_SHIFT; + end_pfn = (end>>PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT); + if (start_pfn < end_pfn) + kernel_physical_mapping_init(pgd_base, start_pfn, end_pfn, + use_pse); + + /* tail is not big page alignment ? */ + start_pfn = end_pfn; + if (start_pfn > (big_page_start>>PAGE_SHIFT)) { + end_pfn = end >> PAGE_SHIFT; + if (start_pfn < end_pfn) + kernel_physical_mapping_init(pgd_base, start_pfn, + end_pfn, 0); + } + + early_ioremap_page_table_range_init(pgd_base); - after_bootmem = 1; + load_cr3(swapper_pg_dir); + + __flush_tlb_all(); + + if (!after_init_bootmem) + reserve_early(table_start << PAGE_SHIFT, + table_end << PAGE_SHIFT, "PGTABLE"); + + if (!after_init_bootmem) + early_memtest(start, end); + + return end >> PAGE_SHIFT; } + /* * paging_init() sets up the page tables - note that the first 8MB are * already mapped by head.S. @@ -1092,6 +1217,13 @@ void mark_rodata_ro(void) } #endif +#ifdef CONFIG_BLK_DEV_INITRD +void free_initrd_mem(unsigned long start, unsigned long end) +{ + free_init_pages("initrd memory", start, end); +} +#endif + int __init reserve_bootmem_generic(unsigned long phys, unsigned long len, int flags) { diff --git a/trunk/arch/x86/mm/init_64.c b/trunk/arch/x86/mm/init_64.c index 54efa57d1c03..07f44d491df1 100644 --- a/trunk/arch/x86/mm/init_64.c +++ b/trunk/arch/x86/mm/init_64.c @@ -48,7 +48,6 @@ #include #include #include -#include /* * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. @@ -62,6 +61,12 @@ static unsigned long dma_reserve __initdata; DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); +int direct_gbpages +#ifdef CONFIG_DIRECT_GBPAGES + = 1 +#endif +; + static int __init parse_direct_gbpages_off(char *arg) { direct_gbpages = 0; @@ -82,10 +87,12 @@ early_param("gbpages", parse_direct_gbpages_on); * around without checking the pgd every time. */ +int after_bootmem; + pteval_t __supported_pte_mask __read_mostly = ~_PAGE_IOMAP; EXPORT_SYMBOL_GPL(__supported_pte_mask); -static int disable_nx __cpuinitdata; +static int do_not_nx __cpuinitdata; /* * noexec=on|off @@ -100,9 +107,9 @@ static int __init nonx_setup(char *str) return -EINVAL; if (!strncmp(str, "on", 2)) { __supported_pte_mask |= _PAGE_NX; - disable_nx = 0; + do_not_nx = 0; } else if (!strncmp(str, "off", 3)) { - disable_nx = 1; + do_not_nx = 1; __supported_pte_mask &= ~_PAGE_NX; } return 0; @@ -114,7 +121,7 @@ void __cpuinit check_efer(void) unsigned long efer; rdmsrl(MSR_EFER, efer); - if (!(efer & EFER_NX) || disable_nx) + if (!(efer & EFER_NX) || do_not_nx) __supported_pte_mask &= ~_PAGE_NX; } @@ -318,9 +325,13 @@ void __init cleanup_highmap(void) } } +static unsigned long __initdata table_start; +static unsigned long __meminitdata table_end; +static unsigned long __meminitdata table_top; + static __ref void *alloc_low_page(unsigned long *phys) { - unsigned long pfn = e820_table_end++; + unsigned long pfn = table_end++; void *adr; if (after_bootmem) { @@ -330,7 +341,7 @@ static __ref void *alloc_low_page(unsigned long *phys) return adr; } - if (pfn >= e820_table_top) + if (pfn >= table_top) panic("alloc_low_page: ran out of memory"); adr = early_memremap(pfn * PAGE_SIZE, PAGE_SIZE); @@ -570,10 +581,58 @@ phys_pud_update(pgd_t *pgd, unsigned long addr, unsigned long end, return phys_pud_init(pud, addr, end, page_size_mask); } -unsigned long __init -kernel_physical_mapping_init(unsigned long start, - unsigned long end, - unsigned long page_size_mask) +static void __init find_early_table_space(unsigned long end, int use_pse, + int use_gbpages) +{ + unsigned long puds, pmds, ptes, tables, start; + + puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; + tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); + if (use_gbpages) { + unsigned long extra; + extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT); + pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT; + } else + pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; + tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); + + if (use_pse) { + unsigned long extra; + extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT); + ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; + } else + ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT; + tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE); + + /* + * RED-PEN putting page tables only on node 0 could + * cause a hotspot and fill up ZONE_DMA. The page tables + * need roughly 0.5KB per GB. + */ + start = 0x8000; + table_start = find_e820_area(start, end, tables, PAGE_SIZE); + if (table_start == -1UL) + panic("Cannot find space for the kernel page tables"); + + table_start >>= PAGE_SHIFT; + table_end = table_start; + table_top = table_start + (tables >> PAGE_SHIFT); + + printk(KERN_DEBUG "kernel direct mapping tables up to %lx @ %lx-%lx\n", + end, table_start << PAGE_SHIFT, table_top << PAGE_SHIFT); +} + +static void __init init_gbpages(void) +{ + if (direct_gbpages && cpu_has_gbpages) + printk(KERN_INFO "Using GB pages for direct mapping\n"); + else + direct_gbpages = 0; +} + +static unsigned long __meminit kernel_physical_mapping_init(unsigned long start, + unsigned long end, + unsigned long page_size_mask) { unsigned long next, last_map_addr = end; @@ -610,6 +669,176 @@ kernel_physical_mapping_init(unsigned long start, return last_map_addr; } +struct map_range { + unsigned long start; + unsigned long end; + unsigned page_size_mask; +}; + +#define NR_RANGE_MR 5 + +static int save_mr(struct map_range *mr, int nr_range, + unsigned long start_pfn, unsigned long end_pfn, + unsigned long page_size_mask) +{ + + if (start_pfn < end_pfn) { + if (nr_range >= NR_RANGE_MR) + panic("run out of range for init_memory_mapping\n"); + mr[nr_range].start = start_pfn<> PAGE_SHIFT; + pos = start_pfn << PAGE_SHIFT; + end_pfn = ((pos + (PMD_SIZE - 1)) >> PMD_SHIFT) + << (PMD_SHIFT - PAGE_SHIFT); + if (end_pfn > (end >> PAGE_SHIFT)) + end_pfn = end >> PAGE_SHIFT; + if (start_pfn < end_pfn) { + nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); + pos = end_pfn << PAGE_SHIFT; + } + + /* big page (2M) range*/ + start_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT) + << (PMD_SHIFT - PAGE_SHIFT); + end_pfn = ((pos + (PUD_SIZE - 1))>>PUD_SHIFT) + << (PUD_SHIFT - PAGE_SHIFT); + if (end_pfn > ((end>>PMD_SHIFT)<<(PMD_SHIFT - PAGE_SHIFT))) + end_pfn = ((end>>PMD_SHIFT)<<(PMD_SHIFT - PAGE_SHIFT)); + if (start_pfn < end_pfn) { + nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, + page_size_mask & (1<>PUD_SHIFT) + << (PUD_SHIFT - PAGE_SHIFT); + end_pfn = (end >> PUD_SHIFT) << (PUD_SHIFT - PAGE_SHIFT); + if (start_pfn < end_pfn) { + nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, + page_size_mask & + ((1<>PMD_SHIFT) + << (PMD_SHIFT - PAGE_SHIFT); + end_pfn = (end >> PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT); + if (start_pfn < end_pfn) { + nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, + page_size_mask & (1<>PAGE_SHIFT; + end_pfn = end>>PAGE_SHIFT; + nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); + + /* try to merge same page size and continuous */ + for (i = 0; nr_range > 1 && i < nr_range - 1; i++) { + unsigned long old_start; + if (mr[i].end != mr[i+1].start || + mr[i].page_size_mask != mr[i+1].page_size_mask) + continue; + /* move it */ + old_start = mr[i].start; + memmove(&mr[i], &mr[i+1], + (nr_range - 1 - i) * sizeof (struct map_range)); + mr[i--].start = old_start; + nr_range--; + } + + for (i = 0; i < nr_range; i++) + printk(KERN_DEBUG " %010lx - %010lx page %s\n", + mr[i].start, mr[i].end, + (mr[i].page_size_mask & (1< table_start) + reserve_early(table_start << PAGE_SHIFT, + table_end << PAGE_SHIFT, "PGTABLE"); + + printk(KERN_INFO "last_map_addr: %lx end: %lx\n", + last_map_addr, end); + + if (!after_bootmem) + early_memtest(start, end); + + return last_map_addr >> PAGE_SHIFT; +} + #ifndef CONFIG_NUMA void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn) { @@ -681,6 +910,28 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); #endif /* CONFIG_MEMORY_HOTPLUG */ +/* + * devmem_is_allowed() checks to see if /dev/mem access to a certain address + * is valid. The argument is a physical page number. + * + * + * On x86, access has to be given to the first megabyte of ram because that area + * contains bios code and data regions used by X and dosemu and similar apps. + * Access has to be given to non-kernel-ram areas as well, these contain the PCI + * mmio resources as well as potential bios/acpi data regions. + */ +int devmem_is_allowed(unsigned long pagenr) +{ + if (pagenr <= 256) + return 1; + if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) + return 0; + if (!page_is_ram(pagenr)) + return 1; + return 0; +} + + static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, kcore_vsyscall; @@ -768,6 +1019,13 @@ void mark_rodata_ro(void) #endif +#ifdef CONFIG_BLK_DEV_INITRD +void free_initrd_mem(unsigned long start, unsigned long end) +{ + free_init_pages("initrd memory", start, end); +} +#endif + int __init reserve_bootmem_generic(unsigned long phys, unsigned long len, int flags) { diff --git a/trunk/arch/x86/mm/iomap_32.c b/trunk/arch/x86/mm/iomap_32.c index bff0c9032f8c..04102d42ff42 100644 --- a/trunk/arch/x86/mm/iomap_32.c +++ b/trunk/arch/x86/mm/iomap_32.c @@ -19,7 +19,6 @@ #include #include #include -#include int is_io_mapping_possible(resource_size_t base, unsigned long size) { @@ -32,27 +31,16 @@ int is_io_mapping_possible(resource_size_t base, unsigned long size) } EXPORT_SYMBOL_GPL(is_io_mapping_possible); -void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) +/* Map 'pfn' using fixed map 'type' and protections 'prot' + */ +void * +iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) { enum fixed_addresses idx; unsigned long vaddr; pagefault_disable(); - idx = type + KM_TYPE_NR * smp_processor_id(); - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); - set_pte(kmap_pte - idx, pfn_pte(pfn, prot)); - arch_flush_lazy_mmu_mode(); - - return (void *)vaddr; -} - -/* - * Map 'pfn' using fixed map 'type' and protections 'prot' - */ -void * -iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) -{ /* * For non-PAT systems, promote PAGE_KERNEL_WC to PAGE_KERNEL_UC_MINUS. * PAGE_KERNEL_WC maps to PWT, which translates to uncached if the @@ -62,7 +50,12 @@ iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) if (!pat_enabled && pgprot_val(prot) == pgprot_val(PAGE_KERNEL_WC)) prot = PAGE_KERNEL_UC_MINUS; - return kmap_atomic_prot_pfn(pfn, type, prot); + idx = type + KM_TYPE_NR*smp_processor_id(); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); + set_pte(kmap_pte-idx, pfn_pte(pfn, prot)); + arch_flush_lazy_mmu_mode(); + + return (void*) vaddr; } EXPORT_SYMBOL_GPL(iomap_atomic_prot_pfn); @@ -72,7 +65,6 @@ iounmap_atomic(void *kvaddr, enum km_type type) unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); - debug_kmap_atomic(type); /* * Force other mappings to Oops if they'll try to access this pte * without first remap it. Keeping stale mappings around is a bad idea diff --git a/trunk/arch/x86/mm/ioremap.c b/trunk/arch/x86/mm/ioremap.c index 0dfa09d69e80..433f7bd4648a 100644 --- a/trunk/arch/x86/mm/ioremap.c +++ b/trunk/arch/x86/mm/ioremap.c @@ -22,17 +22,13 @@ #include #include -static inline int phys_addr_valid(resource_size_t addr) +#ifdef CONFIG_X86_64 + +static inline int phys_addr_valid(unsigned long addr) { -#ifdef CONFIG_PHYS_ADDR_T_64BIT - return !(addr >> boot_cpu_data.x86_phys_bits); -#else - return 1; -#endif + return addr < (1UL << boot_cpu_data.x86_phys_bits); } -#ifdef CONFIG_X86_64 - unsigned long __phys_addr(unsigned long x) { if (x >= __START_KERNEL_map) { @@ -42,7 +38,8 @@ unsigned long __phys_addr(unsigned long x) } else { VIRTUAL_BUG_ON(x < PAGE_OFFSET); x -= PAGE_OFFSET; - VIRTUAL_BUG_ON(!phys_addr_valid(x)); + VIRTUAL_BUG_ON(system_state == SYSTEM_BOOTING ? x > MAXMEM : + !phys_addr_valid(x)); } return x; } @@ -59,8 +56,10 @@ bool __virt_addr_valid(unsigned long x) if (x < PAGE_OFFSET) return false; x -= PAGE_OFFSET; - if (!phys_addr_valid(x)) + if (system_state == SYSTEM_BOOTING ? + x > MAXMEM : !phys_addr_valid(x)) { return false; + } } return pfn_valid(x >> PAGE_SHIFT); @@ -69,12 +68,18 @@ EXPORT_SYMBOL(__virt_addr_valid); #else +static inline int phys_addr_valid(unsigned long addr) +{ + return 1; +} + #ifdef CONFIG_DEBUG_VIRTUAL unsigned long __phys_addr(unsigned long x) { - /* VMALLOC_* aren't constants */ + /* VMALLOC_* aren't constants; not available at the boot time */ VIRTUAL_BUG_ON(x < PAGE_OFFSET); - VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x)); + VIRTUAL_BUG_ON(system_state != SYSTEM_BOOTING && + is_vmalloc_addr((void *) x)); return x - PAGE_OFFSET; } EXPORT_SYMBOL(__phys_addr); @@ -84,9 +89,7 @@ bool __virt_addr_valid(unsigned long x) { if (x < PAGE_OFFSET) return false; - if (__vmalloc_start_set && is_vmalloc_addr((void *) x)) - return false; - if (x >= FIXADDR_START) + if (system_state != SYSTEM_BOOTING && is_vmalloc_addr((void *) x)) return false; return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT); } @@ -505,19 +508,13 @@ static inline pte_t * __init early_ioremap_pte(unsigned long addr) return &bm_pte[pte_index(addr)]; } -static unsigned long slot_virt[FIX_BTMAPS_SLOTS] __initdata; - void __init early_ioremap_init(void) { pmd_t *pmd; - int i; if (early_ioremap_debug) printk(KERN_INFO "early_ioremap_init()\n"); - for (i = 0; i < FIX_BTMAPS_SLOTS; i++) - slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i); - pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)); memset(bm_pte, 0, sizeof(bm_pte)); pmd_populate_kernel(&init_mm, pmd, bm_pte); @@ -584,7 +581,6 @@ static inline void __init early_clear_fixmap(enum fixed_addresses idx) static void __iomem *prev_map[FIX_BTMAPS_SLOTS] __initdata; static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata; - static int __init check_early_ioremap_leak(void) { int count = 0; @@ -606,8 +602,7 @@ static int __init check_early_ioremap_leak(void) } late_initcall(check_early_ioremap_leak); -static void __init __iomem * -__early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot) +static void __init __iomem *__early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot) { unsigned long offset, last_addr; unsigned int nrpages; @@ -673,9 +668,9 @@ __early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot) --nrpages; } if (early_ioremap_debug) - printk(KERN_CONT "%08lx + %08lx\n", offset, slot_virt[slot]); + printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0)); - prev_map[slot] = (void __iomem *)(offset + slot_virt[slot]); + prev_map[slot] = (void __iomem *)(offset + fix_to_virt(idx0)); return prev_map[slot]; } @@ -743,3 +738,8 @@ void __init early_iounmap(void __iomem *addr, unsigned long size) } prev_map[slot] = NULL; } + +void __this_fixmap_does_not_exist(void) +{ + WARN_ON(1); +} diff --git a/trunk/arch/x86/mm/kmmio.c b/trunk/arch/x86/mm/kmmio.c index 4f115e00486b..6a518dd08a36 100644 --- a/trunk/arch/x86/mm/kmmio.c +++ b/trunk/arch/x86/mm/kmmio.c @@ -310,7 +310,7 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx); if (!ctx->active) { - pr_debug("kmmio: spurious debug trap on CPU %d.\n", + pr_warning("kmmio: spurious debug trap on CPU %d.\n", smp_processor_id()); goto out; } diff --git a/trunk/arch/x86/mm/memtest.c b/trunk/arch/x86/mm/memtest.c index 605c8be06217..0bcd7883d036 100644 --- a/trunk/arch/x86/mm/memtest.c +++ b/trunk/arch/x86/mm/memtest.c @@ -100,9 +100,6 @@ static int __init parse_memtest(char *arg) { if (arg) memtest_pattern = simple_strtoul(arg, NULL, 0); - else - memtest_pattern = ARRAY_SIZE(patterns); - return 0; } diff --git a/trunk/arch/x86/mm/numa_32.c b/trunk/arch/x86/mm/numa_32.c index 3daefa04ace5..451fe95a0352 100644 --- a/trunk/arch/x86/mm/numa_32.c +++ b/trunk/arch/x86/mm/numa_32.c @@ -416,11 +416,10 @@ void __init initmem_init(unsigned long start_pfn, for_each_online_node(nid) propagate_e820_map_node(nid); - for_each_online_node(nid) { + for_each_online_node(nid) memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); - NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; - } + NODE_DATA(0)->bdata = &bootmem_node_data[0]; setup_bootmem_allocator(); } diff --git a/trunk/arch/x86/mm/pageattr.c b/trunk/arch/x86/mm/pageattr.c index d71e1b636ce6..9c4294986af7 100644 --- a/trunk/arch/x86/mm/pageattr.c +++ b/trunk/arch/x86/mm/pageattr.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -34,7 +33,6 @@ struct cpa_data { unsigned long pfn; unsigned force_split : 1; int curpage; - struct page **pages; }; /* @@ -47,7 +45,6 @@ static DEFINE_SPINLOCK(cpa_lock); #define CPA_FLUSHTLB 1 #define CPA_ARRAY 2 -#define CPA_PAGES_ARRAY 4 #ifdef CONFIG_PROC_FS static unsigned long direct_pages_count[PG_LEVEL_NUM]; @@ -98,7 +95,7 @@ static inline unsigned long highmap_start_pfn(void) static inline unsigned long highmap_end_pfn(void) { - return __pa(roundup(_brk_end, PMD_SIZE)) >> PAGE_SHIFT; + return __pa(roundup((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT; } #endif @@ -204,10 +201,10 @@ static void cpa_flush_range(unsigned long start, int numpages, int cache) } } -static void cpa_flush_array(unsigned long *start, int numpages, int cache, - int in_flags, struct page **pages) +static void cpa_flush_array(unsigned long *start, int numpages, int cache) { unsigned int i, level; + unsigned long *addr; BUG_ON(irqs_disabled()); @@ -228,22 +225,14 @@ static void cpa_flush_array(unsigned long *start, int numpages, int cache, * will cause all other CPUs to flush the same * cachelines: */ - for (i = 0; i < numpages; i++) { - unsigned long addr; - pte_t *pte; - - if (in_flags & CPA_PAGES_ARRAY) - addr = (unsigned long)page_address(pages[i]); - else - addr = start[i]; - - pte = lookup_address(addr, &level); + for (i = 0, addr = start; i < numpages; i++, addr++) { + pte_t *pte = lookup_address(*addr, &level); /* * Only flush present addresses: */ if (pte && (pte_val(*pte) & _PAGE_PRESENT)) - clflush_cache_range((void *)addr, PAGE_SIZE); + clflush_cache_range((void *) *addr, PAGE_SIZE); } } @@ -595,9 +584,7 @@ static int __change_page_attr(struct cpa_data *cpa, int primary) unsigned int level; pte_t *kpte, old_pte; - if (cpa->flags & CPA_PAGES_ARRAY) - address = (unsigned long)page_address(cpa->pages[cpa->curpage]); - else if (cpa->flags & CPA_ARRAY) + if (cpa->flags & CPA_ARRAY) address = cpa->vaddr[cpa->curpage]; else address = *cpa->vaddr; @@ -700,9 +687,7 @@ static int cpa_process_alias(struct cpa_data *cpa) * No need to redo, when the primary call touched the direct * mapping already: */ - if (cpa->flags & CPA_PAGES_ARRAY) - vaddr = (unsigned long)page_address(cpa->pages[cpa->curpage]); - else if (cpa->flags & CPA_ARRAY) + if (cpa->flags & CPA_ARRAY) vaddr = cpa->vaddr[cpa->curpage]; else vaddr = *cpa->vaddr; @@ -713,7 +698,7 @@ static int cpa_process_alias(struct cpa_data *cpa) alias_cpa = *cpa; temp_cpa_vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); alias_cpa.vaddr = &temp_cpa_vaddr; - alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); + alias_cpa.flags &= ~CPA_ARRAY; ret = __change_page_attr_set_clr(&alias_cpa, 0); @@ -726,7 +711,7 @@ static int cpa_process_alias(struct cpa_data *cpa) * No need to redo, when the primary call touched the high * mapping already: */ - if (within(vaddr, (unsigned long) _text, _brk_end)) + if (within(vaddr, (unsigned long) _text, (unsigned long) _end)) return 0; /* @@ -739,7 +724,7 @@ static int cpa_process_alias(struct cpa_data *cpa) alias_cpa = *cpa; temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + __START_KERNEL_map - phys_base; alias_cpa.vaddr = &temp_cpa_vaddr; - alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); + alias_cpa.flags &= ~CPA_ARRAY; /* * The high mapping range is imprecise, so ignore the return value. @@ -760,7 +745,7 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) */ cpa->numpages = numpages; /* for array changes, we can't use large page */ - if (cpa->flags & (CPA_ARRAY | CPA_PAGES_ARRAY)) + if (cpa->flags & CPA_ARRAY) cpa->numpages = 1; if (!debug_pagealloc) @@ -784,7 +769,7 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) */ BUG_ON(cpa->numpages > numpages); numpages -= cpa->numpages; - if (cpa->flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) + if (cpa->flags & CPA_ARRAY) cpa->curpage++; else *cpa->vaddr += cpa->numpages * PAGE_SIZE; @@ -801,8 +786,7 @@ static inline int cache_attr(pgprot_t attr) static int change_page_attr_set_clr(unsigned long *addr, int numpages, pgprot_t mask_set, pgprot_t mask_clr, - int force_split, int in_flag, - struct page **pages) + int force_split, int array) { struct cpa_data cpa; int ret, cache, checkalias; @@ -817,19 +801,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, return 0; /* Ensure we are PAGE_SIZE aligned */ - if (in_flag & CPA_ARRAY) { - int i; - for (i = 0; i < numpages; i++) { - if (addr[i] & ~PAGE_MASK) { - addr[i] &= PAGE_MASK; - WARN_ON_ONCE(1); - } - } - } else if (!(in_flag & CPA_PAGES_ARRAY)) { - /* - * in_flag of CPA_PAGES_ARRAY implies it is aligned. - * No need to cehck in that case - */ + if (!array) { if (*addr & ~PAGE_MASK) { *addr &= PAGE_MASK; /* @@ -837,6 +809,14 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, */ WARN_ON_ONCE(1); } + } else { + int i; + for (i = 0; i < numpages; i++) { + if (addr[i] & ~PAGE_MASK) { + addr[i] &= PAGE_MASK; + WARN_ON_ONCE(1); + } + } } /* Must avoid aliasing mappings in the highmem code */ @@ -852,7 +832,6 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, arch_flush_lazy_mmu_mode(); cpa.vaddr = addr; - cpa.pages = pages; cpa.numpages = numpages; cpa.mask_set = mask_set; cpa.mask_clr = mask_clr; @@ -860,8 +839,8 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, cpa.curpage = 0; cpa.force_split = force_split; - if (in_flag & (CPA_ARRAY | CPA_PAGES_ARRAY)) - cpa.flags |= in_flag; + if (array) + cpa.flags |= CPA_ARRAY; /* No alias checking for _NX bit modifications */ checkalias = (pgprot_val(mask_set) | pgprot_val(mask_clr)) != _PAGE_NX; @@ -887,10 +866,9 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, * wbindv): */ if (!ret && cpu_has_clflush) { - if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) { - cpa_flush_array(addr, numpages, cache, - cpa.flags, pages); - } else + if (cpa.flags & CPA_ARRAY) + cpa_flush_array(addr, numpages, cache); + else cpa_flush_range(*addr, numpages, cache); } else cpa_flush_all(cache); @@ -910,28 +888,14 @@ static inline int change_page_attr_set(unsigned long *addr, int numpages, pgprot_t mask, int array) { return change_page_attr_set_clr(addr, numpages, mask, __pgprot(0), 0, - (array ? CPA_ARRAY : 0), NULL); + array); } static inline int change_page_attr_clear(unsigned long *addr, int numpages, pgprot_t mask, int array) { return change_page_attr_set_clr(addr, numpages, __pgprot(0), mask, 0, - (array ? CPA_ARRAY : 0), NULL); -} - -static inline int cpa_set_pages_array(struct page **pages, int numpages, - pgprot_t mask) -{ - return change_page_attr_set_clr(NULL, numpages, mask, __pgprot(0), 0, - CPA_PAGES_ARRAY, pages); -} - -static inline int cpa_clear_pages_array(struct page **pages, int numpages, - pgprot_t mask) -{ - return change_page_attr_set_clr(NULL, numpages, __pgprot(0), mask, 0, - CPA_PAGES_ARRAY, pages); + array); } int _set_memory_uc(unsigned long addr, int numpages) @@ -1079,7 +1043,7 @@ int set_memory_np(unsigned long addr, int numpages) int set_memory_4k(unsigned long addr, int numpages) { return change_page_attr_set_clr(&addr, numpages, __pgprot(0), - __pgprot(0), 1, 0, NULL); + __pgprot(0), 1, 0); } int set_pages_uc(struct page *page, int numpages) @@ -1090,35 +1054,6 @@ int set_pages_uc(struct page *page, int numpages) } EXPORT_SYMBOL(set_pages_uc); -int set_pages_array_uc(struct page **pages, int addrinarray) -{ - unsigned long start; - unsigned long end; - int i; - int free_idx; - - for (i = 0; i < addrinarray; i++) { - start = (unsigned long)page_address(pages[i]); - end = start + PAGE_SIZE; - if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL)) - goto err_out; - } - - if (cpa_set_pages_array(pages, addrinarray, - __pgprot(_PAGE_CACHE_UC_MINUS)) == 0) { - return 0; /* Success */ - } -err_out: - free_idx = i; - for (i = 0; i < free_idx; i++) { - start = (unsigned long)page_address(pages[i]); - end = start + PAGE_SIZE; - free_memtype(start, end); - } - return -EINVAL; -} -EXPORT_SYMBOL(set_pages_array_uc); - int set_pages_wb(struct page *page, int numpages) { unsigned long addr = (unsigned long)page_address(page); @@ -1127,26 +1062,6 @@ int set_pages_wb(struct page *page, int numpages) } EXPORT_SYMBOL(set_pages_wb); -int set_pages_array_wb(struct page **pages, int addrinarray) -{ - int retval; - unsigned long start; - unsigned long end; - int i; - - retval = cpa_clear_pages_array(pages, addrinarray, - __pgprot(_PAGE_CACHE_MASK)); - - for (i = 0; i < addrinarray; i++) { - start = (unsigned long)page_address(pages[i]); - end = start + PAGE_SIZE; - free_memtype(start, end); - } - - return retval; -} -EXPORT_SYMBOL(set_pages_array_wb); - int set_pages_x(struct page *page, int numpages) { unsigned long addr = (unsigned long)page_address(page); diff --git a/trunk/arch/x86/mm/pat.c b/trunk/arch/x86/mm/pat.c index 640339ee4fb2..2ed37158012d 100644 --- a/trunk/arch/x86/mm/pat.c +++ b/trunk/arch/x86/mm/pat.c @@ -677,11 +677,10 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot, is_ram = pat_pagerange_is_ram(paddr, paddr + size); /* - * reserve_pfn_range() doesn't support RAM pages. Maintain the current - * behavior with RAM pages by returning success. + * reserve_pfn_range() doesn't support RAM pages. */ if (is_ram != 0) - return 0; + return -EINVAL; ret = reserve_memtype(paddr, paddr + size, want_flags, &flags); if (ret) diff --git a/trunk/arch/x86/mm/pgtable_32.c b/trunk/arch/x86/mm/pgtable_32.c index 46c8834aedc0..f2e477c91c1b 100644 --- a/trunk/arch/x86/mm/pgtable_32.c +++ b/trunk/arch/x86/mm/pgtable_32.c @@ -50,7 +50,7 @@ void set_pte_vaddr(unsigned long vaddr, pte_t pteval) } pte = pte_offset_kernel(pmd, vaddr); if (pte_val(pteval)) - set_pte_at(&init_mm, vaddr, pte, pteval); + set_pte_present(&init_mm, vaddr, pte, pteval); else pte_clear(&init_mm, vaddr, pte); diff --git a/trunk/arch/x86/mm/tlb.c b/trunk/arch/x86/mm/tlb.c index 821e97017e95..a654d59e4483 100644 --- a/trunk/arch/x86/mm/tlb.c +++ b/trunk/arch/x86/mm/tlb.c @@ -186,6 +186,11 @@ static void flush_tlb_others_ipi(const struct cpumask *cpumask, cpumask_andnot(to_cpumask(f->flush_cpumask), cpumask, cpumask_of(smp_processor_id())); + /* + * Make the above memory operations globally visible before + * sending the IPI. + */ + smp_mb(); /* * We have to send the IPI only to * CPUs affected. diff --git a/trunk/arch/x86/pci/common.c b/trunk/arch/x86/pci/common.c index 8c362b96b644..82d22fc601ae 100644 --- a/trunk/arch/x86/pci/common.c +++ b/trunk/arch/x86/pci/common.c @@ -90,7 +90,7 @@ static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d) return 0; } -static const struct dmi_system_id can_skip_pciprobe_dmi_table[] __devinitconst = { +static struct dmi_system_id can_skip_pciprobe_dmi_table[] __devinitdata = { /* * Systems where PCI IO resource ISA alignment can be skipped * when the ISA enable bit in the bridge control is not set @@ -183,7 +183,7 @@ static int __devinit assign_all_busses(const struct dmi_system_id *d) } #endif -static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = { +static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { #ifdef __i386__ /* * Laptops which need pci=assign-busses to see Cardbus cards diff --git a/trunk/arch/x86/pci/early.c b/trunk/arch/x86/pci/early.c index aaf26ae58cd5..f6adf2c6d751 100644 --- a/trunk/arch/x86/pci/early.c +++ b/trunk/arch/x86/pci/early.c @@ -69,12 +69,11 @@ void early_dump_pci_device(u8 bus, u8 slot, u8 func) int j; u32 val; - printk(KERN_INFO "pci 0000:%02x:%02x.%d config space:", - bus, slot, func); + printk(KERN_INFO "PCI: %02x:%02x:%02x", bus, slot, func); for (i = 0; i < 256; i += 4) { if (!(i & 0x0f)) - printk("\n %02x:",i); + printk("\n%04x:",i); val = read_pci_config(bus, slot, func, i); for (j = 0; j < 4; j++) { @@ -97,22 +96,20 @@ void early_dump_pci_devices(void) for (func = 0; func < 8; func++) { u32 class; u8 type; - class = read_pci_config(bus, slot, func, PCI_CLASS_REVISION); if (class == 0xffffffff) - continue; + break; early_dump_pci_device(bus, slot, func); - if (func == 0) { - type = read_pci_config_byte(bus, slot, - func, + /* No multi-function device? */ + type = read_pci_config_byte(bus, slot, func, PCI_HEADER_TYPE); - if (!(type & 0x80)) - break; - } + if (!(type & 0x80)) + break; } } } } + diff --git a/trunk/arch/x86/pci/fixup.c b/trunk/arch/x86/pci/fixup.c index 6dd89555fbfa..7d388d5cf548 100644 --- a/trunk/arch/x86/pci/fixup.c +++ b/trunk/arch/x86/pci/fixup.c @@ -356,7 +356,7 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); -static const struct dmi_system_id __devinitconst msi_k8t_dmi_table[] = { +static struct dmi_system_id __devinitdata msi_k8t_dmi_table[] = { { .ident = "MSI-K8T-Neo2Fir", .matches = { @@ -413,7 +413,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, */ static u16 toshiba_line_size; -static const struct dmi_system_id __devinitconst toshiba_ohci1394_dmi_table[] = { +static struct dmi_system_id __devinitdata toshiba_ohci1394_dmi_table[] = { { .ident = "Toshiba PS5 based laptop", .matches = { @@ -494,6 +494,26 @@ static void __devinit pci_siemens_interrupt_controller(struct pci_dev *dev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015, pci_siemens_interrupt_controller); +/* + * Regular PCI devices have 256 bytes, but AMD Family 10h/11h CPUs have + * 4096 bytes configuration space for each function of their processor + * configuration space. + */ +static void amd_cpu_pci_cfg_space_size(struct pci_dev *dev) +{ + dev->cfg_size = pci_cfg_space_size_ext(dev); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, amd_cpu_pci_cfg_space_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1201, amd_cpu_pci_cfg_space_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1202, amd_cpu_pci_cfg_space_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1203, amd_cpu_pci_cfg_space_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1204, amd_cpu_pci_cfg_space_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1300, amd_cpu_pci_cfg_space_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1301, amd_cpu_pci_cfg_space_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1302, amd_cpu_pci_cfg_space_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1303, amd_cpu_pci_cfg_space_size); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1304, amd_cpu_pci_cfg_space_size); + /* * SB600: Disable BAR1 on device 14.0 to avoid HPET resources from * confusing the PCI engine: diff --git a/trunk/arch/x86/pci/i386.c b/trunk/arch/x86/pci/i386.c index f234a37bd428..5ead808dd70c 100644 --- a/trunk/arch/x86/pci/i386.c +++ b/trunk/arch/x86/pci/i386.c @@ -319,9 +319,6 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, return -EINVAL; } flags = new_flags; - vma->vm_page_prot = __pgprot( - (pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK) | - flags); } if (((vma->vm_pgoff < max_low_pfn_mapped) || diff --git a/trunk/arch/x86/pci/legacy.c b/trunk/arch/x86/pci/legacy.c index 4061bb0f267d..f1065b129e9c 100644 --- a/trunk/arch/x86/pci/legacy.c +++ b/trunk/arch/x86/pci/legacy.c @@ -50,6 +50,8 @@ static int __init pci_legacy_init(void) if (pci_root_bus) pci_bus_add_devices(pci_root_bus); + pcibios_fixup_peer_bridges(); + return 0; } @@ -65,7 +67,6 @@ int __init pci_subsys_init(void) pci_visws_init(); #endif pci_legacy_init(); - pcibios_fixup_peer_bridges(); pcibios_irq_init(); pcibios_init(); diff --git a/trunk/arch/x86/pci/mmconfig-shared.c b/trunk/arch/x86/pci/mmconfig-shared.c index 905bb526b133..89bf9242c80a 100644 --- a/trunk/arch/x86/pci/mmconfig-shared.c +++ b/trunk/arch/x86/pci/mmconfig-shared.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -25,49 +24,24 @@ /* Indicate if the mmcfg resources have been placed into the resource table. */ static int __initdata pci_mmcfg_resources_inserted; -static __init int extend_mmcfg(int num) -{ - struct acpi_mcfg_allocation *new; - int new_num = pci_mmcfg_config_num + num; - - new = kzalloc(sizeof(pci_mmcfg_config[0]) * new_num, GFP_KERNEL); - if (!new) - return -1; - - if (pci_mmcfg_config) { - memcpy(new, pci_mmcfg_config, - sizeof(pci_mmcfg_config[0]) * new_num); - kfree(pci_mmcfg_config); - } - pci_mmcfg_config = new; - - return 0; -} - -static __init void fill_one_mmcfg(u64 addr, int segment, int start, int end) -{ - int i = pci_mmcfg_config_num; - - pci_mmcfg_config_num++; - pci_mmcfg_config[i].address = addr; - pci_mmcfg_config[i].pci_segment = segment; - pci_mmcfg_config[i].start_bus_number = start; - pci_mmcfg_config[i].end_bus_number = end; -} - static const char __init *pci_mmcfg_e7520(void) { u32 win; raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0xce, 2, &win); win = win & 0xf000; - if (win == 0x0000 || win == 0xf000) - return NULL; - - if (extend_mmcfg(1) == -1) - return NULL; - - fill_one_mmcfg(win << 16, 0, 0, 255); + if(win == 0x0000 || win == 0xf000) + pci_mmcfg_config_num = 0; + else { + pci_mmcfg_config_num = 1; + pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL); + if (!pci_mmcfg_config) + return NULL; + pci_mmcfg_config[0].address = win << 16; + pci_mmcfg_config[0].pci_segment = 0; + pci_mmcfg_config[0].start_bus_number = 0; + pci_mmcfg_config[0].end_bus_number = 255; + } return "Intel Corporation E7520 Memory Controller Hub"; } @@ -76,11 +50,13 @@ static const char __init *pci_mmcfg_intel_945(void) { u32 pciexbar, mask = 0, len = 0; + pci_mmcfg_config_num = 1; + raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0x48, 4, &pciexbar); /* Enable bit */ if (!(pciexbar & 1)) - return NULL; + pci_mmcfg_config_num = 0; /* Size bits */ switch ((pciexbar >> 1) & 3) { @@ -97,23 +73,28 @@ static const char __init *pci_mmcfg_intel_945(void) len = 0x04000000U; break; default: - return NULL; + pci_mmcfg_config_num = 0; } /* Errata #2, things break when not aligned on a 256Mb boundary */ /* Can only happen in 64M/128M mode */ if ((pciexbar & mask) & 0x0fffffffU) - return NULL; + pci_mmcfg_config_num = 0; /* Don't hit the APIC registers and their friends */ if ((pciexbar & mask) >= 0xf0000000U) - return NULL; - - if (extend_mmcfg(1) == -1) - return NULL; - - fill_one_mmcfg(pciexbar & mask, 0, 0, (len >> 20) - 1); + pci_mmcfg_config_num = 0; + + if (pci_mmcfg_config_num) { + pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL); + if (!pci_mmcfg_config) + return NULL; + pci_mmcfg_config[0].address = pciexbar & mask; + pci_mmcfg_config[0].pci_segment = 0; + pci_mmcfg_config[0].start_bus_number = 0; + pci_mmcfg_config[0].end_bus_number = (len >> 20) - 1; + } return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub"; } @@ -157,75 +138,20 @@ static const char __init *pci_mmcfg_amd_fam10h(void) busnbits = 8; } - if (extend_mmcfg(1 << segnbits) == -1) - return NULL; - - for (i = 0; i < (1 << segnbits); i++) - fill_one_mmcfg(base + (1<<28) * i, i, 0, (1 << busnbits) - 1); - - return "AMD Family 10h NB"; -} - -static bool __initdata mcp55_checked; -static const char __init *pci_mmcfg_nvidia_mcp55(void) -{ - int bus; - int mcp55_mmconf_found = 0; - - static const u32 extcfg_regnum = 0x90; - static const u32 extcfg_regsize = 4; - static const u32 extcfg_enable_mask = 1<<31; - static const u32 extcfg_start_mask = 0xff<<16; - static const int extcfg_start_shift = 16; - static const u32 extcfg_size_mask = 0x3<<28; - static const int extcfg_size_shift = 28; - static const int extcfg_sizebus[] = {0x100, 0x80, 0x40, 0x20}; - static const u32 extcfg_base_mask[] = {0x7ff8, 0x7ffc, 0x7ffe, 0x7fff}; - static const int extcfg_base_lshift = 25; - - /* - * do check if amd fam10h already took over - */ - if (!acpi_disabled || pci_mmcfg_config_num || mcp55_checked) + pci_mmcfg_config_num = (1 << segnbits); + pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]) * + pci_mmcfg_config_num, GFP_KERNEL); + if (!pci_mmcfg_config) return NULL; - mcp55_checked = true; - for (bus = 0; bus < 256; bus++) { - u64 base; - u32 l, extcfg; - u16 vendor, device; - int start, size_index, end; - - raw_pci_ops->read(0, bus, PCI_DEVFN(0, 0), 0, 4, &l); - vendor = l & 0xffff; - device = (l >> 16) & 0xffff; - - if (PCI_VENDOR_ID_NVIDIA != vendor || 0x0369 != device) - continue; - - raw_pci_ops->read(0, bus, PCI_DEVFN(0, 0), extcfg_regnum, - extcfg_regsize, &extcfg); - - if (!(extcfg & extcfg_enable_mask)) - continue; - - if (extend_mmcfg(1) == -1) - continue; - - size_index = (extcfg & extcfg_size_mask) >> extcfg_size_shift; - base = extcfg & extcfg_base_mask[size_index]; - /* base could > 4G */ - base <<= extcfg_base_lshift; - start = (extcfg & extcfg_start_mask) >> extcfg_start_shift; - end = start + extcfg_sizebus[size_index] - 1; - fill_one_mmcfg(base, 0, start, end); - mcp55_mmconf_found++; + for (i = 0; i < (1 << segnbits); i++) { + pci_mmcfg_config[i].address = base + (1<<28) * i; + pci_mmcfg_config[i].pci_segment = i; + pci_mmcfg_config[i].start_bus_number = 0; + pci_mmcfg_config[i].end_bus_number = (1 << busnbits) - 1; } - if (!mcp55_mmconf_found) - return NULL; - - return "nVidia MCP55"; + return "AMD Family 10h NB"; } struct pci_mmcfg_hostbridge_probe { @@ -245,52 +171,8 @@ static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = { 0x1200, pci_mmcfg_amd_fam10h }, { 0xff, PCI_DEVFN(0, 0), PCI_VENDOR_ID_AMD, 0x1200, pci_mmcfg_amd_fam10h }, - { 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_NVIDIA, - 0x0369, pci_mmcfg_nvidia_mcp55 }, }; -static int __init cmp_mmcfg(const void *x1, const void *x2) -{ - const typeof(pci_mmcfg_config[0]) *m1 = x1; - const typeof(pci_mmcfg_config[0]) *m2 = x2; - int start1, start2; - - start1 = m1->start_bus_number; - start2 = m2->start_bus_number; - - return start1 - start2; -} - -static void __init pci_mmcfg_check_end_bus_number(void) -{ - int i; - typeof(pci_mmcfg_config[0]) *cfg, *cfgx; - - /* sort them at first */ - sort(pci_mmcfg_config, pci_mmcfg_config_num, - sizeof(pci_mmcfg_config[0]), cmp_mmcfg, NULL); - - /* last one*/ - if (pci_mmcfg_config_num > 0) { - i = pci_mmcfg_config_num - 1; - cfg = &pci_mmcfg_config[i]; - if (cfg->end_bus_number < cfg->start_bus_number) - cfg->end_bus_number = 255; - } - - /* don't overlap please */ - for (i = 0; i < pci_mmcfg_config_num - 1; i++) { - cfg = &pci_mmcfg_config[i]; - cfgx = &pci_mmcfg_config[i+1]; - - if (cfg->end_bus_number < cfg->start_bus_number) - cfg->end_bus_number = 255; - - if (cfg->end_bus_number >= cfgx->start_bus_number) - cfg->end_bus_number = cfgx->start_bus_number - 1; - } -} - static int __init pci_mmcfg_check_hostbridge(void) { u32 l; @@ -304,33 +186,31 @@ static int __init pci_mmcfg_check_hostbridge(void) pci_mmcfg_config_num = 0; pci_mmcfg_config = NULL; + name = NULL; - for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) { + for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) { bus = pci_mmcfg_probes[i].bus; devfn = pci_mmcfg_probes[i].devfn; raw_pci_ops->read(0, bus, devfn, 0, 4, &l); vendor = l & 0xffff; device = (l >> 16) & 0xffff; - name = NULL; if (pci_mmcfg_probes[i].vendor == vendor && pci_mmcfg_probes[i].device == device) name = pci_mmcfg_probes[i].probe(); - - if (name) - printk(KERN_INFO "PCI: Found %s with MMCONFIG support.\n", - name); } - /* some end_bus_number is crazy, fix it */ - pci_mmcfg_check_end_bus_number(); + if (name) { + printk(KERN_INFO "PCI: Found %s %s MMCONFIG support.\n", + name, pci_mmcfg_config_num ? "with" : "without"); + } - return pci_mmcfg_config_num != 0; + return name != NULL; } static void __init pci_mmcfg_insert_resources(void) { -#define PCI_MMCFG_RESOURCE_NAME_LEN 24 +#define PCI_MMCFG_RESOURCE_NAME_LEN 19 int i; struct resource *res; char *names; @@ -348,10 +228,9 @@ static void __init pci_mmcfg_insert_resources(void) struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[i]; num_buses = cfg->end_bus_number - cfg->start_bus_number + 1; res->name = names; - snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, - "PCI MMCONFIG %u [%02x-%02x]", cfg->pci_segment, - cfg->start_bus_number, cfg->end_bus_number); - res->start = cfg->address + (cfg->start_bus_number << 20); + snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u", + cfg->pci_segment); + res->start = cfg->address; res->end = res->start + (num_buses << 20) - 1; res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; insert_resource(&iomem_resource, res); @@ -475,6 +354,8 @@ static void __init pci_mmcfg_reject_broken(int early) (pci_mmcfg_config[0].address == 0)) return; + cfg = &pci_mmcfg_config[0]; + for (i = 0; i < pci_mmcfg_config_num; i++) { int valid = 0; u64 addr, size; @@ -542,10 +423,10 @@ static void __init __pci_mmcfg_init(int early) known_bridge = 1; } - if (!known_bridge) + if (!known_bridge) { acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); - - pci_mmcfg_reject_broken(early); + pci_mmcfg_reject_broken(early); + } if ((pci_mmcfg_config_num == 0) || (pci_mmcfg_config == NULL) || diff --git a/trunk/arch/x86/pci/mmconfig_64.c b/trunk/arch/x86/pci/mmconfig_64.c index 94349f8b2f96..30007ffc8e11 100644 --- a/trunk/arch/x86/pci/mmconfig_64.c +++ b/trunk/arch/x86/pci/mmconfig_64.c @@ -112,18 +112,13 @@ static struct pci_raw_ops pci_mmcfg = { static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg) { void __iomem *addr; - u64 start, size; - - start = cfg->start_bus_number; - start <<= 20; - start += cfg->address; - size = cfg->end_bus_number + 1 - cfg->start_bus_number; - size <<= 20; - addr = ioremap_nocache(start, size); + u32 size; + + size = (cfg->end_bus_number + 1) << 20; + addr = ioremap_nocache(cfg->address, size); if (addr) { printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n", - start, start + size - 1); - addr -= cfg->start_bus_number << 20; + cfg->address, cfg->address + size - 1); } return addr; } @@ -162,7 +157,7 @@ void __init pci_mmcfg_arch_free(void) for (i = 0; i < pci_mmcfg_config_num; ++i) { if (pci_mmcfg_virt[i].virt) { - iounmap(pci_mmcfg_virt[i].virt + (pci_mmcfg_virt[i].cfg->start_bus_number << 20)); + iounmap(pci_mmcfg_virt[i].virt); pci_mmcfg_virt[i].virt = NULL; pci_mmcfg_virt[i].cfg = NULL; } diff --git a/trunk/arch/x86/power/cpu_32.c b/trunk/arch/x86/power/cpu_32.c index ce702c5b3a2c..274d06082f48 100644 --- a/trunk/arch/x86/power/cpu_32.c +++ b/trunk/arch/x86/power/cpu_32.c @@ -12,7 +12,6 @@ #include #include #include -#include static struct saved_context saved_context; diff --git a/trunk/arch/x86/power/cpu_64.c b/trunk/arch/x86/power/cpu_64.c index 5343540f2607..e3b6cf70d62c 100644 --- a/trunk/arch/x86/power/cpu_64.c +++ b/trunk/arch/x86/power/cpu_64.c @@ -15,7 +15,6 @@ #include #include #include -#include static void fix_processor_context(void); diff --git a/trunk/arch/x86/power/hibernate_64.c b/trunk/arch/x86/power/hibernate_64.c index 65fdc86e923f..6dd000dd7933 100644 --- a/trunk/arch/x86/power/hibernate_64.c +++ b/trunk/arch/x86/power/hibernate_64.c @@ -14,7 +14,6 @@ #include #include #include -#include /* References to section boundaries */ extern const void __nosave_begin, __nosave_end; diff --git a/trunk/arch/x86/xen/mmu.c b/trunk/arch/x86/xen/mmu.c index db3802fb7b84..cb6afa4ec95c 100644 --- a/trunk/arch/x86/xen/mmu.c +++ b/trunk/arch/x86/xen/mmu.c @@ -1723,9 +1723,9 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, { pmd_t *kernel_pmd; - max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) + - xen_start_info->nr_pt_frames * PAGE_SIZE + - 512*1024); + init_pg_tables_start = __pa(pgd); + init_pg_tables_end = __pa(pgd) + xen_start_info->nr_pt_frames*PAGE_SIZE; + max_pfn_mapped = PFN_DOWN(init_pg_tables_end + 512*1024); kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd); memcpy(level2_kernel_pgt, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD); @@ -1870,6 +1870,7 @@ const struct pv_mmu_ops xen_mmu_ops __initdata = { #ifdef CONFIG_X86_PAE .set_pte_atomic = xen_set_pte_atomic, + .set_pte_present = xen_set_pte_at, .pte_clear = xen_pte_clear, .pmd_clear = xen_pmd_clear, #endif /* CONFIG_X86_PAE */ diff --git a/trunk/arch/xtensa/kernel/process.c b/trunk/arch/xtensa/kernel/process.c index 031f36685710..9185597eb6a0 100644 --- a/trunk/arch/xtensa/kernel/process.c +++ b/trunk/arch/xtensa/kernel/process.c @@ -172,7 +172,7 @@ void prepare_to_copy(struct task_struct *tsk) * childregs. */ -int copy_thread(unsigned long clone_flags, unsigned long usp, +int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct * p, struct pt_regs * regs) { diff --git a/trunk/arch/xtensa/platforms/iss/console.c b/trunk/arch/xtensa/platforms/iss/console.c index 4c559cf7da2d..25d46c84eb08 100644 --- a/trunk/arch/xtensa/platforms/iss/console.c +++ b/trunk/arch/xtensa/platforms/iss/console.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -177,24 +176,22 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) /* Stub, once again.. */ } -static int rs_proc_show(struct seq_file *m, void *v) +static int rs_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { - seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version); - return 0; -} + int len = 0; + off_t begin = 0; -static int rs_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, rs_proc_show, NULL); + len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); + *eof = 1; + + if (off >= len + begin) + return 0; + + *start = page + (off - begin); + return ((count < begin + len - off) ? count : begin + len - off); } -static const struct file_operations rs_proc_fops = { - .owner = THIS_MODULE, - .open = rs_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; static struct tty_operations serial_ops = { .open = rs_open, @@ -206,7 +203,7 @@ static struct tty_operations serial_ops = { .chars_in_buffer = rs_chars_in_buffer, .hangup = rs_hangup, .wait_until_sent = rs_wait_until_sent, - .proc_fops = &rs_proc_fops, + .read_proc = rs_read_proc }; int __init rs_init(void) diff --git a/trunk/drivers/acpi/ac.c b/trunk/drivers/acpi/ac.c index 88e42abf5d88..9b917dac7732 100644 --- a/trunk/drivers/acpi/ac.c +++ b/trunk/drivers/acpi/ac.c @@ -191,6 +191,7 @@ static int acpi_ac_add_fs(struct acpi_device *device) acpi_ac_dir); if (!acpi_device_dir(device)) return -ENODEV; + acpi_device_dir(device)->owner = THIS_MODULE; } /* 'state' [R] */ diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c index 3bcb5bfc45d3..69cbc57c2d1c 100644 --- a/trunk/drivers/acpi/battery.c +++ b/trunk/drivers/acpi/battery.c @@ -760,6 +760,7 @@ static int acpi_battery_add_fs(struct acpi_device *device) acpi_battery_dir); if (!acpi_device_dir(device)) return -ENODEV; + acpi_device_dir(device)->owner = THIS_MODULE; } for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { diff --git a/trunk/drivers/acpi/button.c b/trunk/drivers/acpi/button.c index c2f06069dcd4..171fd914f435 100644 --- a/trunk/drivers/acpi/button.c +++ b/trunk/drivers/acpi/button.c @@ -200,10 +200,12 @@ static int acpi_button_add_fs(struct acpi_device *device) if (!entry) return -ENODEV; + entry->owner = THIS_MODULE; acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry); if (!acpi_device_dir(device)) return -ENODEV; + acpi_device_dir(device)->owner = THIS_MODULE; /* 'info' [R] */ entry = proc_create_data(ACPI_BUTTON_FILE_INFO, @@ -520,6 +522,7 @@ static int __init acpi_button_init(void) acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); if (!acpi_button_dir) return -ENODEV; + acpi_button_dir->owner = THIS_MODULE; result = acpi_bus_register_driver(&acpi_button_driver); if (result < 0) { remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); diff --git a/trunk/drivers/acpi/fan.c b/trunk/drivers/acpi/fan.c index 8a02944bf92d..eaaee1660bdf 100644 --- a/trunk/drivers/acpi/fan.c +++ b/trunk/drivers/acpi/fan.c @@ -193,6 +193,7 @@ static int acpi_fan_add_fs(struct acpi_device *device) acpi_fan_dir); if (!acpi_device_dir(device)) return -ENODEV; + acpi_device_dir(device)->owner = THIS_MODULE; } /* 'status' [R/W] */ @@ -346,6 +347,7 @@ static int __init acpi_fan_init(void) acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir); if (!acpi_fan_dir) return -ENODEV; + acpi_fan_dir->owner = THIS_MODULE; #endif result = acpi_bus_register_driver(&acpi_fan_driver); diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index 196f97d00956..5b38a026d122 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -66,18 +66,11 @@ struct acpi_pci_root { struct acpi_device * device; struct acpi_pci_id id; struct pci_bus *bus; - - u32 osc_support_set; /* _OSC state of support bits */ - u32 osc_control_set; /* _OSC state of control bits */ - u32 osc_control_qry; /* the latest _OSC query result */ - - u32 osc_queried:1; /* has _OSC control been queried? */ }; static LIST_HEAD(acpi_pci_roots); static struct acpi_pci_driver *sub_driver; -static DEFINE_MUTEX(osc_lock); int acpi_pci_register_driver(struct acpi_pci_driver *driver) { @@ -192,175 +185,6 @@ static void acpi_pci_bridge_scan(struct acpi_device *device) } } -static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, - 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66}; - -static acpi_status acpi_pci_run_osc(acpi_handle handle, - const u32 *capbuf, u32 *retval) -{ - acpi_status status; - struct acpi_object_list input; - union acpi_object in_params[4]; - struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; - union acpi_object *out_obj; - u32 errors; - - /* Setting up input parameters */ - input.count = 4; - input.pointer = in_params; - in_params[0].type = ACPI_TYPE_BUFFER; - in_params[0].buffer.length = 16; - in_params[0].buffer.pointer = OSC_UUID; - in_params[1].type = ACPI_TYPE_INTEGER; - in_params[1].integer.value = 1; - in_params[2].type = ACPI_TYPE_INTEGER; - in_params[2].integer.value = 3; - in_params[3].type = ACPI_TYPE_BUFFER; - in_params[3].buffer.length = 12; - in_params[3].buffer.pointer = (u8 *)capbuf; - - status = acpi_evaluate_object(handle, "_OSC", &input, &output); - if (ACPI_FAILURE(status)) - return status; - - if (!output.length) - return AE_NULL_OBJECT; - - out_obj = output.pointer; - if (out_obj->type != ACPI_TYPE_BUFFER) { - printk(KERN_DEBUG "_OSC evaluation returned wrong type\n"); - status = AE_TYPE; - goto out_kfree; - } - /* Need to ignore the bit0 in result code */ - errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); - if (errors) { - if (errors & OSC_REQUEST_ERROR) - printk(KERN_DEBUG "_OSC request failed\n"); - if (errors & OSC_INVALID_UUID_ERROR) - printk(KERN_DEBUG "_OSC invalid UUID\n"); - if (errors & OSC_INVALID_REVISION_ERROR) - printk(KERN_DEBUG "_OSC invalid revision\n"); - if (errors & OSC_CAPABILITIES_MASK_ERROR) { - if (capbuf[OSC_QUERY_TYPE] & OSC_QUERY_ENABLE) - goto out_success; - printk(KERN_DEBUG - "Firmware did not grant requested _OSC control\n"); - status = AE_SUPPORT; - goto out_kfree; - } - status = AE_ERROR; - goto out_kfree; - } -out_success: - *retval = *((u32 *)(out_obj->buffer.pointer + 8)); - status = AE_OK; - -out_kfree: - kfree(output.pointer); - return status; -} - -static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags) -{ - acpi_status status; - u32 support_set, result, capbuf[3]; - - /* do _OSC query for all possible controls */ - support_set = root->osc_support_set | (flags & OSC_SUPPORT_MASKS); - capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; - capbuf[OSC_SUPPORT_TYPE] = support_set; - capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS; - - status = acpi_pci_run_osc(root->device->handle, capbuf, &result); - if (ACPI_SUCCESS(status)) { - root->osc_support_set = support_set; - root->osc_control_qry = result; - root->osc_queried = 1; - } - return status; -} - -static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) -{ - acpi_status status; - acpi_handle tmp; - - status = acpi_get_handle(root->device->handle, "_OSC", &tmp); - if (ACPI_FAILURE(status)) - return status; - mutex_lock(&osc_lock); - status = acpi_pci_query_osc(root, flags); - mutex_unlock(&osc_lock); - return status; -} - -static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) -{ - struct acpi_pci_root *root; - list_for_each_entry(root, &acpi_pci_roots, node) { - if (root->device->handle == handle) - return root; - } - return NULL; -} - -/** - * acpi_pci_osc_control_set - commit requested control to Firmware - * @handle: acpi_handle for the target ACPI object - * @flags: driver's requested control bits - * - * Attempt to take control from Firmware on requested control bits. - **/ -acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags) -{ - acpi_status status; - u32 control_req, result, capbuf[3]; - acpi_handle tmp; - struct acpi_pci_root *root; - - status = acpi_get_handle(handle, "_OSC", &tmp); - if (ACPI_FAILURE(status)) - return status; - - control_req = (flags & OSC_CONTROL_MASKS); - if (!control_req) - return AE_TYPE; - - root = acpi_pci_find_root(handle); - if (!root) - return AE_NOT_EXIST; - - mutex_lock(&osc_lock); - /* No need to evaluate _OSC if the control was already granted. */ - if ((root->osc_control_set & control_req) == control_req) - goto out; - - /* Need to query controls first before requesting them */ - if (!root->osc_queried) { - status = acpi_pci_query_osc(root, root->osc_support_set); - if (ACPI_FAILURE(status)) - goto out; - } - if ((root->osc_control_qry & control_req) != control_req) { - printk(KERN_DEBUG - "Firmware did not grant requested _OSC control\n"); - status = AE_SUPPORT; - goto out; - } - - capbuf[OSC_QUERY_TYPE] = 0; - capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set; - capbuf[OSC_CONTROL_TYPE] = root->osc_control_set | control_req; - status = acpi_pci_run_osc(handle, capbuf, &result); - if (ACPI_SUCCESS(status)) - root->osc_control_set = result; -out: - mutex_unlock(&osc_lock); - return status; -} -EXPORT_SYMBOL(acpi_pci_osc_control_set); - static int __devinit acpi_pci_root_add(struct acpi_device *device) { int result = 0; @@ -393,7 +217,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) * PCI domains, so we indicate this in _OSC support capabilities. */ flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; - acpi_pci_osc_support(root, flags); + pci_acpi_osc_support(device->handle, flags); /* * Segment @@ -529,7 +353,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) if (pci_msi_enabled()) flags |= OSC_MSI_SUPPORT; if (flags != base_flags) - acpi_pci_osc_support(root, flags); + pci_acpi_osc_support(device->handle, flags); end: if (result) { diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index fa2f7422d23d..0cc2fd31e376 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -359,6 +359,7 @@ static int acpi_processor_add_fs(struct acpi_device *device) if (!acpi_device_dir(device)) return -ENODEV; } + acpi_device_dir(device)->owner = THIS_MODULE; /* 'info' [R] */ entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO, @@ -1136,6 +1137,7 @@ static int __init acpi_processor_init(void) acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); if (!acpi_processor_dir) return -ENOMEM; + acpi_processor_dir->owner = THIS_MODULE; /* * Check whether the system is DMI table. If yes, OSPM diff --git a/trunk/drivers/acpi/sbs.c b/trunk/drivers/acpi/sbs.c index 59afd52ccc12..6050ce481873 100644 --- a/trunk/drivers/acpi/sbs.c +++ b/trunk/drivers/acpi/sbs.c @@ -488,6 +488,7 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir, if (!*dir) { return -ENODEV; } + (*dir)->owner = THIS_MODULE; } /* 'info' [R] */ diff --git a/trunk/drivers/acpi/thermal.c b/trunk/drivers/acpi/thermal.c index c11f9aeca706..99e6f1f8ea45 100644 --- a/trunk/drivers/acpi/thermal.c +++ b/trunk/drivers/acpi/thermal.c @@ -1506,6 +1506,7 @@ static int acpi_thermal_add_fs(struct acpi_device *device) acpi_thermal_dir); if (!acpi_device_dir(device)) return -ENODEV; + acpi_device_dir(device)->owner = THIS_MODULE; } /* 'state' [R] */ @@ -1874,6 +1875,7 @@ static int __init acpi_thermal_init(void) acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); if (!acpi_thermal_dir) return -ENODEV; + acpi_thermal_dir->owner = THIS_MODULE; result = acpi_bus_register_driver(&acpi_thermal_driver); if (result < 0) { diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 67cc36dc9b82..bb5ed059114a 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -1125,6 +1125,8 @@ static int acpi_video_device_add_fs(struct acpi_device *device) if (!device_dir) return -ENOMEM; + device_dir->owner = THIS_MODULE; + /* 'info' [R] */ entry = proc_create_data("info", S_IRUGO, device_dir, &acpi_video_device_info_fops, acpi_driver_data(device)); @@ -1401,6 +1403,8 @@ static int acpi_video_bus_add_fs(struct acpi_device *device) if (!device_dir) return -ENOMEM; + device_dir->owner = THIS_MODULE; + /* 'info' [R] */ entry = proc_create_data("info", S_IRUGO, device_dir, &acpi_video_bus_info_fops, @@ -2127,6 +2131,7 @@ static int __init acpi_video_init(void) acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); if (!acpi_video_dir) return -ENODEV; + acpi_video_dir->owner = THIS_MODULE; result = acpi_bus_register_driver(&acpi_video_bus); if (result < 0) { diff --git a/trunk/drivers/auxdisplay/Kconfig b/trunk/drivers/auxdisplay/Kconfig index c07e725ea93d..14b9d5f4c203 100644 --- a/trunk/drivers/auxdisplay/Kconfig +++ b/trunk/drivers/auxdisplay/Kconfig @@ -6,6 +6,7 @@ # menuconfig AUXDISPLAY + depends on PARPORT bool "Auxiliary Display support" ---help--- Say Y here to get to see options for auxiliary display drivers. @@ -13,7 +14,7 @@ menuconfig AUXDISPLAY If you say N, all options in this submenu will be skipped and disabled. -if AUXDISPLAY +if AUXDISPLAY && PARPORT config KS0108 tristate "KS0108 LCD Controller" diff --git a/trunk/drivers/base/cpu.c b/trunk/drivers/base/cpu.c index e62a4ccea54d..5b257a57bc57 100644 --- a/trunk/drivers/base/cpu.c +++ b/trunk/drivers/base/cpu.c @@ -119,7 +119,7 @@ static ssize_t print_cpus_map(char *buf, const struct cpumask *map) #define print_cpus_func(type) \ static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf) \ { \ - return print_cpus_map(buf, cpu_##type##_mask); \ + return print_cpus_map(buf, &cpu_##type##_map); \ } \ static struct sysdev_class_attribute attr_##type##_map = \ _SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL) diff --git a/trunk/drivers/base/iommu.c b/trunk/drivers/base/iommu.c index c2d1eed90376..5e039d4f877c 100644 --- a/trunk/drivers/base/iommu.c +++ b/trunk/drivers/base/iommu.c @@ -31,7 +31,7 @@ void register_iommu(struct iommu_ops *ops) iommu_ops = ops; } -bool iommu_found(void) +bool iommu_found() { return iommu_ops != NULL; } diff --git a/trunk/drivers/base/power/main.c b/trunk/drivers/base/power/main.c index 69b4ddb7de3b..e255341682c8 100644 --- a/trunk/drivers/base/power/main.c +++ b/trunk/drivers/base/power/main.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "../base.h" #include "power.h" @@ -350,8 +349,7 @@ static int resume_device_noirq(struct device *dev, pm_message_t state) * Execute the appropriate "noirq resume" callback for all devices marked * as DPM_OFF_IRQ. * - * Must be called under dpm_list_mtx. Device drivers should not receive - * interrupts while it's being executed. + * Must be called with interrupts disabled and only one CPU running. */ static void dpm_power_up(pm_message_t state) { @@ -372,13 +370,14 @@ static void dpm_power_up(pm_message_t state) * device_power_up - Turn on all devices that need special attention. * @state: PM transition of the system being carried out. * - * Call the "early" resume handlers and enable device drivers to receive - * interrupts. + * Power on system devices, then devices that required we shut them down + * with interrupts disabled. + * + * Must be called with interrupts disabled. */ void device_power_up(pm_message_t state) { dpm_power_up(state); - resume_device_irqs(); } EXPORT_SYMBOL_GPL(device_power_up); @@ -603,17 +602,16 @@ static int suspend_device_noirq(struct device *dev, pm_message_t state) * device_power_down - Shut down special devices. * @state: PM transition of the system being carried out. * - * Prevent device drivers from receiving interrupts and call the "late" - * suspend handlers. + * Power down devices that require interrupts to be disabled. + * Then power down system devices. * - * Must be called under dpm_list_mtx. + * Must be called with interrupts disabled and only one CPU running. */ int device_power_down(pm_message_t state) { struct device *dev; int error = 0; - suspend_device_irqs(); list_for_each_entry_reverse(dev, &dpm_list, power.entry) { error = suspend_device_noirq(dev, state); if (error) { @@ -623,7 +621,7 @@ int device_power_down(pm_message_t state) dev->power.status = DPM_OFF_IRQ; } if (error) - device_power_up(resume_event(state)); + dpm_power_up(resume_event(state)); return error; } EXPORT_SYMBOL_GPL(device_power_down); diff --git a/trunk/drivers/base/sys.c b/trunk/drivers/base/sys.c index 76ce75bad91e..cbd36cf59a0f 100644 --- a/trunk/drivers/base/sys.c +++ b/trunk/drivers/base/sys.c @@ -22,7 +22,6 @@ #include #include #include -#include #include "base.h" @@ -370,13 +369,6 @@ int sysdev_suspend(pm_message_t state) struct sysdev_driver *drv, *err_drv; int ret; - pr_debug("Checking wake-up interrupts\n"); - - /* Return error code if there are any wake-up interrupts pending */ - ret = check_wakeup_irqs(); - if (ret) - return ret; - pr_debug("Suspending System Devices\n"); list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 1300df6f1642..c2c95e614506 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -177,7 +177,6 @@ static int print_unex = 1; #include #include #include -#include #include /* for invalidate_buffers() */ #include @@ -4598,13 +4597,6 @@ MODULE_AUTHOR("Alain L. Knaff"); MODULE_SUPPORTED_DEVICE("fd"); MODULE_LICENSE("GPL"); -/* This doesn't actually get used other than for module information */ -static const struct pnp_device_id floppy_pnpids[] = { - { "PNP0700", 0 }, - { } -}; -MODULE_DEVICE_TABLE(pnp, floppy_pnpids); - #else __setup("floppy=", floppy_setup); diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index 40b17d3b55a1..2621ed2ce6d2 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -1192,30 +1192,6 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) { return err; } -static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev) -{ - int err; - sector_t sec; - loff_t sz; - - err = -ENXIO; - if (unlikely(lo->lo_state != Lo_bound)) - goto out; - err = figure_loop_size(lo); - if (unlikely(err)) - goto out; - sec = get_capacity(lo->lo_disk); - /* the width of sector_t may be narrow for bit-shift */ - sz = sec; - sz <<= 9; - mutex_lock(&bdev->bd_mutex); - bd_set_size(bdev, sz); - mutex_unlock(&bdev->bd_mutex); - - out: - return err; -} - static int lo_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { @@ -1248,11 +1224,6 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, case LOOP_GET_STATUS64: err = loop_get_status64(lo, (struct loop_info64 __user *) arg); break; - case LOOP_SET_CAPACITY: - err = -EPERM; - if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) - err = loop_set_capacity(lo, bdev); - break; default: err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; } @@ -1400,7 +1371,6 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, lo, (struct compat_loop_info __user *) arg); mutex_unlock(&lo->lo_ctl_mutex); break; - case LOOP_SET_CAPACITY: case LOOP_CLR_FD: case LOOP_GET_STATUS64: case LOOP_SET_STATUS64: diff --git a/trunk/drivers/block/nbd.c b/trunk/drivers/block/nbd.c index 4d6de4f15ccb..8299e2d3b611 100644 --- a/trunk/drivers/block/nbd.c +++ b/trunk/drivers/block/nbd.c @@ -4,7 +4,7 @@ * Note that you can not swap over this thing, yet. Seems to work but * deadlocks sometimes - you can not swap over TCP in general. * - * Copyright 1997-2000, 2008 Pavel Machek + * Copyright 1997-2000 Pavel Machek * Parts copyright 2001 Steven Whitehouse * * This file is released under GPLv2 or later. @@ -276,7 +276,7 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req) return 0; error_out: - return -EIO; + return 1; } static struct request *nbd_find_request(struct nbd_device *lo, @@ -467,7 +467,9 @@ static void nbd_handle_req(struct nbd_device *lo, struct request *req) mutex_unlock(&lo->tx_lock); printk(KERN_ERR "%s: Attempted send on closed socket\n", lo->disk->disk_name); - goto error_out; + req->errors++; + nbd_end_request(req); + return; } lo->active_req = req; @@ -529,7 +531,7 @@ static int nbd_thread(void *data) * { printk( "Warning: Ignoring result!\n"); nbd_end_request( req ); } */ -static void do_nbd_request(struct request_queue *q) +static void do_nbd_request(struct request_queue * q) { struct request *req; @@ -566,17 +568,27 @@ static void do_nbd_request(struct request_queue *q) } } -/* Must be called with tx_lock held */ - -static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo, - unsigned int cmd, unsigned long arg) +static int nbd_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) { - switch (cmd) { - case NBD_DISCONNECT: { - struct request sreq; + struct nbd_device *lo = bdev->bd_disk->private_data; + struct file *file; + int error; + struct request sreq ; + struct task_struct *thread; - printk(KERN_INFO "%s: NBD_DISCONNECT\n", lo->disk->disk_name); + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + BUG_ON(lo->magic != LO_MAGIC); + /* Anyone capable of this syscall can do *real bad* things */ + dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n", + lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg); + + switch (cmd) { + case NBD_DISCONNECT: + printk(KERN_INFO "%s: NBD_DISCONNECT\n", lo->disk->disk_name); blk_rq_init(NULL, &sreq); sreq.cmd_type = REQ_TYPE_SPECIAL; nbd_cmd(&sreq) = NBD_CMD_DISC; @@ -587,29 +599,29 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo, */ sreq.sector = 0; sreq.nr_sectors = 0; - if (!lo->sock) + if (!lo->sock) return -EINVAL; - nbd_send_req(lo, &sreq); + mutex_lock(&lo->tx_lock); + nbd_send_req(lo, &sreq); + mutex_unlock(&lo->tx_lock); return 0; - } - case NBD_CLEAR_SOCK: { - struct file *file; - + case NBD_CLEAR_SOCK: + error = 0; + mutex_lock(&lo->tx_lock); lo->sock = NULL; + mutex_unlock(&lo->tx_lock); file = lo->file; lo->file = NULL; nbd_clear_que(lo); BUG_ON(!list_empty(&lo->queue_head)); if (file) fput(file); - return 0; - } - - case NBD_SET_SOCK: { - struct file *file; + return error; + case NBD_SET_SOCK: if (lo->file) return -EBUSY; + error = -EINVAL; file = fget(arg); if (file) { struct inode *inode = file->f_path.dentry->d_inode; @@ -618,14 +630,12 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo, lo->sock = SOCKET_I(inode); if (max_part > 0) bdev->bd_invalidated = 1; - return 0; + error = 0; } else { fput(file); } } - return -EINVAL; - } - + return error; case NBD_SET_BLKSIZE: lo->blksize = arg; lo->bytesize &= ~(lo->blksize-1); @@ -633,50 +643,35 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo, set_blocksize(bdev, lo->blksize); set_capacity(lo->disk, lo->bytesize >> 9); return 0; - case NBD_SET_SIZE: lo->bytesize = arg & ~(lo->blksize-1); bdev->bd_inode->i_size = lo->bytesize; set_blocksize(bdev, lo->blksize); set_capacity(lo->disk, lo->bytesize >> 9); return 0; - case NBD_SET_TIMEOUT: lo->xmit_timeout = arg * HZ; return 0; - case NBD_SET_SIZE_BLOCKS: lo->bytesize = ((u64) arg) * lo->blksize; bdev->bd_inode->i_size = lo->bytesize; set_blocksize(bdev, lo->blksize); set_capacity(lo->disk, lo->bytesize >> 9); return 0; - - case NBD_DO_IT: { - struct task_struct *thread; - struct file *file; - int error; - + case NBD_DO_IT: if (lo->pid) return -EBUSY; if (!lo->file) return -EINVAL; - - mutex_unlock(&lo->tx_lock); - thread = kthread_create(nbd_thread, lo, lo->disk->disk_name); - if (IS_ERR(thread)) { - mutex_lock(&lo->tx_lock); + if (IS_ERR(thread)) return PTR_ERR(thread); - } wake_up_process(thread); error = nbd_do_it(lo); kthread_stop(thread); - - mutex_lock(&lo->tx_lock); if (error) return error; - sock_shutdown(lo, 0); + sock_shutdown(lo, 1); file = lo->file; lo->file = NULL; nbd_clear_que(lo); @@ -689,8 +684,6 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo, if (max_part > 0) ioctl_by_bdev(bdev, BLKRRPART, 0); return lo->harderror; - } - case NBD_CLEAR_QUE: /* * This is for compatibility only. The queue is always cleared @@ -698,7 +691,6 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo, */ BUG_ON(!lo->sock && !list_empty(&lo->queue_head)); return 0; - case NBD_PRINT_DEBUG: printk(KERN_INFO "%s: next = %p, prev = %p, head = %p\n", bdev->bd_disk->disk_name, @@ -706,29 +698,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo, &lo->queue_head); return 0; } - return -ENOTTY; -} - -static int nbd_ioctl(struct block_device *bdev, fmode_t mode, - unsigned int cmd, unsigned long arg) -{ - struct nbd_device *lo = bdev->bd_disk->private_data; - int error; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - BUG_ON(lo->magic != LO_MAGIC); - - /* Anyone capable of this syscall can do *real bad* things */ - dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n", - lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg); - - mutex_lock(&lo->tx_lock); - error = __nbd_ioctl(bdev, lo, cmd, arg); - mutex_unlock(&lo->tx_lock); - - return error; + return -EINVAL; } static struct block_device_operations nbd_fops = diff --git a/trunk/drivers/block/ps3vram.c b/trunk/drivers/block/ps3vram.c index 8eddef373a91..393ed6760d78 100644 --- a/trunk/drivers/block/ps3vram.c +++ b/trunk/drivers/block/ps3vram.c @@ -551,6 +551,8 @@ static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev) dev_warn(&dev->core, "failed to create /proc entry\n"); return; } + + pde->owner = THIS_MODULE; pde->data = priv; } diff --git a/trunk/drivers/char/amiserial.c b/trunk/drivers/char/amiserial.c index fd3ebd1be570..a58869ea8513 100644 --- a/trunk/drivers/char/amiserial.c +++ b/trunk/drivers/char/amiserial.c @@ -79,7 +79,6 @@ static char *serial_version = "4.30"; #include #include #include -#include #include #include #include @@ -1826,13 +1825,14 @@ static int rs_open(struct tty_struct *tty, struct file * filp) * /proc fs routines.... */ -static inline void line_info(struct seq_file *m, struct serial_state *state) +static inline int line_info(char *buf, struct serial_state *state) { struct async_struct *info = state->info, scr_info; char stat_buf[30], control, status; + int ret; unsigned long flags; - seq_printf(m, "%d: uart:amiga_builtin",state->line); + ret = sprintf(buf, "%d: uart:amiga_builtin",state->line); /* * Figure out the current RS-232 lines @@ -1864,49 +1864,55 @@ static inline void line_info(struct seq_file *m, struct serial_state *state) strcat(stat_buf, "|CD"); if (info->quot) { - seq_printf(m, " baud:%d", state->baud_base / info->quot); + ret += sprintf(buf+ret, " baud:%d", + state->baud_base / info->quot); } - seq_printf(m, " tx:%d rx:%d", state->icount.tx, state->icount.rx); + ret += sprintf(buf+ret, " tx:%d rx:%d", + state->icount.tx, state->icount.rx); if (state->icount.frame) - seq_printf(m, " fe:%d", state->icount.frame); + ret += sprintf(buf+ret, " fe:%d", state->icount.frame); if (state->icount.parity) - seq_printf(m, " pe:%d", state->icount.parity); + ret += sprintf(buf+ret, " pe:%d", state->icount.parity); if (state->icount.brk) - seq_printf(m, " brk:%d", state->icount.brk); + ret += sprintf(buf+ret, " brk:%d", state->icount.brk); if (state->icount.overrun) - seq_printf(m, " oe:%d", state->icount.overrun); + ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); /* * Last thing is the RS-232 status lines */ - seq_printf(m, " %s\n", stat_buf+1); -} - -static int rs_proc_show(struct seq_file *m, void *v) -{ - seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version); - line_info(m, &rs_table[0]); - return 0; + ret += sprintf(buf+ret, " %s\n", stat_buf+1); + return ret; } -static int rs_proc_open(struct inode *inode, struct file *file) +static int rs_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { - return single_open(file, rs_proc_show, NULL); + int len = 0, l; + off_t begin = 0; + + len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); + l = line_info(page + len, &rs_table[0]); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); } -static const struct file_operations rs_proc_fops = { - .owner = THIS_MODULE, - .open = rs_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /* * --------------------------------------------------------------------- * rs_init() and friends @@ -1945,9 +1951,9 @@ static const struct tty_operations serial_ops = { .break_ctl = rs_break, .send_xchar = rs_send_xchar, .wait_until_sent = rs_wait_until_sent, + .read_proc = rs_read_proc, .tiocmget = rs_tiocmget, .tiocmset = rs_tiocmset, - .proc_fops = &rs_proc_fops, }; /* diff --git a/trunk/drivers/char/cyclades.c b/trunk/drivers/char/cyclades.c index 272db0e2b491..6a59f72a9c21 100644 --- a/trunk/drivers/char/cyclades.c +++ b/trunk/drivers/char/cyclades.c @@ -657,7 +657,6 @@ #include #include -#include static void cy_throttle(struct tty_struct *tty); static void cy_send_xchar(struct tty_struct *tty, char ch); @@ -869,6 +868,8 @@ static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32); static unsigned detect_isa_irq(void __iomem *); #endif /* CONFIG_ISA */ +static int cyclades_get_proc_info(char *, char **, off_t, int, int *, void *); + #ifndef CONFIG_CYZ_INTR static void cyz_poll(unsigned long); @@ -5215,22 +5216,31 @@ static struct pci_driver cy_pci_driver = { }; #endif -static int cyclades_proc_show(struct seq_file *m, void *v) +static int +cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, + int *eof, void *data) { struct cyclades_port *info; unsigned int i, j; + int len = 0; + off_t begin = 0; + off_t pos = 0; + int size; __u32 cur_jifs = jiffies; - seq_puts(m, "Dev TimeOpen BytesOut IdleOut BytesIn " + size = sprintf(buf, "Dev TimeOpen BytesOut IdleOut BytesIn " "IdleIn Overruns Ldisc\n"); + pos += size; + len += size; + /* Output one line for each known port */ for (i = 0; i < NR_CARDS; i++) for (j = 0; j < cy_card[i].nports; j++) { info = &cy_card[i].ports[j]; if (info->port.count) - seq_printf(m, "%3d %8lu %10lu %8lu " + size = sprintf(buf + len, "%3d %8lu %10lu %8lu " "%10lu %8lu %9lu %6ld\n", info->line, (cur_jifs - info->idle_stats.in_use) / HZ, info->idle_stats.xmit_bytes, @@ -5241,26 +5251,30 @@ static int cyclades_proc_show(struct seq_file *m, void *v) /* FIXME: double check locking */ (long)info->port.tty->ldisc.ops->num); else - seq_printf(m, "%3d %8lu %10lu %8lu " + size = sprintf(buf + len, "%3d %8lu %10lu %8lu " "%10lu %8lu %9lu %6ld\n", info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L); - } - return 0; -} + len += size; + pos = begin + len; -static int cyclades_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, cyclades_proc_show, NULL); + if (pos < offset) { + len = 0; + begin = pos; + } + if (pos > offset + length) + goto done; + } + *eof = 1; +done: + *start = buf + (offset - begin); /* Start of wanted data */ + len -= (offset - begin); /* Start slop */ + if (len > length) + len = length; /* Ending slop */ + if (len < 0) + len = 0; + return len; } -static const struct file_operations cyclades_proc_fops = { - .owner = THIS_MODULE, - .open = cyclades_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /* The serial driver boot-time initialization code! Hardware I/O ports are mapped to character special devices on a first found, first allocated manner. That is, this code searches @@ -5297,9 +5311,9 @@ static const struct tty_operations cy_ops = { .hangup = cy_hangup, .break_ctl = cy_break, .wait_until_sent = cy_wait_until_sent, + .read_proc = cyclades_get_proc_info, .tiocmget = cy_tiocmget, .tiocmset = cy_tiocmset, - .proc_fops = &cyclades_proc_fops, }; static int __init cy_init(void) diff --git a/trunk/drivers/char/hpet.c b/trunk/drivers/char/hpet.c index 50dfa3bc71ce..32b8bbf5003e 100644 --- a/trunk/drivers/char/hpet.c +++ b/trunk/drivers/char/hpet.c @@ -713,7 +713,7 @@ static struct ctl_table_header *sysctl_header; */ #define TICK_CALIBRATE (1000UL) -static unsigned long __hpet_calibrate(struct hpets *hpetp) +static unsigned long hpet_calibrate(struct hpets *hpetp) { struct hpet_timer __iomem *timer = NULL; unsigned long t, m, count, i, flags, start; @@ -750,26 +750,6 @@ static unsigned long __hpet_calibrate(struct hpets *hpetp) return (m - start) / i; } -static unsigned long hpet_calibrate(struct hpets *hpetp) -{ - unsigned long ret = -1; - unsigned long tmp; - - /* - * Try to calibrate until return value becomes stable small value. - * If SMI interruption occurs in calibration loop, the return value - * will be big. This avoids its impact. - */ - for ( ; ; ) { - tmp = __hpet_calibrate(hpetp); - if (ret <= tmp) - break; - ret = tmp; - } - - return ret; -} - int hpet_alloc(struct hpet_data *hdp) { u64 cap, mcfg; diff --git a/trunk/drivers/char/ip2/ip2main.c b/trunk/drivers/char/ip2/ip2main.c index afd9247cf082..70e0ebc30bd0 100644 --- a/trunk/drivers/char/ip2/ip2main.c +++ b/trunk/drivers/char/ip2/ip2main.c @@ -139,7 +139,7 @@ #include static const struct file_operations ip2mem_proc_fops; -static const struct file_operations ip2_proc_fops; +static int ip2_read_proc(char *, char **, off_t, int, int *, void * ); /********************/ /* Type Definitions */ @@ -446,9 +446,9 @@ static const struct tty_operations ip2_ops = { .stop = ip2_stop, .start = ip2_start, .hangup = ip2_hangup, + .read_proc = ip2_read_proc, .tiocmget = ip2_tiocmget, .tiocmset = ip2_tiocmset, - .proc_fops = &ip2_proc_fops, }; /******************************************************************************/ @@ -3029,17 +3029,19 @@ static const struct file_operations ip2mem_proc_fops = { * different sources including ip2mkdev.c and a couple of other drivers. * The bugs are all mine. :-) =mhw= */ -static int ip2_proc_show(struct seq_file *m, void *v) +static int ip2_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { int i, j, box; + int len = 0; int boxes = 0; int ports = 0; int tports = 0; + off_t begin = 0; i2eBordStrPtr pB; - char *sep; - seq_printf(m, "ip2info: 1.0 driver: %s\n", pcVersion); - seq_printf(m, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n", + len += sprintf(page, "ip2info: 1.0 driver: %s\n", pcVersion ); + len += sprintf(page+len, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n", IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR, IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX); @@ -3051,8 +3053,7 @@ static int ip2_proc_show(struct seq_file *m, void *v) switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) { case POR_ID_FIIEX: - seq_printf(m, "Board %d: EX ports=", i); - sep = ""; + len += sprintf( page+len, "Board %d: EX ports=", i ); for( box = 0; box < ABS_MAX_BOXES; ++box ) { ports = 0; @@ -3064,74 +3065,79 @@ static int ip2_proc_show(struct seq_file *m, void *v) ++ports; } } - seq_printf(m, "%s%d", sep, ports); - sep = ","; + len += sprintf( page+len, "%d,", ports ); tports += ports; } - seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8); + + --len; /* Backup over that last comma */ + + len += sprintf( page+len, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8 ); break; case POR_ID_II_4: - seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i); + len += sprintf(page+len, "Board %d: ISA-4 ports=4 boxes=1", i ); tports = ports = 4; break; case POR_ID_II_8: - seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i); + len += sprintf(page+len, "Board %d: ISA-8-std ports=8 boxes=1", i ); tports = ports = 8; break; case POR_ID_II_8R: - seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i); + len += sprintf(page+len, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i ); tports = ports = 8; break; default: - seq_printf(m, "Board %d: unknown", i); + len += sprintf(page+len, "Board %d: unknown", i ); /* Don't try and probe for minor numbers */ tports = ports = 0; } } else { /* Don't try and probe for minor numbers */ - seq_printf(m, "Board %d: vacant", i); + len += sprintf(page+len, "Board %d: vacant", i ); tports = ports = 0; } if( tports ) { - seq_puts(m, " minors="); - sep = ""; + len += sprintf(page+len, " minors=" ); + for ( box = 0; box < ABS_MAX_BOXES; ++box ) { for ( j = 0; j < ABS_BIGGEST_BOX; ++j ) { if ( pB->i2eChannelMap[box] & (1 << j) ) { - seq_printf(m, "%s%d", sep, + len += sprintf (page+len,"%d,", j + ABS_BIGGEST_BOX * (box+i*ABS_MAX_BOXES)); - sep = ","; } } } + + page[ len - 1 ] = '\n'; /* Overwrite that last comma */ + } else { + len += sprintf (page+len,"\n" ); + } + + if (len+begin > off+count) + break; + if (len+begin < off) { + begin += len; + len = 0; } - seq_putc(m, '\n'); } - return 0; - } -static int ip2_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, ip2_proc_show, NULL); -} + if (i >= IP2_MAX_BOARDS) + *eof = 1; + if (off >= len+begin) + return 0; -static const struct file_operations ip2_proc_fops = { - .owner = THIS_MODULE, - .open = ip2_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); + } /******************************************************************************/ /* Function: ip2trace() */ diff --git a/trunk/drivers/char/ipmi/ipmi_msghandler.c b/trunk/drivers/char/ipmi/ipmi_msghandler.c index e93fc8d22fb2..7a88dfd4427b 100644 --- a/trunk/drivers/char/ipmi/ipmi_msghandler.c +++ b/trunk/drivers/char/ipmi/ipmi_msghandler.c @@ -1944,7 +1944,7 @@ static int stat_file_read_proc(char *page, char **start, off_t off, int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, read_proc_t *read_proc, - void *data) + void *data, struct module *owner) { int rv = 0; #ifdef CONFIG_PROC_FS @@ -1970,6 +1970,7 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, } else { file->data = data; file->read_proc = read_proc; + file->owner = owner; mutex_lock(&smi->proc_entry_lock); /* Stick it on the list. */ @@ -1992,21 +1993,23 @@ static int add_proc_entries(ipmi_smi_t smi, int num) smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root); if (!smi->proc_dir) rv = -ENOMEM; + else + smi->proc_dir->owner = THIS_MODULE; if (rv == 0) rv = ipmi_smi_add_proc_entry(smi, "stats", stat_file_read_proc, - smi); + smi, THIS_MODULE); if (rv == 0) rv = ipmi_smi_add_proc_entry(smi, "ipmb", ipmb_file_read_proc, - smi); + smi, THIS_MODULE); if (rv == 0) rv = ipmi_smi_add_proc_entry(smi, "version", version_file_read_proc, - smi); + smi, THIS_MODULE); #endif /* CONFIG_PROC_FS */ return rv; @@ -4262,6 +4265,7 @@ static int ipmi_init_msghandler(void) return -ENOMEM; } + proc_ipmi_root->owner = THIS_MODULE; #endif /* CONFIG_PROC_FS */ setup_timer(&ipmi_timer, ipmi_timeout, 0); diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index e58ea4cd55ce..3000135f2ead 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -2899,7 +2899,7 @@ static int try_smi_init(struct smi_info *new_smi) rv = ipmi_smi_add_proc_entry(new_smi->intf, "type", type_file_read_proc, - new_smi); + new_smi, THIS_MODULE); if (rv) { printk(KERN_ERR "ipmi_si: Unable to create proc entry: %d\n", @@ -2909,7 +2909,7 @@ static int try_smi_init(struct smi_info *new_smi) rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats", stat_file_read_proc, - new_smi); + new_smi, THIS_MODULE); if (rv) { printk(KERN_ERR "ipmi_si: Unable to create proc entry: %d\n", @@ -2919,7 +2919,7 @@ static int try_smi_init(struct smi_info *new_smi) rv = ipmi_smi_add_proc_entry(new_smi->intf, "params", param_read_proc, - new_smi); + new_smi, THIS_MODULE); if (rv) { printk(KERN_ERR "ipmi_si: Unable to create proc entry: %d\n", diff --git a/trunk/drivers/char/istallion.c b/trunk/drivers/char/istallion.c index fff19f7e29d2..5c3dc6b8411c 100644 --- a/trunk/drivers/char/istallion.c +++ b/trunk/drivers/char/istallion.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -614,6 +613,7 @@ static int stli_breakctl(struct tty_struct *tty, int state); static void stli_waituntilsent(struct tty_struct *tty, int timeout); static void stli_sendxchar(struct tty_struct *tty, char ch); static void stli_hangup(struct tty_struct *tty); +static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos); static int stli_brdinit(struct stlibrd *brdp); static int stli_startbrd(struct stlibrd *brdp); @@ -1893,10 +1893,20 @@ static void stli_sendxchar(struct tty_struct *tty, char ch) stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); } -static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stliport *portp, int portnr) +/*****************************************************************************/ + +#define MAXLINE 80 + +/* + * Format info for a specified port. The line is deliberately limited + * to 80 characters. (If it is too long it will be truncated, if too + * short then padded with spaces). + */ + +static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos) { - char *uart; - int rc; + char *sp, *uart; + int rc, cnt; rc = stli_portcmdstats(NULL, portp); @@ -1908,50 +1918,44 @@ static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stlip default:uart = "CD1400"; break; } } - seq_printf(m, "%d: uart:%s ", portnr, uart); - if ((brdp->state & BST_STARTED) && (rc >= 0)) { - char sep; + sp = pos; + sp += sprintf(sp, "%d: uart:%s ", portnr, uart); - seq_printf(m, "tx:%d rx:%d", (int) stli_comstats.txtotal, + if ((brdp->state & BST_STARTED) && (rc >= 0)) { + sp += sprintf(sp, "tx:%d rx:%d", (int) stli_comstats.txtotal, (int) stli_comstats.rxtotal); if (stli_comstats.rxframing) - seq_printf(m, " fe:%d", + sp += sprintf(sp, " fe:%d", (int) stli_comstats.rxframing); if (stli_comstats.rxparity) - seq_printf(m, " pe:%d", + sp += sprintf(sp, " pe:%d", (int) stli_comstats.rxparity); if (stli_comstats.rxbreaks) - seq_printf(m, " brk:%d", + sp += sprintf(sp, " brk:%d", (int) stli_comstats.rxbreaks); if (stli_comstats.rxoverrun) - seq_printf(m, " oe:%d", + sp += sprintf(sp, " oe:%d", (int) stli_comstats.rxoverrun); - sep = ' '; - if (stli_comstats.signals & TIOCM_RTS) { - seq_printf(m, "%c%s", sep, "RTS"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_CTS) { - seq_printf(m, "%c%s", sep, "CTS"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_DTR) { - seq_printf(m, "%c%s", sep, "DTR"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_CD) { - seq_printf(m, "%c%s", sep, "DCD"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_DSR) { - seq_printf(m, "%c%s", sep, "DSR"); - sep = '|'; - } + cnt = sprintf(sp, "%s%s%s%s%s ", + (stli_comstats.signals & TIOCM_RTS) ? "|RTS" : "", + (stli_comstats.signals & TIOCM_CTS) ? "|CTS" : "", + (stli_comstats.signals & TIOCM_DTR) ? "|DTR" : "", + (stli_comstats.signals & TIOCM_CD) ? "|DCD" : "", + (stli_comstats.signals & TIOCM_DSR) ? "|DSR" : ""); + *sp = ' '; + sp += cnt; } - seq_putc(m, '\n'); + + for (cnt = (sp - pos); (cnt < (MAXLINE - 1)); cnt++) + *sp++ = ' '; + if (cnt >= MAXLINE) + pos[(MAXLINE - 2)] = '+'; + pos[(MAXLINE - 1)] = '\n'; + + return(MAXLINE); } /*****************************************************************************/ @@ -1960,15 +1964,26 @@ static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stlip * Port info, read from the /proc file system. */ -static int stli_proc_show(struct seq_file *m, void *v) +static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) { struct stlibrd *brdp; struct stliport *portp; unsigned int brdnr, portnr, totalport; + int curoff, maxoff; + char *pos; + pos = page; totalport = 0; - - seq_printf(m, "%s: version %s\n", stli_drvtitle, stli_drvversion); + curoff = 0; + + if (off == 0) { + pos += sprintf(pos, "%s: version %s", stli_drvtitle, + stli_drvversion); + while (pos < (page + MAXLINE - 1)) + *pos++ = ' '; + *pos++ = '\n'; + } + curoff = MAXLINE; /* * We scan through for each board, panel and port. The offset is @@ -1981,30 +1996,32 @@ static int stli_proc_show(struct seq_file *m, void *v) if (brdp->state == 0) continue; + maxoff = curoff + (brdp->nrports * MAXLINE); + if (off >= maxoff) { + curoff = maxoff; + continue; + } + totalport = brdnr * STL_MAXPORTS; for (portnr = 0; (portnr < brdp->nrports); portnr++, totalport++) { portp = brdp->ports[portnr]; if (portp == NULL) continue; - stli_portinfo(m, brdp, portp, totalport); + if (off >= (curoff += MAXLINE)) + continue; + if ((pos - page + MAXLINE) > count) + goto stli_readdone; + pos += stli_portinfo(brdp, portp, totalport, pos); } } - return 0; -} -static int stli_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, stli_proc_show, NULL); -} + *eof = 1; -static const struct file_operations stli_proc_fops = { - .owner = THIS_MODULE, - .open = stli_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +stli_readdone: + *start = page; + return(pos - page); +} /*****************************************************************************/ @@ -4410,9 +4427,9 @@ static const struct tty_operations stli_ops = { .break_ctl = stli_breakctl, .wait_until_sent = stli_waituntilsent, .send_xchar = stli_sendxchar, + .read_proc = stli_readproc, .tiocmget = stli_tiocmget, .tiocmset = stli_tiocmset, - .proc_fops = &stli_proc_fops, }; static const struct tty_port_operations stli_port_ops = { diff --git a/trunk/drivers/char/pcmcia/synclink_cs.c b/trunk/drivers/char/pcmcia/synclink_cs.c index 19d79fc54461..5608a1e5a3b3 100644 --- a/trunk/drivers/char/pcmcia/synclink_cs.c +++ b/trunk/drivers/char/pcmcia/synclink_cs.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -2620,12 +2619,13 @@ static int mgslpc_open(struct tty_struct *tty, struct file * filp) * /proc fs routines.... */ -static inline void line_info(struct seq_file *m, MGSLPC_INFO *info) +static inline int line_info(char *buf, MGSLPC_INFO *info) { char stat_buf[30]; + int ret; unsigned long flags; - seq_printf(m, "%s:io:%04X irq:%d", + ret = sprintf(buf, "%s:io:%04X irq:%d", info->device_name, info->io_base, info->irq_level); /* output current serial signal states */ @@ -2649,70 +2649,75 @@ static inline void line_info(struct seq_file *m, MGSLPC_INFO *info) strcat(stat_buf, "|RI"); if (info->params.mode == MGSL_MODE_HDLC) { - seq_printf(m, " HDLC txok:%d rxok:%d", + ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d", info->icount.txok, info->icount.rxok); if (info->icount.txunder) - seq_printf(m, " txunder:%d", info->icount.txunder); + ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder); if (info->icount.txabort) - seq_printf(m, " txabort:%d", info->icount.txabort); + ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort); if (info->icount.rxshort) - seq_printf(m, " rxshort:%d", info->icount.rxshort); + ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort); if (info->icount.rxlong) - seq_printf(m, " rxlong:%d", info->icount.rxlong); + ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong); if (info->icount.rxover) - seq_printf(m, " rxover:%d", info->icount.rxover); + ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover); if (info->icount.rxcrc) - seq_printf(m, " rxcrc:%d", info->icount.rxcrc); + ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc); } else { - seq_printf(m, " ASYNC tx:%d rx:%d", + ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d", info->icount.tx, info->icount.rx); if (info->icount.frame) - seq_printf(m, " fe:%d", info->icount.frame); + ret += sprintf(buf+ret, " fe:%d", info->icount.frame); if (info->icount.parity) - seq_printf(m, " pe:%d", info->icount.parity); + ret += sprintf(buf+ret, " pe:%d", info->icount.parity); if (info->icount.brk) - seq_printf(m, " brk:%d", info->icount.brk); + ret += sprintf(buf+ret, " brk:%d", info->icount.brk); if (info->icount.overrun) - seq_printf(m, " oe:%d", info->icount.overrun); + ret += sprintf(buf+ret, " oe:%d", info->icount.overrun); } /* Append serial signal status to end */ - seq_printf(m, " %s\n", stat_buf+1); + ret += sprintf(buf+ret, " %s\n", stat_buf+1); - seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", + ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", info->tx_active,info->bh_requested,info->bh_running, info->pending_bh); + + return ret; } /* Called to print information about devices */ -static int mgslpc_proc_show(struct seq_file *m, void *v) +static int mgslpc_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { + int len = 0, l; + off_t begin = 0; MGSLPC_INFO *info; - seq_printf(m, "synclink driver:%s\n", driver_version); + len += sprintf(page, "synclink driver:%s\n", driver_version); info = mgslpc_device_list; while( info ) { - line_info(m, info); + l = line_info(page + len, info); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } info = info->next_device; } - return 0; -} -static int mgslpc_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, mgslpc_proc_show, NULL); + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); } -static const struct file_operations mgslpc_proc_fops = { - .owner = THIS_MODULE, - .open = mgslpc_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static int rx_alloc_buffers(MGSLPC_INFO *info) { /* each buffer has header and data */ @@ -2856,13 +2861,13 @@ static const struct tty_operations mgslpc_ops = { .send_xchar = mgslpc_send_xchar, .break_ctl = mgslpc_break, .wait_until_sent = mgslpc_wait_until_sent, + .read_proc = mgslpc_read_proc, .set_termios = mgslpc_set_termios, .stop = tx_pause, .start = tx_release, .hangup = mgslpc_hangup, .tiocmget = tiocmget, .tiocmset = tiocmset, - .proc_fops = &mgslpc_proc_fops, }; static void synclink_cs_cleanup(void) diff --git a/trunk/drivers/char/random.c b/trunk/drivers/char/random.c index f824ef8a9273..7c43ae782b26 100644 --- a/trunk/drivers/char/random.c +++ b/trunk/drivers/char/random.c @@ -1488,8 +1488,7 @@ static void rekey_seq_generator(struct work_struct *work) keyptr->count = (ip_cnt & COUNT_MASK) << HASH_BITS; smp_wmb(); ip_cnt++; - schedule_delayed_work(&rekey_work, - round_jiffies_relative(REKEY_INTERVAL)); + schedule_delayed_work(&rekey_work, REKEY_INTERVAL); } static inline struct keydata *get_keyptr(void) diff --git a/trunk/drivers/char/raw.c b/trunk/drivers/char/raw.c index 20d90e6a6e50..96adf28a17e4 100644 --- a/trunk/drivers/char/raw.c +++ b/trunk/drivers/char/raw.c @@ -90,7 +90,6 @@ static int raw_open(struct inode *inode, struct file *filp) blkdev_put(bdev, filp->f_mode); out: mutex_unlock(&raw_mutex); - unlock_kernel(); return err; } diff --git a/trunk/drivers/char/stallion.c b/trunk/drivers/char/stallion.c index 2ad813a801dc..e1e0dd89ac9a 100644 --- a/trunk/drivers/char/stallion.c +++ b/trunk/drivers/char/stallion.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -1380,47 +1379,52 @@ static void stl_sendxchar(struct tty_struct *tty, char ch) stl_putchar(tty, ch); } -static void stl_portinfo(struct seq_file *m, struct stlport *portp, int portnr) +/*****************************************************************************/ + +#define MAXLINE 80 + +/* + * Format info for a specified port. The line is deliberately limited + * to 80 characters. (If it is too long it will be truncated, if too + * short then padded with spaces). + */ + +static int stl_portinfo(struct stlport *portp, int portnr, char *pos) { - int sigs; - char sep; + char *sp; + int sigs, cnt; - seq_printf(m, "%d: uart:%s tx:%d rx:%d", + sp = pos; + sp += sprintf(sp, "%d: uart:%s tx:%d rx:%d", portnr, (portp->hwid == 1) ? "SC26198" : "CD1400", (int) portp->stats.txtotal, (int) portp->stats.rxtotal); if (portp->stats.rxframing) - seq_printf(m, " fe:%d", (int) portp->stats.rxframing); + sp += sprintf(sp, " fe:%d", (int) portp->stats.rxframing); if (portp->stats.rxparity) - seq_printf(m, " pe:%d", (int) portp->stats.rxparity); + sp += sprintf(sp, " pe:%d", (int) portp->stats.rxparity); if (portp->stats.rxbreaks) - seq_printf(m, " brk:%d", (int) portp->stats.rxbreaks); + sp += sprintf(sp, " brk:%d", (int) portp->stats.rxbreaks); if (portp->stats.rxoverrun) - seq_printf(m, " oe:%d", (int) portp->stats.rxoverrun); + sp += sprintf(sp, " oe:%d", (int) portp->stats.rxoverrun); sigs = stl_getsignals(portp); - sep = ' '; - if (sigs & TIOCM_RTS) { - seq_printf(m, "%c%s", sep, "RTS"); - sep = '|'; - } - if (sigs & TIOCM_CTS) { - seq_printf(m, "%c%s", sep, "CTS"); - sep = '|'; - } - if (sigs & TIOCM_DTR) { - seq_printf(m, "%c%s", sep, "DTR"); - sep = '|'; - } - if (sigs & TIOCM_CD) { - seq_printf(m, "%c%s", sep, "DCD"); - sep = '|'; - } - if (sigs & TIOCM_DSR) { - seq_printf(m, "%c%s", sep, "DSR"); - sep = '|'; - } - seq_putc(m, '\n'); + cnt = sprintf(sp, "%s%s%s%s%s ", + (sigs & TIOCM_RTS) ? "|RTS" : "", + (sigs & TIOCM_CTS) ? "|CTS" : "", + (sigs & TIOCM_DTR) ? "|DTR" : "", + (sigs & TIOCM_CD) ? "|DCD" : "", + (sigs & TIOCM_DSR) ? "|DSR" : ""); + *sp = ' '; + sp += cnt; + + for (cnt = sp - pos; cnt < (MAXLINE - 1); cnt++) + *sp++ = ' '; + if (cnt >= MAXLINE) + pos[(MAXLINE - 2)] = '+'; + pos[(MAXLINE - 1)] = '\n'; + + return MAXLINE; } /*****************************************************************************/ @@ -1429,17 +1433,30 @@ static void stl_portinfo(struct seq_file *m, struct stlport *portp, int portnr) * Port info, read from the /proc file system. */ -static int stl_proc_show(struct seq_file *m, void *v) +static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) { struct stlbrd *brdp; struct stlpanel *panelp; struct stlport *portp; unsigned int brdnr, panelnr, portnr; - int totalport; + int totalport, curoff, maxoff; + char *pos; - totalport = 0; + pr_debug("stl_readproc(page=%p,start=%p,off=%lx,count=%d,eof=%p," + "data=%p\n", page, start, off, count, eof, data); - seq_printf(m, "%s: version %s\n", stl_drvtitle, stl_drvversion); + pos = page; + totalport = 0; + curoff = 0; + + if (off == 0) { + pos += sprintf(pos, "%s: version %s", stl_drvtitle, + stl_drvversion); + while (pos < (page + MAXLINE - 1)) + *pos++ = ' '; + *pos++ = '\n'; + } + curoff = MAXLINE; /* * We scan through for each board, panel and port. The offset is @@ -1452,36 +1469,45 @@ static int stl_proc_show(struct seq_file *m, void *v) if (brdp->state == 0) continue; + maxoff = curoff + (brdp->nrports * MAXLINE); + if (off >= maxoff) { + curoff = maxoff; + continue; + } + totalport = brdnr * STL_MAXPORTS; for (panelnr = 0; panelnr < brdp->nrpanels; panelnr++) { panelp = brdp->panels[panelnr]; if (panelp == NULL) continue; + maxoff = curoff + (panelp->nrports * MAXLINE); + if (off >= maxoff) { + curoff = maxoff; + totalport += panelp->nrports; + continue; + } + for (portnr = 0; portnr < panelp->nrports; portnr++, totalport++) { portp = panelp->ports[portnr]; if (portp == NULL) continue; - stl_portinfo(m, portp, totalport); + if (off >= (curoff += MAXLINE)) + continue; + if ((pos - page + MAXLINE) > count) + goto stl_readdone; + pos += stl_portinfo(portp, totalport, pos); } } } - return 0; -} -static int stl_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, stl_proc_show, NULL); -} + *eof = 1; -static const struct file_operations stl_proc_fops = { - .owner = THIS_MODULE, - .open = stl_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +stl_readdone: + *start = page; + return pos - page; +} /*****************************************************************************/ @@ -2540,9 +2566,9 @@ static const struct tty_operations stl_ops = { .break_ctl = stl_breakctl, .wait_until_sent = stl_waituntilsent, .send_xchar = stl_sendxchar, + .read_proc = stl_readproc, .tiocmget = stl_tiocmget, .tiocmset = stl_tiocmset, - .proc_fops = &stl_proc_fops, }; static const struct tty_port_operations stl_port_ops = { diff --git a/trunk/drivers/char/synclink.c b/trunk/drivers/char/synclink.c index afd0b26ca056..0057a8f58cb1 100644 --- a/trunk/drivers/char/synclink.c +++ b/trunk/drivers/char/synclink.c @@ -79,7 +79,6 @@ #include #include #include -#include #include #include #include @@ -3460,17 +3459,18 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp) * /proc fs routines.... */ -static inline void line_info(struct seq_file *m, struct mgsl_struct *info) +static inline int line_info(char *buf, struct mgsl_struct *info) { char stat_buf[30]; + int ret; unsigned long flags; if (info->bus_type == MGSL_BUS_TYPE_PCI) { - seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X", + ret = sprintf(buf, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X", info->device_name, info->io_base, info->irq_level, info->phys_memory_base, info->phys_lcr_base); } else { - seq_printf(m, "%s:(E)ISA io:%04X irq:%d dma:%d", + ret = sprintf(buf, "%s:(E)ISA io:%04X irq:%d dma:%d", info->device_name, info->io_base, info->irq_level, info->dma_level); } @@ -3497,37 +3497,37 @@ static inline void line_info(struct seq_file *m, struct mgsl_struct *info) if (info->params.mode == MGSL_MODE_HDLC || info->params.mode == MGSL_MODE_RAW ) { - seq_printf(m, " HDLC txok:%d rxok:%d", + ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d", info->icount.txok, info->icount.rxok); if (info->icount.txunder) - seq_printf(m, " txunder:%d", info->icount.txunder); + ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder); if (info->icount.txabort) - seq_printf(m, " txabort:%d", info->icount.txabort); + ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort); if (info->icount.rxshort) - seq_printf(m, " rxshort:%d", info->icount.rxshort); + ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort); if (info->icount.rxlong) - seq_printf(m, " rxlong:%d", info->icount.rxlong); + ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong); if (info->icount.rxover) - seq_printf(m, " rxover:%d", info->icount.rxover); + ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover); if (info->icount.rxcrc) - seq_printf(m, " rxcrc:%d", info->icount.rxcrc); + ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc); } else { - seq_printf(m, " ASYNC tx:%d rx:%d", + ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d", info->icount.tx, info->icount.rx); if (info->icount.frame) - seq_printf(m, " fe:%d", info->icount.frame); + ret += sprintf(buf+ret, " fe:%d", info->icount.frame); if (info->icount.parity) - seq_printf(m, " pe:%d", info->icount.parity); + ret += sprintf(buf+ret, " pe:%d", info->icount.parity); if (info->icount.brk) - seq_printf(m, " brk:%d", info->icount.brk); + ret += sprintf(buf+ret, " brk:%d", info->icount.brk); if (info->icount.overrun) - seq_printf(m, " oe:%d", info->icount.overrun); + ret += sprintf(buf+ret, " oe:%d", info->icount.overrun); } /* Append serial signal status to end */ - seq_printf(m, " %s\n", stat_buf+1); + ret += sprintf(buf+ret, " %s\n", stat_buf+1); - seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", + ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", info->tx_active,info->bh_requested,info->bh_running, info->pending_bh); @@ -3544,40 +3544,60 @@ static inline void line_info(struct seq_file *m, struct mgsl_struct *info) u16 Tmr = usc_InReg( info, TMR ); u16 Tccr = usc_InReg( info, TCCR ); u16 Ccar = inw( info->io_base + CCAR ); - seq_printf(m, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n" + ret += sprintf(buf+ret, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n" "ricr=%04X icr =%04X dccr=%04X tmr=%04X tccr=%04X ccar=%04X\n", Tcsr,Tdmr,Ticr,Rscr,Rdmr,Ricr,Icr,Dccr,Tmr,Tccr,Ccar ); } spin_unlock_irqrestore(&info->irq_spinlock,flags); -} + + return ret; + +} /* end of line_info() */ -/* Called to print information about devices */ -static int mgsl_proc_show(struct seq_file *m, void *v) +/* mgsl_read_proc() + * + * Called to print information about devices + * + * Arguments: + * page page of memory to hold returned info + * start + * off + * count + * eof + * data + * + * Return Value: + */ +static int mgsl_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { + int len = 0, l; + off_t begin = 0; struct mgsl_struct *info; - seq_printf(m, "synclink driver:%s\n", driver_version); + len += sprintf(page, "synclink driver:%s\n", driver_version); info = mgsl_device_list; while( info ) { - line_info(m, info); + l = line_info(page + len, info); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } info = info->next_device; } - return 0; -} - -static int mgsl_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, mgsl_proc_show, NULL); -} -static const struct file_operations mgsl_proc_fops = { - .owner = THIS_MODULE, - .open = mgsl_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); + +} /* end of mgsl_read_proc() */ /* mgsl_allocate_dma_buffers() * @@ -4315,13 +4335,13 @@ static const struct tty_operations mgsl_ops = { .send_xchar = mgsl_send_xchar, .break_ctl = mgsl_break, .wait_until_sent = mgsl_wait_until_sent, + .read_proc = mgsl_read_proc, .set_termios = mgsl_set_termios, .stop = mgsl_stop, .start = mgsl_start, .hangup = mgsl_hangup, .tiocmget = tiocmget, .tiocmset = tiocmset, - .proc_fops = &mgsl_proc_fops, }; /* diff --git a/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c index 5e256494686a..efb3dc928a43 100644 --- a/trunk/drivers/char/synclink_gt.c +++ b/trunk/drivers/char/synclink_gt.c @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -155,6 +154,7 @@ static void tx_hold(struct tty_struct *tty); static void tx_release(struct tty_struct *tty); static int ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); +static int read_proc(char *page, char **start, off_t off, int count,int *eof, void *data); static int chars_in_buffer(struct tty_struct *tty); static void throttle(struct tty_struct * tty); static void unthrottle(struct tty_struct * tty); @@ -298,7 +298,6 @@ struct slgt_info { unsigned int rbuf_fill_level; unsigned int if_mode; - unsigned int base_clock; /* device status */ @@ -1157,26 +1156,22 @@ static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *ne return -EFAULT; spin_lock(&info->lock); - if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) { - info->base_clock = tmp_params.clock_speed; - } else { - info->params.mode = tmp_params.mode; - info->params.loopback = tmp_params.loopback; - info->params.flags = tmp_params.flags; - info->params.encoding = tmp_params.encoding; - info->params.clock_speed = tmp_params.clock_speed; - info->params.addr_filter = tmp_params.addr_filter; - info->params.crc_type = tmp_params.crc_type; - info->params.preamble_length = tmp_params.preamble_length; - info->params.preamble = tmp_params.preamble; - info->params.data_rate = tmp_params.data_rate; - info->params.data_bits = tmp_params.data_bits; - info->params.stop_bits = tmp_params.stop_bits; - info->params.parity = tmp_params.parity; - } + info->params.mode = tmp_params.mode; + info->params.loopback = tmp_params.loopback; + info->params.flags = tmp_params.flags; + info->params.encoding = tmp_params.encoding; + info->params.clock_speed = tmp_params.clock_speed; + info->params.addr_filter = tmp_params.addr_filter; + info->params.crc_type = tmp_params.crc_type; + info->params.preamble_length = tmp_params.preamble_length; + info->params.preamble = tmp_params.preamble; + info->params.data_rate = tmp_params.data_rate; + info->params.data_bits = tmp_params.data_bits; + info->params.stop_bits = tmp_params.stop_bits; + info->params.parity = tmp_params.parity; spin_unlock(&info->lock); - program_hw(info); + change_params(info); return 0; } @@ -1234,12 +1229,13 @@ static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file, /* * proc fs support */ -static inline void line_info(struct seq_file *m, struct slgt_info *info) +static inline int line_info(char *buf, struct slgt_info *info) { char stat_buf[30]; + int ret; unsigned long flags; - seq_printf(m, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n", + ret = sprintf(buf, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n", info->device_name, info->phys_reg_addr, info->irq_level, info->max_frame_size); @@ -1264,70 +1260,75 @@ static inline void line_info(struct seq_file *m, struct slgt_info *info) strcat(stat_buf, "|RI"); if (info->params.mode != MGSL_MODE_ASYNC) { - seq_printf(m, "\tHDLC txok:%d rxok:%d", + ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d", info->icount.txok, info->icount.rxok); if (info->icount.txunder) - seq_printf(m, " txunder:%d", info->icount.txunder); + ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder); if (info->icount.txabort) - seq_printf(m, " txabort:%d", info->icount.txabort); + ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort); if (info->icount.rxshort) - seq_printf(m, " rxshort:%d", info->icount.rxshort); + ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort); if (info->icount.rxlong) - seq_printf(m, " rxlong:%d", info->icount.rxlong); + ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong); if (info->icount.rxover) - seq_printf(m, " rxover:%d", info->icount.rxover); + ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover); if (info->icount.rxcrc) - seq_printf(m, " rxcrc:%d", info->icount.rxcrc); + ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc); } else { - seq_printf(m, "\tASYNC tx:%d rx:%d", + ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d", info->icount.tx, info->icount.rx); if (info->icount.frame) - seq_printf(m, " fe:%d", info->icount.frame); + ret += sprintf(buf+ret, " fe:%d", info->icount.frame); if (info->icount.parity) - seq_printf(m, " pe:%d", info->icount.parity); + ret += sprintf(buf+ret, " pe:%d", info->icount.parity); if (info->icount.brk) - seq_printf(m, " brk:%d", info->icount.brk); + ret += sprintf(buf+ret, " brk:%d", info->icount.brk); if (info->icount.overrun) - seq_printf(m, " oe:%d", info->icount.overrun); + ret += sprintf(buf+ret, " oe:%d", info->icount.overrun); } /* Append serial signal status to end */ - seq_printf(m, " %s\n", stat_buf+1); + ret += sprintf(buf+ret, " %s\n", stat_buf+1); - seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", + ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", info->tx_active,info->bh_requested,info->bh_running, info->pending_bh); + + return ret; } /* Called to print information about devices */ -static int synclink_gt_proc_show(struct seq_file *m, void *v) +static int read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { + int len = 0, l; + off_t begin = 0; struct slgt_info *info; - seq_puts(m, "synclink_gt driver\n"); + len += sprintf(page, "synclink_gt driver\n"); info = slgt_device_list; while( info ) { - line_info(m, info); + l = line_info(page + len, info); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } info = info->next_device; } - return 0; -} -static int synclink_gt_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, synclink_gt_proc_show, NULL); + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); } -static const struct file_operations synclink_gt_proc_fops = { - .owner = THIS_MODULE, - .open = synclink_gt_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /* * return count of bytes in transmit buffer */ @@ -2564,13 +2565,10 @@ static int set_params(struct slgt_info *info, MGSL_PARAMS __user *new_params) return -EFAULT; spin_lock_irqsave(&info->lock, flags); - if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) - info->base_clock = tmp_params.clock_speed; - else - memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS)); + memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS)); spin_unlock_irqrestore(&info->lock, flags); - program_hw(info); + change_params(info); return 0; } @@ -3440,7 +3438,6 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev info->magic = MGSL_MAGIC; INIT_WORK(&info->task, bh_handler); info->max_frame_size = 4096; - info->base_clock = 14745600; info->rbuf_fill_level = DMABUFSIZE; info->port.close_delay = 5*HZ/10; info->port.closing_wait = 30*HZ; @@ -3565,13 +3562,13 @@ static const struct tty_operations ops = { .send_xchar = send_xchar, .break_ctl = set_break, .wait_until_sent = wait_until_sent, + .read_proc = read_proc, .set_termios = set_termios, .stop = tx_hold, .start = tx_release, .hangup = hangup, .tiocmget = tiocmget, .tiocmset = tiocmset, - .proc_fops = &synclink_gt_proc_fops, }; static void slgt_cleanup(void) @@ -3788,7 +3785,7 @@ static void enable_loopback(struct slgt_info *info) static void set_rate(struct slgt_info *info, u32 rate) { unsigned int div; - unsigned int osc = info->base_clock; + static unsigned int osc = 14745600; /* div = osc/rate - 1 * @@ -4092,27 +4089,18 @@ static void async_mode(struct slgt_info *info) * 06 CTS IRQ enable * 05 DCD IRQ enable * 04 RI IRQ enable - * 03 0=16x sampling, 1=8x sampling + * 03 reserved, must be zero * 02 1=txd->rxd internal loopback enable * 01 reserved, must be zero * 00 1=master IRQ enable */ val = BIT15 + BIT14 + BIT0; - /* JCR[8] : 1 = x8 async mode feature available */ - if ((rd_reg32(info, JCR) & BIT8) && info->params.data_rate && - ((info->base_clock < (info->params.data_rate * 16)) || - (info->base_clock % (info->params.data_rate * 16)))) { - /* use 8x sampling */ - val |= BIT3; - set_rate(info, info->params.data_rate * 8); - } else { - /* use 16x sampling */ - set_rate(info, info->params.data_rate * 16); - } wr_reg16(info, SCR, val); slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER); + set_rate(info, info->params.data_rate * 16); + if (info->params.loopback) enable_loopback(info); } diff --git a/trunk/drivers/char/synclinkmp.c b/trunk/drivers/char/synclinkmp.c index 26de60efe4b2..8eb6c89a980e 100644 --- a/trunk/drivers/char/synclinkmp.c +++ b/trunk/drivers/char/synclinkmp.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include @@ -521,6 +520,7 @@ static void tx_hold(struct tty_struct *tty); static void tx_release(struct tty_struct *tty); static int ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); +static int read_proc(char *page, char **start, off_t off, int count,int *eof, void *data); static int chars_in_buffer(struct tty_struct *tty); static void throttle(struct tty_struct * tty); static void unthrottle(struct tty_struct * tty); @@ -1354,12 +1354,13 @@ static int ioctl(struct tty_struct *tty, struct file *file, * /proc fs routines.... */ -static inline void line_info(struct seq_file *m, SLMP_INFO *info) +static inline int line_info(char *buf, SLMP_INFO *info) { char stat_buf[30]; + int ret; unsigned long flags; - seq_printf(m, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n" + ret = sprintf(buf, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n" "\tIRQ=%d MaxFrameSize=%u\n", info->device_name, info->phys_sca_base, @@ -1390,70 +1391,75 @@ static inline void line_info(struct seq_file *m, SLMP_INFO *info) strcat(stat_buf, "|RI"); if (info->params.mode == MGSL_MODE_HDLC) { - seq_printf(m, "\tHDLC txok:%d rxok:%d", + ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d", info->icount.txok, info->icount.rxok); if (info->icount.txunder) - seq_printf(m, " txunder:%d", info->icount.txunder); + ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder); if (info->icount.txabort) - seq_printf(m, " txabort:%d", info->icount.txabort); + ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort); if (info->icount.rxshort) - seq_printf(m, " rxshort:%d", info->icount.rxshort); + ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort); if (info->icount.rxlong) - seq_printf(m, " rxlong:%d", info->icount.rxlong); + ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong); if (info->icount.rxover) - seq_printf(m, " rxover:%d", info->icount.rxover); + ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover); if (info->icount.rxcrc) - seq_printf(m, " rxlong:%d", info->icount.rxcrc); + ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxcrc); } else { - seq_printf(m, "\tASYNC tx:%d rx:%d", + ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d", info->icount.tx, info->icount.rx); if (info->icount.frame) - seq_printf(m, " fe:%d", info->icount.frame); + ret += sprintf(buf+ret, " fe:%d", info->icount.frame); if (info->icount.parity) - seq_printf(m, " pe:%d", info->icount.parity); + ret += sprintf(buf+ret, " pe:%d", info->icount.parity); if (info->icount.brk) - seq_printf(m, " brk:%d", info->icount.brk); + ret += sprintf(buf+ret, " brk:%d", info->icount.brk); if (info->icount.overrun) - seq_printf(m, " oe:%d", info->icount.overrun); + ret += sprintf(buf+ret, " oe:%d", info->icount.overrun); } /* Append serial signal status to end */ - seq_printf(m, " %s\n", stat_buf+1); + ret += sprintf(buf+ret, " %s\n", stat_buf+1); - seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", + ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", info->tx_active,info->bh_requested,info->bh_running, info->pending_bh); + + return ret; } /* Called to print information about devices */ -static int synclinkmp_proc_show(struct seq_file *m, void *v) +static int read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { + int len = 0, l; + off_t begin = 0; SLMP_INFO *info; - seq_printf(m, "synclinkmp driver:%s\n", driver_version); + len += sprintf(page, "synclinkmp driver:%s\n", driver_version); info = synclinkmp_device_list; while( info ) { - line_info(m, info); + l = line_info(page + len, info); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } info = info->next_device; } - return 0; -} -static int synclinkmp_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, synclinkmp_proc_show, NULL); + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); } -static const struct file_operations synclinkmp_proc_fops = { - .owner = THIS_MODULE, - .open = synclinkmp_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /* Return the count of bytes in transmit buffer */ static int chars_in_buffer(struct tty_struct *tty) @@ -3899,13 +3905,13 @@ static const struct tty_operations ops = { .send_xchar = send_xchar, .break_ctl = set_break, .wait_until_sent = wait_until_sent, + .read_proc = read_proc, .set_termios = set_termios, .stop = tx_hold, .start = tx_release, .hangup = hangup, .tiocmget = tiocmget, .tiocmset = tiocmset, - .proc_fops = &synclinkmp_proc_fops, }; diff --git a/trunk/drivers/char/sysrq.c b/trunk/drivers/char/sysrq.c index ebea9b2c30a5..33a9351c896d 100644 --- a/trunk/drivers/char/sysrq.c +++ b/trunk/drivers/char/sysrq.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include @@ -346,19 +346,6 @@ static struct sysrq_key_op sysrq_moom_op = { .enable_mask = SYSRQ_ENABLE_SIGNAL, }; -#ifdef CONFIG_BLOCK -static void sysrq_handle_thaw(int key, struct tty_struct *tty) -{ - emergency_thaw_all(); -} -static struct sysrq_key_op sysrq_thaw_op = { - .handler = sysrq_handle_thaw, - .help_msg = "thaw-filesystems(J)", - .action_msg = "Emergency Thaw of all frozen filesystems", - .enable_mask = SYSRQ_ENABLE_SIGNAL, -}; -#endif - static void sysrq_handle_kill(int key, struct tty_struct *tty) { send_sig_all(SIGKILL); @@ -409,13 +396,9 @@ static struct sysrq_key_op *sysrq_key_table[36] = { &sysrq_moom_op, /* f */ /* g: May be registered by ppc for kgdb */ NULL, /* g */ - NULL, /* h - reserved for help */ + NULL, /* h */ &sysrq_kill_op, /* i */ -#ifdef CONFIG_BLOCK - &sysrq_thaw_op, /* j */ -#else NULL, /* j */ -#endif &sysrq_SAK_op, /* k */ #ifdef CONFIG_SMP &sysrq_showallcpus_op, /* l */ diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index 66b99a2049e3..224f271d8cbe 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -464,7 +464,7 @@ void tty_wakeup(struct tty_struct *tty) tty_ldisc_deref(ld); } } - wake_up_interruptible_poll(&tty->write_wait, POLLOUT); + wake_up_interruptible(&tty->write_wait); } EXPORT_SYMBOL_GPL(tty_wakeup); @@ -587,8 +587,8 @@ static void do_tty_hangup(struct work_struct *work) * FIXME: Once we trust the LDISC code better we can wait here for * ldisc completion and fix the driver call race */ - wake_up_interruptible_poll(&tty->write_wait, POLLOUT); - wake_up_interruptible_poll(&tty->read_wait, POLLIN); + wake_up_interruptible(&tty->write_wait); + wake_up_interruptible(&tty->read_wait); /* * Shutdown the current line discipline, and reset it to * N_TTY. @@ -879,7 +879,7 @@ void stop_tty(struct tty_struct *tty) if (tty->link && tty->link->packet) { tty->ctrl_status &= ~TIOCPKT_START; tty->ctrl_status |= TIOCPKT_STOP; - wake_up_interruptible_poll(&tty->link->read_wait, POLLIN); + wake_up_interruptible(&tty->link->read_wait); } spin_unlock_irqrestore(&tty->ctrl_lock, flags); if (tty->ops->stop) @@ -913,7 +913,7 @@ void start_tty(struct tty_struct *tty) if (tty->link && tty->link->packet) { tty->ctrl_status &= ~TIOCPKT_STOP; tty->ctrl_status |= TIOCPKT_START; - wake_up_interruptible_poll(&tty->link->read_wait, POLLIN); + wake_up_interruptible(&tty->link->read_wait); } spin_unlock_irqrestore(&tty->ctrl_lock, flags); if (tty->ops->start) @@ -970,7 +970,7 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, void tty_write_unlock(struct tty_struct *tty) { mutex_unlock(&tty->atomic_write_lock); - wake_up_interruptible_poll(&tty->write_wait, POLLOUT); + wake_up_interruptible(&tty->write_wait); } int tty_write_lock(struct tty_struct *tty, int ndelay) @@ -1623,21 +1623,21 @@ void tty_release_dev(struct file *filp) if (tty_closing) { if (waitqueue_active(&tty->read_wait)) { - wake_up_poll(&tty->read_wait, POLLIN); + wake_up(&tty->read_wait); do_sleep++; } if (waitqueue_active(&tty->write_wait)) { - wake_up_poll(&tty->write_wait, POLLOUT); + wake_up(&tty->write_wait); do_sleep++; } } if (o_tty_closing) { if (waitqueue_active(&o_tty->read_wait)) { - wake_up_poll(&o_tty->read_wait, POLLIN); + wake_up(&o_tty->read_wait); do_sleep++; } if (waitqueue_active(&o_tty->write_wait)) { - wake_up_poll(&o_tty->write_wait, POLLOUT); + wake_up(&o_tty->write_wait); do_sleep++; } } @@ -1758,7 +1758,7 @@ static int __tty_open(struct inode *inode, struct file *filp) struct tty_driver *driver; int index; dev_t device = inode->i_rdev; - unsigned saved_flags = filp->f_flags; + unsigned short saved_flags = filp->f_flags; nonseekable_open(inode, filp); @@ -2681,7 +2681,7 @@ void __do_SAK(struct tty_struct *tty) /* Kill the entire session */ do_each_pid_task(session, PIDTYPE_SID, p) { printk(KERN_NOTICE "SAK: killed process %d" - " (%s): task_session(p)==tty->session\n", + " (%s): task_session_nr(p)==tty->session\n", task_pid_nr(p), p->comm); send_sig(SIGKILL, p, 1); } while_each_pid_task(session, PIDTYPE_SID, p); @@ -2691,7 +2691,7 @@ void __do_SAK(struct tty_struct *tty) do_each_thread(g, p) { if (p->signal->tty == tty) { printk(KERN_NOTICE "SAK: killed process %d" - " (%s): task_session(p)==tty->session\n", + " (%s): task_session_nr(p)==tty->session\n", task_pid_nr(p), p->comm); send_sig(SIGKILL, p, 1); continue; diff --git a/trunk/drivers/crypto/hifn_795x.c b/trunk/drivers/crypto/hifn_795x.c index 4d85402a9e4a..0c79fe7f1567 100644 --- a/trunk/drivers/crypto/hifn_795x.c +++ b/trunk/drivers/crypto/hifn_795x.c @@ -1882,7 +1882,7 @@ static void hifn_clear_rings(struct hifn_device *dev, int error) static void hifn_work(struct work_struct *work) { - struct delayed_work *dw = to_delayed_work(work); + struct delayed_work *dw = container_of(work, struct delayed_work, work); struct hifn_device *dev = container_of(dw, struct hifn_device, work); unsigned long flags; int reset = 0; diff --git a/trunk/drivers/edac/Kconfig b/trunk/drivers/edac/Kconfig index e5f5c5a8ba6c..eee47fd16d79 100644 --- a/trunk/drivers/edac/Kconfig +++ b/trunk/drivers/edac/Kconfig @@ -1,12 +1,13 @@ # # EDAC Kconfig -# Copyright (c) 2008 Doug Thompson www.softwarebitmaker.com +# Copyright (c) 2003 Linux Networx # Licensed and distributed under the GPL # menuconfig EDAC - bool "EDAC - error detection and reporting" + bool "EDAC - error detection and reporting (EXPERIMENTAL)" depends on HAS_IOMEM + depends on EXPERIMENTAL depends on X86 || PPC help EDAC is designed to report errors in the core system. @@ -39,14 +40,6 @@ config EDAC_DEBUG there're four debug levels (x=0,1,2,3 from low to high). Usually you should select 'N'. -config EDAC_DEBUG_VERBOSE - bool "More verbose debugging" - depends on EDAC_DEBUG - help - This option makes debugging information more verbose. - Source file name and line number where debugging message - printed will be added to debugging message. - config EDAC_MM_EDAC tristate "Main Memory EDAC (Error Detection And Correction) reporting" default y @@ -181,27 +174,4 @@ config EDAC_CELL Cell Broadband Engine internal memory controller on platform without a hypervisor -config EDAC_PPC4XX - tristate "PPC4xx IBM DDR2 Memory Controller" - depends on EDAC_MM_EDAC && 4xx - help - This enables support for EDAC on the ECC memory used - with the IBM DDR2 memory controller found in various - PowerPC 4xx embedded processors such as the 405EX[r], - 440SP, 440SPe, 460EX, 460GT and 460SX. - -config EDAC_AMD8131 - tristate "AMD8131 HyperTransport PCI-X Tunnel" - depends on EDAC_MM_EDAC && PCI - help - Support for error detection and correction on the - AMD8131 HyperTransport PCI-X Tunnel chip. - -config EDAC_AMD8111 - tristate "AMD8111 HyperTransport I/O Hub" - depends on EDAC_MM_EDAC && PCI - help - Support for error detection and correction on the - AMD8111 HyperTransport I/O Hub chip. - endif # EDAC diff --git a/trunk/drivers/edac/Makefile b/trunk/drivers/edac/Makefile index a5fdcf02f591..b75196927de3 100644 --- a/trunk/drivers/edac/Makefile +++ b/trunk/drivers/edac/Makefile @@ -34,4 +34,4 @@ obj-$(CONFIG_EDAC_PASEMI) += pasemi_edac.o obj-$(CONFIG_EDAC_MPC85XX) += mpc85xx_edac.o obj-$(CONFIG_EDAC_MV64X60) += mv64x60_edac.o obj-$(CONFIG_EDAC_CELL) += cell_edac.o -obj-$(CONFIG_EDAC_PPC4XX) += ppc4xx_edac.o + diff --git a/trunk/drivers/edac/amd8111_edac.c b/trunk/drivers/edac/amd8111_edac.c deleted file mode 100644 index 614692181120..000000000000 --- a/trunk/drivers/edac/amd8111_edac.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - * amd8111_edac.c, AMD8111 Hyper Transport chip EDAC kernel module - * - * Copyright (c) 2008 Wind River Systems, Inc. - * - * Authors: Cao Qingtao - * Benjamin Walsh - * Hu Yongqi - * - * 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 -#include -#include - -#include "edac_core.h" -#include "edac_module.h" -#include "amd8111_edac.h" - -#define AMD8111_EDAC_REVISION " Ver: 1.0.0 " __DATE__ -#define AMD8111_EDAC_MOD_STR "amd8111_edac" - -#define PCI_DEVICE_ID_AMD_8111_PCI 0x7460 -static int edac_dev_idx; - -enum amd8111_edac_devs { - LPC_BRIDGE = 0, -}; - -enum amd8111_edac_pcis { - PCI_BRIDGE = 0, -}; - -/* Wrapper functions for accessing PCI configuration space */ -static int edac_pci_read_dword(struct pci_dev *dev, int reg, u32 *val32) -{ - int ret; - - ret = pci_read_config_dword(dev, reg, val32); - if (ret != 0) - printk(KERN_ERR AMD8111_EDAC_MOD_STR - " PCI Access Read Error at 0x%x\n", reg); - - return ret; -} - -static void edac_pci_read_byte(struct pci_dev *dev, int reg, u8 *val8) -{ - int ret; - - ret = pci_read_config_byte(dev, reg, val8); - if (ret != 0) - printk(KERN_ERR AMD8111_EDAC_MOD_STR - " PCI Access Read Error at 0x%x\n", reg); -} - -static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32) -{ - int ret; - - ret = pci_write_config_dword(dev, reg, val32); - if (ret != 0) - printk(KERN_ERR AMD8111_EDAC_MOD_STR - " PCI Access Write Error at 0x%x\n", reg); -} - -static void edac_pci_write_byte(struct pci_dev *dev, int reg, u8 val8) -{ - int ret; - - ret = pci_write_config_byte(dev, reg, val8); - if (ret != 0) - printk(KERN_ERR AMD8111_EDAC_MOD_STR - " PCI Access Write Error at 0x%x\n", reg); -} - -/* - * device-specific methods for amd8111 PCI Bridge Controller - * - * Error Reporting and Handling for amd8111 chipset could be found - * in its datasheet 3.1.2 section, P37 - */ -static void amd8111_pci_bridge_init(struct amd8111_pci_info *pci_info) -{ - u32 val32; - struct pci_dev *dev = pci_info->dev; - - /* First clear error detection flags on the host interface */ - - /* Clear SSE/SMA/STA flags in the global status register*/ - edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32); - if (val32 & PCI_STSCMD_CLEAR_MASK) - edac_pci_write_dword(dev, REG_PCI_STSCMD, val32); - - /* Clear CRC and Link Fail flags in HT Link Control reg */ - edac_pci_read_dword(dev, REG_HT_LINK, &val32); - if (val32 & HT_LINK_CLEAR_MASK) - edac_pci_write_dword(dev, REG_HT_LINK, val32); - - /* Second clear all fault on the secondary interface */ - - /* Clear error flags in the memory-base limit reg. */ - edac_pci_read_dword(dev, REG_MEM_LIM, &val32); - if (val32 & MEM_LIMIT_CLEAR_MASK) - edac_pci_write_dword(dev, REG_MEM_LIM, val32); - - /* Clear Discard Timer Expired flag in Interrupt/Bridge Control reg */ - edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32); - if (val32 & PCI_INTBRG_CTRL_CLEAR_MASK) - edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32); - - /* Last enable error detections */ - if (edac_op_state == EDAC_OPSTATE_POLL) { - /* Enable System Error reporting in global status register */ - edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32); - val32 |= PCI_STSCMD_SERREN; - edac_pci_write_dword(dev, REG_PCI_STSCMD, val32); - - /* Enable CRC Sync flood packets to HyperTransport Link */ - edac_pci_read_dword(dev, REG_HT_LINK, &val32); - val32 |= HT_LINK_CRCFEN; - edac_pci_write_dword(dev, REG_HT_LINK, val32); - - /* Enable SSE reporting etc in Interrupt control reg */ - edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32); - val32 |= PCI_INTBRG_CTRL_POLL_MASK; - edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32); - } -} - -static void amd8111_pci_bridge_exit(struct amd8111_pci_info *pci_info) -{ - u32 val32; - struct pci_dev *dev = pci_info->dev; - - if (edac_op_state == EDAC_OPSTATE_POLL) { - /* Disable System Error reporting */ - edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32); - val32 &= ~PCI_STSCMD_SERREN; - edac_pci_write_dword(dev, REG_PCI_STSCMD, val32); - - /* Disable CRC flood packets */ - edac_pci_read_dword(dev, REG_HT_LINK, &val32); - val32 &= ~HT_LINK_CRCFEN; - edac_pci_write_dword(dev, REG_HT_LINK, val32); - - /* Disable DTSERREN/MARSP/SERREN in Interrupt Control reg */ - edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32); - val32 &= ~PCI_INTBRG_CTRL_POLL_MASK; - edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32); - } -} - -static void amd8111_pci_bridge_check(struct edac_pci_ctl_info *edac_dev) -{ - struct amd8111_pci_info *pci_info = edac_dev->pvt_info; - struct pci_dev *dev = pci_info->dev; - u32 val32; - - /* Check out PCI Bridge Status and Command Register */ - edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32); - if (val32 & PCI_STSCMD_CLEAR_MASK) { - printk(KERN_INFO "Error(s) in PCI bridge status and command" - "register on device %s\n", pci_info->ctl_name); - printk(KERN_INFO "SSE: %d, RMA: %d, RTA: %d\n", - (val32 & PCI_STSCMD_SSE) != 0, - (val32 & PCI_STSCMD_RMA) != 0, - (val32 & PCI_STSCMD_RTA) != 0); - - val32 |= PCI_STSCMD_CLEAR_MASK; - edac_pci_write_dword(dev, REG_PCI_STSCMD, val32); - - edac_pci_handle_npe(edac_dev, edac_dev->ctl_name); - } - - /* Check out HyperTransport Link Control Register */ - edac_pci_read_dword(dev, REG_HT_LINK, &val32); - if (val32 & HT_LINK_LKFAIL) { - printk(KERN_INFO "Error(s) in hypertransport link control" - "register on device %s\n", pci_info->ctl_name); - printk(KERN_INFO "LKFAIL: %d\n", - (val32 & HT_LINK_LKFAIL) != 0); - - val32 |= HT_LINK_LKFAIL; - edac_pci_write_dword(dev, REG_HT_LINK, val32); - - edac_pci_handle_npe(edac_dev, edac_dev->ctl_name); - } - - /* Check out PCI Interrupt and Bridge Control Register */ - edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32); - if (val32 & PCI_INTBRG_CTRL_DTSTAT) { - printk(KERN_INFO "Error(s) in PCI interrupt and bridge control" - "register on device %s\n", pci_info->ctl_name); - printk(KERN_INFO "DTSTAT: %d\n", - (val32 & PCI_INTBRG_CTRL_DTSTAT) != 0); - - val32 |= PCI_INTBRG_CTRL_DTSTAT; - edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32); - - edac_pci_handle_npe(edac_dev, edac_dev->ctl_name); - } - - /* Check out PCI Bridge Memory Base-Limit Register */ - edac_pci_read_dword(dev, REG_MEM_LIM, &val32); - if (val32 & MEM_LIMIT_CLEAR_MASK) { - printk(KERN_INFO - "Error(s) in mem limit register on %s device\n", - pci_info->ctl_name); - printk(KERN_INFO "DPE: %d, RSE: %d, RMA: %d\n" - "RTA: %d, STA: %d, MDPE: %d\n", - (val32 & MEM_LIMIT_DPE) != 0, - (val32 & MEM_LIMIT_RSE) != 0, - (val32 & MEM_LIMIT_RMA) != 0, - (val32 & MEM_LIMIT_RTA) != 0, - (val32 & MEM_LIMIT_STA) != 0, - (val32 & MEM_LIMIT_MDPE) != 0); - - val32 |= MEM_LIMIT_CLEAR_MASK; - edac_pci_write_dword(dev, REG_MEM_LIM, val32); - - edac_pci_handle_npe(edac_dev, edac_dev->ctl_name); - } -} - -static struct resource *legacy_io_res; -static int at_compat_reg_broken; -#define LEGACY_NR_PORTS 1 - -/* device-specific methods for amd8111 LPC Bridge device */ -static void amd8111_lpc_bridge_init(struct amd8111_dev_info *dev_info) -{ - u8 val8; - struct pci_dev *dev = dev_info->dev; - - /* First clear REG_AT_COMPAT[SERR, IOCHK] if necessary */ - legacy_io_res = request_region(REG_AT_COMPAT, LEGACY_NR_PORTS, - AMD8111_EDAC_MOD_STR); - if (!legacy_io_res) - printk(KERN_INFO "%s: failed to request legacy I/O region " - "start %d, len %d\n", __func__, - REG_AT_COMPAT, LEGACY_NR_PORTS); - else { - val8 = __do_inb(REG_AT_COMPAT); - if (val8 == 0xff) { /* buggy port */ - printk(KERN_INFO "%s: port %d is buggy, not supported" - " by hardware?\n", __func__, REG_AT_COMPAT); - at_compat_reg_broken = 1; - release_region(REG_AT_COMPAT, LEGACY_NR_PORTS); - legacy_io_res = NULL; - } else { - u8 out8 = 0; - if (val8 & AT_COMPAT_SERR) - out8 = AT_COMPAT_CLRSERR; - if (val8 & AT_COMPAT_IOCHK) - out8 |= AT_COMPAT_CLRIOCHK; - if (out8 > 0) - __do_outb(out8, REG_AT_COMPAT); - } - } - - /* Second clear error flags on LPC bridge */ - edac_pci_read_byte(dev, REG_IO_CTRL_1, &val8); - if (val8 & IO_CTRL_1_CLEAR_MASK) - edac_pci_write_byte(dev, REG_IO_CTRL_1, val8); -} - -static void amd8111_lpc_bridge_exit(struct amd8111_dev_info *dev_info) -{ - if (legacy_io_res) - release_region(REG_AT_COMPAT, LEGACY_NR_PORTS); -} - -static void amd8111_lpc_bridge_check(struct edac_device_ctl_info *edac_dev) -{ - struct amd8111_dev_info *dev_info = edac_dev->pvt_info; - struct pci_dev *dev = dev_info->dev; - u8 val8; - - edac_pci_read_byte(dev, REG_IO_CTRL_1, &val8); - if (val8 & IO_CTRL_1_CLEAR_MASK) { - printk(KERN_INFO - "Error(s) in IO control register on %s device\n", - dev_info->ctl_name); - printk(KERN_INFO "LPC ERR: %d, PW2LPC: %d\n", - (val8 & IO_CTRL_1_LPC_ERR) != 0, - (val8 & IO_CTRL_1_PW2LPC) != 0); - - val8 |= IO_CTRL_1_CLEAR_MASK; - edac_pci_write_byte(dev, REG_IO_CTRL_1, val8); - - edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name); - } - - if (at_compat_reg_broken == 0) { - u8 out8 = 0; - val8 = __do_inb(REG_AT_COMPAT); - if (val8 & AT_COMPAT_SERR) - out8 = AT_COMPAT_CLRSERR; - if (val8 & AT_COMPAT_IOCHK) - out8 |= AT_COMPAT_CLRIOCHK; - if (out8 > 0) { - __do_outb(out8, REG_AT_COMPAT); - edac_device_handle_ue(edac_dev, 0, 0, - edac_dev->ctl_name); - } - } -} - -/* General devices represented by edac_device_ctl_info */ -static struct amd8111_dev_info amd8111_devices[] = { - [LPC_BRIDGE] = { - .err_dev = PCI_DEVICE_ID_AMD_8111_LPC, - .ctl_name = "lpc", - .init = amd8111_lpc_bridge_init, - .exit = amd8111_lpc_bridge_exit, - .check = amd8111_lpc_bridge_check, - }, - {0}, -}; - -/* PCI controllers represented by edac_pci_ctl_info */ -static struct amd8111_pci_info amd8111_pcis[] = { - [PCI_BRIDGE] = { - .err_dev = PCI_DEVICE_ID_AMD_8111_PCI, - .ctl_name = "AMD8111_PCI_Controller", - .init = amd8111_pci_bridge_init, - .exit = amd8111_pci_bridge_exit, - .check = amd8111_pci_bridge_check, - }, - {0}, -}; - -static int amd8111_dev_probe(struct pci_dev *dev, - const struct pci_device_id *id) -{ - struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data]; - - dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD, - dev_info->err_dev, NULL); - - if (!dev_info->dev) { - printk(KERN_ERR "EDAC device not found:" - "vendor %x, device %x, name %s\n", - PCI_VENDOR_ID_AMD, dev_info->err_dev, - dev_info->ctl_name); - return -ENODEV; - } - - if (pci_enable_device(dev_info->dev)) { - pci_dev_put(dev_info->dev); - printk(KERN_ERR "failed to enable:" - "vendor %x, device %x, name %s\n", - PCI_VENDOR_ID_AMD, dev_info->err_dev, - dev_info->ctl_name); - return -ENODEV; - } - - /* - * we do not allocate extra private structure for - * edac_device_ctl_info, but make use of existing - * one instead. - */ - dev_info->edac_idx = edac_dev_idx++; - dev_info->edac_dev = - edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1, - NULL, 0, 0, - NULL, 0, dev_info->edac_idx); - if (!dev_info->edac_dev) - return -ENOMEM; - - dev_info->edac_dev->pvt_info = dev_info; - dev_info->edac_dev->dev = &dev_info->dev->dev; - dev_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR; - dev_info->edac_dev->ctl_name = dev_info->ctl_name; - dev_info->edac_dev->dev_name = dev_info->dev->dev.bus_id; - - if (edac_op_state == EDAC_OPSTATE_POLL) - dev_info->edac_dev->edac_check = dev_info->check; - - if (dev_info->init) - dev_info->init(dev_info); - - if (edac_device_add_device(dev_info->edac_dev) > 0) { - printk(KERN_ERR "failed to add edac_dev for %s\n", - dev_info->ctl_name); - edac_device_free_ctl_info(dev_info->edac_dev); - return -ENODEV; - } - - printk(KERN_INFO "added one edac_dev on AMD8111 " - "vendor %x, device %x, name %s\n", - PCI_VENDOR_ID_AMD, dev_info->err_dev, - dev_info->ctl_name); - - return 0; -} - -static void amd8111_dev_remove(struct pci_dev *dev) -{ - struct amd8111_dev_info *dev_info; - - for (dev_info = amd8111_devices; dev_info->err_dev; dev_info++) - if (dev_info->dev->device == dev->device) - break; - - if (!dev_info->err_dev) /* should never happen */ - return; - - if (dev_info->edac_dev) { - edac_device_del_device(dev_info->edac_dev->dev); - edac_device_free_ctl_info(dev_info->edac_dev); - } - - if (dev_info->exit) - dev_info->exit(dev_info); - - pci_dev_put(dev_info->dev); -} - -static int amd8111_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) -{ - struct amd8111_pci_info *pci_info = &amd8111_pcis[id->driver_data]; - - pci_info->dev = pci_get_device(PCI_VENDOR_ID_AMD, - pci_info->err_dev, NULL); - - if (!pci_info->dev) { - printk(KERN_ERR "EDAC device not found:" - "vendor %x, device %x, name %s\n", - PCI_VENDOR_ID_AMD, pci_info->err_dev, - pci_info->ctl_name); - return -ENODEV; - } - - if (pci_enable_device(pci_info->dev)) { - pci_dev_put(pci_info->dev); - printk(KERN_ERR "failed to enable:" - "vendor %x, device %x, name %s\n", - PCI_VENDOR_ID_AMD, pci_info->err_dev, - pci_info->ctl_name); - return -ENODEV; - } - - /* - * we do not allocate extra private structure for - * edac_pci_ctl_info, but make use of existing - * one instead. - */ - pci_info->edac_idx = edac_pci_alloc_index(); - pci_info->edac_dev = edac_pci_alloc_ctl_info(0, pci_info->ctl_name); - if (!pci_info->edac_dev) - return -ENOMEM; - - pci_info->edac_dev->pvt_info = pci_info; - pci_info->edac_dev->dev = &pci_info->dev->dev; - pci_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR; - pci_info->edac_dev->ctl_name = pci_info->ctl_name; - pci_info->edac_dev->dev_name = pci_info->dev->dev.bus_id; - - if (edac_op_state == EDAC_OPSTATE_POLL) - pci_info->edac_dev->edac_check = pci_info->check; - - if (pci_info->init) - pci_info->init(pci_info); - - if (edac_pci_add_device(pci_info->edac_dev, pci_info->edac_idx) > 0) { - printk(KERN_ERR "failed to add edac_pci for %s\n", - pci_info->ctl_name); - edac_pci_free_ctl_info(pci_info->edac_dev); - return -ENODEV; - } - - printk(KERN_INFO "added one edac_pci on AMD8111 " - "vendor %x, device %x, name %s\n", - PCI_VENDOR_ID_AMD, pci_info->err_dev, - pci_info->ctl_name); - - return 0; -} - -static void amd8111_pci_remove(struct pci_dev *dev) -{ - struct amd8111_pci_info *pci_info; - - for (pci_info = amd8111_pcis; pci_info->err_dev; pci_info++) - if (pci_info->dev->device == dev->device) - break; - - if (!pci_info->err_dev) /* should never happen */ - return; - - if (pci_info->edac_dev) { - edac_pci_del_device(pci_info->edac_dev->dev); - edac_pci_free_ctl_info(pci_info->edac_dev); - } - - if (pci_info->exit) - pci_info->exit(pci_info); - - pci_dev_put(pci_info->dev); -} - -/* PCI Device ID talbe for general EDAC device */ -static const struct pci_device_id amd8111_edac_dev_tbl[] = { - { - PCI_VEND_DEV(AMD, 8111_LPC), - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .class = 0, - .class_mask = 0, - .driver_data = LPC_BRIDGE, - }, - { - 0, - } /* table is NULL-terminated */ -}; -MODULE_DEVICE_TABLE(pci, amd8111_edac_dev_tbl); - -static struct pci_driver amd8111_edac_dev_driver = { - .name = "AMD8111_EDAC_DEV", - .probe = amd8111_dev_probe, - .remove = amd8111_dev_remove, - .id_table = amd8111_edac_dev_tbl, -}; - -/* PCI Device ID table for EDAC PCI controller */ -static const struct pci_device_id amd8111_edac_pci_tbl[] = { - { - PCI_VEND_DEV(AMD, 8111_PCI), - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .class = 0, - .class_mask = 0, - .driver_data = PCI_BRIDGE, - }, - { - 0, - } /* table is NULL-terminated */ -}; -MODULE_DEVICE_TABLE(pci, amd8111_edac_pci_tbl); - -static struct pci_driver amd8111_edac_pci_driver = { - .name = "AMD8111_EDAC_PCI", - .probe = amd8111_pci_probe, - .remove = amd8111_pci_remove, - .id_table = amd8111_edac_pci_tbl, -}; - -static int __init amd8111_edac_init(void) -{ - int val; - - printk(KERN_INFO "AMD8111 EDAC driver " AMD8111_EDAC_REVISION "\n"); - printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc.\n"); - - /* Only POLL mode supported so far */ - edac_op_state = EDAC_OPSTATE_POLL; - - val = pci_register_driver(&amd8111_edac_dev_driver); - val |= pci_register_driver(&amd8111_edac_pci_driver); - - return val; -} - -static void __exit amd8111_edac_exit(void) -{ - pci_unregister_driver(&amd8111_edac_pci_driver); - pci_unregister_driver(&amd8111_edac_dev_driver); -} - - -module_init(amd8111_edac_init); -module_exit(amd8111_edac_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Cao Qingtao \n"); -MODULE_DESCRIPTION("AMD8111 HyperTransport I/O Hub EDAC kernel module"); diff --git a/trunk/drivers/edac/amd8111_edac.h b/trunk/drivers/edac/amd8111_edac.h deleted file mode 100644 index 35794331debc..000000000000 --- a/trunk/drivers/edac/amd8111_edac.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * amd8111_edac.h, EDAC defs for AMD8111 hypertransport chip - * - * Copyright (c) 2008 Wind River Systems, Inc. - * - * Authors: Cao Qingtao - * Benjamin Walsh - * Hu Yongqi - * - * 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 - */ - -#ifndef _AMD8111_EDAC_H_ -#define _AMD8111_EDAC_H_ - -/************************************************************ - * PCI Bridge Status and Command Register, DevA:0x04 - ************************************************************/ -#define REG_PCI_STSCMD 0x04 -enum pci_stscmd_bits { - PCI_STSCMD_SSE = BIT(30), - PCI_STSCMD_RMA = BIT(29), - PCI_STSCMD_RTA = BIT(28), - PCI_STSCMD_SERREN = BIT(8), - PCI_STSCMD_CLEAR_MASK = (PCI_STSCMD_SSE | - PCI_STSCMD_RMA | - PCI_STSCMD_RTA) -}; - -/************************************************************ - * PCI Bridge Memory Base-Limit Register, DevA:0x1c - ************************************************************/ -#define REG_MEM_LIM 0x1c -enum mem_limit_bits { - MEM_LIMIT_DPE = BIT(31), - MEM_LIMIT_RSE = BIT(30), - MEM_LIMIT_RMA = BIT(29), - MEM_LIMIT_RTA = BIT(28), - MEM_LIMIT_STA = BIT(27), - MEM_LIMIT_MDPE = BIT(24), - MEM_LIMIT_CLEAR_MASK = (MEM_LIMIT_DPE | - MEM_LIMIT_RSE | - MEM_LIMIT_RMA | - MEM_LIMIT_RTA | - MEM_LIMIT_STA | - MEM_LIMIT_MDPE) -}; - -/************************************************************ - * HyperTransport Link Control Register, DevA:0xc4 - ************************************************************/ -#define REG_HT_LINK 0xc4 -enum ht_link_bits { - HT_LINK_LKFAIL = BIT(4), - HT_LINK_CRCFEN = BIT(1), - HT_LINK_CLEAR_MASK = (HT_LINK_LKFAIL) -}; - -/************************************************************ - * PCI Bridge Interrupt and Bridge Control, DevA:0x3c - ************************************************************/ -#define REG_PCI_INTBRG_CTRL 0x3c -enum pci_intbrg_ctrl_bits { - PCI_INTBRG_CTRL_DTSERREN = BIT(27), - PCI_INTBRG_CTRL_DTSTAT = BIT(26), - PCI_INTBRG_CTRL_MARSP = BIT(21), - PCI_INTBRG_CTRL_SERREN = BIT(17), - PCI_INTBRG_CTRL_PEREN = BIT(16), - PCI_INTBRG_CTRL_CLEAR_MASK = (PCI_INTBRG_CTRL_DTSTAT), - PCI_INTBRG_CTRL_POLL_MASK = (PCI_INTBRG_CTRL_DTSERREN | - PCI_INTBRG_CTRL_MARSP | - PCI_INTBRG_CTRL_SERREN) -}; - -/************************************************************ - * I/O Control 1 Register, DevB:0x40 - ************************************************************/ -#define REG_IO_CTRL_1 0x40 -enum io_ctrl_1_bits { - IO_CTRL_1_NMIONERR = BIT(7), - IO_CTRL_1_LPC_ERR = BIT(6), - IO_CTRL_1_PW2LPC = BIT(1), - IO_CTRL_1_CLEAR_MASK = (IO_CTRL_1_LPC_ERR | IO_CTRL_1_PW2LPC) -}; - -/************************************************************ - * Legacy I/O Space Registers - ************************************************************/ -#define REG_AT_COMPAT 0x61 -enum at_compat_bits { - AT_COMPAT_SERR = BIT(7), - AT_COMPAT_IOCHK = BIT(6), - AT_COMPAT_CLRIOCHK = BIT(3), - AT_COMPAT_CLRSERR = BIT(2), -}; - -struct amd8111_dev_info { - u16 err_dev; /* PCI Device ID */ - struct pci_dev *dev; - int edac_idx; /* device index */ - char *ctl_name; - struct edac_device_ctl_info *edac_dev; - void (*init)(struct amd8111_dev_info *dev_info); - void (*exit)(struct amd8111_dev_info *dev_info); - void (*check)(struct edac_device_ctl_info *edac_dev); -}; - -struct amd8111_pci_info { - u16 err_dev; /* PCI Device ID */ - struct pci_dev *dev; - int edac_idx; /* pci index */ - const char *ctl_name; - struct edac_pci_ctl_info *edac_dev; - void (*init)(struct amd8111_pci_info *dev_info); - void (*exit)(struct amd8111_pci_info *dev_info); - void (*check)(struct edac_pci_ctl_info *edac_dev); -}; - -#endif /* _AMD8111_EDAC_H_ */ diff --git a/trunk/drivers/edac/amd8131_edac.c b/trunk/drivers/edac/amd8131_edac.c deleted file mode 100644 index c083b31cac5a..000000000000 --- a/trunk/drivers/edac/amd8131_edac.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * amd8131_edac.c, AMD8131 hypertransport chip EDAC kernel module - * - * Copyright (c) 2008 Wind River Systems, Inc. - * - * Authors: Cao Qingtao - * Benjamin Walsh - * Hu Yongqi - * - * 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 -#include -#include - -#include "edac_core.h" -#include "edac_module.h" -#include "amd8131_edac.h" - -#define AMD8131_EDAC_REVISION " Ver: 1.0.0 " __DATE__ -#define AMD8131_EDAC_MOD_STR "amd8131_edac" - -/* Wrapper functions for accessing PCI configuration space */ -static void edac_pci_read_dword(struct pci_dev *dev, int reg, u32 *val32) -{ - int ret; - - ret = pci_read_config_dword(dev, reg, val32); - if (ret != 0) - printk(KERN_ERR AMD8131_EDAC_MOD_STR - " PCI Access Read Error at 0x%x\n", reg); -} - -static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32) -{ - int ret; - - ret = pci_write_config_dword(dev, reg, val32); - if (ret != 0) - printk(KERN_ERR AMD8131_EDAC_MOD_STR - " PCI Access Write Error at 0x%x\n", reg); -} - -static char * const bridge_str[] = { - [NORTH_A] = "NORTH A", - [NORTH_B] = "NORTH B", - [SOUTH_A] = "SOUTH A", - [SOUTH_B] = "SOUTH B", - [NO_BRIDGE] = "NO BRIDGE", -}; - -/* Support up to two AMD8131 chipsets on a platform */ -static struct amd8131_dev_info amd8131_devices[] = { - { - .inst = NORTH_A, - .devfn = DEVFN_PCIX_BRIDGE_NORTH_A, - .ctl_name = "AMD8131_PCIX_NORTH_A", - }, - { - .inst = NORTH_B, - .devfn = DEVFN_PCIX_BRIDGE_NORTH_B, - .ctl_name = "AMD8131_PCIX_NORTH_B", - }, - { - .inst = SOUTH_A, - .devfn = DEVFN_PCIX_BRIDGE_SOUTH_A, - .ctl_name = "AMD8131_PCIX_SOUTH_A", - }, - { - .inst = SOUTH_B, - .devfn = DEVFN_PCIX_BRIDGE_SOUTH_B, - .ctl_name = "AMD8131_PCIX_SOUTH_B", - }, - {.inst = NO_BRIDGE,}, -}; - -static void amd8131_pcix_init(struct amd8131_dev_info *dev_info) -{ - u32 val32; - struct pci_dev *dev = dev_info->dev; - - /* First clear error detection flags */ - edac_pci_read_dword(dev, REG_MEM_LIM, &val32); - if (val32 & MEM_LIMIT_MASK) - edac_pci_write_dword(dev, REG_MEM_LIM, val32); - - /* Clear Discard Timer Timedout flag */ - edac_pci_read_dword(dev, REG_INT_CTLR, &val32); - if (val32 & INT_CTLR_DTS) - edac_pci_write_dword(dev, REG_INT_CTLR, val32); - - /* Clear CRC Error flag on link side A */ - edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32); - if (val32 & LNK_CTRL_CRCERR_A) - edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32); - - /* Clear CRC Error flag on link side B */ - edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32); - if (val32 & LNK_CTRL_CRCERR_B) - edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32); - - /* - * Then enable all error detections. - * - * Setup Discard Timer Sync Flood Enable, - * System Error Enable and Parity Error Enable. - */ - edac_pci_read_dword(dev, REG_INT_CTLR, &val32); - val32 |= INT_CTLR_PERR | INT_CTLR_SERR | INT_CTLR_DTSE; - edac_pci_write_dword(dev, REG_INT_CTLR, val32); - - /* Enable overall SERR Error detection */ - edac_pci_read_dword(dev, REG_STS_CMD, &val32); - val32 |= STS_CMD_SERREN; - edac_pci_write_dword(dev, REG_STS_CMD, val32); - - /* Setup CRC Flood Enable for link side A */ - edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32); - val32 |= LNK_CTRL_CRCFEN; - edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32); - - /* Setup CRC Flood Enable for link side B */ - edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32); - val32 |= LNK_CTRL_CRCFEN; - edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32); -} - -static void amd8131_pcix_exit(struct amd8131_dev_info *dev_info) -{ - u32 val32; - struct pci_dev *dev = dev_info->dev; - - /* Disable SERR, PERR and DTSE Error detection */ - edac_pci_read_dword(dev, REG_INT_CTLR, &val32); - val32 &= ~(INT_CTLR_PERR | INT_CTLR_SERR | INT_CTLR_DTSE); - edac_pci_write_dword(dev, REG_INT_CTLR, val32); - - /* Disable overall System Error detection */ - edac_pci_read_dword(dev, REG_STS_CMD, &val32); - val32 &= ~STS_CMD_SERREN; - edac_pci_write_dword(dev, REG_STS_CMD, val32); - - /* Disable CRC Sync Flood on link side A */ - edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32); - val32 &= ~LNK_CTRL_CRCFEN; - edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32); - - /* Disable CRC Sync Flood on link side B */ - edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32); - val32 &= ~LNK_CTRL_CRCFEN; - edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32); -} - -static void amd8131_pcix_check(struct edac_pci_ctl_info *edac_dev) -{ - struct amd8131_dev_info *dev_info = edac_dev->pvt_info; - struct pci_dev *dev = dev_info->dev; - u32 val32; - - /* Check PCI-X Bridge Memory Base-Limit Register for errors */ - edac_pci_read_dword(dev, REG_MEM_LIM, &val32); - if (val32 & MEM_LIMIT_MASK) { - printk(KERN_INFO "Error(s) in mem limit register " - "on %s bridge\n", dev_info->ctl_name); - printk(KERN_INFO "DPE: %d, RSE: %d, RMA: %d\n" - "RTA: %d, STA: %d, MDPE: %d\n", - val32 & MEM_LIMIT_DPE, - val32 & MEM_LIMIT_RSE, - val32 & MEM_LIMIT_RMA, - val32 & MEM_LIMIT_RTA, - val32 & MEM_LIMIT_STA, - val32 & MEM_LIMIT_MDPE); - - val32 |= MEM_LIMIT_MASK; - edac_pci_write_dword(dev, REG_MEM_LIM, val32); - - edac_pci_handle_npe(edac_dev, edac_dev->ctl_name); - } - - /* Check if Discard Timer timed out */ - edac_pci_read_dword(dev, REG_INT_CTLR, &val32); - if (val32 & INT_CTLR_DTS) { - printk(KERN_INFO "Error(s) in interrupt and control register " - "on %s bridge\n", dev_info->ctl_name); - printk(KERN_INFO "DTS: %d\n", val32 & INT_CTLR_DTS); - - val32 |= INT_CTLR_DTS; - edac_pci_write_dword(dev, REG_INT_CTLR, val32); - - edac_pci_handle_npe(edac_dev, edac_dev->ctl_name); - } - - /* Check if CRC error happens on link side A */ - edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32); - if (val32 & LNK_CTRL_CRCERR_A) { - printk(KERN_INFO "Error(s) in link conf and control register " - "on %s bridge\n", dev_info->ctl_name); - printk(KERN_INFO "CRCERR: %d\n", val32 & LNK_CTRL_CRCERR_A); - - val32 |= LNK_CTRL_CRCERR_A; - edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32); - - edac_pci_handle_npe(edac_dev, edac_dev->ctl_name); - } - - /* Check if CRC error happens on link side B */ - edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32); - if (val32 & LNK_CTRL_CRCERR_B) { - printk(KERN_INFO "Error(s) in link conf and control register " - "on %s bridge\n", dev_info->ctl_name); - printk(KERN_INFO "CRCERR: %d\n", val32 & LNK_CTRL_CRCERR_B); - - val32 |= LNK_CTRL_CRCERR_B; - edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32); - - edac_pci_handle_npe(edac_dev, edac_dev->ctl_name); - } -} - -static struct amd8131_info amd8131_chipset = { - .err_dev = PCI_DEVICE_ID_AMD_8131_APIC, - .devices = amd8131_devices, - .init = amd8131_pcix_init, - .exit = amd8131_pcix_exit, - .check = amd8131_pcix_check, -}; - -/* - * There are 4 PCIX Bridges on ATCA-6101 that share the same PCI Device ID, - * so amd8131_probe() would be called by kernel 4 times, with different - * address of pci_dev for each of them each time. - */ -static int amd8131_probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - struct amd8131_dev_info *dev_info; - - for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE; - dev_info++) - if (dev_info->devfn == dev->devfn) - break; - - if (dev_info->inst == NO_BRIDGE) /* should never happen */ - return -ENODEV; - - /* - * We can't call pci_get_device() as we are used to do because - * there are 4 of them but pci_dev_get() instead. - */ - dev_info->dev = pci_dev_get(dev); - - if (pci_enable_device(dev_info->dev)) { - pci_dev_put(dev_info->dev); - printk(KERN_ERR "failed to enable:" - "vendor %x, device %x, devfn %x, name %s\n", - PCI_VENDOR_ID_AMD, amd8131_chipset.err_dev, - dev_info->devfn, dev_info->ctl_name); - return -ENODEV; - } - - /* - * we do not allocate extra private structure for - * edac_pci_ctl_info, but make use of existing - * one instead. - */ - dev_info->edac_idx = edac_pci_alloc_index(); - dev_info->edac_dev = edac_pci_alloc_ctl_info(0, dev_info->ctl_name); - if (!dev_info->edac_dev) - return -ENOMEM; - - dev_info->edac_dev->pvt_info = dev_info; - dev_info->edac_dev->dev = &dev_info->dev->dev; - dev_info->edac_dev->mod_name = AMD8131_EDAC_MOD_STR; - dev_info->edac_dev->ctl_name = dev_info->ctl_name; - dev_info->edac_dev->dev_name = dev_info->dev->dev.bus_id; - - if (edac_op_state == EDAC_OPSTATE_POLL) - dev_info->edac_dev->edac_check = amd8131_chipset.check; - - if (amd8131_chipset.init) - amd8131_chipset.init(dev_info); - - if (edac_pci_add_device(dev_info->edac_dev, dev_info->edac_idx) > 0) { - printk(KERN_ERR "failed edac_pci_add_device() for %s\n", - dev_info->ctl_name); - edac_pci_free_ctl_info(dev_info->edac_dev); - return -ENODEV; - } - - printk(KERN_INFO "added one device on AMD8131 " - "vendor %x, device %x, devfn %x, name %s\n", - PCI_VENDOR_ID_AMD, amd8131_chipset.err_dev, - dev_info->devfn, dev_info->ctl_name); - - return 0; -} - -static void amd8131_remove(struct pci_dev *dev) -{ - struct amd8131_dev_info *dev_info; - - for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE; - dev_info++) - if (dev_info->devfn == dev->devfn) - break; - - if (dev_info->inst == NO_BRIDGE) /* should never happen */ - return; - - if (dev_info->edac_dev) { - edac_pci_del_device(dev_info->edac_dev->dev); - edac_pci_free_ctl_info(dev_info->edac_dev); - } - - if (amd8131_chipset.exit) - amd8131_chipset.exit(dev_info); - - pci_dev_put(dev_info->dev); -} - -static const struct pci_device_id amd8131_edac_pci_tbl[] = { - { - PCI_VEND_DEV(AMD, 8131_BRIDGE), - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .class = 0, - .class_mask = 0, - .driver_data = 0, - }, - { - 0, - } /* table is NULL-terminated */ -}; -MODULE_DEVICE_TABLE(pci, amd8131_edac_pci_tbl); - -static struct pci_driver amd8131_edac_driver = { - .name = AMD8131_EDAC_MOD_STR, - .probe = amd8131_probe, - .remove = amd8131_remove, - .id_table = amd8131_edac_pci_tbl, -}; - -static int __init amd8131_edac_init(void) -{ - printk(KERN_INFO "AMD8131 EDAC driver " AMD8131_EDAC_REVISION "\n"); - printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc.\n"); - - /* Only POLL mode supported so far */ - edac_op_state = EDAC_OPSTATE_POLL; - - return pci_register_driver(&amd8131_edac_driver); -} - -static void __exit amd8131_edac_exit(void) -{ - pci_unregister_driver(&amd8131_edac_driver); -} - -module_init(amd8131_edac_init); -module_exit(amd8131_edac_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Cao Qingtao \n"); -MODULE_DESCRIPTION("AMD8131 HyperTransport PCI-X Tunnel EDAC kernel module"); diff --git a/trunk/drivers/edac/amd8131_edac.h b/trunk/drivers/edac/amd8131_edac.h deleted file mode 100644 index 60e0d1c72dee..000000000000 --- a/trunk/drivers/edac/amd8131_edac.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * amd8131_edac.h, EDAC defs for AMD8131 hypertransport chip - * - * Copyright (c) 2008 Wind River Systems, Inc. - * - * Authors: Cao Qingtao - * Benjamin Walsh - * Hu Yongqi - * - * 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 - */ - -#ifndef _AMD8131_EDAC_H_ -#define _AMD8131_EDAC_H_ - -#define DEVFN_PCIX_BRIDGE_NORTH_A 8 -#define DEVFN_PCIX_BRIDGE_NORTH_B 16 -#define DEVFN_PCIX_BRIDGE_SOUTH_A 24 -#define DEVFN_PCIX_BRIDGE_SOUTH_B 32 - -/************************************************************ - * PCI-X Bridge Status and Command Register, DevA:0x04 - ************************************************************/ -#define REG_STS_CMD 0x04 -enum sts_cmd_bits { - STS_CMD_SSE = BIT(30), - STS_CMD_SERREN = BIT(8) -}; - -/************************************************************ - * PCI-X Bridge Interrupt and Bridge Control Register, - ************************************************************/ -#define REG_INT_CTLR 0x3c -enum int_ctlr_bits { - INT_CTLR_DTSE = BIT(27), - INT_CTLR_DTS = BIT(26), - INT_CTLR_SERR = BIT(17), - INT_CTLR_PERR = BIT(16) -}; - -/************************************************************ - * PCI-X Bridge Memory Base-Limit Register, DevA:0x1C - ************************************************************/ -#define REG_MEM_LIM 0x1c -enum mem_limit_bits { - MEM_LIMIT_DPE = BIT(31), - MEM_LIMIT_RSE = BIT(30), - MEM_LIMIT_RMA = BIT(29), - MEM_LIMIT_RTA = BIT(28), - MEM_LIMIT_STA = BIT(27), - MEM_LIMIT_MDPE = BIT(24), - MEM_LIMIT_MASK = MEM_LIMIT_DPE|MEM_LIMIT_RSE|MEM_LIMIT_RMA| - MEM_LIMIT_RTA|MEM_LIMIT_STA|MEM_LIMIT_MDPE -}; - -/************************************************************ - * Link Configuration And Control Register, side A - ************************************************************/ -#define REG_LNK_CTRL_A 0xc4 - -/************************************************************ - * Link Configuration And Control Register, side B - ************************************************************/ -#define REG_LNK_CTRL_B 0xc8 - -enum lnk_ctrl_bits { - LNK_CTRL_CRCERR_A = BIT(9), - LNK_CTRL_CRCERR_B = BIT(8), - LNK_CTRL_CRCFEN = BIT(1) -}; - -enum pcix_bridge_inst { - NORTH_A = 0, - NORTH_B = 1, - SOUTH_A = 2, - SOUTH_B = 3, - NO_BRIDGE = 4 -}; - -struct amd8131_dev_info { - int devfn; - enum pcix_bridge_inst inst; - struct pci_dev *dev; - int edac_idx; /* pci device index */ - char *ctl_name; - struct edac_pci_ctl_info *edac_dev; -}; - -/* - * AMD8131 chipset has two pairs of PCIX Bridge and related IOAPIC - * Controler, and ATCA-6101 has two AMD8131 chipsets, so there are - * four PCIX Bridges on ATCA-6101 altogether. - * - * These PCIX Bridges share the same PCI Device ID and are all of - * Function Zero, they could be discrimated by their pci_dev->devfn. - * They share the same set of init/check/exit methods, and their - * private structures are collected in the devices[] array. - */ -struct amd8131_info { - u16 err_dev; /* PCI Device ID for AMD8131 APIC*/ - struct amd8131_dev_info *devices; - void (*init)(struct amd8131_dev_info *dev_info); - void (*exit)(struct amd8131_dev_info *dev_info); - void (*check)(struct edac_pci_ctl_info *edac_dev); -}; - -#endif /* _AMD8131_EDAC_H_ */ - diff --git a/trunk/drivers/edac/edac_core.h b/trunk/drivers/edac/edac_core.h index 28f2c3f959b5..4b55ec607a88 100644 --- a/trunk/drivers/edac/edac_core.h +++ b/trunk/drivers/edac/edac_core.h @@ -49,10 +49,6 @@ #define edac_printk(level, prefix, fmt, arg...) \ printk(level "EDAC " prefix ": " fmt, ##arg) -#define edac_printk_verbose(level, prefix, fmt, arg...) \ - printk(level "EDAC " prefix ": " "in %s, line at %d: " fmt, \ - __FILE__, __LINE__, ##arg) - #define edac_mc_printk(mci, level, fmt, arg...) \ printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg) @@ -75,20 +71,11 @@ #ifdef CONFIG_EDAC_DEBUG extern int edac_debug_level; -#ifndef CONFIG_EDAC_DEBUG_VERBOSE #define edac_debug_printk(level, fmt, arg...) \ do { \ if (level <= edac_debug_level) \ edac_printk(KERN_DEBUG, EDAC_DEBUG, fmt, ##arg); \ - } while (0) -#else /* CONFIG_EDAC_DEBUG_VERBOSE */ -#define edac_debug_printk(level, fmt, arg...) \ - do { \ - if (level <= edac_debug_level) \ - edac_printk_verbose(KERN_DEBUG, EDAC_DEBUG, fmt, \ - ##arg); \ - } while (0) -#endif + } while(0) #define debugf0( ... ) edac_debug_printk(0, __VA_ARGS__ ) #define debugf1( ... ) edac_debug_printk(1, __VA_ARGS__ ) @@ -844,7 +831,6 @@ extern void edac_pci_free_ctl_info(struct edac_pci_ctl_info *pci); extern void edac_pci_reset_delay_period(struct edac_pci_ctl_info *pci, unsigned long value); -extern int edac_pci_alloc_index(void); extern int edac_pci_add_device(struct edac_pci_ctl_info *pci, int edac_idx); extern struct edac_pci_ctl_info *edac_pci_del_device(struct device *dev); diff --git a/trunk/drivers/edac/edac_pci.c b/trunk/drivers/edac/edac_pci.c index 5b150aea703a..5d3c8083a40e 100644 --- a/trunk/drivers/edac/edac_pci.c +++ b/trunk/drivers/edac/edac_pci.c @@ -30,7 +30,6 @@ static DEFINE_MUTEX(edac_pci_ctls_mutex); static LIST_HEAD(edac_pci_list); -static atomic_t pci_indexes = ATOMIC_INIT(0); /* * edac_pci_alloc_ctl_info @@ -318,19 +317,6 @@ void edac_pci_reset_delay_period(struct edac_pci_ctl_info *pci, } EXPORT_SYMBOL_GPL(edac_pci_reset_delay_period); -/* - * edac_pci_alloc_index: Allocate a unique PCI index number - * - * Return: - * allocated index number - * - */ -int edac_pci_alloc_index(void) -{ - return atomic_inc_return(&pci_indexes) - 1; -} -EXPORT_SYMBOL_GPL(edac_pci_alloc_index); - /* * edac_pci_add_device: Insert the 'edac_dev' structure into the * edac_pci global list and create sysfs entries associated with diff --git a/trunk/drivers/edac/ppc4xx_edac.c b/trunk/drivers/edac/ppc4xx_edac.c deleted file mode 100644 index 11f2172aa1e6..000000000000 --- a/trunk/drivers/edac/ppc4xx_edac.c +++ /dev/null @@ -1,1448 +0,0 @@ -/* - * Copyright (c) 2008 Nuovation System Designs, LLC - * Grant Erickson - * - * 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 of the - * License. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "edac_core.h" -#include "ppc4xx_edac.h" - -/* - * This file implements a driver for monitoring and handling events - * associated with the IMB DDR2 ECC controller found in the AMCC/IBM - * 405EX[r], 440SP, 440SPe, 460EX, 460GT and 460SX. - * - * As realized in the 405EX[r], this controller features: - * - * - Support for registered- and non-registered DDR1 and DDR2 memory. - * - 32-bit or 16-bit memory interface with optional ECC. - * - * o ECC support includes: - * - * - 4-bit SEC/DED - * - Aligned-nibble error detect - * - Bypass mode - * - * - Two (2) memory banks/ranks. - * - Up to 1 GiB per bank/rank in 32-bit mode and up to 512 MiB per - * bank/rank in 16-bit mode. - * - * As realized in the 440SP and 440SPe, this controller changes/adds: - * - * - 64-bit or 32-bit memory interface with optional ECC. - * - * o ECC support includes: - * - * - 8-bit SEC/DED - * - Aligned-nibble error detect - * - Bypass mode - * - * - Up to 4 GiB per bank/rank in 64-bit mode and up to 2 GiB - * per bank/rank in 32-bit mode. - * - * As realized in the 460EX and 460GT, this controller changes/adds: - * - * - 64-bit or 32-bit memory interface with optional ECC. - * - * o ECC support includes: - * - * - 8-bit SEC/DED - * - Aligned-nibble error detect - * - Bypass mode - * - * - Four (4) memory banks/ranks. - * - Up to 16 GiB per bank/rank in 64-bit mode and up to 8 GiB - * per bank/rank in 32-bit mode. - * - * At present, this driver has ONLY been tested against the controller - * realization in the 405EX[r] on the AMCC Kilauea and Haleakala - * boards (256 MiB w/o ECC memory soldered onto the board) and a - * proprietary board based on those designs (128 MiB ECC memory, also - * soldered onto the board). - * - * Dynamic feature detection and handling needs to be added for the - * other realizations of this controller listed above. - * - * Eventually, this driver will likely be adapted to the above variant - * realizations of this controller as well as broken apart to handle - * the other known ECC-capable controllers prevalent in other 4xx - * processors: - * - * - IBM SDRAM (405GP, 405CR and 405EP) "ibm,sdram-4xx" - * - IBM DDR1 (440GP, 440GX, 440EP and 440GR) "ibm,sdram-4xx-ddr" - * - Denali DDR1/DDR2 (440EPX and 440GRX) "denali,sdram-4xx-ddr2" - * - * For this controller, unfortunately, correctable errors report - * nothing more than the beat/cycle and byte/lane the correction - * occurred on and the check bit group that covered the error. - * - * In contrast, uncorrectable errors also report the failing address, - * the bus master and the transaction direction (i.e. read or write) - * - * Regardless of whether the error is a CE or a UE, we report the - * following pieces of information in the driver-unique message to the - * EDAC subsystem: - * - * - Device tree path - * - Bank(s) - * - Check bit error group - * - Beat(s)/lane(s) - */ - -/* Preprocessor Definitions */ - -#define EDAC_OPSTATE_INT_STR "interrupt" -#define EDAC_OPSTATE_POLL_STR "polled" -#define EDAC_OPSTATE_UNKNOWN_STR "unknown" - -#define PPC4XX_EDAC_MODULE_NAME "ppc4xx_edac" -#define PPC4XX_EDAC_MODULE_REVISION "v1.0.0 " __DATE__ - -#define PPC4XX_EDAC_MESSAGE_SIZE 256 - -/* - * Kernel logging without an EDAC instance - */ -#define ppc4xx_edac_printk(level, fmt, arg...) \ - edac_printk(level, "PPC4xx MC", fmt, ##arg) - -/* - * Kernel logging with an EDAC instance - */ -#define ppc4xx_edac_mc_printk(level, mci, fmt, arg...) \ - edac_mc_chipset_printk(mci, level, "PPC4xx", fmt, ##arg) - -/* - * Macros to convert bank configuration size enumerations into MiB and - * page values. - */ -#define SDRAM_MBCF_SZ_MiB_MIN 4 -#define SDRAM_MBCF_SZ_TO_MiB(n) (SDRAM_MBCF_SZ_MiB_MIN \ - << (SDRAM_MBCF_SZ_DECODE(n))) -#define SDRAM_MBCF_SZ_TO_PAGES(n) (SDRAM_MBCF_SZ_MiB_MIN \ - << (20 - PAGE_SHIFT + \ - SDRAM_MBCF_SZ_DECODE(n))) - -/* - * The ibm,sdram-4xx-ddr2 Device Control Registers (DCRs) are - * indirectly acccessed and have a base and length defined by the - * device tree. The base can be anything; however, we expect the - * length to be precisely two registers, the first for the address - * window and the second for the data window. - */ -#define SDRAM_DCR_RESOURCE_LEN 2 -#define SDRAM_DCR_ADDR_OFFSET 0 -#define SDRAM_DCR_DATA_OFFSET 1 - -/* - * Device tree interrupt indices - */ -#define INTMAP_ECCDED_INDEX 0 /* Double-bit Error Detect */ -#define INTMAP_ECCSEC_INDEX 1 /* Single-bit Error Correct */ - -/* Type Definitions */ - -/* - * PPC4xx SDRAM memory controller private instance data - */ -struct ppc4xx_edac_pdata { - dcr_host_t dcr_host; /* Indirect DCR address/data window mapping */ - struct { - int sec; /* Single-bit correctable error IRQ assigned */ - int ded; /* Double-bit detectable error IRQ assigned */ - } irqs; -}; - -/* - * Various status data gathered and manipulated when checking and - * reporting ECC status. - */ -struct ppc4xx_ecc_status { - u32 ecces; - u32 besr; - u32 bearh; - u32 bearl; - u32 wmirq; -}; - -/* Function Prototypes */ - -static int ppc4xx_edac_probe(struct of_device *device, - const struct of_device_id *device_id); -static int ppc4xx_edac_remove(struct of_device *device); - -/* Global Variables */ - -/* - * Device tree node type and compatible tuples this driver can match - * on. - */ -static struct of_device_id ppc4xx_edac_match[] = { - { - .compatible = "ibm,sdram-4xx-ddr2" - }, - { } -}; - -static struct of_platform_driver ppc4xx_edac_driver = { - .match_table = ppc4xx_edac_match, - .probe = ppc4xx_edac_probe, - .remove = ppc4xx_edac_remove, - .driver = { - .owner = THIS_MODULE, - .name = PPC4XX_EDAC_MODULE_NAME - } -}; - -/* - * TODO: The row and channel parameters likely need to be dynamically - * set based on the aforementioned variant controller realizations. - */ -static const unsigned ppc4xx_edac_nr_csrows = 2; -static const unsigned ppc4xx_edac_nr_chans = 1; - -/* - * Strings associated with PLB master IDs capable of being posted in - * SDRAM_BESR or SDRAM_WMIRQ on uncorrectable ECC errors. - */ -static const char * const ppc4xx_plb_masters[9] = { - [SDRAM_PLB_M0ID_ICU] = "ICU", - [SDRAM_PLB_M0ID_PCIE0] = "PCI-E 0", - [SDRAM_PLB_M0ID_PCIE1] = "PCI-E 1", - [SDRAM_PLB_M0ID_DMA] = "DMA", - [SDRAM_PLB_M0ID_DCU] = "DCU", - [SDRAM_PLB_M0ID_OPB] = "OPB", - [SDRAM_PLB_M0ID_MAL] = "MAL", - [SDRAM_PLB_M0ID_SEC] = "SEC", - [SDRAM_PLB_M0ID_AHB] = "AHB" -}; - -/** - * mfsdram - read and return controller register data - * @dcr_host: A pointer to the DCR mapping. - * @idcr_n: The indirect DCR register to read. - * - * This routine reads and returns the data associated with the - * controller's specified indirect DCR register. - * - * Returns the read data. - */ -static inline u32 -mfsdram(const dcr_host_t *dcr_host, unsigned int idcr_n) -{ - return __mfdcri(dcr_host->base + SDRAM_DCR_ADDR_OFFSET, - dcr_host->base + SDRAM_DCR_DATA_OFFSET, - idcr_n); -} - -/** - * mtsdram - write controller register data - * @dcr_host: A pointer to the DCR mapping. - * @idcr_n: The indirect DCR register to write. - * @value: The data to write. - * - * This routine writes the provided data to the controller's specified - * indirect DCR register. - */ -static inline void -mtsdram(const dcr_host_t *dcr_host, unsigned int idcr_n, u32 value) -{ - return __mtdcri(dcr_host->base + SDRAM_DCR_ADDR_OFFSET, - dcr_host->base + SDRAM_DCR_DATA_OFFSET, - idcr_n, - value); -} - -/** - * ppc4xx_edac_check_bank_error - check a bank for an ECC bank error - * @status: A pointer to the ECC status structure to check for an - * ECC bank error. - * @bank: The bank to check for an ECC error. - * - * This routine determines whether the specified bank has an ECC - * error. - * - * Returns true if the specified bank has an ECC error; otherwise, - * false. - */ -static bool -ppc4xx_edac_check_bank_error(const struct ppc4xx_ecc_status *status, - unsigned int bank) -{ - switch (bank) { - case 0: - return status->ecces & SDRAM_ECCES_BK0ER; - case 1: - return status->ecces & SDRAM_ECCES_BK1ER; - default: - return false; - } -} - -/** - * ppc4xx_edac_generate_bank_message - generate interpretted bank status message - * @mci: A pointer to the EDAC memory controller instance associated - * with the bank message being generated. - * @status: A pointer to the ECC status structure to generate the - * message from. - * @buffer: A pointer to the buffer in which to generate the - * message. - * @size: The size, in bytes, of space available in buffer. - * - * This routine generates to the provided buffer the portion of the - * driver-unique report message associated with the ECCESS[BKNER] - * field of the specified ECC status. - * - * Returns the number of characters generated on success; otherwise, < - * 0 on error. - */ -static int -ppc4xx_edac_generate_bank_message(const struct mem_ctl_info *mci, - const struct ppc4xx_ecc_status *status, - char *buffer, - size_t size) -{ - int n, total = 0; - unsigned int row, rows; - - n = snprintf(buffer, size, "%s: Banks: ", mci->dev_name); - - if (n < 0 || n >= size) - goto fail; - - buffer += n; - size -= n; - total += n; - - for (rows = 0, row = 0; row < mci->nr_csrows; row++) { - if (ppc4xx_edac_check_bank_error(status, row)) { - n = snprintf(buffer, size, "%s%u", - (rows++ ? ", " : ""), row); - - if (n < 0 || n >= size) - goto fail; - - buffer += n; - size -= n; - total += n; - } - } - - n = snprintf(buffer, size, "%s; ", rows ? "" : "None"); - - if (n < 0 || n >= size) - goto fail; - - buffer += n; - size -= n; - total += n; - - fail: - return total; -} - -/** - * ppc4xx_edac_generate_checkbit_message - generate interpretted checkbit message - * @mci: A pointer to the EDAC memory controller instance associated - * with the checkbit message being generated. - * @status: A pointer to the ECC status structure to generate the - * message from. - * @buffer: A pointer to the buffer in which to generate the - * message. - * @size: The size, in bytes, of space available in buffer. - * - * This routine generates to the provided buffer the portion of the - * driver-unique report message associated with the ECCESS[CKBER] - * field of the specified ECC status. - * - * Returns the number of characters generated on success; otherwise, < - * 0 on error. - */ -static int -ppc4xx_edac_generate_checkbit_message(const struct mem_ctl_info *mci, - const struct ppc4xx_ecc_status *status, - char *buffer, - size_t size) -{ - const struct ppc4xx_edac_pdata *pdata = mci->pvt_info; - const char *ckber = NULL; - - switch (status->ecces & SDRAM_ECCES_CKBER_MASK) { - case SDRAM_ECCES_CKBER_NONE: - ckber = "None"; - break; - case SDRAM_ECCES_CKBER_32_ECC_0_3: - ckber = "ECC0:3"; - break; - case SDRAM_ECCES_CKBER_32_ECC_4_8: - switch (mfsdram(&pdata->dcr_host, SDRAM_MCOPT1) & - SDRAM_MCOPT1_WDTH_MASK) { - case SDRAM_MCOPT1_WDTH_16: - ckber = "ECC0:3"; - break; - case SDRAM_MCOPT1_WDTH_32: - ckber = "ECC4:8"; - break; - default: - ckber = "Unknown"; - break; - } - break; - case SDRAM_ECCES_CKBER_32_ECC_0_8: - ckber = "ECC0:8"; - break; - default: - ckber = "Unknown"; - break; - } - - return snprintf(buffer, size, "Checkbit Error: %s", ckber); -} - -/** - * ppc4xx_edac_generate_lane_message - generate interpretted byte lane message - * @mci: A pointer to the EDAC memory controller instance associated - * with the byte lane message being generated. - * @status: A pointer to the ECC status structure to generate the - * message from. - * @buffer: A pointer to the buffer in which to generate the - * message. - * @size: The size, in bytes, of space available in buffer. - * - * This routine generates to the provided buffer the portion of the - * driver-unique report message associated with the ECCESS[BNCE] - * field of the specified ECC status. - * - * Returns the number of characters generated on success; otherwise, < - * 0 on error. - */ -static int -ppc4xx_edac_generate_lane_message(const struct mem_ctl_info *mci, - const struct ppc4xx_ecc_status *status, - char *buffer, - size_t size) -{ - int n, total = 0; - unsigned int lane, lanes; - const unsigned int first_lane = 0; - const unsigned int lane_count = 16; - - n = snprintf(buffer, size, "; Byte Lane Errors: "); - - if (n < 0 || n >= size) - goto fail; - - buffer += n; - size -= n; - total += n; - - for (lanes = 0, lane = first_lane; lane < lane_count; lane++) { - if ((status->ecces & SDRAM_ECCES_BNCE_ENCODE(lane)) != 0) { - n = snprintf(buffer, size, - "%s%u", - (lanes++ ? ", " : ""), lane); - - if (n < 0 || n >= size) - goto fail; - - buffer += n; - size -= n; - total += n; - } - } - - n = snprintf(buffer, size, "%s; ", lanes ? "" : "None"); - - if (n < 0 || n >= size) - goto fail; - - buffer += n; - size -= n; - total += n; - - fail: - return total; -} - -/** - * ppc4xx_edac_generate_ecc_message - generate interpretted ECC status message - * @mci: A pointer to the EDAC memory controller instance associated - * with the ECCES message being generated. - * @status: A pointer to the ECC status structure to generate the - * message from. - * @buffer: A pointer to the buffer in which to generate the - * message. - * @size: The size, in bytes, of space available in buffer. - * - * This routine generates to the provided buffer the portion of the - * driver-unique report message associated with the ECCESS register of - * the specified ECC status. - * - * Returns the number of characters generated on success; otherwise, < - * 0 on error. - */ -static int -ppc4xx_edac_generate_ecc_message(const struct mem_ctl_info *mci, - const struct ppc4xx_ecc_status *status, - char *buffer, - size_t size) -{ - int n, total = 0; - - n = ppc4xx_edac_generate_bank_message(mci, status, buffer, size); - - if (n < 0 || n >= size) - goto fail; - - buffer += n; - size -= n; - total += n; - - n = ppc4xx_edac_generate_checkbit_message(mci, status, buffer, size); - - if (n < 0 || n >= size) - goto fail; - - buffer += n; - size -= n; - total += n; - - n = ppc4xx_edac_generate_lane_message(mci, status, buffer, size); - - if (n < 0 || n >= size) - goto fail; - - buffer += n; - size -= n; - total += n; - - fail: - return total; -} - -/** - * ppc4xx_edac_generate_plb_message - generate interpretted PLB status message - * @mci: A pointer to the EDAC memory controller instance associated - * with the PLB message being generated. - * @status: A pointer to the ECC status structure to generate the - * message from. - * @buffer: A pointer to the buffer in which to generate the - * message. - * @size: The size, in bytes, of space available in buffer. - * - * This routine generates to the provided buffer the portion of the - * driver-unique report message associated with the PLB-related BESR - * and/or WMIRQ registers of the specified ECC status. - * - * Returns the number of characters generated on success; otherwise, < - * 0 on error. - */ -static int -ppc4xx_edac_generate_plb_message(const struct mem_ctl_info *mci, - const struct ppc4xx_ecc_status *status, - char *buffer, - size_t size) -{ - unsigned int master; - bool read; - - if ((status->besr & SDRAM_BESR_MASK) == 0) - return 0; - - if ((status->besr & SDRAM_BESR_M0ET_MASK) == SDRAM_BESR_M0ET_NONE) - return 0; - - read = ((status->besr & SDRAM_BESR_M0RW_MASK) == SDRAM_BESR_M0RW_READ); - - master = SDRAM_BESR_M0ID_DECODE(status->besr); - - return snprintf(buffer, size, - "%s error w/ PLB master %u \"%s\"; ", - (read ? "Read" : "Write"), - master, - (((master >= SDRAM_PLB_M0ID_FIRST) && - (master <= SDRAM_PLB_M0ID_LAST)) ? - ppc4xx_plb_masters[master] : "UNKNOWN")); -} - -/** - * ppc4xx_edac_generate_message - generate interpretted status message - * @mci: A pointer to the EDAC memory controller instance associated - * with the driver-unique message being generated. - * @status: A pointer to the ECC status structure to generate the - * message from. - * @buffer: A pointer to the buffer in which to generate the - * message. - * @size: The size, in bytes, of space available in buffer. - * - * This routine generates to the provided buffer the driver-unique - * EDAC report message from the specified ECC status. - */ -static void -ppc4xx_edac_generate_message(const struct mem_ctl_info *mci, - const struct ppc4xx_ecc_status *status, - char *buffer, - size_t size) -{ - int n; - - if (buffer == NULL || size == 0) - return; - - n = ppc4xx_edac_generate_ecc_message(mci, status, buffer, size); - - if (n < 0 || n >= size) - return; - - buffer += n; - size -= n; - - ppc4xx_edac_generate_plb_message(mci, status, buffer, size); -} - -#ifdef DEBUG -/** - * ppc4xx_ecc_dump_status - dump controller ECC status registers - * @mci: A pointer to the EDAC memory controller instance - * associated with the status being dumped. - * @status: A pointer to the ECC status structure to generate the - * dump from. - * - * This routine dumps to the kernel log buffer the raw and - * interpretted specified ECC status. - */ -static void -ppc4xx_ecc_dump_status(const struct mem_ctl_info *mci, - const struct ppc4xx_ecc_status *status) -{ - char message[PPC4XX_EDAC_MESSAGE_SIZE]; - - ppc4xx_edac_generate_message(mci, status, message, sizeof(message)); - - ppc4xx_edac_mc_printk(KERN_INFO, mci, - "\n" - "\tECCES: 0x%08x\n" - "\tWMIRQ: 0x%08x\n" - "\tBESR: 0x%08x\n" - "\tBEAR: 0x%08x%08x\n" - "\t%s\n", - status->ecces, - status->wmirq, - status->besr, - status->bearh, - status->bearl, - message); -} -#endif /* DEBUG */ - -/** - * ppc4xx_ecc_get_status - get controller ECC status - * @mci: A pointer to the EDAC memory controller instance - * associated with the status being retrieved. - * @status: A pointer to the ECC status structure to populate the - * ECC status with. - * - * This routine reads and masks, as appropriate, all the relevant - * status registers that deal with ibm,sdram-4xx-ddr2 ECC errors. - * While we read all of them, for correctable errors, we only expect - * to deal with ECCES. For uncorrectable errors, we expect to deal - * with all of them. - */ -static void -ppc4xx_ecc_get_status(const struct mem_ctl_info *mci, - struct ppc4xx_ecc_status *status) -{ - const struct ppc4xx_edac_pdata *pdata = mci->pvt_info; - const dcr_host_t *dcr_host = &pdata->dcr_host; - - status->ecces = mfsdram(dcr_host, SDRAM_ECCES) & SDRAM_ECCES_MASK; - status->wmirq = mfsdram(dcr_host, SDRAM_WMIRQ) & SDRAM_WMIRQ_MASK; - status->besr = mfsdram(dcr_host, SDRAM_BESR) & SDRAM_BESR_MASK; - status->bearl = mfsdram(dcr_host, SDRAM_BEARL); - status->bearh = mfsdram(dcr_host, SDRAM_BEARH); -} - -/** - * ppc4xx_ecc_clear_status - clear controller ECC status - * @mci: A pointer to the EDAC memory controller instance - * associated with the status being cleared. - * @status: A pointer to the ECC status structure containing the - * values to write to clear the ECC status. - * - * This routine clears--by writing the masked (as appropriate) status - * values back to--the status registers that deal with - * ibm,sdram-4xx-ddr2 ECC errors. - */ -static void -ppc4xx_ecc_clear_status(const struct mem_ctl_info *mci, - const struct ppc4xx_ecc_status *status) -{ - const struct ppc4xx_edac_pdata *pdata = mci->pvt_info; - const dcr_host_t *dcr_host = &pdata->dcr_host; - - mtsdram(dcr_host, SDRAM_ECCES, status->ecces & SDRAM_ECCES_MASK); - mtsdram(dcr_host, SDRAM_WMIRQ, status->wmirq & SDRAM_WMIRQ_MASK); - mtsdram(dcr_host, SDRAM_BESR, status->besr & SDRAM_BESR_MASK); - mtsdram(dcr_host, SDRAM_BEARL, 0); - mtsdram(dcr_host, SDRAM_BEARH, 0); -} - -/** - * ppc4xx_edac_handle_ce - handle controller correctable ECC error (CE) - * @mci: A pointer to the EDAC memory controller instance - * associated with the correctable error being handled and reported. - * @status: A pointer to the ECC status structure associated with - * the correctable error being handled and reported. - * - * This routine handles an ibm,sdram-4xx-ddr2 controller ECC - * correctable error. Per the aforementioned discussion, there's not - * enough status available to use the full EDAC correctable error - * interface, so we just pass driver-unique message to the "no info" - * interface. - */ -static void -ppc4xx_edac_handle_ce(struct mem_ctl_info *mci, - const struct ppc4xx_ecc_status *status) -{ - int row; - char message[PPC4XX_EDAC_MESSAGE_SIZE]; - - ppc4xx_edac_generate_message(mci, status, message, sizeof(message)); - - for (row = 0; row < mci->nr_csrows; row++) - if (ppc4xx_edac_check_bank_error(status, row)) - edac_mc_handle_ce_no_info(mci, message); -} - -/** - * ppc4xx_edac_handle_ue - handle controller uncorrectable ECC error (UE) - * @mci: A pointer to the EDAC memory controller instance - * associated with the uncorrectable error being handled and - * reported. - * @status: A pointer to the ECC status structure associated with - * the uncorrectable error being handled and reported. - * - * This routine handles an ibm,sdram-4xx-ddr2 controller ECC - * uncorrectable error. - */ -static void -ppc4xx_edac_handle_ue(struct mem_ctl_info *mci, - const struct ppc4xx_ecc_status *status) -{ - const u64 bear = ((u64)status->bearh << 32 | status->bearl); - const unsigned long page = bear >> PAGE_SHIFT; - const unsigned long offset = bear & ~PAGE_MASK; - int row; - char message[PPC4XX_EDAC_MESSAGE_SIZE]; - - ppc4xx_edac_generate_message(mci, status, message, sizeof(message)); - - for (row = 0; row < mci->nr_csrows; row++) - if (ppc4xx_edac_check_bank_error(status, row)) - edac_mc_handle_ue(mci, page, offset, row, message); -} - -/** - * ppc4xx_edac_check - check controller for ECC errors - * @mci: A pointer to the EDAC memory controller instance - * associated with the ibm,sdram-4xx-ddr2 controller being - * checked. - * - * This routine is used to check and post ECC errors and is called by - * both the EDAC polling thread and this driver's CE and UE interrupt - * handler. - */ -static void -ppc4xx_edac_check(struct mem_ctl_info *mci) -{ -#ifdef DEBUG - static unsigned int count; -#endif - struct ppc4xx_ecc_status status; - - ppc4xx_ecc_get_status(mci, &status); - -#ifdef DEBUG - if (count++ % 30 == 0) - ppc4xx_ecc_dump_status(mci, &status); -#endif - - if (status.ecces & SDRAM_ECCES_UE) - ppc4xx_edac_handle_ue(mci, &status); - - if (status.ecces & SDRAM_ECCES_CE) - ppc4xx_edac_handle_ce(mci, &status); - - ppc4xx_ecc_clear_status(mci, &status); -} - -/** - * ppc4xx_edac_isr - SEC (CE) and DED (UE) interrupt service routine - * @irq: The virtual interrupt number being serviced. - * @dev_id: A pointer to the EDAC memory controller instance - * associated with the interrupt being handled. - * - * This routine implements the interrupt handler for both correctable - * (CE) and uncorrectable (UE) ECC errors for the ibm,sdram-4xx-ddr2 - * controller. It simply calls through to the same routine used during - * polling to check, report and clear the ECC status. - * - * Unconditionally returns IRQ_HANDLED. - */ -static irqreturn_t -ppc4xx_edac_isr(int irq, void *dev_id) -{ - struct mem_ctl_info *mci = dev_id; - - ppc4xx_edac_check(mci); - - return IRQ_HANDLED; -} - -/** - * ppc4xx_edac_get_dtype - return the controller memory width - * @mcopt1: The 32-bit Memory Controller Option 1 register value - * currently set for the controller, from which the width - * is derived. - * - * This routine returns the EDAC device type width appropriate for the - * current controller configuration. - * - * TODO: This needs to be conditioned dynamically through feature - * flags or some such when other controller variants are supported as - * the 405EX[r] is 16-/32-bit and the others are 32-/64-bit with the - * 16- and 64-bit field definition/value/enumeration (b1) overloaded - * among them. - * - * Returns a device type width enumeration. - */ -static enum dev_type __devinit -ppc4xx_edac_get_dtype(u32 mcopt1) -{ - switch (mcopt1 & SDRAM_MCOPT1_WDTH_MASK) { - case SDRAM_MCOPT1_WDTH_16: - return DEV_X2; - case SDRAM_MCOPT1_WDTH_32: - return DEV_X4; - default: - return DEV_UNKNOWN; - } -} - -/** - * ppc4xx_edac_get_mtype - return controller memory type - * @mcopt1: The 32-bit Memory Controller Option 1 register value - * currently set for the controller, from which the memory type - * is derived. - * - * This routine returns the EDAC memory type appropriate for the - * current controller configuration. - * - * Returns a memory type enumeration. - */ -static enum mem_type __devinit -ppc4xx_edac_get_mtype(u32 mcopt1) -{ - bool rden = ((mcopt1 & SDRAM_MCOPT1_RDEN_MASK) == SDRAM_MCOPT1_RDEN); - - switch (mcopt1 & SDRAM_MCOPT1_DDR_TYPE_MASK) { - case SDRAM_MCOPT1_DDR2_TYPE: - return rden ? MEM_RDDR2 : MEM_DDR2; - case SDRAM_MCOPT1_DDR1_TYPE: - return rden ? MEM_RDDR : MEM_DDR; - default: - return MEM_UNKNOWN; - } -} - -/** - * ppc4xx_edac_init_csrows - intialize driver instance rows - * @mci: A pointer to the EDAC memory controller instance - * associated with the ibm,sdram-4xx-ddr2 controller for which - * the csrows (i.e. banks/ranks) are being initialized. - * @mcopt1: The 32-bit Memory Controller Option 1 register value - * currently set for the controller, from which bank width - * and memory typ information is derived. - * - * This routine intializes the virtual "chip select rows" associated - * with the EDAC memory controller instance. An ibm,sdram-4xx-ddr2 - * controller bank/rank is mapped to a row. - * - * Returns 0 if OK; otherwise, -EINVAL if the memory bank size - * configuration cannot be determined. - */ -static int __devinit -ppc4xx_edac_init_csrows(struct mem_ctl_info *mci, u32 mcopt1) -{ - const struct ppc4xx_edac_pdata *pdata = mci->pvt_info; - int status = 0; - enum mem_type mtype; - enum dev_type dtype; - enum edac_type edac_mode; - int row; - u32 mbxcf, size; - static u32 ppc4xx_last_page; - - /* Establish the memory type and width */ - - mtype = ppc4xx_edac_get_mtype(mcopt1); - dtype = ppc4xx_edac_get_dtype(mcopt1); - - /* Establish EDAC mode */ - - if (mci->edac_cap & EDAC_FLAG_SECDED) - edac_mode = EDAC_SECDED; - else if (mci->edac_cap & EDAC_FLAG_EC) - edac_mode = EDAC_EC; - else - edac_mode = EDAC_NONE; - - /* - * Initialize each chip select row structure which correspond - * 1:1 with a controller bank/rank. - */ - - for (row = 0; row < mci->nr_csrows; row++) { - struct csrow_info *csi = &mci->csrows[row]; - - /* - * Get the configuration settings for this - * row/bank/rank and skip disabled banks. - */ - - mbxcf = mfsdram(&pdata->dcr_host, SDRAM_MBXCF(row)); - - if ((mbxcf & SDRAM_MBCF_BE_MASK) != SDRAM_MBCF_BE_ENABLE) - continue; - - /* Map the bank configuration size setting to pages. */ - - size = mbxcf & SDRAM_MBCF_SZ_MASK; - - switch (size) { - case SDRAM_MBCF_SZ_4MB: - case SDRAM_MBCF_SZ_8MB: - case SDRAM_MBCF_SZ_16MB: - case SDRAM_MBCF_SZ_32MB: - case SDRAM_MBCF_SZ_64MB: - case SDRAM_MBCF_SZ_128MB: - case SDRAM_MBCF_SZ_256MB: - case SDRAM_MBCF_SZ_512MB: - case SDRAM_MBCF_SZ_1GB: - case SDRAM_MBCF_SZ_2GB: - case SDRAM_MBCF_SZ_4GB: - case SDRAM_MBCF_SZ_8GB: - csi->nr_pages = SDRAM_MBCF_SZ_TO_PAGES(size); - break; - default: - ppc4xx_edac_mc_printk(KERN_ERR, mci, - "Unrecognized memory bank %d " - "size 0x%08x\n", - row, SDRAM_MBCF_SZ_DECODE(size)); - status = -EINVAL; - goto done; - } - - csi->first_page = ppc4xx_last_page; - csi->last_page = csi->first_page + csi->nr_pages - 1; - csi->page_mask = 0; - - /* - * It's unclear exactly what grain should be set to - * here. The SDRAM_ECCES register allows resolution of - * an error down to a nibble which would potentially - * argue for a grain of '1' byte, even though we only - * know the associated address for uncorrectable - * errors. This value is not used at present for - * anything other than error reporting so getting it - * wrong should be of little consequence. Other - * possible values would be the PLB width (16), the - * page size (PAGE_SIZE) or the memory width (2 or 4). - */ - - csi->grain = 1; - - csi->mtype = mtype; - csi->dtype = dtype; - - csi->edac_mode = edac_mode; - - ppc4xx_last_page += csi->nr_pages; - } - - done: - return status; -} - -/** - * ppc4xx_edac_mc_init - intialize driver instance - * @mci: A pointer to the EDAC memory controller instance being - * initialized. - * @op: A pointer to the OpenFirmware device tree node associated - * with the controller this EDAC instance is bound to. - * @match: A pointer to the OpenFirmware device tree match - * information associated with the controller this EDAC instance - * is bound to. - * @dcr_host: A pointer to the DCR data containing the DCR mapping - * for this controller instance. - * @mcopt1: The 32-bit Memory Controller Option 1 register value - * currently set for the controller, from which ECC capabilities - * and scrub mode are derived. - * - * This routine performs initialization of the EDAC memory controller - * instance and related driver-private data associated with the - * ibm,sdram-4xx-ddr2 memory controller the instance is bound to. - * - * Returns 0 if OK; otherwise, < 0 on error. - */ -static int __devinit -ppc4xx_edac_mc_init(struct mem_ctl_info *mci, - struct of_device *op, - const struct of_device_id *match, - const dcr_host_t *dcr_host, - u32 mcopt1) -{ - int status = 0; - const u32 memcheck = (mcopt1 & SDRAM_MCOPT1_MCHK_MASK); - struct ppc4xx_edac_pdata *pdata = NULL; - const struct device_node *np = op->node; - - if (match == NULL) - return -EINVAL; - - /* Initial driver pointers and private data */ - - mci->dev = &op->dev; - - dev_set_drvdata(mci->dev, mci); - - pdata = mci->pvt_info; - - pdata->dcr_host = *dcr_host; - pdata->irqs.sec = NO_IRQ; - pdata->irqs.ded = NO_IRQ; - - /* Initialize controller capabilities and configuration */ - - mci->mtype_cap = (MEM_FLAG_DDR | MEM_FLAG_RDDR | - MEM_FLAG_DDR2 | MEM_FLAG_RDDR2); - - mci->edac_ctl_cap = (EDAC_FLAG_NONE | - EDAC_FLAG_EC | - EDAC_FLAG_SECDED); - - mci->scrub_cap = SCRUB_NONE; - mci->scrub_mode = SCRUB_NONE; - - /* - * Update the actual capabilites based on the MCOPT1[MCHK] - * settings. Scrubbing is only useful if reporting is enabled. - */ - - switch (memcheck) { - case SDRAM_MCOPT1_MCHK_CHK: - mci->edac_cap = EDAC_FLAG_EC; - break; - case SDRAM_MCOPT1_MCHK_CHK_REP: - mci->edac_cap = (EDAC_FLAG_EC | EDAC_FLAG_SECDED); - mci->scrub_mode = SCRUB_SW_SRC; - break; - default: - mci->edac_cap = EDAC_FLAG_NONE; - break; - } - - /* Initialize strings */ - - mci->mod_name = PPC4XX_EDAC_MODULE_NAME; - mci->mod_ver = PPC4XX_EDAC_MODULE_REVISION; - mci->ctl_name = match->compatible, - mci->dev_name = np->full_name; - - /* Initialize callbacks */ - - mci->edac_check = ppc4xx_edac_check; - mci->ctl_page_to_phys = NULL; - - /* Initialize chip select rows */ - - status = ppc4xx_edac_init_csrows(mci, mcopt1); - - if (status) - ppc4xx_edac_mc_printk(KERN_ERR, mci, - "Failed to initialize rows!\n"); - - return status; -} - -/** - * ppc4xx_edac_register_irq - setup and register controller interrupts - * @op: A pointer to the OpenFirmware device tree node associated - * with the controller this EDAC instance is bound to. - * @mci: A pointer to the EDAC memory controller instance - * associated with the ibm,sdram-4xx-ddr2 controller for which - * interrupts are being registered. - * - * This routine parses the correctable (CE) and uncorrectable error (UE) - * interrupts from the device tree node and maps and assigns them to - * the associated EDAC memory controller instance. - * - * Returns 0 if OK; otherwise, -ENODEV if the interrupts could not be - * mapped and assigned. - */ -static int __devinit -ppc4xx_edac_register_irq(struct of_device *op, struct mem_ctl_info *mci) -{ - int status = 0; - int ded_irq, sec_irq; - struct ppc4xx_edac_pdata *pdata = mci->pvt_info; - struct device_node *np = op->node; - - ded_irq = irq_of_parse_and_map(np, INTMAP_ECCDED_INDEX); - sec_irq = irq_of_parse_and_map(np, INTMAP_ECCSEC_INDEX); - - if (ded_irq == NO_IRQ || sec_irq == NO_IRQ) { - ppc4xx_edac_mc_printk(KERN_ERR, mci, - "Unable to map interrupts.\n"); - status = -ENODEV; - goto fail; - } - - status = request_irq(ded_irq, - ppc4xx_edac_isr, - IRQF_DISABLED, - "[EDAC] MC ECCDED", - mci); - - if (status < 0) { - ppc4xx_edac_mc_printk(KERN_ERR, mci, - "Unable to request irq %d for ECC DED", - ded_irq); - status = -ENODEV; - goto fail1; - } - - status = request_irq(sec_irq, - ppc4xx_edac_isr, - IRQF_DISABLED, - "[EDAC] MC ECCSEC", - mci); - - if (status < 0) { - ppc4xx_edac_mc_printk(KERN_ERR, mci, - "Unable to request irq %d for ECC SEC", - sec_irq); - status = -ENODEV; - goto fail2; - } - - ppc4xx_edac_mc_printk(KERN_INFO, mci, "ECCDED irq is %d\n", ded_irq); - ppc4xx_edac_mc_printk(KERN_INFO, mci, "ECCSEC irq is %d\n", sec_irq); - - pdata->irqs.ded = ded_irq; - pdata->irqs.sec = sec_irq; - - return 0; - - fail2: - free_irq(sec_irq, mci); - - fail1: - free_irq(ded_irq, mci); - - fail: - return status; -} - -/** - * ppc4xx_edac_map_dcrs - locate and map controller registers - * @np: A pointer to the device tree node containing the DCR - * resources to map. - * @dcr_host: A pointer to the DCR data to populate with the - * DCR mapping. - * - * This routine attempts to locate in the device tree and map the DCR - * register resources associated with the controller's indirect DCR - * address and data windows. - * - * Returns 0 if the DCRs were successfully mapped; otherwise, < 0 on - * error. - */ -static int __devinit -ppc4xx_edac_map_dcrs(const struct device_node *np, dcr_host_t *dcr_host) -{ - unsigned int dcr_base, dcr_len; - - if (np == NULL || dcr_host == NULL) - return -EINVAL; - - /* Get the DCR resource extent and sanity check the values. */ - - dcr_base = dcr_resource_start(np, 0); - dcr_len = dcr_resource_len(np, 0); - - if (dcr_base == 0 || dcr_len == 0) { - ppc4xx_edac_printk(KERN_ERR, - "Failed to obtain DCR property.\n"); - return -ENODEV; - } - - if (dcr_len != SDRAM_DCR_RESOURCE_LEN) { - ppc4xx_edac_printk(KERN_ERR, - "Unexpected DCR length %d, expected %d.\n", - dcr_len, SDRAM_DCR_RESOURCE_LEN); - return -ENODEV; - } - - /* Attempt to map the DCR extent. */ - - *dcr_host = dcr_map(np, dcr_base, dcr_len); - - if (!DCR_MAP_OK(*dcr_host)) { - ppc4xx_edac_printk(KERN_INFO, "Failed to map DCRs.\n"); - return -ENODEV; - } - - return 0; -} - -/** - * ppc4xx_edac_probe - check controller and bind driver - * @op: A pointer to the OpenFirmware device tree node associated - * with the controller being probed for driver binding. - * @match: A pointer to the OpenFirmware device tree match - * information associated with the controller being probed - * for driver binding. - * - * This routine probes a specific ibm,sdram-4xx-ddr2 controller - * instance for binding with the driver. - * - * Returns 0 if the controller instance was successfully bound to the - * driver; otherwise, < 0 on error. - */ -static int __devinit -ppc4xx_edac_probe(struct of_device *op, const struct of_device_id *match) -{ - int status = 0; - u32 mcopt1, memcheck; - dcr_host_t dcr_host; - const struct device_node *np = op->node; - struct mem_ctl_info *mci = NULL; - static int ppc4xx_edac_instance; - - /* - * At this point, we only support the controller realized on - * the AMCC PPC 405EX[r]. Reject anything else. - */ - - if (!of_device_is_compatible(np, "ibm,sdram-405ex") && - !of_device_is_compatible(np, "ibm,sdram-405exr")) { - ppc4xx_edac_printk(KERN_NOTICE, - "Only the PPC405EX[r] is supported.\n"); - return -ENODEV; - } - - /* - * Next, get the DCR property and attempt to map it so that we - * can probe the controller. - */ - - status = ppc4xx_edac_map_dcrs(np, &dcr_host); - - if (status) - return status; - - /* - * First determine whether ECC is enabled at all. If not, - * there is no useful checking or monitoring that can be done - * for this controller. - */ - - mcopt1 = mfsdram(&dcr_host, SDRAM_MCOPT1); - memcheck = (mcopt1 & SDRAM_MCOPT1_MCHK_MASK); - - if (memcheck == SDRAM_MCOPT1_MCHK_NON) { - ppc4xx_edac_printk(KERN_INFO, "%s: No ECC memory detected or " - "ECC is disabled.\n", np->full_name); - status = -ENODEV; - goto done; - } - - /* - * At this point, we know ECC is enabled, allocate an EDAC - * controller instance and perform the appropriate - * initialization. - */ - - mci = edac_mc_alloc(sizeof(struct ppc4xx_edac_pdata), - ppc4xx_edac_nr_csrows, - ppc4xx_edac_nr_chans, - ppc4xx_edac_instance); - - if (mci == NULL) { - ppc4xx_edac_printk(KERN_ERR, "%s: " - "Failed to allocate EDAC MC instance!\n", - np->full_name); - status = -ENOMEM; - goto done; - } - - status = ppc4xx_edac_mc_init(mci, op, match, &dcr_host, mcopt1); - - if (status) { - ppc4xx_edac_mc_printk(KERN_ERR, mci, - "Failed to initialize instance!\n"); - goto fail; - } - - /* - * We have a valid, initialized EDAC instance bound to the - * controller. Attempt to register it with the EDAC subsystem - * and, if necessary, register interrupts. - */ - - if (edac_mc_add_mc(mci)) { - ppc4xx_edac_mc_printk(KERN_ERR, mci, - "Failed to add instance!\n"); - status = -ENODEV; - goto fail; - } - - if (edac_op_state == EDAC_OPSTATE_INT) { - status = ppc4xx_edac_register_irq(op, mci); - - if (status) - goto fail1; - } - - ppc4xx_edac_instance++; - - return 0; - - fail1: - edac_mc_del_mc(mci->dev); - - fail: - edac_mc_free(mci); - - done: - return status; -} - -/** - * ppc4xx_edac_remove - unbind driver from controller - * @op: A pointer to the OpenFirmware device tree node associated - * with the controller this EDAC instance is to be unbound/removed - * from. - * - * This routine unbinds the EDAC memory controller instance associated - * with the specified ibm,sdram-4xx-ddr2 controller described by the - * OpenFirmware device tree node passed as a parameter. - * - * Unconditionally returns 0. - */ -static int -ppc4xx_edac_remove(struct of_device *op) -{ - struct mem_ctl_info *mci = dev_get_drvdata(&op->dev); - struct ppc4xx_edac_pdata *pdata = mci->pvt_info; - - if (edac_op_state == EDAC_OPSTATE_INT) { - free_irq(pdata->irqs.sec, mci); - free_irq(pdata->irqs.ded, mci); - } - - dcr_unmap(pdata->dcr_host, SDRAM_DCR_RESOURCE_LEN); - - edac_mc_del_mc(mci->dev); - edac_mc_free(mci); - - return 0; -} - -/** - * ppc4xx_edac_opstate_init - initialize EDAC reporting method - * - * This routine ensures that the EDAC memory controller reporting - * method is mapped to a sane value as the EDAC core defines the value - * to EDAC_OPSTATE_INVAL by default. We don't call the global - * opstate_init as that defaults to polling and we want interrupt as - * the default. - */ -static inline void __init -ppc4xx_edac_opstate_init(void) -{ - switch (edac_op_state) { - case EDAC_OPSTATE_POLL: - case EDAC_OPSTATE_INT: - break; - default: - edac_op_state = EDAC_OPSTATE_INT; - break; - } - - ppc4xx_edac_printk(KERN_INFO, "Reporting type: %s\n", - ((edac_op_state == EDAC_OPSTATE_POLL) ? - EDAC_OPSTATE_POLL_STR : - ((edac_op_state == EDAC_OPSTATE_INT) ? - EDAC_OPSTATE_INT_STR : - EDAC_OPSTATE_UNKNOWN_STR))); -} - -/** - * ppc4xx_edac_init - driver/module insertion entry point - * - * This routine is the driver/module insertion entry point. It - * initializes the EDAC memory controller reporting state and - * registers the driver as an OpenFirmware device tree platform - * driver. - */ -static int __init -ppc4xx_edac_init(void) -{ - ppc4xx_edac_printk(KERN_INFO, PPC4XX_EDAC_MODULE_REVISION "\n"); - - ppc4xx_edac_opstate_init(); - - return of_register_platform_driver(&ppc4xx_edac_driver); -} - -/** - * ppc4xx_edac_exit - driver/module removal entry point - * - * This routine is the driver/module removal entry point. It - * unregisters the driver as an OpenFirmware device tree platform - * driver. - */ -static void __exit -ppc4xx_edac_exit(void) -{ - of_unregister_platform_driver(&ppc4xx_edac_driver); -} - -module_init(ppc4xx_edac_init); -module_exit(ppc4xx_edac_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Grant Erickson "); -MODULE_DESCRIPTION("EDAC MC Driver for the PPC4xx IBM DDR2 Memory Controller"); -module_param(edac_op_state, int, 0444); -MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting State: " - "0=" EDAC_OPSTATE_POLL_STR ", 2=" EDAC_OPSTATE_INT_STR); diff --git a/trunk/drivers/edac/ppc4xx_edac.h b/trunk/drivers/edac/ppc4xx_edac.h deleted file mode 100644 index d3154764c449..000000000000 --- a/trunk/drivers/edac/ppc4xx_edac.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2008 Nuovation System Designs, LLC - * Grant Erickson - * - * This file defines processor mnemonics for accessing and managing - * the IBM DDR1/DDR2 ECC controller found in the 405EX[r], 440SP, - * 440SPe, 460EX, 460GT and 460SX. - * - * 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 of the - * License. - * - */ - -#ifndef __PPC4XX_EDAC_H -#define __PPC4XX_EDAC_H - -#include - -/* - * Macro for generating register field mnemonics - */ -#define PPC_REG_BITS 32 -#define PPC_REG_VAL(bit, val) ((val) << ((PPC_REG_BITS - 1) - (bit))) -#define PPC_REG_DECODE(bit, val) ((val) >> ((PPC_REG_BITS - 1) - (bit))) - -/* - * IBM 4xx DDR1/DDR2 SDRAM memory controller registers (at least those - * relevant to ECC) - */ -#define SDRAM_BESR 0x00 /* Error status (read/clear) */ -#define SDRAM_BESRT 0x01 /* Error statuss (test/set) */ -#define SDRAM_BEARL 0x02 /* Error address low */ -#define SDRAM_BEARH 0x03 /* Error address high */ -#define SDRAM_WMIRQ 0x06 /* Write master (read/clear) */ -#define SDRAM_WMIRQT 0x07 /* Write master (test/set) */ -#define SDRAM_MCOPT1 0x20 /* Controller options 1 */ -#define SDRAM_MBXCF_BASE 0x40 /* Bank n configuration base */ -#define SDRAM_MBXCF(n) (SDRAM_MBXCF_BASE + (4 * (n))) -#define SDRAM_MB0CF SDRAM_MBXCF(0) -#define SDRAM_MB1CF SDRAM_MBXCF(1) -#define SDRAM_MB2CF SDRAM_MBXCF(2) -#define SDRAM_MB3CF SDRAM_MBXCF(3) -#define SDRAM_ECCCR 0x98 /* ECC error status */ -#define SDRAM_ECCES SDRAM_ECCCR - -/* - * PLB Master IDs - */ -#define SDRAM_PLB_M0ID_FIRST 0 -#define SDRAM_PLB_M0ID_ICU SDRAM_PLB_M0ID_FIRST -#define SDRAM_PLB_M0ID_PCIE0 1 -#define SDRAM_PLB_M0ID_PCIE1 2 -#define SDRAM_PLB_M0ID_DMA 3 -#define SDRAM_PLB_M0ID_DCU 4 -#define SDRAM_PLB_M0ID_OPB 5 -#define SDRAM_PLB_M0ID_MAL 6 -#define SDRAM_PLB_M0ID_SEC 7 -#define SDRAM_PLB_M0ID_AHB 8 -#define SDRAM_PLB_M0ID_LAST SDRAM_PLB_M0ID_AHB -#define SDRAM_PLB_M0ID_COUNT (SDRAM_PLB_M0ID_LAST - \ - SDRAM_PLB_M0ID_FIRST + 1) - -/* - * Memory Controller Bus Error Status Register - */ -#define SDRAM_BESR_MASK PPC_REG_VAL(7, 0xFF) -#define SDRAM_BESR_M0ID_MASK PPC_REG_VAL(3, 0xF) -#define SDRAM_BESR_M0ID_DECODE(n) PPC_REG_DECODE(3, n) -#define SDRAM_BESR_M0ID_ICU PPC_REG_VAL(3, SDRAM_PLB_M0ID_ICU) -#define SDRAM_BESR_M0ID_PCIE0 PPC_REG_VAL(3, SDRAM_PLB_M0ID_PCIE0) -#define SDRAM_BESR_M0ID_PCIE1 PPC_REG_VAL(3, SDRAM_PLB_M0ID_PCIE1) -#define SDRAM_BESR_M0ID_DMA PPC_REG_VAL(3, SDRAM_PLB_M0ID_DMA) -#define SDRAM_BESR_M0ID_DCU PPC_REG_VAL(3, SDRAM_PLB_M0ID_DCU) -#define SDRAM_BESR_M0ID_OPB PPC_REG_VAL(3, SDRAM_PLB_M0ID_OPB) -#define SDRAM_BESR_M0ID_MAL PPC_REG_VAL(3, SDRAM_PLB_M0ID_MAL) -#define SDRAM_BESR_M0ID_SEC PPC_REG_VAL(3, SDRAM_PLB_M0ID_SEC) -#define SDRAM_BESR_M0ID_AHB PPC_REG_VAL(3, SDRAM_PLB_M0ID_AHB) -#define SDRAM_BESR_M0ET_MASK PPC_REG_VAL(6, 0x7) -#define SDRAM_BESR_M0ET_NONE PPC_REG_VAL(6, 0) -#define SDRAM_BESR_M0ET_ECC PPC_REG_VAL(6, 1) -#define SDRAM_BESR_M0RW_MASK PPC_REG_VAL(7, 1) -#define SDRAM_BESR_M0RW_WRITE PPC_REG_VAL(7, 0) -#define SDRAM_BESR_M0RW_READ PPC_REG_VAL(7, 1) - -/* - * Memory Controller PLB Write Master Interrupt Register - */ -#define SDRAM_WMIRQ_MASK PPC_REG_VAL(8, 0x1FF) -#define SDRAM_WMIRQ_ENCODE(id) PPC_REG_VAL((id % \ - SDRAM_PLB_M0ID_COUNT), 1) -#define SDRAM_WMIRQ_ICU PPC_REG_VAL(SDRAM_PLB_M0ID_ICU, 1) -#define SDRAM_WMIRQ_PCIE0 PPC_REG_VAL(SDRAM_PLB_M0ID_PCIE0, 1) -#define SDRAM_WMIRQ_PCIE1 PPC_REG_VAL(SDRAM_PLB_M0ID_PCIE1, 1) -#define SDRAM_WMIRQ_DMA PPC_REG_VAL(SDRAM_PLB_M0ID_DMA, 1) -#define SDRAM_WMIRQ_DCU PPC_REG_VAL(SDRAM_PLB_M0ID_DCU, 1) -#define SDRAM_WMIRQ_OPB PPC_REG_VAL(SDRAM_PLB_M0ID_OPB, 1) -#define SDRAM_WMIRQ_MAL PPC_REG_VAL(SDRAM_PLB_M0ID_MAL, 1) -#define SDRAM_WMIRQ_SEC PPC_REG_VAL(SDRAM_PLB_M0ID_SEC, 1) -#define SDRAM_WMIRQ_AHB PPC_REG_VAL(SDRAM_PLB_M0ID_AHB, 1) - -/* - * Memory Controller Options 1 Register - */ -#define SDRAM_MCOPT1_MCHK_MASK PPC_REG_VAL(3, 0x3) /* ECC mask */ -#define SDRAM_MCOPT1_MCHK_NON PPC_REG_VAL(3, 0x0) /* No ECC gen */ -#define SDRAM_MCOPT1_MCHK_GEN PPC_REG_VAL(3, 0x2) /* ECC gen */ -#define SDRAM_MCOPT1_MCHK_CHK PPC_REG_VAL(3, 0x1) /* ECC gen and chk */ -#define SDRAM_MCOPT1_MCHK_CHK_REP PPC_REG_VAL(3, 0x3) /* ECC gen/chk/rpt */ -#define SDRAM_MCOPT1_MCHK_DECODE(n) ((((u32)(n)) >> 28) & 0x3) -#define SDRAM_MCOPT1_RDEN_MASK PPC_REG_VAL(4, 0x1) /* Rgstrd DIMM mask */ -#define SDRAM_MCOPT1_RDEN PPC_REG_VAL(4, 0x1) /* Rgstrd DIMM enbl */ -#define SDRAM_MCOPT1_WDTH_MASK PPC_REG_VAL(7, 0x1) /* Width mask */ -#define SDRAM_MCOPT1_WDTH_32 PPC_REG_VAL(7, 0x0) /* 32 bits */ -#define SDRAM_MCOPT1_WDTH_16 PPC_REG_VAL(7, 0x1) /* 16 bits */ -#define SDRAM_MCOPT1_DDR_TYPE_MASK PPC_REG_VAL(11, 0x1) /* DDR type mask */ -#define SDRAM_MCOPT1_DDR1_TYPE PPC_REG_VAL(11, 0x0) /* DDR1 type */ -#define SDRAM_MCOPT1_DDR2_TYPE PPC_REG_VAL(11, 0x1) /* DDR2 type */ - -/* - * Memory Bank 0 - n Configuration Register - */ -#define SDRAM_MBCF_BA_MASK PPC_REG_VAL(12, 0x1FFF) -#define SDRAM_MBCF_SZ_MASK PPC_REG_VAL(19, 0xF) -#define SDRAM_MBCF_SZ_DECODE(mbxcf) PPC_REG_DECODE(19, mbxcf) -#define SDRAM_MBCF_SZ_4MB PPC_REG_VAL(19, 0x0) -#define SDRAM_MBCF_SZ_8MB PPC_REG_VAL(19, 0x1) -#define SDRAM_MBCF_SZ_16MB PPC_REG_VAL(19, 0x2) -#define SDRAM_MBCF_SZ_32MB PPC_REG_VAL(19, 0x3) -#define SDRAM_MBCF_SZ_64MB PPC_REG_VAL(19, 0x4) -#define SDRAM_MBCF_SZ_128MB PPC_REG_VAL(19, 0x5) -#define SDRAM_MBCF_SZ_256MB PPC_REG_VAL(19, 0x6) -#define SDRAM_MBCF_SZ_512MB PPC_REG_VAL(19, 0x7) -#define SDRAM_MBCF_SZ_1GB PPC_REG_VAL(19, 0x8) -#define SDRAM_MBCF_SZ_2GB PPC_REG_VAL(19, 0x9) -#define SDRAM_MBCF_SZ_4GB PPC_REG_VAL(19, 0xA) -#define SDRAM_MBCF_SZ_8GB PPC_REG_VAL(19, 0xB) -#define SDRAM_MBCF_AM_MASK PPC_REG_VAL(23, 0xF) -#define SDRAM_MBCF_AM_MODE0 PPC_REG_VAL(23, 0x0) -#define SDRAM_MBCF_AM_MODE1 PPC_REG_VAL(23, 0x1) -#define SDRAM_MBCF_AM_MODE2 PPC_REG_VAL(23, 0x2) -#define SDRAM_MBCF_AM_MODE3 PPC_REG_VAL(23, 0x3) -#define SDRAM_MBCF_AM_MODE4 PPC_REG_VAL(23, 0x4) -#define SDRAM_MBCF_AM_MODE5 PPC_REG_VAL(23, 0x5) -#define SDRAM_MBCF_AM_MODE6 PPC_REG_VAL(23, 0x6) -#define SDRAM_MBCF_AM_MODE7 PPC_REG_VAL(23, 0x7) -#define SDRAM_MBCF_AM_MODE8 PPC_REG_VAL(23, 0x8) -#define SDRAM_MBCF_AM_MODE9 PPC_REG_VAL(23, 0x9) -#define SDRAM_MBCF_BE_MASK PPC_REG_VAL(31, 0x1) -#define SDRAM_MBCF_BE_DISABLE PPC_REG_VAL(31, 0x0) -#define SDRAM_MBCF_BE_ENABLE PPC_REG_VAL(31, 0x1) - -/* - * ECC Error Status - */ -#define SDRAM_ECCES_MASK PPC_REG_VAL(21, 0x3FFFFF) -#define SDRAM_ECCES_BNCE_MASK PPC_REG_VAL(15, 0xFFFF) -#define SDRAM_ECCES_BNCE_ENCODE(lane) PPC_REG_VAL(((lane) & 0xF), 1) -#define SDRAM_ECCES_CKBER_MASK PPC_REG_VAL(17, 0x3) -#define SDRAM_ECCES_CKBER_NONE PPC_REG_VAL(17, 0) -#define SDRAM_ECCES_CKBER_16_ECC_0_3 PPC_REG_VAL(17, 2) -#define SDRAM_ECCES_CKBER_32_ECC_0_3 PPC_REG_VAL(17, 1) -#define SDRAM_ECCES_CKBER_32_ECC_4_8 PPC_REG_VAL(17, 2) -#define SDRAM_ECCES_CKBER_32_ECC_0_8 PPC_REG_VAL(17, 3) -#define SDRAM_ECCES_CE PPC_REG_VAL(18, 1) -#define SDRAM_ECCES_UE PPC_REG_VAL(19, 1) -#define SDRAM_ECCES_BKNER_MASK PPC_REG_VAL(21, 0x3) -#define SDRAM_ECCES_BK0ER PPC_REG_VAL(20, 1) -#define SDRAM_ECCES_BK1ER PPC_REG_VAL(21, 1) - -#endif /* __PPC4XX_EDAC_H */ diff --git a/trunk/drivers/firmware/dmi_scan.c b/trunk/drivers/firmware/dmi_scan.c index 5f1b5400d96a..8f0f7c449305 100644 --- a/trunk/drivers/firmware/dmi_scan.c +++ b/trunk/drivers/firmware/dmi_scan.c @@ -68,8 +68,7 @@ static char * __init dmi_string(const struct dmi_header *dm, u8 s) * pointing to completely the wrong place for example */ static void dmi_table(u8 *buf, int len, int num, - void (*decode)(const struct dmi_header *, void *), - void *private_data) + void (*decode)(const struct dmi_header *)) { u8 *data = buf; int i = 0; @@ -90,7 +89,7 @@ static void dmi_table(u8 *buf, int len, int num, while ((data - buf < len - 1) && (data[0] || data[1])) data++; if (data - buf < len - 1) - decode(dm, private_data); + decode(dm); data += 2; i++; } @@ -100,8 +99,7 @@ static u32 dmi_base; static u16 dmi_len; static u16 dmi_num; -static int __init dmi_walk_early(void (*decode)(const struct dmi_header *, - void *)) +static int __init dmi_walk_early(void (*decode)(const struct dmi_header *)) { u8 *buf; @@ -109,7 +107,7 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *, if (buf == NULL) return -1; - dmi_table(buf, dmi_len, dmi_num, decode, NULL); + dmi_table(buf, dmi_len, dmi_num, decode); dmi_iounmap(buf, dmi_len); return 0; @@ -297,7 +295,7 @@ static void __init dmi_save_extended_devices(const struct dmi_header *dm) * and machine entries. For 2.5 we should pull the smbus controller info * out of here. */ -static void __init dmi_decode(const struct dmi_header *dm, void *dummy) +static void __init dmi_decode(const struct dmi_header *dm) { switch(dm->type) { case 0: /* BIOS Information */ @@ -600,12 +598,10 @@ int dmi_get_year(int field) /** * dmi_walk - Walk the DMI table and get called back for every record * @decode: Callback function - * @private_data: Private data to be passed to the callback function * * Returns -1 when the DMI table can't be reached, 0 on success. */ -int dmi_walk(void (*decode)(const struct dmi_header *, void *), - void *private_data) +int dmi_walk(void (*decode)(const struct dmi_header *)) { u8 *buf; @@ -616,7 +612,7 @@ int dmi_walk(void (*decode)(const struct dmi_header *, void *), if (buf == NULL) return -1; - dmi_table(buf, dmi_len, dmi_num, decode, private_data); + dmi_table(buf, dmi_len, dmi_num, decode); iounmap(buf); return 0; diff --git a/trunk/drivers/gpio/gpiolib.c b/trunk/drivers/gpio/gpiolib.c index 51a8d4103be5..42fb2fd24c0c 100644 --- a/trunk/drivers/gpio/gpiolib.c +++ b/trunk/drivers/gpio/gpiolib.c @@ -69,24 +69,20 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label) * those calls have no teeth) we can't avoid autorequesting. This nag * message should motivate switching to explicit requests... so should * the weaker cleanup after faults, compared to gpio_request(). - * - * NOTE: the autorequest mechanism is going away; at this point it's - * only "legal" in the sense that (old) code using it won't break yet, - * but instead only triggers a WARN() stack dump. */ static int gpio_ensure_requested(struct gpio_desc *desc, unsigned offset) { - const struct gpio_chip *chip = desc->chip; - const int gpio = chip->base + offset; + if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { + struct gpio_chip *chip = desc->chip; + int gpio = chip->base + offset; - if (WARN(test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0, - "autorequest GPIO-%d\n", gpio)) { if (!try_module_get(chip->owner)) { pr_err("GPIO-%d: module can't be gotten \n", gpio); clear_bit(FLAG_REQUESTED, &desc->flags); /* lose */ return -EIO; } + pr_warning("GPIO-%d autorequested\n", gpio); desc_set_label(desc, "[auto]"); /* caller must chip->request() w/o spinlock */ if (chip->request) @@ -442,7 +438,6 @@ int gpio_export(unsigned gpio, bool direction_may_change) unsigned long flags; struct gpio_desc *desc; int status = -EINVAL; - char *ioname = NULL; /* can't export until sysfs is available ... */ if (!gpio_class.p) { @@ -466,14 +461,11 @@ int gpio_export(unsigned gpio, bool direction_may_change) } spin_unlock_irqrestore(&gpio_lock, flags); - if (desc->chip->names && desc->chip->names[gpio - desc->chip->base]) - ioname = desc->chip->names[gpio - desc->chip->base]; - if (status == 0) { struct device *dev; dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), - desc, ioname ? ioname : "gpio%d", gpio); + desc, "gpio%d", gpio); if (dev) { if (direction_may_change) status = sysfs_create_group(&dev->kobj, @@ -521,7 +513,6 @@ void gpio_unexport(unsigned gpio) mutex_lock(&sysfs_lock); desc = &gpio_desc[gpio]; - if (test_bit(FLAG_EXPORT, &desc->flags)) { struct device *dev = NULL; diff --git a/trunk/drivers/gpu/drm/ati_pcigart.c b/trunk/drivers/gpu/drm/ati_pcigart.c index 628eae3e9b83..c533d0c9ec61 100644 --- a/trunk/drivers/gpu/drm/ati_pcigart.c +++ b/trunk/drivers/gpu/drm/ati_pcigart.c @@ -77,7 +77,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info if (!entry->busaddr[i]) break; pci_unmap_page(dev->pdev, entry->busaddr[i], - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + PAGE_SIZE, PCI_DMA_TODEVICE); } if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) @@ -95,14 +95,13 @@ EXPORT_SYMBOL(drm_ati_pcigart_cleanup); int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) { - struct drm_local_map *map = &gart_info->mapping; struct drm_sg_mem *entry = dev->sg; void *address = NULL; unsigned long pages; - u32 *pci_gart = NULL, page_base, gart_idx; + u32 *pci_gart, page_base; dma_addr_t bus_address = 0; int i, j, ret = 0; - int max_ati_pages, max_real_pages; + int max_pages; if (!entry) { DRM_ERROR("no scatter/gather memory!\n"); @@ -118,7 +117,6 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga goto done; } - pci_gart = gart_info->table_handle->vaddr; address = gart_info->table_handle->vaddr; bus_address = gart_info->table_handle->busaddr; } else { @@ -129,23 +127,18 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga (unsigned long)address); } + pci_gart = (u32 *) address; - max_ati_pages = (gart_info->table_size / sizeof(u32)); - max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); - pages = (entry->pages <= max_real_pages) - ? entry->pages : max_real_pages; + max_pages = (gart_info->table_size / sizeof(u32)); + pages = (entry->pages <= max_pages) + ? entry->pages : max_pages; - if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { - memset(pci_gart, 0, max_ati_pages * sizeof(u32)); - } else { - memset_io((void __iomem *)map->handle, 0, max_ati_pages * sizeof(u32)); - } + memset(pci_gart, 0, max_pages * sizeof(u32)); - gart_idx = 0; for (i = 0; i < pages; i++) { /* we need to support large memory configurations */ entry->busaddr[i] = pci_map_page(dev->pdev, entry->pagelist[i], - 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + 0, PAGE_SIZE, PCI_DMA_TODEVICE); if (entry->busaddr[i] == 0) { DRM_ERROR("unable to map PCIGART pages!\n"); drm_ati_pcigart_cleanup(dev, gart_info); @@ -156,26 +149,19 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga page_base = (u32) entry->busaddr[i]; for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { - u32 val; - switch(gart_info->gart_reg_if) { case DRM_ATI_GART_IGP: - val = page_base | 0xc; + *pci_gart = cpu_to_le32((page_base) | 0xc); break; case DRM_ATI_GART_PCIE: - val = (page_base >> 8) | 0xc; + *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); break; default: case DRM_ATI_GART_PCI: - val = page_base; + *pci_gart = cpu_to_le32(page_base); break; } - if (gart_info->gart_table_location == - DRM_ATI_GART_MAIN) - pci_gart[gart_idx] = cpu_to_le32(val); - else - DRM_WRITE32(map, gart_idx * sizeof(u32), val); - gart_idx++; + pci_gart++; page_base += ATI_PCIGART_PAGE_SIZE; } } diff --git a/trunk/drivers/gpu/drm/drm_bufs.c b/trunk/drivers/gpu/drm/drm_bufs.c index 6d80d17f1e96..12715d3c078d 100644 --- a/trunk/drivers/gpu/drm/drm_bufs.c +++ b/trunk/drivers/gpu/drm/drm_bufs.c @@ -34,17 +34,15 @@ */ #include -#include -#include #include "drmP.h" -resource_size_t drm_get_resource_start(struct drm_device *dev, unsigned int resource) +unsigned long drm_get_resource_start(struct drm_device *dev, unsigned int resource) { return pci_resource_start(dev->pdev, resource); } EXPORT_SYMBOL(drm_get_resource_start); -resource_size_t drm_get_resource_len(struct drm_device *dev, unsigned int resource) +unsigned long drm_get_resource_len(struct drm_device *dev, unsigned int resource) { return pci_resource_len(dev->pdev, resource); } @@ -52,44 +50,24 @@ resource_size_t drm_get_resource_len(struct drm_device *dev, unsigned int resour EXPORT_SYMBOL(drm_get_resource_len); static struct drm_map_list *drm_find_matching_map(struct drm_device *dev, - struct drm_local_map *map) + drm_local_map_t *map) { struct drm_map_list *entry; list_for_each_entry(entry, &dev->maplist, head) { - /* - * Because the kernel-userspace ABI is fixed at a 32-bit offset - * while PCI resources may live above that, we ignore the map - * offset for maps of type _DRM_FRAMEBUFFER or _DRM_REGISTERS. - * It is assumed that each driver will have only one resource of - * each type. - */ - if (!entry->map || - map->type != entry->map->type || - entry->master != dev->primary->master) - continue; - switch (map->type) { - case _DRM_SHM: - if (map->flags != _DRM_CONTAINS_LOCK) - break; - case _DRM_REGISTERS: - case _DRM_FRAME_BUFFER: + if (entry->map && (entry->master == dev->primary->master) && (map->type == entry->map->type) && + ((entry->map->offset == map->offset) || + ((map->type == _DRM_SHM) && (map->flags&_DRM_CONTAINS_LOCK)))) { return entry; - default: /* Make gcc happy */ - ; } - if (entry->map->offset == map->offset) - return entry; } return NULL; } static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash, - unsigned long user_token, int hashed_handle, int shm) + unsigned long user_token, int hashed_handle) { - int use_hashed_handle, shift; - unsigned long add; - + int use_hashed_handle; #if (BITS_PER_LONG == 64) use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle); #elif (BITS_PER_LONG == 32) @@ -105,47 +83,30 @@ static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash, if (ret != -EINVAL) return ret; } - - shift = 0; - add = DRM_MAP_HASH_OFFSET >> PAGE_SHIFT; - if (shm && (SHMLBA > PAGE_SIZE)) { - int bits = ilog2(SHMLBA >> PAGE_SHIFT) + 1; - - /* For shared memory, we have to preserve the SHMLBA - * bits of the eventual vma->vm_pgoff value during - * mmap(). Otherwise we run into cache aliasing problems - * on some platforms. On these platforms, the pgoff of - * a mmap() request is used to pick a suitable virtual - * address for the mmap() region such that it will not - * cause cache aliasing problems. - * - * Therefore, make sure the SHMLBA relevant bits of the - * hash value we use are equal to those in the original - * kernel virtual address. - */ - shift = bits; - add |= ((user_token >> PAGE_SHIFT) & ((1UL << bits) - 1UL)); - } - return drm_ht_just_insert_please(&dev->map_hash, hash, user_token, 32 - PAGE_SHIFT - 3, - shift, add); + 0, DRM_MAP_HASH_OFFSET >> PAGE_SHIFT); } /** - * Core function to create a range of memory available for mapping by a - * non-root process. + * Ioctl to specify a range of memory that is available for mapping by a non-root process. + * + * \param inode device inode. + * \param file_priv DRM file private. + * \param cmd command. + * \param arg pointer to a drm_map structure. + * \return zero on success or a negative value on error. * * Adjusts the memory offset to its absolute value according to the mapping * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where * applicable and if supported by the kernel. */ -static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, +static int drm_addmap_core(struct drm_device * dev, unsigned int offset, unsigned int size, enum drm_map_type type, enum drm_map_flags flags, struct drm_map_list ** maplist) { - struct drm_local_map *map; + struct drm_map *map; struct drm_map_list *list; drm_dma_handle_t *dmah; unsigned long user_token; @@ -168,9 +129,9 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; } - DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n", - (unsigned long long)map->offset, map->size, map->type); - if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) { + DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n", + map->offset, map->size, map->type); + if ((map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK))) { drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EINVAL; } @@ -298,8 +259,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, drm_free(map, sizeof(*map), DRM_MEM_MAPS); return -EPERM; } - DRM_DEBUG("AGP offset = 0x%08llx, size = 0x%08lx\n", - (unsigned long long)map->offset, map->size); + DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size); break; case _DRM_GEM: @@ -349,8 +309,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, /* We do it here so that dev->struct_mutex protects the increment */ user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle : map->offset; - ret = drm_map_handle(dev, &list->hash, user_token, 0, - (map->type == _DRM_SHM)); + ret = drm_map_handle(dev, &list->hash, user_token, 0); if (ret) { if (map->type == _DRM_REGISTERS) iounmap(map->handle); @@ -368,9 +327,9 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, return 0; } -int drm_addmap(struct drm_device * dev, resource_size_t offset, +int drm_addmap(struct drm_device * dev, unsigned int offset, unsigned int size, enum drm_map_type type, - enum drm_map_flags flags, struct drm_local_map ** map_ptr) + enum drm_map_flags flags, drm_local_map_t ** map_ptr) { struct drm_map_list *list; int rc; @@ -383,17 +342,6 @@ int drm_addmap(struct drm_device * dev, resource_size_t offset, EXPORT_SYMBOL(drm_addmap); -/** - * Ioctl to specify a range of memory that is available for mapping by a - * non-root process. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_map structure. - * \return zero on success or a negative value on error. - * - */ int drm_addmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -419,13 +367,19 @@ int drm_addmap_ioctl(struct drm_device *dev, void *data, * Remove a map private from list and deallocate resources if the mapping * isn't in use. * + * \param inode device inode. + * \param file_priv DRM file private. + * \param cmd command. + * \param arg pointer to a struct drm_map structure. + * \return zero on success or a negative value on error. + * * Searches the map on drm_device::maplist, removes it from the list, see if * its being used, and free any associate resource (such as MTRR's) if it's not * being on use. * * \sa drm_addmap */ -int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map) +int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map) { struct drm_map_list *r_list = NULL, *list_t; drm_dma_handle_t dmah; @@ -488,7 +442,7 @@ int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map) } EXPORT_SYMBOL(drm_rmmap_locked); -int drm_rmmap(struct drm_device *dev, struct drm_local_map *map) +int drm_rmmap(struct drm_device *dev, drm_local_map_t *map) { int ret; @@ -508,18 +462,12 @@ EXPORT_SYMBOL(drm_rmmap); * One use case might be after addmap is allowed for normal users for SHM and * gets used by drivers that the server doesn't need to care about. This seems * unlikely. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a struct drm_map structure. - * \return zero on success or a negative value on error. */ int drm_rmmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_map *request = data; - struct drm_local_map *map = NULL; + drm_local_map_t *map = NULL; struct drm_map_list *r_list; int ret; @@ -1586,7 +1534,7 @@ int drm_mapbufs(struct drm_device *dev, void *data, && (dma->flags & _DRM_DMA_USE_SG)) || (drm_core_check_feature(dev, DRIVER_FB_DMA) && (dma->flags & _DRM_DMA_USE_FB))) { - struct drm_local_map *map = dev->agp_buffer_map; + struct drm_map *map = dev->agp_buffer_map; unsigned long token = dev->agp_buffer_token; if (!map) { diff --git a/trunk/drivers/gpu/drm/drm_context.c b/trunk/drivers/gpu/drm/drm_context.c index 7d1e53c10d4b..809ec0f03452 100644 --- a/trunk/drivers/gpu/drm/drm_context.c +++ b/trunk/drivers/gpu/drm/drm_context.c @@ -143,7 +143,7 @@ int drm_getsareactx(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_ctx_priv_map *request = data; - struct drm_local_map *map; + struct drm_map *map; struct drm_map_list *_entry; mutex_lock(&dev->struct_mutex); @@ -186,7 +186,7 @@ int drm_setsareactx(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_ctx_priv_map *request = data; - struct drm_local_map *map = NULL; + struct drm_map *map = NULL; struct drm_map_list *r_list = NULL; mutex_lock(&dev->struct_mutex); diff --git a/trunk/drivers/gpu/drm/drm_drv.c b/trunk/drivers/gpu/drm/drm_drv.c index c4ada8b6295b..ed32edb17166 100644 --- a/trunk/drivers/gpu/drm/drm_drv.c +++ b/trunk/drivers/gpu/drm/drm_drv.c @@ -254,19 +254,15 @@ int drm_lastclose(struct drm_device * dev) int drm_init(struct drm_driver *driver) { struct pci_dev *pdev = NULL; - const struct pci_device_id *pid; + struct pci_device_id *pid; int i; DRM_DEBUG("\n"); INIT_LIST_HEAD(&driver->device_list); - if (driver->driver_features & DRIVER_MODESET) - return pci_register_driver(&driver->pci_driver); - - /* If not using KMS, fall back to stealth mode manual scanning. */ for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { - pid = &driver->pci_driver.id_table[i]; + pid = (struct pci_device_id *)&driver->pci_driver.id_table[i]; /* Loop around setting up a DRM device for each PCI device * matching our ID and device class. If we had the internal @@ -291,17 +287,68 @@ int drm_init(struct drm_driver *driver) EXPORT_SYMBOL(drm_init); +/** + * Called via cleanup_module() at module unload time. + * + * Cleans up all DRM device, calling drm_lastclose(). + * + * \sa drm_init + */ +static void drm_cleanup(struct drm_device * dev) +{ + struct drm_map_list *r_list, *list_temp; + DRM_DEBUG("\n"); + + if (!dev) { + DRM_ERROR("cleanup called no dev\n"); + return; + } + + drm_vblank_cleanup(dev); + + drm_lastclose(dev); + + if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && + dev->agp && dev->agp->agp_mtrr >= 0) { + int retval; + retval = mtrr_del(dev->agp->agp_mtrr, + dev->agp->agp_info.aper_base, + dev->agp->agp_info.aper_size * 1024 * 1024); + DRM_DEBUG("mtrr_del=%d\n", retval); + } + + if (dev->driver->unload) + dev->driver->unload(dev); + + if (drm_core_has_AGP(dev) && dev->agp) { + drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); + dev->agp = NULL; + } + + drm_ht_remove(&dev->map_hash); + drm_ctxbitmap_cleanup(dev); + + list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) + drm_rmmap(dev, r_list->map); + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + drm_put_minor(&dev->control); + + if (dev->driver->driver_features & DRIVER_GEM) + drm_gem_destroy(dev); + + drm_put_minor(&dev->primary); + if (drm_put_dev(dev)) + DRM_ERROR("Cannot unload module\n"); +} + void drm_exit(struct drm_driver *driver) { struct drm_device *dev, *tmp; DRM_DEBUG("\n"); - if (driver->driver_features & DRIVER_MODESET) { - pci_unregister_driver(&driver->pci_driver); - } else { - list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item) - drm_put_dev(dev); - } + list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item) + drm_cleanup(dev); DRM_INFO("Module unloaded\n"); } @@ -421,7 +468,6 @@ int drm_ioctl(struct inode *inode, struct file *filp, drm_ioctl_t *func; unsigned int nr = DRM_IOCTL_NR(cmd); int retcode = -EINVAL; - char stack_kdata[128]; char *kdata = NULL; atomic_inc(&dev->ioctl_count); @@ -460,14 +506,10 @@ int drm_ioctl(struct inode *inode, struct file *filp, retcode = -EACCES; } else { if (cmd & (IOC_IN | IOC_OUT)) { - if (_IOC_SIZE(cmd) <= sizeof(stack_kdata)) { - kdata = stack_kdata; - } else { - kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); - if (!kdata) { - retcode = -ENOMEM; - goto err_i1; - } + kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); + if (!kdata) { + retcode = -ENOMEM; + goto err_i1; } } @@ -488,7 +530,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, } err_i1: - if (kdata != stack_kdata) + if (kdata) kfree(kdata); atomic_dec(&dev->ioctl_count); if (retcode) @@ -498,7 +540,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, EXPORT_SYMBOL(drm_ioctl); -struct drm_local_map *drm_getsarea(struct drm_device *dev) +drm_local_map_t *drm_getsarea(struct drm_device *dev) { struct drm_map_list *entry; diff --git a/trunk/drivers/gpu/drm/drm_edid.c b/trunk/drivers/gpu/drm/drm_edid.c index c67400067b85..a839a28d8ee6 100644 --- a/trunk/drivers/gpu/drm/drm_edid.c +++ b/trunk/drivers/gpu/drm/drm_edid.c @@ -550,20 +550,11 @@ static int add_detailed_info(struct drm_connector *connector, } #define DDC_ADDR 0x50 -/** - * Get EDID information via I2C. - * - * \param adapter : i2c device adaptor - * \param buf : EDID data buffer to be filled - * \param len : EDID data buffer length - * \return 0 on success or -1 on failure. - * - * Try to fetch EDID information by calling i2c driver function. - */ -int drm_do_probe_ddc_edid(struct i2c_adapter *adapter, - unsigned char *buf, int len) + +unsigned char *drm_do_probe_ddc_edid(struct i2c_adapter *adapter) { unsigned char start = 0x0; + unsigned char *buf = kmalloc(EDID_LENGTH, GFP_KERNEL); struct i2c_msg msgs[] = { { .addr = DDC_ADDR, @@ -573,36 +564,31 @@ int drm_do_probe_ddc_edid(struct i2c_adapter *adapter, }, { .addr = DDC_ADDR, .flags = I2C_M_RD, - .len = len, + .len = EDID_LENGTH, .buf = buf, } }; + if (!buf) { + dev_warn(&adapter->dev, "unable to allocate memory for EDID " + "block.\n"); + return NULL; + } + if (i2c_transfer(adapter, msgs, 2) == 2) - return 0; + return buf; dev_info(&adapter->dev, "unable to read EDID block.\n"); - return -1; + kfree(buf); + return NULL; } EXPORT_SYMBOL(drm_do_probe_ddc_edid); -/** - * Get EDID information. - * - * \param adapter : i2c device adaptor. - * \param buf : EDID data buffer to be filled - * \param len : EDID data buffer length - * \return 0 on success or -1 on failure. - * - * Initialize DDC, then fetch EDID information - * by calling drm_do_probe_ddc_edid function. - */ -static int drm_ddc_read(struct i2c_adapter *adapter, - unsigned char *buf, int len) +static unsigned char *drm_ddc_read(struct i2c_adapter *adapter) { struct i2c_algo_bit_data *algo_data = adapter->algo_data; + unsigned char *edid = NULL; int i, j; - int ret = -1; algo_data->setscl(algo_data->data, 1); @@ -630,7 +616,7 @@ static int drm_ddc_read(struct i2c_adapter *adapter, msleep(15); /* Do the real work */ - ret = drm_do_probe_ddc_edid(adapter, buf, len); + edid = drm_do_probe_ddc_edid(adapter); algo_data->setsda(algo_data->data, 0); algo_data->setscl(algo_data->data, 0); msleep(15); @@ -646,7 +632,7 @@ static int drm_ddc_read(struct i2c_adapter *adapter, msleep(15); algo_data->setscl(algo_data->data, 0); algo_data->setsda(algo_data->data, 0); - if (ret == 0) + if (edid) break; } /* Release the DDC lines when done or the Apple Cinema HD display @@ -655,31 +641,9 @@ static int drm_ddc_read(struct i2c_adapter *adapter, algo_data->setsda(algo_data->data, 1); algo_data->setscl(algo_data->data, 1); - return ret; -} - -static int drm_ddc_read_edid(struct drm_connector *connector, - struct i2c_adapter *adapter, - char *buf, int len) -{ - int ret; - - ret = drm_ddc_read(adapter, buf, len); - if (ret != 0) { - dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n", - drm_get_connector_name(connector)); - goto end; - } - if (!edid_is_valid((struct edid *)buf)) { - dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n", - drm_get_connector_name(connector)); - ret = -1; - } -end: - return ret; + return edid; } -#define MAX_EDID_EXT_NUM 4 /** * drm_get_edid - get EDID data, if available * @connector: connector we're probing @@ -692,118 +656,27 @@ static int drm_ddc_read_edid(struct drm_connector *connector, struct edid *drm_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) { - int ret; struct edid *edid; - edid = kmalloc(EDID_LENGTH * (MAX_EDID_EXT_NUM + 1), - GFP_KERNEL); - if (edid == NULL) { - dev_warn(&connector->dev->pdev->dev, - "Failed to allocate EDID\n"); - goto end; + edid = (struct edid *)drm_ddc_read(adapter); + if (!edid) { + dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n", + drm_get_connector_name(connector)); + return NULL; } - - /* Read first EDID block */ - ret = drm_ddc_read_edid(connector, adapter, - (unsigned char *)edid, EDID_LENGTH); - if (ret != 0) - goto clean_up; - - /* There are EDID extensions to be read */ - if (edid->extensions != 0) { - int edid_ext_num = edid->extensions; - - if (edid_ext_num > MAX_EDID_EXT_NUM) { - dev_warn(&connector->dev->pdev->dev, - "The number of extension(%d) is " - "over max (%d), actually read number (%d)\n", - edid_ext_num, MAX_EDID_EXT_NUM, - MAX_EDID_EXT_NUM); - /* Reset EDID extension number to be read */ - edid_ext_num = MAX_EDID_EXT_NUM; - } - /* Read EDID including extensions too */ - ret = drm_ddc_read_edid(connector, adapter, (char *)edid, - EDID_LENGTH * (edid_ext_num + 1)); - if (ret != 0) - goto clean_up; - + if (!edid_is_valid(edid)) { + dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n", + drm_get_connector_name(connector)); + kfree(edid); + return NULL; } connector->display_info.raw_edid = (char *)edid; - goto end; -clean_up: - kfree(edid); - edid = NULL; -end: return edid; - } EXPORT_SYMBOL(drm_get_edid); -#define HDMI_IDENTIFIER 0x000C03 -#define VENDOR_BLOCK 0x03 -/** - * drm_detect_hdmi_monitor - detect whether monitor is hdmi. - * @edid: monitor EDID information - * - * Parse the CEA extension according to CEA-861-B. - * Return true if HDMI, false if not or unknown. - */ -bool drm_detect_hdmi_monitor(struct edid *edid) -{ - char *edid_ext = NULL; - int i, hdmi_id, edid_ext_num; - int start_offset, end_offset; - bool is_hdmi = false; - - /* No EDID or EDID extensions */ - if (edid == NULL || edid->extensions == 0) - goto end; - - /* Chose real EDID extension number */ - edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ? - MAX_EDID_EXT_NUM : edid->extensions; - - /* Find CEA extension */ - for (i = 0; i < edid_ext_num; i++) { - edid_ext = (char *)edid + EDID_LENGTH * (i + 1); - /* This block is CEA extension */ - if (edid_ext[0] == 0x02) - break; - } - - if (i == edid_ext_num) - goto end; - - /* Data block offset in CEA extension block */ - start_offset = 4; - end_offset = edid_ext[2]; - - /* - * Because HDMI identifier is in Vendor Specific Block, - * search it from all data blocks of CEA extension. - */ - for (i = start_offset; i < end_offset; - /* Increased by data block len */ - i += ((edid_ext[i] & 0x1f) + 1)) { - /* Find vendor specific block */ - if ((edid_ext[i] >> 5) == VENDOR_BLOCK) { - hdmi_id = edid_ext[i + 1] | (edid_ext[i + 2] << 8) | - edid_ext[i + 3] << 16; - /* Find HDMI identifier */ - if (hdmi_id == HDMI_IDENTIFIER) - is_hdmi = true; - break; - } - } - -end: - return is_hdmi; -} -EXPORT_SYMBOL(drm_detect_hdmi_monitor); - /** * drm_add_edid_modes - add modes from EDID data, if available * @connector: connector we're probing diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c index 09a3571c9908..e13cb62bbaee 100644 --- a/trunk/drivers/gpu/drm/drm_fops.c +++ b/trunk/drivers/gpu/drm/drm_fops.c @@ -274,7 +274,6 @@ static int drm_open_helper(struct inode *inode, struct file *filp, /* create a new master */ priv->minor->master = drm_master_create(priv->minor); if (!priv->minor->master) { - mutex_unlock(&dev->struct_mutex); ret = -ENOMEM; goto out_free; } diff --git a/trunk/drivers/gpu/drm/drm_gem.c b/trunk/drivers/gpu/drm/drm_gem.c index c1173d8c4588..88d3368ffddd 100644 --- a/trunk/drivers/gpu/drm/drm_gem.c +++ b/trunk/drivers/gpu/drm/drm_gem.c @@ -502,7 +502,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) struct drm_file *priv = filp->private_data; struct drm_device *dev = priv->minor->dev; struct drm_gem_mm *mm = dev->mm_private; - struct drm_local_map *map = NULL; + struct drm_map *map = NULL; struct drm_gem_object *obj; struct drm_hash_item *hash; unsigned long prot; diff --git a/trunk/drivers/gpu/drm/drm_info.c b/trunk/drivers/gpu/drm/drm_info.c index f0f6c6b93f3a..1b699768ccfb 100644 --- a/trunk/drivers/gpu/drm/drm_info.c +++ b/trunk/drivers/gpu/drm/drm_info.c @@ -72,7 +72,7 @@ int drm_vm_info(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; - struct drm_local_map *map; + struct drm_map *map; struct drm_map_list *r_list; /* Hardcoded from _DRM_FRAME_BUFFER, @@ -94,9 +94,9 @@ int drm_vm_info(struct seq_file *m, void *data) else type = types[map->type]; - seq_printf(m, "%4d 0x%016llx 0x%08lx %4.4s 0x%02x 0x%08lx ", + seq_printf(m, "%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ", i, - (unsigned long long)map->offset, + map->offset, map->size, type, map->flags, (unsigned long) r_list->user_token); if (map->mtrr < 0) diff --git a/trunk/drivers/gpu/drm/drm_ioc32.c b/trunk/drivers/gpu/drm/drm_ioc32.c index 282d9fdf9f4e..920b72fbc958 100644 --- a/trunk/drivers/gpu/drm/drm_ioc32.c +++ b/trunk/drivers/gpu/drm/drm_ioc32.c @@ -954,7 +954,6 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd, DRM_IOCTL_SG_FREE, (unsigned long)request); } -#if defined(CONFIG_X86) || defined(CONFIG_IA64) typedef struct drm_update_draw32 { drm_drawable_t handle; unsigned int type; @@ -985,7 +984,6 @@ static int compat_drm_update_draw(struct file *file, unsigned int cmd, DRM_IOCTL_UPDATE_DRAW, (unsigned long)request); return err; } -#endif struct drm_wait_vblank_request32 { enum drm_vblank_seq_type type; @@ -1068,9 +1066,7 @@ drm_ioctl_compat_t *drm_compat_ioctls[] = { #endif [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc, [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free, -#if defined(CONFIG_X86) || defined(CONFIG_IA64) [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw, -#endif [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank, }; diff --git a/trunk/drivers/gpu/drm/drm_memory.c b/trunk/drivers/gpu/drm/drm_memory.c index 0c707f533eab..bcc869bc4092 100644 --- a/trunk/drivers/gpu/drm/drm_memory.c +++ b/trunk/drivers/gpu/drm/drm_memory.c @@ -159,7 +159,7 @@ static inline void *agp_remap(unsigned long offset, unsigned long size, #endif /* debug_memory */ -void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev) +void drm_core_ioremap(struct drm_map *map, struct drm_device *dev) { if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) @@ -169,7 +169,7 @@ void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev) } EXPORT_SYMBOL(drm_core_ioremap); -void drm_core_ioremap_wc(struct drm_local_map *map, struct drm_device *dev) +void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev) { if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) @@ -179,7 +179,7 @@ void drm_core_ioremap_wc(struct drm_local_map *map, struct drm_device *dev) } EXPORT_SYMBOL(drm_core_ioremap_wc); -void drm_core_ioremapfree(struct drm_local_map *map, struct drm_device *dev) +void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev) { if (!map->handle || !map->size) return; diff --git a/trunk/drivers/gpu/drm/drm_proc.c b/trunk/drivers/gpu/drm/drm_proc.c index bae5391165ac..9b3c5af61e98 100644 --- a/trunk/drivers/gpu/drm/drm_proc.c +++ b/trunk/drivers/gpu/drm/drm_proc.c @@ -40,6 +40,7 @@ #include #include "drmP.h" + /*************************************************** * Initialization, etc. **************************************************/ diff --git a/trunk/drivers/gpu/drm/drm_stub.c b/trunk/drivers/gpu/drm/drm_stub.c index d009661781bc..48f33be8fd0f 100644 --- a/trunk/drivers/gpu/drm/drm_stub.c +++ b/trunk/drivers/gpu/drm/drm_stub.c @@ -381,7 +381,6 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, } if (drm_core_check_feature(dev, DRIVER_MODESET)) { - pci_set_drvdata(pdev, dev); ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); if (ret) goto err_g2; @@ -405,9 +404,9 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, list_add_tail(&dev->driver_item, &driver->device_list); - DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, pci_name(pdev), dev->primary->index); + driver->date, dev->primary->index); return 0; @@ -419,7 +418,29 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, drm_free(dev, sizeof(*dev), DRM_MEM_STUB); return ret; } -EXPORT_SYMBOL(drm_get_dev); + +/** + * Put a device minor number. + * + * \param dev device data structure + * \return always zero + * + * Cleans up the proc resources. If it is the last minor then release the foreign + * "drm" data, otherwise unregisters the "drm" data, frees the dev list and + * unregisters the character device. + */ +int drm_put_dev(struct drm_device * dev) +{ + DRM_DEBUG("release primary %s\n", dev->driver->pci_driver.name); + + if (dev->devname) { + drm_free(dev->devname, strlen(dev->devname) + 1, + DRM_MEM_DRIVER); + dev->devname = NULL; + } + drm_free(dev, sizeof(*dev), DRM_MEM_STUB); + return 0; +} /** * Put a secondary minor number. @@ -451,67 +472,3 @@ int drm_put_minor(struct drm_minor **minor_p) *minor_p = NULL; return 0; } - -/** - * Called via drm_exit() at module unload time or when pci device is - * unplugged. - * - * Cleans up all DRM device, calling drm_lastclose(). - * - * \sa drm_init - */ -void drm_put_dev(struct drm_device *dev) -{ - struct drm_driver *driver = dev->driver; - struct drm_map_list *r_list, *list_temp; - - DRM_DEBUG("\n"); - - if (!dev) { - DRM_ERROR("cleanup called no dev\n"); - return; - } - - drm_vblank_cleanup(dev); - - drm_lastclose(dev); - - if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && - dev->agp && dev->agp->agp_mtrr >= 0) { - int retval; - retval = mtrr_del(dev->agp->agp_mtrr, - dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size * 1024 * 1024); - DRM_DEBUG("mtrr_del=%d\n", retval); - } - - if (dev->driver->unload) - dev->driver->unload(dev); - - if (drm_core_has_AGP(dev) && dev->agp) { - drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); - dev->agp = NULL; - } - - drm_ht_remove(&dev->map_hash); - drm_ctxbitmap_cleanup(dev); - - list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) - drm_rmmap(dev, r_list->map); - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_put_minor(&dev->control); - - if (driver->driver_features & DRIVER_GEM) - drm_gem_destroy(dev); - - drm_put_minor(&dev->primary); - - if (dev->devname) { - drm_free(dev->devname, strlen(dev->devname) + 1, - DRM_MEM_DRIVER); - dev->devname = NULL; - } - drm_free(dev, sizeof(*dev), DRM_MEM_STUB); -} -EXPORT_SYMBOL(drm_put_dev); diff --git a/trunk/drivers/gpu/drm/drm_sysfs.c b/trunk/drivers/gpu/drm/drm_sysfs.c index 5de573a981cb..186d08159d48 100644 --- a/trunk/drivers/gpu/drm/drm_sysfs.c +++ b/trunk/drivers/gpu/drm/drm_sysfs.c @@ -35,9 +35,7 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) struct drm_minor *drm_minor = to_drm_minor(dev); struct drm_device *drm_dev = drm_minor->dev; - if (drm_minor->type == DRM_MINOR_LEGACY && - !drm_core_check_feature(drm_dev, DRIVER_MODESET) && - drm_dev->driver->suspend) + if (drm_minor->type == DRM_MINOR_LEGACY && drm_dev->driver->suspend) return drm_dev->driver->suspend(drm_dev, state); return 0; @@ -55,9 +53,7 @@ static int drm_sysfs_resume(struct device *dev) struct drm_minor *drm_minor = to_drm_minor(dev); struct drm_device *drm_dev = drm_minor->dev; - if (drm_minor->type == DRM_MINOR_LEGACY && - !drm_core_check_feature(drm_dev, DRIVER_MODESET) && - drm_dev->driver->resume) + if (drm_minor->type == DRM_MINOR_LEGACY && drm_dev->driver->resume) return drm_dev->driver->resume(drm_dev); return 0; @@ -122,6 +118,20 @@ void drm_sysfs_destroy(void) class_destroy(drm_class); } +static ssize_t show_dri(struct device *device, struct device_attribute *attr, + char *buf) +{ + struct drm_minor *drm_minor = to_drm_minor(device); + struct drm_device *drm_dev = drm_minor->dev; + if (drm_dev->driver->dri_library_name) + return drm_dev->driver->dri_library_name(drm_dev, buf); + return snprintf(buf, PAGE_SIZE, "%s\n", drm_dev->driver->pci_driver.name); +} + +static struct device_attribute device_attrs[] = { + __ATTR(dri_library_name, S_IRUGO, show_dri, NULL), +}; + /** * drm_sysfs_device_release - do nothing * @dev: Linux device @@ -464,6 +474,7 @@ void drm_sysfs_hotplug_event(struct drm_device *dev) int drm_sysfs_device_add(struct drm_minor *minor) { int err; + int i, j; char *minor_str; minor->kdev.parent = &minor->dev->pdev->dev; @@ -485,8 +496,18 @@ int drm_sysfs_device_add(struct drm_minor *minor) goto err_out; } + for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { + err = device_create_file(&minor->kdev, &device_attrs[i]); + if (err) + goto err_out_files; + } + return 0; +err_out_files: + if (i > 0) + for (j = 0; j < i; j++) + device_remove_file(&minor->kdev, &device_attrs[j]); device_unregister(&minor->kdev); err_out: @@ -502,5 +523,9 @@ int drm_sysfs_device_add(struct drm_minor *minor) */ void drm_sysfs_device_remove(struct drm_minor *minor) { + int i; + + for (i = 0; i < ARRAY_SIZE(device_attrs); i++) + device_remove_file(&minor->kdev, &device_attrs[i]); device_unregister(&minor->kdev); } diff --git a/trunk/drivers/gpu/drm/drm_vm.c b/trunk/drivers/gpu/drm/drm_vm.c index 22f76567ac7d..3ffae021d280 100644 --- a/trunk/drivers/gpu/drm/drm_vm.c +++ b/trunk/drivers/gpu/drm/drm_vm.c @@ -91,7 +91,7 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct drm_file *priv = vma->vm_file->private_data; struct drm_device *dev = priv->minor->dev; - struct drm_local_map *map = NULL; + struct drm_map *map = NULL; struct drm_map_list *r_list; struct drm_hash_item *hash; @@ -115,9 +115,9 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) * Using vm_pgoff as a selector forces us to use this unusual * addressing scheme. */ - resource_size_t offset = (unsigned long)vmf->virtual_address - - vma->vm_start; - resource_size_t baddr = map->offset + offset; + unsigned long offset = (unsigned long)vmf->virtual_address - + vma->vm_start; + unsigned long baddr = map->offset + offset; struct drm_agp_mem *agpmem; struct page *page; @@ -149,10 +149,8 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) vmf->page = page; DRM_DEBUG - ("baddr = 0x%llx page = 0x%p, offset = 0x%llx, count=%d\n", - (unsigned long long)baddr, - __va(agpmem->memory->memory[offset]), - (unsigned long long)offset, + ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n", + baddr, __va(agpmem->memory->memory[offset]), offset, page_count(page)); return 0; } @@ -178,7 +176,7 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) */ static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - struct drm_local_map *map = vma->vm_private_data; + struct drm_map *map = (struct drm_map *) vma->vm_private_data; unsigned long offset; unsigned long i; struct page *page; @@ -211,7 +209,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) struct drm_file *priv = vma->vm_file->private_data; struct drm_device *dev = priv->minor->dev; struct drm_vma_entry *pt, *temp; - struct drm_local_map *map; + struct drm_map *map; struct drm_map_list *r_list; int found_maps = 0; @@ -324,7 +322,7 @@ static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) */ static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - struct drm_local_map *map = vma->vm_private_data; + struct drm_map *map = (struct drm_map *) vma->vm_private_data; struct drm_file *priv = vma->vm_file->private_data; struct drm_device *dev = priv->minor->dev; struct drm_sg_mem *entry = dev->sg; @@ -514,14 +512,14 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) return 0; } -resource_size_t drm_core_get_map_ofs(struct drm_local_map * map) +unsigned long drm_core_get_map_ofs(struct drm_map * map) { return map->offset; } EXPORT_SYMBOL(drm_core_get_map_ofs); -resource_size_t drm_core_get_reg_ofs(struct drm_device *dev) +unsigned long drm_core_get_reg_ofs(struct drm_device *dev) { #ifdef __alpha__ return dev->hose->dense_mem_base - dev->hose->mem_space->start; @@ -549,8 +547,8 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) { struct drm_file *priv = filp->private_data; struct drm_device *dev = priv->minor->dev; - struct drm_local_map *map = NULL; - resource_size_t offset = 0; + struct drm_map *map = NULL; + unsigned long offset = 0; struct drm_hash_item *hash; DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", @@ -625,9 +623,9 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) vma->vm_page_prot)) return -EAGAIN; DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," - " offset = 0x%llx\n", + " offset = 0x%lx\n", map->type, - vma->vm_start, vma->vm_end, (unsigned long long)(map->offset + offset)); + vma->vm_start, vma->vm_end, map->offset + offset); vma->vm_ops = &drm_vm_ops; break; case _DRM_CONSISTENT: diff --git a/trunk/drivers/gpu/drm/i810/i810_drv.h b/trunk/drivers/gpu/drm/i810/i810_drv.h index 21e2691f28f9..0118849a5672 100644 --- a/trunk/drivers/gpu/drm/i810/i810_drv.h +++ b/trunk/drivers/gpu/drm/i810/i810_drv.h @@ -77,8 +77,8 @@ typedef struct _drm_i810_ring_buffer { } drm_i810_ring_buffer_t; typedef struct drm_i810_private { - struct drm_local_map *sarea_map; - struct drm_local_map *mmio_map; + struct drm_map *sarea_map; + struct drm_map *mmio_map; drm_i810_sarea_t *sarea_priv; drm_i810_ring_buffer_t ring; diff --git a/trunk/drivers/gpu/drm/i830/i830_drv.h b/trunk/drivers/gpu/drm/i830/i830_drv.h index da82afe4ded5..b5bf8cc0fdaa 100644 --- a/trunk/drivers/gpu/drm/i830/i830_drv.h +++ b/trunk/drivers/gpu/drm/i830/i830_drv.h @@ -84,8 +84,8 @@ typedef struct _drm_i830_ring_buffer { } drm_i830_ring_buffer_t; typedef struct drm_i830_private { - struct drm_local_map *sarea_map; - struct drm_local_map *mmio_map; + struct drm_map *sarea_map; + struct drm_map *mmio_map; drm_i830_sarea_t *sarea_priv; drm_i830_ring_buffer_t ring; diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 85549f615b1f..a818b377e1f7 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -1099,7 +1099,7 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) int i915_driver_load(struct drm_device *dev, unsigned long flags) { struct drm_i915_private *dev_priv = dev->dev_private; - resource_size_t base, size; + unsigned long base, size; int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; /* i915 has 4 more counters */ diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index 2c0167693450..dcb91f5df6e3 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -42,8 +42,6 @@ module_param_named(modeset, i915_modeset, int, 0400); unsigned int i915_fbpercrtc = 0; module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); -static struct drm_driver driver; - static struct pci_device_id pciidlist[] = { i915_PCI_IDS }; @@ -119,36 +117,6 @@ static int i915_resume(struct drm_device *dev) return ret; } -static int __devinit -i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - return drm_get_dev(pdev, ent, &driver); -} - -static void -i915_pci_remove(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - - drm_put_dev(dev); -} - -static int -i915_pci_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - - return i915_suspend(dev, state); -} - -static int -i915_pci_resume(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - - return i915_resume(dev); -} - static struct vm_operations_struct i915_gem_vm_ops = { .fault = i915_gem_fault, .open = drm_gem_vm_open, @@ -206,12 +174,6 @@ static struct drm_driver driver = { .pci_driver = { .name = DRIVER_NAME, .id_table = pciidlist, - .probe = i915_pci_probe, - .remove = i915_pci_remove, -#ifdef CONFIG_PM - .resume = i915_pci_resume, - .suspend = i915_pci_suspend, -#endif }, .name = DRIVER_NAME, diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index e0389ad1477d..b52cba0f16d2 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -446,16 +446,13 @@ fast_shmem_write(struct page **pages, int length) { char __iomem *vaddr; - unsigned long unwritten; vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT], KM_USER0); if (vaddr == NULL) return -ENOMEM; - unwritten = __copy_from_user_inatomic(vaddr + page_offset, data, length); + __copy_from_user_inatomic(vaddr + page_offset, data, length); kunmap_atomic(vaddr, KM_USER0); - if (unwritten) - return -EFAULT; return 0; } @@ -1096,7 +1093,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) struct drm_gem_mm *mm = dev->mm_private; struct drm_i915_gem_object *obj_priv = obj->driver_private; struct drm_map_list *list; - struct drm_local_map *map; + struct drm_map *map; int ret = 0; /* Set the object up for mmap'ing */ diff --git a/trunk/drivers/gpu/drm/mga/mga_dma.c b/trunk/drivers/gpu/drm/mga/mga_dma.c index 7a6bf9ffc5a3..b49c5ff29585 100644 --- a/trunk/drivers/gpu/drm/mga/mga_dma.c +++ b/trunk/drivers/gpu/drm/mga/mga_dma.c @@ -148,8 +148,8 @@ void mga_do_dma_flush(drm_mga_private_t * dev_priv) primary->space = head - tail; } - DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset)); - DRM_DEBUG(" tail = 0x%06lx\n", (unsigned long)(tail - dev_priv->primary->offset)); + DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset); + DRM_DEBUG(" tail = 0x%06lx\n", tail - dev_priv->primary->offset); DRM_DEBUG(" space = 0x%06x\n", primary->space); mga_flush_write_combine(); @@ -187,7 +187,7 @@ void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv) primary->space = head - dev_priv->primary->offset; } - DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset)); + DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset); DRM_DEBUG(" tail = 0x%06x\n", primary->tail); DRM_DEBUG(" wrap = %d\n", primary->last_wrap); DRM_DEBUG(" space = 0x%06x\n", primary->space); @@ -239,7 +239,7 @@ static void mga_freelist_print(struct drm_device * dev) for (entry = dev_priv->head->next; entry; entry = entry->next) { DRM_INFO(" %p idx=%2d age=0x%x 0x%06lx\n", entry, entry->buf->idx, entry->age.head, - (unsigned long)(entry->age.head - dev_priv->primary->offset)); + entry->age.head - dev_priv->primary->offset); } DRM_INFO("\n"); } @@ -340,10 +340,10 @@ static struct drm_buf *mga_freelist_get(struct drm_device * dev) DRM_DEBUG(" tail=0x%06lx %d\n", tail->age.head ? - (unsigned long)(tail->age.head - dev_priv->primary->offset) : 0, + tail->age.head - dev_priv->primary->offset : 0, tail->age.wrap); DRM_DEBUG(" head=0x%06lx %d\n", - (unsigned long)(head - dev_priv->primary->offset), wrap); + head - dev_priv->primary->offset, wrap); if (TEST_AGE(&tail->age, head, wrap)) { prev = dev_priv->tail->prev; @@ -366,9 +366,8 @@ int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf) drm_mga_freelist_t *head, *entry, *prev; DRM_DEBUG("age=0x%06lx wrap=%d\n", - (unsigned long)(buf_priv->list_entry->age.head - - dev_priv->primary->offset), - buf_priv->list_entry->age.wrap); + buf_priv->list_entry->age.head - + dev_priv->primary->offset, buf_priv->list_entry->age.wrap); entry = buf_priv->list_entry; head = dev_priv->head; diff --git a/trunk/drivers/gpu/drm/mga/mga_drv.h b/trunk/drivers/gpu/drm/mga/mga_drv.h index 3d264f288237..88257c276eb9 100644 --- a/trunk/drivers/gpu/drm/mga/mga_drv.h +++ b/trunk/drivers/gpu/drm/mga/mga_drv.h @@ -113,8 +113,8 @@ typedef struct drm_mga_private { * \sa drm_mga_private_t::mmio */ /*@{ */ - resource_size_t mmio_base; /**< Bus address of base of MMIO. */ - resource_size_t mmio_size; /**< Size of the MMIO region. */ + u32 mmio_base; /**< Bus address of base of MMIO. */ + u32 mmio_size; /**< Size of the MMIO region. */ /*@} */ u32 clear_cmd; @@ -317,8 +317,8 @@ do { \ DRM_INFO( "\n" ); \ DRM_INFO( " tail=0x%06x head=0x%06lx\n", \ dev_priv->prim.tail, \ - (unsigned long)(MGA_READ(MGA_PRIMADDRESS) - \ - dev_priv->primary->offset)); \ + MGA_READ( MGA_PRIMADDRESS ) - \ + dev_priv->primary->offset ); \ } \ if ( !test_bit( 0, &dev_priv->prim.wrapped ) ) { \ if ( dev_priv->prim.space < \ diff --git a/trunk/drivers/gpu/drm/r128/r128_cce.c b/trunk/drivers/gpu/drm/r128/r128_cce.c index 32de4cedc363..c31afbde62e7 100644 --- a/trunk/drivers/gpu/drm/r128/r128_cce.c +++ b/trunk/drivers/gpu/drm/r128/r128_cce.c @@ -525,12 +525,11 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) } else #endif { - dev_priv->cce_ring->handle = - (void *)(unsigned long)dev_priv->cce_ring->offset; + dev_priv->cce_ring->handle = (void *)dev_priv->cce_ring->offset; dev_priv->ring_rptr->handle = - (void *)(unsigned long)dev_priv->ring_rptr->offset; + (void *)dev_priv->ring_rptr->offset; dev->agp_buffer_map->handle = - (void *)(unsigned long)dev->agp_buffer_map->offset; + (void *)dev->agp_buffer_map->offset; } #if __OS_HAS_AGP diff --git a/trunk/drivers/gpu/drm/radeon/Makefile b/trunk/drivers/gpu/drm/radeon/Makefile index 52ce439a0f2e..feb521ebc393 100644 --- a/trunk/drivers/gpu/drm/radeon/Makefile +++ b/trunk/drivers/gpu/drm/radeon/Makefile @@ -3,7 +3,7 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. ccflags-y := -Iinclude/drm -radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o r600_cp.o +radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o radeon-$(CONFIG_COMPAT) += radeon_ioc32.o diff --git a/trunk/drivers/gpu/drm/radeon/r300_cmdbuf.c b/trunk/drivers/gpu/drm/radeon/r300_cmdbuf.c index cb2e470f97d4..cace3964feeb 100644 --- a/trunk/drivers/gpu/drm/radeon/r300_cmdbuf.c +++ b/trunk/drivers/gpu/drm/radeon/r300_cmdbuf.c @@ -37,8 +37,6 @@ #include "radeon_drv.h" #include "r300_reg.h" -#include - #define R300_SIMULTANEOUS_CLIPRECTS 4 /* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects @@ -207,10 +205,6 @@ void r300_init_reg_flags(struct drm_device *dev) ADD_RANGE(0x42C0, 2); ADD_RANGE(R300_RS_CNTL_0, 2); - ADD_RANGE(R300_SU_REG_DEST, 1); - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) - ADD_RANGE(RV530_FG_ZBREG_DEST, 1); - ADD_RANGE(R300_SC_HYPERZ, 2); ADD_RANGE(0x43E8, 1); @@ -236,7 +230,6 @@ void r300_init_reg_flags(struct drm_device *dev) ADD_RANGE(R300_ZB_DEPTHPITCH, 1); ADD_RANGE(R300_ZB_DEPTHCLEARVALUE, 1); ADD_RANGE(R300_ZB_ZMASK_OFFSET, 13); - ADD_RANGE(R300_ZB_ZPASS_DATA, 2); /* ZB_ZPASS_DATA, ZB_ZPASS_ADDR */ ADD_RANGE(R300_TX_FILTER_0, 16); ADD_RANGE(R300_TX_FILTER1_0, 16); @@ -924,7 +917,6 @@ static int r300_scratch(drm_radeon_private_t *dev_priv, { u32 *ref_age_base; u32 i, buf_idx, h_pending; - u64 ptr_addr; RING_LOCALS; if (cmdbuf->bufsz < @@ -938,8 +930,7 @@ static int r300_scratch(drm_radeon_private_t *dev_priv, dev_priv->scratch_ages[header.scratch.reg]++; - ptr_addr = get_unaligned((u64 *)cmdbuf->buf); - ref_age_base = (u32 *)(unsigned long)ptr_addr; + ref_age_base = (u32 *)(unsigned long)*((uint64_t *)cmdbuf->buf); cmdbuf->buf += sizeof(u64); cmdbuf->bufsz -= sizeof(u64); diff --git a/trunk/drivers/gpu/drm/radeon/r300_reg.h b/trunk/drivers/gpu/drm/radeon/r300_reg.h index bdbc95fa6721..ee6f811599a3 100644 --- a/trunk/drivers/gpu/drm/radeon/r300_reg.h +++ b/trunk/drivers/gpu/drm/radeon/r300_reg.h @@ -1770,9 +1770,4 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define R500_RB3D_COLOR_CLEAR_VALUE_AR 0x46c0 #define R500_RB3D_CONSTANT_COLOR_AR 0x4ef8 -#define R300_SU_REG_DEST 0x42c8 -#define RV530_FG_ZBREG_DEST 0x4be8 -#define R300_ZB_ZPASS_DATA 0x4f58 -#define R300_ZB_ZPASS_ADDR 0x4f5c - #endif /* _R300_REG_H */ diff --git a/trunk/drivers/gpu/drm/radeon/r600_cp.c b/trunk/drivers/gpu/drm/radeon/r600_cp.c deleted file mode 100644 index 9d14eee3ed09..000000000000 --- a/trunk/drivers/gpu/drm/radeon/r600_cp.c +++ /dev/null @@ -1,2253 +0,0 @@ -/* - * Copyright 2008-2009 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Dave Airlie - * Alex Deucher - */ - -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_drv.h" - -#include "r600_microcode.h" - -# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ -# define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1)) - -#define R600_PTE_VALID (1 << 0) -#define R600_PTE_SYSTEM (1 << 1) -#define R600_PTE_SNOOPED (1 << 2) -#define R600_PTE_READABLE (1 << 5) -#define R600_PTE_WRITEABLE (1 << 6) - -/* MAX values used for gfx init */ -#define R6XX_MAX_SH_GPRS 256 -#define R6XX_MAX_TEMP_GPRS 16 -#define R6XX_MAX_SH_THREADS 256 -#define R6XX_MAX_SH_STACK_ENTRIES 4096 -#define R6XX_MAX_BACKENDS 8 -#define R6XX_MAX_BACKENDS_MASK 0xff -#define R6XX_MAX_SIMDS 8 -#define R6XX_MAX_SIMDS_MASK 0xff -#define R6XX_MAX_PIPES 8 -#define R6XX_MAX_PIPES_MASK 0xff - -#define R7XX_MAX_SH_GPRS 256 -#define R7XX_MAX_TEMP_GPRS 16 -#define R7XX_MAX_SH_THREADS 256 -#define R7XX_MAX_SH_STACK_ENTRIES 4096 -#define R7XX_MAX_BACKENDS 8 -#define R7XX_MAX_BACKENDS_MASK 0xff -#define R7XX_MAX_SIMDS 16 -#define R7XX_MAX_SIMDS_MASK 0xffff -#define R7XX_MAX_PIPES 8 -#define R7XX_MAX_PIPES_MASK 0xff - -static int r600_do_wait_for_fifo(drm_radeon_private_t *dev_priv, int entries) -{ - int i; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - for (i = 0; i < dev_priv->usec_timeout; i++) { - int slots; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) - slots = (RADEON_READ(R600_GRBM_STATUS) - & R700_CMDFIFO_AVAIL_MASK); - else - slots = (RADEON_READ(R600_GRBM_STATUS) - & R600_CMDFIFO_AVAIL_MASK); - if (slots >= entries) - return 0; - DRM_UDELAY(1); - } - DRM_INFO("wait for fifo failed status : 0x%08X 0x%08X\n", - RADEON_READ(R600_GRBM_STATUS), - RADEON_READ(R600_GRBM_STATUS2)); - - return -EBUSY; -} - -static int r600_do_wait_for_idle(drm_radeon_private_t *dev_priv) -{ - int i, ret; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) - ret = r600_do_wait_for_fifo(dev_priv, 8); - else - ret = r600_do_wait_for_fifo(dev_priv, 16); - if (ret) - return ret; - for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(RADEON_READ(R600_GRBM_STATUS) & R600_GUI_ACTIVE)) - return 0; - DRM_UDELAY(1); - } - DRM_INFO("wait idle failed status : 0x%08X 0x%08X\n", - RADEON_READ(R600_GRBM_STATUS), - RADEON_READ(R600_GRBM_STATUS2)); - - return -EBUSY; -} - -void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) -{ - struct drm_sg_mem *entry = dev->sg; - int max_pages; - int pages; - int i; - - if (!entry) - return; - - if (gart_info->bus_addr) { - max_pages = (gart_info->table_size / sizeof(u64)); - pages = (entry->pages <= max_pages) - ? entry->pages : max_pages; - - for (i = 0; i < pages; i++) { - if (!entry->busaddr[i]) - break; - pci_unmap_page(dev->pdev, entry->busaddr[i], - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - } - if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) - gart_info->bus_addr = 0; - } -} - -/* R600 has page table setup */ -int r600_page_table_init(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info; - struct drm_local_map *map = &gart_info->mapping; - struct drm_sg_mem *entry = dev->sg; - int ret = 0; - int i, j; - int pages; - u64 page_base; - dma_addr_t entry_addr; - int max_ati_pages, max_real_pages, gart_idx; - - /* okay page table is available - lets rock */ - max_ati_pages = (gart_info->table_size / sizeof(u64)); - max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); - - pages = (entry->pages <= max_real_pages) ? - entry->pages : max_real_pages; - - memset_io((void __iomem *)map->handle, 0, max_ati_pages * sizeof(u64)); - - gart_idx = 0; - for (i = 0; i < pages; i++) { - entry->busaddr[i] = pci_map_page(dev->pdev, - entry->pagelist[i], 0, - PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); - if (entry->busaddr[i] == 0) { - DRM_ERROR("unable to map PCIGART pages!\n"); - r600_page_table_cleanup(dev, gart_info); - goto done; - } - entry_addr = entry->busaddr[i]; - for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { - page_base = (u64) entry_addr & ATI_PCIGART_PAGE_MASK; - page_base |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED; - page_base |= R600_PTE_READABLE | R600_PTE_WRITEABLE; - - DRM_WRITE64(map, gart_idx * sizeof(u64), page_base); - - gart_idx++; - - if ((i % 128) == 0) - DRM_DEBUG("page entry %d: 0x%016llx\n", - i, (unsigned long long)page_base); - entry_addr += ATI_PCIGART_PAGE_SIZE; - } - } - ret = 1; -done: - return ret; -} - -static void r600_vm_flush_gart_range(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - u32 resp, countdown = 1000; - RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR, dev_priv->gart_vm_start >> 12); - RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); - RADEON_WRITE(R600_VM_CONTEXT0_REQUEST_RESPONSE, 2); - - do { - resp = RADEON_READ(R600_VM_CONTEXT0_REQUEST_RESPONSE); - countdown--; - DRM_UDELAY(1); - } while (((resp & 0xf0) == 0) && countdown); -} - -static void r600_vm_init(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - /* initialise the VM to use the page table we constructed up there */ - u32 vm_c0, i; - u32 mc_rd_a; - u32 vm_l2_cntl, vm_l2_cntl3; - /* okay set up the PCIE aperture type thingo */ - RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12); - RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); - RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); - - /* setup MC RD a */ - mc_rd_a = R600_MCD_L1_TLB | R600_MCD_L1_FRAG_PROC | R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS | - R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | R600_MCD_EFFECTIVE_L1_TLB_SIZE(5) | - R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(5) | R600_MCD_WAIT_L2_QUERY; - - RADEON_WRITE(R600_MCD_RD_A_CNTL, mc_rd_a); - RADEON_WRITE(R600_MCD_RD_B_CNTL, mc_rd_a); - - RADEON_WRITE(R600_MCD_WR_A_CNTL, mc_rd_a); - RADEON_WRITE(R600_MCD_WR_B_CNTL, mc_rd_a); - - RADEON_WRITE(R600_MCD_RD_GFX_CNTL, mc_rd_a); - RADEON_WRITE(R600_MCD_WR_GFX_CNTL, mc_rd_a); - - RADEON_WRITE(R600_MCD_RD_SYS_CNTL, mc_rd_a); - RADEON_WRITE(R600_MCD_WR_SYS_CNTL, mc_rd_a); - - RADEON_WRITE(R600_MCD_RD_HDP_CNTL, mc_rd_a | R600_MCD_L1_STRICT_ORDERING); - RADEON_WRITE(R600_MCD_WR_HDP_CNTL, mc_rd_a /*| R600_MCD_L1_STRICT_ORDERING*/); - - RADEON_WRITE(R600_MCD_RD_PDMA_CNTL, mc_rd_a); - RADEON_WRITE(R600_MCD_WR_PDMA_CNTL, mc_rd_a); - - RADEON_WRITE(R600_MCD_RD_SEM_CNTL, mc_rd_a | R600_MCD_SEMAPHORE_MODE); - RADEON_WRITE(R600_MCD_WR_SEM_CNTL, mc_rd_a); - - vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W; - vm_l2_cntl |= R600_VM_L2_CNTL_QUEUE_SIZE(7); - RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl); - - RADEON_WRITE(R600_VM_L2_CNTL2, 0); - vm_l2_cntl3 = (R600_VM_L2_CNTL3_BANK_SELECT_0(0) | - R600_VM_L2_CNTL3_BANK_SELECT_1(1) | - R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(2)); - RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3); - - vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT; - - RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0); - - vm_c0 &= ~R600_VM_ENABLE_CONTEXT; - - /* disable all other contexts */ - for (i = 1; i < 8; i++) - RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0); - - RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12); - RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12); - RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); - - r600_vm_flush_gart_range(dev); -} - -/* load r600 microcode */ -static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) -{ - int i; - - r600_do_cp_stop(dev_priv); - - RADEON_WRITE(R600_CP_RB_CNTL, - R600_RB_NO_UPDATE | - R600_RB_BLKSZ(15) | - R600_RB_BUFSZ(3)); - - RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); - RADEON_READ(R600_GRBM_SOFT_RESET); - DRM_UDELAY(15000); - RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); - - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600)) { - DRM_INFO("Loading R600 CP Microcode\n"); - for (i = 0; i < PM4_UCODE_SIZE; i++) { - RADEON_WRITE(R600_CP_ME_RAM_DATA, - R600_cp_microcode[i][0]); - RADEON_WRITE(R600_CP_ME_RAM_DATA, - R600_cp_microcode[i][1]); - RADEON_WRITE(R600_CP_ME_RAM_DATA, - R600_cp_microcode[i][2]); - } - - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - DRM_INFO("Loading R600 PFP Microcode\n"); - for (i = 0; i < PFP_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_PFP_UCODE_DATA, R600_pfp_microcode[i]); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610)) { - DRM_INFO("Loading RV610 CP Microcode\n"); - for (i = 0; i < PM4_UCODE_SIZE; i++) { - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV610_cp_microcode[i][0]); - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV610_cp_microcode[i][1]); - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV610_cp_microcode[i][2]); - } - - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - DRM_INFO("Loading RV610 PFP Microcode\n"); - for (i = 0; i < PFP_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV610_pfp_microcode[i]); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) { - DRM_INFO("Loading RV630 CP Microcode\n"); - for (i = 0; i < PM4_UCODE_SIZE; i++) { - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV630_cp_microcode[i][0]); - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV630_cp_microcode[i][1]); - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV630_cp_microcode[i][2]); - } - - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - DRM_INFO("Loading RV630 PFP Microcode\n"); - for (i = 0; i < PFP_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV630_pfp_microcode[i]); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620)) { - DRM_INFO("Loading RV620 CP Microcode\n"); - for (i = 0; i < PM4_UCODE_SIZE; i++) { - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV620_cp_microcode[i][0]); - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV620_cp_microcode[i][1]); - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV620_cp_microcode[i][2]); - } - - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - DRM_INFO("Loading RV620 PFP Microcode\n"); - for (i = 0; i < PFP_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV620_pfp_microcode[i]); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) { - DRM_INFO("Loading RV635 CP Microcode\n"); - for (i = 0; i < PM4_UCODE_SIZE; i++) { - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV635_cp_microcode[i][0]); - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV635_cp_microcode[i][1]); - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV635_cp_microcode[i][2]); - } - - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - DRM_INFO("Loading RV635 PFP Microcode\n"); - for (i = 0; i < PFP_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV635_pfp_microcode[i]); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670)) { - DRM_INFO("Loading RV670 CP Microcode\n"); - for (i = 0; i < PM4_UCODE_SIZE; i++) { - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV670_cp_microcode[i][0]); - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV670_cp_microcode[i][1]); - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV670_cp_microcode[i][2]); - } - - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - DRM_INFO("Loading RV670 PFP Microcode\n"); - for (i = 0; i < PFP_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { - DRM_INFO("Loading RS780 CP Microcode\n"); - for (i = 0; i < PM4_UCODE_SIZE; i++) { - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV670_cp_microcode[i][0]); - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV670_cp_microcode[i][1]); - RADEON_WRITE(R600_CP_ME_RAM_DATA, - RV670_cp_microcode[i][2]); - } - - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - DRM_INFO("Loading RS780 PFP Microcode\n"); - for (i = 0; i < PFP_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]); - } - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); - -} - -static void r700_vm_init(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - /* initialise the VM to use the page table we constructed up there */ - u32 vm_c0, i; - u32 mc_vm_md_l1; - u32 vm_l2_cntl, vm_l2_cntl3; - /* okay set up the PCIE aperture type thingo */ - RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12); - RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); - RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); - - mc_vm_md_l1 = R700_ENABLE_L1_TLB | - R700_ENABLE_L1_FRAGMENT_PROCESSING | - R700_SYSTEM_ACCESS_MODE_IN_SYS | - R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | - R700_EFFECTIVE_L1_TLB_SIZE(5) | - R700_EFFECTIVE_L1_QUEUE_SIZE(5); - - RADEON_WRITE(R700_MC_VM_MD_L1_TLB0_CNTL, mc_vm_md_l1); - RADEON_WRITE(R700_MC_VM_MD_L1_TLB1_CNTL, mc_vm_md_l1); - RADEON_WRITE(R700_MC_VM_MD_L1_TLB2_CNTL, mc_vm_md_l1); - RADEON_WRITE(R700_MC_VM_MB_L1_TLB0_CNTL, mc_vm_md_l1); - RADEON_WRITE(R700_MC_VM_MB_L1_TLB1_CNTL, mc_vm_md_l1); - RADEON_WRITE(R700_MC_VM_MB_L1_TLB2_CNTL, mc_vm_md_l1); - RADEON_WRITE(R700_MC_VM_MB_L1_TLB3_CNTL, mc_vm_md_l1); - - vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W; - vm_l2_cntl |= R700_VM_L2_CNTL_QUEUE_SIZE(7); - RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl); - - RADEON_WRITE(R600_VM_L2_CNTL2, 0); - vm_l2_cntl3 = R700_VM_L2_CNTL3_BANK_SELECT(0) | R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(2); - RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3); - - vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT; - - RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0); - - vm_c0 &= ~R600_VM_ENABLE_CONTEXT; - - /* disable all other contexts */ - for (i = 1; i < 8; i++) - RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0); - - RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12); - RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12); - RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); - - r600_vm_flush_gart_range(dev); -} - -/* load r600 microcode */ -static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) -{ - int i; - - r600_do_cp_stop(dev_priv); - - RADEON_WRITE(R600_CP_RB_CNTL, - R600_RB_NO_UPDATE | - (15 << 8) | - (3 << 0)); - - RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); - RADEON_READ(R600_GRBM_SOFT_RESET); - DRM_UDELAY(15000); - RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); - - - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)) { - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - DRM_INFO("Loading RV770 PFP Microcode\n"); - for (i = 0; i < R700_PFP_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV770_pfp_microcode[i]); - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - DRM_INFO("Loading RV770 CP Microcode\n"); - for (i = 0; i < R700_PM4_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_ME_RAM_DATA, RV770_cp_microcode[i]); - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV730)) { - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - DRM_INFO("Loading RV730 PFP Microcode\n"); - for (i = 0; i < R700_PFP_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV730_pfp_microcode[i]); - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - DRM_INFO("Loading RV730 CP Microcode\n"); - for (i = 0; i < R700_PM4_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_ME_RAM_DATA, RV730_cp_microcode[i]); - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) { - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - DRM_INFO("Loading RV710 PFP Microcode\n"); - for (i = 0; i < R700_PFP_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV710_pfp_microcode[i]); - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - DRM_INFO("Loading RV710 CP Microcode\n"); - for (i = 0; i < R700_PM4_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_ME_RAM_DATA, RV710_cp_microcode[i]); - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - - } - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); - -} - -static void r600_test_writeback(drm_radeon_private_t *dev_priv) -{ - u32 tmp; - - /* Start with assuming that writeback doesn't work */ - dev_priv->writeback_works = 0; - - /* Writeback doesn't seem to work everywhere, test it here and possibly - * enable it if it appears to work - */ - radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0); - - RADEON_WRITE(R600_SCRATCH_REG1, 0xdeadbeef); - - for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { - u32 val; - - val = radeon_read_ring_rptr(dev_priv, R600_SCRATCHOFF(1)); - if (val == 0xdeadbeef) - break; - DRM_UDELAY(1); - } - - if (tmp < dev_priv->usec_timeout) { - dev_priv->writeback_works = 1; - DRM_INFO("writeback test succeeded in %d usecs\n", tmp); - } else { - dev_priv->writeback_works = 0; - DRM_INFO("writeback test failed\n"); - } - if (radeon_no_wb == 1) { - dev_priv->writeback_works = 0; - DRM_INFO("writeback forced off\n"); - } - - if (!dev_priv->writeback_works) { - /* Disable writeback to avoid unnecessary bus master transfer */ - RADEON_WRITE(R600_CP_RB_CNTL, RADEON_READ(R600_CP_RB_CNTL) | - RADEON_RB_NO_UPDATE); - RADEON_WRITE(R600_SCRATCH_UMSK, 0); - } -} - -int r600_do_engine_reset(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - u32 cp_ptr, cp_me_cntl, cp_rb_cntl; - - DRM_INFO("Resetting GPU\n"); - - cp_ptr = RADEON_READ(R600_CP_RB_WPTR); - cp_me_cntl = RADEON_READ(R600_CP_ME_CNTL); - RADEON_WRITE(R600_CP_ME_CNTL, R600_CP_ME_HALT); - - RADEON_WRITE(R600_GRBM_SOFT_RESET, 0x7fff); - RADEON_READ(R600_GRBM_SOFT_RESET); - DRM_UDELAY(50); - RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); - RADEON_READ(R600_GRBM_SOFT_RESET); - - RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); - cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL); - RADEON_WRITE(R600_CP_RB_CNTL, R600_RB_RPTR_WR_ENA); - - RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr); - RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr); - RADEON_WRITE(R600_CP_RB_CNTL, cp_rb_cntl); - RADEON_WRITE(R600_CP_ME_CNTL, cp_me_cntl); - - /* Reset the CP ring */ - r600_do_cp_reset(dev_priv); - - /* The CP is no longer running after an engine reset */ - dev_priv->cp_running = 0; - - /* Reset any pending vertex, indirect buffers */ - radeon_freelist_reset(dev); - - return 0; - -} - -static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes, - u32 num_backends, - u32 backend_disable_mask) -{ - u32 backend_map = 0; - u32 enabled_backends_mask; - u32 enabled_backends_count; - u32 cur_pipe; - u32 swizzle_pipe[R6XX_MAX_PIPES]; - u32 cur_backend; - u32 i; - - if (num_tile_pipes > R6XX_MAX_PIPES) - num_tile_pipes = R6XX_MAX_PIPES; - if (num_tile_pipes < 1) - num_tile_pipes = 1; - if (num_backends > R6XX_MAX_BACKENDS) - num_backends = R6XX_MAX_BACKENDS; - if (num_backends < 1) - num_backends = 1; - - enabled_backends_mask = 0; - enabled_backends_count = 0; - for (i = 0; i < R6XX_MAX_BACKENDS; ++i) { - if (((backend_disable_mask >> i) & 1) == 0) { - enabled_backends_mask |= (1 << i); - ++enabled_backends_count; - } - if (enabled_backends_count == num_backends) - break; - } - - if (enabled_backends_count == 0) { - enabled_backends_mask = 1; - enabled_backends_count = 1; - } - - if (enabled_backends_count != num_backends) - num_backends = enabled_backends_count; - - memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES); - switch (num_tile_pipes) { - case 1: - swizzle_pipe[0] = 0; - break; - case 2: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - break; - case 3: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - break; - case 4: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - break; - case 5: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - break; - case 6: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 5; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - break; - case 7: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - swizzle_pipe[6] = 5; - break; - case 8: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - swizzle_pipe[6] = 5; - swizzle_pipe[7] = 7; - break; - } - - cur_backend = 0; - for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { - while (((1 << cur_backend) & enabled_backends_mask) == 0) - cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; - - backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); - - cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; - } - - return backend_map; -} - -static int r600_count_pipe_bits(uint32_t val) -{ - int i, ret = 0; - for (i = 0; i < 32; i++) { - ret += val & 1; - val >>= 1; - } - return ret; -} - -static void r600_gfx_init(struct drm_device *dev, - drm_radeon_private_t *dev_priv) -{ - int i, j, num_qd_pipes; - u32 sx_debug_1; - u32 tc_cntl; - u32 arb_pop; - u32 num_gs_verts_per_thread; - u32 vgt_gs_per_es; - u32 gs_prim_buffer_depth = 0; - u32 sq_ms_fifo_sizes; - u32 sq_config; - u32 sq_gpr_resource_mgmt_1 = 0; - u32 sq_gpr_resource_mgmt_2 = 0; - u32 sq_thread_resource_mgmt = 0; - u32 sq_stack_resource_mgmt_1 = 0; - u32 sq_stack_resource_mgmt_2 = 0; - u32 hdp_host_path_cntl; - u32 backend_map; - u32 gb_tiling_config = 0; - u32 cc_rb_backend_disable = 0; - u32 cc_gc_shader_pipe_config = 0; - u32 ramcfg; - - /* setup chip specs */ - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_R600: - dev_priv->r600_max_pipes = 4; - dev_priv->r600_max_tile_pipes = 8; - dev_priv->r600_max_simds = 4; - dev_priv->r600_max_backends = 4; - dev_priv->r600_max_gprs = 256; - dev_priv->r600_max_threads = 192; - dev_priv->r600_max_stack_entries = 256; - dev_priv->r600_max_hw_contexts = 8; - dev_priv->r600_max_gs_threads = 16; - dev_priv->r600_sx_max_export_size = 128; - dev_priv->r600_sx_max_export_pos_size = 16; - dev_priv->r600_sx_max_export_smx_size = 128; - dev_priv->r600_sq_num_cf_insts = 2; - break; - case CHIP_RV630: - case CHIP_RV635: - dev_priv->r600_max_pipes = 2; - dev_priv->r600_max_tile_pipes = 2; - dev_priv->r600_max_simds = 3; - dev_priv->r600_max_backends = 1; - dev_priv->r600_max_gprs = 128; - dev_priv->r600_max_threads = 192; - dev_priv->r600_max_stack_entries = 128; - dev_priv->r600_max_hw_contexts = 8; - dev_priv->r600_max_gs_threads = 4; - dev_priv->r600_sx_max_export_size = 128; - dev_priv->r600_sx_max_export_pos_size = 16; - dev_priv->r600_sx_max_export_smx_size = 128; - dev_priv->r600_sq_num_cf_insts = 2; - break; - case CHIP_RV610: - case CHIP_RS780: - case CHIP_RV620: - dev_priv->r600_max_pipes = 1; - dev_priv->r600_max_tile_pipes = 1; - dev_priv->r600_max_simds = 2; - dev_priv->r600_max_backends = 1; - dev_priv->r600_max_gprs = 128; - dev_priv->r600_max_threads = 192; - dev_priv->r600_max_stack_entries = 128; - dev_priv->r600_max_hw_contexts = 4; - dev_priv->r600_max_gs_threads = 4; - dev_priv->r600_sx_max_export_size = 128; - dev_priv->r600_sx_max_export_pos_size = 16; - dev_priv->r600_sx_max_export_smx_size = 128; - dev_priv->r600_sq_num_cf_insts = 1; - break; - case CHIP_RV670: - dev_priv->r600_max_pipes = 4; - dev_priv->r600_max_tile_pipes = 4; - dev_priv->r600_max_simds = 4; - dev_priv->r600_max_backends = 4; - dev_priv->r600_max_gprs = 192; - dev_priv->r600_max_threads = 192; - dev_priv->r600_max_stack_entries = 256; - dev_priv->r600_max_hw_contexts = 8; - dev_priv->r600_max_gs_threads = 16; - dev_priv->r600_sx_max_export_size = 128; - dev_priv->r600_sx_max_export_pos_size = 16; - dev_priv->r600_sx_max_export_smx_size = 128; - dev_priv->r600_sq_num_cf_insts = 2; - break; - default: - break; - } - - /* Initialize HDP */ - j = 0; - for (i = 0; i < 32; i++) { - RADEON_WRITE((0x2c14 + j), 0x00000000); - RADEON_WRITE((0x2c18 + j), 0x00000000); - RADEON_WRITE((0x2c1c + j), 0x00000000); - RADEON_WRITE((0x2c20 + j), 0x00000000); - RADEON_WRITE((0x2c24 + j), 0x00000000); - j += 0x18; - } - - RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff)); - - /* setup tiling, simd, pipe config */ - ramcfg = RADEON_READ(R600_RAMCFG); - - switch (dev_priv->r600_max_tile_pipes) { - case 1: - gb_tiling_config |= R600_PIPE_TILING(0); - break; - case 2: - gb_tiling_config |= R600_PIPE_TILING(1); - break; - case 4: - gb_tiling_config |= R600_PIPE_TILING(2); - break; - case 8: - gb_tiling_config |= R600_PIPE_TILING(3); - break; - default: - break; - } - - gb_tiling_config |= R600_BANK_TILING((ramcfg >> R600_NOOFBANK_SHIFT) & R600_NOOFBANK_MASK); - - gb_tiling_config |= R600_GROUP_SIZE(0); - - if (((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK) > 3) { - gb_tiling_config |= R600_ROW_TILING(3); - gb_tiling_config |= R600_SAMPLE_SPLIT(3); - } else { - gb_tiling_config |= - R600_ROW_TILING(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK)); - gb_tiling_config |= - R600_SAMPLE_SPLIT(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK)); - } - - gb_tiling_config |= R600_BANK_SWAPS(1); - - backend_map = r600_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, - dev_priv->r600_max_backends, - (0xff << dev_priv->r600_max_backends) & 0xff); - gb_tiling_config |= R600_BACKEND_MAP(backend_map); - - cc_gc_shader_pipe_config = - R600_INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R6XX_MAX_PIPES_MASK); - cc_gc_shader_pipe_config |= - R600_INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R6XX_MAX_SIMDS_MASK); - - cc_rb_backend_disable = - R600_BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R6XX_MAX_BACKENDS_MASK); - - RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config); - RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); - RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); - - RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); - RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - - num_qd_pipes = - R6XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK); - RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK); - RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK); - - /* set HW defaults for 3D engine */ - RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) | - R600_ROQ_IB2_START(0x2b))); - - RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, (R600_MEQ_END(0x40) | - R600_ROQ_END(0x40))); - - RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO | - R600_SYNC_GRADIENT | - R600_SYNC_WALKER | - R600_SYNC_ALIGNER)); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) - RADEON_WRITE(R600_ARB_GDEC_RD_CNTL, 0x00000021); - - sx_debug_1 = RADEON_READ(R600_SX_DEBUG_1); - sx_debug_1 |= R600_SMX_EVENT_RELEASE; - if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600)) - sx_debug_1 |= R600_ENABLE_NEW_SMX_ADDRESS; - RADEON_WRITE(R600_SX_DEBUG_1, sx_debug_1); - - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) - RADEON_WRITE(R600_DB_DEBUG, R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE); - else - RADEON_WRITE(R600_DB_DEBUG, 0); - - RADEON_WRITE(R600_DB_WATERMARKS, (R600_DEPTH_FREE(4) | - R600_DEPTH_FLUSH(16) | - R600_DEPTH_PENDING_FREE(4) | - R600_DEPTH_CACHELINE_FREE(16))); - RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); - RADEON_WRITE(R600_VGT_NUM_INSTANCES, 0); - - RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0)); - RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(0)); - - sq_ms_fifo_sizes = RADEON_READ(R600_SQ_MS_FIFO_SIZES); - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { - sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(0xa) | - R600_FETCH_FIFO_HIWATER(0xa) | - R600_DONE_FIFO_HIWATER(0xe0) | - R600_ALU_UPDATE_FIFO_HIWATER(0x8)); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) { - sq_ms_fifo_sizes &= ~R600_DONE_FIFO_HIWATER(0xff); - sq_ms_fifo_sizes |= R600_DONE_FIFO_HIWATER(0x4); - } - RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); - - /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT - * should be adjusted as needed by the 2D/3D drivers. This just sets default values - */ - sq_config = RADEON_READ(R600_SQ_CONFIG); - sq_config &= ~(R600_PS_PRIO(3) | - R600_VS_PRIO(3) | - R600_GS_PRIO(3) | - R600_ES_PRIO(3)); - sq_config |= (R600_DX9_CONSTS | - R600_VC_ENABLE | - R600_PS_PRIO(0) | - R600_VS_PRIO(1) | - R600_GS_PRIO(2) | - R600_ES_PRIO(3)); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) { - sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(124) | - R600_NUM_VS_GPRS(124) | - R600_NUM_CLAUSE_TEMP_GPRS(4)); - sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(0) | - R600_NUM_ES_GPRS(0)); - sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(136) | - R600_NUM_VS_THREADS(48) | - R600_NUM_GS_THREADS(4) | - R600_NUM_ES_THREADS(4)); - sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(128) | - R600_NUM_VS_STACK_ENTRIES(128)); - sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(0) | - R600_NUM_ES_STACK_ENTRIES(0)); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { - /* no vertex cache */ - sq_config &= ~R600_VC_ENABLE; - - sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | - R600_NUM_VS_GPRS(44) | - R600_NUM_CLAUSE_TEMP_GPRS(2)); - sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) | - R600_NUM_ES_GPRS(17)); - sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | - R600_NUM_VS_THREADS(78) | - R600_NUM_GS_THREADS(4) | - R600_NUM_ES_THREADS(31)); - sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) | - R600_NUM_VS_STACK_ENTRIES(40)); - sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) | - R600_NUM_ES_STACK_ENTRIES(16)); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) { - sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | - R600_NUM_VS_GPRS(44) | - R600_NUM_CLAUSE_TEMP_GPRS(2)); - sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(18) | - R600_NUM_ES_GPRS(18)); - sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | - R600_NUM_VS_THREADS(78) | - R600_NUM_GS_THREADS(4) | - R600_NUM_ES_THREADS(31)); - sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) | - R600_NUM_VS_STACK_ENTRIES(40)); - sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) | - R600_NUM_ES_STACK_ENTRIES(16)); - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) { - sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | - R600_NUM_VS_GPRS(44) | - R600_NUM_CLAUSE_TEMP_GPRS(2)); - sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) | - R600_NUM_ES_GPRS(17)); - sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | - R600_NUM_VS_THREADS(78) | - R600_NUM_GS_THREADS(4) | - R600_NUM_ES_THREADS(31)); - sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(64) | - R600_NUM_VS_STACK_ENTRIES(64)); - sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(64) | - R600_NUM_ES_STACK_ENTRIES(64)); - } - - RADEON_WRITE(R600_SQ_CONFIG, sq_config); - RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1); - RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2); - RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); - RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1); - RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2); - - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) - RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_TC_ONLY)); - else - RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_VC_AND_TC)); - - RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_2S, (R600_S0_X(0xc) | - R600_S0_Y(0x4) | - R600_S1_X(0x4) | - R600_S1_Y(0xc))); - RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_4S, (R600_S0_X(0xe) | - R600_S0_Y(0xe) | - R600_S1_X(0x2) | - R600_S1_Y(0x2) | - R600_S2_X(0xa) | - R600_S2_Y(0x6) | - R600_S3_X(0x6) | - R600_S3_Y(0xa))); - RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0, (R600_S0_X(0xe) | - R600_S0_Y(0xb) | - R600_S1_X(0x4) | - R600_S1_Y(0xc) | - R600_S2_X(0x1) | - R600_S2_Y(0x6) | - R600_S3_X(0xa) | - R600_S3_Y(0xe))); - RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1, (R600_S4_X(0x6) | - R600_S4_Y(0x1) | - R600_S5_X(0x0) | - R600_S5_Y(0x0) | - R600_S6_X(0xb) | - R600_S6_Y(0x4) | - R600_S7_X(0x7) | - R600_S7_Y(0x8))); - - - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_R600: - case CHIP_RV630: - case CHIP_RV635: - gs_prim_buffer_depth = 0; - break; - case CHIP_RV610: - case CHIP_RS780: - case CHIP_RV620: - gs_prim_buffer_depth = 32; - break; - case CHIP_RV670: - gs_prim_buffer_depth = 128; - break; - default: - break; - } - - num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16; - vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; - /* Max value for this is 256 */ - if (vgt_gs_per_es > 256) - vgt_gs_per_es = 256; - - RADEON_WRITE(R600_VGT_ES_PER_GS, 128); - RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es); - RADEON_WRITE(R600_VGT_GS_PER_VS, 2); - RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16); - - /* more default values. 2D/3D driver should adjust as needed */ - RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0); - RADEON_WRITE(R600_VGT_STRMOUT_EN, 0); - RADEON_WRITE(R600_SX_MISC, 0); - RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0); - RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0); - RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0); - RADEON_WRITE(R600_SPI_INPUT_Z, 0); - RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2)); - RADEON_WRITE(R600_CB_COLOR7_FRAG, 0); - - /* clear render buffer base addresses */ - RADEON_WRITE(R600_CB_COLOR0_BASE, 0); - RADEON_WRITE(R600_CB_COLOR1_BASE, 0); - RADEON_WRITE(R600_CB_COLOR2_BASE, 0); - RADEON_WRITE(R600_CB_COLOR3_BASE, 0); - RADEON_WRITE(R600_CB_COLOR4_BASE, 0); - RADEON_WRITE(R600_CB_COLOR5_BASE, 0); - RADEON_WRITE(R600_CB_COLOR6_BASE, 0); - RADEON_WRITE(R600_CB_COLOR7_BASE, 0); - - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_RV610: - case CHIP_RS780: - case CHIP_RV620: - tc_cntl = R600_TC_L2_SIZE(8); - break; - case CHIP_RV630: - case CHIP_RV635: - tc_cntl = R600_TC_L2_SIZE(4); - break; - case CHIP_R600: - tc_cntl = R600_TC_L2_SIZE(0) | R600_L2_DISABLE_LATE_HIT; - break; - default: - tc_cntl = R600_TC_L2_SIZE(0); - break; - } - - RADEON_WRITE(R600_TC_CNTL, tc_cntl); - - hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL); - RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl); - - arb_pop = RADEON_READ(R600_ARB_POP); - arb_pop |= R600_ENABLE_TC128; - RADEON_WRITE(R600_ARB_POP, arb_pop); - - RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); - RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA | - R600_NUM_CLIP_SEQ(3))); - RADEON_WRITE(R600_PA_SC_ENHANCE, R600_FORCE_EOV_MAX_CLK_CNT(4095)); - -} - -static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes, - u32 num_backends, - u32 backend_disable_mask) -{ - u32 backend_map = 0; - u32 enabled_backends_mask; - u32 enabled_backends_count; - u32 cur_pipe; - u32 swizzle_pipe[R7XX_MAX_PIPES]; - u32 cur_backend; - u32 i; - - if (num_tile_pipes > R7XX_MAX_PIPES) - num_tile_pipes = R7XX_MAX_PIPES; - if (num_tile_pipes < 1) - num_tile_pipes = 1; - if (num_backends > R7XX_MAX_BACKENDS) - num_backends = R7XX_MAX_BACKENDS; - if (num_backends < 1) - num_backends = 1; - - enabled_backends_mask = 0; - enabled_backends_count = 0; - for (i = 0; i < R7XX_MAX_BACKENDS; ++i) { - if (((backend_disable_mask >> i) & 1) == 0) { - enabled_backends_mask |= (1 << i); - ++enabled_backends_count; - } - if (enabled_backends_count == num_backends) - break; - } - - if (enabled_backends_count == 0) { - enabled_backends_mask = 1; - enabled_backends_count = 1; - } - - if (enabled_backends_count != num_backends) - num_backends = enabled_backends_count; - - memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES); - switch (num_tile_pipes) { - case 1: - swizzle_pipe[0] = 0; - break; - case 2: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - break; - case 3: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 1; - break; - case 4: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 3; - swizzle_pipe[3] = 1; - break; - case 5: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 1; - swizzle_pipe[4] = 3; - break; - case 6: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 5; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 1; - break; - case 7: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 1; - swizzle_pipe[6] = 5; - break; - case 8: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 1; - swizzle_pipe[6] = 7; - swizzle_pipe[7] = 5; - break; - } - - cur_backend = 0; - for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { - while (((1 << cur_backend) & enabled_backends_mask) == 0) - cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; - - backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); - - cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; - } - - return backend_map; -} - -static void r700_gfx_init(struct drm_device *dev, - drm_radeon_private_t *dev_priv) -{ - int i, j, num_qd_pipes; - u32 sx_debug_1; - u32 smx_dc_ctl0; - u32 num_gs_verts_per_thread; - u32 vgt_gs_per_es; - u32 gs_prim_buffer_depth = 0; - u32 sq_ms_fifo_sizes; - u32 sq_config; - u32 sq_thread_resource_mgmt; - u32 hdp_host_path_cntl; - u32 sq_dyn_gpr_size_simd_ab_0; - u32 backend_map; - u32 gb_tiling_config = 0; - u32 cc_rb_backend_disable = 0; - u32 cc_gc_shader_pipe_config = 0; - u32 mc_arb_ramcfg; - u32 db_debug4; - - /* setup chip specs */ - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_RV770: - dev_priv->r600_max_pipes = 4; - dev_priv->r600_max_tile_pipes = 8; - dev_priv->r600_max_simds = 10; - dev_priv->r600_max_backends = 4; - dev_priv->r600_max_gprs = 256; - dev_priv->r600_max_threads = 248; - dev_priv->r600_max_stack_entries = 512; - dev_priv->r600_max_hw_contexts = 8; - dev_priv->r600_max_gs_threads = 16 * 2; - dev_priv->r600_sx_max_export_size = 128; - dev_priv->r600_sx_max_export_pos_size = 16; - dev_priv->r600_sx_max_export_smx_size = 112; - dev_priv->r600_sq_num_cf_insts = 2; - - dev_priv->r700_sx_num_of_sets = 7; - dev_priv->r700_sc_prim_fifo_size = 0xF9; - dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; - dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; - break; - case CHIP_RV730: - dev_priv->r600_max_pipes = 2; - dev_priv->r600_max_tile_pipes = 4; - dev_priv->r600_max_simds = 8; - dev_priv->r600_max_backends = 2; - dev_priv->r600_max_gprs = 128; - dev_priv->r600_max_threads = 248; - dev_priv->r600_max_stack_entries = 256; - dev_priv->r600_max_hw_contexts = 8; - dev_priv->r600_max_gs_threads = 16 * 2; - dev_priv->r600_sx_max_export_size = 256; - dev_priv->r600_sx_max_export_pos_size = 32; - dev_priv->r600_sx_max_export_smx_size = 224; - dev_priv->r600_sq_num_cf_insts = 2; - - dev_priv->r700_sx_num_of_sets = 7; - dev_priv->r700_sc_prim_fifo_size = 0xf9; - dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; - dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; - break; - case CHIP_RV710: - dev_priv->r600_max_pipes = 2; - dev_priv->r600_max_tile_pipes = 2; - dev_priv->r600_max_simds = 2; - dev_priv->r600_max_backends = 1; - dev_priv->r600_max_gprs = 256; - dev_priv->r600_max_threads = 192; - dev_priv->r600_max_stack_entries = 256; - dev_priv->r600_max_hw_contexts = 4; - dev_priv->r600_max_gs_threads = 8 * 2; - dev_priv->r600_sx_max_export_size = 128; - dev_priv->r600_sx_max_export_pos_size = 16; - dev_priv->r600_sx_max_export_smx_size = 112; - dev_priv->r600_sq_num_cf_insts = 1; - - dev_priv->r700_sx_num_of_sets = 7; - dev_priv->r700_sc_prim_fifo_size = 0x40; - dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; - dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; - break; - default: - break; - } - - /* Initialize HDP */ - j = 0; - for (i = 0; i < 32; i++) { - RADEON_WRITE((0x2c14 + j), 0x00000000); - RADEON_WRITE((0x2c18 + j), 0x00000000); - RADEON_WRITE((0x2c1c + j), 0x00000000); - RADEON_WRITE((0x2c20 + j), 0x00000000); - RADEON_WRITE((0x2c24 + j), 0x00000000); - j += 0x18; - } - - RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff)); - - /* setup tiling, simd, pipe config */ - mc_arb_ramcfg = RADEON_READ(R700_MC_ARB_RAMCFG); - - switch (dev_priv->r600_max_tile_pipes) { - case 1: - gb_tiling_config |= R600_PIPE_TILING(0); - break; - case 2: - gb_tiling_config |= R600_PIPE_TILING(1); - break; - case 4: - gb_tiling_config |= R600_PIPE_TILING(2); - break; - case 8: - gb_tiling_config |= R600_PIPE_TILING(3); - break; - default: - break; - } - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770) - gb_tiling_config |= R600_BANK_TILING(1); - else - gb_tiling_config |= R600_BANK_TILING((mc_arb_ramcfg >> R700_NOOFBANK_SHIFT) & R700_NOOFBANK_MASK); - - gb_tiling_config |= R600_GROUP_SIZE(0); - - if (((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK) > 3) { - gb_tiling_config |= R600_ROW_TILING(3); - gb_tiling_config |= R600_SAMPLE_SPLIT(3); - } else { - gb_tiling_config |= - R600_ROW_TILING(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK)); - gb_tiling_config |= - R600_SAMPLE_SPLIT(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK)); - } - - gb_tiling_config |= R600_BANK_SWAPS(1); - - backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, - dev_priv->r600_max_backends, - (0xff << dev_priv->r600_max_backends) & 0xff); - gb_tiling_config |= R600_BACKEND_MAP(backend_map); - - cc_gc_shader_pipe_config = - R600_INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R7XX_MAX_PIPES_MASK); - cc_gc_shader_pipe_config |= - R600_INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R7XX_MAX_SIMDS_MASK); - - cc_rb_backend_disable = - R600_BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R7XX_MAX_BACKENDS_MASK); - - RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config); - RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); - RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); - - RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); - RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - - RADEON_WRITE(R700_CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); - RADEON_WRITE(R700_CGTS_SYS_TCC_DISABLE, 0); - RADEON_WRITE(R700_CGTS_TCC_DISABLE, 0); - RADEON_WRITE(R700_CGTS_USER_SYS_TCC_DISABLE, 0); - RADEON_WRITE(R700_CGTS_USER_TCC_DISABLE, 0); - - num_qd_pipes = - R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK); - RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK); - RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK); - - /* set HW defaults for 3D engine */ - RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) | - R600_ROQ_IB2_START(0x2b))); - - RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, R700_STQ_SPLIT(0x30)); - - RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO | - R600_SYNC_GRADIENT | - R600_SYNC_WALKER | - R600_SYNC_ALIGNER)); - - sx_debug_1 = RADEON_READ(R700_SX_DEBUG_1); - sx_debug_1 |= R700_ENABLE_NEW_SMX_ADDRESS; - RADEON_WRITE(R700_SX_DEBUG_1, sx_debug_1); - - smx_dc_ctl0 = RADEON_READ(R600_SMX_DC_CTL0); - smx_dc_ctl0 &= ~R700_CACHE_DEPTH(0x1ff); - smx_dc_ctl0 |= R700_CACHE_DEPTH((dev_priv->r700_sx_num_of_sets * 64) - 1); - RADEON_WRITE(R600_SMX_DC_CTL0, smx_dc_ctl0); - - RADEON_WRITE(R700_SMX_EVENT_CTL, (R700_ES_FLUSH_CTL(4) | - R700_GS_FLUSH_CTL(4) | - R700_ACK_FLUSH_CTL(3) | - R700_SYNC_FLUSH_CTL)); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770) - RADEON_WRITE(R700_DB_DEBUG3, R700_DB_CLK_OFF_DELAY(0x1f)); - else { - db_debug4 = RADEON_READ(RV700_DB_DEBUG4); - db_debug4 |= RV700_DISABLE_TILE_COVERED_FOR_PS_ITER; - RADEON_WRITE(RV700_DB_DEBUG4, db_debug4); - } - - RADEON_WRITE(R600_SX_EXPORT_BUFFER_SIZES, (R600_COLOR_BUFFER_SIZE((dev_priv->r600_sx_max_export_size / 4) - 1) | - R600_POSITION_BUFFER_SIZE((dev_priv->r600_sx_max_export_pos_size / 4) - 1) | - R600_SMX_BUFFER_SIZE((dev_priv->r600_sx_max_export_smx_size / 4) - 1))); - - RADEON_WRITE(R700_PA_SC_FIFO_SIZE_R7XX, (R700_SC_PRIM_FIFO_SIZE(dev_priv->r700_sc_prim_fifo_size) | - R700_SC_HIZ_TILE_FIFO_SIZE(dev_priv->r700_sc_hiz_tile_fifo_size) | - R700_SC_EARLYZ_TILE_FIFO_SIZE(dev_priv->r700_sc_earlyz_tile_fifo_fize))); - - RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); - - RADEON_WRITE(R600_VGT_NUM_INSTANCES, 1); - - RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0)); - - RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(4)); - - RADEON_WRITE(R600_CP_PERFMON_CNTL, 0); - - sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(16 * dev_priv->r600_sq_num_cf_insts) | - R600_DONE_FIFO_HIWATER(0xe0) | - R600_ALU_UPDATE_FIFO_HIWATER(0x8)); - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_RV770: - sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x1); - break; - case CHIP_RV730: - case CHIP_RV710: - default: - sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x4); - break; - } - RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); - - /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT - * should be adjusted as needed by the 2D/3D drivers. This just sets default values - */ - sq_config = RADEON_READ(R600_SQ_CONFIG); - sq_config &= ~(R600_PS_PRIO(3) | - R600_VS_PRIO(3) | - R600_GS_PRIO(3) | - R600_ES_PRIO(3)); - sq_config |= (R600_DX9_CONSTS | - R600_VC_ENABLE | - R600_EXPORT_SRC_C | - R600_PS_PRIO(0) | - R600_VS_PRIO(1) | - R600_GS_PRIO(2) | - R600_ES_PRIO(3)); - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710) - /* no vertex cache */ - sq_config &= ~R600_VC_ENABLE; - - RADEON_WRITE(R600_SQ_CONFIG, sq_config); - - RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, (R600_NUM_PS_GPRS((dev_priv->r600_max_gprs * 24)/64) | - R600_NUM_VS_GPRS((dev_priv->r600_max_gprs * 24)/64) | - R600_NUM_CLAUSE_TEMP_GPRS(((dev_priv->r600_max_gprs * 24)/64)/2))); - - RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, (R600_NUM_GS_GPRS((dev_priv->r600_max_gprs * 7)/64) | - R600_NUM_ES_GPRS((dev_priv->r600_max_gprs * 7)/64))); - - sq_thread_resource_mgmt = (R600_NUM_PS_THREADS((dev_priv->r600_max_threads * 4)/8) | - R600_NUM_VS_THREADS((dev_priv->r600_max_threads * 2)/8) | - R600_NUM_ES_THREADS((dev_priv->r600_max_threads * 1)/8)); - if (((dev_priv->r600_max_threads * 1) / 8) > dev_priv->r600_max_gs_threads) - sq_thread_resource_mgmt |= R600_NUM_GS_THREADS(dev_priv->r600_max_gs_threads); - else - sq_thread_resource_mgmt |= R600_NUM_GS_THREADS((dev_priv->r600_max_gs_threads * 1)/8); - RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); - - RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, (R600_NUM_PS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) | - R600_NUM_VS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4))); - - RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, (R600_NUM_GS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) | - R600_NUM_ES_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4))); - - sq_dyn_gpr_size_simd_ab_0 = (R700_SIMDA_RING0((dev_priv->r600_max_gprs * 38)/64) | - R700_SIMDA_RING1((dev_priv->r600_max_gprs * 38)/64) | - R700_SIMDB_RING0((dev_priv->r600_max_gprs * 38)/64) | - R700_SIMDB_RING1((dev_priv->r600_max_gprs * 38)/64)); - - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0); - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0); - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0); - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0); - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0); - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0); - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0); - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0); - - RADEON_WRITE(R700_PA_SC_FORCE_EOV_MAX_CNTS, (R700_FORCE_EOV_MAX_CLK_CNT(4095) | - R700_FORCE_EOV_MAX_REZ_CNT(255))); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710) - RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_TC_ONLY) | - R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO))); - else - RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_VC_AND_TC) | - R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO))); - - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_RV770: - case CHIP_RV730: - gs_prim_buffer_depth = 384; - break; - case CHIP_RV710: - gs_prim_buffer_depth = 128; - break; - default: - break; - } - - num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16; - vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; - /* Max value for this is 256 */ - if (vgt_gs_per_es > 256) - vgt_gs_per_es = 256; - - RADEON_WRITE(R600_VGT_ES_PER_GS, 128); - RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es); - RADEON_WRITE(R600_VGT_GS_PER_VS, 2); - - /* more default values. 2D/3D driver should adjust as needed */ - RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16); - RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0); - RADEON_WRITE(R600_VGT_STRMOUT_EN, 0); - RADEON_WRITE(R600_SX_MISC, 0); - RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0); - RADEON_WRITE(R700_PA_SC_EDGERULE, 0xaaaaaaaa); - RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0); - RADEON_WRITE(R600_PA_SC_CLIPRECT_RULE, 0xffff); - RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0); - RADEON_WRITE(R600_SPI_INPUT_Z, 0); - RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2)); - RADEON_WRITE(R600_CB_COLOR7_FRAG, 0); - - /* clear render buffer base addresses */ - RADEON_WRITE(R600_CB_COLOR0_BASE, 0); - RADEON_WRITE(R600_CB_COLOR1_BASE, 0); - RADEON_WRITE(R600_CB_COLOR2_BASE, 0); - RADEON_WRITE(R600_CB_COLOR3_BASE, 0); - RADEON_WRITE(R600_CB_COLOR4_BASE, 0); - RADEON_WRITE(R600_CB_COLOR5_BASE, 0); - RADEON_WRITE(R600_CB_COLOR6_BASE, 0); - RADEON_WRITE(R600_CB_COLOR7_BASE, 0); - - RADEON_WRITE(R700_TCP_CNTL, 0); - - hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL); - RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl); - - RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); - - RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA | - R600_NUM_CLIP_SEQ(3))); - -} - -static void r600_cp_init_ring_buffer(struct drm_device *dev, - drm_radeon_private_t *dev_priv, - struct drm_file *file_priv) -{ - struct drm_radeon_master_private *master_priv; - u32 ring_start; - u64 rptr_addr; - - if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) - r700_gfx_init(dev, dev_priv); - else - r600_gfx_init(dev, dev_priv); - - RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); - RADEON_READ(R600_GRBM_SOFT_RESET); - DRM_UDELAY(15000); - RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); - - - /* Set ring buffer size */ -#ifdef __BIG_ENDIAN - RADEON_WRITE(R600_CP_RB_CNTL, - RADEON_BUF_SWAP_32BIT | - RADEON_RB_NO_UPDATE | - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#else - RADEON_WRITE(R600_CP_RB_CNTL, - RADEON_RB_NO_UPDATE | - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#endif - - RADEON_WRITE(R600_CP_SEM_WAIT_TIMER, 0x4); - - /* Set the write pointer delay */ - RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); - -#ifdef __BIG_ENDIAN - RADEON_WRITE(R600_CP_RB_CNTL, - RADEON_BUF_SWAP_32BIT | - RADEON_RB_NO_UPDATE | - RADEON_RB_RPTR_WR_ENA | - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#else - RADEON_WRITE(R600_CP_RB_CNTL, - RADEON_RB_NO_UPDATE | - RADEON_RB_RPTR_WR_ENA | - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#endif - - /* Initialize the ring buffer's read and write pointers */ - RADEON_WRITE(R600_CP_RB_RPTR_WR, 0); - RADEON_WRITE(R600_CP_RB_WPTR, 0); - SET_RING_HEAD(dev_priv, 0); - dev_priv->ring.tail = 0; - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - rptr_addr = dev_priv->ring_rptr->offset - - dev->agp->base + - dev_priv->gart_vm_start; - } else -#endif - { - rptr_addr = dev_priv->ring_rptr->offset - - ((unsigned long) dev->sg->virtual) - + dev_priv->gart_vm_start; - } - RADEON_WRITE(R600_CP_RB_RPTR_ADDR, - rptr_addr & 0xffffffff); - RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, - upper_32_bits(rptr_addr)); - -#ifdef __BIG_ENDIAN - RADEON_WRITE(R600_CP_RB_CNTL, - RADEON_BUF_SWAP_32BIT | - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#else - RADEON_WRITE(R600_CP_RB_CNTL, - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#endif - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - /* XXX */ - radeon_write_agp_base(dev_priv, dev->agp->base); - - /* XXX */ - radeon_write_agp_location(dev_priv, - (((dev_priv->gart_vm_start - 1 + - dev_priv->gart_size) & 0xffff0000) | - (dev_priv->gart_vm_start >> 16))); - - ring_start = (dev_priv->cp_ring->offset - - dev->agp->base - + dev_priv->gart_vm_start); - } else -#endif - ring_start = (dev_priv->cp_ring->offset - - (unsigned long)dev->sg->virtual - + dev_priv->gart_vm_start); - - RADEON_WRITE(R600_CP_RB_BASE, ring_start >> 8); - - RADEON_WRITE(R600_CP_ME_CNTL, 0xff); - - RADEON_WRITE(R600_CP_DEBUG, (1 << 27) | (1 << 28)); - - /* Initialize the scratch register pointer. This will cause - * the scratch register values to be written out to memory - * whenever they are updated. - * - * We simply put this behind the ring read pointer, this works - * with PCI GART as well as (whatever kind of) AGP GART - */ - { - u64 scratch_addr; - - scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR); - scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32; - scratch_addr += R600_SCRATCH_REG_OFFSET; - scratch_addr >>= 8; - scratch_addr &= 0xffffffff; - - RADEON_WRITE(R600_SCRATCH_ADDR, (uint32_t)scratch_addr); - } - - RADEON_WRITE(R600_SCRATCH_UMSK, 0x7); - - /* Turn on bus mastering */ - radeon_enable_bm(dev_priv); - - radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(0), 0); - RADEON_WRITE(R600_LAST_FRAME_REG, 0); - - radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0); - RADEON_WRITE(R600_LAST_DISPATCH_REG, 0); - - radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(2), 0); - RADEON_WRITE(R600_LAST_CLEAR_REG, 0); - - /* reset sarea copies of these */ - master_priv = file_priv->master->driver_priv; - if (master_priv->sarea_priv) { - master_priv->sarea_priv->last_frame = 0; - master_priv->sarea_priv->last_dispatch = 0; - master_priv->sarea_priv->last_clear = 0; - } - - r600_do_wait_for_idle(dev_priv); - -} - -int r600_do_cleanup_cp(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - /* Make sure interrupts are disabled here because the uninstall ioctl - * may not have been called from userspace and after dev_private - * is freed, it's too late. - */ - if (dev->irq_enabled) - drm_irq_uninstall(dev); - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - if (dev_priv->cp_ring != NULL) { - drm_core_ioremapfree(dev_priv->cp_ring, dev); - dev_priv->cp_ring = NULL; - } - if (dev_priv->ring_rptr != NULL) { - drm_core_ioremapfree(dev_priv->ring_rptr, dev); - dev_priv->ring_rptr = NULL; - } - if (dev->agp_buffer_map != NULL) { - drm_core_ioremapfree(dev->agp_buffer_map, dev); - dev->agp_buffer_map = NULL; - } - } else -#endif - { - - if (dev_priv->gart_info.bus_addr) - r600_page_table_cleanup(dev, &dev_priv->gart_info); - - if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { - drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); - dev_priv->gart_info.addr = NULL; - } - } - /* only clear to the start of flags */ - memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); - - return 0; -} - -int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, - struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; - - DRM_DEBUG("\n"); - - /* if we require new memory map but we don't have it fail */ - if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { - DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { - DRM_DEBUG("Forcing AGP card to PCI mode\n"); - dev_priv->flags &= ~RADEON_IS_AGP; - /* The writeback test succeeds, but when writeback is enabled, - * the ring buffer read ptr update fails after first 128 bytes. - */ - radeon_no_wb = 1; - } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) - && !init->is_pci) { - DRM_DEBUG("Restoring AGP flag\n"); - dev_priv->flags |= RADEON_IS_AGP; - } - - dev_priv->usec_timeout = init->usec_timeout; - if (dev_priv->usec_timeout < 1 || - dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { - DRM_DEBUG("TIMEOUT problem!\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - /* Enable vblank on CRTC1 for older X servers - */ - dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; - - dev_priv->cp_mode = init->cp_mode; - - /* We don't support anything other than bus-mastering ring mode, - * but the ring can be in either AGP or PCI space for the ring - * read pointer. - */ - if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && - (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { - DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - switch (init->fb_bpp) { - case 16: - dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; - break; - case 32: - default: - dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; - break; - } - dev_priv->front_offset = init->front_offset; - dev_priv->front_pitch = init->front_pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->back_pitch = init->back_pitch; - - dev_priv->ring_offset = init->ring_offset; - dev_priv->ring_rptr_offset = init->ring_rptr_offset; - dev_priv->buffers_offset = init->buffers_offset; - dev_priv->gart_textures_offset = init->gart_textures_offset; - - master_priv->sarea = drm_getsarea(dev); - if (!master_priv->sarea) { - DRM_ERROR("could not find sarea!\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); - if (!dev_priv->cp_ring) { - DRM_ERROR("could not find cp ring region!\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); - if (!dev_priv->ring_rptr) { - DRM_ERROR("could not find ring read pointer!\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - dev->agp_buffer_token = init->buffers_offset; - dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); - if (!dev->agp_buffer_map) { - DRM_ERROR("could not find dma buffer region!\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - if (init->gart_textures_offset) { - dev_priv->gart_textures = - drm_core_findmap(dev, init->gart_textures_offset); - if (!dev_priv->gart_textures) { - DRM_ERROR("could not find GART texture region!\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - } - -#if __OS_HAS_AGP - /* XXX */ - if (dev_priv->flags & RADEON_IS_AGP) { - drm_core_ioremap_wc(dev_priv->cp_ring, dev); - drm_core_ioremap_wc(dev_priv->ring_rptr, dev); - drm_core_ioremap_wc(dev->agp_buffer_map, dev); - if (!dev_priv->cp_ring->handle || - !dev_priv->ring_rptr->handle || - !dev->agp_buffer_map->handle) { - DRM_ERROR("could not find ioremap agp regions!\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - } else -#endif - { - dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset; - dev_priv->ring_rptr->handle = - (void *)dev_priv->ring_rptr->offset; - dev->agp_buffer_map->handle = - (void *)dev->agp_buffer_map->offset; - - DRM_DEBUG("dev_priv->cp_ring->handle %p\n", - dev_priv->cp_ring->handle); - DRM_DEBUG("dev_priv->ring_rptr->handle %p\n", - dev_priv->ring_rptr->handle); - DRM_DEBUG("dev->agp_buffer_map->handle %p\n", - dev->agp_buffer_map->handle); - } - - dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 24; - dev_priv->fb_size = - (((radeon_read_fb_location(dev_priv) & 0xffff0000u) << 8) + 0x1000000) - - dev_priv->fb_location; - - dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | - ((dev_priv->front_offset - + dev_priv->fb_location) >> 10)); - - dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) | - ((dev_priv->back_offset - + dev_priv->fb_location) >> 10)); - - dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) | - ((dev_priv->depth_offset - + dev_priv->fb_location) >> 10)); - - dev_priv->gart_size = init->gart_size; - - /* New let's set the memory map ... */ - if (dev_priv->new_memmap) { - u32 base = 0; - - DRM_INFO("Setting GART location based on new memory map\n"); - - /* If using AGP, try to locate the AGP aperture at the same - * location in the card and on the bus, though we have to - * align it down. - */ -#if __OS_HAS_AGP - /* XXX */ - if (dev_priv->flags & RADEON_IS_AGP) { - base = dev->agp->base; - /* Check if valid */ - if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location && - base < (dev_priv->fb_location + dev_priv->fb_size - 1)) { - DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", - dev->agp->base); - base = 0; - } - } -#endif - /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ - if (base == 0) { - base = dev_priv->fb_location + dev_priv->fb_size; - if (base < dev_priv->fb_location || - ((base + dev_priv->gart_size) & 0xfffffffful) < base) - base = dev_priv->fb_location - - dev_priv->gart_size; - } - dev_priv->gart_vm_start = base & 0xffc00000u; - if (dev_priv->gart_vm_start != base) - DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n", - base, dev_priv->gart_vm_start); - } - -#if __OS_HAS_AGP - /* XXX */ - if (dev_priv->flags & RADEON_IS_AGP) - dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - - dev->agp->base - + dev_priv->gart_vm_start); - else -#endif - dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - - (unsigned long)dev->sg->virtual - + dev_priv->gart_vm_start); - - DRM_DEBUG("fb 0x%08x size %d\n", - (unsigned int) dev_priv->fb_location, - (unsigned int) dev_priv->fb_size); - DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size); - DRM_DEBUG("dev_priv->gart_vm_start 0x%08x\n", - (unsigned int) dev_priv->gart_vm_start); - DRM_DEBUG("dev_priv->gart_buffers_offset 0x%08lx\n", - dev_priv->gart_buffers_offset); - - dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle; - dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle - + init->ring_size / sizeof(u32)); - dev_priv->ring.size = init->ring_size; - dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); - - dev_priv->ring.rptr_update = /* init->rptr_update */ 4096; - dev_priv->ring.rptr_update_l2qw = drm_order(/* init->rptr_update */ 4096 / 8); - - dev_priv->ring.fetch_size = /* init->fetch_size */ 32; - dev_priv->ring.fetch_size_l2ow = drm_order(/* init->fetch_size */ 32 / 16); - - dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; - - dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - /* XXX turn off pcie gart */ - } else -#endif - { - dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); - /* if we have an offset set from userspace */ - if (!dev_priv->pcigart_offset_set) { - DRM_ERROR("Need gart offset from userspace\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - DRM_DEBUG("Using gart offset 0x%08lx\n", dev_priv->pcigart_offset); - - dev_priv->gart_info.bus_addr = - dev_priv->pcigart_offset + dev_priv->fb_location; - dev_priv->gart_info.mapping.offset = - dev_priv->pcigart_offset + dev_priv->fb_aper_offset; - dev_priv->gart_info.mapping.size = - dev_priv->gart_info.table_size; - - drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev); - if (!dev_priv->gart_info.mapping.handle) { - DRM_ERROR("ioremap failed.\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - dev_priv->gart_info.addr = - dev_priv->gart_info.mapping.handle; - - DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", - dev_priv->gart_info.addr, - dev_priv->pcigart_offset); - - if (!r600_page_table_init(dev)) { - DRM_ERROR("Failed to init GART table\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) - r700_vm_init(dev); - else - r600_vm_init(dev); - } - - if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) - r700_cp_load_microcode(dev_priv); - else - r600_cp_load_microcode(dev_priv); - - r600_cp_init_ring_buffer(dev, dev_priv, file_priv); - - dev_priv->last_buf = 0; - - r600_do_engine_reset(dev); - r600_test_writeback(dev_priv); - - return 0; -} - -int r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - DRM_DEBUG("\n"); - if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) { - r700_vm_init(dev); - r700_cp_load_microcode(dev_priv); - } else { - r600_vm_init(dev); - r600_cp_load_microcode(dev_priv); - } - r600_cp_init_ring_buffer(dev, dev_priv, file_priv); - r600_do_engine_reset(dev); - - return 0; -} - -/* Wait for the CP to go idle. - */ -int r600_do_cp_idle(drm_radeon_private_t *dev_priv) -{ - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(5); - OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); - OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); - /* wait for 3D idle clean */ - OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); - OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2); - OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN); - - ADVANCE_RING(); - COMMIT_RING(); - - return r600_do_wait_for_idle(dev_priv); -} - -/* Start the Command Processor. - */ -void r600_do_cp_start(drm_radeon_private_t *dev_priv) -{ - u32 cp_me; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(7); - OUT_RING(CP_PACKET3(R600_IT_ME_INITIALIZE, 5)); - OUT_RING(0x00000001); - if (((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) - OUT_RING(0x00000003); - else - OUT_RING(0x00000000); - OUT_RING((dev_priv->r600_max_hw_contexts - 1)); - OUT_RING(R600_ME_INITIALIZE_DEVICE_ID(1)); - OUT_RING(0x00000000); - OUT_RING(0x00000000); - ADVANCE_RING(); - COMMIT_RING(); - - /* set the mux and reset the halt bit */ - cp_me = 0xff; - RADEON_WRITE(R600_CP_ME_CNTL, cp_me); - - dev_priv->cp_running = 1; - -} - -void r600_do_cp_reset(drm_radeon_private_t *dev_priv) -{ - u32 cur_read_ptr; - DRM_DEBUG("\n"); - - cur_read_ptr = RADEON_READ(R600_CP_RB_RPTR); - RADEON_WRITE(R600_CP_RB_WPTR, cur_read_ptr); - SET_RING_HEAD(dev_priv, cur_read_ptr); - dev_priv->ring.tail = cur_read_ptr; -} - -void r600_do_cp_stop(drm_radeon_private_t *dev_priv) -{ - uint32_t cp_me; - - DRM_DEBUG("\n"); - - cp_me = 0xff | R600_CP_ME_HALT; - - RADEON_WRITE(R600_CP_ME_CNTL, cp_me); - - dev_priv->cp_running = 0; -} - -int r600_cp_dispatch_indirect(struct drm_device *dev, - struct drm_buf *buf, int start, int end) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - if (start != end) { - unsigned long offset = (dev_priv->gart_buffers_offset - + buf->offset + start); - int dwords = (end - start + 3) / sizeof(u32); - - DRM_DEBUG("dwords:%d\n", dwords); - DRM_DEBUG("offset 0x%lx\n", offset); - - - /* Indirect buffer data must be a multiple of 16 dwords. - * pad the data with a Type-2 CP packet. - */ - while (dwords & 0xf) { - u32 *data = (u32 *) - ((char *)dev->agp_buffer_map->handle - + buf->offset + start); - data[dwords++] = RADEON_CP_PACKET2; - } - - /* Fire off the indirect buffer */ - BEGIN_RING(4); - OUT_RING(CP_PACKET3(R600_IT_INDIRECT_BUFFER, 2)); - OUT_RING((offset & 0xfffffffc)); - OUT_RING((upper_32_bits(offset) & 0xff)); - OUT_RING(dwords); - ADVANCE_RING(); - } - - return 0; -} diff --git a/trunk/drivers/gpu/drm/radeon/r600_microcode.h b/trunk/drivers/gpu/drm/radeon/r600_microcode.h deleted file mode 100644 index 778c8b4b2fd9..000000000000 --- a/trunk/drivers/gpu/drm/radeon/r600_microcode.h +++ /dev/null @@ -1,23297 +0,0 @@ -/* - * Copyright 2008-2009 Advanced Micro Devices, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef R600_MICROCODE_H -#define R600_MICROCODE_H - -static const int ME_JUMP_TABLE_START = 1764; -static const int ME_JUMP_TABLE_END = 1792; - -#define PFP_UCODE_SIZE 576 -#define PM4_UCODE_SIZE 1792 -#define R700_PFP_UCODE_SIZE 848 -#define R700_PM4_UCODE_SIZE 1360 - -static const u32 R600_cp_microcode[][3] = { - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0000ffff, 0x00284621, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00000000, 0x00e00000, 0x000 }, - { 0x00010000, 0xc0294620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x614 }, - { 0x00000000, 0x00600000, 0x5b2 }, - { 0x00000000, 0x00600000, 0x5c5 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000f00, 0x00281622, 0x000 }, - { 0x00000008, 0x00211625, 0x000 }, - { 0x00000020, 0x00203625, 0x000 }, - { 0x8d000000, 0x00204411, 0x000 }, - { 0x00000004, 0x002f0225, 0x000 }, - { 0x00000000, 0x0ce00000, 0x018 }, - { 0x00412000, 0x00404811, 0x019 }, - { 0x00422000, 0x00204811, 0x000 }, - { 0x8e000000, 0x00204411, 0x000 }, - { 0x00000031, 0x00204a2d, 0x000 }, - { 0x90000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x0000000c, 0x00211622, 0x000 }, - { 0x00000003, 0x00281625, 0x000 }, - { 0x00000019, 0x00211a22, 0x000 }, - { 0x00000004, 0x00281a26, 0x000 }, - { 0x00000000, 0x002914c5, 0x000 }, - { 0x00000021, 0x00203625, 0x000 }, - { 0x00000000, 0x003a1402, 0x000 }, - { 0x00000016, 0x00211625, 0x000 }, - { 0x00000003, 0x00281625, 0x000 }, - { 0x0000001d, 0x00200e2d, 0x000 }, - { 0xfffffffc, 0x00280e23, 0x000 }, - { 0x00000000, 0x002914a3, 0x000 }, - { 0x0000001d, 0x00203625, 0x000 }, - { 0x00008000, 0x00280e22, 0x000 }, - { 0x00000007, 0x00220e23, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x20000000, 0x00280e22, 0x000 }, - { 0x00000006, 0x00210e23, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x00000000, 0x00220222, 0x000 }, - { 0x00000000, 0x14e00000, 0x038 }, - { 0x00000000, 0x2ee00000, 0x035 }, - { 0x00000000, 0x2ce00000, 0x037 }, - { 0x00000000, 0x00400e2d, 0x039 }, - { 0x00000008, 0x00200e2d, 0x000 }, - { 0x00000009, 0x0040122d, 0x046 }, - { 0x00000001, 0x00400e2d, 0x039 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x003ffffc, 0x00281223, 0x000 }, - { 0x00000002, 0x00221224, 0x000 }, - { 0x0000001f, 0x00211e23, 0x000 }, - { 0x00000000, 0x14e00000, 0x03e }, - { 0x00000008, 0x00401c11, 0x041 }, - { 0x0000000d, 0x00201e2d, 0x000 }, - { 0x0000000f, 0x00281e27, 0x000 }, - { 0x00000003, 0x00221e27, 0x000 }, - { 0x7fc00000, 0x00281a23, 0x000 }, - { 0x00000014, 0x00211a26, 0x000 }, - { 0x00000001, 0x00331a26, 0x000 }, - { 0x00000008, 0x00221a26, 0x000 }, - { 0x00000000, 0x00290cc7, 0x000 }, - { 0x00000030, 0x00203624, 0x000 }, - { 0x00007f00, 0x00281221, 0x000 }, - { 0x00001400, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x04b }, - { 0x00000001, 0x00290e23, 0x000 }, - { 0x00000010, 0x00203623, 0x000 }, - { 0x0000e000, 0x00204411, 0x000 }, - { 0xfff80000, 0x00294a23, 0x000 }, - { 0x00000000, 0x003a2c02, 0x000 }, - { 0x00000002, 0x00220e2b, 0x000 }, - { 0xfc000000, 0x00280e23, 0x000 }, - { 0x00000011, 0x00203623, 0x000 }, - { 0x00001fff, 0x00294a23, 0x000 }, - { 0x00000030, 0x00204a2d, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000032, 0x00200e2d, 0x000 }, - { 0x060a0200, 0x00294a23, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14e00000, 0x061 }, - { 0x00000000, 0x2ee00000, 0x05f }, - { 0x00000000, 0x2ce00000, 0x05e }, - { 0x00000000, 0x00400e2d, 0x062 }, - { 0x00000001, 0x00400e2d, 0x062 }, - { 0x0000000a, 0x00200e2d, 0x000 }, - { 0x0000000b, 0x0040122d, 0x06a }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x003ffffc, 0x00281223, 0x000 }, - { 0x00000002, 0x00221224, 0x000 }, - { 0x7fc00000, 0x00281623, 0x000 }, - { 0x00000014, 0x00211625, 0x000 }, - { 0x00000001, 0x00331625, 0x000 }, - { 0x80000000, 0x00280e23, 0x000 }, - { 0x00000000, 0x00290ca3, 0x000 }, - { 0x3ffffc00, 0x00290e23, 0x000 }, - { 0x0000001f, 0x00211e23, 0x000 }, - { 0x00000000, 0x14e00000, 0x06d }, - { 0x00000100, 0x00401c11, 0x070 }, - { 0x0000000d, 0x00201e2d, 0x000 }, - { 0x000000f0, 0x00281e27, 0x000 }, - { 0x00000004, 0x00221e27, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0xfffff0ff, 0x00281a30, 0x000 }, - { 0x0000a028, 0x00204411, 0x000 }, - { 0x00000000, 0x002948e6, 0x000 }, - { 0x0000a018, 0x00204411, 0x000 }, - { 0x3fffffff, 0x00284a23, 0x000 }, - { 0x0000a010, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x0000002d, 0x0020162d, 0x000 }, - { 0x00000000, 0x002f00a3, 0x000 }, - { 0x00000000, 0x0cc00000, 0x080 }, - { 0x0000002e, 0x0020162d, 0x000 }, - { 0x00000000, 0x002f00a4, 0x000 }, - { 0x00000000, 0x0cc00000, 0x081 }, - { 0x00000000, 0x00400000, 0x087 }, - { 0x0000002d, 0x00203623, 0x000 }, - { 0x0000002e, 0x00203624, 0x000 }, - { 0x0000001d, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x087 }, - { 0x00000000, 0x00600000, 0x5ed }, - { 0x00000000, 0x00600000, 0x5e1 }, - { 0x00000002, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x08a }, - { 0x00000018, 0xc0403620, 0x090 }, - { 0x00000000, 0x2ee00000, 0x08e }, - { 0x00000000, 0x2ce00000, 0x08d }, - { 0x00000002, 0x00400e2d, 0x08f }, - { 0x00000003, 0x00400e2d, 0x08f }, - { 0x0000000c, 0x00200e2d, 0x000 }, - { 0x00000018, 0x00203623, 0x000 }, - { 0x00000003, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x095 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x09d }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x2ee00000, 0x09b }, - { 0x00000000, 0x2ce00000, 0x09a }, - { 0x00000002, 0x00400e2d, 0x09c }, - { 0x00000003, 0x00400e2d, 0x09c }, - { 0x0000000c, 0x00200e2d, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000000, 0x003a0c02, 0x000 }, - { 0x003f0000, 0x00280e23, 0x000 }, - { 0x00000010, 0x00210e23, 0x000 }, - { 0x00000013, 0x00203623, 0x000 }, - { 0x0000001e, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0a4 }, - { 0x0000001c, 0xc0203620, 0x000 }, - { 0x0000001f, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0a7 }, - { 0x0000001b, 0xc0203620, 0x000 }, - { 0x00000008, 0x00210e2b, 0x000 }, - { 0x0000007f, 0x00280e23, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0db }, - { 0x00000000, 0x27000000, 0x000 }, - { 0x00000000, 0x00600000, 0x28c }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x0000000c, 0x00221e30, 0x000 }, - { 0x99800000, 0x00204411, 0x000 }, - { 0x00000004, 0x0020122d, 0x000 }, - { 0x00000008, 0x00221224, 0x000 }, - { 0x00000010, 0x00201811, 0x000 }, - { 0x00000000, 0x00291ce4, 0x000 }, - { 0x00000000, 0x00604807, 0x128 }, - { 0x9b000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x9c000000, 0x00204411, 0x000 }, - { 0x00000000, 0x0033146f, 0x000 }, - { 0x00000001, 0x00333e23, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0x00203c05, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x00000000, 0x00201010, 0x000 }, - { 0x0000e007, 0x00204411, 0x000 }, - { 0x0000000f, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0c5 }, - { 0x00f8ff08, 0x00204811, 0x000 }, - { 0x98000000, 0x00404811, 0x0d6 }, - { 0x000000f0, 0x00280e22, 0x000 }, - { 0x000000a0, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x0d4 }, - { 0x00000013, 0x00200e2d, 0x000 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0cf }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0ce }, - { 0x00003f00, 0x00400c11, 0x0d0 }, - { 0x00001f00, 0x00400c11, 0x0d0 }, - { 0x00000f00, 0x00200c11, 0x000 }, - { 0x00380009, 0x00294a23, 0x000 }, - { 0x3f000000, 0x00280e2b, 0x000 }, - { 0x00000002, 0x00220e23, 0x000 }, - { 0x00000007, 0x00494a23, 0x0d6 }, - { 0x00380f09, 0x00204811, 0x000 }, - { 0x68000007, 0x00204811, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a24, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000a202, 0x00204411, 0x000 }, - { 0x00ff0000, 0x00284a22, 0x000 }, - { 0x00000030, 0x00200e2d, 0x000 }, - { 0x0000002e, 0x0020122d, 0x000 }, - { 0x00000000, 0x002f0083, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0e3 }, - { 0x00000000, 0x00600000, 0x5e7 }, - { 0x00000000, 0x00400000, 0x0e4 }, - { 0x00000000, 0x00600000, 0x5ea }, - { 0x00000007, 0x0020222d, 0x000 }, - { 0x00000005, 0x00220e22, 0x000 }, - { 0x00100000, 0x00280e23, 0x000 }, - { 0x00000000, 0x00292068, 0x000 }, - { 0x00000000, 0x003a0c02, 0x000 }, - { 0x000000ef, 0x00280e23, 0x000 }, - { 0x00000000, 0x00292068, 0x000 }, - { 0x0000001d, 0x00200e2d, 0x000 }, - { 0x00000003, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x0f1 }, - { 0x0000000b, 0x00210228, 0x000 }, - { 0x00000000, 0x14c00000, 0x0f1 }, - { 0x00000400, 0x00292228, 0x000 }, - { 0x0000001a, 0x00203628, 0x000 }, - { 0x0000001c, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x0f6 }, - { 0x0000a30c, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000001e, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x104 }, - { 0x0000a30f, 0x00204411, 0x000 }, - { 0x00000013, 0x00200e2d, 0x000 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x0fd }, - { 0xffffffff, 0x00404811, 0x104 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x100 }, - { 0x0000ffff, 0x00404811, 0x104 }, - { 0x00000004, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x103 }, - { 0x000000ff, 0x00404811, 0x104 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0002c400, 0x00204411, 0x000 }, - { 0x0000001f, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x10b }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x00000019, 0x00203623, 0x000 }, - { 0x00000018, 0x40224a20, 0x000 }, - { 0x00000010, 0xc0424a20, 0x10d }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x00000019, 0x00203623, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000000a, 0x00201011, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x114 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00531224, 0x110 }, - { 0xffbfffff, 0x00283a2e, 0x000 }, - { 0x0000001b, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x127 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0x00000018, 0x00220e30, 0x000 }, - { 0xfc000000, 0x00280e23, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x00000000, 0x00201010, 0x000 }, - { 0x0000e00e, 0x00204411, 0x000 }, - { 0x07f8ff08, 0x00204811, 0x000 }, - { 0x00000000, 0x00294a23, 0x000 }, - { 0x00000024, 0x00201e2d, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a24, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x00800000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204806, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x614 }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x613 }, - { 0x00000004, 0x00404c11, 0x12e }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x2fe }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x19f }, - { 0x00000000, 0x00600000, 0x151 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000ffff, 0x40280620, 0x000 }, - { 0x00000010, 0xc0210a20, 0x000 }, - { 0x00000000, 0x00341461, 0x000 }, - { 0x00000000, 0x00741882, 0x2a4 }, - { 0x0001a1fd, 0x00604411, 0x2c9 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x138 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x2fe }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x19f }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x151 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x00000010, 0x40211620, 0x000 }, - { 0x0000ffff, 0xc0681a20, 0x2a4 }, - { 0x0001a1fd, 0x00604411, 0x2c9 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x149 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000001, 0x00300a2f, 0x000 }, - { 0x00000001, 0x00210a22, 0x000 }, - { 0x00000003, 0x00384a22, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001a, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600000, 0x17c }, - { 0x00000000, 0x00600000, 0x18d }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00202c08, 0x000 }, - { 0x00000000, 0x00202411, 0x000 }, - { 0x00000000, 0x00202811, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000002, 0x00221e29, 0x000 }, - { 0x00000000, 0x007048eb, 0x189 }, - { 0x00000000, 0x00600000, 0x2a4 }, - { 0x00000001, 0x40330620, 0x000 }, - { 0x00000000, 0xc0302409, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x28c }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x173 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000001, 0x00530621, 0x16f }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0604800, 0x184 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000013, 0x0020062d, 0x000 }, - { 0x00000000, 0x0078042a, 0x2e4 }, - { 0x00000000, 0x00202809, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x165 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000210, 0x00600411, 0x2fe }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x181 }, - { 0x0000001b, 0xc0203620, 0x000 }, - { 0x0000001c, 0xc0203620, 0x000 }, - { 0x3f800000, 0x00200411, 0x000 }, - { 0x46000000, 0x00600811, 0x19f }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x188 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000021, 0x00804811, 0x000 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000ffff, 0x40281620, 0x000 }, - { 0x00000010, 0xc0811a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000008, 0x00221e30, 0x000 }, - { 0x00000032, 0x00201a2d, 0x000 }, - { 0x0000e000, 0x00204411, 0x000 }, - { 0xfffbff09, 0x00204811, 0x000 }, - { 0x00000011, 0x0020222d, 0x000 }, - { 0x00001fff, 0x00294a28, 0x000 }, - { 0x00000006, 0x0020222d, 0x000 }, - { 0x00000000, 0x002920e8, 0x000 }, - { 0x00000000, 0x00204808, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a26, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000100, 0x00201811, 0x000 }, - { 0x00000008, 0x00621e28, 0x128 }, - { 0x00000008, 0x00822228, 0x000 }, - { 0x0002c000, 0x00204411, 0x000 }, - { 0x0000001b, 0x00600e2d, 0x1aa }, - { 0x0000001c, 0x00600e2d, 0x1aa }, - { 0x0000c008, 0x00204411, 0x000 }, - { 0x0000001d, 0x00200e2d, 0x000 }, - { 0x00000000, 0x14c00000, 0x1a6 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0x39000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00804802, 0x000 }, - { 0x00000020, 0x00202e2d, 0x000 }, - { 0x00000000, 0x003b0d63, 0x000 }, - { 0x00000008, 0x00224a23, 0x000 }, - { 0x00000010, 0x00224a23, 0x000 }, - { 0x00000018, 0x00224a23, 0x000 }, - { 0x00000000, 0x00804803, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00001000, 0x00600411, 0x2fe }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x19f }, - { 0x00000007, 0x0021062f, 0x000 }, - { 0x00000019, 0x00200a2d, 0x000 }, - { 0x00000001, 0x00202c11, 0x000 }, - { 0x0000ffff, 0x40282220, 0x000 }, - { 0x0000000f, 0x00262228, 0x000 }, - { 0x00000010, 0x40212620, 0x000 }, - { 0x0000000f, 0x00262629, 0x000 }, - { 0x00000000, 0x00202802, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001b, 0x00204811, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1cd }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000081, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000080, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1c9 }, - { 0x00000000, 0x00600000, 0x1d6 }, - { 0x00000001, 0x00531e27, 0x1c5 }, - { 0x00000001, 0x00202c11, 0x000 }, - { 0x0000001f, 0x00280a22, 0x000 }, - { 0x0000001f, 0x00282a2a, 0x000 }, - { 0x00000001, 0x00530621, 0x1be }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000002, 0x00304a2f, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000001, 0x00301e2f, 0x000 }, - { 0x00000000, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x1d6 }, - { 0x00000001, 0x00531e27, 0x1d2 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x0000000f, 0x00260e23, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000000f, 0x00261224, 0x000 }, - { 0x00000000, 0x00201411, 0x000 }, - { 0x00000000, 0x00601811, 0x2a4 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022b, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1e5 }, - { 0x00000010, 0x00221628, 0x000 }, - { 0xffff0000, 0x00281625, 0x000 }, - { 0x0000ffff, 0x00281a29, 0x000 }, - { 0x00000000, 0x002948c5, 0x000 }, - { 0x00000000, 0x0020480a, 0x000 }, - { 0x00000000, 0x00202c11, 0x000 }, - { 0x00000010, 0x00221623, 0x000 }, - { 0xffff0000, 0x00281625, 0x000 }, - { 0x0000ffff, 0x00281a24, 0x000 }, - { 0x00000000, 0x002948c5, 0x000 }, - { 0x00000000, 0x00731503, 0x1f2 }, - { 0x00000000, 0x00201805, 0x000 }, - { 0x00000000, 0x00731524, 0x1f2 }, - { 0x00000000, 0x002d14c5, 0x000 }, - { 0x00000000, 0x003008a2, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00202802, 0x000 }, - { 0x00000000, 0x00202003, 0x000 }, - { 0x00000000, 0x00802404, 0x000 }, - { 0x0000000f, 0x00210225, 0x000 }, - { 0x00000000, 0x14c00000, 0x613 }, - { 0x00000000, 0x002b1405, 0x000 }, - { 0x00000001, 0x00901625, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x2fe }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x19f }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001a, 0x00294a22, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00384a21, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000ffff, 0x40281220, 0x000 }, - { 0x00000010, 0xc0211a20, 0x000 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211620, 0x000 }, - { 0x00000000, 0x00741465, 0x2a4 }, - { 0x0001a1fd, 0x00604411, 0x2c9 }, - { 0x00000001, 0x00330621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0cc00000, 0x206 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x1ff }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x5c5 }, - { 0x00000000, 0x0040040f, 0x200 }, - { 0x00000000, 0x00600000, 0x5b2 }, - { 0x00000000, 0x00600000, 0x5c5 }, - { 0x00000210, 0x00600411, 0x2fe }, - { 0x00000000, 0x00600000, 0x18d }, - { 0x00000000, 0x00600000, 0x189 }, - { 0x00000000, 0x00600000, 0x2a4 }, - { 0x00000000, 0x00600000, 0x28c }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204808, 0x000 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x21f }, - { 0x00000000, 0xc0404800, 0x21c }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x00600411, 0x2e4 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x5b2 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000018, 0x40210a20, 0x000 }, - { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x235 }, - { 0x0000001a, 0x0020222d, 0x000 }, - { 0x00080101, 0x00292228, 0x000 }, - { 0x0000001a, 0x00203628, 0x000 }, - { 0x0000a30c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x23a }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000010, 0x00600411, 0x2fe }, - { 0x3f800000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x19f }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x00000000, 0x00600000, 0x265 }, - { 0x0000001d, 0x00201e2d, 0x000 }, - { 0x00000001, 0x00211e27, 0x000 }, - { 0x00000000, 0x14e00000, 0x253 }, - { 0x00000018, 0x00201e2d, 0x000 }, - { 0x0000ffff, 0x00281e27, 0x000 }, - { 0x00000000, 0x00341c27, 0x000 }, - { 0x00000000, 0x12c00000, 0x248 }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f00e5, 0x000 }, - { 0x00000000, 0x08c00000, 0x24b }, - { 0x00000000, 0x00201407, 0x000 }, - { 0x00000018, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00211e27, 0x000 }, - { 0x00000000, 0x00341c47, 0x000 }, - { 0x00000000, 0x12c00000, 0x250 }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f00e6, 0x000 }, - { 0x00000000, 0x08c00000, 0x253 }, - { 0x00000000, 0x00201807, 0x000 }, - { 0x00000000, 0x00600000, 0x2aa }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000000, 0x00342023, 0x000 }, - { 0x00000000, 0x12c00000, 0x25b }, - { 0x00000000, 0x00342044, 0x000 }, - { 0x00000000, 0x12c00000, 0x25a }, - { 0x00000016, 0x00404811, 0x25f }, - { 0x00000018, 0x00404811, 0x25f }, - { 0x00000000, 0x00342044, 0x000 }, - { 0x00000000, 0x12c00000, 0x25e }, - { 0x00000017, 0x00404811, 0x25f }, - { 0x00000019, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0x00604411, 0x2d2 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x23f }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000010, 0x40210620, 0x000 }, - { 0x0000ffff, 0xc0280a20, 0x000 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x00000010, 0x40211620, 0x000 }, - { 0x0000ffff, 0xc0881a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x614 }, - { 0x00000000, 0x00600000, 0x5b2 }, - { 0x00000000, 0xc0600000, 0x28c }, - { 0x00000005, 0x00200a2d, 0x000 }, - { 0x00000008, 0x00220a22, 0x000 }, - { 0x00000034, 0x00201a2d, 0x000 }, - { 0x00000024, 0x00201e2d, 0x000 }, - { 0x00007000, 0x00281e27, 0x000 }, - { 0x00000000, 0x00311ce6, 0x000 }, - { 0x00000033, 0x00201a2d, 0x000 }, - { 0x0000000c, 0x00221a26, 0x000 }, - { 0x00000000, 0x002f00e6, 0x000 }, - { 0x00000000, 0x06e00000, 0x27b }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x00000034, 0x00203623, 0x000 }, - { 0x00000010, 0x00201811, 0x000 }, - { 0x00000000, 0x00691ce2, 0x128 }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x286 }, - { 0x00000001, 0x00333e2f, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000024, 0x00403627, 0x000 }, - { 0x0000000c, 0xc0220a20, 0x000 }, - { 0x00000032, 0x00203622, 0x000 }, - { 0x00000031, 0xc0403620, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000009, 0x00204811, 0x000 }, - { 0xa1000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000029, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002c1ce3, 0x000 }, - { 0x00000029, 0x00203627, 0x000 }, - { 0x0000002a, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002c1ce4, 0x000 }, - { 0x0000002a, 0x00203627, 0x000 }, - { 0x0000002b, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120a3, 0x000 }, - { 0x00000000, 0x002d1d07, 0x000 }, - { 0x0000002b, 0x00203627, 0x000 }, - { 0x0000002c, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x00000000, 0x002d1d07, 0x000 }, - { 0x0000002c, 0x00803627, 0x000 }, - { 0x00000029, 0x00203623, 0x000 }, - { 0x0000002a, 0x00203624, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x0000002b, 0x00203627, 0x000 }, - { 0x00000000, 0x00311cc4, 0x000 }, - { 0x0000002c, 0x00803627, 0x000 }, - { 0x00000022, 0x00203627, 0x000 }, - { 0x00000023, 0x00203628, 0x000 }, - { 0x0000001d, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14c00000, 0x2c5 }, - { 0x00000000, 0x00400000, 0x2c2 }, - { 0x00000022, 0x00203627, 0x000 }, - { 0x00000023, 0x00203628, 0x000 }, - { 0x0000001d, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x2c2 }, - { 0x00000003, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x2c5 }, - { 0x0000002b, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002e00e1, 0x000 }, - { 0x00000000, 0x02c00000, 0x2c5 }, - { 0x00000029, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120a1, 0x000 }, - { 0x00000000, 0x002e00e8, 0x000 }, - { 0x00000000, 0x06c00000, 0x2c5 }, - { 0x0000002c, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002e00e2, 0x000 }, - { 0x00000000, 0x02c00000, 0x2c5 }, - { 0x0000002a, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120c2, 0x000 }, - { 0x00000000, 0x002e00e8, 0x000 }, - { 0x00000000, 0x06c00000, 0x2c5 }, - { 0x00000000, 0x00600000, 0x5ed }, - { 0x00000000, 0x00600000, 0x29e }, - { 0x00000000, 0x00400000, 0x2c7 }, - { 0x00000000, 0x00600000, 0x29e }, - { 0x00000000, 0x00600000, 0x5e4 }, - { 0x00000000, 0x00400000, 0x2c7 }, - { 0x00000000, 0x00600000, 0x290 }, - { 0x00000000, 0x00400000, 0x2c7 }, - { 0x00000022, 0x00201e2d, 0x000 }, - { 0x00000023, 0x0080222d, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000010, 0x00221e21, 0x000 }, - { 0x00000000, 0x00294847, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000000, 0x00311ca1, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294847, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000010, 0x00221e21, 0x000 }, - { 0x00000000, 0x003120c2, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000001, 0x00220a21, 0x000 }, - { 0x00000000, 0x003308a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000001, 0x00220a21, 0x000 }, - { 0x00000000, 0x003008a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x003808c5, 0x000 }, - { 0x00000000, 0x00300841, 0x000 }, - { 0x00000001, 0x00220a22, 0x000 }, - { 0x00000000, 0x003308a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x0000001d, 0x0020222d, 0x000 }, - { 0x00000000, 0x14c00000, 0x301 }, - { 0xffffffef, 0x00280621, 0x000 }, - { 0x0000001a, 0x0020222d, 0x000 }, - { 0x0000f8e0, 0x00204411, 0x000 }, - { 0x00000000, 0x00294901, 0x000 }, - { 0x00000000, 0x00894901, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00804811, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x97000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00002257, 0x00204411, 0x000 }, - { 0x00000003, 0xc0484a20, 0x000 }, - { 0x0000225d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0x00600000, 0x5c5 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00384a22, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x40204800, 0x000 }, - { 0x00000001, 0x40304a20, 0x000 }, - { 0x00000002, 0xc0304a20, 0x000 }, - { 0x00000001, 0x00530a22, 0x334 }, - { 0x0000003f, 0xc0280a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000017, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x614 }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x33d }, - { 0x00000014, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x351 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000016, 0x00604811, 0x35e }, - { 0x00002100, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x355 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00404811, 0x349 }, - { 0x00000028, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x349 }, - { 0x00002104, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x00000035, 0x00203626, 0x000 }, - { 0x00000049, 0x00201811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00331a26, 0x000 }, - { 0x00000000, 0x002f0226, 0x000 }, - { 0x00000000, 0x0cc00000, 0x360 }, - { 0x00000035, 0x00801a2d, 0x000 }, - { 0x0000003f, 0xc0280a20, 0x000 }, - { 0x00000015, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x376 }, - { 0x0000001e, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x380 }, - { 0x00000020, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x38c }, - { 0x0000000f, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x398 }, - { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x398 }, - { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x39a }, - { 0x00000016, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x39f }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x08000000, 0x00290a22, 0x000 }, - { 0x00000003, 0x40210e20, 0x000 }, - { 0x0000000c, 0xc0211220, 0x000 }, - { 0x00080000, 0x00281224, 0x000 }, - { 0x00000014, 0xc0221620, 0x000 }, - { 0x00000000, 0x002914a4, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x002948a2, 0x000 }, - { 0x0000a1fe, 0x00204411, 0x000 }, - { 0x00000000, 0x00404803, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000015, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x614 }, - { 0x00000015, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x382 }, - { 0x0000210e, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x614 }, - { 0x00000003, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x38e }, - { 0x00002108, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00404811, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000006, 0x00404811, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000016, 0x00604811, 0x35e }, - { 0x00000016, 0x00404811, 0x000 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x0000001d, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x3b9 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000017, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x614 }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x3ab }, - { 0x00002100, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0xbabecafe, 0x00204811, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000004, 0x00404811, 0x000 }, - { 0x00002170, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000a, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x3be }, - { 0x8c000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00003fff, 0x40280a20, 0x000 }, - { 0x80000000, 0x40280e20, 0x000 }, - { 0x40000000, 0xc0281220, 0x000 }, - { 0x00040000, 0x00694622, 0x614 }, - { 0x00000000, 0x00201410, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x3cc }, - { 0x00000000, 0xc0401800, 0x3cf }, - { 0x00003fff, 0xc0281a20, 0x000 }, - { 0x00040000, 0x00694626, 0x614 }, - { 0x00000000, 0x00201810, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x3d2 }, - { 0x00000000, 0xc0401c00, 0x3d5 }, - { 0x00003fff, 0xc0281e20, 0x000 }, - { 0x00040000, 0x00694627, 0x614 }, - { 0x00000000, 0x00201c10, 0x000 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0x002820c5, 0x000 }, - { 0x00000000, 0x004948e8, 0x000 }, - { 0xa5800000, 0x00200811, 0x000 }, - { 0x00002000, 0x00200c11, 0x000 }, - { 0x83000000, 0x00604411, 0x3fd }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x40204800, 0x000 }, - { 0x0000001f, 0xc0210220, 0x000 }, - { 0x00000000, 0x14c00000, 0x3e2 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0000ffff, 0xc0481220, 0x3ea }, - { 0xa7800000, 0x00200811, 0x000 }, - { 0x0000a000, 0x00200c11, 0x000 }, - { 0x83000000, 0x00604411, 0x3fd }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x83000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00304883, 0x000 }, - { 0x84000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1d000000, 0x000 }, - { 0x83000000, 0x00604411, 0x3fd }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0xa9800000, 0x00200811, 0x000 }, - { 0x0000c000, 0x00400c11, 0x3e5 }, - { 0xab800000, 0x00200811, 0x000 }, - { 0x0000f8e0, 0x00400c11, 0x3e5 }, - { 0xad800000, 0x00200811, 0x000 }, - { 0x0000f880, 0x00400c11, 0x3e5 }, - { 0xb3800000, 0x00200811, 0x000 }, - { 0x0000f3fc, 0x00400c11, 0x3e5 }, - { 0xaf800000, 0x00200811, 0x000 }, - { 0x0000e000, 0x00400c11, 0x3e5 }, - { 0xb1800000, 0x00200811, 0x000 }, - { 0x0000f000, 0x00400c11, 0x3e5 }, - { 0x83000000, 0x00204411, 0x000 }, - { 0x00002148, 0x00204811, 0x000 }, - { 0x84000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1d000000, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00182000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0018a000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0018c000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0018f8e0, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0018f880, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0018e000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0018f000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0018f3fc, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x86000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00404801, 0x000 }, - { 0x85000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00404801, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x614 }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000000, 0x00404c02, 0x42e }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x00000000, 0xc0201000, 0x000 }, - { 0x00000000, 0xc0201400, 0x000 }, - { 0x00000000, 0xc0201800, 0x000 }, - { 0x00000000, 0xc0201c00, 0x000 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x43c }, - { 0x00000000, 0xc0202000, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x00000010, 0x00280a23, 0x000 }, - { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x444 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0x00694624, 0x614 }, - { 0x00000000, 0x00400000, 0x44d }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00000000, 0x1ac00000, 0x449 }, - { 0x9e000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x44c }, - { 0x00000000, 0x002824f0, 0x000 }, - { 0x00000007, 0x00280a23, 0x000 }, - { 0x00000001, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x454 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x04e00000, 0x46d }, - { 0x00000000, 0x00400000, 0x47a }, - { 0x00000002, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x459 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x02e00000, 0x46d }, - { 0x00000000, 0x00400000, 0x47a }, - { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x45e }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x0ce00000, 0x46d }, - { 0x00000000, 0x00400000, 0x47a }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x463 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x0ae00000, 0x46d }, - { 0x00000000, 0x00400000, 0x47a }, - { 0x00000005, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x468 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x06e00000, 0x46d }, - { 0x00000000, 0x00400000, 0x47a }, - { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x46d }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x08e00000, 0x46d }, - { 0x00000000, 0x00400000, 0x47a }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x000 }, - { 0x00000008, 0x00210a23, 0x000 }, - { 0x00000000, 0x14c00000, 0x477 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x00000000, 0xc0204400, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x480 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x00404c08, 0x43c }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x00000011, 0x40211220, 0x000 }, - { 0x00000012, 0x40211620, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00210225, 0x000 }, - { 0x00000000, 0x14e00000, 0x48a }, - { 0x00040000, 0xc0494a20, 0x48b }, - { 0xfffbffff, 0xc0284a20, 0x000 }, - { 0x00000000, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x497 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000c, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x493 }, - { 0xa0000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000004, 0x00204811, 0x000 }, - { 0x0000216b, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204810, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000005, 0x00204811, 0x000 }, - { 0x0000216c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204810, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00400000, 0x491 }, - { 0x00000000, 0xc0210a20, 0x000 }, - { 0x00000000, 0x14c00000, 0x4ae }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1ac00000, 0x4a9 }, - { 0x9e000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x4ac }, - { 0x00000000, 0x00400000, 0x4b2 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0xc0294620, 0x000 }, - { 0x00000000, 0xc0600000, 0x614 }, - { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x4b9 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x00000000, 0xc0204400, 0x000 }, - { 0x00000000, 0xc0404810, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x614 }, - { 0x00000000, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x4bb }, - { 0x00002180, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000003, 0x00333e2f, 0x000 }, - { 0x00000001, 0x00210221, 0x000 }, - { 0x00000000, 0x14e00000, 0x4eb }, - { 0x00000035, 0x00200a2d, 0x000 }, - { 0x00040000, 0x18e00c11, 0x4da }, - { 0x00000001, 0x00333e2f, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xd8c04800, 0x4ce }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000036, 0x0020122d, 0x000 }, - { 0x00000000, 0x00290c83, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000011, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000000, 0x00400000, 0x491 }, - { 0x00000035, 0xc0203620, 0x000 }, - { 0x00000036, 0xc0403620, 0x000 }, - { 0x0000304a, 0x00204411, 0x000 }, - { 0xe0000000, 0xc0484a20, 0x000 }, - { 0x0000000f, 0x00210221, 0x000 }, - { 0x00000000, 0x14c00000, 0x4f2 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0xd9000000, 0x000 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000002, 0x00204811, 0x000 }, - { 0x000000ff, 0x00280e30, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x4f6 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0x14c00000, 0x50b }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x00000024, 0x00203623, 0x000 }, - { 0x00000034, 0x00203623, 0x000 }, - { 0x00000032, 0x00203623, 0x000 }, - { 0x00000031, 0x00203623, 0x000 }, - { 0x0000001d, 0x00203623, 0x000 }, - { 0x0000002d, 0x00203623, 0x000 }, - { 0x0000002e, 0x00203623, 0x000 }, - { 0x0000001b, 0x00203623, 0x000 }, - { 0x0000001c, 0x00203623, 0x000 }, - { 0xffffe000, 0x00200c11, 0x000 }, - { 0x00000029, 0x00203623, 0x000 }, - { 0x0000002a, 0x00203623, 0x000 }, - { 0x00001fff, 0x00200c11, 0x000 }, - { 0x0000002b, 0x00203623, 0x000 }, - { 0x0000002c, 0x00203623, 0x000 }, - { 0xf1ffffff, 0x00283a2e, 0x000 }, - { 0x0000001a, 0xc0220e20, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000033, 0x40203620, 0x000 }, - { 0x87000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1f4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x9d000000, 0x00204411, 0x000 }, - { 0x0000001f, 0x40214a20, 0x000 }, - { 0x96000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x00000000, 0xc0201000, 0x000 }, - { 0x0000001f, 0x00211624, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000025, 0x00203623, 0x000 }, - { 0x00000003, 0x00281e23, 0x000 }, - { 0x00000008, 0x00222223, 0x000 }, - { 0xfffff000, 0x00282228, 0x000 }, - { 0x00000000, 0x002920e8, 0x000 }, - { 0x00000027, 0x00203628, 0x000 }, - { 0x00000018, 0x00211e23, 0x000 }, - { 0x00000028, 0x00203627, 0x000 }, - { 0x00000002, 0x00221624, 0x000 }, - { 0x00000000, 0x003014a8, 0x000 }, - { 0x00000026, 0x00203625, 0x000 }, - { 0x00000003, 0x00211a24, 0x000 }, - { 0x10000000, 0x00281a26, 0x000 }, - { 0xefffffff, 0x00283a2e, 0x000 }, - { 0x00000000, 0x004938ce, 0x602 }, - { 0x00000001, 0x40280a20, 0x000 }, - { 0x00000006, 0x40280e20, 0x000 }, - { 0x00000300, 0xc0281220, 0x000 }, - { 0x00000008, 0x00211224, 0x000 }, - { 0x00000000, 0xc0201620, 0x000 }, - { 0x00000000, 0xc0201a20, 0x000 }, - { 0x00000000, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x541 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00002258, 0x00300a24, 0x000 }, - { 0x00040000, 0x00694622, 0x614 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00020000, 0x00294a26, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x549 }, - { 0x00000000, 0xc0201c10, 0x000 }, - { 0x00000000, 0xc0400000, 0x55b }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x549 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00002258, 0x00300a24, 0x000 }, - { 0x00040000, 0x00694622, 0x614 }, - { 0x00000000, 0xc0201c10, 0x000 }, - { 0x00000000, 0xc0400000, 0x55b }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x54d }, - { 0x00000000, 0xc0201c00, 0x000 }, - { 0x00000000, 0xc0400000, 0x55b }, - { 0x00000004, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x559 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1ac00000, 0x554 }, - { 0x9e000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x557 }, - { 0x00000000, 0x00401c10, 0x55b }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x0ee00000, 0x55d }, - { 0x00000000, 0x00600000, 0x5a4 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x56d }, - { 0x0000a2b7, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2b6, 0x00604411, 0x614 }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x0000a2c4, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x56b }, - { 0x0000a2d1, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d1, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x00000001, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x57d }, - { 0x0000a2bb, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2ba, 0x00604411, 0x614 }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x0000a2c5, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x57b }, - { 0x0000a2d2, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d2, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x00000002, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x58d }, - { 0x0000a2bf, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2be, 0x00604411, 0x614 }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x0000a2c6, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x58b }, - { 0x0000a2d3, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d3, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x0000a2c3, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2c2, 0x00604411, 0x614 }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x0000a2c7, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x599 }, - { 0x0000a2d4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d4, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x85000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0x0000304a, 0x00204411, 0x000 }, - { 0x01000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00400000, 0x59f }, - { 0xa4000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0xc0600000, 0x5a4 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000005, 0x00204811, 0x000 }, - { 0x0000a1f4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x88000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0xff000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000002, 0x00804811, 0x000 }, - { 0x00000000, 0x0ee00000, 0x5b7 }, - { 0x00001000, 0x00200811, 0x000 }, - { 0x00000034, 0x00203622, 0x000 }, - { 0x00000000, 0x00600000, 0x5bb }, - { 0x00000000, 0x00600000, 0x5a4 }, - { 0x98000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00804811, 0x000 }, - { 0x00000000, 0xc0600000, 0x5bb }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000022, 0x00204811, 0x000 }, - { 0x89000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0xff000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000002, 0x00804811, 0x000 }, - { 0x0000217a, 0xc0204411, 0x000 }, - { 0x00000000, 0x00404811, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0xff000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000002, 0x00804811, 0x000 }, - { 0x00000000, 0x00600000, 0x5e1 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0xc0204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000016, 0x00604811, 0x35e }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00010000, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x09800000, 0x00204811, 0x000 }, - { 0xffffffff, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x614 }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000004, 0x00404c11, 0x5dc }, - { 0x0000001d, 0x00201e2d, 0x000 }, - { 0x00000004, 0x00291e27, 0x000 }, - { 0x0000001d, 0x00803627, 0x000 }, - { 0x0000001d, 0x00201e2d, 0x000 }, - { 0xfffffffb, 0x00281e27, 0x000 }, - { 0x0000001d, 0x00803627, 0x000 }, - { 0x0000001d, 0x00201e2d, 0x000 }, - { 0x00000008, 0x00291e27, 0x000 }, - { 0x0000001d, 0x00803627, 0x000 }, - { 0x0000001d, 0x00201e2d, 0x000 }, - { 0xfffffff7, 0x00281e27, 0x000 }, - { 0x0000001d, 0x00803627, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000016, 0x00604811, 0x35e }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00010000, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x01800000, 0x00204811, 0x000 }, - { 0x00ffffff, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004217f, 0x00604411, 0x614 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x613 }, - { 0x00000010, 0x00404c11, 0x5f9 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x38c00000, 0x000 }, - { 0x00000025, 0x00200a2d, 0x000 }, - { 0x00000026, 0x00200e2d, 0x000 }, - { 0x00000027, 0x0020122d, 0x000 }, - { 0x00000028, 0x0020162d, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000004, 0x00301224, 0x000 }, - { 0x00000000, 0x002f0064, 0x000 }, - { 0x00000000, 0x0cc00000, 0x612 }, - { 0x00000003, 0x00281a22, 0x000 }, - { 0x00000008, 0x00221222, 0x000 }, - { 0xfffff000, 0x00281224, 0x000 }, - { 0x00000000, 0x002910c4, 0x000 }, - { 0x00000027, 0x00403624, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x1ac00000, 0x614 }, - { 0x9f000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x617 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00001000, 0x00600411, 0x2fe }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x19f }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001b, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0xc0204411, 0x000 }, - { 0x00000029, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x0000002c, 0x0020222d, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000002a, 0x0020222d, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000002b, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00404811, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x013304ef, 0x059b0239, 0x000 }, - { 0x01b00159, 0x0425059b, 0x000 }, - { 0x021201f6, 0x02390142, 0x000 }, - { 0x0210022e, 0x0289022a, 0x000 }, - { 0x03c2059b, 0x059b059b, 0x000 }, - { 0x05cd05ce, 0x0308059b, 0x000 }, - { 0x059b05a0, 0x03090329, 0x000 }, - { 0x0313026b, 0x032b031d, 0x000 }, - { 0x059b059b, 0x059b059b, 0x000 }, - { 0x059b052c, 0x059b059b, 0x000 }, - { 0x03a5059b, 0x04a2032d, 0x000 }, - { 0x04810433, 0x0423059b, 0x000 }, - { 0x04bb04ed, 0x042704c8, 0x000 }, - { 0x043304f4, 0x033a0365, 0x000 }, - { 0x059b059b, 0x059b059b, 0x000 }, - { 0x059b059b, 0x059b059b, 0x000 }, - { 0x059b059b, 0x05b905a2, 0x000 }, - { 0x059b059b, 0x0007059b, 0x000 }, - { 0x059b059b, 0x059b059b, 0x000 }, - { 0x059b059b, 0x059b059b, 0x000 }, - { 0x03e303d8, 0x03f303f1, 0x000 }, - { 0x03f903f5, 0x03f703fb, 0x000 }, - { 0x04070403, 0x040f040b, 0x000 }, - { 0x04170413, 0x041f041b, 0x000 }, - { 0x059b059b, 0x059b059b, 0x000 }, - { 0x059b059b, 0x059b059b, 0x000 }, - { 0x059b059b, 0x059b059b, 0x000 }, - { 0x00020600, 0x06190006, 0x000 }, -}; - -static const u32 R600_pfp_microcode[] = { -0xd40071, -0xd40072, -0xca0400, -0xa00000, -0x7e828b, -0x800003, -0xca0400, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xc41838, -0xca2400, -0xca2800, -0x9581a8, -0xc41c3a, -0xc3c000, -0xca0800, -0xca0c00, -0x7c744b, -0xc20005, -0x99c000, -0xc41c3a, -0x7c744c, -0xc0fff0, -0x042c04, -0x309002, -0x7d2500, -0x351402, -0x7d350b, -0x255403, -0x7cd580, -0x259c03, -0x95c004, -0xd5001b, -0x7eddc1, -0x7d9d80, -0xd6801b, -0xd5801b, -0xd4401e, -0xd5401e, -0xd6401e, -0xd6801e, -0xd4801e, -0xd4c01e, -0x9783d4, -0xd5c01e, -0xca0800, -0x80001b, -0xca0c00, -0xe4011e, -0xd4001e, -0x80000d, -0xc41838, -0xe4013e, -0xd4001e, -0x80000d, -0xc41838, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4011e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4013e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca1800, -0xd4401e, -0xd5801e, -0x800054, -0xd40073, -0xd4401e, -0xca0800, -0xca0c00, -0xca1000, -0xd48019, -0xd4c018, -0xd50017, -0xd4801e, -0xd4c01e, -0xd5001e, -0xe2001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0xd48060, -0xd4401e, -0x800002, -0xd4801e, -0xca0800, -0xd48061, -0xd4401e, -0x800002, -0xd4801e, -0xca0800, -0xca0c00, -0xd4401e, -0xd48016, -0xd4c016, -0xd4801e, -0x8001b9, -0xd4c01e, -0xc6083e, -0xca0c00, -0xca1000, -0x948004, -0xca1400, -0xe420f3, -0xd42013, -0xd56065, -0xd4e01c, -0xd5201c, -0xd5601c, -0x800002, -0x062001, -0xc6083e, -0xca0c00, -0xca1000, -0x9483f7, -0xca1400, -0xe420f3, -0x80007a, -0xd42013, -0xc6083e, -0xca0c00, -0xca1000, -0x9883ef, -0xca1400, -0xd40064, -0x80008e, -0x000000, -0xc41432, -0xc6183e, -0xc4082f, -0x954005, -0xc40c30, -0xd4401e, -0x800002, -0xee001e, -0x9583f5, -0xc41031, -0xd44033, -0xd52065, -0xd4a01c, -0xd4e01c, -0xd5201c, -0xd40073, -0xe4015e, -0xd4001e, -0x8001b9, -0x062001, -0x0a2001, -0xd60074, -0xc40836, -0xc61040, -0x988007, -0xcc3835, -0x95010f, -0xd4001f, -0xd46062, -0x800002, -0xd42062, -0xcc1433, -0x8401bc, -0xd40070, -0xd5401e, -0x800002, -0xee001e, -0xca0c00, -0xca1000, -0xd4c01a, -0x8401bc, -0xd5001a, -0xcc0443, -0x35101f, -0x2c9401, -0x7d098b, -0x984005, -0x7d15cb, -0xd4001a, -0x8001b9, -0xd4006d, -0x344401, -0xcc0c44, -0x98403a, -0xcc2c46, -0x958004, -0xcc0445, -0x8001b9, -0xd4001a, -0xd4c01a, -0x282801, -0x8400f3, -0xcc1003, -0x98801b, -0x04380c, -0x8400f3, -0xcc1003, -0x988017, -0x043808, -0x8400f3, -0xcc1003, -0x988013, -0x043804, -0x8400f3, -0xcc1003, -0x988014, -0xcc1047, -0x9a8009, -0xcc1448, -0x9840da, -0xd4006d, -0xcc1844, -0xd5001a, -0xd5401a, -0x8000cc, -0xd5801a, -0x96c0d3, -0xd4006d, -0x8001b9, -0xd4006e, -0x9ac003, -0xd4006d, -0xd4006e, -0x800002, -0xec007f, -0x9ac0ca, -0xd4006d, -0x8001b9, -0xd4006e, -0xcc1403, -0xcc1803, -0xcc1c03, -0x7d9103, -0x7dd583, -0x7d190c, -0x35cc1f, -0x35701f, -0x7cf0cb, -0x7cd08b, -0x880000, -0x7e8e8b, -0x95c004, -0xd4006e, -0x8001b9, -0xd4001a, -0xd4c01a, -0xcc0803, -0xcc0c03, -0xcc1003, -0xcc1403, -0xcc1803, -0xcc1c03, -0xcc2403, -0xcc2803, -0x35c41f, -0x36b01f, -0x7c704b, -0x34f01f, -0x7c704b, -0x35701f, -0x7c704b, -0x7d8881, -0x7dccc1, -0x7e5101, -0x7e9541, -0x7c9082, -0x7cd4c2, -0x7c848b, -0x9ac003, -0x7c8c8b, -0x2c8801, -0x98809c, -0xd4006d, -0x98409a, -0xd4006e, -0xcc0847, -0xcc0c48, -0xcc1044, -0xd4801a, -0xd4c01a, -0x800104, -0xd5001a, -0xcc0832, -0xd40032, -0x9482d8, -0xca0c00, -0xd4401e, -0x800002, -0xd4001e, -0xe4011e, -0xd4001e, -0xca0800, -0xca0c00, -0xca1000, -0xd4401e, -0xca1400, -0xd4801e, -0xd4c01e, -0xd5001e, -0xd5401e, -0xd54034, -0x800002, -0xee001e, -0x280404, -0xe2001a, -0xe2001a, -0xd4401a, -0xca3800, -0xcc0803, -0xcc0c03, -0xcc0c03, -0xcc0c03, -0x9882bc, -0x000000, -0x8401bc, -0xd7806f, -0x800002, -0xee001f, -0xca0400, -0xc2ff00, -0xcc0834, -0xc13fff, -0x7c74cb, -0x7cc90b, -0x7d010f, -0x9902af, -0x7c738b, -0x8401bc, -0xd7806f, -0x800002, -0xee001f, -0xca0800, -0x281900, -0x7d898b, -0x958014, -0x281404, -0xca0c00, -0xca1000, -0xca1c00, -0xca2400, -0xe2001f, -0xd4c01a, -0xd5001a, -0xd5401a, -0xcc1803, -0xcc2c03, -0xcc2c03, -0xcc2c03, -0x7da58b, -0x7d9c47, -0x984296, -0x000000, -0x800164, -0xd4c01a, -0xd4401e, -0xd4801e, -0x800002, -0xee001e, -0xe4011e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4013e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0x248c06, -0x0ccc06, -0x98c006, -0xcc1049, -0x990004, -0xd40071, -0xe4011e, -0xd4001e, -0xd4401e, -0xd4801e, -0x800002, -0xee001e, -0xca0800, -0xca0c00, -0x34d018, -0x251001, -0x95001f, -0xc17fff, -0xca1000, -0xca1400, -0xca1800, -0xd4801d, -0xd4c01d, -0x7db18b, -0xc14202, -0xc2c001, -0xd5801d, -0x34dc0e, -0x7d5d4c, -0x7f734c, -0xd7401e, -0xd5001e, -0xd5401e, -0xc14200, -0xc2c000, -0x099c01, -0x31dc10, -0x7f5f4c, -0x7f734c, -0x7d8380, -0xd5806f, -0xd58066, -0xd7401e, -0xec005e, -0xc82402, -0x8001b9, -0xd60074, -0xd4401e, -0xd4801e, -0xd4c01e, -0x800002, -0xee001e, -0x800002, -0xee001f, -0xd4001f, -0x800002, -0xd4001f, -0xd4001f, -0x880000, -0xd4001f, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x010174, -0x02017b, -0x030090, -0x040080, -0x050005, -0x060040, -0x070033, -0x08012f, -0x090047, -0x0a0037, -0x1001b7, -0x1700a4, -0x22013d, -0x23014c, -0x2000b5, -0x240128, -0x27004e, -0x28006b, -0x2a0061, -0x2b0053, -0x2f0066, -0x320088, -0x340182, -0x3c0159, -0x3f0073, -0x41018f, -0x440131, -0x550176, -0x56017d, -0x60000c, -0x610035, -0x620039, -0x630039, -0x640039, -0x650039, -0x660039, -0x670039, -0x68003b, -0x690042, -0x6a0049, -0x6b0049, -0x6c0049, -0x6d0049, -0x6e0049, -0x6f0049, -0x7301b7, -0x000007, -0x000007, -0x000007, -0x000007, -0x000007, -0x000007, -0x000007, -0x000007, -0x000007, -0x000007, -0x000007, -0x000007, -0x000007, -0x000007, -0x000007, -0x000007, -0x000007, -0x000007, -}; - -static const u32 RV610_cp_microcode[][3] = { - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0000ffff, 0x00284621, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00000000, 0x00e00000, 0x000 }, - { 0x00010000, 0xc0294620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x00000000, 0x00600000, 0x631 }, - { 0x00000000, 0x00600000, 0x645 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000f00, 0x00281622, 0x000 }, - { 0x00000008, 0x00211625, 0x000 }, - { 0x00000018, 0x00203625, 0x000 }, - { 0x8d000000, 0x00204411, 0x000 }, - { 0x00000004, 0x002f0225, 0x000 }, - { 0x00000000, 0x0ce00000, 0x018 }, - { 0x00412000, 0x00404811, 0x019 }, - { 0x00422000, 0x00204811, 0x000 }, - { 0x8e000000, 0x00204411, 0x000 }, - { 0x00000028, 0x00204a2d, 0x000 }, - { 0x90000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x0000000c, 0x00211622, 0x000 }, - { 0x00000003, 0x00281625, 0x000 }, - { 0x00000019, 0x00211a22, 0x000 }, - { 0x00000004, 0x00281a26, 0x000 }, - { 0x00000000, 0x002914c5, 0x000 }, - { 0x00000019, 0x00203625, 0x000 }, - { 0x00000000, 0x003a1402, 0x000 }, - { 0x00000016, 0x00211625, 0x000 }, - { 0x00000003, 0x00281625, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0xfffffffc, 0x00280e23, 0x000 }, - { 0x00000000, 0x002914a3, 0x000 }, - { 0x00000017, 0x00203625, 0x000 }, - { 0x00008000, 0x00280e22, 0x000 }, - { 0x00000007, 0x00220e23, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x20000000, 0x00280e22, 0x000 }, - { 0x00000006, 0x00210e23, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x00000000, 0x00220222, 0x000 }, - { 0x00000000, 0x14e00000, 0x038 }, - { 0x00000000, 0x2ee00000, 0x035 }, - { 0x00000000, 0x2ce00000, 0x037 }, - { 0x00000000, 0x00400e2d, 0x039 }, - { 0x00000008, 0x00200e2d, 0x000 }, - { 0x00000009, 0x0040122d, 0x046 }, - { 0x00000001, 0x00400e2d, 0x039 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x003ffffc, 0x00281223, 0x000 }, - { 0x00000002, 0x00221224, 0x000 }, - { 0x0000001f, 0x00211e23, 0x000 }, - { 0x00000000, 0x14e00000, 0x03e }, - { 0x00000008, 0x00401c11, 0x041 }, - { 0x0000000d, 0x00201e2d, 0x000 }, - { 0x0000000f, 0x00281e27, 0x000 }, - { 0x00000003, 0x00221e27, 0x000 }, - { 0x7fc00000, 0x00281a23, 0x000 }, - { 0x00000014, 0x00211a26, 0x000 }, - { 0x00000001, 0x00331a26, 0x000 }, - { 0x00000008, 0x00221a26, 0x000 }, - { 0x00000000, 0x00290cc7, 0x000 }, - { 0x00000027, 0x00203624, 0x000 }, - { 0x00007f00, 0x00281221, 0x000 }, - { 0x00001400, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x04b }, - { 0x00000001, 0x00290e23, 0x000 }, - { 0x0000000e, 0x00203623, 0x000 }, - { 0x0000e000, 0x00204411, 0x000 }, - { 0xfff80000, 0x00294a23, 0x000 }, - { 0x00000000, 0x003a2c02, 0x000 }, - { 0x00000002, 0x00220e2b, 0x000 }, - { 0xfc000000, 0x00280e23, 0x000 }, - { 0x0000000f, 0x00203623, 0x000 }, - { 0x00001fff, 0x00294a23, 0x000 }, - { 0x00000027, 0x00204a2d, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000029, 0x00200e2d, 0x000 }, - { 0x060a0200, 0x00294a23, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14e00000, 0x061 }, - { 0x00000000, 0x2ee00000, 0x05f }, - { 0x00000000, 0x2ce00000, 0x05e }, - { 0x00000000, 0x00400e2d, 0x062 }, - { 0x00000001, 0x00400e2d, 0x062 }, - { 0x0000000a, 0x00200e2d, 0x000 }, - { 0x0000000b, 0x0040122d, 0x06a }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x003ffffc, 0x00281223, 0x000 }, - { 0x00000002, 0x00221224, 0x000 }, - { 0x7fc00000, 0x00281623, 0x000 }, - { 0x00000014, 0x00211625, 0x000 }, - { 0x00000001, 0x00331625, 0x000 }, - { 0x80000000, 0x00280e23, 0x000 }, - { 0x00000000, 0x00290ca3, 0x000 }, - { 0x3ffffc00, 0x00290e23, 0x000 }, - { 0x0000001f, 0x00211e23, 0x000 }, - { 0x00000000, 0x14e00000, 0x06d }, - { 0x00000100, 0x00401c11, 0x070 }, - { 0x0000000d, 0x00201e2d, 0x000 }, - { 0x000000f0, 0x00281e27, 0x000 }, - { 0x00000004, 0x00221e27, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0xfffff0ff, 0x00281a30, 0x000 }, - { 0x0000a028, 0x00204411, 0x000 }, - { 0x00000000, 0x002948e6, 0x000 }, - { 0x0000a018, 0x00204411, 0x000 }, - { 0x3fffffff, 0x00284a23, 0x000 }, - { 0x0000a010, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000030, 0x0020162d, 0x000 }, - { 0x00000002, 0x00291625, 0x000 }, - { 0x00000030, 0x00203625, 0x000 }, - { 0x00000025, 0x0020162d, 0x000 }, - { 0x00000000, 0x002f00a3, 0x000 }, - { 0x00000000, 0x0cc00000, 0x083 }, - { 0x00000026, 0x0020162d, 0x000 }, - { 0x00000000, 0x002f00a4, 0x000 }, - { 0x00000000, 0x0cc00000, 0x084 }, - { 0x00000000, 0x00400000, 0x08a }, - { 0x00000025, 0x00203623, 0x000 }, - { 0x00000026, 0x00203624, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x08a }, - { 0x00000000, 0x00600000, 0x668 }, - { 0x00000000, 0x00600000, 0x65c }, - { 0x00000002, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x08d }, - { 0x00000012, 0xc0403620, 0x093 }, - { 0x00000000, 0x2ee00000, 0x091 }, - { 0x00000000, 0x2ce00000, 0x090 }, - { 0x00000002, 0x00400e2d, 0x092 }, - { 0x00000003, 0x00400e2d, 0x092 }, - { 0x0000000c, 0x00200e2d, 0x000 }, - { 0x00000012, 0x00203623, 0x000 }, - { 0x00000003, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x098 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x0a0 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x2ee00000, 0x09e }, - { 0x00000000, 0x2ce00000, 0x09d }, - { 0x00000002, 0x00400e2d, 0x09f }, - { 0x00000003, 0x00400e2d, 0x09f }, - { 0x0000000c, 0x00200e2d, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000000, 0x003a0c02, 0x000 }, - { 0x003f0000, 0x00280e23, 0x000 }, - { 0x00000010, 0x00210e23, 0x000 }, - { 0x00000011, 0x00203623, 0x000 }, - { 0x0000001e, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0a7 }, - { 0x00000016, 0xc0203620, 0x000 }, - { 0x0000001f, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0aa }, - { 0x00000015, 0xc0203620, 0x000 }, - { 0x00000008, 0x00210e2b, 0x000 }, - { 0x0000007f, 0x00280e23, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0e1 }, - { 0x00000000, 0x27000000, 0x000 }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0b3 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x0000000c, 0x00221e30, 0x000 }, - { 0x99800000, 0x00204411, 0x000 }, - { 0x00000004, 0x0020122d, 0x000 }, - { 0x00000008, 0x00221224, 0x000 }, - { 0x00000010, 0x00201811, 0x000 }, - { 0x00000000, 0x00291ce4, 0x000 }, - { 0x00000000, 0x00604807, 0x12f }, - { 0x9b000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x9c000000, 0x00204411, 0x000 }, - { 0x00000000, 0x0033146f, 0x000 }, - { 0x00000001, 0x00333e23, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0x00203c05, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x00000000, 0x00201010, 0x000 }, - { 0x0000e007, 0x00204411, 0x000 }, - { 0x0000000f, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0cb }, - { 0x00f8ff08, 0x00204811, 0x000 }, - { 0x98000000, 0x00404811, 0x0dc }, - { 0x000000f0, 0x00280e22, 0x000 }, - { 0x000000a0, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x0da }, - { 0x00000011, 0x00200e2d, 0x000 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0d5 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0d4 }, - { 0x00003f00, 0x00400c11, 0x0d6 }, - { 0x00001f00, 0x00400c11, 0x0d6 }, - { 0x00000f00, 0x00200c11, 0x000 }, - { 0x00380009, 0x00294a23, 0x000 }, - { 0x3f000000, 0x00280e2b, 0x000 }, - { 0x00000002, 0x00220e23, 0x000 }, - { 0x00000007, 0x00494a23, 0x0dc }, - { 0x00380f09, 0x00204811, 0x000 }, - { 0x68000007, 0x00204811, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a24, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000a202, 0x00204411, 0x000 }, - { 0x00ff0000, 0x00280e22, 0x000 }, - { 0x00000080, 0x00294a23, 0x000 }, - { 0x00000027, 0x00200e2d, 0x000 }, - { 0x00000026, 0x0020122d, 0x000 }, - { 0x00000000, 0x002f0083, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0ea }, - { 0x00000000, 0x00600000, 0x662 }, - { 0x00000000, 0x00400000, 0x0eb }, - { 0x00000000, 0x00600000, 0x665 }, - { 0x00000007, 0x0020222d, 0x000 }, - { 0x00000005, 0x00220e22, 0x000 }, - { 0x00100000, 0x00280e23, 0x000 }, - { 0x00000000, 0x00292068, 0x000 }, - { 0x00000000, 0x003a0c02, 0x000 }, - { 0x000000ef, 0x00280e23, 0x000 }, - { 0x00000000, 0x00292068, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0x00000003, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x0f8 }, - { 0x0000000b, 0x00210228, 0x000 }, - { 0x00000000, 0x14c00000, 0x0f8 }, - { 0x00000400, 0x00292228, 0x000 }, - { 0x00000014, 0x00203628, 0x000 }, - { 0x0000001c, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x0fd }, - { 0x0000a30c, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000001e, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x10b }, - { 0x0000a30f, 0x00204411, 0x000 }, - { 0x00000011, 0x00200e2d, 0x000 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x104 }, - { 0xffffffff, 0x00404811, 0x10b }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x107 }, - { 0x0000ffff, 0x00404811, 0x10b }, - { 0x00000004, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x10a }, - { 0x000000ff, 0x00404811, 0x10b }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0002c400, 0x00204411, 0x000 }, - { 0x0000001f, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x112 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x00000013, 0x00203623, 0x000 }, - { 0x00000018, 0x40224a20, 0x000 }, - { 0x00000010, 0xc0424a20, 0x114 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x00000013, 0x00203623, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000000a, 0x00201011, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x11b }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00531224, 0x117 }, - { 0xffbfffff, 0x00283a2e, 0x000 }, - { 0x0000001b, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x12e }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0x00000018, 0x00220e30, 0x000 }, - { 0xfc000000, 0x00280e23, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x00000000, 0x00201010, 0x000 }, - { 0x0000e00e, 0x00204411, 0x000 }, - { 0x07f8ff08, 0x00204811, 0x000 }, - { 0x00000000, 0x00294a23, 0x000 }, - { 0x0000001c, 0x00201e2d, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a24, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x00800000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204806, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x68d }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x68c }, - { 0x00000004, 0x00404c11, 0x135 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x0000001c, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68d }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x13c }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00000000, 0x00600000, 0x160 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000ffff, 0x40280620, 0x000 }, - { 0x00000010, 0xc0210a20, 0x000 }, - { 0x00000000, 0x00341461, 0x000 }, - { 0x00000000, 0x00741882, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x147 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x160 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x00000010, 0x40211620, 0x000 }, - { 0x0000ffff, 0xc0681a20, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x158 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000001, 0x00300a2f, 0x000 }, - { 0x00000001, 0x00210a22, 0x000 }, - { 0x00000003, 0x00384a22, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001a, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600000, 0x18f }, - { 0x00000000, 0x00600000, 0x1a0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00202c08, 0x000 }, - { 0x00000000, 0x00202411, 0x000 }, - { 0x00000000, 0x00202811, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000002, 0x00221e29, 0x000 }, - { 0x00000000, 0x007048eb, 0x19c }, - { 0x00000000, 0x00600000, 0x2bb }, - { 0x00000001, 0x40330620, 0x000 }, - { 0x00000000, 0xc0302409, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ae00000, 0x181 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x00000000, 0x00400000, 0x186 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x186 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000001, 0x00530621, 0x182 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0604800, 0x197 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000011, 0x0020062d, 0x000 }, - { 0x00000000, 0x0078042a, 0x2fb }, - { 0x00000000, 0x00202809, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x174 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000210, 0x00600411, 0x315 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x194 }, - { 0x00000015, 0xc0203620, 0x000 }, - { 0x00000016, 0xc0203620, 0x000 }, - { 0x3f800000, 0x00200411, 0x000 }, - { 0x46000000, 0x00600811, 0x1b2 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x19b }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000021, 0x00804811, 0x000 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000ffff, 0x40281620, 0x000 }, - { 0x00000010, 0xc0811a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000008, 0x00221e30, 0x000 }, - { 0x00000029, 0x00201a2d, 0x000 }, - { 0x0000e000, 0x00204411, 0x000 }, - { 0xfffbff09, 0x00204811, 0x000 }, - { 0x0000000f, 0x0020222d, 0x000 }, - { 0x00001fff, 0x00294a28, 0x000 }, - { 0x00000006, 0x0020222d, 0x000 }, - { 0x00000000, 0x002920e8, 0x000 }, - { 0x00000000, 0x00204808, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a26, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000100, 0x00201811, 0x000 }, - { 0x00000008, 0x00621e28, 0x12f }, - { 0x00000008, 0x00822228, 0x000 }, - { 0x0002c000, 0x00204411, 0x000 }, - { 0x00000015, 0x00600e2d, 0x1bd }, - { 0x00000016, 0x00600e2d, 0x1bd }, - { 0x0000c008, 0x00204411, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0x00000000, 0x14c00000, 0x1b9 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0x39000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00804802, 0x000 }, - { 0x00000018, 0x00202e2d, 0x000 }, - { 0x00000000, 0x003b0d63, 0x000 }, - { 0x00000008, 0x00224a23, 0x000 }, - { 0x00000010, 0x00224a23, 0x000 }, - { 0x00000018, 0x00224a23, 0x000 }, - { 0x00000000, 0x00804803, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00001000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00000007, 0x0021062f, 0x000 }, - { 0x00000013, 0x00200a2d, 0x000 }, - { 0x00000001, 0x00202c11, 0x000 }, - { 0x0000ffff, 0x40282220, 0x000 }, - { 0x0000000f, 0x00262228, 0x000 }, - { 0x00000010, 0x40212620, 0x000 }, - { 0x0000000f, 0x00262629, 0x000 }, - { 0x00000000, 0x00202802, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001b, 0x00204811, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1e0 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000081, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000080, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1dc }, - { 0x00000000, 0x00600000, 0x1e9 }, - { 0x00000001, 0x00531e27, 0x1d8 }, - { 0x00000001, 0x00202c11, 0x000 }, - { 0x0000001f, 0x00280a22, 0x000 }, - { 0x0000001f, 0x00282a2a, 0x000 }, - { 0x00000001, 0x00530621, 0x1d1 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000002, 0x00304a2f, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000001, 0x00301e2f, 0x000 }, - { 0x00000000, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x1e9 }, - { 0x00000001, 0x00531e27, 0x1e5 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x0000000f, 0x00260e23, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000000f, 0x00261224, 0x000 }, - { 0x00000000, 0x00201411, 0x000 }, - { 0x00000000, 0x00601811, 0x2bb }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022b, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1f8 }, - { 0x00000010, 0x00221628, 0x000 }, - { 0xffff0000, 0x00281625, 0x000 }, - { 0x0000ffff, 0x00281a29, 0x000 }, - { 0x00000000, 0x002948c5, 0x000 }, - { 0x00000000, 0x0020480a, 0x000 }, - { 0x00000000, 0x00202c11, 0x000 }, - { 0x00000010, 0x00221623, 0x000 }, - { 0xffff0000, 0x00281625, 0x000 }, - { 0x0000ffff, 0x00281a24, 0x000 }, - { 0x00000000, 0x002948c5, 0x000 }, - { 0x00000000, 0x00731503, 0x205 }, - { 0x00000000, 0x00201805, 0x000 }, - { 0x00000000, 0x00731524, 0x205 }, - { 0x00000000, 0x002d14c5, 0x000 }, - { 0x00000000, 0x003008a2, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00202802, 0x000 }, - { 0x00000000, 0x00202003, 0x000 }, - { 0x00000000, 0x00802404, 0x000 }, - { 0x0000000f, 0x00210225, 0x000 }, - { 0x00000000, 0x14c00000, 0x68c }, - { 0x00000000, 0x002b1405, 0x000 }, - { 0x00000001, 0x00901625, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001a, 0x00294a22, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00384a21, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000ffff, 0x40281220, 0x000 }, - { 0x00000010, 0xc0211a20, 0x000 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211620, 0x000 }, - { 0x00000000, 0x00741465, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00000001, 0x00330621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0cc00000, 0x219 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x212 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x645 }, - { 0x00000000, 0x0040040f, 0x213 }, - { 0x00000000, 0x00600000, 0x631 }, - { 0x00000000, 0x00600000, 0x645 }, - { 0x00000210, 0x00600411, 0x315 }, - { 0x00000000, 0x00600000, 0x1a0 }, - { 0x00000000, 0x00600000, 0x19c }, - { 0x00000000, 0x00600000, 0x2bb }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204808, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ae00000, 0x232 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x00000000, 0x00400000, 0x236 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x236 }, - { 0x00000000, 0xc0404800, 0x233 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x00600411, 0x2fb }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x631 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000018, 0x40210a20, 0x000 }, - { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x24c }, - { 0x00000014, 0x0020222d, 0x000 }, - { 0x00080101, 0x00292228, 0x000 }, - { 0x00000014, 0x00203628, 0x000 }, - { 0x0000a30c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x251 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000010, 0x00600411, 0x315 }, - { 0x3f800000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x00000000, 0x00600000, 0x27c }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000001, 0x00211e27, 0x000 }, - { 0x00000000, 0x14e00000, 0x26a }, - { 0x00000012, 0x00201e2d, 0x000 }, - { 0x0000ffff, 0x00281e27, 0x000 }, - { 0x00000000, 0x00341c27, 0x000 }, - { 0x00000000, 0x12c00000, 0x25f }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f00e5, 0x000 }, - { 0x00000000, 0x08c00000, 0x262 }, - { 0x00000000, 0x00201407, 0x000 }, - { 0x00000012, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00211e27, 0x000 }, - { 0x00000000, 0x00341c47, 0x000 }, - { 0x00000000, 0x12c00000, 0x267 }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f00e6, 0x000 }, - { 0x00000000, 0x08c00000, 0x26a }, - { 0x00000000, 0x00201807, 0x000 }, - { 0x00000000, 0x00600000, 0x2c1 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000000, 0x00342023, 0x000 }, - { 0x00000000, 0x12c00000, 0x272 }, - { 0x00000000, 0x00342044, 0x000 }, - { 0x00000000, 0x12c00000, 0x271 }, - { 0x00000016, 0x00404811, 0x276 }, - { 0x00000018, 0x00404811, 0x276 }, - { 0x00000000, 0x00342044, 0x000 }, - { 0x00000000, 0x12c00000, 0x275 }, - { 0x00000017, 0x00404811, 0x276 }, - { 0x00000019, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0x00604411, 0x2e9 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x256 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000010, 0x40210620, 0x000 }, - { 0x0000ffff, 0xc0280a20, 0x000 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x00000010, 0x40211620, 0x000 }, - { 0x0000ffff, 0xc0881a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x00000000, 0x00600000, 0x631 }, - { 0x00000000, 0xc0600000, 0x2a3 }, - { 0x00000005, 0x00200a2d, 0x000 }, - { 0x00000008, 0x00220a22, 0x000 }, - { 0x0000002b, 0x00201a2d, 0x000 }, - { 0x0000001c, 0x00201e2d, 0x000 }, - { 0x00007000, 0x00281e27, 0x000 }, - { 0x00000000, 0x00311ce6, 0x000 }, - { 0x0000002a, 0x00201a2d, 0x000 }, - { 0x0000000c, 0x00221a26, 0x000 }, - { 0x00000000, 0x002f00e6, 0x000 }, - { 0x00000000, 0x06e00000, 0x292 }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x0000002b, 0x00203623, 0x000 }, - { 0x00000010, 0x00201811, 0x000 }, - { 0x00000000, 0x00691ce2, 0x12f }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x29d }, - { 0x00000001, 0x00333e2f, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000001c, 0x00403627, 0x000 }, - { 0x0000000c, 0xc0220a20, 0x000 }, - { 0x00000029, 0x00203622, 0x000 }, - { 0x00000028, 0xc0403620, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000009, 0x00204811, 0x000 }, - { 0xa1000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002c1ce3, 0x000 }, - { 0x00000021, 0x00203627, 0x000 }, - { 0x00000022, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002c1ce4, 0x000 }, - { 0x00000022, 0x00203627, 0x000 }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120a3, 0x000 }, - { 0x00000000, 0x002d1d07, 0x000 }, - { 0x00000023, 0x00203627, 0x000 }, - { 0x00000024, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x00000000, 0x002d1d07, 0x000 }, - { 0x00000024, 0x00803627, 0x000 }, - { 0x00000021, 0x00203623, 0x000 }, - { 0x00000022, 0x00203624, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000023, 0x00203627, 0x000 }, - { 0x00000000, 0x00311cc4, 0x000 }, - { 0x00000024, 0x00803627, 0x000 }, - { 0x0000001a, 0x00203627, 0x000 }, - { 0x0000001b, 0x00203628, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14c00000, 0x2dc }, - { 0x00000000, 0x00400000, 0x2d9 }, - { 0x0000001a, 0x00203627, 0x000 }, - { 0x0000001b, 0x00203628, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x2d9 }, - { 0x00000003, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x2dc }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002e00e1, 0x000 }, - { 0x00000000, 0x02c00000, 0x2dc }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120a1, 0x000 }, - { 0x00000000, 0x002e00e8, 0x000 }, - { 0x00000000, 0x06c00000, 0x2dc }, - { 0x00000024, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002e00e2, 0x000 }, - { 0x00000000, 0x02c00000, 0x2dc }, - { 0x00000022, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120c2, 0x000 }, - { 0x00000000, 0x002e00e8, 0x000 }, - { 0x00000000, 0x06c00000, 0x2dc }, - { 0x00000000, 0x00600000, 0x668 }, - { 0x00000000, 0x00600000, 0x2b5 }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x00000000, 0x00600000, 0x2b5 }, - { 0x00000000, 0x00600000, 0x65f }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x00000000, 0x00600000, 0x2a7 }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x0000001a, 0x00201e2d, 0x000 }, - { 0x0000001b, 0x0080222d, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000010, 0x00221e21, 0x000 }, - { 0x00000000, 0x00294847, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000000, 0x00311ca1, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294847, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000010, 0x00221e21, 0x000 }, - { 0x00000000, 0x003120c2, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000001, 0x00220a21, 0x000 }, - { 0x00000000, 0x003308a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000001, 0x00220a21, 0x000 }, - { 0x00000000, 0x003008a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x003808c5, 0x000 }, - { 0x00000000, 0x00300841, 0x000 }, - { 0x00000001, 0x00220a22, 0x000 }, - { 0x00000000, 0x003308a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000017, 0x0020222d, 0x000 }, - { 0x00000000, 0x14c00000, 0x318 }, - { 0xffffffef, 0x00280621, 0x000 }, - { 0x00000014, 0x0020222d, 0x000 }, - { 0x0000f8e0, 0x00204411, 0x000 }, - { 0x00000000, 0x00294901, 0x000 }, - { 0x00000000, 0x00894901, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00804811, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x97000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00002257, 0x00204411, 0x000 }, - { 0x00000003, 0xc0484a20, 0x000 }, - { 0x0000225d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0x00600000, 0x645 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00384a22, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x40204800, 0x000 }, - { 0x00000001, 0x40304a20, 0x000 }, - { 0x00000002, 0xc0304a20, 0x000 }, - { 0x00000001, 0x00530a22, 0x34b }, - { 0x0000003f, 0xc0280a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000018, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68d }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x354 }, - { 0x00000014, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x364 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00604802, 0x36e }, - { 0x00002100, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x36a }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x35f }, - { 0x00000028, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5c0 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x35f }, - { 0x0000002c, 0x00203626, 0x000 }, - { 0x00000049, 0x00201811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x00000001, 0x00331a26, 0x000 }, - { 0x00000000, 0x002f0226, 0x000 }, - { 0x00000000, 0x0cc00000, 0x370 }, - { 0x0000002c, 0x00801a2d, 0x000 }, - { 0x0000003f, 0xc0280a20, 0x000 }, - { 0x00000015, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x386 }, - { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3b1 }, - { 0x00000016, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3b5 }, - { 0x00000020, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x39c }, - { 0x0000000f, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3a8 }, - { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3a8 }, - { 0x0000001e, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x390 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x08000000, 0x00290a22, 0x000 }, - { 0x00000003, 0x40210e20, 0x000 }, - { 0x0000000c, 0xc0211220, 0x000 }, - { 0x00080000, 0x00281224, 0x000 }, - { 0x00000014, 0xc0221620, 0x000 }, - { 0x00000000, 0x002914a4, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x002948a2, 0x000 }, - { 0x0000a1fe, 0x00204411, 0x000 }, - { 0x00000000, 0x00404803, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68d }, - { 0x00000015, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x392 }, - { 0x0000210e, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000017, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68d }, - { 0x00000003, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x39e }, - { 0x00002108, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x80000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000010, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x3ae }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000006, 0x00404811, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36e }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x0000001d, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x3ce }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000018, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68d }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x3c0 }, - { 0x00002100, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0xbabecafe, 0x00204811, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000004, 0x00404811, 0x000 }, - { 0x00002170, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000a, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x3d3 }, - { 0x8c000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00003fff, 0x40280a20, 0x000 }, - { 0x80000000, 0x40280e20, 0x000 }, - { 0x40000000, 0xc0281220, 0x000 }, - { 0x00040000, 0x00694622, 0x68d }, - { 0x00000000, 0x00201410, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x3e1 }, - { 0x00000000, 0xc0401800, 0x3e4 }, - { 0x00003fff, 0xc0281a20, 0x000 }, - { 0x00040000, 0x00694626, 0x68d }, - { 0x00000000, 0x00201810, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x3e7 }, - { 0x00000000, 0xc0401c00, 0x3ea }, - { 0x00003fff, 0xc0281e20, 0x000 }, - { 0x00040000, 0x00694627, 0x68d }, - { 0x00000000, 0x00201c10, 0x000 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0x002820c5, 0x000 }, - { 0x00000000, 0x004948e8, 0x000 }, - { 0xa5800000, 0x00200811, 0x000 }, - { 0x00002000, 0x00200c11, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x40204800, 0x000 }, - { 0x0000001f, 0xc0210220, 0x000 }, - { 0x00000000, 0x14c00000, 0x3f7 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0000ffff, 0xc0481220, 0x3ff }, - { 0xa7800000, 0x00200811, 0x000 }, - { 0x0000a000, 0x00200c11, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x83000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00304883, 0x000 }, - { 0x84000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1d000000, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0xa9800000, 0x00200811, 0x000 }, - { 0x0000c000, 0x00400c11, 0x3fa }, - { 0xab800000, 0x00200811, 0x000 }, - { 0x0000f8e0, 0x00400c11, 0x3fa }, - { 0xad800000, 0x00200811, 0x000 }, - { 0x0000f880, 0x00400c11, 0x3fa }, - { 0xb3800000, 0x00200811, 0x000 }, - { 0x0000f3fc, 0x00400c11, 0x3fa }, - { 0xaf800000, 0x00200811, 0x000 }, - { 0x0000e000, 0x00400c11, 0x3fa }, - { 0xb1800000, 0x00200811, 0x000 }, - { 0x0000f000, 0x00400c11, 0x3fa }, - { 0x83000000, 0x00204411, 0x000 }, - { 0x00002148, 0x00204811, 0x000 }, - { 0x84000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1d000000, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x01182000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0218a000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0318c000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0418f8e0, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0518f880, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0618e000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0718f000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0818f3fc, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00000030, 0x00200a2d, 0x000 }, - { 0x00000000, 0xc0290c40, 0x000 }, - { 0x00000030, 0x00203623, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x86000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00404801, 0x000 }, - { 0x85000000, 0xc0204411, 0x000 }, - { 0x00000000, 0x00404801, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x00000018, 0x40210220, 0x000 }, - { 0x00000000, 0x14c00000, 0x445 }, - { 0x00800000, 0xc0494a20, 0x446 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x68d }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000000, 0x00404c02, 0x44b }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x00000000, 0xc0201000, 0x000 }, - { 0x00000000, 0xc0201400, 0x000 }, - { 0x00000000, 0xc0201800, 0x000 }, - { 0x00000000, 0xc0201c00, 0x000 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x459 }, - { 0x00000000, 0xc0202000, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x00000010, 0x00280a23, 0x000 }, - { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x461 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0x00694624, 0x68d }, - { 0x00000000, 0x00400000, 0x466 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x00604805, 0x692 }, - { 0x00000000, 0x002824f0, 0x000 }, - { 0x00000007, 0x00280a23, 0x000 }, - { 0x00000001, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x46d }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x04e00000, 0x486 }, - { 0x00000000, 0x00400000, 0x493 }, - { 0x00000002, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x472 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x02e00000, 0x486 }, - { 0x00000000, 0x00400000, 0x493 }, - { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x477 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x0ce00000, 0x486 }, - { 0x00000000, 0x00400000, 0x493 }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x47c }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x0ae00000, 0x486 }, - { 0x00000000, 0x00400000, 0x493 }, - { 0x00000005, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x481 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x06e00000, 0x486 }, - { 0x00000000, 0x00400000, 0x493 }, - { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x486 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x08e00000, 0x486 }, - { 0x00000000, 0x00400000, 0x493 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x000 }, - { 0x00000008, 0x00210a23, 0x000 }, - { 0x00000000, 0x14c00000, 0x490 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x00000000, 0xc0204400, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x499 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x00404c08, 0x459 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x00000011, 0x40211220, 0x000 }, - { 0x00000012, 0x40211620, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00210225, 0x000 }, - { 0x00000000, 0x14e00000, 0x4a3 }, - { 0x00040000, 0xc0494a20, 0x4a4 }, - { 0xfffbffff, 0xc0284a20, 0x000 }, - { 0x00000000, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x4b0 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000c, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x4ac }, - { 0xa0000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000004, 0x00204811, 0x000 }, - { 0x0000216b, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204810, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000005, 0x00204811, 0x000 }, - { 0x0000216c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204810, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00400000, 0x4aa }, - { 0x00000000, 0xc0210a20, 0x000 }, - { 0x00000000, 0x14c00000, 0x4c3 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0604800, 0x692 }, - { 0x00000000, 0x00400000, 0x4c7 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0xc0294620, 0x000 }, - { 0x00000000, 0xc0600000, 0x68d }, - { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x4ce }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x00000000, 0xc0204400, 0x000 }, - { 0x00000000, 0xc0404810, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68d }, - { 0x00000000, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x4d0 }, - { 0x00002180, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000003, 0x00333e2f, 0x000 }, - { 0x00000001, 0x00210221, 0x000 }, - { 0x00000000, 0x14e00000, 0x500 }, - { 0x0000002c, 0x00200a2d, 0x000 }, - { 0x00040000, 0x18e00c11, 0x4ef }, - { 0x00000001, 0x00333e2f, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xd8c04800, 0x4e3 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000002d, 0x0020122d, 0x000 }, - { 0x00000000, 0x00290c83, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000011, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000000, 0x00400000, 0x4aa }, - { 0x0000002c, 0xc0203620, 0x000 }, - { 0x0000002d, 0xc0403620, 0x000 }, - { 0x0000000f, 0x00210221, 0x000 }, - { 0x00000000, 0x14c00000, 0x505 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0xd9000000, 0x000 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0xb5000000, 0x00204411, 0x000 }, - { 0x00002000, 0x00204811, 0x000 }, - { 0xb6000000, 0x00204411, 0x000 }, - { 0x0000a000, 0x00204811, 0x000 }, - { 0xb7000000, 0x00204411, 0x000 }, - { 0x0000c000, 0x00204811, 0x000 }, - { 0xb8000000, 0x00204411, 0x000 }, - { 0x0000f8e0, 0x00204811, 0x000 }, - { 0xb9000000, 0x00204411, 0x000 }, - { 0x0000f880, 0x00204811, 0x000 }, - { 0xba000000, 0x00204411, 0x000 }, - { 0x0000e000, 0x00204811, 0x000 }, - { 0xbb000000, 0x00204411, 0x000 }, - { 0x0000f000, 0x00204811, 0x000 }, - { 0xbc000000, 0x00204411, 0x000 }, - { 0x0000f3fc, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000002, 0x00204811, 0x000 }, - { 0x000000ff, 0x00280e30, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x519 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0x14c00000, 0x52e }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x0000001c, 0x00203623, 0x000 }, - { 0x0000002b, 0x00203623, 0x000 }, - { 0x00000029, 0x00203623, 0x000 }, - { 0x00000028, 0x00203623, 0x000 }, - { 0x00000017, 0x00203623, 0x000 }, - { 0x00000025, 0x00203623, 0x000 }, - { 0x00000026, 0x00203623, 0x000 }, - { 0x00000015, 0x00203623, 0x000 }, - { 0x00000016, 0x00203623, 0x000 }, - { 0xffffe000, 0x00200c11, 0x000 }, - { 0x00000021, 0x00203623, 0x000 }, - { 0x00000022, 0x00203623, 0x000 }, - { 0x00001fff, 0x00200c11, 0x000 }, - { 0x00000023, 0x00203623, 0x000 }, - { 0x00000024, 0x00203623, 0x000 }, - { 0xf1ffffff, 0x00283a2e, 0x000 }, - { 0x0000001a, 0xc0220e20, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x0000002a, 0x40203620, 0x000 }, - { 0x87000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1f4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x00000030, 0x00203623, 0x000 }, - { 0x9d000000, 0x00204411, 0x000 }, - { 0x0000001f, 0x40214a20, 0x000 }, - { 0x96000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x00000000, 0xc0201000, 0x000 }, - { 0x0000001f, 0x00211624, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x0000001d, 0x00203623, 0x000 }, - { 0x00000003, 0x00281e23, 0x000 }, - { 0x00000008, 0x00222223, 0x000 }, - { 0xfffff000, 0x00282228, 0x000 }, - { 0x00000000, 0x002920e8, 0x000 }, - { 0x0000001f, 0x00203628, 0x000 }, - { 0x00000018, 0x00211e23, 0x000 }, - { 0x00000020, 0x00203627, 0x000 }, - { 0x00000002, 0x00221624, 0x000 }, - { 0x00000000, 0x003014a8, 0x000 }, - { 0x0000001e, 0x00203625, 0x000 }, - { 0x00000003, 0x00211a24, 0x000 }, - { 0x10000000, 0x00281a26, 0x000 }, - { 0xefffffff, 0x00283a2e, 0x000 }, - { 0x00000000, 0x004938ce, 0x67b }, - { 0x00000001, 0x40280a20, 0x000 }, - { 0x00000006, 0x40280e20, 0x000 }, - { 0x00000300, 0xc0281220, 0x000 }, - { 0x00000008, 0x00211224, 0x000 }, - { 0x00000000, 0xc0201620, 0x000 }, - { 0x00000000, 0xc0201a20, 0x000 }, - { 0x00000000, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x566 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00002258, 0x00300a24, 0x000 }, - { 0x00040000, 0x00694622, 0x68d }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00020000, 0x00294a26, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x56e }, - { 0x00000000, 0xc0201c10, 0x000 }, - { 0x00000000, 0xc0400000, 0x57c }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x56e }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00002258, 0x00300a24, 0x000 }, - { 0x00040000, 0x00694622, 0x68d }, - { 0x00000000, 0xc0201c10, 0x000 }, - { 0x00000000, 0xc0400000, 0x57c }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x572 }, - { 0x00000000, 0xc0201c00, 0x000 }, - { 0x00000000, 0xc0400000, 0x57c }, - { 0x00000004, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x57a }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0604800, 0x692 }, - { 0x00000000, 0x00401c10, 0x57c }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x0ee00000, 0x57e }, - { 0x00000000, 0x00600000, 0x5c9 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x58f }, - { 0x0000a2b7, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2b6, 0x00604411, 0x68d }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x0000a2c4, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x58d }, - { 0x0000a2d1, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d1, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x00000001, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5a0 }, - { 0x0000a2bb, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2ba, 0x00604411, 0x68d }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x0000a2c5, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x59e }, - { 0x0000a2d2, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d2, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x00000002, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5b1 }, - { 0x0000a2bf, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2be, 0x00604411, 0x68d }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x0000a2c6, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x5af }, - { 0x0000a2d3, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d3, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x0000a2c3, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2c2, 0x00604411, 0x68d }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x0000a2c7, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x5be }, - { 0x0000a2d4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d4, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x85000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0x0000304a, 0x00204411, 0x000 }, - { 0x01000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00400000, 0x5c4 }, - { 0xa4000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0xc0600000, 0x5c9 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000002c, 0x00203621, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000000, 0x002f0230, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5d0 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000030, 0x00403621, 0x5e3 }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00007e00, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x5e3 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a092, 0x00604411, 0x68d }, - { 0x00000031, 0x00203630, 0x000 }, - { 0x0004a093, 0x00604411, 0x68d }, - { 0x00000032, 0x00203630, 0x000 }, - { 0x0004a2b6, 0x00604411, 0x68d }, - { 0x00000033, 0x00203630, 0x000 }, - { 0x0004a2ba, 0x00604411, 0x68d }, - { 0x00000034, 0x00203630, 0x000 }, - { 0x0004a2be, 0x00604411, 0x68d }, - { 0x00000035, 0x00203630, 0x000 }, - { 0x0004a2c2, 0x00604411, 0x68d }, - { 0x00000036, 0x00203630, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x00000005, 0x00204811, 0x000 }, - { 0x0000a1f4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x88000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000001, 0x002f0230, 0x000 }, - { 0x00000000, 0x0ce00000, 0x62c }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x62c }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00007e00, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x605 }, - { 0x0000a092, 0x00204411, 0x000 }, - { 0x00000031, 0x00204a2d, 0x000 }, - { 0x0000a093, 0x00204411, 0x000 }, - { 0x00000032, 0x00204a2d, 0x000 }, - { 0x0000a2b6, 0x00204411, 0x000 }, - { 0x00000033, 0x00204a2d, 0x000 }, - { 0x0000a2ba, 0x00204411, 0x000 }, - { 0x00000034, 0x00204a2d, 0x000 }, - { 0x0000a2be, 0x00204411, 0x000 }, - { 0x00000035, 0x00204a2d, 0x000 }, - { 0x0000a2c2, 0x00204411, 0x000 }, - { 0x00000036, 0x00204a2d, 0x000 }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x000001ff, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x62b }, - { 0x00000000, 0x00210221, 0x000 }, - { 0x00000000, 0x14c00000, 0x60e }, - { 0x0004a003, 0x00604411, 0x68d }, - { 0x0000a003, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000001, 0x00210621, 0x000 }, - { 0x00000000, 0x14c00000, 0x613 }, - { 0x0004a010, 0x00604411, 0x68d }, - { 0x0000a010, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000001, 0x00210621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x62b }, - { 0x0004a011, 0x00604411, 0x68d }, - { 0x0000a011, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a012, 0x00604411, 0x68d }, - { 0x0000a012, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a013, 0x00604411, 0x68d }, - { 0x0000a013, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a014, 0x00604411, 0x68d }, - { 0x0000a014, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a015, 0x00604411, 0x68d }, - { 0x0000a015, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a016, 0x00604411, 0x68d }, - { 0x0000a016, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a017, 0x00604411, 0x68d }, - { 0x0000a017, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x0000002c, 0x0080062d, 0x000 }, - { 0xff000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000002, 0x00804811, 0x000 }, - { 0x00000000, 0x0ee00000, 0x63d }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00000002, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x63b }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x00001000, 0x00200811, 0x000 }, - { 0x0000002b, 0x00203622, 0x000 }, - { 0x00000000, 0x00600000, 0x641 }, - { 0x00000000, 0x00600000, 0x5c9 }, - { 0x98000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00804811, 0x000 }, - { 0x00000000, 0xc0600000, 0x641 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000022, 0x00204811, 0x000 }, - { 0x89000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00404811, 0x62d }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00404811, 0x62d }, - { 0x00000000, 0x00600000, 0x65c }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0xc0204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36e }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00010000, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x09800000, 0x00204811, 0x000 }, - { 0xffffffff, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x68d }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000004, 0x00404c11, 0x656 }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000004, 0x00291e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0xfffffffb, 0x00281e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000008, 0x00291e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0xfffffff7, 0x00281e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36e }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00010000, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x01800000, 0x00204811, 0x000 }, - { 0xffffffff, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004217f, 0x00604411, 0x68d }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x68c }, - { 0x00000010, 0x00404c11, 0x672 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x38c00000, 0x000 }, - { 0x0000001d, 0x00200a2d, 0x000 }, - { 0x0000001e, 0x00200e2d, 0x000 }, - { 0x0000001f, 0x0020122d, 0x000 }, - { 0x00000020, 0x0020162d, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000004, 0x00301224, 0x000 }, - { 0x00000000, 0x002f0064, 0x000 }, - { 0x00000000, 0x0cc00000, 0x68b }, - { 0x00000003, 0x00281a22, 0x000 }, - { 0x00000008, 0x00221222, 0x000 }, - { 0xfffff000, 0x00281224, 0x000 }, - { 0x00000000, 0x002910c4, 0x000 }, - { 0x0000001f, 0x00403624, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x1ac00000, 0x68d }, - { 0x9f000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x690 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x1ac00000, 0x692 }, - { 0x9e000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x695 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00001000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001b, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0xc0204411, 0x000 }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000024, 0x0020222d, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000022, 0x0020222d, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00404811, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x01420502, 0x05c00250, 0x000 }, - { 0x01c30168, 0x043f05c0, 0x000 }, - { 0x02250209, 0x02500151, 0x000 }, - { 0x02230245, 0x02a00241, 0x000 }, - { 0x03d705c0, 0x05c005c0, 0x000 }, - { 0x0649064a, 0x031f05c0, 0x000 }, - { 0x05c005c5, 0x03200340, 0x000 }, - { 0x032a0282, 0x03420334, 0x000 }, - { 0x05c005c0, 0x05c005c0, 0x000 }, - { 0x05c00551, 0x05c005c0, 0x000 }, - { 0x03ba05c0, 0x04bb0344, 0x000 }, - { 0x049a0450, 0x043d05c0, 0x000 }, - { 0x04d005c0, 0x044104dd, 0x000 }, - { 0x04500507, 0x03510375, 0x000 }, - { 0x05c005c0, 0x05c005c0, 0x000 }, - { 0x05c005c0, 0x05c005c0, 0x000 }, - { 0x05c005c0, 0x063f05c7, 0x000 }, - { 0x05c005c0, 0x000705c0, 0x000 }, - { 0x05c005c0, 0x05c005c0, 0x000 }, - { 0x05c005c0, 0x05c005c0, 0x000 }, - { 0x03f803ed, 0x04080406, 0x000 }, - { 0x040e040a, 0x040c0410, 0x000 }, - { 0x041c0418, 0x04240420, 0x000 }, - { 0x042c0428, 0x04340430, 0x000 }, - { 0x05c005c0, 0x043805c0, 0x000 }, - { 0x05c005c0, 0x05c005c0, 0x000 }, - { 0x05c005c0, 0x05c005c0, 0x000 }, - { 0x00020679, 0x06970006, 0x000 }, -}; - -static const u32 RV610_pfp_microcode[] = { -0xca0400, -0xa00000, -0x7e828b, -0x7c038b, -0x8001b8, -0x7c038b, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xc41838, -0xca2400, -0xca2800, -0x9581a8, -0xc41c3a, -0xc3c000, -0xca0800, -0xca0c00, -0x7c744b, -0xc20005, -0x99c000, -0xc41c3a, -0x7c744c, -0xc0fff0, -0x042c04, -0x309002, -0x7d2500, -0x351402, -0x7d350b, -0x255403, -0x7cd580, -0x259c03, -0x95c004, -0xd5001b, -0x7eddc1, -0x7d9d80, -0xd6801b, -0xd5801b, -0xd4401e, -0xd5401e, -0xd6401e, -0xd6801e, -0xd4801e, -0xd4c01e, -0x9783d3, -0xd5c01e, -0xca0800, -0x80001a, -0xca0c00, -0xe4011e, -0xd4001e, -0x80000c, -0xc41838, -0xe4013e, -0xd4001e, -0x80000c, -0xc41838, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4011e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4013e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca1800, -0xd4401e, -0xd5801e, -0x800053, -0xd40075, -0xd4401e, -0xca0800, -0xca0c00, -0xca1000, -0xd48019, -0xd4c018, -0xd50017, -0xd4801e, -0xd4c01e, -0xd5001e, -0xe2001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0xd48060, -0xd4401e, -0x800000, -0xd4801e, -0xca0800, -0xd48061, -0xd4401e, -0x800000, -0xd4801e, -0xca0800, -0xca0c00, -0xd4401e, -0xd48016, -0xd4c016, -0xd4801e, -0x8001b8, -0xd4c01e, -0xc60843, -0xca0c00, -0xca1000, -0x948004, -0xca1400, -0xe420f3, -0xd42013, -0xd56065, -0xd4e01c, -0xd5201c, -0xd5601c, -0x800000, -0x062001, -0xc60843, -0xca0c00, -0xca1000, -0x9483f7, -0xca1400, -0xe420f3, -0x800079, -0xd42013, -0xc60843, -0xca0c00, -0xca1000, -0x9883ef, -0xca1400, -0xd40064, -0x80008d, -0x000000, -0xc41432, -0xc61843, -0xc4082f, -0x954005, -0xc40c30, -0xd4401e, -0x800000, -0xee001e, -0x9583f5, -0xc41031, -0xd44033, -0xd52065, -0xd4a01c, -0xd4e01c, -0xd5201c, -0xe4015e, -0xd4001e, -0x800000, -0x062001, -0xca1800, -0x0a2001, -0xd60076, -0xc40836, -0x988007, -0xc61045, -0x950110, -0xd4001f, -0xd46062, -0x800000, -0xd42062, -0xcc3835, -0xcc1433, -0x8401bb, -0xd40072, -0xd5401e, -0x800000, -0xee001e, -0xe2001a, -0x8401bb, -0xe2001a, -0xcc104b, -0xcc0447, -0x2c9401, -0x7d098b, -0x984005, -0x7d15cb, -0xd4001a, -0x8001b8, -0xd4006d, -0x344401, -0xcc0c48, -0x98403a, -0xcc2c4a, -0x958004, -0xcc0449, -0x8001b8, -0xd4001a, -0xd4c01a, -0x282801, -0x8400f0, -0xcc1003, -0x98801b, -0x04380c, -0x8400f0, -0xcc1003, -0x988017, -0x043808, -0x8400f0, -0xcc1003, -0x988013, -0x043804, -0x8400f0, -0xcc1003, -0x988014, -0xcc104c, -0x9a8009, -0xcc144d, -0x9840dc, -0xd4006d, -0xcc1848, -0xd5001a, -0xd5401a, -0x8000c9, -0xd5801a, -0x96c0d5, -0xd4006d, -0x8001b8, -0xd4006e, -0x9ac003, -0xd4006d, -0xd4006e, -0x800000, -0xec007f, -0x9ac0cc, -0xd4006d, -0x8001b8, -0xd4006e, -0xcc1403, -0xcc1803, -0xcc1c03, -0x7d9103, -0x7dd583, -0x7d190c, -0x35cc1f, -0x35701f, -0x7cf0cb, -0x7cd08b, -0x880000, -0x7e8e8b, -0x95c004, -0xd4006e, -0x8001b8, -0xd4001a, -0xd4c01a, -0xcc0803, -0xcc0c03, -0xcc1003, -0xcc1403, -0xcc1803, -0xcc1c03, -0xcc2403, -0xcc2803, -0x35c41f, -0x36b01f, -0x7c704b, -0x34f01f, -0x7c704b, -0x35701f, -0x7c704b, -0x7d8881, -0x7dccc1, -0x7e5101, -0x7e9541, -0x7c9082, -0x7cd4c2, -0x7c848b, -0x9ac003, -0x7c8c8b, -0x2c8801, -0x98809e, -0xd4006d, -0x98409c, -0xd4006e, -0xcc084c, -0xcc0c4d, -0xcc1048, -0xd4801a, -0xd4c01a, -0x800101, -0xd5001a, -0xcc0832, -0xd40032, -0x9482d9, -0xca0c00, -0xd4401e, -0x800000, -0xd4001e, -0xe4011e, -0xd4001e, -0xca0800, -0xca0c00, -0xca1000, -0xd4401e, -0xca1400, -0xd4801e, -0xd4c01e, -0xd5001e, -0xd5401e, -0xd54034, -0x800000, -0xee001e, -0x280404, -0xe2001a, -0xe2001a, -0xd4401a, -0xca3800, -0xcc0803, -0xcc0c03, -0xcc0c03, -0xcc0c03, -0x9882bd, -0x000000, -0x8401bb, -0xd7a06f, -0x800000, -0xee001f, -0xca0400, -0xc2ff00, -0xcc0834, -0xc13fff, -0x7c74cb, -0x7cc90b, -0x7d010f, -0x9902b0, -0x7c738b, -0x8401bb, -0xd7a06f, -0x800000, -0xee001f, -0xca0800, -0x281900, -0x7d898b, -0x958014, -0x281404, -0xca0c00, -0xca1000, -0xca1c00, -0xca2400, -0xe2001f, -0xd4c01a, -0xd5001a, -0xd5401a, -0xcc1803, -0xcc2c03, -0xcc2c03, -0xcc2c03, -0x7da58b, -0x7d9c47, -0x984297, -0x000000, -0x800161, -0xd4c01a, -0xd4401e, -0xd4801e, -0x800000, -0xee001e, -0xe4011e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4013e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0x248c06, -0x0ccc06, -0x98c006, -0xcc104e, -0x990004, -0xd40073, -0xe4011e, -0xd4001e, -0xd4401e, -0xd4801e, -0x800000, -0xee001e, -0xca0800, -0xca0c00, -0x34d018, -0x251001, -0x950021, -0xc17fff, -0xca1000, -0xca1400, -0xca1800, -0xd4801d, -0xd4c01d, -0x7db18b, -0xc14202, -0xc2c001, -0xd5801d, -0x34dc0e, -0x7d5d4c, -0x7f734c, -0xd7401e, -0xd5001e, -0xd5401e, -0xc14200, -0xc2c000, -0x099c01, -0x31dc10, -0x7f5f4c, -0x7f734c, -0x042802, -0x7d8380, -0xd5a86f, -0xd58066, -0xd7401e, -0xec005e, -0xc82402, -0xc82402, -0x8001b8, -0xd60076, -0xd4401e, -0xd4801e, -0xd4c01e, -0x800000, -0xee001e, -0x800000, -0xee001f, -0xd4001f, -0x800000, -0xd4001f, -0xd4001f, -0x880000, -0xd4001f, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x010171, -0x020178, -0x03008f, -0x04007f, -0x050003, -0x06003f, -0x070032, -0x08012c, -0x090046, -0x0a0036, -0x1001b6, -0x1700a2, -0x22013a, -0x230149, -0x2000b4, -0x240125, -0x27004d, -0x28006a, -0x2a0060, -0x2b0052, -0x2f0065, -0x320087, -0x34017f, -0x3c0156, -0x3f0072, -0x41018c, -0x44012e, -0x550173, -0x56017a, -0x60000b, -0x610034, -0x620038, -0x630038, -0x640038, -0x650038, -0x660038, -0x670038, -0x68003a, -0x690041, -0x6a0048, -0x6b0048, -0x6c0048, -0x6d0048, -0x6e0048, -0x6f0048, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -}; - -static const u32 RV620_cp_microcode[][3] = { - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0000ffff, 0x00284621, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00000000, 0x00e00000, 0x000 }, - { 0x00010000, 0xc0294620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x00000000, 0x00600000, 0x631 }, - { 0x00000000, 0x00600000, 0x645 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000f00, 0x00281622, 0x000 }, - { 0x00000008, 0x00211625, 0x000 }, - { 0x00000018, 0x00203625, 0x000 }, - { 0x8d000000, 0x00204411, 0x000 }, - { 0x00000004, 0x002f0225, 0x000 }, - { 0x00000000, 0x0ce00000, 0x018 }, - { 0x00412000, 0x00404811, 0x019 }, - { 0x00422000, 0x00204811, 0x000 }, - { 0x8e000000, 0x00204411, 0x000 }, - { 0x00000028, 0x00204a2d, 0x000 }, - { 0x90000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x0000000c, 0x00211622, 0x000 }, - { 0x00000003, 0x00281625, 0x000 }, - { 0x00000019, 0x00211a22, 0x000 }, - { 0x00000004, 0x00281a26, 0x000 }, - { 0x00000000, 0x002914c5, 0x000 }, - { 0x00000019, 0x00203625, 0x000 }, - { 0x00000000, 0x003a1402, 0x000 }, - { 0x00000016, 0x00211625, 0x000 }, - { 0x00000003, 0x00281625, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0xfffffffc, 0x00280e23, 0x000 }, - { 0x00000000, 0x002914a3, 0x000 }, - { 0x00000017, 0x00203625, 0x000 }, - { 0x00008000, 0x00280e22, 0x000 }, - { 0x00000007, 0x00220e23, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x20000000, 0x00280e22, 0x000 }, - { 0x00000006, 0x00210e23, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x00000000, 0x00220222, 0x000 }, - { 0x00000000, 0x14e00000, 0x038 }, - { 0x00000000, 0x2ee00000, 0x035 }, - { 0x00000000, 0x2ce00000, 0x037 }, - { 0x00000000, 0x00400e2d, 0x039 }, - { 0x00000008, 0x00200e2d, 0x000 }, - { 0x00000009, 0x0040122d, 0x046 }, - { 0x00000001, 0x00400e2d, 0x039 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x003ffffc, 0x00281223, 0x000 }, - { 0x00000002, 0x00221224, 0x000 }, - { 0x0000001f, 0x00211e23, 0x000 }, - { 0x00000000, 0x14e00000, 0x03e }, - { 0x00000008, 0x00401c11, 0x041 }, - { 0x0000000d, 0x00201e2d, 0x000 }, - { 0x0000000f, 0x00281e27, 0x000 }, - { 0x00000003, 0x00221e27, 0x000 }, - { 0x7fc00000, 0x00281a23, 0x000 }, - { 0x00000014, 0x00211a26, 0x000 }, - { 0x00000001, 0x00331a26, 0x000 }, - { 0x00000008, 0x00221a26, 0x000 }, - { 0x00000000, 0x00290cc7, 0x000 }, - { 0x00000027, 0x00203624, 0x000 }, - { 0x00007f00, 0x00281221, 0x000 }, - { 0x00001400, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x04b }, - { 0x00000001, 0x00290e23, 0x000 }, - { 0x0000000e, 0x00203623, 0x000 }, - { 0x0000e000, 0x00204411, 0x000 }, - { 0xfff80000, 0x00294a23, 0x000 }, - { 0x00000000, 0x003a2c02, 0x000 }, - { 0x00000002, 0x00220e2b, 0x000 }, - { 0xfc000000, 0x00280e23, 0x000 }, - { 0x0000000f, 0x00203623, 0x000 }, - { 0x00001fff, 0x00294a23, 0x000 }, - { 0x00000027, 0x00204a2d, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000029, 0x00200e2d, 0x000 }, - { 0x060a0200, 0x00294a23, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14e00000, 0x061 }, - { 0x00000000, 0x2ee00000, 0x05f }, - { 0x00000000, 0x2ce00000, 0x05e }, - { 0x00000000, 0x00400e2d, 0x062 }, - { 0x00000001, 0x00400e2d, 0x062 }, - { 0x0000000a, 0x00200e2d, 0x000 }, - { 0x0000000b, 0x0040122d, 0x06a }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x003ffffc, 0x00281223, 0x000 }, - { 0x00000002, 0x00221224, 0x000 }, - { 0x7fc00000, 0x00281623, 0x000 }, - { 0x00000014, 0x00211625, 0x000 }, - { 0x00000001, 0x00331625, 0x000 }, - { 0x80000000, 0x00280e23, 0x000 }, - { 0x00000000, 0x00290ca3, 0x000 }, - { 0x3ffffc00, 0x00290e23, 0x000 }, - { 0x0000001f, 0x00211e23, 0x000 }, - { 0x00000000, 0x14e00000, 0x06d }, - { 0x00000100, 0x00401c11, 0x070 }, - { 0x0000000d, 0x00201e2d, 0x000 }, - { 0x000000f0, 0x00281e27, 0x000 }, - { 0x00000004, 0x00221e27, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0xfffff0ff, 0x00281a30, 0x000 }, - { 0x0000a028, 0x00204411, 0x000 }, - { 0x00000000, 0x002948e6, 0x000 }, - { 0x0000a018, 0x00204411, 0x000 }, - { 0x3fffffff, 0x00284a23, 0x000 }, - { 0x0000a010, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000030, 0x0020162d, 0x000 }, - { 0x00000002, 0x00291625, 0x000 }, - { 0x00000030, 0x00203625, 0x000 }, - { 0x00000025, 0x0020162d, 0x000 }, - { 0x00000000, 0x002f00a3, 0x000 }, - { 0x00000000, 0x0cc00000, 0x083 }, - { 0x00000026, 0x0020162d, 0x000 }, - { 0x00000000, 0x002f00a4, 0x000 }, - { 0x00000000, 0x0cc00000, 0x084 }, - { 0x00000000, 0x00400000, 0x08a }, - { 0x00000025, 0x00203623, 0x000 }, - { 0x00000026, 0x00203624, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x08a }, - { 0x00000000, 0x00600000, 0x668 }, - { 0x00000000, 0x00600000, 0x65c }, - { 0x00000002, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x08d }, - { 0x00000012, 0xc0403620, 0x093 }, - { 0x00000000, 0x2ee00000, 0x091 }, - { 0x00000000, 0x2ce00000, 0x090 }, - { 0x00000002, 0x00400e2d, 0x092 }, - { 0x00000003, 0x00400e2d, 0x092 }, - { 0x0000000c, 0x00200e2d, 0x000 }, - { 0x00000012, 0x00203623, 0x000 }, - { 0x00000003, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x098 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x0a0 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x2ee00000, 0x09e }, - { 0x00000000, 0x2ce00000, 0x09d }, - { 0x00000002, 0x00400e2d, 0x09f }, - { 0x00000003, 0x00400e2d, 0x09f }, - { 0x0000000c, 0x00200e2d, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000000, 0x003a0c02, 0x000 }, - { 0x003f0000, 0x00280e23, 0x000 }, - { 0x00000010, 0x00210e23, 0x000 }, - { 0x00000011, 0x00203623, 0x000 }, - { 0x0000001e, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0a7 }, - { 0x00000016, 0xc0203620, 0x000 }, - { 0x0000001f, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0aa }, - { 0x00000015, 0xc0203620, 0x000 }, - { 0x00000008, 0x00210e2b, 0x000 }, - { 0x0000007f, 0x00280e23, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0e1 }, - { 0x00000000, 0x27000000, 0x000 }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0b3 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x0000000c, 0x00221e30, 0x000 }, - { 0x99800000, 0x00204411, 0x000 }, - { 0x00000004, 0x0020122d, 0x000 }, - { 0x00000008, 0x00221224, 0x000 }, - { 0x00000010, 0x00201811, 0x000 }, - { 0x00000000, 0x00291ce4, 0x000 }, - { 0x00000000, 0x00604807, 0x12f }, - { 0x9b000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x9c000000, 0x00204411, 0x000 }, - { 0x00000000, 0x0033146f, 0x000 }, - { 0x00000001, 0x00333e23, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0x00203c05, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x00000000, 0x00201010, 0x000 }, - { 0x0000e007, 0x00204411, 0x000 }, - { 0x0000000f, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0cb }, - { 0x00f8ff08, 0x00204811, 0x000 }, - { 0x98000000, 0x00404811, 0x0dc }, - { 0x000000f0, 0x00280e22, 0x000 }, - { 0x000000a0, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x0da }, - { 0x00000011, 0x00200e2d, 0x000 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0d5 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0d4 }, - { 0x00003f00, 0x00400c11, 0x0d6 }, - { 0x00001f00, 0x00400c11, 0x0d6 }, - { 0x00000f00, 0x00200c11, 0x000 }, - { 0x00380009, 0x00294a23, 0x000 }, - { 0x3f000000, 0x00280e2b, 0x000 }, - { 0x00000002, 0x00220e23, 0x000 }, - { 0x00000007, 0x00494a23, 0x0dc }, - { 0x00380f09, 0x00204811, 0x000 }, - { 0x68000007, 0x00204811, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a24, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000a202, 0x00204411, 0x000 }, - { 0x00ff0000, 0x00280e22, 0x000 }, - { 0x00000080, 0x00294a23, 0x000 }, - { 0x00000027, 0x00200e2d, 0x000 }, - { 0x00000026, 0x0020122d, 0x000 }, - { 0x00000000, 0x002f0083, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0ea }, - { 0x00000000, 0x00600000, 0x662 }, - { 0x00000000, 0x00400000, 0x0eb }, - { 0x00000000, 0x00600000, 0x665 }, - { 0x00000007, 0x0020222d, 0x000 }, - { 0x00000005, 0x00220e22, 0x000 }, - { 0x00100000, 0x00280e23, 0x000 }, - { 0x00000000, 0x00292068, 0x000 }, - { 0x00000000, 0x003a0c02, 0x000 }, - { 0x000000ef, 0x00280e23, 0x000 }, - { 0x00000000, 0x00292068, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0x00000003, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x0f8 }, - { 0x0000000b, 0x00210228, 0x000 }, - { 0x00000000, 0x14c00000, 0x0f8 }, - { 0x00000400, 0x00292228, 0x000 }, - { 0x00000014, 0x00203628, 0x000 }, - { 0x0000001c, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x0fd }, - { 0x0000a30c, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000001e, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x10b }, - { 0x0000a30f, 0x00204411, 0x000 }, - { 0x00000011, 0x00200e2d, 0x000 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x104 }, - { 0xffffffff, 0x00404811, 0x10b }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x107 }, - { 0x0000ffff, 0x00404811, 0x10b }, - { 0x00000004, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x10a }, - { 0x000000ff, 0x00404811, 0x10b }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0002c400, 0x00204411, 0x000 }, - { 0x0000001f, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x112 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x00000013, 0x00203623, 0x000 }, - { 0x00000018, 0x40224a20, 0x000 }, - { 0x00000010, 0xc0424a20, 0x114 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x00000013, 0x00203623, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000000a, 0x00201011, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x11b }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00531224, 0x117 }, - { 0xffbfffff, 0x00283a2e, 0x000 }, - { 0x0000001b, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x12e }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0x00000018, 0x00220e30, 0x000 }, - { 0xfc000000, 0x00280e23, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x00000000, 0x00201010, 0x000 }, - { 0x0000e00e, 0x00204411, 0x000 }, - { 0x07f8ff08, 0x00204811, 0x000 }, - { 0x00000000, 0x00294a23, 0x000 }, - { 0x0000001c, 0x00201e2d, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a24, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x00800000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204806, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x68d }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x68c }, - { 0x00000004, 0x00404c11, 0x135 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x0000001c, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68d }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x13c }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00000000, 0x00600000, 0x160 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000ffff, 0x40280620, 0x000 }, - { 0x00000010, 0xc0210a20, 0x000 }, - { 0x00000000, 0x00341461, 0x000 }, - { 0x00000000, 0x00741882, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x147 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x160 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x00000010, 0x40211620, 0x000 }, - { 0x0000ffff, 0xc0681a20, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x158 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000001, 0x00300a2f, 0x000 }, - { 0x00000001, 0x00210a22, 0x000 }, - { 0x00000003, 0x00384a22, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001a, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600000, 0x18f }, - { 0x00000000, 0x00600000, 0x1a0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00202c08, 0x000 }, - { 0x00000000, 0x00202411, 0x000 }, - { 0x00000000, 0x00202811, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000002, 0x00221e29, 0x000 }, - { 0x00000000, 0x007048eb, 0x19c }, - { 0x00000000, 0x00600000, 0x2bb }, - { 0x00000001, 0x40330620, 0x000 }, - { 0x00000000, 0xc0302409, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ae00000, 0x181 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x00000000, 0x00400000, 0x186 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x186 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000001, 0x00530621, 0x182 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0604800, 0x197 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000011, 0x0020062d, 0x000 }, - { 0x00000000, 0x0078042a, 0x2fb }, - { 0x00000000, 0x00202809, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x174 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000210, 0x00600411, 0x315 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x194 }, - { 0x00000015, 0xc0203620, 0x000 }, - { 0x00000016, 0xc0203620, 0x000 }, - { 0x3f800000, 0x00200411, 0x000 }, - { 0x46000000, 0x00600811, 0x1b2 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x19b }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000021, 0x00804811, 0x000 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000ffff, 0x40281620, 0x000 }, - { 0x00000010, 0xc0811a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000008, 0x00221e30, 0x000 }, - { 0x00000029, 0x00201a2d, 0x000 }, - { 0x0000e000, 0x00204411, 0x000 }, - { 0xfffbff09, 0x00204811, 0x000 }, - { 0x0000000f, 0x0020222d, 0x000 }, - { 0x00001fff, 0x00294a28, 0x000 }, - { 0x00000006, 0x0020222d, 0x000 }, - { 0x00000000, 0x002920e8, 0x000 }, - { 0x00000000, 0x00204808, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a26, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000100, 0x00201811, 0x000 }, - { 0x00000008, 0x00621e28, 0x12f }, - { 0x00000008, 0x00822228, 0x000 }, - { 0x0002c000, 0x00204411, 0x000 }, - { 0x00000015, 0x00600e2d, 0x1bd }, - { 0x00000016, 0x00600e2d, 0x1bd }, - { 0x0000c008, 0x00204411, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0x00000000, 0x14c00000, 0x1b9 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0x39000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00804802, 0x000 }, - { 0x00000018, 0x00202e2d, 0x000 }, - { 0x00000000, 0x003b0d63, 0x000 }, - { 0x00000008, 0x00224a23, 0x000 }, - { 0x00000010, 0x00224a23, 0x000 }, - { 0x00000018, 0x00224a23, 0x000 }, - { 0x00000000, 0x00804803, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00001000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00000007, 0x0021062f, 0x000 }, - { 0x00000013, 0x00200a2d, 0x000 }, - { 0x00000001, 0x00202c11, 0x000 }, - { 0x0000ffff, 0x40282220, 0x000 }, - { 0x0000000f, 0x00262228, 0x000 }, - { 0x00000010, 0x40212620, 0x000 }, - { 0x0000000f, 0x00262629, 0x000 }, - { 0x00000000, 0x00202802, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001b, 0x00204811, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1e0 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000081, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000080, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1dc }, - { 0x00000000, 0x00600000, 0x1e9 }, - { 0x00000001, 0x00531e27, 0x1d8 }, - { 0x00000001, 0x00202c11, 0x000 }, - { 0x0000001f, 0x00280a22, 0x000 }, - { 0x0000001f, 0x00282a2a, 0x000 }, - { 0x00000001, 0x00530621, 0x1d1 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000002, 0x00304a2f, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000001, 0x00301e2f, 0x000 }, - { 0x00000000, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x1e9 }, - { 0x00000001, 0x00531e27, 0x1e5 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x0000000f, 0x00260e23, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000000f, 0x00261224, 0x000 }, - { 0x00000000, 0x00201411, 0x000 }, - { 0x00000000, 0x00601811, 0x2bb }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022b, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1f8 }, - { 0x00000010, 0x00221628, 0x000 }, - { 0xffff0000, 0x00281625, 0x000 }, - { 0x0000ffff, 0x00281a29, 0x000 }, - { 0x00000000, 0x002948c5, 0x000 }, - { 0x00000000, 0x0020480a, 0x000 }, - { 0x00000000, 0x00202c11, 0x000 }, - { 0x00000010, 0x00221623, 0x000 }, - { 0xffff0000, 0x00281625, 0x000 }, - { 0x0000ffff, 0x00281a24, 0x000 }, - { 0x00000000, 0x002948c5, 0x000 }, - { 0x00000000, 0x00731503, 0x205 }, - { 0x00000000, 0x00201805, 0x000 }, - { 0x00000000, 0x00731524, 0x205 }, - { 0x00000000, 0x002d14c5, 0x000 }, - { 0x00000000, 0x003008a2, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00202802, 0x000 }, - { 0x00000000, 0x00202003, 0x000 }, - { 0x00000000, 0x00802404, 0x000 }, - { 0x0000000f, 0x00210225, 0x000 }, - { 0x00000000, 0x14c00000, 0x68c }, - { 0x00000000, 0x002b1405, 0x000 }, - { 0x00000001, 0x00901625, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001a, 0x00294a22, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00384a21, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000ffff, 0x40281220, 0x000 }, - { 0x00000010, 0xc0211a20, 0x000 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211620, 0x000 }, - { 0x00000000, 0x00741465, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00000001, 0x00330621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0cc00000, 0x219 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x212 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x645 }, - { 0x00000000, 0x0040040f, 0x213 }, - { 0x00000000, 0x00600000, 0x631 }, - { 0x00000000, 0x00600000, 0x645 }, - { 0x00000210, 0x00600411, 0x315 }, - { 0x00000000, 0x00600000, 0x1a0 }, - { 0x00000000, 0x00600000, 0x19c }, - { 0x00000000, 0x00600000, 0x2bb }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204808, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ae00000, 0x232 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x00000000, 0x00400000, 0x236 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x236 }, - { 0x00000000, 0xc0404800, 0x233 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x00600411, 0x2fb }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x631 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000018, 0x40210a20, 0x000 }, - { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x24c }, - { 0x00000014, 0x0020222d, 0x000 }, - { 0x00080101, 0x00292228, 0x000 }, - { 0x00000014, 0x00203628, 0x000 }, - { 0x0000a30c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x251 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000010, 0x00600411, 0x315 }, - { 0x3f800000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x00000000, 0x00600000, 0x27c }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000001, 0x00211e27, 0x000 }, - { 0x00000000, 0x14e00000, 0x26a }, - { 0x00000012, 0x00201e2d, 0x000 }, - { 0x0000ffff, 0x00281e27, 0x000 }, - { 0x00000000, 0x00341c27, 0x000 }, - { 0x00000000, 0x12c00000, 0x25f }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f00e5, 0x000 }, - { 0x00000000, 0x08c00000, 0x262 }, - { 0x00000000, 0x00201407, 0x000 }, - { 0x00000012, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00211e27, 0x000 }, - { 0x00000000, 0x00341c47, 0x000 }, - { 0x00000000, 0x12c00000, 0x267 }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f00e6, 0x000 }, - { 0x00000000, 0x08c00000, 0x26a }, - { 0x00000000, 0x00201807, 0x000 }, - { 0x00000000, 0x00600000, 0x2c1 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000000, 0x00342023, 0x000 }, - { 0x00000000, 0x12c00000, 0x272 }, - { 0x00000000, 0x00342044, 0x000 }, - { 0x00000000, 0x12c00000, 0x271 }, - { 0x00000016, 0x00404811, 0x276 }, - { 0x00000018, 0x00404811, 0x276 }, - { 0x00000000, 0x00342044, 0x000 }, - { 0x00000000, 0x12c00000, 0x275 }, - { 0x00000017, 0x00404811, 0x276 }, - { 0x00000019, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0x00604411, 0x2e9 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x256 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000010, 0x40210620, 0x000 }, - { 0x0000ffff, 0xc0280a20, 0x000 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x00000010, 0x40211620, 0x000 }, - { 0x0000ffff, 0xc0881a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x00000000, 0x00600000, 0x631 }, - { 0x00000000, 0xc0600000, 0x2a3 }, - { 0x00000005, 0x00200a2d, 0x000 }, - { 0x00000008, 0x00220a22, 0x000 }, - { 0x0000002b, 0x00201a2d, 0x000 }, - { 0x0000001c, 0x00201e2d, 0x000 }, - { 0x00007000, 0x00281e27, 0x000 }, - { 0x00000000, 0x00311ce6, 0x000 }, - { 0x0000002a, 0x00201a2d, 0x000 }, - { 0x0000000c, 0x00221a26, 0x000 }, - { 0x00000000, 0x002f00e6, 0x000 }, - { 0x00000000, 0x06e00000, 0x292 }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x0000002b, 0x00203623, 0x000 }, - { 0x00000010, 0x00201811, 0x000 }, - { 0x00000000, 0x00691ce2, 0x12f }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x29d }, - { 0x00000001, 0x00333e2f, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000001c, 0x00403627, 0x000 }, - { 0x0000000c, 0xc0220a20, 0x000 }, - { 0x00000029, 0x00203622, 0x000 }, - { 0x00000028, 0xc0403620, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000009, 0x00204811, 0x000 }, - { 0xa1000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002c1ce3, 0x000 }, - { 0x00000021, 0x00203627, 0x000 }, - { 0x00000022, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002c1ce4, 0x000 }, - { 0x00000022, 0x00203627, 0x000 }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120a3, 0x000 }, - { 0x00000000, 0x002d1d07, 0x000 }, - { 0x00000023, 0x00203627, 0x000 }, - { 0x00000024, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x00000000, 0x002d1d07, 0x000 }, - { 0x00000024, 0x00803627, 0x000 }, - { 0x00000021, 0x00203623, 0x000 }, - { 0x00000022, 0x00203624, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000023, 0x00203627, 0x000 }, - { 0x00000000, 0x00311cc4, 0x000 }, - { 0x00000024, 0x00803627, 0x000 }, - { 0x0000001a, 0x00203627, 0x000 }, - { 0x0000001b, 0x00203628, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14c00000, 0x2dc }, - { 0x00000000, 0x00400000, 0x2d9 }, - { 0x0000001a, 0x00203627, 0x000 }, - { 0x0000001b, 0x00203628, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x2d9 }, - { 0x00000003, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x2dc }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002e00e1, 0x000 }, - { 0x00000000, 0x02c00000, 0x2dc }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120a1, 0x000 }, - { 0x00000000, 0x002e00e8, 0x000 }, - { 0x00000000, 0x06c00000, 0x2dc }, - { 0x00000024, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002e00e2, 0x000 }, - { 0x00000000, 0x02c00000, 0x2dc }, - { 0x00000022, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120c2, 0x000 }, - { 0x00000000, 0x002e00e8, 0x000 }, - { 0x00000000, 0x06c00000, 0x2dc }, - { 0x00000000, 0x00600000, 0x668 }, - { 0x00000000, 0x00600000, 0x2b5 }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x00000000, 0x00600000, 0x2b5 }, - { 0x00000000, 0x00600000, 0x65f }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x00000000, 0x00600000, 0x2a7 }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x0000001a, 0x00201e2d, 0x000 }, - { 0x0000001b, 0x0080222d, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000010, 0x00221e21, 0x000 }, - { 0x00000000, 0x00294847, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000000, 0x00311ca1, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294847, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000010, 0x00221e21, 0x000 }, - { 0x00000000, 0x003120c2, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000001, 0x00220a21, 0x000 }, - { 0x00000000, 0x003308a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000001, 0x00220a21, 0x000 }, - { 0x00000000, 0x003008a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x003808c5, 0x000 }, - { 0x00000000, 0x00300841, 0x000 }, - { 0x00000001, 0x00220a22, 0x000 }, - { 0x00000000, 0x003308a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000017, 0x0020222d, 0x000 }, - { 0x00000000, 0x14c00000, 0x318 }, - { 0xffffffef, 0x00280621, 0x000 }, - { 0x00000014, 0x0020222d, 0x000 }, - { 0x0000f8e0, 0x00204411, 0x000 }, - { 0x00000000, 0x00294901, 0x000 }, - { 0x00000000, 0x00894901, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00804811, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x97000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00002257, 0x00204411, 0x000 }, - { 0x00000003, 0xc0484a20, 0x000 }, - { 0x0000225d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0x00600000, 0x645 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00384a22, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x40204800, 0x000 }, - { 0x00000001, 0x40304a20, 0x000 }, - { 0x00000002, 0xc0304a20, 0x000 }, - { 0x00000001, 0x00530a22, 0x34b }, - { 0x0000003f, 0xc0280a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000018, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68d }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x354 }, - { 0x00000014, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x364 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00604802, 0x36e }, - { 0x00002100, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x36a }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x35f }, - { 0x00000028, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5c0 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x35f }, - { 0x0000002c, 0x00203626, 0x000 }, - { 0x00000049, 0x00201811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x00000001, 0x00331a26, 0x000 }, - { 0x00000000, 0x002f0226, 0x000 }, - { 0x00000000, 0x0cc00000, 0x370 }, - { 0x0000002c, 0x00801a2d, 0x000 }, - { 0x0000003f, 0xc0280a20, 0x000 }, - { 0x00000015, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x386 }, - { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3b1 }, - { 0x00000016, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3b5 }, - { 0x00000020, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x39c }, - { 0x0000000f, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3a8 }, - { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3a8 }, - { 0x0000001e, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x390 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x08000000, 0x00290a22, 0x000 }, - { 0x00000003, 0x40210e20, 0x000 }, - { 0x0000000c, 0xc0211220, 0x000 }, - { 0x00080000, 0x00281224, 0x000 }, - { 0x00000014, 0xc0221620, 0x000 }, - { 0x00000000, 0x002914a4, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x002948a2, 0x000 }, - { 0x0000a1fe, 0x00204411, 0x000 }, - { 0x00000000, 0x00404803, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68d }, - { 0x00000015, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x392 }, - { 0x0000210e, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000017, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68d }, - { 0x00000003, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x39e }, - { 0x00002108, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x80000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000010, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x3ae }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000006, 0x00404811, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36e }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x0000001d, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x3ce }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000018, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68d }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x3c0 }, - { 0x00002100, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0xbabecafe, 0x00204811, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000004, 0x00404811, 0x000 }, - { 0x00002170, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000a, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x3d3 }, - { 0x8c000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00003fff, 0x40280a20, 0x000 }, - { 0x80000000, 0x40280e20, 0x000 }, - { 0x40000000, 0xc0281220, 0x000 }, - { 0x00040000, 0x00694622, 0x68d }, - { 0x00000000, 0x00201410, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x3e1 }, - { 0x00000000, 0xc0401800, 0x3e4 }, - { 0x00003fff, 0xc0281a20, 0x000 }, - { 0x00040000, 0x00694626, 0x68d }, - { 0x00000000, 0x00201810, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x3e7 }, - { 0x00000000, 0xc0401c00, 0x3ea }, - { 0x00003fff, 0xc0281e20, 0x000 }, - { 0x00040000, 0x00694627, 0x68d }, - { 0x00000000, 0x00201c10, 0x000 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0x002820c5, 0x000 }, - { 0x00000000, 0x004948e8, 0x000 }, - { 0xa5800000, 0x00200811, 0x000 }, - { 0x00002000, 0x00200c11, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x40204800, 0x000 }, - { 0x0000001f, 0xc0210220, 0x000 }, - { 0x00000000, 0x14c00000, 0x3f7 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0000ffff, 0xc0481220, 0x3ff }, - { 0xa7800000, 0x00200811, 0x000 }, - { 0x0000a000, 0x00200c11, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x83000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00304883, 0x000 }, - { 0x84000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1d000000, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0xa9800000, 0x00200811, 0x000 }, - { 0x0000c000, 0x00400c11, 0x3fa }, - { 0xab800000, 0x00200811, 0x000 }, - { 0x0000f8e0, 0x00400c11, 0x3fa }, - { 0xad800000, 0x00200811, 0x000 }, - { 0x0000f880, 0x00400c11, 0x3fa }, - { 0xb3800000, 0x00200811, 0x000 }, - { 0x0000f3fc, 0x00400c11, 0x3fa }, - { 0xaf800000, 0x00200811, 0x000 }, - { 0x0000e000, 0x00400c11, 0x3fa }, - { 0xb1800000, 0x00200811, 0x000 }, - { 0x0000f000, 0x00400c11, 0x3fa }, - { 0x83000000, 0x00204411, 0x000 }, - { 0x00002148, 0x00204811, 0x000 }, - { 0x84000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1d000000, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x01182000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0218a000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0318c000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0418f8e0, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0518f880, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0618e000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0718f000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0818f3fc, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00000030, 0x00200a2d, 0x000 }, - { 0x00000000, 0xc0290c40, 0x000 }, - { 0x00000030, 0x00203623, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x86000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00404801, 0x000 }, - { 0x85000000, 0xc0204411, 0x000 }, - { 0x00000000, 0x00404801, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x00000018, 0x40210220, 0x000 }, - { 0x00000000, 0x14c00000, 0x445 }, - { 0x00800000, 0xc0494a20, 0x446 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x68d }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000000, 0x00404c02, 0x44b }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x00000000, 0xc0201000, 0x000 }, - { 0x00000000, 0xc0201400, 0x000 }, - { 0x00000000, 0xc0201800, 0x000 }, - { 0x00000000, 0xc0201c00, 0x000 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x459 }, - { 0x00000000, 0xc0202000, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x00000010, 0x00280a23, 0x000 }, - { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x461 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0x00694624, 0x68d }, - { 0x00000000, 0x00400000, 0x466 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x00604805, 0x692 }, - { 0x00000000, 0x002824f0, 0x000 }, - { 0x00000007, 0x00280a23, 0x000 }, - { 0x00000001, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x46d }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x04e00000, 0x486 }, - { 0x00000000, 0x00400000, 0x493 }, - { 0x00000002, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x472 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x02e00000, 0x486 }, - { 0x00000000, 0x00400000, 0x493 }, - { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x477 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x0ce00000, 0x486 }, - { 0x00000000, 0x00400000, 0x493 }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x47c }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x0ae00000, 0x486 }, - { 0x00000000, 0x00400000, 0x493 }, - { 0x00000005, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x481 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x06e00000, 0x486 }, - { 0x00000000, 0x00400000, 0x493 }, - { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x486 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x08e00000, 0x486 }, - { 0x00000000, 0x00400000, 0x493 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x000 }, - { 0x00000008, 0x00210a23, 0x000 }, - { 0x00000000, 0x14c00000, 0x490 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x00000000, 0xc0204400, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x499 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x00404c08, 0x459 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x00000011, 0x40211220, 0x000 }, - { 0x00000012, 0x40211620, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00210225, 0x000 }, - { 0x00000000, 0x14e00000, 0x4a3 }, - { 0x00040000, 0xc0494a20, 0x4a4 }, - { 0xfffbffff, 0xc0284a20, 0x000 }, - { 0x00000000, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x4b0 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000c, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x4ac }, - { 0xa0000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000004, 0x00204811, 0x000 }, - { 0x0000216b, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204810, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000005, 0x00204811, 0x000 }, - { 0x0000216c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204810, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00400000, 0x4aa }, - { 0x00000000, 0xc0210a20, 0x000 }, - { 0x00000000, 0x14c00000, 0x4c3 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0604800, 0x692 }, - { 0x00000000, 0x00400000, 0x4c7 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0xc0294620, 0x000 }, - { 0x00000000, 0xc0600000, 0x68d }, - { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x4ce }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x00000000, 0xc0204400, 0x000 }, - { 0x00000000, 0xc0404810, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68d }, - { 0x00000000, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x4d0 }, - { 0x00002180, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000003, 0x00333e2f, 0x000 }, - { 0x00000001, 0x00210221, 0x000 }, - { 0x00000000, 0x14e00000, 0x500 }, - { 0x0000002c, 0x00200a2d, 0x000 }, - { 0x00040000, 0x18e00c11, 0x4ef }, - { 0x00000001, 0x00333e2f, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xd8c04800, 0x4e3 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000002d, 0x0020122d, 0x000 }, - { 0x00000000, 0x00290c83, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000011, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000000, 0x00400000, 0x4aa }, - { 0x0000002c, 0xc0203620, 0x000 }, - { 0x0000002d, 0xc0403620, 0x000 }, - { 0x0000000f, 0x00210221, 0x000 }, - { 0x00000000, 0x14c00000, 0x505 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0xd9000000, 0x000 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0xb5000000, 0x00204411, 0x000 }, - { 0x00002000, 0x00204811, 0x000 }, - { 0xb6000000, 0x00204411, 0x000 }, - { 0x0000a000, 0x00204811, 0x000 }, - { 0xb7000000, 0x00204411, 0x000 }, - { 0x0000c000, 0x00204811, 0x000 }, - { 0xb8000000, 0x00204411, 0x000 }, - { 0x0000f8e0, 0x00204811, 0x000 }, - { 0xb9000000, 0x00204411, 0x000 }, - { 0x0000f880, 0x00204811, 0x000 }, - { 0xba000000, 0x00204411, 0x000 }, - { 0x0000e000, 0x00204811, 0x000 }, - { 0xbb000000, 0x00204411, 0x000 }, - { 0x0000f000, 0x00204811, 0x000 }, - { 0xbc000000, 0x00204411, 0x000 }, - { 0x0000f3fc, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000002, 0x00204811, 0x000 }, - { 0x000000ff, 0x00280e30, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x519 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0x14c00000, 0x52e }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x0000001c, 0x00203623, 0x000 }, - { 0x0000002b, 0x00203623, 0x000 }, - { 0x00000029, 0x00203623, 0x000 }, - { 0x00000028, 0x00203623, 0x000 }, - { 0x00000017, 0x00203623, 0x000 }, - { 0x00000025, 0x00203623, 0x000 }, - { 0x00000026, 0x00203623, 0x000 }, - { 0x00000015, 0x00203623, 0x000 }, - { 0x00000016, 0x00203623, 0x000 }, - { 0xffffe000, 0x00200c11, 0x000 }, - { 0x00000021, 0x00203623, 0x000 }, - { 0x00000022, 0x00203623, 0x000 }, - { 0x00001fff, 0x00200c11, 0x000 }, - { 0x00000023, 0x00203623, 0x000 }, - { 0x00000024, 0x00203623, 0x000 }, - { 0xf1ffffff, 0x00283a2e, 0x000 }, - { 0x0000001a, 0xc0220e20, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x0000002a, 0x40203620, 0x000 }, - { 0x87000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1f4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x00000030, 0x00203623, 0x000 }, - { 0x9d000000, 0x00204411, 0x000 }, - { 0x0000001f, 0x40214a20, 0x000 }, - { 0x96000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x00000000, 0xc0201000, 0x000 }, - { 0x0000001f, 0x00211624, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x0000001d, 0x00203623, 0x000 }, - { 0x00000003, 0x00281e23, 0x000 }, - { 0x00000008, 0x00222223, 0x000 }, - { 0xfffff000, 0x00282228, 0x000 }, - { 0x00000000, 0x002920e8, 0x000 }, - { 0x0000001f, 0x00203628, 0x000 }, - { 0x00000018, 0x00211e23, 0x000 }, - { 0x00000020, 0x00203627, 0x000 }, - { 0x00000002, 0x00221624, 0x000 }, - { 0x00000000, 0x003014a8, 0x000 }, - { 0x0000001e, 0x00203625, 0x000 }, - { 0x00000003, 0x00211a24, 0x000 }, - { 0x10000000, 0x00281a26, 0x000 }, - { 0xefffffff, 0x00283a2e, 0x000 }, - { 0x00000000, 0x004938ce, 0x67b }, - { 0x00000001, 0x40280a20, 0x000 }, - { 0x00000006, 0x40280e20, 0x000 }, - { 0x00000300, 0xc0281220, 0x000 }, - { 0x00000008, 0x00211224, 0x000 }, - { 0x00000000, 0xc0201620, 0x000 }, - { 0x00000000, 0xc0201a20, 0x000 }, - { 0x00000000, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x566 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00002258, 0x00300a24, 0x000 }, - { 0x00040000, 0x00694622, 0x68d }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00020000, 0x00294a26, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x56e }, - { 0x00000000, 0xc0201c10, 0x000 }, - { 0x00000000, 0xc0400000, 0x57c }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x56e }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00002258, 0x00300a24, 0x000 }, - { 0x00040000, 0x00694622, 0x68d }, - { 0x00000000, 0xc0201c10, 0x000 }, - { 0x00000000, 0xc0400000, 0x57c }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x572 }, - { 0x00000000, 0xc0201c00, 0x000 }, - { 0x00000000, 0xc0400000, 0x57c }, - { 0x00000004, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x57a }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0604800, 0x692 }, - { 0x00000000, 0x00401c10, 0x57c }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x0ee00000, 0x57e }, - { 0x00000000, 0x00600000, 0x5c9 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x58f }, - { 0x0000a2b7, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2b6, 0x00604411, 0x68d }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x0000a2c4, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x58d }, - { 0x0000a2d1, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d1, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x00000001, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5a0 }, - { 0x0000a2bb, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2ba, 0x00604411, 0x68d }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x0000a2c5, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x59e }, - { 0x0000a2d2, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d2, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x00000002, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5b1 }, - { 0x0000a2bf, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2be, 0x00604411, 0x68d }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x0000a2c6, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x5af }, - { 0x0000a2d3, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d3, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x0000a2c3, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2c2, 0x00604411, 0x68d }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x0000a2c7, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x5be }, - { 0x0000a2d4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d4, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x85000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0x0000304a, 0x00204411, 0x000 }, - { 0x01000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00400000, 0x5c4 }, - { 0xa4000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0xc0600000, 0x5c9 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000002c, 0x00203621, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000000, 0x002f0230, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5d0 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000030, 0x00403621, 0x5e3 }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00007e00, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x5e3 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a092, 0x00604411, 0x68d }, - { 0x00000031, 0x00203630, 0x000 }, - { 0x0004a093, 0x00604411, 0x68d }, - { 0x00000032, 0x00203630, 0x000 }, - { 0x0004a2b6, 0x00604411, 0x68d }, - { 0x00000033, 0x00203630, 0x000 }, - { 0x0004a2ba, 0x00604411, 0x68d }, - { 0x00000034, 0x00203630, 0x000 }, - { 0x0004a2be, 0x00604411, 0x68d }, - { 0x00000035, 0x00203630, 0x000 }, - { 0x0004a2c2, 0x00604411, 0x68d }, - { 0x00000036, 0x00203630, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x00000005, 0x00204811, 0x000 }, - { 0x0000a1f4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x88000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000001, 0x002f0230, 0x000 }, - { 0x00000000, 0x0ce00000, 0x62c }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x62c }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00007e00, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x605 }, - { 0x0000a092, 0x00204411, 0x000 }, - { 0x00000031, 0x00204a2d, 0x000 }, - { 0x0000a093, 0x00204411, 0x000 }, - { 0x00000032, 0x00204a2d, 0x000 }, - { 0x0000a2b6, 0x00204411, 0x000 }, - { 0x00000033, 0x00204a2d, 0x000 }, - { 0x0000a2ba, 0x00204411, 0x000 }, - { 0x00000034, 0x00204a2d, 0x000 }, - { 0x0000a2be, 0x00204411, 0x000 }, - { 0x00000035, 0x00204a2d, 0x000 }, - { 0x0000a2c2, 0x00204411, 0x000 }, - { 0x00000036, 0x00204a2d, 0x000 }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x000001ff, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x62b }, - { 0x00000000, 0x00210221, 0x000 }, - { 0x00000000, 0x14c00000, 0x60e }, - { 0x0004a003, 0x00604411, 0x68d }, - { 0x0000a003, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000001, 0x00210621, 0x000 }, - { 0x00000000, 0x14c00000, 0x613 }, - { 0x0004a010, 0x00604411, 0x68d }, - { 0x0000a010, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000001, 0x00210621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x62b }, - { 0x0004a011, 0x00604411, 0x68d }, - { 0x0000a011, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a012, 0x00604411, 0x68d }, - { 0x0000a012, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a013, 0x00604411, 0x68d }, - { 0x0000a013, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a014, 0x00604411, 0x68d }, - { 0x0000a014, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a015, 0x00604411, 0x68d }, - { 0x0000a015, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a016, 0x00604411, 0x68d }, - { 0x0000a016, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a017, 0x00604411, 0x68d }, - { 0x0000a017, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x0000002c, 0x0080062d, 0x000 }, - { 0xff000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000002, 0x00804811, 0x000 }, - { 0x00000000, 0x0ee00000, 0x63d }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00000002, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x63b }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x68d }, - { 0x00001000, 0x00200811, 0x000 }, - { 0x0000002b, 0x00203622, 0x000 }, - { 0x00000000, 0x00600000, 0x641 }, - { 0x00000000, 0x00600000, 0x5c9 }, - { 0x98000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00804811, 0x000 }, - { 0x00000000, 0xc0600000, 0x641 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000022, 0x00204811, 0x000 }, - { 0x89000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00404811, 0x62d }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00404811, 0x62d }, - { 0x00000000, 0x00600000, 0x65c }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0xc0204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36e }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00010000, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x09800000, 0x00204811, 0x000 }, - { 0xffffffff, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x68d }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000004, 0x00404c11, 0x656 }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000004, 0x00291e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0xfffffffb, 0x00281e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000008, 0x00291e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0xfffffff7, 0x00281e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36e }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00010000, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x01800000, 0x00204811, 0x000 }, - { 0xffffffff, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004217f, 0x00604411, 0x68d }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x68c }, - { 0x00000010, 0x00404c11, 0x672 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x38c00000, 0x000 }, - { 0x0000001d, 0x00200a2d, 0x000 }, - { 0x0000001e, 0x00200e2d, 0x000 }, - { 0x0000001f, 0x0020122d, 0x000 }, - { 0x00000020, 0x0020162d, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000004, 0x00301224, 0x000 }, - { 0x00000000, 0x002f0064, 0x000 }, - { 0x00000000, 0x0cc00000, 0x68b }, - { 0x00000003, 0x00281a22, 0x000 }, - { 0x00000008, 0x00221222, 0x000 }, - { 0xfffff000, 0x00281224, 0x000 }, - { 0x00000000, 0x002910c4, 0x000 }, - { 0x0000001f, 0x00403624, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x1ac00000, 0x68d }, - { 0x9f000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x690 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x1ac00000, 0x692 }, - { 0x9e000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x695 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00001000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001b, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0xc0204411, 0x000 }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000024, 0x0020222d, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000022, 0x0020222d, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00404811, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x01420502, 0x05c00250, 0x000 }, - { 0x01c30168, 0x043f05c0, 0x000 }, - { 0x02250209, 0x02500151, 0x000 }, - { 0x02230245, 0x02a00241, 0x000 }, - { 0x03d705c0, 0x05c005c0, 0x000 }, - { 0x0649064a, 0x031f05c0, 0x000 }, - { 0x05c005c5, 0x03200340, 0x000 }, - { 0x032a0282, 0x03420334, 0x000 }, - { 0x05c005c0, 0x05c005c0, 0x000 }, - { 0x05c00551, 0x05c005c0, 0x000 }, - { 0x03ba05c0, 0x04bb0344, 0x000 }, - { 0x049a0450, 0x043d05c0, 0x000 }, - { 0x04d005c0, 0x044104dd, 0x000 }, - { 0x04500507, 0x03510375, 0x000 }, - { 0x05c005c0, 0x05c005c0, 0x000 }, - { 0x05c005c0, 0x05c005c0, 0x000 }, - { 0x05c005c0, 0x063f05c7, 0x000 }, - { 0x05c005c0, 0x000705c0, 0x000 }, - { 0x05c005c0, 0x05c005c0, 0x000 }, - { 0x05c005c0, 0x05c005c0, 0x000 }, - { 0x03f803ed, 0x04080406, 0x000 }, - { 0x040e040a, 0x040c0410, 0x000 }, - { 0x041c0418, 0x04240420, 0x000 }, - { 0x042c0428, 0x04340430, 0x000 }, - { 0x05c005c0, 0x043805c0, 0x000 }, - { 0x05c005c0, 0x05c005c0, 0x000 }, - { 0x05c005c0, 0x05c005c0, 0x000 }, - { 0x00020679, 0x06970006, 0x000 }, -}; - -static const u32 RV620_pfp_microcode[] = { -0xca0400, -0xa00000, -0x7e828b, -0x7c038b, -0x8001b8, -0x7c038b, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xc41838, -0xca2400, -0xca2800, -0x9581a8, -0xc41c3a, -0xc3c000, -0xca0800, -0xca0c00, -0x7c744b, -0xc20005, -0x99c000, -0xc41c3a, -0x7c744c, -0xc0fff0, -0x042c04, -0x309002, -0x7d2500, -0x351402, -0x7d350b, -0x255403, -0x7cd580, -0x259c03, -0x95c004, -0xd5001b, -0x7eddc1, -0x7d9d80, -0xd6801b, -0xd5801b, -0xd4401e, -0xd5401e, -0xd6401e, -0xd6801e, -0xd4801e, -0xd4c01e, -0x9783d3, -0xd5c01e, -0xca0800, -0x80001a, -0xca0c00, -0xe4011e, -0xd4001e, -0x80000c, -0xc41838, -0xe4013e, -0xd4001e, -0x80000c, -0xc41838, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4011e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4013e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca1800, -0xd4401e, -0xd5801e, -0x800053, -0xd40075, -0xd4401e, -0xca0800, -0xca0c00, -0xca1000, -0xd48019, -0xd4c018, -0xd50017, -0xd4801e, -0xd4c01e, -0xd5001e, -0xe2001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0xd48060, -0xd4401e, -0x800000, -0xd4801e, -0xca0800, -0xd48061, -0xd4401e, -0x800000, -0xd4801e, -0xca0800, -0xca0c00, -0xd4401e, -0xd48016, -0xd4c016, -0xd4801e, -0x8001b8, -0xd4c01e, -0xc60843, -0xca0c00, -0xca1000, -0x948004, -0xca1400, -0xe420f3, -0xd42013, -0xd56065, -0xd4e01c, -0xd5201c, -0xd5601c, -0x800000, -0x062001, -0xc60843, -0xca0c00, -0xca1000, -0x9483f7, -0xca1400, -0xe420f3, -0x800079, -0xd42013, -0xc60843, -0xca0c00, -0xca1000, -0x9883ef, -0xca1400, -0xd40064, -0x80008d, -0x000000, -0xc41432, -0xc61843, -0xc4082f, -0x954005, -0xc40c30, -0xd4401e, -0x800000, -0xee001e, -0x9583f5, -0xc41031, -0xd44033, -0xd52065, -0xd4a01c, -0xd4e01c, -0xd5201c, -0xe4015e, -0xd4001e, -0x800000, -0x062001, -0xca1800, -0x0a2001, -0xd60076, -0xc40836, -0x988007, -0xc61045, -0x950110, -0xd4001f, -0xd46062, -0x800000, -0xd42062, -0xcc3835, -0xcc1433, -0x8401bb, -0xd40072, -0xd5401e, -0x800000, -0xee001e, -0xe2001a, -0x8401bb, -0xe2001a, -0xcc104b, -0xcc0447, -0x2c9401, -0x7d098b, -0x984005, -0x7d15cb, -0xd4001a, -0x8001b8, -0xd4006d, -0x344401, -0xcc0c48, -0x98403a, -0xcc2c4a, -0x958004, -0xcc0449, -0x8001b8, -0xd4001a, -0xd4c01a, -0x282801, -0x8400f0, -0xcc1003, -0x98801b, -0x04380c, -0x8400f0, -0xcc1003, -0x988017, -0x043808, -0x8400f0, -0xcc1003, -0x988013, -0x043804, -0x8400f0, -0xcc1003, -0x988014, -0xcc104c, -0x9a8009, -0xcc144d, -0x9840dc, -0xd4006d, -0xcc1848, -0xd5001a, -0xd5401a, -0x8000c9, -0xd5801a, -0x96c0d5, -0xd4006d, -0x8001b8, -0xd4006e, -0x9ac003, -0xd4006d, -0xd4006e, -0x800000, -0xec007f, -0x9ac0cc, -0xd4006d, -0x8001b8, -0xd4006e, -0xcc1403, -0xcc1803, -0xcc1c03, -0x7d9103, -0x7dd583, -0x7d190c, -0x35cc1f, -0x35701f, -0x7cf0cb, -0x7cd08b, -0x880000, -0x7e8e8b, -0x95c004, -0xd4006e, -0x8001b8, -0xd4001a, -0xd4c01a, -0xcc0803, -0xcc0c03, -0xcc1003, -0xcc1403, -0xcc1803, -0xcc1c03, -0xcc2403, -0xcc2803, -0x35c41f, -0x36b01f, -0x7c704b, -0x34f01f, -0x7c704b, -0x35701f, -0x7c704b, -0x7d8881, -0x7dccc1, -0x7e5101, -0x7e9541, -0x7c9082, -0x7cd4c2, -0x7c848b, -0x9ac003, -0x7c8c8b, -0x2c8801, -0x98809e, -0xd4006d, -0x98409c, -0xd4006e, -0xcc084c, -0xcc0c4d, -0xcc1048, -0xd4801a, -0xd4c01a, -0x800101, -0xd5001a, -0xcc0832, -0xd40032, -0x9482d9, -0xca0c00, -0xd4401e, -0x800000, -0xd4001e, -0xe4011e, -0xd4001e, -0xca0800, -0xca0c00, -0xca1000, -0xd4401e, -0xca1400, -0xd4801e, -0xd4c01e, -0xd5001e, -0xd5401e, -0xd54034, -0x800000, -0xee001e, -0x280404, -0xe2001a, -0xe2001a, -0xd4401a, -0xca3800, -0xcc0803, -0xcc0c03, -0xcc0c03, -0xcc0c03, -0x9882bd, -0x000000, -0x8401bb, -0xd7a06f, -0x800000, -0xee001f, -0xca0400, -0xc2ff00, -0xcc0834, -0xc13fff, -0x7c74cb, -0x7cc90b, -0x7d010f, -0x9902b0, -0x7c738b, -0x8401bb, -0xd7a06f, -0x800000, -0xee001f, -0xca0800, -0x281900, -0x7d898b, -0x958014, -0x281404, -0xca0c00, -0xca1000, -0xca1c00, -0xca2400, -0xe2001f, -0xd4c01a, -0xd5001a, -0xd5401a, -0xcc1803, -0xcc2c03, -0xcc2c03, -0xcc2c03, -0x7da58b, -0x7d9c47, -0x984297, -0x000000, -0x800161, -0xd4c01a, -0xd4401e, -0xd4801e, -0x800000, -0xee001e, -0xe4011e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4013e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0x248c06, -0x0ccc06, -0x98c006, -0xcc104e, -0x990004, -0xd40073, -0xe4011e, -0xd4001e, -0xd4401e, -0xd4801e, -0x800000, -0xee001e, -0xca0800, -0xca0c00, -0x34d018, -0x251001, -0x950021, -0xc17fff, -0xca1000, -0xca1400, -0xca1800, -0xd4801d, -0xd4c01d, -0x7db18b, -0xc14202, -0xc2c001, -0xd5801d, -0x34dc0e, -0x7d5d4c, -0x7f734c, -0xd7401e, -0xd5001e, -0xd5401e, -0xc14200, -0xc2c000, -0x099c01, -0x31dc10, -0x7f5f4c, -0x7f734c, -0x042802, -0x7d8380, -0xd5a86f, -0xd58066, -0xd7401e, -0xec005e, -0xc82402, -0xc82402, -0x8001b8, -0xd60076, -0xd4401e, -0xd4801e, -0xd4c01e, -0x800000, -0xee001e, -0x800000, -0xee001f, -0xd4001f, -0x800000, -0xd4001f, -0xd4001f, -0x880000, -0xd4001f, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x010171, -0x020178, -0x03008f, -0x04007f, -0x050003, -0x06003f, -0x070032, -0x08012c, -0x090046, -0x0a0036, -0x1001b6, -0x1700a2, -0x22013a, -0x230149, -0x2000b4, -0x240125, -0x27004d, -0x28006a, -0x2a0060, -0x2b0052, -0x2f0065, -0x320087, -0x34017f, -0x3c0156, -0x3f0072, -0x41018c, -0x44012e, -0x550173, -0x56017a, -0x60000b, -0x610034, -0x620038, -0x630038, -0x640038, -0x650038, -0x660038, -0x670038, -0x68003a, -0x690041, -0x6a0048, -0x6b0048, -0x6c0048, -0x6d0048, -0x6e0048, -0x6f0048, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -}; - -static const u32 RV630_cp_microcode[][3] = { - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0000ffff, 0x00284621, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00000000, 0x00e00000, 0x000 }, - { 0x00010000, 0xc0294620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x00000000, 0x00600000, 0x62e }, - { 0x00000000, 0x00600000, 0x642 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000f00, 0x00281622, 0x000 }, - { 0x00000008, 0x00211625, 0x000 }, - { 0x00000018, 0x00203625, 0x000 }, - { 0x8d000000, 0x00204411, 0x000 }, - { 0x00000004, 0x002f0225, 0x000 }, - { 0x00000000, 0x0ce00000, 0x018 }, - { 0x00412000, 0x00404811, 0x019 }, - { 0x00422000, 0x00204811, 0x000 }, - { 0x8e000000, 0x00204411, 0x000 }, - { 0x00000028, 0x00204a2d, 0x000 }, - { 0x90000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x0000000c, 0x00211622, 0x000 }, - { 0x00000003, 0x00281625, 0x000 }, - { 0x00000019, 0x00211a22, 0x000 }, - { 0x00000004, 0x00281a26, 0x000 }, - { 0x00000000, 0x002914c5, 0x000 }, - { 0x00000019, 0x00203625, 0x000 }, - { 0x00000000, 0x003a1402, 0x000 }, - { 0x00000016, 0x00211625, 0x000 }, - { 0x00000003, 0x00281625, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0xfffffffc, 0x00280e23, 0x000 }, - { 0x00000000, 0x002914a3, 0x000 }, - { 0x00000017, 0x00203625, 0x000 }, - { 0x00008000, 0x00280e22, 0x000 }, - { 0x00000007, 0x00220e23, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x20000000, 0x00280e22, 0x000 }, - { 0x00000006, 0x00210e23, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x00000000, 0x00220222, 0x000 }, - { 0x00000000, 0x14e00000, 0x038 }, - { 0x00000000, 0x2ee00000, 0x035 }, - { 0x00000000, 0x2ce00000, 0x037 }, - { 0x00000000, 0x00400e2d, 0x039 }, - { 0x00000008, 0x00200e2d, 0x000 }, - { 0x00000009, 0x0040122d, 0x046 }, - { 0x00000001, 0x00400e2d, 0x039 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x003ffffc, 0x00281223, 0x000 }, - { 0x00000002, 0x00221224, 0x000 }, - { 0x0000001f, 0x00211e23, 0x000 }, - { 0x00000000, 0x14e00000, 0x03e }, - { 0x00000008, 0x00401c11, 0x041 }, - { 0x0000000d, 0x00201e2d, 0x000 }, - { 0x0000000f, 0x00281e27, 0x000 }, - { 0x00000003, 0x00221e27, 0x000 }, - { 0x7fc00000, 0x00281a23, 0x000 }, - { 0x00000014, 0x00211a26, 0x000 }, - { 0x00000001, 0x00331a26, 0x000 }, - { 0x00000008, 0x00221a26, 0x000 }, - { 0x00000000, 0x00290cc7, 0x000 }, - { 0x00000027, 0x00203624, 0x000 }, - { 0x00007f00, 0x00281221, 0x000 }, - { 0x00001400, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x04b }, - { 0x00000001, 0x00290e23, 0x000 }, - { 0x0000000e, 0x00203623, 0x000 }, - { 0x0000e000, 0x00204411, 0x000 }, - { 0xfff80000, 0x00294a23, 0x000 }, - { 0x00000000, 0x003a2c02, 0x000 }, - { 0x00000002, 0x00220e2b, 0x000 }, - { 0xfc000000, 0x00280e23, 0x000 }, - { 0x0000000f, 0x00203623, 0x000 }, - { 0x00001fff, 0x00294a23, 0x000 }, - { 0x00000027, 0x00204a2d, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000029, 0x00200e2d, 0x000 }, - { 0x060a0200, 0x00294a23, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14e00000, 0x061 }, - { 0x00000000, 0x2ee00000, 0x05f }, - { 0x00000000, 0x2ce00000, 0x05e }, - { 0x00000000, 0x00400e2d, 0x062 }, - { 0x00000001, 0x00400e2d, 0x062 }, - { 0x0000000a, 0x00200e2d, 0x000 }, - { 0x0000000b, 0x0040122d, 0x06a }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x003ffffc, 0x00281223, 0x000 }, - { 0x00000002, 0x00221224, 0x000 }, - { 0x7fc00000, 0x00281623, 0x000 }, - { 0x00000014, 0x00211625, 0x000 }, - { 0x00000001, 0x00331625, 0x000 }, - { 0x80000000, 0x00280e23, 0x000 }, - { 0x00000000, 0x00290ca3, 0x000 }, - { 0x3ffffc00, 0x00290e23, 0x000 }, - { 0x0000001f, 0x00211e23, 0x000 }, - { 0x00000000, 0x14e00000, 0x06d }, - { 0x00000100, 0x00401c11, 0x070 }, - { 0x0000000d, 0x00201e2d, 0x000 }, - { 0x000000f0, 0x00281e27, 0x000 }, - { 0x00000004, 0x00221e27, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0xfffff0ff, 0x00281a30, 0x000 }, - { 0x0000a028, 0x00204411, 0x000 }, - { 0x00000000, 0x002948e6, 0x000 }, - { 0x0000a018, 0x00204411, 0x000 }, - { 0x3fffffff, 0x00284a23, 0x000 }, - { 0x0000a010, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000030, 0x0020162d, 0x000 }, - { 0x00000002, 0x00291625, 0x000 }, - { 0x00000030, 0x00203625, 0x000 }, - { 0x00000025, 0x0020162d, 0x000 }, - { 0x00000000, 0x002f00a3, 0x000 }, - { 0x00000000, 0x0cc00000, 0x083 }, - { 0x00000026, 0x0020162d, 0x000 }, - { 0x00000000, 0x002f00a4, 0x000 }, - { 0x00000000, 0x0cc00000, 0x084 }, - { 0x00000000, 0x00400000, 0x08a }, - { 0x00000025, 0x00203623, 0x000 }, - { 0x00000026, 0x00203624, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x08a }, - { 0x00000000, 0x00600000, 0x665 }, - { 0x00000000, 0x00600000, 0x659 }, - { 0x00000002, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x08d }, - { 0x00000012, 0xc0403620, 0x093 }, - { 0x00000000, 0x2ee00000, 0x091 }, - { 0x00000000, 0x2ce00000, 0x090 }, - { 0x00000002, 0x00400e2d, 0x092 }, - { 0x00000003, 0x00400e2d, 0x092 }, - { 0x0000000c, 0x00200e2d, 0x000 }, - { 0x00000012, 0x00203623, 0x000 }, - { 0x00000003, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x098 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x0a0 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x2ee00000, 0x09e }, - { 0x00000000, 0x2ce00000, 0x09d }, - { 0x00000002, 0x00400e2d, 0x09f }, - { 0x00000003, 0x00400e2d, 0x09f }, - { 0x0000000c, 0x00200e2d, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000000, 0x003a0c02, 0x000 }, - { 0x003f0000, 0x00280e23, 0x000 }, - { 0x00000010, 0x00210e23, 0x000 }, - { 0x00000011, 0x00203623, 0x000 }, - { 0x0000001e, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0a7 }, - { 0x00000016, 0xc0203620, 0x000 }, - { 0x0000001f, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0aa }, - { 0x00000015, 0xc0203620, 0x000 }, - { 0x00000008, 0x00210e2b, 0x000 }, - { 0x0000007f, 0x00280e23, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0e1 }, - { 0x00000000, 0x27000000, 0x000 }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0b3 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x0000000c, 0x00221e30, 0x000 }, - { 0x99800000, 0x00204411, 0x000 }, - { 0x00000004, 0x0020122d, 0x000 }, - { 0x00000008, 0x00221224, 0x000 }, - { 0x00000010, 0x00201811, 0x000 }, - { 0x00000000, 0x00291ce4, 0x000 }, - { 0x00000000, 0x00604807, 0x12f }, - { 0x9b000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x9c000000, 0x00204411, 0x000 }, - { 0x00000000, 0x0033146f, 0x000 }, - { 0x00000001, 0x00333e23, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0x00203c05, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x00000000, 0x00201010, 0x000 }, - { 0x0000e007, 0x00204411, 0x000 }, - { 0x0000000f, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0cb }, - { 0x00f8ff08, 0x00204811, 0x000 }, - { 0x98000000, 0x00404811, 0x0dc }, - { 0x000000f0, 0x00280e22, 0x000 }, - { 0x000000a0, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x0da }, - { 0x00000011, 0x00200e2d, 0x000 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0d5 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0d4 }, - { 0x00003f00, 0x00400c11, 0x0d6 }, - { 0x00001f00, 0x00400c11, 0x0d6 }, - { 0x00000f00, 0x00200c11, 0x000 }, - { 0x00380009, 0x00294a23, 0x000 }, - { 0x3f000000, 0x00280e2b, 0x000 }, - { 0x00000002, 0x00220e23, 0x000 }, - { 0x00000007, 0x00494a23, 0x0dc }, - { 0x00380f09, 0x00204811, 0x000 }, - { 0x68000007, 0x00204811, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a24, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000a202, 0x00204411, 0x000 }, - { 0x00ff0000, 0x00280e22, 0x000 }, - { 0x00000080, 0x00294a23, 0x000 }, - { 0x00000027, 0x00200e2d, 0x000 }, - { 0x00000026, 0x0020122d, 0x000 }, - { 0x00000000, 0x002f0083, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0ea }, - { 0x00000000, 0x00600000, 0x65f }, - { 0x00000000, 0x00400000, 0x0eb }, - { 0x00000000, 0x00600000, 0x662 }, - { 0x00000007, 0x0020222d, 0x000 }, - { 0x00000005, 0x00220e22, 0x000 }, - { 0x00100000, 0x00280e23, 0x000 }, - { 0x00000000, 0x00292068, 0x000 }, - { 0x00000000, 0x003a0c02, 0x000 }, - { 0x000000ef, 0x00280e23, 0x000 }, - { 0x00000000, 0x00292068, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0x00000003, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x0f8 }, - { 0x0000000b, 0x00210228, 0x000 }, - { 0x00000000, 0x14c00000, 0x0f8 }, - { 0x00000400, 0x00292228, 0x000 }, - { 0x00000014, 0x00203628, 0x000 }, - { 0x0000001c, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x0fd }, - { 0x0000a30c, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000001e, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x10b }, - { 0x0000a30f, 0x00204411, 0x000 }, - { 0x00000011, 0x00200e2d, 0x000 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x104 }, - { 0xffffffff, 0x00404811, 0x10b }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x107 }, - { 0x0000ffff, 0x00404811, 0x10b }, - { 0x00000004, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x10a }, - { 0x000000ff, 0x00404811, 0x10b }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0002c400, 0x00204411, 0x000 }, - { 0x0000001f, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x112 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x00000013, 0x00203623, 0x000 }, - { 0x00000018, 0x40224a20, 0x000 }, - { 0x00000010, 0xc0424a20, 0x114 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x00000013, 0x00203623, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000000a, 0x00201011, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x11b }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00531224, 0x117 }, - { 0xffbfffff, 0x00283a2e, 0x000 }, - { 0x0000001b, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x12e }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0x00000018, 0x00220e30, 0x000 }, - { 0xfc000000, 0x00280e23, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x00000000, 0x00201010, 0x000 }, - { 0x0000e00e, 0x00204411, 0x000 }, - { 0x07f8ff08, 0x00204811, 0x000 }, - { 0x00000000, 0x00294a23, 0x000 }, - { 0x0000001c, 0x00201e2d, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a24, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x00800000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204806, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x68a }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x689 }, - { 0x00000004, 0x00404c11, 0x135 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x0000001c, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68a }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x13c }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00000000, 0x00600000, 0x160 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000ffff, 0x40280620, 0x000 }, - { 0x00000010, 0xc0210a20, 0x000 }, - { 0x00000000, 0x00341461, 0x000 }, - { 0x00000000, 0x00741882, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x147 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x160 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x00000010, 0x40211620, 0x000 }, - { 0x0000ffff, 0xc0681a20, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x158 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000001, 0x00300a2f, 0x000 }, - { 0x00000001, 0x00210a22, 0x000 }, - { 0x00000003, 0x00384a22, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001a, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600000, 0x18f }, - { 0x00000000, 0x00600000, 0x1a0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00202c08, 0x000 }, - { 0x00000000, 0x00202411, 0x000 }, - { 0x00000000, 0x00202811, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000002, 0x00221e29, 0x000 }, - { 0x00000000, 0x007048eb, 0x19c }, - { 0x00000000, 0x00600000, 0x2bb }, - { 0x00000001, 0x40330620, 0x000 }, - { 0x00000000, 0xc0302409, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ae00000, 0x181 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x00000000, 0x00400000, 0x186 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x186 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000001, 0x00530621, 0x182 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0604800, 0x197 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000011, 0x0020062d, 0x000 }, - { 0x00000000, 0x0078042a, 0x2fb }, - { 0x00000000, 0x00202809, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x174 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000210, 0x00600411, 0x315 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x194 }, - { 0x00000015, 0xc0203620, 0x000 }, - { 0x00000016, 0xc0203620, 0x000 }, - { 0x3f800000, 0x00200411, 0x000 }, - { 0x46000000, 0x00600811, 0x1b2 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x19b }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000021, 0x00804811, 0x000 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000ffff, 0x40281620, 0x000 }, - { 0x00000010, 0xc0811a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000008, 0x00221e30, 0x000 }, - { 0x00000029, 0x00201a2d, 0x000 }, - { 0x0000e000, 0x00204411, 0x000 }, - { 0xfffbff09, 0x00204811, 0x000 }, - { 0x0000000f, 0x0020222d, 0x000 }, - { 0x00001fff, 0x00294a28, 0x000 }, - { 0x00000006, 0x0020222d, 0x000 }, - { 0x00000000, 0x002920e8, 0x000 }, - { 0x00000000, 0x00204808, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a26, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000100, 0x00201811, 0x000 }, - { 0x00000008, 0x00621e28, 0x12f }, - { 0x00000008, 0x00822228, 0x000 }, - { 0x0002c000, 0x00204411, 0x000 }, - { 0x00000015, 0x00600e2d, 0x1bd }, - { 0x00000016, 0x00600e2d, 0x1bd }, - { 0x0000c008, 0x00204411, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0x00000000, 0x14c00000, 0x1b9 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0x39000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00804802, 0x000 }, - { 0x00000018, 0x00202e2d, 0x000 }, - { 0x00000000, 0x003b0d63, 0x000 }, - { 0x00000008, 0x00224a23, 0x000 }, - { 0x00000010, 0x00224a23, 0x000 }, - { 0x00000018, 0x00224a23, 0x000 }, - { 0x00000000, 0x00804803, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00001000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00000007, 0x0021062f, 0x000 }, - { 0x00000013, 0x00200a2d, 0x000 }, - { 0x00000001, 0x00202c11, 0x000 }, - { 0x0000ffff, 0x40282220, 0x000 }, - { 0x0000000f, 0x00262228, 0x000 }, - { 0x00000010, 0x40212620, 0x000 }, - { 0x0000000f, 0x00262629, 0x000 }, - { 0x00000000, 0x00202802, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001b, 0x00204811, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1e0 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000081, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000080, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1dc }, - { 0x00000000, 0x00600000, 0x1e9 }, - { 0x00000001, 0x00531e27, 0x1d8 }, - { 0x00000001, 0x00202c11, 0x000 }, - { 0x0000001f, 0x00280a22, 0x000 }, - { 0x0000001f, 0x00282a2a, 0x000 }, - { 0x00000001, 0x00530621, 0x1d1 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000002, 0x00304a2f, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000001, 0x00301e2f, 0x000 }, - { 0x00000000, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x1e9 }, - { 0x00000001, 0x00531e27, 0x1e5 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x0000000f, 0x00260e23, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000000f, 0x00261224, 0x000 }, - { 0x00000000, 0x00201411, 0x000 }, - { 0x00000000, 0x00601811, 0x2bb }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022b, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1f8 }, - { 0x00000010, 0x00221628, 0x000 }, - { 0xffff0000, 0x00281625, 0x000 }, - { 0x0000ffff, 0x00281a29, 0x000 }, - { 0x00000000, 0x002948c5, 0x000 }, - { 0x00000000, 0x0020480a, 0x000 }, - { 0x00000000, 0x00202c11, 0x000 }, - { 0x00000010, 0x00221623, 0x000 }, - { 0xffff0000, 0x00281625, 0x000 }, - { 0x0000ffff, 0x00281a24, 0x000 }, - { 0x00000000, 0x002948c5, 0x000 }, - { 0x00000000, 0x00731503, 0x205 }, - { 0x00000000, 0x00201805, 0x000 }, - { 0x00000000, 0x00731524, 0x205 }, - { 0x00000000, 0x002d14c5, 0x000 }, - { 0x00000000, 0x003008a2, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00202802, 0x000 }, - { 0x00000000, 0x00202003, 0x000 }, - { 0x00000000, 0x00802404, 0x000 }, - { 0x0000000f, 0x00210225, 0x000 }, - { 0x00000000, 0x14c00000, 0x689 }, - { 0x00000000, 0x002b1405, 0x000 }, - { 0x00000001, 0x00901625, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001a, 0x00294a22, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00384a21, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000ffff, 0x40281220, 0x000 }, - { 0x00000010, 0xc0211a20, 0x000 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211620, 0x000 }, - { 0x00000000, 0x00741465, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00000001, 0x00330621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0cc00000, 0x219 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x212 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x642 }, - { 0x00000000, 0x0040040f, 0x213 }, - { 0x00000000, 0x00600000, 0x62e }, - { 0x00000000, 0x00600000, 0x642 }, - { 0x00000210, 0x00600411, 0x315 }, - { 0x00000000, 0x00600000, 0x1a0 }, - { 0x00000000, 0x00600000, 0x19c }, - { 0x00000000, 0x00600000, 0x2bb }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204808, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ae00000, 0x232 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x00000000, 0x00400000, 0x236 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x236 }, - { 0x00000000, 0xc0404800, 0x233 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x00600411, 0x2fb }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x62e }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000018, 0x40210a20, 0x000 }, - { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x24c }, - { 0x00000014, 0x0020222d, 0x000 }, - { 0x00080101, 0x00292228, 0x000 }, - { 0x00000014, 0x00203628, 0x000 }, - { 0x0000a30c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x251 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000010, 0x00600411, 0x315 }, - { 0x3f800000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x00000000, 0x00600000, 0x27c }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000001, 0x00211e27, 0x000 }, - { 0x00000000, 0x14e00000, 0x26a }, - { 0x00000012, 0x00201e2d, 0x000 }, - { 0x0000ffff, 0x00281e27, 0x000 }, - { 0x00000000, 0x00341c27, 0x000 }, - { 0x00000000, 0x12c00000, 0x25f }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f00e5, 0x000 }, - { 0x00000000, 0x08c00000, 0x262 }, - { 0x00000000, 0x00201407, 0x000 }, - { 0x00000012, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00211e27, 0x000 }, - { 0x00000000, 0x00341c47, 0x000 }, - { 0x00000000, 0x12c00000, 0x267 }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f00e6, 0x000 }, - { 0x00000000, 0x08c00000, 0x26a }, - { 0x00000000, 0x00201807, 0x000 }, - { 0x00000000, 0x00600000, 0x2c1 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000000, 0x00342023, 0x000 }, - { 0x00000000, 0x12c00000, 0x272 }, - { 0x00000000, 0x00342044, 0x000 }, - { 0x00000000, 0x12c00000, 0x271 }, - { 0x00000016, 0x00404811, 0x276 }, - { 0x00000018, 0x00404811, 0x276 }, - { 0x00000000, 0x00342044, 0x000 }, - { 0x00000000, 0x12c00000, 0x275 }, - { 0x00000017, 0x00404811, 0x276 }, - { 0x00000019, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0x00604411, 0x2e9 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x256 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000010, 0x40210620, 0x000 }, - { 0x0000ffff, 0xc0280a20, 0x000 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x00000010, 0x40211620, 0x000 }, - { 0x0000ffff, 0xc0881a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x00000000, 0x00600000, 0x62e }, - { 0x00000000, 0xc0600000, 0x2a3 }, - { 0x00000005, 0x00200a2d, 0x000 }, - { 0x00000008, 0x00220a22, 0x000 }, - { 0x0000002b, 0x00201a2d, 0x000 }, - { 0x0000001c, 0x00201e2d, 0x000 }, - { 0x00007000, 0x00281e27, 0x000 }, - { 0x00000000, 0x00311ce6, 0x000 }, - { 0x0000002a, 0x00201a2d, 0x000 }, - { 0x0000000c, 0x00221a26, 0x000 }, - { 0x00000000, 0x002f00e6, 0x000 }, - { 0x00000000, 0x06e00000, 0x292 }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x0000002b, 0x00203623, 0x000 }, - { 0x00000010, 0x00201811, 0x000 }, - { 0x00000000, 0x00691ce2, 0x12f }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x29d }, - { 0x00000001, 0x00333e2f, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000001c, 0x00403627, 0x000 }, - { 0x0000000c, 0xc0220a20, 0x000 }, - { 0x00000029, 0x00203622, 0x000 }, - { 0x00000028, 0xc0403620, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000009, 0x00204811, 0x000 }, - { 0xa1000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002c1ce3, 0x000 }, - { 0x00000021, 0x00203627, 0x000 }, - { 0x00000022, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002c1ce4, 0x000 }, - { 0x00000022, 0x00203627, 0x000 }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120a3, 0x000 }, - { 0x00000000, 0x002d1d07, 0x000 }, - { 0x00000023, 0x00203627, 0x000 }, - { 0x00000024, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x00000000, 0x002d1d07, 0x000 }, - { 0x00000024, 0x00803627, 0x000 }, - { 0x00000021, 0x00203623, 0x000 }, - { 0x00000022, 0x00203624, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000023, 0x00203627, 0x000 }, - { 0x00000000, 0x00311cc4, 0x000 }, - { 0x00000024, 0x00803627, 0x000 }, - { 0x0000001a, 0x00203627, 0x000 }, - { 0x0000001b, 0x00203628, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14c00000, 0x2dc }, - { 0x00000000, 0x00400000, 0x2d9 }, - { 0x0000001a, 0x00203627, 0x000 }, - { 0x0000001b, 0x00203628, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x2d9 }, - { 0x00000003, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x2dc }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002e00e1, 0x000 }, - { 0x00000000, 0x02c00000, 0x2dc }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120a1, 0x000 }, - { 0x00000000, 0x002e00e8, 0x000 }, - { 0x00000000, 0x06c00000, 0x2dc }, - { 0x00000024, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002e00e2, 0x000 }, - { 0x00000000, 0x02c00000, 0x2dc }, - { 0x00000022, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120c2, 0x000 }, - { 0x00000000, 0x002e00e8, 0x000 }, - { 0x00000000, 0x06c00000, 0x2dc }, - { 0x00000000, 0x00600000, 0x665 }, - { 0x00000000, 0x00600000, 0x2b5 }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x00000000, 0x00600000, 0x2b5 }, - { 0x00000000, 0x00600000, 0x65c }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x00000000, 0x00600000, 0x2a7 }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x0000001a, 0x00201e2d, 0x000 }, - { 0x0000001b, 0x0080222d, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000010, 0x00221e21, 0x000 }, - { 0x00000000, 0x00294847, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000000, 0x00311ca1, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294847, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000010, 0x00221e21, 0x000 }, - { 0x00000000, 0x003120c2, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000001, 0x00220a21, 0x000 }, - { 0x00000000, 0x003308a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000001, 0x00220a21, 0x000 }, - { 0x00000000, 0x003008a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x003808c5, 0x000 }, - { 0x00000000, 0x00300841, 0x000 }, - { 0x00000001, 0x00220a22, 0x000 }, - { 0x00000000, 0x003308a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000017, 0x0020222d, 0x000 }, - { 0x00000000, 0x14c00000, 0x318 }, - { 0xffffffef, 0x00280621, 0x000 }, - { 0x00000014, 0x0020222d, 0x000 }, - { 0x0000f8e0, 0x00204411, 0x000 }, - { 0x00000000, 0x00294901, 0x000 }, - { 0x00000000, 0x00894901, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00804811, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x97000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00002257, 0x00204411, 0x000 }, - { 0x00000003, 0xc0484a20, 0x000 }, - { 0x0000225d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0x00600000, 0x642 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00384a22, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x40204800, 0x000 }, - { 0x00000001, 0x40304a20, 0x000 }, - { 0x00000002, 0xc0304a20, 0x000 }, - { 0x00000001, 0x00530a22, 0x34b }, - { 0x0000003f, 0xc0280a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000018, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68a }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x354 }, - { 0x00000014, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x364 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00604802, 0x36e }, - { 0x00002100, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x36a }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x35f }, - { 0x00000028, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5bd }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x35f }, - { 0x0000002c, 0x00203626, 0x000 }, - { 0x00000049, 0x00201811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x00000001, 0x00331a26, 0x000 }, - { 0x00000000, 0x002f0226, 0x000 }, - { 0x00000000, 0x0cc00000, 0x370 }, - { 0x0000002c, 0x00801a2d, 0x000 }, - { 0x0000003f, 0xc0280a20, 0x000 }, - { 0x00000015, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x386 }, - { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3b1 }, - { 0x00000016, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3b5 }, - { 0x00000020, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x39c }, - { 0x0000000f, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3a8 }, - { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3a8 }, - { 0x0000001e, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x390 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x08000000, 0x00290a22, 0x000 }, - { 0x00000003, 0x40210e20, 0x000 }, - { 0x0000000c, 0xc0211220, 0x000 }, - { 0x00080000, 0x00281224, 0x000 }, - { 0x00000014, 0xc0221620, 0x000 }, - { 0x00000000, 0x002914a4, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x002948a2, 0x000 }, - { 0x0000a1fe, 0x00204411, 0x000 }, - { 0x00000000, 0x00404803, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68a }, - { 0x00000015, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x392 }, - { 0x0000210e, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000017, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68a }, - { 0x00000003, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x39e }, - { 0x00002108, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x80000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000010, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x3ae }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000006, 0x00404811, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36e }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x0000001d, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x3ce }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000018, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68a }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x3c0 }, - { 0x00002100, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0xbabecafe, 0x00204811, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000004, 0x00404811, 0x000 }, - { 0x00002170, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000a, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x3d3 }, - { 0x8c000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00003fff, 0x40280a20, 0x000 }, - { 0x80000000, 0x40280e20, 0x000 }, - { 0x40000000, 0xc0281220, 0x000 }, - { 0x00040000, 0x00694622, 0x68a }, - { 0x00000000, 0x00201410, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x3e1 }, - { 0x00000000, 0xc0401800, 0x3e4 }, - { 0x00003fff, 0xc0281a20, 0x000 }, - { 0x00040000, 0x00694626, 0x68a }, - { 0x00000000, 0x00201810, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x3e7 }, - { 0x00000000, 0xc0401c00, 0x3ea }, - { 0x00003fff, 0xc0281e20, 0x000 }, - { 0x00040000, 0x00694627, 0x68a }, - { 0x00000000, 0x00201c10, 0x000 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0x002820c5, 0x000 }, - { 0x00000000, 0x004948e8, 0x000 }, - { 0xa5800000, 0x00200811, 0x000 }, - { 0x00002000, 0x00200c11, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x40204800, 0x000 }, - { 0x0000001f, 0xc0210220, 0x000 }, - { 0x00000000, 0x14c00000, 0x3f7 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0000ffff, 0xc0481220, 0x3ff }, - { 0xa7800000, 0x00200811, 0x000 }, - { 0x0000a000, 0x00200c11, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x83000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00304883, 0x000 }, - { 0x84000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1d000000, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0xa9800000, 0x00200811, 0x000 }, - { 0x0000c000, 0x00400c11, 0x3fa }, - { 0xab800000, 0x00200811, 0x000 }, - { 0x0000f8e0, 0x00400c11, 0x3fa }, - { 0xad800000, 0x00200811, 0x000 }, - { 0x0000f880, 0x00400c11, 0x3fa }, - { 0xb3800000, 0x00200811, 0x000 }, - { 0x0000f3fc, 0x00400c11, 0x3fa }, - { 0xaf800000, 0x00200811, 0x000 }, - { 0x0000e000, 0x00400c11, 0x3fa }, - { 0xb1800000, 0x00200811, 0x000 }, - { 0x0000f000, 0x00400c11, 0x3fa }, - { 0x83000000, 0x00204411, 0x000 }, - { 0x00002148, 0x00204811, 0x000 }, - { 0x84000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1d000000, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x01182000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0218a000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0318c000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0418f8e0, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0518f880, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0618e000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0718f000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0818f3fc, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00000030, 0x00200a2d, 0x000 }, - { 0x00000000, 0xc0290c40, 0x000 }, - { 0x00000030, 0x00203623, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x86000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00404801, 0x000 }, - { 0x85000000, 0xc0204411, 0x000 }, - { 0x00000000, 0x00404801, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x68a }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000000, 0x00404c02, 0x448 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x00000000, 0xc0201000, 0x000 }, - { 0x00000000, 0xc0201400, 0x000 }, - { 0x00000000, 0xc0201800, 0x000 }, - { 0x00000000, 0xc0201c00, 0x000 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x456 }, - { 0x00000000, 0xc0202000, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x00000010, 0x00280a23, 0x000 }, - { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x45e }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0x00694624, 0x68a }, - { 0x00000000, 0x00400000, 0x463 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x00604805, 0x68f }, - { 0x00000000, 0x002824f0, 0x000 }, - { 0x00000007, 0x00280a23, 0x000 }, - { 0x00000001, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x46a }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x04e00000, 0x483 }, - { 0x00000000, 0x00400000, 0x490 }, - { 0x00000002, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x46f }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x02e00000, 0x483 }, - { 0x00000000, 0x00400000, 0x490 }, - { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x474 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x0ce00000, 0x483 }, - { 0x00000000, 0x00400000, 0x490 }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x479 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x0ae00000, 0x483 }, - { 0x00000000, 0x00400000, 0x490 }, - { 0x00000005, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x47e }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x06e00000, 0x483 }, - { 0x00000000, 0x00400000, 0x490 }, - { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x483 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x08e00000, 0x483 }, - { 0x00000000, 0x00400000, 0x490 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x000 }, - { 0x00000008, 0x00210a23, 0x000 }, - { 0x00000000, 0x14c00000, 0x48d }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x00000000, 0xc0204400, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x496 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x00404c08, 0x456 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x00000011, 0x40211220, 0x000 }, - { 0x00000012, 0x40211620, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00210225, 0x000 }, - { 0x00000000, 0x14e00000, 0x4a0 }, - { 0x00040000, 0xc0494a20, 0x4a1 }, - { 0xfffbffff, 0xc0284a20, 0x000 }, - { 0x00000000, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x4ad }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000c, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x4a9 }, - { 0xa0000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000004, 0x00204811, 0x000 }, - { 0x0000216b, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204810, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000005, 0x00204811, 0x000 }, - { 0x0000216c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204810, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00400000, 0x4a7 }, - { 0x00000000, 0xc0210a20, 0x000 }, - { 0x00000000, 0x14c00000, 0x4c0 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0604800, 0x68f }, - { 0x00000000, 0x00400000, 0x4c4 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0xc0294620, 0x000 }, - { 0x00000000, 0xc0600000, 0x68a }, - { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x4cb }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x00000000, 0xc0204400, 0x000 }, - { 0x00000000, 0xc0404810, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68a }, - { 0x00000000, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x4cd }, - { 0x00002180, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000003, 0x00333e2f, 0x000 }, - { 0x00000001, 0x00210221, 0x000 }, - { 0x00000000, 0x14e00000, 0x4fd }, - { 0x0000002c, 0x00200a2d, 0x000 }, - { 0x00040000, 0x18e00c11, 0x4ec }, - { 0x00000001, 0x00333e2f, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xd8c04800, 0x4e0 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000002d, 0x0020122d, 0x000 }, - { 0x00000000, 0x00290c83, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000011, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000000, 0x00400000, 0x4a7 }, - { 0x0000002c, 0xc0203620, 0x000 }, - { 0x0000002d, 0xc0403620, 0x000 }, - { 0x0000000f, 0x00210221, 0x000 }, - { 0x00000000, 0x14c00000, 0x502 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0xd9000000, 0x000 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0xb5000000, 0x00204411, 0x000 }, - { 0x00002000, 0x00204811, 0x000 }, - { 0xb6000000, 0x00204411, 0x000 }, - { 0x0000a000, 0x00204811, 0x000 }, - { 0xb7000000, 0x00204411, 0x000 }, - { 0x0000c000, 0x00204811, 0x000 }, - { 0xb8000000, 0x00204411, 0x000 }, - { 0x0000f8e0, 0x00204811, 0x000 }, - { 0xb9000000, 0x00204411, 0x000 }, - { 0x0000f880, 0x00204811, 0x000 }, - { 0xba000000, 0x00204411, 0x000 }, - { 0x0000e000, 0x00204811, 0x000 }, - { 0xbb000000, 0x00204411, 0x000 }, - { 0x0000f000, 0x00204811, 0x000 }, - { 0xbc000000, 0x00204411, 0x000 }, - { 0x0000f3fc, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000002, 0x00204811, 0x000 }, - { 0x000000ff, 0x00280e30, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x516 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0x14c00000, 0x52b }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x0000001c, 0x00203623, 0x000 }, - { 0x0000002b, 0x00203623, 0x000 }, - { 0x00000029, 0x00203623, 0x000 }, - { 0x00000028, 0x00203623, 0x000 }, - { 0x00000017, 0x00203623, 0x000 }, - { 0x00000025, 0x00203623, 0x000 }, - { 0x00000026, 0x00203623, 0x000 }, - { 0x00000015, 0x00203623, 0x000 }, - { 0x00000016, 0x00203623, 0x000 }, - { 0xffffe000, 0x00200c11, 0x000 }, - { 0x00000021, 0x00203623, 0x000 }, - { 0x00000022, 0x00203623, 0x000 }, - { 0x00001fff, 0x00200c11, 0x000 }, - { 0x00000023, 0x00203623, 0x000 }, - { 0x00000024, 0x00203623, 0x000 }, - { 0xf1ffffff, 0x00283a2e, 0x000 }, - { 0x0000001a, 0xc0220e20, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x0000002a, 0x40203620, 0x000 }, - { 0x87000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1f4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x00000030, 0x00203623, 0x000 }, - { 0x9d000000, 0x00204411, 0x000 }, - { 0x0000001f, 0x40214a20, 0x000 }, - { 0x96000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x00000000, 0xc0201000, 0x000 }, - { 0x0000001f, 0x00211624, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x0000001d, 0x00203623, 0x000 }, - { 0x00000003, 0x00281e23, 0x000 }, - { 0x00000008, 0x00222223, 0x000 }, - { 0xfffff000, 0x00282228, 0x000 }, - { 0x00000000, 0x002920e8, 0x000 }, - { 0x0000001f, 0x00203628, 0x000 }, - { 0x00000018, 0x00211e23, 0x000 }, - { 0x00000020, 0x00203627, 0x000 }, - { 0x00000002, 0x00221624, 0x000 }, - { 0x00000000, 0x003014a8, 0x000 }, - { 0x0000001e, 0x00203625, 0x000 }, - { 0x00000003, 0x00211a24, 0x000 }, - { 0x10000000, 0x00281a26, 0x000 }, - { 0xefffffff, 0x00283a2e, 0x000 }, - { 0x00000000, 0x004938ce, 0x678 }, - { 0x00000001, 0x40280a20, 0x000 }, - { 0x00000006, 0x40280e20, 0x000 }, - { 0x00000300, 0xc0281220, 0x000 }, - { 0x00000008, 0x00211224, 0x000 }, - { 0x00000000, 0xc0201620, 0x000 }, - { 0x00000000, 0xc0201a20, 0x000 }, - { 0x00000000, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x563 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00002258, 0x00300a24, 0x000 }, - { 0x00040000, 0x00694622, 0x68a }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00020000, 0x00294a26, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x56b }, - { 0x00000000, 0xc0201c10, 0x000 }, - { 0x00000000, 0xc0400000, 0x579 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x56b }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00002258, 0x00300a24, 0x000 }, - { 0x00040000, 0x00694622, 0x68a }, - { 0x00000000, 0xc0201c10, 0x000 }, - { 0x00000000, 0xc0400000, 0x579 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x56f }, - { 0x00000000, 0xc0201c00, 0x000 }, - { 0x00000000, 0xc0400000, 0x579 }, - { 0x00000004, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x577 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0604800, 0x68f }, - { 0x00000000, 0x00401c10, 0x579 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x0ee00000, 0x57b }, - { 0x00000000, 0x00600000, 0x5c6 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x58c }, - { 0x0000a2b7, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2b6, 0x00604411, 0x68a }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x0000a2c4, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x58a }, - { 0x0000a2d1, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d1, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x00000001, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x59d }, - { 0x0000a2bb, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2ba, 0x00604411, 0x68a }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x0000a2c5, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x59b }, - { 0x0000a2d2, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d2, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x00000002, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5ae }, - { 0x0000a2bf, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2be, 0x00604411, 0x68a }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x0000a2c6, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x5ac }, - { 0x0000a2d3, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d3, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x0000a2c3, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2c2, 0x00604411, 0x68a }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x0000a2c7, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x5bb }, - { 0x0000a2d4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d4, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x85000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0x0000304a, 0x00204411, 0x000 }, - { 0x01000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00400000, 0x5c1 }, - { 0xa4000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0xc0600000, 0x5c6 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000002c, 0x00203621, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000000, 0x002f0230, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5cd }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000030, 0x00403621, 0x5e0 }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00007e00, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x5e0 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a092, 0x00604411, 0x68a }, - { 0x00000031, 0x00203630, 0x000 }, - { 0x0004a093, 0x00604411, 0x68a }, - { 0x00000032, 0x00203630, 0x000 }, - { 0x0004a2b6, 0x00604411, 0x68a }, - { 0x00000033, 0x00203630, 0x000 }, - { 0x0004a2ba, 0x00604411, 0x68a }, - { 0x00000034, 0x00203630, 0x000 }, - { 0x0004a2be, 0x00604411, 0x68a }, - { 0x00000035, 0x00203630, 0x000 }, - { 0x0004a2c2, 0x00604411, 0x68a }, - { 0x00000036, 0x00203630, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x00000005, 0x00204811, 0x000 }, - { 0x0000a1f4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x88000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000001, 0x002f0230, 0x000 }, - { 0x00000000, 0x0ce00000, 0x629 }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x629 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00007e00, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x602 }, - { 0x0000a092, 0x00204411, 0x000 }, - { 0x00000031, 0x00204a2d, 0x000 }, - { 0x0000a093, 0x00204411, 0x000 }, - { 0x00000032, 0x00204a2d, 0x000 }, - { 0x0000a2b6, 0x00204411, 0x000 }, - { 0x00000033, 0x00204a2d, 0x000 }, - { 0x0000a2ba, 0x00204411, 0x000 }, - { 0x00000034, 0x00204a2d, 0x000 }, - { 0x0000a2be, 0x00204411, 0x000 }, - { 0x00000035, 0x00204a2d, 0x000 }, - { 0x0000a2c2, 0x00204411, 0x000 }, - { 0x00000036, 0x00204a2d, 0x000 }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x000001ff, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x628 }, - { 0x00000000, 0x00210221, 0x000 }, - { 0x00000000, 0x14c00000, 0x60b }, - { 0x0004a003, 0x00604411, 0x68a }, - { 0x0000a003, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000001, 0x00210621, 0x000 }, - { 0x00000000, 0x14c00000, 0x610 }, - { 0x0004a010, 0x00604411, 0x68a }, - { 0x0000a010, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000001, 0x00210621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x628 }, - { 0x0004a011, 0x00604411, 0x68a }, - { 0x0000a011, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a012, 0x00604411, 0x68a }, - { 0x0000a012, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a013, 0x00604411, 0x68a }, - { 0x0000a013, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a014, 0x00604411, 0x68a }, - { 0x0000a014, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a015, 0x00604411, 0x68a }, - { 0x0000a015, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a016, 0x00604411, 0x68a }, - { 0x0000a016, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a017, 0x00604411, 0x68a }, - { 0x0000a017, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x0000002c, 0x0080062d, 0x000 }, - { 0xff000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000002, 0x00804811, 0x000 }, - { 0x00000000, 0x0ee00000, 0x63a }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00000002, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x638 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x00001000, 0x00200811, 0x000 }, - { 0x0000002b, 0x00203622, 0x000 }, - { 0x00000000, 0x00600000, 0x63e }, - { 0x00000000, 0x00600000, 0x5c6 }, - { 0x98000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00804811, 0x000 }, - { 0x00000000, 0xc0600000, 0x63e }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000022, 0x00204811, 0x000 }, - { 0x89000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00404811, 0x62a }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00404811, 0x62a }, - { 0x00000000, 0x00600000, 0x659 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0xc0204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36e }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00010000, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x09800000, 0x00204811, 0x000 }, - { 0xffffffff, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x68a }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000004, 0x00404c11, 0x653 }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000004, 0x00291e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0xfffffffb, 0x00281e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000008, 0x00291e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0xfffffff7, 0x00281e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36e }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00010000, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x01800000, 0x00204811, 0x000 }, - { 0xffffffff, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004217f, 0x00604411, 0x68a }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x689 }, - { 0x00000010, 0x00404c11, 0x66f }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x38c00000, 0x000 }, - { 0x0000001d, 0x00200a2d, 0x000 }, - { 0x0000001e, 0x00200e2d, 0x000 }, - { 0x0000001f, 0x0020122d, 0x000 }, - { 0x00000020, 0x0020162d, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000004, 0x00301224, 0x000 }, - { 0x00000000, 0x002f0064, 0x000 }, - { 0x00000000, 0x0cc00000, 0x688 }, - { 0x00000003, 0x00281a22, 0x000 }, - { 0x00000008, 0x00221222, 0x000 }, - { 0xfffff000, 0x00281224, 0x000 }, - { 0x00000000, 0x002910c4, 0x000 }, - { 0x0000001f, 0x00403624, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x1ac00000, 0x68a }, - { 0x9f000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x68d }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x1ac00000, 0x68f }, - { 0x9e000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x692 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00001000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001b, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0xc0204411, 0x000 }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000024, 0x0020222d, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000022, 0x0020222d, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00404811, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x014204ff, 0x05bd0250, 0x000 }, - { 0x01c30168, 0x043f05bd, 0x000 }, - { 0x02250209, 0x02500151, 0x000 }, - { 0x02230245, 0x02a00241, 0x000 }, - { 0x03d705bd, 0x05bd05bd, 0x000 }, - { 0x06460647, 0x031f05bd, 0x000 }, - { 0x05bd05c2, 0x03200340, 0x000 }, - { 0x032a0282, 0x03420334, 0x000 }, - { 0x05bd05bd, 0x05bd05bd, 0x000 }, - { 0x05bd054e, 0x05bd05bd, 0x000 }, - { 0x03ba05bd, 0x04b80344, 0x000 }, - { 0x0497044d, 0x043d05bd, 0x000 }, - { 0x04cd05bd, 0x044104da, 0x000 }, - { 0x044d0504, 0x03510375, 0x000 }, - { 0x05bd05bd, 0x05bd05bd, 0x000 }, - { 0x05bd05bd, 0x05bd05bd, 0x000 }, - { 0x05bd05bd, 0x063c05c4, 0x000 }, - { 0x05bd05bd, 0x000705bd, 0x000 }, - { 0x05bd05bd, 0x05bd05bd, 0x000 }, - { 0x05bd05bd, 0x05bd05bd, 0x000 }, - { 0x03f803ed, 0x04080406, 0x000 }, - { 0x040e040a, 0x040c0410, 0x000 }, - { 0x041c0418, 0x04240420, 0x000 }, - { 0x042c0428, 0x04340430, 0x000 }, - { 0x05bd05bd, 0x043805bd, 0x000 }, - { 0x05bd05bd, 0x05bd05bd, 0x000 }, - { 0x05bd05bd, 0x05bd05bd, 0x000 }, - { 0x00020676, 0x06940006, 0x000 }, -}; - -static const u32 RV630_pfp_microcode[] = { -0xca0400, -0xa00000, -0x7e828b, -0x7c038b, -0x8001b8, -0x7c038b, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xc41838, -0xca2400, -0xca2800, -0x9581a8, -0xc41c3a, -0xc3c000, -0xca0800, -0xca0c00, -0x7c744b, -0xc20005, -0x99c000, -0xc41c3a, -0x7c744c, -0xc0fff0, -0x042c04, -0x309002, -0x7d2500, -0x351402, -0x7d350b, -0x255403, -0x7cd580, -0x259c03, -0x95c004, -0xd5001b, -0x7eddc1, -0x7d9d80, -0xd6801b, -0xd5801b, -0xd4401e, -0xd5401e, -0xd6401e, -0xd6801e, -0xd4801e, -0xd4c01e, -0x9783d3, -0xd5c01e, -0xca0800, -0x80001a, -0xca0c00, -0xe4011e, -0xd4001e, -0x80000c, -0xc41838, -0xe4013e, -0xd4001e, -0x80000c, -0xc41838, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4011e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4013e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca1800, -0xd4401e, -0xd5801e, -0x800053, -0xd40075, -0xd4401e, -0xca0800, -0xca0c00, -0xca1000, -0xd48019, -0xd4c018, -0xd50017, -0xd4801e, -0xd4c01e, -0xd5001e, -0xe2001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0xd48060, -0xd4401e, -0x800000, -0xd4801e, -0xca0800, -0xd48061, -0xd4401e, -0x800000, -0xd4801e, -0xca0800, -0xca0c00, -0xd4401e, -0xd48016, -0xd4c016, -0xd4801e, -0x8001b8, -0xd4c01e, -0xc60843, -0xca0c00, -0xca1000, -0x948004, -0xca1400, -0xe420f3, -0xd42013, -0xd56065, -0xd4e01c, -0xd5201c, -0xd5601c, -0x800000, -0x062001, -0xc60843, -0xca0c00, -0xca1000, -0x9483f7, -0xca1400, -0xe420f3, -0x800079, -0xd42013, -0xc60843, -0xca0c00, -0xca1000, -0x9883ef, -0xca1400, -0xd40064, -0x80008d, -0x000000, -0xc41432, -0xc61843, -0xc4082f, -0x954005, -0xc40c30, -0xd4401e, -0x800000, -0xee001e, -0x9583f5, -0xc41031, -0xd44033, -0xd52065, -0xd4a01c, -0xd4e01c, -0xd5201c, -0xe4015e, -0xd4001e, -0x800000, -0x062001, -0xca1800, -0x0a2001, -0xd60076, -0xc40836, -0x988007, -0xc61045, -0x950110, -0xd4001f, -0xd46062, -0x800000, -0xd42062, -0xcc3835, -0xcc1433, -0x8401bb, -0xd40072, -0xd5401e, -0x800000, -0xee001e, -0xe2001a, -0x8401bb, -0xe2001a, -0xcc104b, -0xcc0447, -0x2c9401, -0x7d098b, -0x984005, -0x7d15cb, -0xd4001a, -0x8001b8, -0xd4006d, -0x344401, -0xcc0c48, -0x98403a, -0xcc2c4a, -0x958004, -0xcc0449, -0x8001b8, -0xd4001a, -0xd4c01a, -0x282801, -0x8400f0, -0xcc1003, -0x98801b, -0x04380c, -0x8400f0, -0xcc1003, -0x988017, -0x043808, -0x8400f0, -0xcc1003, -0x988013, -0x043804, -0x8400f0, -0xcc1003, -0x988014, -0xcc104c, -0x9a8009, -0xcc144d, -0x9840dc, -0xd4006d, -0xcc1848, -0xd5001a, -0xd5401a, -0x8000c9, -0xd5801a, -0x96c0d5, -0xd4006d, -0x8001b8, -0xd4006e, -0x9ac003, -0xd4006d, -0xd4006e, -0x800000, -0xec007f, -0x9ac0cc, -0xd4006d, -0x8001b8, -0xd4006e, -0xcc1403, -0xcc1803, -0xcc1c03, -0x7d9103, -0x7dd583, -0x7d190c, -0x35cc1f, -0x35701f, -0x7cf0cb, -0x7cd08b, -0x880000, -0x7e8e8b, -0x95c004, -0xd4006e, -0x8001b8, -0xd4001a, -0xd4c01a, -0xcc0803, -0xcc0c03, -0xcc1003, -0xcc1403, -0xcc1803, -0xcc1c03, -0xcc2403, -0xcc2803, -0x35c41f, -0x36b01f, -0x7c704b, -0x34f01f, -0x7c704b, -0x35701f, -0x7c704b, -0x7d8881, -0x7dccc1, -0x7e5101, -0x7e9541, -0x7c9082, -0x7cd4c2, -0x7c848b, -0x9ac003, -0x7c8c8b, -0x2c8801, -0x98809e, -0xd4006d, -0x98409c, -0xd4006e, -0xcc084c, -0xcc0c4d, -0xcc1048, -0xd4801a, -0xd4c01a, -0x800101, -0xd5001a, -0xcc0832, -0xd40032, -0x9482d9, -0xca0c00, -0xd4401e, -0x800000, -0xd4001e, -0xe4011e, -0xd4001e, -0xca0800, -0xca0c00, -0xca1000, -0xd4401e, -0xca1400, -0xd4801e, -0xd4c01e, -0xd5001e, -0xd5401e, -0xd54034, -0x800000, -0xee001e, -0x280404, -0xe2001a, -0xe2001a, -0xd4401a, -0xca3800, -0xcc0803, -0xcc0c03, -0xcc0c03, -0xcc0c03, -0x9882bd, -0x000000, -0x8401bb, -0xd7a06f, -0x800000, -0xee001f, -0xca0400, -0xc2ff00, -0xcc0834, -0xc13fff, -0x7c74cb, -0x7cc90b, -0x7d010f, -0x9902b0, -0x7c738b, -0x8401bb, -0xd7a06f, -0x800000, -0xee001f, -0xca0800, -0x281900, -0x7d898b, -0x958014, -0x281404, -0xca0c00, -0xca1000, -0xca1c00, -0xca2400, -0xe2001f, -0xd4c01a, -0xd5001a, -0xd5401a, -0xcc1803, -0xcc2c03, -0xcc2c03, -0xcc2c03, -0x7da58b, -0x7d9c47, -0x984297, -0x000000, -0x800161, -0xd4c01a, -0xd4401e, -0xd4801e, -0x800000, -0xee001e, -0xe4011e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4013e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0x248c06, -0x0ccc06, -0x98c006, -0xcc104e, -0x990004, -0xd40073, -0xe4011e, -0xd4001e, -0xd4401e, -0xd4801e, -0x800000, -0xee001e, -0xca0800, -0xca0c00, -0x34d018, -0x251001, -0x950021, -0xc17fff, -0xca1000, -0xca1400, -0xca1800, -0xd4801d, -0xd4c01d, -0x7db18b, -0xc14202, -0xc2c001, -0xd5801d, -0x34dc0e, -0x7d5d4c, -0x7f734c, -0xd7401e, -0xd5001e, -0xd5401e, -0xc14200, -0xc2c000, -0x099c01, -0x31dc10, -0x7f5f4c, -0x7f734c, -0x042802, -0x7d8380, -0xd5a86f, -0xd58066, -0xd7401e, -0xec005e, -0xc82402, -0xc82402, -0x8001b8, -0xd60076, -0xd4401e, -0xd4801e, -0xd4c01e, -0x800000, -0xee001e, -0x800000, -0xee001f, -0xd4001f, -0x800000, -0xd4001f, -0xd4001f, -0x880000, -0xd4001f, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x010171, -0x020178, -0x03008f, -0x04007f, -0x050003, -0x06003f, -0x070032, -0x08012c, -0x090046, -0x0a0036, -0x1001b6, -0x1700a2, -0x22013a, -0x230149, -0x2000b4, -0x240125, -0x27004d, -0x28006a, -0x2a0060, -0x2b0052, -0x2f0065, -0x320087, -0x34017f, -0x3c0156, -0x3f0072, -0x41018c, -0x44012e, -0x550173, -0x56017a, -0x60000b, -0x610034, -0x620038, -0x630038, -0x640038, -0x650038, -0x660038, -0x670038, -0x68003a, -0x690041, -0x6a0048, -0x6b0048, -0x6c0048, -0x6d0048, -0x6e0048, -0x6f0048, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -}; - -static const u32 RV635_cp_microcode[][3] = { - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0000ffff, 0x00284621, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00000000, 0x00e00000, 0x000 }, - { 0x00010000, 0xc0294620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x00000000, 0x00600000, 0x62e }, - { 0x00000000, 0x00600000, 0x642 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000f00, 0x00281622, 0x000 }, - { 0x00000008, 0x00211625, 0x000 }, - { 0x00000018, 0x00203625, 0x000 }, - { 0x8d000000, 0x00204411, 0x000 }, - { 0x00000004, 0x002f0225, 0x000 }, - { 0x00000000, 0x0ce00000, 0x018 }, - { 0x00412000, 0x00404811, 0x019 }, - { 0x00422000, 0x00204811, 0x000 }, - { 0x8e000000, 0x00204411, 0x000 }, - { 0x00000028, 0x00204a2d, 0x000 }, - { 0x90000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x0000000c, 0x00211622, 0x000 }, - { 0x00000003, 0x00281625, 0x000 }, - { 0x00000019, 0x00211a22, 0x000 }, - { 0x00000004, 0x00281a26, 0x000 }, - { 0x00000000, 0x002914c5, 0x000 }, - { 0x00000019, 0x00203625, 0x000 }, - { 0x00000000, 0x003a1402, 0x000 }, - { 0x00000016, 0x00211625, 0x000 }, - { 0x00000003, 0x00281625, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0xfffffffc, 0x00280e23, 0x000 }, - { 0x00000000, 0x002914a3, 0x000 }, - { 0x00000017, 0x00203625, 0x000 }, - { 0x00008000, 0x00280e22, 0x000 }, - { 0x00000007, 0x00220e23, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x20000000, 0x00280e22, 0x000 }, - { 0x00000006, 0x00210e23, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x00000000, 0x00220222, 0x000 }, - { 0x00000000, 0x14e00000, 0x038 }, - { 0x00000000, 0x2ee00000, 0x035 }, - { 0x00000000, 0x2ce00000, 0x037 }, - { 0x00000000, 0x00400e2d, 0x039 }, - { 0x00000008, 0x00200e2d, 0x000 }, - { 0x00000009, 0x0040122d, 0x046 }, - { 0x00000001, 0x00400e2d, 0x039 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x003ffffc, 0x00281223, 0x000 }, - { 0x00000002, 0x00221224, 0x000 }, - { 0x0000001f, 0x00211e23, 0x000 }, - { 0x00000000, 0x14e00000, 0x03e }, - { 0x00000008, 0x00401c11, 0x041 }, - { 0x0000000d, 0x00201e2d, 0x000 }, - { 0x0000000f, 0x00281e27, 0x000 }, - { 0x00000003, 0x00221e27, 0x000 }, - { 0x7fc00000, 0x00281a23, 0x000 }, - { 0x00000014, 0x00211a26, 0x000 }, - { 0x00000001, 0x00331a26, 0x000 }, - { 0x00000008, 0x00221a26, 0x000 }, - { 0x00000000, 0x00290cc7, 0x000 }, - { 0x00000027, 0x00203624, 0x000 }, - { 0x00007f00, 0x00281221, 0x000 }, - { 0x00001400, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x04b }, - { 0x00000001, 0x00290e23, 0x000 }, - { 0x0000000e, 0x00203623, 0x000 }, - { 0x0000e000, 0x00204411, 0x000 }, - { 0xfff80000, 0x00294a23, 0x000 }, - { 0x00000000, 0x003a2c02, 0x000 }, - { 0x00000002, 0x00220e2b, 0x000 }, - { 0xfc000000, 0x00280e23, 0x000 }, - { 0x0000000f, 0x00203623, 0x000 }, - { 0x00001fff, 0x00294a23, 0x000 }, - { 0x00000027, 0x00204a2d, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000029, 0x00200e2d, 0x000 }, - { 0x060a0200, 0x00294a23, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14e00000, 0x061 }, - { 0x00000000, 0x2ee00000, 0x05f }, - { 0x00000000, 0x2ce00000, 0x05e }, - { 0x00000000, 0x00400e2d, 0x062 }, - { 0x00000001, 0x00400e2d, 0x062 }, - { 0x0000000a, 0x00200e2d, 0x000 }, - { 0x0000000b, 0x0040122d, 0x06a }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x003ffffc, 0x00281223, 0x000 }, - { 0x00000002, 0x00221224, 0x000 }, - { 0x7fc00000, 0x00281623, 0x000 }, - { 0x00000014, 0x00211625, 0x000 }, - { 0x00000001, 0x00331625, 0x000 }, - { 0x80000000, 0x00280e23, 0x000 }, - { 0x00000000, 0x00290ca3, 0x000 }, - { 0x3ffffc00, 0x00290e23, 0x000 }, - { 0x0000001f, 0x00211e23, 0x000 }, - { 0x00000000, 0x14e00000, 0x06d }, - { 0x00000100, 0x00401c11, 0x070 }, - { 0x0000000d, 0x00201e2d, 0x000 }, - { 0x000000f0, 0x00281e27, 0x000 }, - { 0x00000004, 0x00221e27, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0xfffff0ff, 0x00281a30, 0x000 }, - { 0x0000a028, 0x00204411, 0x000 }, - { 0x00000000, 0x002948e6, 0x000 }, - { 0x0000a018, 0x00204411, 0x000 }, - { 0x3fffffff, 0x00284a23, 0x000 }, - { 0x0000a010, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000030, 0x0020162d, 0x000 }, - { 0x00000002, 0x00291625, 0x000 }, - { 0x00000030, 0x00203625, 0x000 }, - { 0x00000025, 0x0020162d, 0x000 }, - { 0x00000000, 0x002f00a3, 0x000 }, - { 0x00000000, 0x0cc00000, 0x083 }, - { 0x00000026, 0x0020162d, 0x000 }, - { 0x00000000, 0x002f00a4, 0x000 }, - { 0x00000000, 0x0cc00000, 0x084 }, - { 0x00000000, 0x00400000, 0x08a }, - { 0x00000025, 0x00203623, 0x000 }, - { 0x00000026, 0x00203624, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x08a }, - { 0x00000000, 0x00600000, 0x665 }, - { 0x00000000, 0x00600000, 0x659 }, - { 0x00000002, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x08d }, - { 0x00000012, 0xc0403620, 0x093 }, - { 0x00000000, 0x2ee00000, 0x091 }, - { 0x00000000, 0x2ce00000, 0x090 }, - { 0x00000002, 0x00400e2d, 0x092 }, - { 0x00000003, 0x00400e2d, 0x092 }, - { 0x0000000c, 0x00200e2d, 0x000 }, - { 0x00000012, 0x00203623, 0x000 }, - { 0x00000003, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x098 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x0a0 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x2ee00000, 0x09e }, - { 0x00000000, 0x2ce00000, 0x09d }, - { 0x00000002, 0x00400e2d, 0x09f }, - { 0x00000003, 0x00400e2d, 0x09f }, - { 0x0000000c, 0x00200e2d, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000000, 0x003a0c02, 0x000 }, - { 0x003f0000, 0x00280e23, 0x000 }, - { 0x00000010, 0x00210e23, 0x000 }, - { 0x00000011, 0x00203623, 0x000 }, - { 0x0000001e, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0a7 }, - { 0x00000016, 0xc0203620, 0x000 }, - { 0x0000001f, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0aa }, - { 0x00000015, 0xc0203620, 0x000 }, - { 0x00000008, 0x00210e2b, 0x000 }, - { 0x0000007f, 0x00280e23, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0e1 }, - { 0x00000000, 0x27000000, 0x000 }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0b3 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x0000000c, 0x00221e30, 0x000 }, - { 0x99800000, 0x00204411, 0x000 }, - { 0x00000004, 0x0020122d, 0x000 }, - { 0x00000008, 0x00221224, 0x000 }, - { 0x00000010, 0x00201811, 0x000 }, - { 0x00000000, 0x00291ce4, 0x000 }, - { 0x00000000, 0x00604807, 0x12f }, - { 0x9b000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x9c000000, 0x00204411, 0x000 }, - { 0x00000000, 0x0033146f, 0x000 }, - { 0x00000001, 0x00333e23, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0x00203c05, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x00000000, 0x00201010, 0x000 }, - { 0x0000e007, 0x00204411, 0x000 }, - { 0x0000000f, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0cb }, - { 0x00f8ff08, 0x00204811, 0x000 }, - { 0x98000000, 0x00404811, 0x0dc }, - { 0x000000f0, 0x00280e22, 0x000 }, - { 0x000000a0, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x0da }, - { 0x00000011, 0x00200e2d, 0x000 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0d5 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0d4 }, - { 0x00003f00, 0x00400c11, 0x0d6 }, - { 0x00001f00, 0x00400c11, 0x0d6 }, - { 0x00000f00, 0x00200c11, 0x000 }, - { 0x00380009, 0x00294a23, 0x000 }, - { 0x3f000000, 0x00280e2b, 0x000 }, - { 0x00000002, 0x00220e23, 0x000 }, - { 0x00000007, 0x00494a23, 0x0dc }, - { 0x00380f09, 0x00204811, 0x000 }, - { 0x68000007, 0x00204811, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a24, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000a202, 0x00204411, 0x000 }, - { 0x00ff0000, 0x00280e22, 0x000 }, - { 0x00000080, 0x00294a23, 0x000 }, - { 0x00000027, 0x00200e2d, 0x000 }, - { 0x00000026, 0x0020122d, 0x000 }, - { 0x00000000, 0x002f0083, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0ea }, - { 0x00000000, 0x00600000, 0x65f }, - { 0x00000000, 0x00400000, 0x0eb }, - { 0x00000000, 0x00600000, 0x662 }, - { 0x00000007, 0x0020222d, 0x000 }, - { 0x00000005, 0x00220e22, 0x000 }, - { 0x00100000, 0x00280e23, 0x000 }, - { 0x00000000, 0x00292068, 0x000 }, - { 0x00000000, 0x003a0c02, 0x000 }, - { 0x000000ef, 0x00280e23, 0x000 }, - { 0x00000000, 0x00292068, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0x00000003, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x0f8 }, - { 0x0000000b, 0x00210228, 0x000 }, - { 0x00000000, 0x14c00000, 0x0f8 }, - { 0x00000400, 0x00292228, 0x000 }, - { 0x00000014, 0x00203628, 0x000 }, - { 0x0000001c, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x0fd }, - { 0x0000a30c, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000001e, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x10b }, - { 0x0000a30f, 0x00204411, 0x000 }, - { 0x00000011, 0x00200e2d, 0x000 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x104 }, - { 0xffffffff, 0x00404811, 0x10b }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x107 }, - { 0x0000ffff, 0x00404811, 0x10b }, - { 0x00000004, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x10a }, - { 0x000000ff, 0x00404811, 0x10b }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0002c400, 0x00204411, 0x000 }, - { 0x0000001f, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x112 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x00000013, 0x00203623, 0x000 }, - { 0x00000018, 0x40224a20, 0x000 }, - { 0x00000010, 0xc0424a20, 0x114 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x00000013, 0x00203623, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000000a, 0x00201011, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x11b }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00531224, 0x117 }, - { 0xffbfffff, 0x00283a2e, 0x000 }, - { 0x0000001b, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x12e }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0x00000018, 0x00220e30, 0x000 }, - { 0xfc000000, 0x00280e23, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x00000000, 0x00201010, 0x000 }, - { 0x0000e00e, 0x00204411, 0x000 }, - { 0x07f8ff08, 0x00204811, 0x000 }, - { 0x00000000, 0x00294a23, 0x000 }, - { 0x0000001c, 0x00201e2d, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a24, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x00800000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204806, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x68a }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x689 }, - { 0x00000004, 0x00404c11, 0x135 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x0000001c, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68a }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x13c }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00000000, 0x00600000, 0x160 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000ffff, 0x40280620, 0x000 }, - { 0x00000010, 0xc0210a20, 0x000 }, - { 0x00000000, 0x00341461, 0x000 }, - { 0x00000000, 0x00741882, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x147 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x160 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x00000010, 0x40211620, 0x000 }, - { 0x0000ffff, 0xc0681a20, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x158 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000001, 0x00300a2f, 0x000 }, - { 0x00000001, 0x00210a22, 0x000 }, - { 0x00000003, 0x00384a22, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001a, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600000, 0x18f }, - { 0x00000000, 0x00600000, 0x1a0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00202c08, 0x000 }, - { 0x00000000, 0x00202411, 0x000 }, - { 0x00000000, 0x00202811, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000002, 0x00221e29, 0x000 }, - { 0x00000000, 0x007048eb, 0x19c }, - { 0x00000000, 0x00600000, 0x2bb }, - { 0x00000001, 0x40330620, 0x000 }, - { 0x00000000, 0xc0302409, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ae00000, 0x181 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x00000000, 0x00400000, 0x186 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x186 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000001, 0x00530621, 0x182 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0604800, 0x197 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000011, 0x0020062d, 0x000 }, - { 0x00000000, 0x0078042a, 0x2fb }, - { 0x00000000, 0x00202809, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x174 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000210, 0x00600411, 0x315 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x194 }, - { 0x00000015, 0xc0203620, 0x000 }, - { 0x00000016, 0xc0203620, 0x000 }, - { 0x3f800000, 0x00200411, 0x000 }, - { 0x46000000, 0x00600811, 0x1b2 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x19b }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000021, 0x00804811, 0x000 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000ffff, 0x40281620, 0x000 }, - { 0x00000010, 0xc0811a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000008, 0x00221e30, 0x000 }, - { 0x00000029, 0x00201a2d, 0x000 }, - { 0x0000e000, 0x00204411, 0x000 }, - { 0xfffbff09, 0x00204811, 0x000 }, - { 0x0000000f, 0x0020222d, 0x000 }, - { 0x00001fff, 0x00294a28, 0x000 }, - { 0x00000006, 0x0020222d, 0x000 }, - { 0x00000000, 0x002920e8, 0x000 }, - { 0x00000000, 0x00204808, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a26, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000100, 0x00201811, 0x000 }, - { 0x00000008, 0x00621e28, 0x12f }, - { 0x00000008, 0x00822228, 0x000 }, - { 0x0002c000, 0x00204411, 0x000 }, - { 0x00000015, 0x00600e2d, 0x1bd }, - { 0x00000016, 0x00600e2d, 0x1bd }, - { 0x0000c008, 0x00204411, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0x00000000, 0x14c00000, 0x1b9 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0x39000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00804802, 0x000 }, - { 0x00000018, 0x00202e2d, 0x000 }, - { 0x00000000, 0x003b0d63, 0x000 }, - { 0x00000008, 0x00224a23, 0x000 }, - { 0x00000010, 0x00224a23, 0x000 }, - { 0x00000018, 0x00224a23, 0x000 }, - { 0x00000000, 0x00804803, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00001000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00000007, 0x0021062f, 0x000 }, - { 0x00000013, 0x00200a2d, 0x000 }, - { 0x00000001, 0x00202c11, 0x000 }, - { 0x0000ffff, 0x40282220, 0x000 }, - { 0x0000000f, 0x00262228, 0x000 }, - { 0x00000010, 0x40212620, 0x000 }, - { 0x0000000f, 0x00262629, 0x000 }, - { 0x00000000, 0x00202802, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001b, 0x00204811, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1e0 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000081, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000080, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1dc }, - { 0x00000000, 0x00600000, 0x1e9 }, - { 0x00000001, 0x00531e27, 0x1d8 }, - { 0x00000001, 0x00202c11, 0x000 }, - { 0x0000001f, 0x00280a22, 0x000 }, - { 0x0000001f, 0x00282a2a, 0x000 }, - { 0x00000001, 0x00530621, 0x1d1 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000002, 0x00304a2f, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000001, 0x00301e2f, 0x000 }, - { 0x00000000, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x1e9 }, - { 0x00000001, 0x00531e27, 0x1e5 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x0000000f, 0x00260e23, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000000f, 0x00261224, 0x000 }, - { 0x00000000, 0x00201411, 0x000 }, - { 0x00000000, 0x00601811, 0x2bb }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022b, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1f8 }, - { 0x00000010, 0x00221628, 0x000 }, - { 0xffff0000, 0x00281625, 0x000 }, - { 0x0000ffff, 0x00281a29, 0x000 }, - { 0x00000000, 0x002948c5, 0x000 }, - { 0x00000000, 0x0020480a, 0x000 }, - { 0x00000000, 0x00202c11, 0x000 }, - { 0x00000010, 0x00221623, 0x000 }, - { 0xffff0000, 0x00281625, 0x000 }, - { 0x0000ffff, 0x00281a24, 0x000 }, - { 0x00000000, 0x002948c5, 0x000 }, - { 0x00000000, 0x00731503, 0x205 }, - { 0x00000000, 0x00201805, 0x000 }, - { 0x00000000, 0x00731524, 0x205 }, - { 0x00000000, 0x002d14c5, 0x000 }, - { 0x00000000, 0x003008a2, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00202802, 0x000 }, - { 0x00000000, 0x00202003, 0x000 }, - { 0x00000000, 0x00802404, 0x000 }, - { 0x0000000f, 0x00210225, 0x000 }, - { 0x00000000, 0x14c00000, 0x689 }, - { 0x00000000, 0x002b1405, 0x000 }, - { 0x00000001, 0x00901625, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001a, 0x00294a22, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00384a21, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000ffff, 0x40281220, 0x000 }, - { 0x00000010, 0xc0211a20, 0x000 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211620, 0x000 }, - { 0x00000000, 0x00741465, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00000001, 0x00330621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0cc00000, 0x219 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x212 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x642 }, - { 0x00000000, 0x0040040f, 0x213 }, - { 0x00000000, 0x00600000, 0x62e }, - { 0x00000000, 0x00600000, 0x642 }, - { 0x00000210, 0x00600411, 0x315 }, - { 0x00000000, 0x00600000, 0x1a0 }, - { 0x00000000, 0x00600000, 0x19c }, - { 0x00000000, 0x00600000, 0x2bb }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204808, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ae00000, 0x232 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x00000000, 0x00400000, 0x236 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x236 }, - { 0x00000000, 0xc0404800, 0x233 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x00600411, 0x2fb }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x62e }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000018, 0x40210a20, 0x000 }, - { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x24c }, - { 0x00000014, 0x0020222d, 0x000 }, - { 0x00080101, 0x00292228, 0x000 }, - { 0x00000014, 0x00203628, 0x000 }, - { 0x0000a30c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x251 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000010, 0x00600411, 0x315 }, - { 0x3f800000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x00000000, 0x00600000, 0x27c }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000001, 0x00211e27, 0x000 }, - { 0x00000000, 0x14e00000, 0x26a }, - { 0x00000012, 0x00201e2d, 0x000 }, - { 0x0000ffff, 0x00281e27, 0x000 }, - { 0x00000000, 0x00341c27, 0x000 }, - { 0x00000000, 0x12c00000, 0x25f }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f00e5, 0x000 }, - { 0x00000000, 0x08c00000, 0x262 }, - { 0x00000000, 0x00201407, 0x000 }, - { 0x00000012, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00211e27, 0x000 }, - { 0x00000000, 0x00341c47, 0x000 }, - { 0x00000000, 0x12c00000, 0x267 }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f00e6, 0x000 }, - { 0x00000000, 0x08c00000, 0x26a }, - { 0x00000000, 0x00201807, 0x000 }, - { 0x00000000, 0x00600000, 0x2c1 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000000, 0x00342023, 0x000 }, - { 0x00000000, 0x12c00000, 0x272 }, - { 0x00000000, 0x00342044, 0x000 }, - { 0x00000000, 0x12c00000, 0x271 }, - { 0x00000016, 0x00404811, 0x276 }, - { 0x00000018, 0x00404811, 0x276 }, - { 0x00000000, 0x00342044, 0x000 }, - { 0x00000000, 0x12c00000, 0x275 }, - { 0x00000017, 0x00404811, 0x276 }, - { 0x00000019, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0x00604411, 0x2e9 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x256 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000010, 0x40210620, 0x000 }, - { 0x0000ffff, 0xc0280a20, 0x000 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x00000010, 0x40211620, 0x000 }, - { 0x0000ffff, 0xc0881a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x00000000, 0x00600000, 0x62e }, - { 0x00000000, 0xc0600000, 0x2a3 }, - { 0x00000005, 0x00200a2d, 0x000 }, - { 0x00000008, 0x00220a22, 0x000 }, - { 0x0000002b, 0x00201a2d, 0x000 }, - { 0x0000001c, 0x00201e2d, 0x000 }, - { 0x00007000, 0x00281e27, 0x000 }, - { 0x00000000, 0x00311ce6, 0x000 }, - { 0x0000002a, 0x00201a2d, 0x000 }, - { 0x0000000c, 0x00221a26, 0x000 }, - { 0x00000000, 0x002f00e6, 0x000 }, - { 0x00000000, 0x06e00000, 0x292 }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x0000002b, 0x00203623, 0x000 }, - { 0x00000010, 0x00201811, 0x000 }, - { 0x00000000, 0x00691ce2, 0x12f }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x29d }, - { 0x00000001, 0x00333e2f, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000001c, 0x00403627, 0x000 }, - { 0x0000000c, 0xc0220a20, 0x000 }, - { 0x00000029, 0x00203622, 0x000 }, - { 0x00000028, 0xc0403620, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000009, 0x00204811, 0x000 }, - { 0xa1000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002c1ce3, 0x000 }, - { 0x00000021, 0x00203627, 0x000 }, - { 0x00000022, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002c1ce4, 0x000 }, - { 0x00000022, 0x00203627, 0x000 }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120a3, 0x000 }, - { 0x00000000, 0x002d1d07, 0x000 }, - { 0x00000023, 0x00203627, 0x000 }, - { 0x00000024, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x00000000, 0x002d1d07, 0x000 }, - { 0x00000024, 0x00803627, 0x000 }, - { 0x00000021, 0x00203623, 0x000 }, - { 0x00000022, 0x00203624, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000023, 0x00203627, 0x000 }, - { 0x00000000, 0x00311cc4, 0x000 }, - { 0x00000024, 0x00803627, 0x000 }, - { 0x0000001a, 0x00203627, 0x000 }, - { 0x0000001b, 0x00203628, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14c00000, 0x2dc }, - { 0x00000000, 0x00400000, 0x2d9 }, - { 0x0000001a, 0x00203627, 0x000 }, - { 0x0000001b, 0x00203628, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x2d9 }, - { 0x00000003, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x2dc }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002e00e1, 0x000 }, - { 0x00000000, 0x02c00000, 0x2dc }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120a1, 0x000 }, - { 0x00000000, 0x002e00e8, 0x000 }, - { 0x00000000, 0x06c00000, 0x2dc }, - { 0x00000024, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002e00e2, 0x000 }, - { 0x00000000, 0x02c00000, 0x2dc }, - { 0x00000022, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120c2, 0x000 }, - { 0x00000000, 0x002e00e8, 0x000 }, - { 0x00000000, 0x06c00000, 0x2dc }, - { 0x00000000, 0x00600000, 0x665 }, - { 0x00000000, 0x00600000, 0x2b5 }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x00000000, 0x00600000, 0x2b5 }, - { 0x00000000, 0x00600000, 0x65c }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x00000000, 0x00600000, 0x2a7 }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x0000001a, 0x00201e2d, 0x000 }, - { 0x0000001b, 0x0080222d, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000010, 0x00221e21, 0x000 }, - { 0x00000000, 0x00294847, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000000, 0x00311ca1, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294847, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000010, 0x00221e21, 0x000 }, - { 0x00000000, 0x003120c2, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000001, 0x00220a21, 0x000 }, - { 0x00000000, 0x003308a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000001, 0x00220a21, 0x000 }, - { 0x00000000, 0x003008a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x003808c5, 0x000 }, - { 0x00000000, 0x00300841, 0x000 }, - { 0x00000001, 0x00220a22, 0x000 }, - { 0x00000000, 0x003308a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000017, 0x0020222d, 0x000 }, - { 0x00000000, 0x14c00000, 0x318 }, - { 0xffffffef, 0x00280621, 0x000 }, - { 0x00000014, 0x0020222d, 0x000 }, - { 0x0000f8e0, 0x00204411, 0x000 }, - { 0x00000000, 0x00294901, 0x000 }, - { 0x00000000, 0x00894901, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00804811, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x97000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00002257, 0x00204411, 0x000 }, - { 0x00000003, 0xc0484a20, 0x000 }, - { 0x0000225d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0x00600000, 0x642 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00384a22, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x40204800, 0x000 }, - { 0x00000001, 0x40304a20, 0x000 }, - { 0x00000002, 0xc0304a20, 0x000 }, - { 0x00000001, 0x00530a22, 0x34b }, - { 0x0000003f, 0xc0280a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000018, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68a }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x354 }, - { 0x00000014, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x364 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00604802, 0x36e }, - { 0x00002100, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x36a }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x35f }, - { 0x00000028, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5bd }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x35f }, - { 0x0000002c, 0x00203626, 0x000 }, - { 0x00000049, 0x00201811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x00000001, 0x00331a26, 0x000 }, - { 0x00000000, 0x002f0226, 0x000 }, - { 0x00000000, 0x0cc00000, 0x370 }, - { 0x0000002c, 0x00801a2d, 0x000 }, - { 0x0000003f, 0xc0280a20, 0x000 }, - { 0x00000015, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x386 }, - { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3b1 }, - { 0x00000016, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3b5 }, - { 0x00000020, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x39c }, - { 0x0000000f, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3a8 }, - { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3a8 }, - { 0x0000001e, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x390 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x08000000, 0x00290a22, 0x000 }, - { 0x00000003, 0x40210e20, 0x000 }, - { 0x0000000c, 0xc0211220, 0x000 }, - { 0x00080000, 0x00281224, 0x000 }, - { 0x00000014, 0xc0221620, 0x000 }, - { 0x00000000, 0x002914a4, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x002948a2, 0x000 }, - { 0x0000a1fe, 0x00204411, 0x000 }, - { 0x00000000, 0x00404803, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68a }, - { 0x00000015, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x392 }, - { 0x0000210e, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000017, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68a }, - { 0x00000003, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x39e }, - { 0x00002108, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x80000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000010, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x3ae }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000006, 0x00404811, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36e }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x0000001d, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x3ce }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000018, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68a }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x3c0 }, - { 0x00002100, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0xbabecafe, 0x00204811, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000004, 0x00404811, 0x000 }, - { 0x00002170, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000a, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x3d3 }, - { 0x8c000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00003fff, 0x40280a20, 0x000 }, - { 0x80000000, 0x40280e20, 0x000 }, - { 0x40000000, 0xc0281220, 0x000 }, - { 0x00040000, 0x00694622, 0x68a }, - { 0x00000000, 0x00201410, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x3e1 }, - { 0x00000000, 0xc0401800, 0x3e4 }, - { 0x00003fff, 0xc0281a20, 0x000 }, - { 0x00040000, 0x00694626, 0x68a }, - { 0x00000000, 0x00201810, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x3e7 }, - { 0x00000000, 0xc0401c00, 0x3ea }, - { 0x00003fff, 0xc0281e20, 0x000 }, - { 0x00040000, 0x00694627, 0x68a }, - { 0x00000000, 0x00201c10, 0x000 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0x002820c5, 0x000 }, - { 0x00000000, 0x004948e8, 0x000 }, - { 0xa5800000, 0x00200811, 0x000 }, - { 0x00002000, 0x00200c11, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x40204800, 0x000 }, - { 0x0000001f, 0xc0210220, 0x000 }, - { 0x00000000, 0x14c00000, 0x3f7 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0000ffff, 0xc0481220, 0x3ff }, - { 0xa7800000, 0x00200811, 0x000 }, - { 0x0000a000, 0x00200c11, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x83000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00304883, 0x000 }, - { 0x84000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1d000000, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0xa9800000, 0x00200811, 0x000 }, - { 0x0000c000, 0x00400c11, 0x3fa }, - { 0xab800000, 0x00200811, 0x000 }, - { 0x0000f8e0, 0x00400c11, 0x3fa }, - { 0xad800000, 0x00200811, 0x000 }, - { 0x0000f880, 0x00400c11, 0x3fa }, - { 0xb3800000, 0x00200811, 0x000 }, - { 0x0000f3fc, 0x00400c11, 0x3fa }, - { 0xaf800000, 0x00200811, 0x000 }, - { 0x0000e000, 0x00400c11, 0x3fa }, - { 0xb1800000, 0x00200811, 0x000 }, - { 0x0000f000, 0x00400c11, 0x3fa }, - { 0x83000000, 0x00204411, 0x000 }, - { 0x00002148, 0x00204811, 0x000 }, - { 0x84000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1d000000, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x01182000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0218a000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0318c000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0418f8e0, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0518f880, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0618e000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0718f000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0818f3fc, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00000030, 0x00200a2d, 0x000 }, - { 0x00000000, 0xc0290c40, 0x000 }, - { 0x00000030, 0x00203623, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x86000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00404801, 0x000 }, - { 0x85000000, 0xc0204411, 0x000 }, - { 0x00000000, 0x00404801, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x68a }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000000, 0x00404c02, 0x448 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x00000000, 0xc0201000, 0x000 }, - { 0x00000000, 0xc0201400, 0x000 }, - { 0x00000000, 0xc0201800, 0x000 }, - { 0x00000000, 0xc0201c00, 0x000 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x456 }, - { 0x00000000, 0xc0202000, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x00000010, 0x00280a23, 0x000 }, - { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x45e }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0x00694624, 0x68a }, - { 0x00000000, 0x00400000, 0x463 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x00604805, 0x68f }, - { 0x00000000, 0x002824f0, 0x000 }, - { 0x00000007, 0x00280a23, 0x000 }, - { 0x00000001, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x46a }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x04e00000, 0x483 }, - { 0x00000000, 0x00400000, 0x490 }, - { 0x00000002, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x46f }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x02e00000, 0x483 }, - { 0x00000000, 0x00400000, 0x490 }, - { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x474 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x0ce00000, 0x483 }, - { 0x00000000, 0x00400000, 0x490 }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x479 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x0ae00000, 0x483 }, - { 0x00000000, 0x00400000, 0x490 }, - { 0x00000005, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x47e }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x06e00000, 0x483 }, - { 0x00000000, 0x00400000, 0x490 }, - { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x483 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x08e00000, 0x483 }, - { 0x00000000, 0x00400000, 0x490 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x000 }, - { 0x00000008, 0x00210a23, 0x000 }, - { 0x00000000, 0x14c00000, 0x48d }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x00000000, 0xc0204400, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x496 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x00404c08, 0x456 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x00000011, 0x40211220, 0x000 }, - { 0x00000012, 0x40211620, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00210225, 0x000 }, - { 0x00000000, 0x14e00000, 0x4a0 }, - { 0x00040000, 0xc0494a20, 0x4a1 }, - { 0xfffbffff, 0xc0284a20, 0x000 }, - { 0x00000000, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x4ad }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000c, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x4a9 }, - { 0xa0000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000004, 0x00204811, 0x000 }, - { 0x0000216b, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204810, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000005, 0x00204811, 0x000 }, - { 0x0000216c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204810, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00400000, 0x4a7 }, - { 0x00000000, 0xc0210a20, 0x000 }, - { 0x00000000, 0x14c00000, 0x4c0 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0604800, 0x68f }, - { 0x00000000, 0x00400000, 0x4c4 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0xc0294620, 0x000 }, - { 0x00000000, 0xc0600000, 0x68a }, - { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x4cb }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x00000000, 0xc0204400, 0x000 }, - { 0x00000000, 0xc0404810, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x68a }, - { 0x00000000, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x4cd }, - { 0x00002180, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000003, 0x00333e2f, 0x000 }, - { 0x00000001, 0x00210221, 0x000 }, - { 0x00000000, 0x14e00000, 0x4fd }, - { 0x0000002c, 0x00200a2d, 0x000 }, - { 0x00040000, 0x18e00c11, 0x4ec }, - { 0x00000001, 0x00333e2f, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xd8c04800, 0x4e0 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000002d, 0x0020122d, 0x000 }, - { 0x00000000, 0x00290c83, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000011, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000000, 0x00400000, 0x4a7 }, - { 0x0000002c, 0xc0203620, 0x000 }, - { 0x0000002d, 0xc0403620, 0x000 }, - { 0x0000000f, 0x00210221, 0x000 }, - { 0x00000000, 0x14c00000, 0x502 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0xd9000000, 0x000 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0xb5000000, 0x00204411, 0x000 }, - { 0x00002000, 0x00204811, 0x000 }, - { 0xb6000000, 0x00204411, 0x000 }, - { 0x0000a000, 0x00204811, 0x000 }, - { 0xb7000000, 0x00204411, 0x000 }, - { 0x0000c000, 0x00204811, 0x000 }, - { 0xb8000000, 0x00204411, 0x000 }, - { 0x0000f8e0, 0x00204811, 0x000 }, - { 0xb9000000, 0x00204411, 0x000 }, - { 0x0000f880, 0x00204811, 0x000 }, - { 0xba000000, 0x00204411, 0x000 }, - { 0x0000e000, 0x00204811, 0x000 }, - { 0xbb000000, 0x00204411, 0x000 }, - { 0x0000f000, 0x00204811, 0x000 }, - { 0xbc000000, 0x00204411, 0x000 }, - { 0x0000f3fc, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000002, 0x00204811, 0x000 }, - { 0x000000ff, 0x00280e30, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x516 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0x14c00000, 0x52b }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x0000001c, 0x00203623, 0x000 }, - { 0x0000002b, 0x00203623, 0x000 }, - { 0x00000029, 0x00203623, 0x000 }, - { 0x00000028, 0x00203623, 0x000 }, - { 0x00000017, 0x00203623, 0x000 }, - { 0x00000025, 0x00203623, 0x000 }, - { 0x00000026, 0x00203623, 0x000 }, - { 0x00000015, 0x00203623, 0x000 }, - { 0x00000016, 0x00203623, 0x000 }, - { 0xffffe000, 0x00200c11, 0x000 }, - { 0x00000021, 0x00203623, 0x000 }, - { 0x00000022, 0x00203623, 0x000 }, - { 0x00001fff, 0x00200c11, 0x000 }, - { 0x00000023, 0x00203623, 0x000 }, - { 0x00000024, 0x00203623, 0x000 }, - { 0xf1ffffff, 0x00283a2e, 0x000 }, - { 0x0000001a, 0xc0220e20, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x0000002a, 0x40203620, 0x000 }, - { 0x87000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1f4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x00000030, 0x00203623, 0x000 }, - { 0x9d000000, 0x00204411, 0x000 }, - { 0x0000001f, 0x40214a20, 0x000 }, - { 0x96000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x00000000, 0xc0201000, 0x000 }, - { 0x0000001f, 0x00211624, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x0000001d, 0x00203623, 0x000 }, - { 0x00000003, 0x00281e23, 0x000 }, - { 0x00000008, 0x00222223, 0x000 }, - { 0xfffff000, 0x00282228, 0x000 }, - { 0x00000000, 0x002920e8, 0x000 }, - { 0x0000001f, 0x00203628, 0x000 }, - { 0x00000018, 0x00211e23, 0x000 }, - { 0x00000020, 0x00203627, 0x000 }, - { 0x00000002, 0x00221624, 0x000 }, - { 0x00000000, 0x003014a8, 0x000 }, - { 0x0000001e, 0x00203625, 0x000 }, - { 0x00000003, 0x00211a24, 0x000 }, - { 0x10000000, 0x00281a26, 0x000 }, - { 0xefffffff, 0x00283a2e, 0x000 }, - { 0x00000000, 0x004938ce, 0x678 }, - { 0x00000001, 0x40280a20, 0x000 }, - { 0x00000006, 0x40280e20, 0x000 }, - { 0x00000300, 0xc0281220, 0x000 }, - { 0x00000008, 0x00211224, 0x000 }, - { 0x00000000, 0xc0201620, 0x000 }, - { 0x00000000, 0xc0201a20, 0x000 }, - { 0x00000000, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x563 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00002258, 0x00300a24, 0x000 }, - { 0x00040000, 0x00694622, 0x68a }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00020000, 0x00294a26, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x56b }, - { 0x00000000, 0xc0201c10, 0x000 }, - { 0x00000000, 0xc0400000, 0x579 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x56b }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00002258, 0x00300a24, 0x000 }, - { 0x00040000, 0x00694622, 0x68a }, - { 0x00000000, 0xc0201c10, 0x000 }, - { 0x00000000, 0xc0400000, 0x579 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x56f }, - { 0x00000000, 0xc0201c00, 0x000 }, - { 0x00000000, 0xc0400000, 0x579 }, - { 0x00000004, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x577 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0604800, 0x68f }, - { 0x00000000, 0x00401c10, 0x579 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x0ee00000, 0x57b }, - { 0x00000000, 0x00600000, 0x5c6 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x58c }, - { 0x0000a2b7, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2b6, 0x00604411, 0x68a }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x0000a2c4, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x58a }, - { 0x0000a2d1, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d1, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x00000001, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x59d }, - { 0x0000a2bb, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2ba, 0x00604411, 0x68a }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x0000a2c5, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x59b }, - { 0x0000a2d2, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d2, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x00000002, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5ae }, - { 0x0000a2bf, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2be, 0x00604411, 0x68a }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x0000a2c6, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x5ac }, - { 0x0000a2d3, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d3, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x0000a2c3, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2c2, 0x00604411, 0x68a }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x0000a2c7, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x5bb }, - { 0x0000a2d4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d4, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x85000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0x0000304a, 0x00204411, 0x000 }, - { 0x01000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00400000, 0x5c1 }, - { 0xa4000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0xc0600000, 0x5c6 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000002c, 0x00203621, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000000, 0x002f0230, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5cd }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000030, 0x00403621, 0x5e0 }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00007e00, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x5e0 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a092, 0x00604411, 0x68a }, - { 0x00000031, 0x00203630, 0x000 }, - { 0x0004a093, 0x00604411, 0x68a }, - { 0x00000032, 0x00203630, 0x000 }, - { 0x0004a2b6, 0x00604411, 0x68a }, - { 0x00000033, 0x00203630, 0x000 }, - { 0x0004a2ba, 0x00604411, 0x68a }, - { 0x00000034, 0x00203630, 0x000 }, - { 0x0004a2be, 0x00604411, 0x68a }, - { 0x00000035, 0x00203630, 0x000 }, - { 0x0004a2c2, 0x00604411, 0x68a }, - { 0x00000036, 0x00203630, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x00000005, 0x00204811, 0x000 }, - { 0x0000a1f4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x88000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000001, 0x002f0230, 0x000 }, - { 0x00000000, 0x0ce00000, 0x629 }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x629 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00007e00, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x602 }, - { 0x0000a092, 0x00204411, 0x000 }, - { 0x00000031, 0x00204a2d, 0x000 }, - { 0x0000a093, 0x00204411, 0x000 }, - { 0x00000032, 0x00204a2d, 0x000 }, - { 0x0000a2b6, 0x00204411, 0x000 }, - { 0x00000033, 0x00204a2d, 0x000 }, - { 0x0000a2ba, 0x00204411, 0x000 }, - { 0x00000034, 0x00204a2d, 0x000 }, - { 0x0000a2be, 0x00204411, 0x000 }, - { 0x00000035, 0x00204a2d, 0x000 }, - { 0x0000a2c2, 0x00204411, 0x000 }, - { 0x00000036, 0x00204a2d, 0x000 }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x000001ff, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x628 }, - { 0x00000000, 0x00210221, 0x000 }, - { 0x00000000, 0x14c00000, 0x60b }, - { 0x0004a003, 0x00604411, 0x68a }, - { 0x0000a003, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000001, 0x00210621, 0x000 }, - { 0x00000000, 0x14c00000, 0x610 }, - { 0x0004a010, 0x00604411, 0x68a }, - { 0x0000a010, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000001, 0x00210621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x628 }, - { 0x0004a011, 0x00604411, 0x68a }, - { 0x0000a011, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a012, 0x00604411, 0x68a }, - { 0x0000a012, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a013, 0x00604411, 0x68a }, - { 0x0000a013, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a014, 0x00604411, 0x68a }, - { 0x0000a014, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a015, 0x00604411, 0x68a }, - { 0x0000a015, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a016, 0x00604411, 0x68a }, - { 0x0000a016, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a017, 0x00604411, 0x68a }, - { 0x0000a017, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x0000002c, 0x0080062d, 0x000 }, - { 0xff000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000002, 0x00804811, 0x000 }, - { 0x00000000, 0x0ee00000, 0x63a }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00000002, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x638 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x68a }, - { 0x00001000, 0x00200811, 0x000 }, - { 0x0000002b, 0x00203622, 0x000 }, - { 0x00000000, 0x00600000, 0x63e }, - { 0x00000000, 0x00600000, 0x5c6 }, - { 0x98000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00804811, 0x000 }, - { 0x00000000, 0xc0600000, 0x63e }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000022, 0x00204811, 0x000 }, - { 0x89000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00404811, 0x62a }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00404811, 0x62a }, - { 0x00000000, 0x00600000, 0x659 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0xc0204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36e }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00010000, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x09800000, 0x00204811, 0x000 }, - { 0xffffffff, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x68a }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000004, 0x00404c11, 0x653 }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000004, 0x00291e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0xfffffffb, 0x00281e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000008, 0x00291e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0xfffffff7, 0x00281e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36e }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00010000, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x01800000, 0x00204811, 0x000 }, - { 0xffffffff, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004217f, 0x00604411, 0x68a }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x689 }, - { 0x00000010, 0x00404c11, 0x66f }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x38c00000, 0x000 }, - { 0x0000001d, 0x00200a2d, 0x000 }, - { 0x0000001e, 0x00200e2d, 0x000 }, - { 0x0000001f, 0x0020122d, 0x000 }, - { 0x00000020, 0x0020162d, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000004, 0x00301224, 0x000 }, - { 0x00000000, 0x002f0064, 0x000 }, - { 0x00000000, 0x0cc00000, 0x688 }, - { 0x00000003, 0x00281a22, 0x000 }, - { 0x00000008, 0x00221222, 0x000 }, - { 0xfffff000, 0x00281224, 0x000 }, - { 0x00000000, 0x002910c4, 0x000 }, - { 0x0000001f, 0x00403624, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x1ac00000, 0x68a }, - { 0x9f000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x68d }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x1ac00000, 0x68f }, - { 0x9e000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x692 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00001000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001b, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0xc0204411, 0x000 }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000024, 0x0020222d, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000022, 0x0020222d, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00404811, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x014204ff, 0x05bd0250, 0x000 }, - { 0x01c30168, 0x043f05bd, 0x000 }, - { 0x02250209, 0x02500151, 0x000 }, - { 0x02230245, 0x02a00241, 0x000 }, - { 0x03d705bd, 0x05bd05bd, 0x000 }, - { 0x06460647, 0x031f05bd, 0x000 }, - { 0x05bd05c2, 0x03200340, 0x000 }, - { 0x032a0282, 0x03420334, 0x000 }, - { 0x05bd05bd, 0x05bd05bd, 0x000 }, - { 0x05bd054e, 0x05bd05bd, 0x000 }, - { 0x03ba05bd, 0x04b80344, 0x000 }, - { 0x0497044d, 0x043d05bd, 0x000 }, - { 0x04cd05bd, 0x044104da, 0x000 }, - { 0x044d0504, 0x03510375, 0x000 }, - { 0x05bd05bd, 0x05bd05bd, 0x000 }, - { 0x05bd05bd, 0x05bd05bd, 0x000 }, - { 0x05bd05bd, 0x063c05c4, 0x000 }, - { 0x05bd05bd, 0x000705bd, 0x000 }, - { 0x05bd05bd, 0x05bd05bd, 0x000 }, - { 0x05bd05bd, 0x05bd05bd, 0x000 }, - { 0x03f803ed, 0x04080406, 0x000 }, - { 0x040e040a, 0x040c0410, 0x000 }, - { 0x041c0418, 0x04240420, 0x000 }, - { 0x042c0428, 0x04340430, 0x000 }, - { 0x05bd05bd, 0x043805bd, 0x000 }, - { 0x05bd05bd, 0x05bd05bd, 0x000 }, - { 0x05bd05bd, 0x05bd05bd, 0x000 }, - { 0x00020676, 0x06940006, 0x000 }, -}; - -static const u32 RV635_pfp_microcode[] = { -0xca0400, -0xa00000, -0x7e828b, -0x7c038b, -0x8001b8, -0x7c038b, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xc41838, -0xca2400, -0xca2800, -0x9581a8, -0xc41c3a, -0xc3c000, -0xca0800, -0xca0c00, -0x7c744b, -0xc20005, -0x99c000, -0xc41c3a, -0x7c744c, -0xc0fff0, -0x042c04, -0x309002, -0x7d2500, -0x351402, -0x7d350b, -0x255403, -0x7cd580, -0x259c03, -0x95c004, -0xd5001b, -0x7eddc1, -0x7d9d80, -0xd6801b, -0xd5801b, -0xd4401e, -0xd5401e, -0xd6401e, -0xd6801e, -0xd4801e, -0xd4c01e, -0x9783d3, -0xd5c01e, -0xca0800, -0x80001a, -0xca0c00, -0xe4011e, -0xd4001e, -0x80000c, -0xc41838, -0xe4013e, -0xd4001e, -0x80000c, -0xc41838, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4011e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4013e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca1800, -0xd4401e, -0xd5801e, -0x800053, -0xd40075, -0xd4401e, -0xca0800, -0xca0c00, -0xca1000, -0xd48019, -0xd4c018, -0xd50017, -0xd4801e, -0xd4c01e, -0xd5001e, -0xe2001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0xd48060, -0xd4401e, -0x800000, -0xd4801e, -0xca0800, -0xd48061, -0xd4401e, -0x800000, -0xd4801e, -0xca0800, -0xca0c00, -0xd4401e, -0xd48016, -0xd4c016, -0xd4801e, -0x8001b8, -0xd4c01e, -0xc60843, -0xca0c00, -0xca1000, -0x948004, -0xca1400, -0xe420f3, -0xd42013, -0xd56065, -0xd4e01c, -0xd5201c, -0xd5601c, -0x800000, -0x062001, -0xc60843, -0xca0c00, -0xca1000, -0x9483f7, -0xca1400, -0xe420f3, -0x800079, -0xd42013, -0xc60843, -0xca0c00, -0xca1000, -0x9883ef, -0xca1400, -0xd40064, -0x80008d, -0x000000, -0xc41432, -0xc61843, -0xc4082f, -0x954005, -0xc40c30, -0xd4401e, -0x800000, -0xee001e, -0x9583f5, -0xc41031, -0xd44033, -0xd52065, -0xd4a01c, -0xd4e01c, -0xd5201c, -0xe4015e, -0xd4001e, -0x800000, -0x062001, -0xca1800, -0x0a2001, -0xd60076, -0xc40836, -0x988007, -0xc61045, -0x950110, -0xd4001f, -0xd46062, -0x800000, -0xd42062, -0xcc3835, -0xcc1433, -0x8401bb, -0xd40072, -0xd5401e, -0x800000, -0xee001e, -0xe2001a, -0x8401bb, -0xe2001a, -0xcc104b, -0xcc0447, -0x2c9401, -0x7d098b, -0x984005, -0x7d15cb, -0xd4001a, -0x8001b8, -0xd4006d, -0x344401, -0xcc0c48, -0x98403a, -0xcc2c4a, -0x958004, -0xcc0449, -0x8001b8, -0xd4001a, -0xd4c01a, -0x282801, -0x8400f0, -0xcc1003, -0x98801b, -0x04380c, -0x8400f0, -0xcc1003, -0x988017, -0x043808, -0x8400f0, -0xcc1003, -0x988013, -0x043804, -0x8400f0, -0xcc1003, -0x988014, -0xcc104c, -0x9a8009, -0xcc144d, -0x9840dc, -0xd4006d, -0xcc1848, -0xd5001a, -0xd5401a, -0x8000c9, -0xd5801a, -0x96c0d5, -0xd4006d, -0x8001b8, -0xd4006e, -0x9ac003, -0xd4006d, -0xd4006e, -0x800000, -0xec007f, -0x9ac0cc, -0xd4006d, -0x8001b8, -0xd4006e, -0xcc1403, -0xcc1803, -0xcc1c03, -0x7d9103, -0x7dd583, -0x7d190c, -0x35cc1f, -0x35701f, -0x7cf0cb, -0x7cd08b, -0x880000, -0x7e8e8b, -0x95c004, -0xd4006e, -0x8001b8, -0xd4001a, -0xd4c01a, -0xcc0803, -0xcc0c03, -0xcc1003, -0xcc1403, -0xcc1803, -0xcc1c03, -0xcc2403, -0xcc2803, -0x35c41f, -0x36b01f, -0x7c704b, -0x34f01f, -0x7c704b, -0x35701f, -0x7c704b, -0x7d8881, -0x7dccc1, -0x7e5101, -0x7e9541, -0x7c9082, -0x7cd4c2, -0x7c848b, -0x9ac003, -0x7c8c8b, -0x2c8801, -0x98809e, -0xd4006d, -0x98409c, -0xd4006e, -0xcc084c, -0xcc0c4d, -0xcc1048, -0xd4801a, -0xd4c01a, -0x800101, -0xd5001a, -0xcc0832, -0xd40032, -0x9482d9, -0xca0c00, -0xd4401e, -0x800000, -0xd4001e, -0xe4011e, -0xd4001e, -0xca0800, -0xca0c00, -0xca1000, -0xd4401e, -0xca1400, -0xd4801e, -0xd4c01e, -0xd5001e, -0xd5401e, -0xd54034, -0x800000, -0xee001e, -0x280404, -0xe2001a, -0xe2001a, -0xd4401a, -0xca3800, -0xcc0803, -0xcc0c03, -0xcc0c03, -0xcc0c03, -0x9882bd, -0x000000, -0x8401bb, -0xd7a06f, -0x800000, -0xee001f, -0xca0400, -0xc2ff00, -0xcc0834, -0xc13fff, -0x7c74cb, -0x7cc90b, -0x7d010f, -0x9902b0, -0x7c738b, -0x8401bb, -0xd7a06f, -0x800000, -0xee001f, -0xca0800, -0x281900, -0x7d898b, -0x958014, -0x281404, -0xca0c00, -0xca1000, -0xca1c00, -0xca2400, -0xe2001f, -0xd4c01a, -0xd5001a, -0xd5401a, -0xcc1803, -0xcc2c03, -0xcc2c03, -0xcc2c03, -0x7da58b, -0x7d9c47, -0x984297, -0x000000, -0x800161, -0xd4c01a, -0xd4401e, -0xd4801e, -0x800000, -0xee001e, -0xe4011e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4013e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0x248c06, -0x0ccc06, -0x98c006, -0xcc104e, -0x990004, -0xd40073, -0xe4011e, -0xd4001e, -0xd4401e, -0xd4801e, -0x800000, -0xee001e, -0xca0800, -0xca0c00, -0x34d018, -0x251001, -0x950021, -0xc17fff, -0xca1000, -0xca1400, -0xca1800, -0xd4801d, -0xd4c01d, -0x7db18b, -0xc14202, -0xc2c001, -0xd5801d, -0x34dc0e, -0x7d5d4c, -0x7f734c, -0xd7401e, -0xd5001e, -0xd5401e, -0xc14200, -0xc2c000, -0x099c01, -0x31dc10, -0x7f5f4c, -0x7f734c, -0x042802, -0x7d8380, -0xd5a86f, -0xd58066, -0xd7401e, -0xec005e, -0xc82402, -0xc82402, -0x8001b8, -0xd60076, -0xd4401e, -0xd4801e, -0xd4c01e, -0x800000, -0xee001e, -0x800000, -0xee001f, -0xd4001f, -0x800000, -0xd4001f, -0xd4001f, -0x880000, -0xd4001f, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x010171, -0x020178, -0x03008f, -0x04007f, -0x050003, -0x06003f, -0x070032, -0x08012c, -0x090046, -0x0a0036, -0x1001b6, -0x1700a2, -0x22013a, -0x230149, -0x2000b4, -0x240125, -0x27004d, -0x28006a, -0x2a0060, -0x2b0052, -0x2f0065, -0x320087, -0x34017f, -0x3c0156, -0x3f0072, -0x41018c, -0x44012e, -0x550173, -0x56017a, -0x60000b, -0x610034, -0x620038, -0x630038, -0x640038, -0x650038, -0x660038, -0x670038, -0x68003a, -0x690041, -0x6a0048, -0x6b0048, -0x6c0048, -0x6d0048, -0x6e0048, -0x6f0048, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -}; - -static const u32 RV670_cp_microcode[][3] = { - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0000ffff, 0x00284621, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00000000, 0x00e00000, 0x000 }, - { 0x00010000, 0xc0294620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x67c }, - { 0x00000000, 0x00600000, 0x624 }, - { 0x00000000, 0x00600000, 0x638 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000f00, 0x00281622, 0x000 }, - { 0x00000008, 0x00211625, 0x000 }, - { 0x00000018, 0x00203625, 0x000 }, - { 0x8d000000, 0x00204411, 0x000 }, - { 0x00000004, 0x002f0225, 0x000 }, - { 0x00000000, 0x0ce00000, 0x018 }, - { 0x00412000, 0x00404811, 0x019 }, - { 0x00422000, 0x00204811, 0x000 }, - { 0x8e000000, 0x00204411, 0x000 }, - { 0x00000028, 0x00204a2d, 0x000 }, - { 0x90000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x0000000c, 0x00211622, 0x000 }, - { 0x00000003, 0x00281625, 0x000 }, - { 0x00000019, 0x00211a22, 0x000 }, - { 0x00000004, 0x00281a26, 0x000 }, - { 0x00000000, 0x002914c5, 0x000 }, - { 0x00000019, 0x00203625, 0x000 }, - { 0x00000000, 0x003a1402, 0x000 }, - { 0x00000016, 0x00211625, 0x000 }, - { 0x00000003, 0x00281625, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0xfffffffc, 0x00280e23, 0x000 }, - { 0x00000000, 0x002914a3, 0x000 }, - { 0x00000017, 0x00203625, 0x000 }, - { 0x00008000, 0x00280e22, 0x000 }, - { 0x00000007, 0x00220e23, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x20000000, 0x00280e22, 0x000 }, - { 0x00000006, 0x00210e23, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x00000000, 0x00220222, 0x000 }, - { 0x00000000, 0x14e00000, 0x038 }, - { 0x00000000, 0x2ee00000, 0x035 }, - { 0x00000000, 0x2ce00000, 0x037 }, - { 0x00000000, 0x00400e2d, 0x039 }, - { 0x00000008, 0x00200e2d, 0x000 }, - { 0x00000009, 0x0040122d, 0x046 }, - { 0x00000001, 0x00400e2d, 0x039 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x003ffffc, 0x00281223, 0x000 }, - { 0x00000002, 0x00221224, 0x000 }, - { 0x0000001f, 0x00211e23, 0x000 }, - { 0x00000000, 0x14e00000, 0x03e }, - { 0x00000008, 0x00401c11, 0x041 }, - { 0x0000000d, 0x00201e2d, 0x000 }, - { 0x0000000f, 0x00281e27, 0x000 }, - { 0x00000003, 0x00221e27, 0x000 }, - { 0x7fc00000, 0x00281a23, 0x000 }, - { 0x00000014, 0x00211a26, 0x000 }, - { 0x00000001, 0x00331a26, 0x000 }, - { 0x00000008, 0x00221a26, 0x000 }, - { 0x00000000, 0x00290cc7, 0x000 }, - { 0x00000027, 0x00203624, 0x000 }, - { 0x00007f00, 0x00281221, 0x000 }, - { 0x00001400, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x04b }, - { 0x00000001, 0x00290e23, 0x000 }, - { 0x0000000e, 0x00203623, 0x000 }, - { 0x0000e000, 0x00204411, 0x000 }, - { 0xfff80000, 0x00294a23, 0x000 }, - { 0x00000000, 0x003a2c02, 0x000 }, - { 0x00000002, 0x00220e2b, 0x000 }, - { 0xfc000000, 0x00280e23, 0x000 }, - { 0x0000000f, 0x00203623, 0x000 }, - { 0x00001fff, 0x00294a23, 0x000 }, - { 0x00000027, 0x00204a2d, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000029, 0x00200e2d, 0x000 }, - { 0x060a0200, 0x00294a23, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14e00000, 0x061 }, - { 0x00000000, 0x2ee00000, 0x05f }, - { 0x00000000, 0x2ce00000, 0x05e }, - { 0x00000000, 0x00400e2d, 0x062 }, - { 0x00000001, 0x00400e2d, 0x062 }, - { 0x0000000a, 0x00200e2d, 0x000 }, - { 0x0000000b, 0x0040122d, 0x06a }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x003ffffc, 0x00281223, 0x000 }, - { 0x00000002, 0x00221224, 0x000 }, - { 0x7fc00000, 0x00281623, 0x000 }, - { 0x00000014, 0x00211625, 0x000 }, - { 0x00000001, 0x00331625, 0x000 }, - { 0x80000000, 0x00280e23, 0x000 }, - { 0x00000000, 0x00290ca3, 0x000 }, - { 0x3ffffc00, 0x00290e23, 0x000 }, - { 0x0000001f, 0x00211e23, 0x000 }, - { 0x00000000, 0x14e00000, 0x06d }, - { 0x00000100, 0x00401c11, 0x070 }, - { 0x0000000d, 0x00201e2d, 0x000 }, - { 0x000000f0, 0x00281e27, 0x000 }, - { 0x00000004, 0x00221e27, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0xfffff0ff, 0x00281a30, 0x000 }, - { 0x0000a028, 0x00204411, 0x000 }, - { 0x00000000, 0x002948e6, 0x000 }, - { 0x0000a018, 0x00204411, 0x000 }, - { 0x3fffffff, 0x00284a23, 0x000 }, - { 0x0000a010, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000030, 0x0020162d, 0x000 }, - { 0x00000002, 0x00291625, 0x000 }, - { 0x00000030, 0x00203625, 0x000 }, - { 0x00000025, 0x0020162d, 0x000 }, - { 0x00000000, 0x002f00a3, 0x000 }, - { 0x00000000, 0x0cc00000, 0x083 }, - { 0x00000026, 0x0020162d, 0x000 }, - { 0x00000000, 0x002f00a4, 0x000 }, - { 0x00000000, 0x0cc00000, 0x084 }, - { 0x00000000, 0x00400000, 0x08a }, - { 0x00000025, 0x00203623, 0x000 }, - { 0x00000026, 0x00203624, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x08a }, - { 0x00000000, 0x00600000, 0x659 }, - { 0x00000000, 0x00600000, 0x64d }, - { 0x00000002, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x08d }, - { 0x00000012, 0xc0403620, 0x093 }, - { 0x00000000, 0x2ee00000, 0x091 }, - { 0x00000000, 0x2ce00000, 0x090 }, - { 0x00000002, 0x00400e2d, 0x092 }, - { 0x00000003, 0x00400e2d, 0x092 }, - { 0x0000000c, 0x00200e2d, 0x000 }, - { 0x00000012, 0x00203623, 0x000 }, - { 0x00000003, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x098 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x0a0 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x2ee00000, 0x09e }, - { 0x00000000, 0x2ce00000, 0x09d }, - { 0x00000002, 0x00400e2d, 0x09f }, - { 0x00000003, 0x00400e2d, 0x09f }, - { 0x0000000c, 0x00200e2d, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000000, 0x003a0c02, 0x000 }, - { 0x003f0000, 0x00280e23, 0x000 }, - { 0x00000010, 0x00210e23, 0x000 }, - { 0x00000011, 0x00203623, 0x000 }, - { 0x0000001e, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0a7 }, - { 0x00000016, 0xc0203620, 0x000 }, - { 0x0000001f, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0aa }, - { 0x00000015, 0xc0203620, 0x000 }, - { 0x00000008, 0x00210e2b, 0x000 }, - { 0x0000007f, 0x00280e23, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0e1 }, - { 0x00000000, 0x27000000, 0x000 }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0b3 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x0000000c, 0x00221e30, 0x000 }, - { 0x99800000, 0x00204411, 0x000 }, - { 0x00000004, 0x0020122d, 0x000 }, - { 0x00000008, 0x00221224, 0x000 }, - { 0x00000010, 0x00201811, 0x000 }, - { 0x00000000, 0x00291ce4, 0x000 }, - { 0x00000000, 0x00604807, 0x12f }, - { 0x9b000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x9c000000, 0x00204411, 0x000 }, - { 0x00000000, 0x0033146f, 0x000 }, - { 0x00000001, 0x00333e23, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0x00203c05, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x00000000, 0x00201010, 0x000 }, - { 0x0000e007, 0x00204411, 0x000 }, - { 0x0000000f, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0cb }, - { 0x00f8ff08, 0x00204811, 0x000 }, - { 0x98000000, 0x00404811, 0x0dc }, - { 0x000000f0, 0x00280e22, 0x000 }, - { 0x000000a0, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x0da }, - { 0x00000011, 0x00200e2d, 0x000 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0d5 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0d4 }, - { 0x00003f00, 0x00400c11, 0x0d6 }, - { 0x00001f00, 0x00400c11, 0x0d6 }, - { 0x00000f00, 0x00200c11, 0x000 }, - { 0x00380009, 0x00294a23, 0x000 }, - { 0x3f000000, 0x00280e2b, 0x000 }, - { 0x00000002, 0x00220e23, 0x000 }, - { 0x00000007, 0x00494a23, 0x0dc }, - { 0x00380f09, 0x00204811, 0x000 }, - { 0x68000007, 0x00204811, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a24, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000a202, 0x00204411, 0x000 }, - { 0x00ff0000, 0x00280e22, 0x000 }, - { 0x00000080, 0x00294a23, 0x000 }, - { 0x00000027, 0x00200e2d, 0x000 }, - { 0x00000026, 0x0020122d, 0x000 }, - { 0x00000000, 0x002f0083, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0ea }, - { 0x00000000, 0x00600000, 0x653 }, - { 0x00000000, 0x00400000, 0x0eb }, - { 0x00000000, 0x00600000, 0x656 }, - { 0x00000007, 0x0020222d, 0x000 }, - { 0x00000005, 0x00220e22, 0x000 }, - { 0x00100000, 0x00280e23, 0x000 }, - { 0x00000000, 0x00292068, 0x000 }, - { 0x00000000, 0x003a0c02, 0x000 }, - { 0x000000ef, 0x00280e23, 0x000 }, - { 0x00000000, 0x00292068, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0x00000003, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x0f8 }, - { 0x0000000b, 0x00210228, 0x000 }, - { 0x00000000, 0x14c00000, 0x0f8 }, - { 0x00000400, 0x00292228, 0x000 }, - { 0x00000014, 0x00203628, 0x000 }, - { 0x0000001c, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x0fd }, - { 0x0000a30c, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000001e, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x10b }, - { 0x0000a30f, 0x00204411, 0x000 }, - { 0x00000011, 0x00200e2d, 0x000 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x104 }, - { 0xffffffff, 0x00404811, 0x10b }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x107 }, - { 0x0000ffff, 0x00404811, 0x10b }, - { 0x00000004, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x10a }, - { 0x000000ff, 0x00404811, 0x10b }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0002c400, 0x00204411, 0x000 }, - { 0x0000001f, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x112 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x00000013, 0x00203623, 0x000 }, - { 0x00000018, 0x40224a20, 0x000 }, - { 0x00000010, 0xc0424a20, 0x114 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x00000013, 0x00203623, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000000a, 0x00201011, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x11b }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00531224, 0x117 }, - { 0xffbfffff, 0x00283a2e, 0x000 }, - { 0x0000001b, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x12e }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0x00000018, 0x00220e30, 0x000 }, - { 0xfc000000, 0x00280e23, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x00000000, 0x00201010, 0x000 }, - { 0x0000e00e, 0x00204411, 0x000 }, - { 0x07f8ff08, 0x00204811, 0x000 }, - { 0x00000000, 0x00294a23, 0x000 }, - { 0x0000001c, 0x00201e2d, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a24, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x00800000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204806, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x67c }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x67b }, - { 0x00000004, 0x00404c11, 0x135 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x0000001c, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x67c }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x13c }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00000000, 0x00600000, 0x160 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000ffff, 0x40280620, 0x000 }, - { 0x00000010, 0xc0210a20, 0x000 }, - { 0x00000000, 0x00341461, 0x000 }, - { 0x00000000, 0x00741882, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x147 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x160 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x00000010, 0x40211620, 0x000 }, - { 0x0000ffff, 0xc0681a20, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x158 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000001, 0x00300a2f, 0x000 }, - { 0x00000001, 0x00210a22, 0x000 }, - { 0x00000003, 0x00384a22, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001a, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600000, 0x18f }, - { 0x00000000, 0x00600000, 0x1a0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00202c08, 0x000 }, - { 0x00000000, 0x00202411, 0x000 }, - { 0x00000000, 0x00202811, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000002, 0x00221e29, 0x000 }, - { 0x00000000, 0x007048eb, 0x19c }, - { 0x00000000, 0x00600000, 0x2bb }, - { 0x00000001, 0x40330620, 0x000 }, - { 0x00000000, 0xc0302409, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ae00000, 0x181 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x00000000, 0x00400000, 0x186 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x186 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000001, 0x00530621, 0x182 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0604800, 0x197 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000011, 0x0020062d, 0x000 }, - { 0x00000000, 0x0078042a, 0x2fb }, - { 0x00000000, 0x00202809, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x174 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000210, 0x00600411, 0x315 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x194 }, - { 0x00000015, 0xc0203620, 0x000 }, - { 0x00000016, 0xc0203620, 0x000 }, - { 0x3f800000, 0x00200411, 0x000 }, - { 0x46000000, 0x00600811, 0x1b2 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x19b }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000021, 0x00804811, 0x000 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000ffff, 0x40281620, 0x000 }, - { 0x00000010, 0xc0811a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000008, 0x00221e30, 0x000 }, - { 0x00000029, 0x00201a2d, 0x000 }, - { 0x0000e000, 0x00204411, 0x000 }, - { 0xfffbff09, 0x00204811, 0x000 }, - { 0x0000000f, 0x0020222d, 0x000 }, - { 0x00001fff, 0x00294a28, 0x000 }, - { 0x00000006, 0x0020222d, 0x000 }, - { 0x00000000, 0x002920e8, 0x000 }, - { 0x00000000, 0x00204808, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a26, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000100, 0x00201811, 0x000 }, - { 0x00000008, 0x00621e28, 0x12f }, - { 0x00000008, 0x00822228, 0x000 }, - { 0x0002c000, 0x00204411, 0x000 }, - { 0x00000015, 0x00600e2d, 0x1bd }, - { 0x00000016, 0x00600e2d, 0x1bd }, - { 0x0000c008, 0x00204411, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0x00000000, 0x14c00000, 0x1b9 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0x39000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00804802, 0x000 }, - { 0x00000018, 0x00202e2d, 0x000 }, - { 0x00000000, 0x003b0d63, 0x000 }, - { 0x00000008, 0x00224a23, 0x000 }, - { 0x00000010, 0x00224a23, 0x000 }, - { 0x00000018, 0x00224a23, 0x000 }, - { 0x00000000, 0x00804803, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00001000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00000007, 0x0021062f, 0x000 }, - { 0x00000013, 0x00200a2d, 0x000 }, - { 0x00000001, 0x00202c11, 0x000 }, - { 0x0000ffff, 0x40282220, 0x000 }, - { 0x0000000f, 0x00262228, 0x000 }, - { 0x00000010, 0x40212620, 0x000 }, - { 0x0000000f, 0x00262629, 0x000 }, - { 0x00000000, 0x00202802, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001b, 0x00204811, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1e0 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000081, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000080, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1dc }, - { 0x00000000, 0x00600000, 0x1e9 }, - { 0x00000001, 0x00531e27, 0x1d8 }, - { 0x00000001, 0x00202c11, 0x000 }, - { 0x0000001f, 0x00280a22, 0x000 }, - { 0x0000001f, 0x00282a2a, 0x000 }, - { 0x00000001, 0x00530621, 0x1d1 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000002, 0x00304a2f, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000001, 0x00301e2f, 0x000 }, - { 0x00000000, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x1e9 }, - { 0x00000001, 0x00531e27, 0x1e5 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x0000000f, 0x00260e23, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000000f, 0x00261224, 0x000 }, - { 0x00000000, 0x00201411, 0x000 }, - { 0x00000000, 0x00601811, 0x2bb }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022b, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1f8 }, - { 0x00000010, 0x00221628, 0x000 }, - { 0xffff0000, 0x00281625, 0x000 }, - { 0x0000ffff, 0x00281a29, 0x000 }, - { 0x00000000, 0x002948c5, 0x000 }, - { 0x00000000, 0x0020480a, 0x000 }, - { 0x00000000, 0x00202c11, 0x000 }, - { 0x00000010, 0x00221623, 0x000 }, - { 0xffff0000, 0x00281625, 0x000 }, - { 0x0000ffff, 0x00281a24, 0x000 }, - { 0x00000000, 0x002948c5, 0x000 }, - { 0x00000000, 0x00731503, 0x205 }, - { 0x00000000, 0x00201805, 0x000 }, - { 0x00000000, 0x00731524, 0x205 }, - { 0x00000000, 0x002d14c5, 0x000 }, - { 0x00000000, 0x003008a2, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00202802, 0x000 }, - { 0x00000000, 0x00202003, 0x000 }, - { 0x00000000, 0x00802404, 0x000 }, - { 0x0000000f, 0x00210225, 0x000 }, - { 0x00000000, 0x14c00000, 0x67b }, - { 0x00000000, 0x002b1405, 0x000 }, - { 0x00000001, 0x00901625, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001a, 0x00294a22, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00384a21, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000ffff, 0x40281220, 0x000 }, - { 0x00000010, 0xc0211a20, 0x000 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211620, 0x000 }, - { 0x00000000, 0x00741465, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00000001, 0x00330621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0cc00000, 0x219 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x212 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x638 }, - { 0x00000000, 0x0040040f, 0x213 }, - { 0x00000000, 0x00600000, 0x624 }, - { 0x00000000, 0x00600000, 0x638 }, - { 0x00000210, 0x00600411, 0x315 }, - { 0x00000000, 0x00600000, 0x1a0 }, - { 0x00000000, 0x00600000, 0x19c }, - { 0x00000000, 0x00600000, 0x2bb }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204808, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ae00000, 0x232 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x00000000, 0x00400000, 0x236 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x236 }, - { 0x00000000, 0xc0404800, 0x233 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x00600411, 0x2fb }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x624 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000018, 0x40210a20, 0x000 }, - { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x24c }, - { 0x00000014, 0x0020222d, 0x000 }, - { 0x00080101, 0x00292228, 0x000 }, - { 0x00000014, 0x00203628, 0x000 }, - { 0x0000a30c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x251 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000010, 0x00600411, 0x315 }, - { 0x3f800000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x00000000, 0x00600000, 0x27c }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000001, 0x00211e27, 0x000 }, - { 0x00000000, 0x14e00000, 0x26a }, - { 0x00000012, 0x00201e2d, 0x000 }, - { 0x0000ffff, 0x00281e27, 0x000 }, - { 0x00000000, 0x00341c27, 0x000 }, - { 0x00000000, 0x12c00000, 0x25f }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f00e5, 0x000 }, - { 0x00000000, 0x08c00000, 0x262 }, - { 0x00000000, 0x00201407, 0x000 }, - { 0x00000012, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00211e27, 0x000 }, - { 0x00000000, 0x00341c47, 0x000 }, - { 0x00000000, 0x12c00000, 0x267 }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f00e6, 0x000 }, - { 0x00000000, 0x08c00000, 0x26a }, - { 0x00000000, 0x00201807, 0x000 }, - { 0x00000000, 0x00600000, 0x2c1 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000000, 0x00342023, 0x000 }, - { 0x00000000, 0x12c00000, 0x272 }, - { 0x00000000, 0x00342044, 0x000 }, - { 0x00000000, 0x12c00000, 0x271 }, - { 0x00000016, 0x00404811, 0x276 }, - { 0x00000018, 0x00404811, 0x276 }, - { 0x00000000, 0x00342044, 0x000 }, - { 0x00000000, 0x12c00000, 0x275 }, - { 0x00000017, 0x00404811, 0x276 }, - { 0x00000019, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0x00604411, 0x2e9 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x256 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000010, 0x40210620, 0x000 }, - { 0x0000ffff, 0xc0280a20, 0x000 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x00000010, 0x40211620, 0x000 }, - { 0x0000ffff, 0xc0881a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x67c }, - { 0x00000000, 0x00600000, 0x624 }, - { 0x00000000, 0xc0600000, 0x2a3 }, - { 0x00000005, 0x00200a2d, 0x000 }, - { 0x00000008, 0x00220a22, 0x000 }, - { 0x0000002b, 0x00201a2d, 0x000 }, - { 0x0000001c, 0x00201e2d, 0x000 }, - { 0x00007000, 0x00281e27, 0x000 }, - { 0x00000000, 0x00311ce6, 0x000 }, - { 0x0000002a, 0x00201a2d, 0x000 }, - { 0x0000000c, 0x00221a26, 0x000 }, - { 0x00000000, 0x002f00e6, 0x000 }, - { 0x00000000, 0x06e00000, 0x292 }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x0000002b, 0x00203623, 0x000 }, - { 0x00000010, 0x00201811, 0x000 }, - { 0x00000000, 0x00691ce2, 0x12f }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x29d }, - { 0x00000001, 0x00333e2f, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000001c, 0x00403627, 0x000 }, - { 0x0000000c, 0xc0220a20, 0x000 }, - { 0x00000029, 0x00203622, 0x000 }, - { 0x00000028, 0xc0403620, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000009, 0x00204811, 0x000 }, - { 0xa1000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002c1ce3, 0x000 }, - { 0x00000021, 0x00203627, 0x000 }, - { 0x00000022, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002c1ce4, 0x000 }, - { 0x00000022, 0x00203627, 0x000 }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120a3, 0x000 }, - { 0x00000000, 0x002d1d07, 0x000 }, - { 0x00000023, 0x00203627, 0x000 }, - { 0x00000024, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x00000000, 0x002d1d07, 0x000 }, - { 0x00000024, 0x00803627, 0x000 }, - { 0x00000021, 0x00203623, 0x000 }, - { 0x00000022, 0x00203624, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000023, 0x00203627, 0x000 }, - { 0x00000000, 0x00311cc4, 0x000 }, - { 0x00000024, 0x00803627, 0x000 }, - { 0x0000001a, 0x00203627, 0x000 }, - { 0x0000001b, 0x00203628, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14c00000, 0x2dc }, - { 0x00000000, 0x00400000, 0x2d9 }, - { 0x0000001a, 0x00203627, 0x000 }, - { 0x0000001b, 0x00203628, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x2d9 }, - { 0x00000003, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x2dc }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002e00e1, 0x000 }, - { 0x00000000, 0x02c00000, 0x2dc }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120a1, 0x000 }, - { 0x00000000, 0x002e00e8, 0x000 }, - { 0x00000000, 0x06c00000, 0x2dc }, - { 0x00000024, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002e00e2, 0x000 }, - { 0x00000000, 0x02c00000, 0x2dc }, - { 0x00000022, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120c2, 0x000 }, - { 0x00000000, 0x002e00e8, 0x000 }, - { 0x00000000, 0x06c00000, 0x2dc }, - { 0x00000000, 0x00600000, 0x659 }, - { 0x00000000, 0x00600000, 0x2b5 }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x00000000, 0x00600000, 0x2b5 }, - { 0x00000000, 0x00600000, 0x650 }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x00000000, 0x00600000, 0x2a7 }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x0000001a, 0x00201e2d, 0x000 }, - { 0x0000001b, 0x0080222d, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000010, 0x00221e21, 0x000 }, - { 0x00000000, 0x00294847, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000000, 0x00311ca1, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294847, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000010, 0x00221e21, 0x000 }, - { 0x00000000, 0x003120c2, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000001, 0x00220a21, 0x000 }, - { 0x00000000, 0x003308a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000001, 0x00220a21, 0x000 }, - { 0x00000000, 0x003008a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x003808c5, 0x000 }, - { 0x00000000, 0x00300841, 0x000 }, - { 0x00000001, 0x00220a22, 0x000 }, - { 0x00000000, 0x003308a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000017, 0x0020222d, 0x000 }, - { 0x00000000, 0x14c00000, 0x318 }, - { 0xffffffef, 0x00280621, 0x000 }, - { 0x00000014, 0x0020222d, 0x000 }, - { 0x0000f8e0, 0x00204411, 0x000 }, - { 0x00000000, 0x00294901, 0x000 }, - { 0x00000000, 0x00894901, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00804811, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x97000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00002257, 0x00204411, 0x000 }, - { 0x00000003, 0xc0484a20, 0x000 }, - { 0x0000225d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0x00600000, 0x638 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00384a22, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x40204800, 0x000 }, - { 0x00000001, 0x40304a20, 0x000 }, - { 0x00000002, 0xc0304a20, 0x000 }, - { 0x00000001, 0x00530a22, 0x34b }, - { 0x0000003f, 0xc0280a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000018, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x67c }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x354 }, - { 0x00000014, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x362 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00604802, 0x36a }, - { 0x00002100, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x366 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x35d }, - { 0x00000028, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5b3 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x35d }, - { 0x0000002c, 0x00203626, 0x000 }, - { 0x00000049, 0x00201811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x00000001, 0x00331a26, 0x000 }, - { 0x00000000, 0x002f0226, 0x000 }, - { 0x00000000, 0x0cc00000, 0x36c }, - { 0x0000002c, 0x00801a2d, 0x000 }, - { 0x0000003f, 0xc0280a20, 0x000 }, - { 0x00000015, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x382 }, - { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3ad }, - { 0x00000016, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3af }, - { 0x00000020, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x398 }, - { 0x0000000f, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3a4 }, - { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3a4 }, - { 0x0000001e, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x38c }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x08000000, 0x00290a22, 0x000 }, - { 0x00000003, 0x40210e20, 0x000 }, - { 0x0000000c, 0xc0211220, 0x000 }, - { 0x00080000, 0x00281224, 0x000 }, - { 0x00000014, 0xc0221620, 0x000 }, - { 0x00000000, 0x002914a4, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x002948a2, 0x000 }, - { 0x0000a1fe, 0x00204411, 0x000 }, - { 0x00000000, 0x00404803, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x67c }, - { 0x00000015, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x38e }, - { 0x0000210e, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000017, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x67c }, - { 0x00000003, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x39a }, - { 0x00002108, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x80000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000010, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x3aa }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000006, 0x00404811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36a }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x0000001d, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x3c4 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000018, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x67c }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x3b8 }, - { 0x00002100, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0xbabecafe, 0x00204811, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000004, 0x00404811, 0x000 }, - { 0x00002170, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000a, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x3c9 }, - { 0x8c000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00003fff, 0x40280a20, 0x000 }, - { 0x80000000, 0x40280e20, 0x000 }, - { 0x40000000, 0xc0281220, 0x000 }, - { 0x00040000, 0x00694622, 0x67c }, - { 0x00000000, 0x00201410, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x3d7 }, - { 0x00000000, 0xc0401800, 0x3da }, - { 0x00003fff, 0xc0281a20, 0x000 }, - { 0x00040000, 0x00694626, 0x67c }, - { 0x00000000, 0x00201810, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x3dd }, - { 0x00000000, 0xc0401c00, 0x3e0 }, - { 0x00003fff, 0xc0281e20, 0x000 }, - { 0x00040000, 0x00694627, 0x67c }, - { 0x00000000, 0x00201c10, 0x000 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0x002820c5, 0x000 }, - { 0x00000000, 0x004948e8, 0x000 }, - { 0xa5800000, 0x00200811, 0x000 }, - { 0x00002000, 0x00200c11, 0x000 }, - { 0x83000000, 0x00604411, 0x408 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x40204800, 0x000 }, - { 0x0000001f, 0xc0210220, 0x000 }, - { 0x00000000, 0x14c00000, 0x3ed }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0000ffff, 0xc0481220, 0x3f5 }, - { 0xa7800000, 0x00200811, 0x000 }, - { 0x0000a000, 0x00200c11, 0x000 }, - { 0x83000000, 0x00604411, 0x408 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x83000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00304883, 0x000 }, - { 0x84000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1d000000, 0x000 }, - { 0x83000000, 0x00604411, 0x408 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0xa9800000, 0x00200811, 0x000 }, - { 0x0000c000, 0x00400c11, 0x3f0 }, - { 0xab800000, 0x00200811, 0x000 }, - { 0x0000f8e0, 0x00400c11, 0x3f0 }, - { 0xad800000, 0x00200811, 0x000 }, - { 0x0000f880, 0x00400c11, 0x3f0 }, - { 0xb3800000, 0x00200811, 0x000 }, - { 0x0000f3fc, 0x00400c11, 0x3f0 }, - { 0xaf800000, 0x00200811, 0x000 }, - { 0x0000e000, 0x00400c11, 0x3f0 }, - { 0xb1800000, 0x00200811, 0x000 }, - { 0x0000f000, 0x00400c11, 0x3f0 }, - { 0x83000000, 0x00204411, 0x000 }, - { 0x00002148, 0x00204811, 0x000 }, - { 0x84000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1d000000, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x01182000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0218a000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0318c000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0418f8e0, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0518f880, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0618e000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0718f000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0818f3fc, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00000030, 0x00200a2d, 0x000 }, - { 0x00000000, 0xc0290c40, 0x000 }, - { 0x00000030, 0x00203623, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x86000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00404801, 0x000 }, - { 0x85000000, 0xc0204411, 0x000 }, - { 0x00000000, 0x00404801, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x67c }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000000, 0x00404c02, 0x43e }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x00000000, 0xc0201000, 0x000 }, - { 0x00000000, 0xc0201400, 0x000 }, - { 0x00000000, 0xc0201800, 0x000 }, - { 0x00000000, 0xc0201c00, 0x000 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x44c }, - { 0x00000000, 0xc0202000, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x00000010, 0x00280a23, 0x000 }, - { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x454 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0x00694624, 0x67c }, - { 0x00000000, 0x00400000, 0x459 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x00604805, 0x681 }, - { 0x00000000, 0x002824f0, 0x000 }, - { 0x00000007, 0x00280a23, 0x000 }, - { 0x00000001, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x460 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x04e00000, 0x479 }, - { 0x00000000, 0x00400000, 0x486 }, - { 0x00000002, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x465 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x02e00000, 0x479 }, - { 0x00000000, 0x00400000, 0x486 }, - { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x46a }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x0ce00000, 0x479 }, - { 0x00000000, 0x00400000, 0x486 }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x46f }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x0ae00000, 0x479 }, - { 0x00000000, 0x00400000, 0x486 }, - { 0x00000005, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x474 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x06e00000, 0x479 }, - { 0x00000000, 0x00400000, 0x486 }, - { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x479 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x08e00000, 0x479 }, - { 0x00000000, 0x00400000, 0x486 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x000 }, - { 0x00000008, 0x00210a23, 0x000 }, - { 0x00000000, 0x14c00000, 0x483 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x00000000, 0xc0204400, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x48c }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x00404c08, 0x44c }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x00000011, 0x40211220, 0x000 }, - { 0x00000012, 0x40211620, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00210225, 0x000 }, - { 0x00000000, 0x14e00000, 0x496 }, - { 0x00040000, 0xc0494a20, 0x497 }, - { 0xfffbffff, 0xc0284a20, 0x000 }, - { 0x00000000, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x4a3 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000c, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x49f }, - { 0xa0000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000004, 0x00204811, 0x000 }, - { 0x0000216b, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204810, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000005, 0x00204811, 0x000 }, - { 0x0000216c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204810, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00400000, 0x49d }, - { 0x00000000, 0xc0210a20, 0x000 }, - { 0x00000000, 0x14c00000, 0x4b6 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0604800, 0x681 }, - { 0x00000000, 0x00400000, 0x4ba }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0xc0294620, 0x000 }, - { 0x00000000, 0xc0600000, 0x67c }, - { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x4c1 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x00000000, 0xc0204400, 0x000 }, - { 0x00000000, 0xc0404810, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x67c }, - { 0x00000000, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x4c3 }, - { 0x00002180, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000003, 0x00333e2f, 0x000 }, - { 0x00000001, 0x00210221, 0x000 }, - { 0x00000000, 0x14e00000, 0x4f3 }, - { 0x0000002c, 0x00200a2d, 0x000 }, - { 0x00040000, 0x18e00c11, 0x4e2 }, - { 0x00000001, 0x00333e2f, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xd8c04800, 0x4d6 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000002d, 0x0020122d, 0x000 }, - { 0x00000000, 0x00290c83, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000011, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000000, 0x00400000, 0x49d }, - { 0x0000002c, 0xc0203620, 0x000 }, - { 0x0000002d, 0xc0403620, 0x000 }, - { 0x0000000f, 0x00210221, 0x000 }, - { 0x00000000, 0x14c00000, 0x4f8 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0xd9000000, 0x000 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0xb5000000, 0x00204411, 0x000 }, - { 0x00002000, 0x00204811, 0x000 }, - { 0xb6000000, 0x00204411, 0x000 }, - { 0x0000a000, 0x00204811, 0x000 }, - { 0xb7000000, 0x00204411, 0x000 }, - { 0x0000c000, 0x00204811, 0x000 }, - { 0xb8000000, 0x00204411, 0x000 }, - { 0x0000f8e0, 0x00204811, 0x000 }, - { 0xb9000000, 0x00204411, 0x000 }, - { 0x0000f880, 0x00204811, 0x000 }, - { 0xba000000, 0x00204411, 0x000 }, - { 0x0000e000, 0x00204811, 0x000 }, - { 0xbb000000, 0x00204411, 0x000 }, - { 0x0000f000, 0x00204811, 0x000 }, - { 0xbc000000, 0x00204411, 0x000 }, - { 0x0000f3fc, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000002, 0x00204811, 0x000 }, - { 0x000000ff, 0x00280e30, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x50c }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0x14c00000, 0x521 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x0000001c, 0x00203623, 0x000 }, - { 0x0000002b, 0x00203623, 0x000 }, - { 0x00000029, 0x00203623, 0x000 }, - { 0x00000028, 0x00203623, 0x000 }, - { 0x00000017, 0x00203623, 0x000 }, - { 0x00000025, 0x00203623, 0x000 }, - { 0x00000026, 0x00203623, 0x000 }, - { 0x00000015, 0x00203623, 0x000 }, - { 0x00000016, 0x00203623, 0x000 }, - { 0xffffe000, 0x00200c11, 0x000 }, - { 0x00000021, 0x00203623, 0x000 }, - { 0x00000022, 0x00203623, 0x000 }, - { 0x00001fff, 0x00200c11, 0x000 }, - { 0x00000023, 0x00203623, 0x000 }, - { 0x00000024, 0x00203623, 0x000 }, - { 0xf1ffffff, 0x00283a2e, 0x000 }, - { 0x0000001a, 0xc0220e20, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x0000002a, 0x40203620, 0x000 }, - { 0x87000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1f4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x00000030, 0x00203623, 0x000 }, - { 0x9d000000, 0x00204411, 0x000 }, - { 0x0000001f, 0x40214a20, 0x000 }, - { 0x96000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x00000000, 0xc0201000, 0x000 }, - { 0x0000001f, 0x00211624, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x0000001d, 0x00203623, 0x000 }, - { 0x00000003, 0x00281e23, 0x000 }, - { 0x00000008, 0x00222223, 0x000 }, - { 0xfffff000, 0x00282228, 0x000 }, - { 0x00000000, 0x002920e8, 0x000 }, - { 0x0000001f, 0x00203628, 0x000 }, - { 0x00000018, 0x00211e23, 0x000 }, - { 0x00000020, 0x00203627, 0x000 }, - { 0x00000002, 0x00221624, 0x000 }, - { 0x00000000, 0x003014a8, 0x000 }, - { 0x0000001e, 0x00203625, 0x000 }, - { 0x00000003, 0x00211a24, 0x000 }, - { 0x10000000, 0x00281a26, 0x000 }, - { 0xefffffff, 0x00283a2e, 0x000 }, - { 0x00000000, 0x004938ce, 0x66a }, - { 0x00000001, 0x40280a20, 0x000 }, - { 0x00000006, 0x40280e20, 0x000 }, - { 0x00000300, 0xc0281220, 0x000 }, - { 0x00000008, 0x00211224, 0x000 }, - { 0x00000000, 0xc0201620, 0x000 }, - { 0x00000000, 0xc0201a20, 0x000 }, - { 0x00000000, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x559 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00002258, 0x00300a24, 0x000 }, - { 0x00040000, 0x00694622, 0x67c }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00020000, 0x00294a26, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x561 }, - { 0x00000000, 0xc0201c10, 0x000 }, - { 0x00000000, 0xc0400000, 0x56f }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x561 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00002258, 0x00300a24, 0x000 }, - { 0x00040000, 0x00694622, 0x67c }, - { 0x00000000, 0xc0201c10, 0x000 }, - { 0x00000000, 0xc0400000, 0x56f }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x565 }, - { 0x00000000, 0xc0201c00, 0x000 }, - { 0x00000000, 0xc0400000, 0x56f }, - { 0x00000004, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x56d }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0604800, 0x681 }, - { 0x00000000, 0x00401c10, 0x56f }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x0ee00000, 0x571 }, - { 0x00000000, 0x00600000, 0x5bc }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x582 }, - { 0x0000a2b7, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2b6, 0x00604411, 0x67c }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x67c }, - { 0x0000a2c4, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x580 }, - { 0x0000a2d1, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d1, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x00000001, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x593 }, - { 0x0000a2bb, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2ba, 0x00604411, 0x67c }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x67c }, - { 0x0000a2c5, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x591 }, - { 0x0000a2d2, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d2, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x00000002, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5a4 }, - { 0x0000a2bf, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2be, 0x00604411, 0x67c }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x67c }, - { 0x0000a2c6, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x5a2 }, - { 0x0000a2d3, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d3, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x0000a2c3, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a2c2, 0x00604411, 0x67c }, - { 0x0000001a, 0x00212230, 0x000 }, - { 0x00000006, 0x00222630, 0x000 }, - { 0x00042004, 0x00604411, 0x67c }, - { 0x0000a2c7, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x5b1 }, - { 0x0000a2d4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d4, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x85000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0x0000304a, 0x00204411, 0x000 }, - { 0x01000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00400000, 0x5b7 }, - { 0xa4000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0xc0600000, 0x5bc }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000002c, 0x00203621, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000000, 0x002f0230, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5c3 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000030, 0x00403621, 0x5d6 }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00007e00, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x5d6 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004a092, 0x00604411, 0x67c }, - { 0x00000031, 0x00203630, 0x000 }, - { 0x0004a093, 0x00604411, 0x67c }, - { 0x00000032, 0x00203630, 0x000 }, - { 0x0004a2b6, 0x00604411, 0x67c }, - { 0x00000033, 0x00203630, 0x000 }, - { 0x0004a2ba, 0x00604411, 0x67c }, - { 0x00000034, 0x00203630, 0x000 }, - { 0x0004a2be, 0x00604411, 0x67c }, - { 0x00000035, 0x00203630, 0x000 }, - { 0x0004a2c2, 0x00604411, 0x67c }, - { 0x00000036, 0x00203630, 0x000 }, - { 0x00042004, 0x00604411, 0x67c }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x00000005, 0x00204811, 0x000 }, - { 0x0000a1f4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x88000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000001, 0x002f0230, 0x000 }, - { 0x00000000, 0x0ce00000, 0x61f }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x61f }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00007e00, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x5f8 }, - { 0x0000a092, 0x00204411, 0x000 }, - { 0x00000031, 0x00204a2d, 0x000 }, - { 0x0000a093, 0x00204411, 0x000 }, - { 0x00000032, 0x00204a2d, 0x000 }, - { 0x0000a2b6, 0x00204411, 0x000 }, - { 0x00000033, 0x00204a2d, 0x000 }, - { 0x0000a2ba, 0x00204411, 0x000 }, - { 0x00000034, 0x00204a2d, 0x000 }, - { 0x0000a2be, 0x00204411, 0x000 }, - { 0x00000035, 0x00204a2d, 0x000 }, - { 0x0000a2c2, 0x00204411, 0x000 }, - { 0x00000036, 0x00204a2d, 0x000 }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x000001ff, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x61e }, - { 0x00000000, 0x00210221, 0x000 }, - { 0x00000000, 0x14c00000, 0x601 }, - { 0x0004a003, 0x00604411, 0x67c }, - { 0x0000a003, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000001, 0x00210621, 0x000 }, - { 0x00000000, 0x14c00000, 0x606 }, - { 0x0004a010, 0x00604411, 0x67c }, - { 0x0000a010, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00000001, 0x00210621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x61e }, - { 0x0004a011, 0x00604411, 0x67c }, - { 0x0000a011, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a012, 0x00604411, 0x67c }, - { 0x0000a012, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a013, 0x00604411, 0x67c }, - { 0x0000a013, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a014, 0x00604411, 0x67c }, - { 0x0000a014, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a015, 0x00604411, 0x67c }, - { 0x0000a015, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a016, 0x00604411, 0x67c }, - { 0x0000a016, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x0004a017, 0x00604411, 0x67c }, - { 0x0000a017, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x00042004, 0x00604411, 0x67c }, - { 0x0000002c, 0x0080062d, 0x000 }, - { 0xff000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000002, 0x00804811, 0x000 }, - { 0x00000000, 0x0ee00000, 0x630 }, - { 0x00000030, 0x0020062d, 0x000 }, - { 0x00000002, 0x00280621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x62e }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x67c }, - { 0x00001000, 0x00200811, 0x000 }, - { 0x0000002b, 0x00203622, 0x000 }, - { 0x00000000, 0x00600000, 0x634 }, - { 0x00000000, 0x00600000, 0x5bc }, - { 0x98000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00804811, 0x000 }, - { 0x00000000, 0xc0600000, 0x634 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000022, 0x00204811, 0x000 }, - { 0x89000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00404811, 0x620 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00404811, 0x620 }, - { 0x00000000, 0x00600000, 0x64d }, - { 0x0001a2a4, 0xc0204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36a }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00010000, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x09800000, 0x00204811, 0x000 }, - { 0xffffffff, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x67c }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000004, 0x00404c11, 0x647 }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000004, 0x00291e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0xfffffffb, 0x00281e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000008, 0x00291e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0xfffffff7, 0x00281e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000016, 0x00604811, 0x36a }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00010000, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x01800000, 0x00204811, 0x000 }, - { 0xffffffff, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004217f, 0x00604411, 0x67c }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x67b }, - { 0x00000010, 0x00404c11, 0x661 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x38c00000, 0x000 }, - { 0x0000001d, 0x00200a2d, 0x000 }, - { 0x0000001e, 0x00200e2d, 0x000 }, - { 0x0000001f, 0x0020122d, 0x000 }, - { 0x00000020, 0x0020162d, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000004, 0x00301224, 0x000 }, - { 0x00000000, 0x002f0064, 0x000 }, - { 0x00000000, 0x0cc00000, 0x67a }, - { 0x00000003, 0x00281a22, 0x000 }, - { 0x00000008, 0x00221222, 0x000 }, - { 0xfffff000, 0x00281224, 0x000 }, - { 0x00000000, 0x002910c4, 0x000 }, - { 0x0000001f, 0x00403624, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x1ac00000, 0x67c }, - { 0x9f000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x67f }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x1ac00000, 0x681 }, - { 0x9e000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x684 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00001000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001b, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0xc0204411, 0x000 }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000024, 0x0020222d, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000022, 0x0020222d, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00404811, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x014204f5, 0x05b30250, 0x000 }, - { 0x01c30168, 0x043505b3, 0x000 }, - { 0x02250209, 0x02500151, 0x000 }, - { 0x02230245, 0x02a00241, 0x000 }, - { 0x03cd05b3, 0x05b305b3, 0x000 }, - { 0x063c063d, 0x031f05b3, 0x000 }, - { 0x05b305b8, 0x03200340, 0x000 }, - { 0x032a0282, 0x03420334, 0x000 }, - { 0x05b305b3, 0x05b305b3, 0x000 }, - { 0x05b30544, 0x05b305b3, 0x000 }, - { 0x03b205b3, 0x04ae0344, 0x000 }, - { 0x048d0443, 0x043305b3, 0x000 }, - { 0x04c305b3, 0x043704d0, 0x000 }, - { 0x044304fa, 0x03510371, 0x000 }, - { 0x05b305b3, 0x05b305b3, 0x000 }, - { 0x05b305b3, 0x05b305b3, 0x000 }, - { 0x05b305b3, 0x063205ba, 0x000 }, - { 0x05b305b3, 0x000705b3, 0x000 }, - { 0x05b305b3, 0x05b305b3, 0x000 }, - { 0x05b305b3, 0x05b305b3, 0x000 }, - { 0x03ee03e3, 0x03fe03fc, 0x000 }, - { 0x04040400, 0x04020406, 0x000 }, - { 0x0412040e, 0x041a0416, 0x000 }, - { 0x0422041e, 0x042a0426, 0x000 }, - { 0x05b305b3, 0x042e05b3, 0x000 }, - { 0x05b305b3, 0x05b305b3, 0x000 }, - { 0x05b305b3, 0x05b305b3, 0x000 }, - { 0x00020668, 0x06860006, 0x000 }, -}; - -static const u32 RV670_pfp_microcode[] = { -0xca0400, -0xa00000, -0x7e828b, -0x7c038b, -0x8001b8, -0x7c038b, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xc41838, -0xca2400, -0xca2800, -0x9581a8, -0xc41c3a, -0xc3c000, -0xca0800, -0xca0c00, -0x7c744b, -0xc20005, -0x99c000, -0xc41c3a, -0x7c744c, -0xc0fff0, -0x042c04, -0x309002, -0x7d2500, -0x351402, -0x7d350b, -0x255403, -0x7cd580, -0x259c03, -0x95c004, -0xd5001b, -0x7eddc1, -0x7d9d80, -0xd6801b, -0xd5801b, -0xd4401e, -0xd5401e, -0xd6401e, -0xd6801e, -0xd4801e, -0xd4c01e, -0x9783d3, -0xd5c01e, -0xca0800, -0x80001a, -0xca0c00, -0xe4011e, -0xd4001e, -0x80000c, -0xc41838, -0xe4013e, -0xd4001e, -0x80000c, -0xc41838, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4011e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4013e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca1800, -0xd4401e, -0xd5801e, -0x800053, -0xd40075, -0xd4401e, -0xca0800, -0xca0c00, -0xca1000, -0xd48019, -0xd4c018, -0xd50017, -0xd4801e, -0xd4c01e, -0xd5001e, -0xe2001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0xd48060, -0xd4401e, -0x800000, -0xd4801e, -0xca0800, -0xd48061, -0xd4401e, -0x800000, -0xd4801e, -0xca0800, -0xca0c00, -0xd4401e, -0xd48016, -0xd4c016, -0xd4801e, -0x8001b8, -0xd4c01e, -0xc60843, -0xca0c00, -0xca1000, -0x948004, -0xca1400, -0xe420f3, -0xd42013, -0xd56065, -0xd4e01c, -0xd5201c, -0xd5601c, -0x800000, -0x062001, -0xc60843, -0xca0c00, -0xca1000, -0x9483f7, -0xca1400, -0xe420f3, -0x800079, -0xd42013, -0xc60843, -0xca0c00, -0xca1000, -0x9883ef, -0xca1400, -0xd40064, -0x80008d, -0x000000, -0xc41432, -0xc61843, -0xc4082f, -0x954005, -0xc40c30, -0xd4401e, -0x800000, -0xee001e, -0x9583f5, -0xc41031, -0xd44033, -0xd52065, -0xd4a01c, -0xd4e01c, -0xd5201c, -0xe4015e, -0xd4001e, -0x800000, -0x062001, -0xca1800, -0x0a2001, -0xd60076, -0xc40836, -0x988007, -0xc61045, -0x950110, -0xd4001f, -0xd46062, -0x800000, -0xd42062, -0xcc3835, -0xcc1433, -0x8401bb, -0xd40072, -0xd5401e, -0x800000, -0xee001e, -0xe2001a, -0x8401bb, -0xe2001a, -0xcc104b, -0xcc0447, -0x2c9401, -0x7d098b, -0x984005, -0x7d15cb, -0xd4001a, -0x8001b8, -0xd4006d, -0x344401, -0xcc0c48, -0x98403a, -0xcc2c4a, -0x958004, -0xcc0449, -0x8001b8, -0xd4001a, -0xd4c01a, -0x282801, -0x8400f0, -0xcc1003, -0x98801b, -0x04380c, -0x8400f0, -0xcc1003, -0x988017, -0x043808, -0x8400f0, -0xcc1003, -0x988013, -0x043804, -0x8400f0, -0xcc1003, -0x988014, -0xcc104c, -0x9a8009, -0xcc144d, -0x9840dc, -0xd4006d, -0xcc1848, -0xd5001a, -0xd5401a, -0x8000c9, -0xd5801a, -0x96c0d5, -0xd4006d, -0x8001b8, -0xd4006e, -0x9ac003, -0xd4006d, -0xd4006e, -0x800000, -0xec007f, -0x9ac0cc, -0xd4006d, -0x8001b8, -0xd4006e, -0xcc1403, -0xcc1803, -0xcc1c03, -0x7d9103, -0x7dd583, -0x7d190c, -0x35cc1f, -0x35701f, -0x7cf0cb, -0x7cd08b, -0x880000, -0x7e8e8b, -0x95c004, -0xd4006e, -0x8001b8, -0xd4001a, -0xd4c01a, -0xcc0803, -0xcc0c03, -0xcc1003, -0xcc1403, -0xcc1803, -0xcc1c03, -0xcc2403, -0xcc2803, -0x35c41f, -0x36b01f, -0x7c704b, -0x34f01f, -0x7c704b, -0x35701f, -0x7c704b, -0x7d8881, -0x7dccc1, -0x7e5101, -0x7e9541, -0x7c9082, -0x7cd4c2, -0x7c848b, -0x9ac003, -0x7c8c8b, -0x2c8801, -0x98809e, -0xd4006d, -0x98409c, -0xd4006e, -0xcc084c, -0xcc0c4d, -0xcc1048, -0xd4801a, -0xd4c01a, -0x800101, -0xd5001a, -0xcc0832, -0xd40032, -0x9482d9, -0xca0c00, -0xd4401e, -0x800000, -0xd4001e, -0xe4011e, -0xd4001e, -0xca0800, -0xca0c00, -0xca1000, -0xd4401e, -0xca1400, -0xd4801e, -0xd4c01e, -0xd5001e, -0xd5401e, -0xd54034, -0x800000, -0xee001e, -0x280404, -0xe2001a, -0xe2001a, -0xd4401a, -0xca3800, -0xcc0803, -0xcc0c03, -0xcc0c03, -0xcc0c03, -0x9882bd, -0x000000, -0x8401bb, -0xd7a06f, -0x800000, -0xee001f, -0xca0400, -0xc2ff00, -0xcc0834, -0xc13fff, -0x7c74cb, -0x7cc90b, -0x7d010f, -0x9902b0, -0x7c738b, -0x8401bb, -0xd7a06f, -0x800000, -0xee001f, -0xca0800, -0x281900, -0x7d898b, -0x958014, -0x281404, -0xca0c00, -0xca1000, -0xca1c00, -0xca2400, -0xe2001f, -0xd4c01a, -0xd5001a, -0xd5401a, -0xcc1803, -0xcc2c03, -0xcc2c03, -0xcc2c03, -0x7da58b, -0x7d9c47, -0x984297, -0x000000, -0x800161, -0xd4c01a, -0xd4401e, -0xd4801e, -0x800000, -0xee001e, -0xe4011e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4013e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0x248c06, -0x0ccc06, -0x98c006, -0xcc104e, -0x990004, -0xd40073, -0xe4011e, -0xd4001e, -0xd4401e, -0xd4801e, -0x800000, -0xee001e, -0xca0800, -0xca0c00, -0x34d018, -0x251001, -0x950021, -0xc17fff, -0xca1000, -0xca1400, -0xca1800, -0xd4801d, -0xd4c01d, -0x7db18b, -0xc14202, -0xc2c001, -0xd5801d, -0x34dc0e, -0x7d5d4c, -0x7f734c, -0xd7401e, -0xd5001e, -0xd5401e, -0xc14200, -0xc2c000, -0x099c01, -0x31dc10, -0x7f5f4c, -0x7f734c, -0x042802, -0x7d8380, -0xd5a86f, -0xd58066, -0xd7401e, -0xec005e, -0xc82402, -0xc82402, -0x8001b8, -0xd60076, -0xd4401e, -0xd4801e, -0xd4c01e, -0x800000, -0xee001e, -0x800000, -0xee001f, -0xd4001f, -0x800000, -0xd4001f, -0xd4001f, -0x880000, -0xd4001f, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x010171, -0x020178, -0x03008f, -0x04007f, -0x050003, -0x06003f, -0x070032, -0x08012c, -0x090046, -0x0a0036, -0x1001b6, -0x1700a2, -0x22013a, -0x230149, -0x2000b4, -0x240125, -0x27004d, -0x28006a, -0x2a0060, -0x2b0052, -0x2f0065, -0x320087, -0x34017f, -0x3c0156, -0x3f0072, -0x41018c, -0x44012e, -0x550173, -0x56017a, -0x60000b, -0x610034, -0x620038, -0x630038, -0x640038, -0x650038, -0x660038, -0x670038, -0x68003a, -0x690041, -0x6a0048, -0x6b0048, -0x6c0048, -0x6d0048, -0x6e0048, -0x6f0048, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -}; - -static const u32 RS780_cp_microcode[][3] = { - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0000ffff, 0x00284621, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00000000, 0x00e00000, 0x000 }, - { 0x00010000, 0xc0294620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x622 }, - { 0x00000000, 0x00600000, 0x5d1 }, - { 0x00000000, 0x00600000, 0x5de }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000f00, 0x00281622, 0x000 }, - { 0x00000008, 0x00211625, 0x000 }, - { 0x00000018, 0x00203625, 0x000 }, - { 0x8d000000, 0x00204411, 0x000 }, - { 0x00000004, 0x002f0225, 0x000 }, - { 0x00000000, 0x0ce00000, 0x018 }, - { 0x00412000, 0x00404811, 0x019 }, - { 0x00422000, 0x00204811, 0x000 }, - { 0x8e000000, 0x00204411, 0x000 }, - { 0x00000028, 0x00204a2d, 0x000 }, - { 0x90000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x0000000c, 0x00211622, 0x000 }, - { 0x00000003, 0x00281625, 0x000 }, - { 0x00000019, 0x00211a22, 0x000 }, - { 0x00000004, 0x00281a26, 0x000 }, - { 0x00000000, 0x002914c5, 0x000 }, - { 0x00000019, 0x00203625, 0x000 }, - { 0x00000000, 0x003a1402, 0x000 }, - { 0x00000016, 0x00211625, 0x000 }, - { 0x00000003, 0x00281625, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0xfffffffc, 0x00280e23, 0x000 }, - { 0x00000000, 0x002914a3, 0x000 }, - { 0x00000017, 0x00203625, 0x000 }, - { 0x00008000, 0x00280e22, 0x000 }, - { 0x00000007, 0x00220e23, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x20000000, 0x00280e22, 0x000 }, - { 0x00000006, 0x00210e23, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x00000000, 0x00220222, 0x000 }, - { 0x00000000, 0x14e00000, 0x038 }, - { 0x00000000, 0x2ee00000, 0x035 }, - { 0x00000000, 0x2ce00000, 0x037 }, - { 0x00000000, 0x00400e2d, 0x039 }, - { 0x00000008, 0x00200e2d, 0x000 }, - { 0x00000009, 0x0040122d, 0x046 }, - { 0x00000001, 0x00400e2d, 0x039 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x003ffffc, 0x00281223, 0x000 }, - { 0x00000002, 0x00221224, 0x000 }, - { 0x0000001f, 0x00211e23, 0x000 }, - { 0x00000000, 0x14e00000, 0x03e }, - { 0x00000008, 0x00401c11, 0x041 }, - { 0x0000000d, 0x00201e2d, 0x000 }, - { 0x0000000f, 0x00281e27, 0x000 }, - { 0x00000003, 0x00221e27, 0x000 }, - { 0x7fc00000, 0x00281a23, 0x000 }, - { 0x00000014, 0x00211a26, 0x000 }, - { 0x00000001, 0x00331a26, 0x000 }, - { 0x00000008, 0x00221a26, 0x000 }, - { 0x00000000, 0x00290cc7, 0x000 }, - { 0x00000027, 0x00203624, 0x000 }, - { 0x00007f00, 0x00281221, 0x000 }, - { 0x00001400, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x04b }, - { 0x00000001, 0x00290e23, 0x000 }, - { 0x0000000e, 0x00203623, 0x000 }, - { 0x0000e000, 0x00204411, 0x000 }, - { 0xfff80000, 0x00294a23, 0x000 }, - { 0x00000000, 0x003a2c02, 0x000 }, - { 0x00000002, 0x00220e2b, 0x000 }, - { 0xfc000000, 0x00280e23, 0x000 }, - { 0x0000000f, 0x00203623, 0x000 }, - { 0x00001fff, 0x00294a23, 0x000 }, - { 0x00000027, 0x00204a2d, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000029, 0x00200e2d, 0x000 }, - { 0x060a0200, 0x00294a23, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14e00000, 0x061 }, - { 0x00000000, 0x2ee00000, 0x05f }, - { 0x00000000, 0x2ce00000, 0x05e }, - { 0x00000000, 0x00400e2d, 0x062 }, - { 0x00000001, 0x00400e2d, 0x062 }, - { 0x0000000a, 0x00200e2d, 0x000 }, - { 0x0000000b, 0x0040122d, 0x06a }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x003ffffc, 0x00281223, 0x000 }, - { 0x00000002, 0x00221224, 0x000 }, - { 0x7fc00000, 0x00281623, 0x000 }, - { 0x00000014, 0x00211625, 0x000 }, - { 0x00000001, 0x00331625, 0x000 }, - { 0x80000000, 0x00280e23, 0x000 }, - { 0x00000000, 0x00290ca3, 0x000 }, - { 0x3ffffc00, 0x00290e23, 0x000 }, - { 0x0000001f, 0x00211e23, 0x000 }, - { 0x00000000, 0x14e00000, 0x06d }, - { 0x00000100, 0x00401c11, 0x070 }, - { 0x0000000d, 0x00201e2d, 0x000 }, - { 0x000000f0, 0x00281e27, 0x000 }, - { 0x00000004, 0x00221e27, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0xfffff0ff, 0x00281a30, 0x000 }, - { 0x0000a028, 0x00204411, 0x000 }, - { 0x00000000, 0x002948e6, 0x000 }, - { 0x0000a018, 0x00204411, 0x000 }, - { 0x3fffffff, 0x00284a23, 0x000 }, - { 0x0000a010, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000030, 0x0020162d, 0x000 }, - { 0x00000002, 0x00291625, 0x000 }, - { 0x00000030, 0x00203625, 0x000 }, - { 0x00000025, 0x0020162d, 0x000 }, - { 0x00000000, 0x002f00a3, 0x000 }, - { 0x00000000, 0x0cc00000, 0x083 }, - { 0x00000026, 0x0020162d, 0x000 }, - { 0x00000000, 0x002f00a4, 0x000 }, - { 0x00000000, 0x0cc00000, 0x084 }, - { 0x00000000, 0x00400000, 0x08a }, - { 0x00000025, 0x00203623, 0x000 }, - { 0x00000026, 0x00203624, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x08a }, - { 0x00000000, 0x00600000, 0x5ff }, - { 0x00000000, 0x00600000, 0x5f3 }, - { 0x00000002, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x08d }, - { 0x00000012, 0xc0403620, 0x093 }, - { 0x00000000, 0x2ee00000, 0x091 }, - { 0x00000000, 0x2ce00000, 0x090 }, - { 0x00000002, 0x00400e2d, 0x092 }, - { 0x00000003, 0x00400e2d, 0x092 }, - { 0x0000000c, 0x00200e2d, 0x000 }, - { 0x00000012, 0x00203623, 0x000 }, - { 0x00000003, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x098 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x0a0 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x2ee00000, 0x09e }, - { 0x00000000, 0x2ce00000, 0x09d }, - { 0x00000002, 0x00400e2d, 0x09f }, - { 0x00000003, 0x00400e2d, 0x09f }, - { 0x0000000c, 0x00200e2d, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000000, 0x003a0c02, 0x000 }, - { 0x003f0000, 0x00280e23, 0x000 }, - { 0x00000010, 0x00210e23, 0x000 }, - { 0x00000011, 0x00203623, 0x000 }, - { 0x0000001e, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0a7 }, - { 0x00000016, 0xc0203620, 0x000 }, - { 0x0000001f, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0aa }, - { 0x00000015, 0xc0203620, 0x000 }, - { 0x00000008, 0x00210e2b, 0x000 }, - { 0x0000007f, 0x00280e23, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0e1 }, - { 0x00000000, 0x27000000, 0x000 }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ae00000, 0x0b3 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x0000000c, 0x00221e30, 0x000 }, - { 0x99800000, 0x00204411, 0x000 }, - { 0x00000004, 0x0020122d, 0x000 }, - { 0x00000008, 0x00221224, 0x000 }, - { 0x00000010, 0x00201811, 0x000 }, - { 0x00000000, 0x00291ce4, 0x000 }, - { 0x00000000, 0x00604807, 0x12f }, - { 0x9b000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x9c000000, 0x00204411, 0x000 }, - { 0x00000000, 0x0033146f, 0x000 }, - { 0x00000001, 0x00333e23, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0x00203c05, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x00000000, 0x00201010, 0x000 }, - { 0x0000e007, 0x00204411, 0x000 }, - { 0x0000000f, 0x0021022b, 0x000 }, - { 0x00000000, 0x14c00000, 0x0cb }, - { 0x00f8ff08, 0x00204811, 0x000 }, - { 0x98000000, 0x00404811, 0x0dc }, - { 0x000000f0, 0x00280e22, 0x000 }, - { 0x000000a0, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x0da }, - { 0x00000011, 0x00200e2d, 0x000 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0d5 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0d4 }, - { 0x00003f00, 0x00400c11, 0x0d6 }, - { 0x00001f00, 0x00400c11, 0x0d6 }, - { 0x00000f00, 0x00200c11, 0x000 }, - { 0x00380009, 0x00294a23, 0x000 }, - { 0x3f000000, 0x00280e2b, 0x000 }, - { 0x00000002, 0x00220e23, 0x000 }, - { 0x00000007, 0x00494a23, 0x0dc }, - { 0x00380f09, 0x00204811, 0x000 }, - { 0x68000007, 0x00204811, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a24, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000a202, 0x00204411, 0x000 }, - { 0x00ff0000, 0x00280e22, 0x000 }, - { 0x00000080, 0x00294a23, 0x000 }, - { 0x00000027, 0x00200e2d, 0x000 }, - { 0x00000026, 0x0020122d, 0x000 }, - { 0x00000000, 0x002f0083, 0x000 }, - { 0x00000000, 0x0ce00000, 0x0ea }, - { 0x00000000, 0x00600000, 0x5f9 }, - { 0x00000000, 0x00400000, 0x0eb }, - { 0x00000000, 0x00600000, 0x5fc }, - { 0x00000007, 0x0020222d, 0x000 }, - { 0x00000005, 0x00220e22, 0x000 }, - { 0x00100000, 0x00280e23, 0x000 }, - { 0x00000000, 0x00292068, 0x000 }, - { 0x00000000, 0x003a0c02, 0x000 }, - { 0x000000ef, 0x00280e23, 0x000 }, - { 0x00000000, 0x00292068, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0x00000003, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x0f8 }, - { 0x0000000b, 0x00210228, 0x000 }, - { 0x00000000, 0x14c00000, 0x0f8 }, - { 0x00000400, 0x00292228, 0x000 }, - { 0x00000014, 0x00203628, 0x000 }, - { 0x0000001c, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x0fd }, - { 0x0000a30c, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000001e, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x10b }, - { 0x0000a30f, 0x00204411, 0x000 }, - { 0x00000011, 0x00200e2d, 0x000 }, - { 0x00000001, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x104 }, - { 0xffffffff, 0x00404811, 0x10b }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x107 }, - { 0x0000ffff, 0x00404811, 0x10b }, - { 0x00000004, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x10a }, - { 0x000000ff, 0x00404811, 0x10b }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0002c400, 0x00204411, 0x000 }, - { 0x0000001f, 0x00210e22, 0x000 }, - { 0x00000000, 0x14c00000, 0x112 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x00000013, 0x00203623, 0x000 }, - { 0x00000018, 0x40224a20, 0x000 }, - { 0x00000010, 0xc0424a20, 0x114 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x00000013, 0x00203623, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000000a, 0x00201011, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x11b }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00531224, 0x117 }, - { 0xffbfffff, 0x00283a2e, 0x000 }, - { 0x0000001b, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x12e }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000d, 0x00204811, 0x000 }, - { 0x00000018, 0x00220e30, 0x000 }, - { 0xfc000000, 0x00280e23, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x00000000, 0x00201010, 0x000 }, - { 0x0000e00e, 0x00204411, 0x000 }, - { 0x07f8ff08, 0x00204811, 0x000 }, - { 0x00000000, 0x00294a23, 0x000 }, - { 0x0000001c, 0x00201e2d, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a24, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x00800000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204806, 0x000 }, - { 0x00000008, 0x00214a27, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x622 }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x621 }, - { 0x00000004, 0x00404c11, 0x135 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x0000001c, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x622 }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x13c }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00000000, 0x00600000, 0x160 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000ffff, 0x40280620, 0x000 }, - { 0x00000010, 0xc0210a20, 0x000 }, - { 0x00000000, 0x00341461, 0x000 }, - { 0x00000000, 0x00741882, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x147 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x160 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x00000010, 0x40211620, 0x000 }, - { 0x0000ffff, 0xc0681a20, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x158 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000001, 0x00300a2f, 0x000 }, - { 0x00000001, 0x00210a22, 0x000 }, - { 0x00000003, 0x00384a22, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001a, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600000, 0x18f }, - { 0x00000000, 0x00600000, 0x1a0 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00202c08, 0x000 }, - { 0x00000000, 0x00202411, 0x000 }, - { 0x00000000, 0x00202811, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000002, 0x00221e29, 0x000 }, - { 0x00000000, 0x007048eb, 0x19c }, - { 0x00000000, 0x00600000, 0x2bb }, - { 0x00000001, 0x40330620, 0x000 }, - { 0x00000000, 0xc0302409, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ae00000, 0x181 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x00000000, 0x00400000, 0x186 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x186 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000001, 0x00530621, 0x182 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0604800, 0x197 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000011, 0x0020062d, 0x000 }, - { 0x00000000, 0x0078042a, 0x2fb }, - { 0x00000000, 0x00202809, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x174 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000210, 0x00600411, 0x315 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x194 }, - { 0x00000015, 0xc0203620, 0x000 }, - { 0x00000016, 0xc0203620, 0x000 }, - { 0x3f800000, 0x00200411, 0x000 }, - { 0x46000000, 0x00600811, 0x1b2 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x19b }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000021, 0x00804811, 0x000 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000ffff, 0x40281620, 0x000 }, - { 0x00000010, 0xc0811a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x00000008, 0x00221e30, 0x000 }, - { 0x00000029, 0x00201a2d, 0x000 }, - { 0x0000e000, 0x00204411, 0x000 }, - { 0xfffbff09, 0x00204811, 0x000 }, - { 0x0000000f, 0x0020222d, 0x000 }, - { 0x00001fff, 0x00294a28, 0x000 }, - { 0x00000006, 0x0020222d, 0x000 }, - { 0x00000000, 0x002920e8, 0x000 }, - { 0x00000000, 0x00204808, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00294a26, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000100, 0x00201811, 0x000 }, - { 0x00000008, 0x00621e28, 0x12f }, - { 0x00000008, 0x00822228, 0x000 }, - { 0x0002c000, 0x00204411, 0x000 }, - { 0x00000015, 0x00600e2d, 0x1bd }, - { 0x00000016, 0x00600e2d, 0x1bd }, - { 0x0000c008, 0x00204411, 0x000 }, - { 0x00000017, 0x00200e2d, 0x000 }, - { 0x00000000, 0x14c00000, 0x1b9 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0x39000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00804802, 0x000 }, - { 0x00000018, 0x00202e2d, 0x000 }, - { 0x00000000, 0x003b0d63, 0x000 }, - { 0x00000008, 0x00224a23, 0x000 }, - { 0x00000010, 0x00224a23, 0x000 }, - { 0x00000018, 0x00224a23, 0x000 }, - { 0x00000000, 0x00804803, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00001000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00000007, 0x0021062f, 0x000 }, - { 0x00000013, 0x00200a2d, 0x000 }, - { 0x00000001, 0x00202c11, 0x000 }, - { 0x0000ffff, 0x40282220, 0x000 }, - { 0x0000000f, 0x00262228, 0x000 }, - { 0x00000010, 0x40212620, 0x000 }, - { 0x0000000f, 0x00262629, 0x000 }, - { 0x00000000, 0x00202802, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001b, 0x00204811, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1e0 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000081, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000080, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1dc }, - { 0x00000000, 0x00600000, 0x1e9 }, - { 0x00000001, 0x00531e27, 0x1d8 }, - { 0x00000001, 0x00202c11, 0x000 }, - { 0x0000001f, 0x00280a22, 0x000 }, - { 0x0000001f, 0x00282a2a, 0x000 }, - { 0x00000001, 0x00530621, 0x1d1 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000002, 0x00304a2f, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000001, 0x00301e2f, 0x000 }, - { 0x00000000, 0x002f0227, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00600000, 0x1e9 }, - { 0x00000001, 0x00531e27, 0x1e5 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x0000000f, 0x00260e23, 0x000 }, - { 0x00000010, 0xc0211220, 0x000 }, - { 0x0000000f, 0x00261224, 0x000 }, - { 0x00000000, 0x00201411, 0x000 }, - { 0x00000000, 0x00601811, 0x2bb }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022b, 0x000 }, - { 0x00000000, 0x0ce00000, 0x1f8 }, - { 0x00000010, 0x00221628, 0x000 }, - { 0xffff0000, 0x00281625, 0x000 }, - { 0x0000ffff, 0x00281a29, 0x000 }, - { 0x00000000, 0x002948c5, 0x000 }, - { 0x00000000, 0x0020480a, 0x000 }, - { 0x00000000, 0x00202c11, 0x000 }, - { 0x00000010, 0x00221623, 0x000 }, - { 0xffff0000, 0x00281625, 0x000 }, - { 0x0000ffff, 0x00281a24, 0x000 }, - { 0x00000000, 0x002948c5, 0x000 }, - { 0x00000000, 0x00731503, 0x205 }, - { 0x00000000, 0x00201805, 0x000 }, - { 0x00000000, 0x00731524, 0x205 }, - { 0x00000000, 0x002d14c5, 0x000 }, - { 0x00000000, 0x003008a2, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00202802, 0x000 }, - { 0x00000000, 0x00202003, 0x000 }, - { 0x00000000, 0x00802404, 0x000 }, - { 0x0000000f, 0x00210225, 0x000 }, - { 0x00000000, 0x14c00000, 0x621 }, - { 0x00000000, 0x002b1405, 0x000 }, - { 0x00000001, 0x00901625, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001a, 0x00294a22, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00384a21, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000ffff, 0x40281220, 0x000 }, - { 0x00000010, 0xc0211a20, 0x000 }, - { 0x0000ffff, 0x40280e20, 0x000 }, - { 0x00000010, 0xc0211620, 0x000 }, - { 0x00000000, 0x00741465, 0x2bb }, - { 0x0001a1fd, 0x00604411, 0x2e0 }, - { 0x00000001, 0x00330621, 0x000 }, - { 0x00000000, 0x002f0221, 0x000 }, - { 0x00000000, 0x0cc00000, 0x219 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x212 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x5de }, - { 0x00000000, 0x0040040f, 0x213 }, - { 0x00000000, 0x00600000, 0x5d1 }, - { 0x00000000, 0x00600000, 0x5de }, - { 0x00000210, 0x00600411, 0x315 }, - { 0x00000000, 0x00600000, 0x1a0 }, - { 0x00000000, 0x00600000, 0x19c }, - { 0x00000000, 0x00600000, 0x2bb }, - { 0x00000000, 0x00600000, 0x2a3 }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204808, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ae00000, 0x232 }, - { 0x00000000, 0x00600000, 0x13a }, - { 0x00000000, 0x00400000, 0x236 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x236 }, - { 0x00000000, 0xc0404800, 0x233 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x00600411, 0x2fb }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000000, 0x00600000, 0x5d1 }, - { 0x0000a00c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000018, 0x40210a20, 0x000 }, - { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x24c }, - { 0x00000014, 0x0020222d, 0x000 }, - { 0x00080101, 0x00292228, 0x000 }, - { 0x00000014, 0x00203628, 0x000 }, - { 0x0000a30c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x251 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000010, 0x00600411, 0x315 }, - { 0x3f800000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x00000000, 0x00600000, 0x27c }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000001, 0x00211e27, 0x000 }, - { 0x00000000, 0x14e00000, 0x26a }, - { 0x00000012, 0x00201e2d, 0x000 }, - { 0x0000ffff, 0x00281e27, 0x000 }, - { 0x00000000, 0x00341c27, 0x000 }, - { 0x00000000, 0x12c00000, 0x25f }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f00e5, 0x000 }, - { 0x00000000, 0x08c00000, 0x262 }, - { 0x00000000, 0x00201407, 0x000 }, - { 0x00000012, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00211e27, 0x000 }, - { 0x00000000, 0x00341c47, 0x000 }, - { 0x00000000, 0x12c00000, 0x267 }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x002f00e6, 0x000 }, - { 0x00000000, 0x08c00000, 0x26a }, - { 0x00000000, 0x00201807, 0x000 }, - { 0x00000000, 0x00600000, 0x2c1 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x00000000, 0x00342023, 0x000 }, - { 0x00000000, 0x12c00000, 0x272 }, - { 0x00000000, 0x00342044, 0x000 }, - { 0x00000000, 0x12c00000, 0x271 }, - { 0x00000016, 0x00404811, 0x276 }, - { 0x00000018, 0x00404811, 0x276 }, - { 0x00000000, 0x00342044, 0x000 }, - { 0x00000000, 0x12c00000, 0x275 }, - { 0x00000017, 0x00404811, 0x276 }, - { 0x00000019, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0x00604411, 0x2e9 }, - { 0x00003fff, 0x002f022f, 0x000 }, - { 0x00000000, 0x0cc00000, 0x256 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x00000010, 0x40210620, 0x000 }, - { 0x0000ffff, 0xc0280a20, 0x000 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x00000010, 0x40211620, 0x000 }, - { 0x0000ffff, 0xc0881a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00042004, 0x00604411, 0x622 }, - { 0x00000000, 0x00600000, 0x5d1 }, - { 0x00000000, 0xc0600000, 0x2a3 }, - { 0x00000005, 0x00200a2d, 0x000 }, - { 0x00000008, 0x00220a22, 0x000 }, - { 0x0000002b, 0x00201a2d, 0x000 }, - { 0x0000001c, 0x00201e2d, 0x000 }, - { 0x00007000, 0x00281e27, 0x000 }, - { 0x00000000, 0x00311ce6, 0x000 }, - { 0x0000002a, 0x00201a2d, 0x000 }, - { 0x0000000c, 0x00221a26, 0x000 }, - { 0x00000000, 0x002f00e6, 0x000 }, - { 0x00000000, 0x06e00000, 0x292 }, - { 0x00000000, 0x00201c11, 0x000 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x0000002b, 0x00203623, 0x000 }, - { 0x00000010, 0x00201811, 0x000 }, - { 0x00000000, 0x00691ce2, 0x12f }, - { 0x93800000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x95000000, 0x00204411, 0x000 }, - { 0x00000000, 0x002f022f, 0x000 }, - { 0x00000000, 0x0ce00000, 0x29d }, - { 0x00000001, 0x00333e2f, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x92000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000001c, 0x00403627, 0x000 }, - { 0x0000000c, 0xc0220a20, 0x000 }, - { 0x00000029, 0x00203622, 0x000 }, - { 0x00000028, 0xc0403620, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000009, 0x00204811, 0x000 }, - { 0xa1000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00804811, 0x000 }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002c1ce3, 0x000 }, - { 0x00000021, 0x00203627, 0x000 }, - { 0x00000022, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002c1ce4, 0x000 }, - { 0x00000022, 0x00203627, 0x000 }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120a3, 0x000 }, - { 0x00000000, 0x002d1d07, 0x000 }, - { 0x00000023, 0x00203627, 0x000 }, - { 0x00000024, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x00000000, 0x002d1d07, 0x000 }, - { 0x00000024, 0x00803627, 0x000 }, - { 0x00000021, 0x00203623, 0x000 }, - { 0x00000022, 0x00203624, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000023, 0x00203627, 0x000 }, - { 0x00000000, 0x00311cc4, 0x000 }, - { 0x00000024, 0x00803627, 0x000 }, - { 0x0000001a, 0x00203627, 0x000 }, - { 0x0000001b, 0x00203628, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14c00000, 0x2dc }, - { 0x00000000, 0x00400000, 0x2d9 }, - { 0x0000001a, 0x00203627, 0x000 }, - { 0x0000001b, 0x00203628, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000002, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x2d9 }, - { 0x00000003, 0x00210227, 0x000 }, - { 0x00000000, 0x14e00000, 0x2dc }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002e00e1, 0x000 }, - { 0x00000000, 0x02c00000, 0x2dc }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120a1, 0x000 }, - { 0x00000000, 0x002e00e8, 0x000 }, - { 0x00000000, 0x06c00000, 0x2dc }, - { 0x00000024, 0x00201e2d, 0x000 }, - { 0x00000000, 0x002e00e2, 0x000 }, - { 0x00000000, 0x02c00000, 0x2dc }, - { 0x00000022, 0x00201e2d, 0x000 }, - { 0x00000000, 0x003120c2, 0x000 }, - { 0x00000000, 0x002e00e8, 0x000 }, - { 0x00000000, 0x06c00000, 0x2dc }, - { 0x00000000, 0x00600000, 0x5ff }, - { 0x00000000, 0x00600000, 0x2b5 }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x00000000, 0x00600000, 0x2b5 }, - { 0x00000000, 0x00600000, 0x5f6 }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x00000000, 0x00600000, 0x2a7 }, - { 0x00000000, 0x00400000, 0x2de }, - { 0x0000001a, 0x00201e2d, 0x000 }, - { 0x0000001b, 0x0080222d, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000010, 0x00221e21, 0x000 }, - { 0x00000000, 0x00294847, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000000, 0x00311ca1, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294847, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000010, 0x00221e21, 0x000 }, - { 0x00000000, 0x003120c2, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000001, 0x00220a21, 0x000 }, - { 0x00000000, 0x003308a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00311ca3, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294887, 0x000 }, - { 0x00000001, 0x00220a21, 0x000 }, - { 0x00000000, 0x003008a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000010, 0x00221e23, 0x000 }, - { 0x00000000, 0x003120c4, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x003808c5, 0x000 }, - { 0x00000000, 0x00300841, 0x000 }, - { 0x00000001, 0x00220a22, 0x000 }, - { 0x00000000, 0x003308a2, 0x000 }, - { 0x00000010, 0x00221e22, 0x000 }, - { 0x00000010, 0x00212222, 0x000 }, - { 0x00000000, 0x00894907, 0x000 }, - { 0x00000017, 0x0020222d, 0x000 }, - { 0x00000000, 0x14c00000, 0x318 }, - { 0xffffffef, 0x00280621, 0x000 }, - { 0x00000014, 0x0020222d, 0x000 }, - { 0x0000f8e0, 0x00204411, 0x000 }, - { 0x00000000, 0x00294901, 0x000 }, - { 0x00000000, 0x00894901, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x060a0200, 0x00804811, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x97000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0204811, 0x000 }, - { 0x8a000000, 0xc0204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00002257, 0x00204411, 0x000 }, - { 0x00000003, 0xc0484a20, 0x000 }, - { 0x0000225d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0x00600000, 0x5de }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00384a22, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0001a1fd, 0x00204411, 0x000 }, - { 0x00000000, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x40204800, 0x000 }, - { 0x00000001, 0x40304a20, 0x000 }, - { 0x00000002, 0xc0304a20, 0x000 }, - { 0x00000001, 0x00530a22, 0x355 }, - { 0x0000003f, 0xc0280a20, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000018, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x622 }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x35e }, - { 0x00000014, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x36c }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00604802, 0x374 }, - { 0x00002100, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x370 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x367 }, - { 0x00000028, 0x002f0222, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5ba }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x367 }, - { 0x0000002c, 0x00203626, 0x000 }, - { 0x00000049, 0x00201811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x00000001, 0x00331a26, 0x000 }, - { 0x00000000, 0x002f0226, 0x000 }, - { 0x00000000, 0x0cc00000, 0x376 }, - { 0x0000002c, 0x00801a2d, 0x000 }, - { 0x0000003f, 0xc0280a20, 0x000 }, - { 0x00000015, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x38c }, - { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3b7 }, - { 0x00000016, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3b9 }, - { 0x00000020, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3a2 }, - { 0x0000000f, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3ae }, - { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x3ae }, - { 0x0000001e, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x396 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x08000000, 0x00290a22, 0x000 }, - { 0x00000003, 0x40210e20, 0x000 }, - { 0x0000000c, 0xc0211220, 0x000 }, - { 0x00080000, 0x00281224, 0x000 }, - { 0x00000014, 0xc0221620, 0x000 }, - { 0x00000000, 0x002914a4, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x002948a2, 0x000 }, - { 0x0000a1fe, 0x00204411, 0x000 }, - { 0x00000000, 0x00404803, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000016, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x622 }, - { 0x00000015, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x398 }, - { 0x0000210e, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000017, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x622 }, - { 0x00000003, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x3a4 }, - { 0x00002108, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404802, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x80000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000010, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x3b4 }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000006, 0x00404811, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000016, 0x00604811, 0x374 }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x0000001d, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x3ce }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x00000018, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x622 }, - { 0x00000011, 0x00210230, 0x000 }, - { 0x00000000, 0x14e00000, 0x3c2 }, - { 0x00002100, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0xbabecafe, 0x00204811, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000004, 0x00404811, 0x000 }, - { 0x00002170, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000a, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x3d3 }, - { 0x8c000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00003fff, 0x40280a20, 0x000 }, - { 0x80000000, 0x40280e20, 0x000 }, - { 0x40000000, 0xc0281220, 0x000 }, - { 0x00040000, 0x00694622, 0x622 }, - { 0x00000000, 0x00201410, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x3e1 }, - { 0x00000000, 0xc0401800, 0x3e4 }, - { 0x00003fff, 0xc0281a20, 0x000 }, - { 0x00040000, 0x00694626, 0x622 }, - { 0x00000000, 0x00201810, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x3e7 }, - { 0x00000000, 0xc0401c00, 0x3ea }, - { 0x00003fff, 0xc0281e20, 0x000 }, - { 0x00040000, 0x00694627, 0x622 }, - { 0x00000000, 0x00201c10, 0x000 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0x002820c5, 0x000 }, - { 0x00000000, 0x004948e8, 0x000 }, - { 0xa5800000, 0x00200811, 0x000 }, - { 0x00002000, 0x00200c11, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x40204800, 0x000 }, - { 0x0000001f, 0xc0210220, 0x000 }, - { 0x00000000, 0x14c00000, 0x3f7 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00008000, 0x00204811, 0x000 }, - { 0x0000ffff, 0xc0481220, 0x3ff }, - { 0xa7800000, 0x00200811, 0x000 }, - { 0x0000a000, 0x00200c11, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0x00204402, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000ffff, 0xc0281220, 0x000 }, - { 0x83000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00304883, 0x000 }, - { 0x84000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1d000000, 0x000 }, - { 0x83000000, 0x00604411, 0x412 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0xa9800000, 0x00200811, 0x000 }, - { 0x0000c000, 0x00400c11, 0x3fa }, - { 0xab800000, 0x00200811, 0x000 }, - { 0x0000f8e0, 0x00400c11, 0x3fa }, - { 0xad800000, 0x00200811, 0x000 }, - { 0x0000f880, 0x00400c11, 0x3fa }, - { 0xb3800000, 0x00200811, 0x000 }, - { 0x0000f3fc, 0x00400c11, 0x3fa }, - { 0xaf800000, 0x00200811, 0x000 }, - { 0x0000e000, 0x00400c11, 0x3fa }, - { 0xb1800000, 0x00200811, 0x000 }, - { 0x0000f000, 0x00400c11, 0x3fa }, - { 0x83000000, 0x00204411, 0x000 }, - { 0x00002148, 0x00204811, 0x000 }, - { 0x84000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x1d000000, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x01182000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0218a000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0318c000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0418f8e0, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0518f880, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0618e000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0718f000, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x0818f3fc, 0xc0304620, 0x000 }, - { 0x00000000, 0xd9004800, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x00000033, 0xc0300a20, 0x000 }, - { 0x00000000, 0xc0403440, 0x000 }, - { 0x00000030, 0x00200a2d, 0x000 }, - { 0x00000000, 0xc0290c40, 0x000 }, - { 0x00000030, 0x00203623, 0x000 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x00a0000a, 0x000 }, - { 0x86000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00404801, 0x000 }, - { 0x85000000, 0xc0204411, 0x000 }, - { 0x00000000, 0x00404801, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x00000018, 0x40210220, 0x000 }, - { 0x00000000, 0x14c00000, 0x447 }, - { 0x00800000, 0xc0494a20, 0x448 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x06e00000, 0x450 }, - { 0x00000004, 0x00200811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x622 }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000000, 0x00404c02, 0x450 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x00000000, 0xc0201000, 0x000 }, - { 0x00000000, 0xc0201400, 0x000 }, - { 0x00000000, 0xc0201800, 0x000 }, - { 0x00000000, 0xc0201c00, 0x000 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x461 }, - { 0x00000000, 0xc0202000, 0x000 }, - { 0x00000004, 0x002f0228, 0x000 }, - { 0x00000000, 0x06e00000, 0x461 }, - { 0x00000004, 0x00202011, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x00000010, 0x00280a23, 0x000 }, - { 0x00000010, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ce00000, 0x469 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0x00694624, 0x622 }, - { 0x00000000, 0x00400000, 0x46e }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x00604805, 0x627 }, - { 0x00000000, 0x002824f0, 0x000 }, - { 0x00000007, 0x00280a23, 0x000 }, - { 0x00000001, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x475 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x04e00000, 0x48e }, - { 0x00000000, 0x00400000, 0x49b }, - { 0x00000002, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x47a }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x02e00000, 0x48e }, - { 0x00000000, 0x00400000, 0x49b }, - { 0x00000003, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x47f }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x0ce00000, 0x48e }, - { 0x00000000, 0x00400000, 0x49b }, - { 0x00000004, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x484 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x0ae00000, 0x48e }, - { 0x00000000, 0x00400000, 0x49b }, - { 0x00000005, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x489 }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x06e00000, 0x48e }, - { 0x00000000, 0x00400000, 0x49b }, - { 0x00000006, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x48e }, - { 0x00000000, 0x002f00c9, 0x000 }, - { 0x00000000, 0x08e00000, 0x48e }, - { 0x00000000, 0x00400000, 0x49b }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x000 }, - { 0x00000008, 0x00210a23, 0x000 }, - { 0x00000000, 0x14c00000, 0x498 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x00000000, 0xc0204400, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00007f00, 0x00280a21, 0x000 }, - { 0x00004500, 0x002f0222, 0x000 }, - { 0x00000000, 0x0ae00000, 0x4a1 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x00404c08, 0x461 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000010, 0x40210e20, 0x000 }, - { 0x00000011, 0x40211220, 0x000 }, - { 0x00000012, 0x40211620, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00210225, 0x000 }, - { 0x00000000, 0x14e00000, 0x4ab }, - { 0x00040000, 0xc0494a20, 0x4ac }, - { 0xfffbffff, 0xc0284a20, 0x000 }, - { 0x00000000, 0x00210223, 0x000 }, - { 0x00000000, 0x14e00000, 0x4b8 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x0000000c, 0x00204811, 0x000 }, - { 0x00000000, 0x00200010, 0x000 }, - { 0x00000000, 0x14c00000, 0x4b4 }, - { 0xa0000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000004, 0x00204811, 0x000 }, - { 0x0000216b, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204810, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000005, 0x00204811, 0x000 }, - { 0x0000216c, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204810, 0x000 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0ce00000, 0x000 }, - { 0x00000000, 0x00400000, 0x4b2 }, - { 0x00000000, 0xc0210a20, 0x000 }, - { 0x00000000, 0x14c00000, 0x4cb }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0604800, 0x627 }, - { 0x00000000, 0x00400000, 0x4cf }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00040000, 0xc0294620, 0x000 }, - { 0x00000000, 0xc0600000, 0x622 }, - { 0x00000001, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x4d6 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0xcafebabe, 0x00404811, 0x000 }, - { 0x00000000, 0xc0204400, 0x000 }, - { 0x00000000, 0xc0404810, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x000021f8, 0x00204411, 0x000 }, - { 0x0000000e, 0x00204811, 0x000 }, - { 0x000421f9, 0x00604411, 0x622 }, - { 0x00000000, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x4d8 }, - { 0x00002180, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000003, 0x00333e2f, 0x000 }, - { 0x00000001, 0x00210221, 0x000 }, - { 0x00000000, 0x14e00000, 0x508 }, - { 0x0000002c, 0x00200a2d, 0x000 }, - { 0x00040000, 0x18e00c11, 0x4f7 }, - { 0x00000001, 0x00333e2f, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xd8c04800, 0x4eb }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000002d, 0x0020122d, 0x000 }, - { 0x00000000, 0x00290c83, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204802, 0x000 }, - { 0x00000000, 0x00204803, 0x000 }, - { 0x00000008, 0x00300a22, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000011, 0x00210224, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000000, 0x00400000, 0x4b2 }, - { 0x0000002c, 0xc0203620, 0x000 }, - { 0x0000002d, 0xc0403620, 0x000 }, - { 0x0000000f, 0x00210221, 0x000 }, - { 0x00000000, 0x14c00000, 0x50d }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00000000, 0xd9000000, 0x000 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0xb5000000, 0x00204411, 0x000 }, - { 0x00002000, 0x00204811, 0x000 }, - { 0xb6000000, 0x00204411, 0x000 }, - { 0x0000a000, 0x00204811, 0x000 }, - { 0xb7000000, 0x00204411, 0x000 }, - { 0x0000c000, 0x00204811, 0x000 }, - { 0xb8000000, 0x00204411, 0x000 }, - { 0x0000f8e0, 0x00204811, 0x000 }, - { 0xb9000000, 0x00204411, 0x000 }, - { 0x0000f880, 0x00204811, 0x000 }, - { 0xba000000, 0x00204411, 0x000 }, - { 0x0000e000, 0x00204811, 0x000 }, - { 0xbb000000, 0x00204411, 0x000 }, - { 0x0000f000, 0x00204811, 0x000 }, - { 0xbc000000, 0x00204411, 0x000 }, - { 0x0000f3fc, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000002, 0x00204811, 0x000 }, - { 0x000000ff, 0x00280e30, 0x000 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x521 }, - { 0x00000000, 0xc0200800, 0x000 }, - { 0x00000000, 0x14c00000, 0x536 }, - { 0x00000000, 0x00200c11, 0x000 }, - { 0x0000001c, 0x00203623, 0x000 }, - { 0x0000002b, 0x00203623, 0x000 }, - { 0x00000029, 0x00203623, 0x000 }, - { 0x00000028, 0x00203623, 0x000 }, - { 0x00000017, 0x00203623, 0x000 }, - { 0x00000025, 0x00203623, 0x000 }, - { 0x00000026, 0x00203623, 0x000 }, - { 0x00000015, 0x00203623, 0x000 }, - { 0x00000016, 0x00203623, 0x000 }, - { 0xffffe000, 0x00200c11, 0x000 }, - { 0x00000021, 0x00203623, 0x000 }, - { 0x00000022, 0x00203623, 0x000 }, - { 0x00001fff, 0x00200c11, 0x000 }, - { 0x00000023, 0x00203623, 0x000 }, - { 0x00000024, 0x00203623, 0x000 }, - { 0xf1ffffff, 0x00283a2e, 0x000 }, - { 0x0000001a, 0xc0220e20, 0x000 }, - { 0x00000000, 0x0029386e, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000006, 0x00204811, 0x000 }, - { 0x0000002a, 0x40203620, 0x000 }, - { 0x87000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x0000a1f4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0x9d000000, 0x00204411, 0x000 }, - { 0x0000001f, 0x40214a20, 0x000 }, - { 0x96000000, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0200c00, 0x000 }, - { 0x00000000, 0xc0201000, 0x000 }, - { 0x0000001f, 0x00211624, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x0000001d, 0x00203623, 0x000 }, - { 0x00000003, 0x00281e23, 0x000 }, - { 0x00000008, 0x00222223, 0x000 }, - { 0xfffff000, 0x00282228, 0x000 }, - { 0x00000000, 0x002920e8, 0x000 }, - { 0x0000001f, 0x00203628, 0x000 }, - { 0x00000018, 0x00211e23, 0x000 }, - { 0x00000020, 0x00203627, 0x000 }, - { 0x00000002, 0x00221624, 0x000 }, - { 0x00000000, 0x003014a8, 0x000 }, - { 0x0000001e, 0x00203625, 0x000 }, - { 0x00000003, 0x00211a24, 0x000 }, - { 0x10000000, 0x00281a26, 0x000 }, - { 0xefffffff, 0x00283a2e, 0x000 }, - { 0x00000000, 0x004938ce, 0x610 }, - { 0x00000001, 0x40280a20, 0x000 }, - { 0x00000006, 0x40280e20, 0x000 }, - { 0x00000300, 0xc0281220, 0x000 }, - { 0x00000008, 0x00211224, 0x000 }, - { 0x00000000, 0xc0201620, 0x000 }, - { 0x00000000, 0xc0201a20, 0x000 }, - { 0x00000000, 0x00210222, 0x000 }, - { 0x00000000, 0x14c00000, 0x56c }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00002258, 0x00300a24, 0x000 }, - { 0x00040000, 0x00694622, 0x622 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00020000, 0x00294a26, 0x000 }, - { 0x00000000, 0x00204810, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x574 }, - { 0x00000000, 0xc0201c10, 0x000 }, - { 0x00000000, 0xc0400000, 0x582 }, - { 0x00000002, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x574 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00002258, 0x00300a24, 0x000 }, - { 0x00040000, 0x00694622, 0x622 }, - { 0x00000000, 0xc0201c10, 0x000 }, - { 0x00000000, 0xc0400000, 0x582 }, - { 0x00000000, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x578 }, - { 0x00000000, 0xc0201c00, 0x000 }, - { 0x00000000, 0xc0400000, 0x582 }, - { 0x00000004, 0x002f0223, 0x000 }, - { 0x00000000, 0x0cc00000, 0x580 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x0000216d, 0x00204411, 0x000 }, - { 0x00000000, 0xc0204800, 0x000 }, - { 0x00000000, 0xc0604800, 0x627 }, - { 0x00000000, 0x00401c10, 0x582 }, - { 0x00000000, 0xc0200000, 0x000 }, - { 0x00000000, 0xc0400000, 0x000 }, - { 0x00000000, 0x0ee00000, 0x584 }, - { 0x00000000, 0x00600000, 0x5c3 }, - { 0x00000000, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x592 }, - { 0x0000a2b7, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x00000033, 0x0020262d, 0x000 }, - { 0x0000001a, 0x00212229, 0x000 }, - { 0x00000006, 0x00222629, 0x000 }, - { 0x0000a2c4, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x590 }, - { 0x0000a2d1, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d1, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x00000001, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5a0 }, - { 0x0000a2bb, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x00000034, 0x0020262d, 0x000 }, - { 0x0000001a, 0x00212229, 0x000 }, - { 0x00000006, 0x00222629, 0x000 }, - { 0x0000a2c5, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x59e }, - { 0x0000a2d2, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d2, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x00000002, 0x002f0224, 0x000 }, - { 0x00000000, 0x0cc00000, 0x5ae }, - { 0x0000a2bf, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x00000035, 0x0020262d, 0x000 }, - { 0x0000001a, 0x00212229, 0x000 }, - { 0x00000006, 0x00222629, 0x000 }, - { 0x0000a2c6, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x5ac }, - { 0x0000a2d3, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d3, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x0000a2c3, 0x00204411, 0x000 }, - { 0x00000000, 0x00204807, 0x000 }, - { 0x00000036, 0x0020262d, 0x000 }, - { 0x0000001a, 0x00212229, 0x000 }, - { 0x00000006, 0x00222629, 0x000 }, - { 0x0000a2c7, 0x00204411, 0x000 }, - { 0x00000000, 0x003048e9, 0x000 }, - { 0x00000000, 0x00e00000, 0x5b8 }, - { 0x0000a2d4, 0x00204411, 0x000 }, - { 0x00000000, 0x00404808, 0x000 }, - { 0x0000a2d4, 0x00204411, 0x000 }, - { 0x00000001, 0x00504a28, 0x000 }, - { 0x85000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0x0000304a, 0x00204411, 0x000 }, - { 0x01000000, 0x00204811, 0x000 }, - { 0x00000000, 0x00400000, 0x5be }, - { 0xa4000000, 0xc0204411, 0x000 }, - { 0x00000000, 0xc0404800, 0x000 }, - { 0x00000000, 0xc0600000, 0x5c3 }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x0000003f, 0x00204811, 0x000 }, - { 0x00000005, 0x00204811, 0x000 }, - { 0x0000a1f4, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x88000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0xff000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x00000002, 0x00804811, 0x000 }, - { 0x00000000, 0x0ee00000, 0x5d6 }, - { 0x00001000, 0x00200811, 0x000 }, - { 0x0000002b, 0x00203622, 0x000 }, - { 0x00000000, 0x00600000, 0x5da }, - { 0x00000000, 0x00600000, 0x5c3 }, - { 0x98000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00804811, 0x000 }, - { 0x00000000, 0xc0600000, 0x5da }, - { 0x00000000, 0xc0400400, 0x001 }, - { 0x0000a2a4, 0x00204411, 0x000 }, - { 0x00000022, 0x00204811, 0x000 }, - { 0x89000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00404811, 0x5cd }, - { 0x97000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x8a000000, 0x00204411, 0x000 }, - { 0x00000000, 0x00404811, 0x5cd }, - { 0x00000000, 0x00600000, 0x5f3 }, - { 0x0001a2a4, 0xc0204411, 0x000 }, - { 0x00000016, 0x00604811, 0x374 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00010000, 0x00204811, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x09800000, 0x00204811, 0x000 }, - { 0xffffffff, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x0004217f, 0x00604411, 0x622 }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x000 }, - { 0x00000004, 0x00404c11, 0x5ed }, - { 0x00000000, 0x00400000, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000004, 0x00291e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0xfffffffb, 0x00281e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0x00000008, 0x00291e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x00000017, 0x00201e2d, 0x000 }, - { 0xfffffff7, 0x00281e27, 0x000 }, - { 0x00000017, 0x00803627, 0x000 }, - { 0x0001a2a4, 0x00204411, 0x000 }, - { 0x00000016, 0x00604811, 0x374 }, - { 0x00002010, 0x00204411, 0x000 }, - { 0x00010000, 0x00204811, 0x000 }, - { 0x0000217c, 0x00204411, 0x000 }, - { 0x01800000, 0x00204811, 0x000 }, - { 0xffffffff, 0x00204811, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000000, 0x17000000, 0x000 }, - { 0x81000000, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0004217f, 0x00604411, 0x622 }, - { 0x0000001f, 0x00210230, 0x000 }, - { 0x00000000, 0x14c00000, 0x621 }, - { 0x00000010, 0x00404c11, 0x607 }, - { 0x00000000, 0xc0200400, 0x000 }, - { 0x00000000, 0x38c00000, 0x000 }, - { 0x0000001d, 0x00200a2d, 0x000 }, - { 0x0000001e, 0x00200e2d, 0x000 }, - { 0x0000001f, 0x0020122d, 0x000 }, - { 0x00000020, 0x0020162d, 0x000 }, - { 0x00002169, 0x00204411, 0x000 }, - { 0x00000000, 0x00204804, 0x000 }, - { 0x00000000, 0x00204805, 0x000 }, - { 0x00000000, 0x00204801, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000004, 0x00301224, 0x000 }, - { 0x00000000, 0x002f0064, 0x000 }, - { 0x00000000, 0x0cc00000, 0x620 }, - { 0x00000003, 0x00281a22, 0x000 }, - { 0x00000008, 0x00221222, 0x000 }, - { 0xfffff000, 0x00281224, 0x000 }, - { 0x00000000, 0x002910c4, 0x000 }, - { 0x0000001f, 0x00403624, 0x000 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x1ac00000, 0x622 }, - { 0x9f000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x625 }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x1ac00000, 0x627 }, - { 0x9e000000, 0x00204411, 0x000 }, - { 0xcafebabe, 0x00204811, 0x000 }, - { 0x00000000, 0x1ae00000, 0x62a }, - { 0x00000000, 0x00800000, 0x000 }, - { 0x00000000, 0x00600000, 0x00b }, - { 0x00001000, 0x00600411, 0x315 }, - { 0x00000000, 0x00200411, 0x000 }, - { 0x00000000, 0x00600811, 0x1b2 }, - { 0x0000225c, 0x00204411, 0x000 }, - { 0x00000003, 0x00204811, 0x000 }, - { 0x00002256, 0x00204411, 0x000 }, - { 0x0000001b, 0x00204811, 0x000 }, - { 0x0000a1fc, 0x00204411, 0x000 }, - { 0x00000001, 0x00204811, 0x000 }, - { 0x0001a1fd, 0xc0204411, 0x000 }, - { 0x00000021, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000024, 0x0020222d, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000022, 0x0020222d, 0x000 }, - { 0x0000ffff, 0x00282228, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00204811, 0x000 }, - { 0x00000023, 0x00201e2d, 0x000 }, - { 0x00000010, 0x00221e27, 0x000 }, - { 0x00000000, 0x00294907, 0x000 }, - { 0x00000000, 0x00404811, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x00000000, 0x00000000, 0x000 }, - { 0x0142050a, 0x05ba0250, 0x000 }, - { 0x01c30168, 0x044105ba, 0x000 }, - { 0x02250209, 0x02500151, 0x000 }, - { 0x02230245, 0x02a00241, 0x000 }, - { 0x03d705ba, 0x05ba05ba, 0x000 }, - { 0x05e205e3, 0x031f05ba, 0x000 }, - { 0x032005bf, 0x0320034a, 0x000 }, - { 0x03340282, 0x034c033e, 0x000 }, - { 0x05ba05ba, 0x05ba05ba, 0x000 }, - { 0x05ba0557, 0x05ba032a, 0x000 }, - { 0x03bc05ba, 0x04c3034e, 0x000 }, - { 0x04a20455, 0x043f05ba, 0x000 }, - { 0x04d805ba, 0x044304e5, 0x000 }, - { 0x0455050f, 0x035b037b, 0x000 }, - { 0x05ba05ba, 0x05ba05ba, 0x000 }, - { 0x05ba05ba, 0x05ba05ba, 0x000 }, - { 0x05ba05ba, 0x05d805c1, 0x000 }, - { 0x05ba05ba, 0x000705ba, 0x000 }, - { 0x05ba05ba, 0x05ba05ba, 0x000 }, - { 0x05ba05ba, 0x05ba05ba, 0x000 }, - { 0x03f803ed, 0x04080406, 0x000 }, - { 0x040e040a, 0x040c0410, 0x000 }, - { 0x041c0418, 0x04240420, 0x000 }, - { 0x042c0428, 0x04340430, 0x000 }, - { 0x05ba05ba, 0x043a0438, 0x000 }, - { 0x05ba05ba, 0x05ba05ba, 0x000 }, - { 0x05ba05ba, 0x05ba05ba, 0x000 }, - { 0x0002060e, 0x062c0006, 0x000 }, -}; - -static const u32 RS780_pfp_microcode[] = { -0xca0400, -0xa00000, -0x7e828b, -0x7c038b, -0x8001db, -0x7c038b, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xc41838, -0xca2400, -0xca2800, -0x9581cb, -0xc41c3a, -0xc3c000, -0xca0800, -0xca0c00, -0x7c744b, -0xc20005, -0x99c000, -0xc41c3a, -0x7c744c, -0xc0ffe0, -0x042c08, -0x309002, -0x7d2500, -0x351402, -0x7d350b, -0x255407, -0x7cd580, -0x259c07, -0x95c004, -0xd5001b, -0x7eddc1, -0x7d9d80, -0xd6801b, -0xd5801b, -0xd4401e, -0xd5401e, -0xd6401e, -0xd6801e, -0xd4801e, -0xd4c01e, -0x9783d3, -0xd5c01e, -0xca0800, -0x80001a, -0xca0c00, -0xe4011e, -0xd4001e, -0x80000c, -0xc41838, -0xe4013e, -0xd4001e, -0x80000c, -0xc41838, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4011e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4013e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0xca0c00, -0x8001db, -0xd48024, -0xca0800, -0x7c00c0, -0xc81425, -0xc81824, -0x7c9488, -0x7c9880, -0xc20003, -0xd40075, -0x7c744c, -0x800064, -0xd4401e, -0xca1800, -0xd4401e, -0xd5801e, -0x800062, -0xd40075, -0xd4401e, -0xca0800, -0xca0c00, -0xca1000, -0xd48019, -0xd4c018, -0xd50017, -0xd4801e, -0xd4c01e, -0xd5001e, -0xe2001e, -0xca0400, -0xa00000, -0x7e828b, -0xd40075, -0xd4401e, -0xca0800, -0xca0c00, -0xca1000, -0xd48019, -0xd4c018, -0xd50017, -0xd4801e, -0xd4c01e, -0xd5001e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0x248c01, -0xd48060, -0x94c003, -0x041001, -0x041002, -0xd50025, -0xd4401e, -0x800000, -0xd4801e, -0xca0800, -0xd48061, -0xd4401e, -0x800000, -0xd4801e, -0xca0800, -0xca0c00, -0xd4401e, -0xd48016, -0xd4c016, -0xd4801e, -0x8001db, -0xd4c01e, -0xc60843, -0xca0c00, -0xca1000, -0x948004, -0xca1400, -0xe420f3, -0xd42013, -0xd56065, -0xd4e01c, -0xd5201c, -0xd5601c, -0x800000, -0x062001, -0xc60843, -0xca0c00, -0xca1000, -0x9483f7, -0xca1400, -0xe420f3, -0x80009c, -0xd42013, -0xc60843, -0xca0c00, -0xca1000, -0x9883ef, -0xca1400, -0xd40064, -0x8000b0, -0x000000, -0xc41432, -0xc61843, -0xc4082f, -0x954005, -0xc40c30, -0xd4401e, -0x800000, -0xee001e, -0x9583f5, -0xc41031, -0xd44033, -0xd52065, -0xd4a01c, -0xd4e01c, -0xd5201c, -0xe4015e, -0xd4001e, -0x800000, -0x062001, -0xca1800, -0x0a2001, -0xd60076, -0xc40836, -0x988007, -0xc61045, -0x950110, -0xd4001f, -0xd46062, -0x800000, -0xd42062, -0xcc3835, -0xcc1433, -0x8401de, -0xd40072, -0xd5401e, -0x800000, -0xee001e, -0xe2001a, -0x8401de, -0xe2001a, -0xcc104b, -0xcc0447, -0x2c9401, -0x7d098b, -0x984005, -0x7d15cb, -0xd4001a, -0x8001db, -0xd4006d, -0x344401, -0xcc0c48, -0x98403a, -0xcc2c4a, -0x958004, -0xcc0449, -0x8001db, -0xd4001a, -0xd4c01a, -0x282801, -0x840113, -0xcc1003, -0x98801b, -0x04380c, -0x840113, -0xcc1003, -0x988017, -0x043808, -0x840113, -0xcc1003, -0x988013, -0x043804, -0x840113, -0xcc1003, -0x988014, -0xcc104c, -0x9a8009, -0xcc144d, -0x9840dc, -0xd4006d, -0xcc1848, -0xd5001a, -0xd5401a, -0x8000ec, -0xd5801a, -0x96c0d5, -0xd4006d, -0x8001db, -0xd4006e, -0x9ac003, -0xd4006d, -0xd4006e, -0x800000, -0xec007f, -0x9ac0cc, -0xd4006d, -0x8001db, -0xd4006e, -0xcc1403, -0xcc1803, -0xcc1c03, -0x7d9103, -0x7dd583, -0x7d190c, -0x35cc1f, -0x35701f, -0x7cf0cb, -0x7cd08b, -0x880000, -0x7e8e8b, -0x95c004, -0xd4006e, -0x8001db, -0xd4001a, -0xd4c01a, -0xcc0803, -0xcc0c03, -0xcc1003, -0xcc1403, -0xcc1803, -0xcc1c03, -0xcc2403, -0xcc2803, -0x35c41f, -0x36b01f, -0x7c704b, -0x34f01f, -0x7c704b, -0x35701f, -0x7c704b, -0x7d8881, -0x7dccc1, -0x7e5101, -0x7e9541, -0x7c9082, -0x7cd4c2, -0x7c848b, -0x9ac003, -0x7c8c8b, -0x2c8801, -0x98809e, -0xd4006d, -0x98409c, -0xd4006e, -0xcc084c, -0xcc0c4d, -0xcc1048, -0xd4801a, -0xd4c01a, -0x800124, -0xd5001a, -0xcc0832, -0xd40032, -0x9482b6, -0xca0c00, -0xd4401e, -0x800000, -0xd4001e, -0xe4011e, -0xd4001e, -0xca0800, -0xca0c00, -0xca1000, -0xd4401e, -0xca1400, -0xd4801e, -0xd4c01e, -0xd5001e, -0xd5401e, -0xd54034, -0x800000, -0xee001e, -0x280404, -0xe2001a, -0xe2001a, -0xd4401a, -0xca3800, -0xcc0803, -0xcc0c03, -0xcc0c03, -0xcc0c03, -0x98829a, -0x000000, -0x8401de, -0xd7a06f, -0x800000, -0xee001f, -0xca0400, -0xc2ff00, -0xcc0834, -0xc13fff, -0x7c74cb, -0x7cc90b, -0x7d010f, -0x99028d, -0x7c738b, -0x8401de, -0xd7a06f, -0x800000, -0xee001f, -0xca0800, -0x281900, -0x7d898b, -0x958014, -0x281404, -0xca0c00, -0xca1000, -0xca1c00, -0xca2400, -0xe2001f, -0xd4c01a, -0xd5001a, -0xd5401a, -0xcc1803, -0xcc2c03, -0xcc2c03, -0xcc2c03, -0x7da58b, -0x7d9c47, -0x984274, -0x000000, -0x800184, -0xd4c01a, -0xd4401e, -0xd4801e, -0x800000, -0xee001e, -0xe4011e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xe4013e, -0xd4001e, -0xd4401e, -0xee001e, -0xca0400, -0xa00000, -0x7e828b, -0xca0800, -0x248c06, -0x0ccc06, -0x98c006, -0xcc104e, -0x990004, -0xd40073, -0xe4011e, -0xd4001e, -0xd4401e, -0xd4801e, -0x800000, -0xee001e, -0xca0800, -0xca0c00, -0x34d018, -0x251001, -0x950021, -0xc17fff, -0xca1000, -0xca1400, -0xca1800, -0xd4801d, -0xd4c01d, -0x7db18b, -0xc14202, -0xc2c001, -0xd5801d, -0x34dc0e, -0x7d5d4c, -0x7f734c, -0xd7401e, -0xd5001e, -0xd5401e, -0xc14200, -0xc2c000, -0x099c01, -0x31dc10, -0x7f5f4c, -0x7f734c, -0x042802, -0x7d8380, -0xd5a86f, -0xd58066, -0xd7401e, -0xec005e, -0xc82402, -0xc82402, -0x8001db, -0xd60076, -0xd4401e, -0xd4801e, -0xd4c01e, -0x800000, -0xee001e, -0x800000, -0xee001f, -0xd4001f, -0x800000, -0xd4001f, -0xd4001f, -0x880000, -0xd4001f, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x000000, -0x010194, -0x02019b, -0x0300b2, -0x0400a2, -0x050003, -0x06003f, -0x070032, -0x08014f, -0x090046, -0x0a0036, -0x1001d9, -0x1700c5, -0x22015d, -0x23016c, -0x2000d7, -0x240148, -0x26004d, -0x27005c, -0x28008d, -0x290051, -0x2a007e, -0x2b0061, -0x2f0088, -0x3200aa, -0x3401a2, -0x36006f, -0x3c0179, -0x3f0095, -0x4101af, -0x440151, -0x550196, -0x56019d, -0x60000b, -0x610034, -0x620038, -0x630038, -0x640038, -0x650038, -0x660038, -0x670038, -0x68003a, -0x690041, -0x6a0048, -0x6b0048, -0x6c0048, -0x6d0048, -0x6e0048, -0x6f0048, -0x7301d9, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -0x000006, -}; - -static const u32 RV770_cp_microcode[] = { -0xcc0003ea, -0x7c408000, -0xa0000000, -0xcc800062, -0x80000001, -0xd040007f, -0x80000001, -0xcc400041, -0x7c40c000, -0xc0160004, -0x30d03fff, -0x7d15000c, -0xcc110000, -0x28d8001e, -0x31980001, -0x28dc001f, -0xc8200004, -0x95c00006, -0x7c424000, -0xcc000062, -0x7e56800c, -0xcc290000, -0xc8240004, -0x7e26000b, -0x95800006, -0x7c42c000, -0xcc000062, -0x7ed7000c, -0xcc310000, -0xc82c0004, -0x7e2e000c, -0xcc000062, -0x31103fff, -0x80000001, -0xce110000, -0x7c40c000, -0x80000001, -0xcc400040, -0x80000001, -0xcc412257, -0x7c418000, -0xcc400045, -0xcc400048, -0xcc41225c, -0xcc41a1fc, -0x7c408000, -0xa0000000, -0xcc800062, -0xcc400045, -0xcc400048, -0x7c40c000, -0xcc41225c, -0xcc41a1fc, -0x7c408000, -0xa0000000, -0xcc800062, -0xcc000045, -0xcc000048, -0xcc41225c, -0xcc41a1fc, -0x7c408000, -0xa0000000, -0xcc800062, -0x040ca1fd, -0xc0120001, -0xcc000045, -0xcc000048, -0x7cd0c00c, -0xcc41225c, -0xcc41a1fc, -0xd04d0000, -0x7c408000, -0xa0000000, -0xcc800062, -0x80000001, -0xcc41225d, -0x7c408000, -0x7c40c000, -0xc02a0002, -0x7c410000, -0x7d29000c, -0x30940001, -0x30980006, -0x309c0300, -0x29dc0008, -0x7c420000, -0x7c424000, -0x9540000f, -0xc02e0004, -0x05f02258, -0x7f2f000c, -0xcc310000, -0xc8280004, -0xccc12169, -0xcd01216a, -0xce81216b, -0x0db40002, -0xcc01216c, -0x9740000e, -0x0db40000, -0x8000007b, -0xc834000a, -0x0db40002, -0x97400009, -0x0db40000, -0xc02e0004, -0x05f02258, -0x7f2f000c, -0xcc310000, -0xc8280004, -0x8000007b, -0xc834000a, -0x97400004, -0x7e028000, -0x8000007b, -0xc834000a, -0x0db40004, -0x9740ff8c, -0x00000000, -0xce01216d, -0xce41216e, -0xc8280003, -0xc834000a, -0x9b400004, -0x043c0005, -0x8400026d, -0xcc000062, -0x0df40000, -0x9740000b, -0xc82c03e6, -0xce81a2b7, -0xc0300006, -0x7ef34028, -0xc0300020, -0x7f6b8020, -0x7fb3c029, -0xcf81a2c4, -0x80000001, -0xcfc1a2d1, -0x0df40001, -0x9740000b, -0xc82c03e7, -0xce81a2bb, -0xc0300006, -0x7ef34028, -0xc0300020, -0x7f6b8020, -0x7fb3c029, -0xcf81a2c5, -0x80000001, -0xcfc1a2d2, -0x0df40002, -0x9740000b, -0xc82c03e8, -0xce81a2bf, -0xc0300006, -0x7ef34028, -0xc0300020, -0x7f6b8020, -0x7fb3c029, -0xcf81a2c6, -0x80000001, -0xcfc1a2d3, -0xc82c03e9, -0xce81a2c3, -0xc0300006, -0x7ef34028, -0xc0300020, -0x7f6b8020, -0x7fb3c029, -0xcf81a2c7, -0x80000001, -0xcfc1a2d4, -0x80000001, -0xcc400042, -0x7c40c000, -0x7c410000, -0x2914001d, -0x31540001, -0x9940000d, -0x31181000, -0xc81c0011, -0x09dc0001, -0x95c0ffff, -0xc81c0011, -0xccc12100, -0xcd012101, -0xccc12102, -0xcd012103, -0x04180004, -0x8000039f, -0xcd81a2a4, -0xc02a0004, -0x95800008, -0x36a821a3, -0xcc290000, -0xc8280004, -0xc81c0011, -0x0de40040, -0x9640ffff, -0xc81c0011, -0xccc12170, -0xcd012171, -0xc8200012, -0x96000000, -0xc8200012, -0x8000039f, -0xcc000064, -0x7c40c000, -0x7c410000, -0xcc000045, -0xcc000048, -0x40d40003, -0xcd41225c, -0xcd01a1fc, -0xc01a0001, -0x041ca1fd, -0x7dd9c00c, -0x7c420000, -0x08cc0001, -0x06240001, -0x06280002, -0xce1d0000, -0xce5d0000, -0x98c0fffa, -0xce9d0000, -0x7c408000, -0xa0000000, -0xcc800062, -0x7c40c000, -0x30d00001, -0x28cc0001, -0x7c414000, -0x95000006, -0x7c418000, -0xcd41216d, -0xcd81216e, -0x800000f3, -0xc81c0003, -0xc0220004, -0x7e16000c, -0xcc210000, -0xc81c0004, -0x7c424000, -0x98c00004, -0x7c428000, -0x80000001, -0xcde50000, -0xce412169, -0xce81216a, -0xcdc1216b, -0x80000001, -0xcc01216c, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0x7c41c000, -0x28a40008, -0x326400ff, -0x0e68003c, -0x9680000a, -0x7c020000, -0x7c420000, -0x1e300003, -0xcc00006a, -0x9b000003, -0x42200005, -0x04200040, -0x80000110, -0x7c024000, -0x7e024000, -0x9a400000, -0x0a640001, -0x30ec0010, -0x9ac0000a, -0xcc000062, -0xc02a0004, -0xc82c0021, -0x7e92800c, -0xcc000041, -0xcc290000, -0xcec00021, -0x80000120, -0xc8300004, -0xcd01216d, -0xcd41216e, -0xc8300003, -0x7f1f000b, -0x30f40007, -0x27780001, -0x9740002a, -0x07b80125, -0x9f800000, -0x00000000, -0x80000135, -0x7f1b8004, -0x80000139, -0x7f1b8005, -0x8000013d, -0x7f1b8002, -0x80000141, -0x7f1b8003, -0x80000145, -0x7f1b8007, -0x80000149, -0x7f1b8006, -0x8000014e, -0x28a40008, -0x9b800019, -0x28a40008, -0x8000015e, -0x326400ff, -0x9b800015, -0x28a40008, -0x8000015e, -0x326400ff, -0x9b800011, -0x28a40008, -0x8000015e, -0x326400ff, -0x9b80000d, -0x28a40008, -0x8000015e, -0x326400ff, -0x9b800009, -0x28a40008, -0x8000015e, -0x326400ff, -0x9b800005, -0x28a40008, -0x8000015e, -0x326400ff, -0x28a40008, -0x326400ff, -0x0e68003c, -0x9a80feb1, -0x28ec0008, -0x7c434000, -0x7c438000, -0x7c43c000, -0x96c00007, -0xcc000062, -0xcf412169, -0xcf81216a, -0xcfc1216b, -0x80000001, -0xcc01216c, -0x80000001, -0xcff50000, -0xcc00006b, -0x840003a2, -0x0e68003c, -0x9a800004, -0xc8280015, -0x80000001, -0xd040007f, -0x9680ffab, -0x7e024000, -0x8400023b, -0xc00e0002, -0xcc000041, -0x80000239, -0xccc1304a, -0x7c40c000, -0x7c410000, -0xc01e0001, -0x29240012, -0xc0220002, -0x96400005, -0xc0260004, -0xc027fffb, -0x7d25000b, -0xc0260000, -0x7dd2800b, -0x7e12c00b, -0x7d25000c, -0x7c414000, -0x7c418000, -0xccc12169, -0x9a80000a, -0xcd01216a, -0xcd41216b, -0x96c0fe82, -0xcd81216c, -0xc8300018, -0x97000000, -0xc8300018, -0x80000001, -0xcc000018, -0x840003a2, -0xcc00007f, -0xc8140013, -0xc8180014, -0xcd41216b, -0x96c0fe76, -0xcd81216c, -0x80000182, -0xc8300018, -0xc80c0008, -0x98c00000, -0xc80c0008, -0x7c410000, -0x95000002, -0x00000000, -0x7c414000, -0xc8200009, -0xcc400043, -0xce01a1f4, -0xcc400044, -0xc00e8000, -0x7c424000, -0x7c428000, -0x2aac001f, -0x96c0fe63, -0xc035f000, -0xce4003e2, -0x32780003, -0x267c0008, -0x7ff7c00b, -0x7ffbc00c, -0x2a780018, -0xcfc003e3, -0xcf8003e4, -0x26b00002, -0x7f3f0000, -0xcf0003e5, -0x8000031f, -0x7c80c000, -0x7c40c000, -0x28d00008, -0x3110000f, -0x9500000f, -0x25280001, -0x06a801b3, -0x9e800000, -0x00000000, -0x800001d4, -0xc0120800, -0x800001e2, -0xc814000f, -0x800001e9, -0xc8140010, -0x800001f0, -0xccc1a2a4, -0x800001f9, -0xc8140011, -0x30d0003f, -0x0d280015, -0x9a800012, -0x0d28001e, -0x9a80001e, -0x0d280020, -0x9a800023, -0x0d24000f, -0x0d280010, -0x7e6a800c, -0x9a800026, -0x0d200004, -0x0d240014, -0x0d280028, -0x7e62400c, -0x7ea6800c, -0x9a80002a, -0xc8140011, -0x80000001, -0xccc1a2a4, -0xc0120800, -0x7c414000, -0x7d0cc00c, -0xc0120008, -0x29580003, -0x295c000c, -0x7c420000, -0x7dd1c00b, -0x26200014, -0x7e1e400c, -0x7e4e800c, -0xce81a2a4, -0x80000001, -0xcd81a1fe, -0xc814000f, -0x0410210e, -0x95400000, -0xc814000f, -0xd0510000, -0x80000001, -0xccc1a2a4, -0xc8140010, -0x04102108, -0x95400000, -0xc8140010, -0xd0510000, -0x80000001, -0xccc1a2a4, -0xccc1a2a4, -0x04100001, -0xcd000019, -0x840003a2, -0xcc00007f, -0xc8100019, -0x99000000, -0xc8100019, -0x80000002, -0x7c408000, -0x04102100, -0x09540001, -0x9540ffff, -0xc8140011, -0xd0510000, -0x8000039f, -0xccc1a2a4, -0x7c40c000, -0xcc40000d, -0x94c0fdff, -0xcc40000e, -0x7c410000, -0x95000005, -0x08cc0001, -0xc8140005, -0x99400014, -0x00000000, -0x98c0fffb, -0x7c410000, -0x80000002, -0x7d008000, -0xc8140005, -0x7c40c000, -0x9940000c, -0xc818000c, -0x7c410000, -0x9580fdee, -0xc820000e, -0xc81c000d, -0x66200020, -0x7e1e002c, -0x25240002, -0x7e624020, -0x80000001, -0xcce60000, -0x7c410000, -0xcc00006c, -0xcc00006d, -0xc818001f, -0xc81c001e, -0x65980020, -0x7dd9c02c, -0x7cd4c00c, -0xccde0000, -0x45dc0004, -0xc8280017, -0x9680000f, -0xc00e0001, -0x28680008, -0x2aac0016, -0x32a800ff, -0x0eb00049, -0x7f2f000b, -0x97000006, -0x00000000, -0xc8140005, -0x7c40c000, -0x80000223, -0x7c410000, -0x80000226, -0xd040007f, -0x8400023b, -0xcc000041, -0xccc1304a, -0x94000000, -0xc83c001a, -0x043c0005, -0xcfc1a2a4, -0xc0361f90, -0xc0387fff, -0x7c03c010, -0x7f7b400c, -0xcf41217c, -0xcfc1217d, -0xcc01217e, -0xc03a0004, -0x0434217f, -0x7f7b400c, -0xcc350000, -0xc83c0004, -0x2bfc001f, -0x04380020, -0x97c00005, -0xcc000062, -0x9b800000, -0x0bb80001, -0x80000247, -0xcc000071, -0xcc01a1f4, -0x04380016, -0xc0360002, -0xcf81a2a4, -0x88000000, -0xcf412010, -0x7c40c000, -0x28d0001c, -0x95000005, -0x04d40001, -0xcd400065, -0x80000001, -0xcd400068, -0x09540002, -0x80000001, -0xcd400066, -0x8400026c, -0xc81803ea, -0x7c40c000, -0x9980fd9d, -0xc8140016, -0x08d00001, -0x9940002b, -0xcd000068, -0x7c408000, -0xa0000000, -0xcc800062, -0x043c0005, -0xcfc1a2a4, -0xcc01a1f4, -0x840003a2, -0xcc000046, -0x88000000, -0xcc00007f, -0x8400027e, -0xc81803ea, -0x7c40c000, -0x9980fd8b, -0xc8140016, -0x08d00001, -0x99400019, -0xcd000068, -0x7c408000, -0xa0000000, -0xcc800062, -0x043c0022, -0xcfc1a2a4, -0x840003a2, -0xcc000047, -0x88000000, -0xcc00007f, -0xc8100016, -0x9900000d, -0xcc400067, -0x80000002, -0x7c408000, -0xc81803ea, -0x9980fd77, -0x7c40c000, -0x94c00003, -0xc8100016, -0x99000004, -0xccc00068, -0x80000002, -0x7c408000, -0x8400023b, -0xc0148000, -0xcc000041, -0xcd41304a, -0xc0148000, -0x99000000, -0xc8100016, -0x80000002, -0x7c408000, -0xc0120001, -0x7c51400c, -0x80000001, -0xd0550000, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0x291c001f, -0xccc0004a, -0xcd00004b, -0x95c00003, -0xc01c8000, -0xcdc12010, -0xdd830000, -0x055c2000, -0xcc000062, -0x80000001, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc0004c, -0xcd00004d, -0xdd830000, -0x055ca000, -0x80000001, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc0004e, -0xcd00004f, -0xdd830000, -0x055cc000, -0x80000001, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00050, -0xcd000051, -0xdd830000, -0x055cf8e0, -0x80000001, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00052, -0xcd000053, -0xdd830000, -0x055cf880, -0x80000001, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00054, -0xcd000055, -0xdd830000, -0x055ce000, -0x80000001, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00056, -0xcd000057, -0xdd830000, -0x055cf000, -0x80000001, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00058, -0xcd000059, -0xdd830000, -0x055cf3fc, -0x80000001, -0xd81f4100, -0xd0432000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043a000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043c000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043f8e0, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043f880, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043e000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043f000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043f3fc, -0x7c408000, -0xa0000000, -0xcc800062, -0xc81403e0, -0xcc430000, -0xcc430000, -0xcc430000, -0x7d45c000, -0xcdc30000, -0xd0430000, -0x7c408000, -0xa0000000, -0xcc800062, -0x7c40c000, -0xc81003e2, -0xc81403e5, -0xc81803e3, -0xc81c03e4, -0xcd812169, -0xcdc1216a, -0xccc1216b, -0xcc01216c, -0x04200004, -0x7da18000, -0x7d964002, -0x9640fcd7, -0xcd8003e3, -0x31280003, -0xc02df000, -0x25180008, -0x7dad800b, -0x7da9800c, -0x80000001, -0xcd8003e3, -0x308cffff, -0xd04d0000, -0x7c408000, -0xa0000000, -0xcc800062, -0x7c40c000, -0x7c410000, -0x29240018, -0x32640001, -0x9a400013, -0xc8140020, -0x15580002, -0x9580ffff, -0xc8140020, -0xcc00006e, -0xccc12180, -0xcd01218d, -0xcc412181, -0x2914001f, -0x34588000, -0xcd81218c, -0x9540fcb9, -0xcc412182, -0xc8140020, -0x9940ffff, -0xc8140020, -0x80000002, -0x7c408000, -0x7c414000, -0x7c418000, -0x7c41c000, -0x65b40020, -0x7f57402c, -0xd4378100, -0x47740004, -0xd4378100, -0x47740004, -0xd4378100, -0x47740004, -0x09dc0004, -0xd4378100, -0x99c0fff8, -0x47740004, -0x2924001f, -0xc0380019, -0x9640fca1, -0xc03e0004, -0xcf8121f8, -0x37e021f9, -0xcc210000, -0xc8200004, -0x2a200018, -0x32200001, -0x9a00fffb, -0xcf8121f8, -0x80000002, -0x7c408000, -0x7c40c000, -0x28d00018, -0x31100001, -0xc0160080, -0x95000003, -0xc02a0004, -0x7cd4c00c, -0xccc1217c, -0xcc41217d, -0xcc41217e, -0x7c418000, -0x1db00003, -0x36a0217f, -0x9b000003, -0x419c0005, -0x041c0040, -0x99c00000, -0x09dc0001, -0xcc210000, -0xc8240004, -0x2a6c001f, -0x419c0005, -0x9ac0fffa, -0xcc800062, -0x80000002, -0x7c408000, -0x7c40c000, -0x04d403e6, -0x80000001, -0xcc540000, -0x8000039f, -0xcc4003ea, -0xc01c8000, -0x044ca000, -0xcdc12010, -0x7c410000, -0xc8140009, -0x04180000, -0x041c0008, -0xcd800071, -0x09dc0001, -0x05980001, -0xcd0d0000, -0x99c0fffc, -0xcc800062, -0x8000039f, -0xcd400071, -0xc00e0100, -0xcc000041, -0xccc1304a, -0xc83c007f, -0xcc00007f, -0x80000001, -0xcc00007f, -0xcc00007f, -0x88000000, -0xcc00007f, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00010333, -0x00100004, -0x00170006, -0x00210008, -0x00270028, -0x00280023, -0x00290029, -0x002a0026, -0x002b0029, -0x002d0038, -0x002e003f, -0x002f004a, -0x0034004c, -0x00360030, -0x003900af, -0x003a00d0, -0x003b00e5, -0x003c00fd, -0x003d016c, -0x003f00ad, -0x00410338, -0x0043036c, -0x0044018f, -0x004500fd, -0x004601ad, -0x004701ad, -0x00480200, -0x0049020e, -0x004a0257, -0x004b0284, -0x00520261, -0x00530273, -0x00540289, -0x0057029b, -0x0060029f, -0x006102ae, -0x006202b8, -0x006302c2, -0x006402cc, -0x006502d6, -0x006602e0, -0x006702ea, -0x006802f4, -0x006902f8, -0x006a02fc, -0x006b0300, -0x006c0304, -0x006d0308, -0x006e030c, -0x006f0310, -0x00700314, -0x00720386, -0x0074038c, -0x0079038a, -0x007c031e, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -0x000f039b, -}; - -static const u32 RV770_pfp_microcode[] = { -0x7c408000, -0xa0000000, -0x7e82800b, -0x80000000, -0xdc030000, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xc818000e, -0x31980001, -0x7c424000, -0x95800252, -0x7c428000, -0xc81c001c, -0xc037c000, -0x7c40c000, -0x7c410000, -0x7cb4800b, -0xc0360003, -0x99c00000, -0xc81c001c, -0x7cb4800c, -0x24d40002, -0x7d654000, -0xcd400043, -0xce800043, -0xcd000043, -0xcc800040, -0xce400040, -0xce800040, -0xccc00040, -0xdc3a0000, -0x9780ffde, -0xcd000040, -0x7c40c000, -0x80000018, -0x7c410000, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xc818000e, -0x8000000c, -0x31980002, -0xd40003c0, -0xd4000fc0, -0xd4000fa2, -0xc818000e, -0x288c0008, -0x30cc000f, -0x34100001, -0x7d0d0008, -0x8000000c, -0x7d91800b, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xd40003c0, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xcc4003f9, -0x80000261, -0xcc4003f8, -0xc82003f8, -0xc81c03f9, -0xc81803fb, -0xc037ffff, -0x7c414000, -0xcf41a29e, -0x66200020, -0x7de1c02c, -0x7d58c008, -0x7cdcc020, -0x68d00020, -0xc0360003, -0xcc000054, -0x7cb4800c, -0x8000006a, -0xcc800040, -0x7c418000, -0xcd81a29e, -0xcc800040, -0xcd800040, -0x80000068, -0xcc000054, -0xc019ffff, -0xcc800040, -0xcd81a29e, -0x7c40c000, -0x7c410000, -0x7c414000, -0xccc1a1fa, -0xcd01a1f9, -0xcd41a29d, -0xccc00040, -0xcd000040, -0xcd400040, -0xcc400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xcc000054, -0xcc800040, -0x7c40c000, -0x7c410000, -0x7c414000, -0xccc1a1fa, -0xcd01a1f9, -0xcd41a29d, -0xccc00040, -0xcd000040, -0xcd400040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0x7c40c000, -0x30d00001, -0xccc1a29f, -0x95000003, -0x04140001, -0x04140002, -0xcd4003fb, -0xcc800040, -0x80000000, -0xccc00040, -0x7c40c000, -0xcc800040, -0xccc1a2a2, -0x80000000, -0xccc00040, -0x7c40c000, -0x28d4001f, -0xcc800040, -0x95400003, -0x7c410000, -0xccc00057, -0x2918001f, -0xccc00040, -0x95800003, -0xcd000040, -0xcd000058, -0x80000261, -0xcc00007f, -0xc8200017, -0xc8300022, -0x9a000006, -0x0e280001, -0xc824001e, -0x0a640001, -0xd4001240, -0xce400040, -0xc036c000, -0x96800007, -0x37747900, -0x041c0001, -0xcf400040, -0xcdc00040, -0xcf0003fa, -0x7c030000, -0xca0c0010, -0x7c410000, -0x94c00004, -0x7c414000, -0xd42002c4, -0xcde00044, -0x9b00000b, -0x7c418000, -0xcc00004b, -0xcda00049, -0xcd200041, -0xcd600041, -0xcda00041, -0x06200001, -0xce000056, -0x80000261, -0xcc00007f, -0xc8280020, -0xc82c0021, -0xcc000063, -0x7eea4001, -0x65740020, -0x7f53402c, -0x269c0002, -0x7df5c020, -0x69f80020, -0xce80004b, -0xce600049, -0xcde00041, -0xcfa00041, -0xce600041, -0x271c0002, -0x7df5c020, -0x69f80020, -0x7db24001, -0xcf00004b, -0xce600049, -0xcde00041, -0xcfa00041, -0x800000bd, -0xce600041, -0xc8200017, -0xc8300022, -0x9a000006, -0x0e280001, -0xc824001e, -0x0a640001, -0xd4001240, -0xce400040, -0xca0c0010, -0x7c410000, -0x94c0000b, -0xc036c000, -0x96800007, -0x37747900, -0x041c0001, -0xcf400040, -0xcdc00040, -0xcf0003fa, -0x7c030000, -0x800000b6, -0x7c414000, -0xcc000048, -0x800000ef, -0x00000000, -0xc8200017, -0xc81c0023, -0x0e240002, -0x99c00015, -0x7c418000, -0x0a200001, -0xce000056, -0xd4000440, -0xcc000040, -0xc036c000, -0xca140013, -0x96400007, -0x37747900, -0xcf400040, -0xcc000040, -0xc83003fa, -0x80000104, -0xcf000022, -0xcc000022, -0x9540015d, -0xcc00007f, -0xcca00046, -0x80000000, -0xcc200046, -0x80000261, -0xcc000064, -0xc8200017, -0xc810001f, -0x96000005, -0x09100001, -0xd4000440, -0xcd000040, -0xcd000022, -0xcc800040, -0xd0400040, -0xc80c0025, -0x94c0feeb, -0xc8100008, -0xcd000040, -0xd4000fc0, -0x80000000, -0xd4000fa2, -0x7c40c000, -0x7c410000, -0xccc003fd, -0xcd0003fc, -0xccc00042, -0xcd000042, -0x2914001f, -0x29180010, -0x31980007, -0x3b5c0001, -0x7d76000b, -0x99800005, -0x7d5e400b, -0xcc000042, -0x80000261, -0xcc00004d, -0x29980001, -0x292c0008, -0x9980003d, -0x32ec0001, -0x96000004, -0x2930000c, -0x80000261, -0xcc000042, -0x04140010, -0xcd400042, -0x33300001, -0x34280001, -0x8400015e, -0xc8140003, -0x9b40001b, -0x0438000c, -0x8400015e, -0xc8140003, -0x9b400017, -0x04380008, -0x8400015e, -0xc8140003, -0x9b400013, -0x04380004, -0x8400015e, -0xc8140003, -0x9b400015, -0xc80c03fd, -0x9a800009, -0xc81003fc, -0x9b000118, -0xcc00004d, -0x04140010, -0xccc00042, -0xcd000042, -0x80000136, -0xcd400042, -0x96c00111, -0xcc00004d, -0x80000261, -0xcc00004e, -0x9ac00003, -0xcc00004d, -0xcc00004e, -0xdf830000, -0x80000000, -0xd80301ff, -0x9ac00107, -0xcc00004d, -0x80000261, -0xcc00004e, -0xc8180003, -0xc81c0003, -0xc8200003, -0x7d5d4003, -0x7da1c003, -0x7d5d400c, -0x2a10001f, -0x299c001f, -0x7d1d000b, -0x7d17400b, -0x88000000, -0x7e92800b, -0x96400004, -0xcc00004e, -0x80000261, -0xcc000042, -0x04380008, -0xcf800042, -0xc8080003, -0xc80c0003, -0xc8100003, -0xc8140003, -0xc8180003, -0xc81c0003, -0xc8240003, -0xc8280003, -0x29fc001f, -0x2ab0001f, -0x7ff3c00b, -0x28f0001f, -0x7ff3c00b, -0x2970001f, -0x7ff3c00b, -0x7d888001, -0x7dccc001, -0x7e510001, -0x7e954001, -0x7c908002, -0x7cd4c002, -0x7cbc800b, -0x9ac00003, -0x7c8f400b, -0x38b40001, -0x9b4000d8, -0xcc00004d, -0x9bc000d6, -0xcc00004e, -0xc80c03fd, -0xc81003fc, -0xccc00042, -0x8000016f, -0xcd000042, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xcc400040, -0xcc400040, -0xcc400040, -0x7c40c000, -0xccc00040, -0xccc0000d, -0x80000000, -0xd0400040, -0x7c40c000, -0x7c410000, -0x65140020, -0x7d4d402c, -0x24580002, -0x7d598020, -0x7c41c000, -0xcd800042, -0x69980020, -0xcd800042, -0xcdc00042, -0xc023c000, -0x05e40002, -0x7ca0800b, -0x26640010, -0x7ca4800c, -0xcc800040, -0xcdc00040, -0xccc00040, -0x95c0000e, -0xcd000040, -0x09dc0001, -0xc8280003, -0x96800008, -0xce800040, -0xc834001d, -0x97400000, -0xc834001d, -0x26a80008, -0x84000264, -0xcc2b0000, -0x99c0fff7, -0x09dc0001, -0xdc3a0000, -0x97800004, -0x7c418000, -0x800001a3, -0x25980002, -0xa0000000, -0x7d808000, -0xc818001d, -0x7c40c000, -0x64d00008, -0x95800000, -0xc818001d, -0xcc130000, -0xcc800040, -0xccc00040, -0x80000000, -0xcc400040, -0xc810001f, -0x7c40c000, -0xcc800040, -0x7cd1400c, -0xcd400040, -0x05180001, -0x80000000, -0xcd800022, -0x7c40c000, -0x64500020, -0x84000264, -0xcc000061, -0x7cd0c02c, -0xc8200017, -0xc8d60000, -0x99400008, -0x7c438000, -0xdf830000, -0xcfa0004f, -0x84000264, -0xcc000062, -0x80000000, -0xd040007f, -0x80000261, -0xcc000062, -0x84000264, -0xcc000061, -0xc8200017, -0x7c40c000, -0xc036ff00, -0xc810000d, -0xc0303fff, -0x7cf5400b, -0x7d51800b, -0x7d81800f, -0x99800008, -0x7cf3800b, -0xdf830000, -0xcfa0004f, -0x84000264, -0xcc000062, -0x80000000, -0xd040007f, -0x80000261, -0xcc000062, -0x84000264, -0x7c40c000, -0x28dc0008, -0x95c00019, -0x30dc0010, -0x7c410000, -0x99c00004, -0x64540020, -0x80000209, -0xc91d0000, -0x7d15002c, -0xc91e0000, -0x7c420000, -0x7c424000, -0x7c418000, -0x7de5c00b, -0x7de28007, -0x9a80000e, -0x41ac0005, -0x9ac00000, -0x0aec0001, -0x30dc0010, -0x99c00004, -0x00000000, -0x8000020c, -0xc91d0000, -0x8000020c, -0xc91e0000, -0xcc800040, -0xccc00040, -0xd0400040, -0xc80c0025, -0x94c0fde3, -0xc8100008, -0xcd000040, -0xd4000fc0, -0x80000000, -0xd4000fa2, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xd40003c0, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0x7c40c000, -0x30d00006, -0x0d100006, -0x99000007, -0xc8140015, -0x99400005, -0xcc000052, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xccc00040, -0x80000000, -0xd0400040, -0x7c40c000, -0xcc4d0000, -0xdc3a0000, -0x9780fdbc, -0x04cc0001, -0x80000243, -0xcc4d0000, -0x7c40c000, -0x7c410000, -0x29240018, -0x32640001, -0x9640000f, -0xcc800040, -0x7c414000, -0x7c418000, -0x7c41c000, -0xccc00043, -0xcd000043, -0x31dc7fff, -0xcdc00043, -0xccc00040, -0xcd000040, -0xcd400040, -0xcd800040, -0x80000000, -0xcdc00040, -0xccc00040, -0xcd000040, -0x80000000, -0xd0400040, -0x80000000, -0xd040007f, -0xcc00007f, -0x80000000, -0xcc00007f, -0xcc00007f, -0x88000000, -0xcc00007f, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00030223, -0x0004022b, -0x000500a0, -0x00020003, -0x0006003c, -0x00070027, -0x00080192, -0x00090044, -0x000a002d, -0x0010025f, -0x001700f1, -0x002201d8, -0x002301e9, -0x0026004c, -0x0027005f, -0x0020011b, -0x00280093, -0x0029004f, -0x002a0084, -0x002b0065, -0x002f008e, -0x003200d9, -0x00340233, -0x00360075, -0x0039010b, -0x003c01fd, -0x003f00a0, -0x00410248, -0x00440195, -0x0048019e, -0x004901c6, -0x004a01d0, -0x00550226, -0x0056022e, -0x0060000a, -0x0061002a, -0x00620030, -0x00630030, -0x00640030, -0x00650030, -0x00660030, -0x00670030, -0x00680037, -0x0069003f, -0x006a0047, -0x006b0047, -0x006c0047, -0x006d0047, -0x006e0047, -0x006f0047, -0x00700047, -0x0073025f, -0x007b0241, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -}; - -static const u32 RV730_pfp_microcode[] = { -0x7c408000, -0xa0000000, -0x7e82800b, -0x80000000, -0xdc030000, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xc818000e, -0x31980001, -0x7c424000, -0x9580023a, -0x7c428000, -0xc81c001c, -0xc037c000, -0x7c40c000, -0x7c410000, -0x7cb4800b, -0xc0360003, -0x99c00000, -0xc81c001c, -0x7cb4800c, -0x24d40002, -0x7d654000, -0xcd400043, -0xce800043, -0xcd000043, -0xcc800040, -0xce400040, -0xce800040, -0xccc00040, -0xdc3a0000, -0x9780ffde, -0xcd000040, -0x7c40c000, -0x80000018, -0x7c410000, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xc818000e, -0x8000000c, -0x31980002, -0xd40003c0, -0xd4000fc0, -0xd4000fa2, -0xc818000e, -0x288c0008, -0x30cc000f, -0x34100001, -0x7d0d0008, -0x8000000c, -0x7d91800b, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xd40003c0, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xcc4003f9, -0x80000249, -0xcc4003f8, -0xc037ffff, -0x7c414000, -0xcf41a29e, -0xc82003f8, -0xc81c03f9, -0x66200020, -0xc81803fb, -0x7de1c02c, -0x7d58c008, -0x7cdcc020, -0x69100020, -0xc0360003, -0xcc000054, -0x7cb4800c, -0x80000069, -0xcc800040, -0x7c418000, -0xcd81a29e, -0xcc800040, -0x80000067, -0xcd800040, -0xc019ffff, -0xcc800040, -0xcd81a29e, -0x7c40c000, -0x7c410000, -0x7c414000, -0xccc1a1fa, -0xcd01a1f9, -0xcd41a29d, -0xccc00040, -0xcd000040, -0xcd400040, -0xcc400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xcc000054, -0xcc800040, -0x7c40c000, -0x7c410000, -0x7c414000, -0xccc1a1fa, -0xcd01a1f9, -0xcd41a29d, -0xccc00040, -0xcd000040, -0xcd400040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0x7c40c000, -0x30d00001, -0xccc1a29f, -0x95000003, -0x04140001, -0x04140002, -0xcd4003fb, -0xcc800040, -0x80000000, -0xccc00040, -0x7c40c000, -0xcc800040, -0xccc1a2a2, -0x80000000, -0xccc00040, -0x7c40c000, -0x28d4001f, -0xcc800040, -0x95400003, -0x7c410000, -0xccc00057, -0x2918001f, -0xccc00040, -0x95800003, -0xcd000040, -0xcd000058, -0x80000249, -0xcc00007f, -0xc8200017, -0xc8300022, -0x9a000006, -0x0e280001, -0xc824001e, -0x0a640001, -0xd4001240, -0xce400040, -0xc036c000, -0x96800007, -0x37747900, -0x041c0001, -0xcf400040, -0xcdc00040, -0xcf0003fa, -0x7c030000, -0xca0c0010, -0x7c410000, -0x94c00004, -0x7c414000, -0xd42002c4, -0xcde00044, -0x9b00000b, -0x7c418000, -0xcc00004b, -0xcda00049, -0xcd200041, -0xcd600041, -0xcda00041, -0x06200001, -0xce000056, -0x80000249, -0xcc00007f, -0xc8280020, -0xc82c0021, -0xcc000063, -0x7eea4001, -0x65740020, -0x7f53402c, -0x269c0002, -0x7df5c020, -0x69f80020, -0xce80004b, -0xce600049, -0xcde00041, -0xcfa00041, -0xce600041, -0x271c0002, -0x7df5c020, -0x69f80020, -0x7db24001, -0xcf00004b, -0xce600049, -0xcde00041, -0xcfa00041, -0x800000bc, -0xce600041, -0xc8200017, -0xc8300022, -0x9a000006, -0x0e280001, -0xc824001e, -0x0a640001, -0xd4001240, -0xce400040, -0xca0c0010, -0x7c410000, -0x94c0000b, -0xc036c000, -0x96800007, -0x37747900, -0x041c0001, -0xcf400040, -0xcdc00040, -0xcf0003fa, -0x7c030000, -0x800000b5, -0x7c414000, -0xcc000048, -0x800000ee, -0x00000000, -0xc8200017, -0xc81c0023, -0x0e240002, -0x99c00015, -0x7c418000, -0x0a200001, -0xce000056, -0xd4000440, -0xcc000040, -0xc036c000, -0xca140013, -0x96400007, -0x37747900, -0xcf400040, -0xcc000040, -0xc83003fa, -0x80000103, -0xcf000022, -0xcc000022, -0x95400146, -0xcc00007f, -0xcca00046, -0x80000000, -0xcc200046, -0x80000249, -0xcc000064, -0xc8200017, -0xc810001f, -0x96000005, -0x09100001, -0xd4000440, -0xcd000040, -0xcd000022, -0xcc800040, -0xd0400040, -0xc80c0025, -0x94c0feec, -0xc8100008, -0xcd000040, -0xd4000fc0, -0x80000000, -0xd4000fa2, -0x7c40c000, -0x7c410000, -0xccc003fd, -0xcd0003fc, -0xccc00042, -0xcd000042, -0x2914001f, -0x29180010, -0x31980007, -0x3b5c0001, -0x7d76000b, -0x99800005, -0x7d5e400b, -0xcc000042, -0x80000249, -0xcc00004d, -0x29980001, -0x292c0008, -0x9980003d, -0x32ec0001, -0x96000004, -0x2930000c, -0x80000249, -0xcc000042, -0x04140010, -0xcd400042, -0x33300001, -0x34280001, -0x8400015d, -0xc8140003, -0x9b40001b, -0x0438000c, -0x8400015d, -0xc8140003, -0x9b400017, -0x04380008, -0x8400015d, -0xc8140003, -0x9b400013, -0x04380004, -0x8400015d, -0xc8140003, -0x9b400015, -0xc80c03fd, -0x9a800009, -0xc81003fc, -0x9b000101, -0xcc00004d, -0x04140010, -0xccc00042, -0xcd000042, -0x80000135, -0xcd400042, -0x96c000fa, -0xcc00004d, -0x80000249, -0xcc00004e, -0x9ac00003, -0xcc00004d, -0xcc00004e, -0xdf830000, -0x80000000, -0xd80301ff, -0x9ac000f0, -0xcc00004d, -0x80000249, -0xcc00004e, -0xc8180003, -0xc81c0003, -0xc8200003, -0x7d5d4003, -0x7da1c003, -0x7d5d400c, -0x2a10001f, -0x299c001f, -0x7d1d000b, -0x7d17400b, -0x88000000, -0x7e92800b, -0x96400004, -0xcc00004e, -0x80000249, -0xcc000042, -0x04380008, -0xcf800042, -0xc8080003, -0xc80c0003, -0xc8100003, -0xc8140003, -0xc8180003, -0xc81c0003, -0xc8240003, -0xc8280003, -0x29fc001f, -0x2ab0001f, -0x7ff3c00b, -0x28f0001f, -0x7ff3c00b, -0x2970001f, -0x7ff3c00b, -0x7d888001, -0x7dccc001, -0x7e510001, -0x7e954001, -0x7c908002, -0x7cd4c002, -0x7cbc800b, -0x9ac00003, -0x7c8f400b, -0x38b40001, -0x9b4000c1, -0xcc00004d, -0x9bc000bf, -0xcc00004e, -0xc80c03fd, -0xc81003fc, -0xccc00042, -0x8000016e, -0xcd000042, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xcc400040, -0xcc400040, -0xcc400040, -0x7c40c000, -0xccc00040, -0xccc0000d, -0x80000000, -0xd0400040, -0x7c40c000, -0x7c410000, -0x65140020, -0x7d4d402c, -0x24580002, -0x7d598020, -0x7c41c000, -0xcd800042, -0x69980020, -0xcd800042, -0xcdc00042, -0xc023c000, -0x05e40002, -0x7ca0800b, -0x26640010, -0x7ca4800c, -0xcc800040, -0xcdc00040, -0xccc00040, -0x95c0000e, -0xcd000040, -0x09dc0001, -0xc8280003, -0x96800008, -0xce800040, -0xc834001d, -0x97400000, -0xc834001d, -0x26a80008, -0x8400024c, -0xcc2b0000, -0x99c0fff7, -0x09dc0001, -0xdc3a0000, -0x97800004, -0x7c418000, -0x800001a2, -0x25980002, -0xa0000000, -0x7d808000, -0xc818001d, -0x7c40c000, -0x64d00008, -0x95800000, -0xc818001d, -0xcc130000, -0xcc800040, -0xccc00040, -0x80000000, -0xcc400040, -0xc810001f, -0x7c40c000, -0xcc800040, -0x7cd1400c, -0xcd400040, -0x05180001, -0x80000000, -0xcd800022, -0x7c40c000, -0x64500020, -0x8400024c, -0xcc000061, -0x7cd0c02c, -0xc8200017, -0xc8d60000, -0x99400008, -0x7c438000, -0xdf830000, -0xcfa0004f, -0x8400024c, -0xcc000062, -0x80000000, -0xd040007f, -0x80000249, -0xcc000062, -0x8400024c, -0xcc000061, -0xc8200017, -0x7c40c000, -0xc036ff00, -0xc810000d, -0xc0303fff, -0x7cf5400b, -0x7d51800b, -0x7d81800f, -0x99800008, -0x7cf3800b, -0xdf830000, -0xcfa0004f, -0x8400024c, -0xcc000062, -0x80000000, -0xd040007f, -0x80000249, -0xcc000062, -0x8400024c, -0x7c40c000, -0x28dc0008, -0x95c00019, -0x30dc0010, -0x7c410000, -0x99c00004, -0x64540020, -0x80000208, -0xc91d0000, -0x7d15002c, -0xc91e0000, -0x7c420000, -0x7c424000, -0x7c418000, -0x7de5c00b, -0x7de28007, -0x9a80000e, -0x41ac0005, -0x9ac00000, -0x0aec0001, -0x30dc0010, -0x99c00004, -0x00000000, -0x8000020b, -0xc91d0000, -0x8000020b, -0xc91e0000, -0xcc800040, -0xccc00040, -0xd0400040, -0xc80c0025, -0x94c0fde4, -0xc8100008, -0xcd000040, -0xd4000fc0, -0x80000000, -0xd4000fa2, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xd40003c0, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0x7c40c000, -0x30d00006, -0x0d100006, -0x99000007, -0xc8140015, -0x99400005, -0xcc000052, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xccc00040, -0x80000000, -0xd0400040, -0x7c40c000, -0xcc4d0000, -0xdc3a0000, -0x9780fdbd, -0x04cc0001, -0x80000242, -0xcc4d0000, -0x80000000, -0xd040007f, -0xcc00007f, -0x80000000, -0xcc00007f, -0xcc00007f, -0x88000000, -0xcc00007f, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00030222, -0x0004022a, -0x0005009f, -0x00020003, -0x0006003c, -0x00070027, -0x00080191, -0x00090044, -0x000a002d, -0x00100247, -0x001700f0, -0x002201d7, -0x002301e8, -0x0026004c, -0x0027005f, -0x0020011a, -0x00280092, -0x0029004f, -0x002a0083, -0x002b0064, -0x002f008d, -0x003200d8, -0x00340232, -0x00360074, -0x0039010a, -0x003c01fc, -0x003f009f, -0x00410005, -0x00440194, -0x0048019d, -0x004901c5, -0x004a01cf, -0x00550225, -0x0056022d, -0x0060000a, -0x0061002a, -0x00620030, -0x00630030, -0x00640030, -0x00650030, -0x00660030, -0x00670030, -0x00680037, -0x0069003f, -0x006a0047, -0x006b0047, -0x006c0047, -0x006d0047, -0x006e0047, -0x006f0047, -0x00700047, -0x00730247, -0x007b0240, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -}; - -static const u32 RV730_cp_microcode[] = { -0xcc0003ea, -0x7c408000, -0xa0000000, -0xcc800062, -0x80000001, -0xd040007f, -0x80000001, -0xcc400041, -0x7c40c000, -0xc0160004, -0x30d03fff, -0x7d15000c, -0xcc110000, -0x28d8001e, -0x31980001, -0x28dc001f, -0xc8200004, -0x95c00006, -0x7c424000, -0xcc000062, -0x7e56800c, -0xcc290000, -0xc8240004, -0x7e26000b, -0x95800006, -0x7c42c000, -0xcc000062, -0x7ed7000c, -0xcc310000, -0xc82c0004, -0x7e2e000c, -0xcc000062, -0x31103fff, -0x80000001, -0xce110000, -0x7c40c000, -0x80000001, -0xcc400040, -0x80000001, -0xcc412257, -0x7c418000, -0xcc400045, -0xcc400048, -0xcc41225c, -0xcc41a1fc, -0x7c408000, -0xa0000000, -0xcc800062, -0xcc400045, -0xcc400048, -0x7c40c000, -0xcc41225c, -0xcc41a1fc, -0x7c408000, -0xa0000000, -0xcc800062, -0xcc000045, -0xcc000048, -0xcc41225c, -0xcc41a1fc, -0x7c408000, -0xa0000000, -0xcc800062, -0x040ca1fd, -0xc0120001, -0xcc000045, -0xcc000048, -0x7cd0c00c, -0xcc41225c, -0xcc41a1fc, -0xd04d0000, -0x7c408000, -0xa0000000, -0xcc800062, -0x80000001, -0xcc41225d, -0x7c408000, -0x7c40c000, -0xc02a0002, -0x7c410000, -0x7d29000c, -0x30940001, -0x30980006, -0x309c0300, -0x29dc0008, -0x7c420000, -0x7c424000, -0x9540000f, -0xc02e0004, -0x05f02258, -0x7f2f000c, -0xcc310000, -0xc8280004, -0xccc12169, -0xcd01216a, -0xce81216b, -0x0db40002, -0xcc01216c, -0x9740000e, -0x0db40000, -0x8000007b, -0xc834000a, -0x0db40002, -0x97400009, -0x0db40000, -0xc02e0004, -0x05f02258, -0x7f2f000c, -0xcc310000, -0xc8280004, -0x8000007b, -0xc834000a, -0x97400004, -0x7e028000, -0x8000007b, -0xc834000a, -0x0db40004, -0x9740ff8c, -0x00000000, -0xce01216d, -0xce41216e, -0xc8280003, -0xc834000a, -0x9b400004, -0x043c0005, -0x8400026b, -0xcc000062, -0x0df40000, -0x9740000b, -0xc82c03e6, -0xce81a2b7, -0xc0300006, -0x7ef34028, -0xc0300020, -0x7f6b8020, -0x7fb3c029, -0xcf81a2c4, -0x80000001, -0xcfc1a2d1, -0x0df40001, -0x9740000b, -0xc82c03e7, -0xce81a2bb, -0xc0300006, -0x7ef34028, -0xc0300020, -0x7f6b8020, -0x7fb3c029, -0xcf81a2c5, -0x80000001, -0xcfc1a2d2, -0x0df40002, -0x9740000b, -0xc82c03e8, -0xce81a2bf, -0xc0300006, -0x7ef34028, -0xc0300020, -0x7f6b8020, -0x7fb3c029, -0xcf81a2c6, -0x80000001, -0xcfc1a2d3, -0xc82c03e9, -0xce81a2c3, -0xc0300006, -0x7ef34028, -0xc0300020, -0x7f6b8020, -0x7fb3c029, -0xcf81a2c7, -0x80000001, -0xcfc1a2d4, -0x80000001, -0xcc400042, -0x7c40c000, -0x7c410000, -0x2914001d, -0x31540001, -0x9940000c, -0x31181000, -0xc81c0011, -0x95c00000, -0xc81c0011, -0xccc12100, -0xcd012101, -0xccc12102, -0xcd012103, -0x04180004, -0x8000037c, -0xcd81a2a4, -0xc02a0004, -0x95800008, -0x36a821a3, -0xcc290000, -0xc8280004, -0xc81c0011, -0x0de40040, -0x9640ffff, -0xc81c0011, -0xccc12170, -0xcd012171, -0xc8200012, -0x96000000, -0xc8200012, -0x8000037c, -0xcc000064, -0x7c40c000, -0x7c410000, -0xcc000045, -0xcc000048, -0x40d40003, -0xcd41225c, -0xcd01a1fc, -0xc01a0001, -0x041ca1fd, -0x7dd9c00c, -0x7c420000, -0x08cc0001, -0x06240001, -0x06280002, -0xce1d0000, -0xce5d0000, -0x98c0fffa, -0xce9d0000, -0x7c408000, -0xa0000000, -0xcc800062, -0x7c40c000, -0x30d00001, -0x28cc0001, -0x7c414000, -0x95000006, -0x7c418000, -0xcd41216d, -0xcd81216e, -0x800000f2, -0xc81c0003, -0xc0220004, -0x7e16000c, -0xcc210000, -0xc81c0004, -0x7c424000, -0x98c00004, -0x7c428000, -0x80000001, -0xcde50000, -0xce412169, -0xce81216a, -0xcdc1216b, -0x80000001, -0xcc01216c, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0x7c41c000, -0x28a40008, -0x326400ff, -0x0e68003c, -0x9680000a, -0x7c020000, -0x7c420000, -0x1e300003, -0xcc00006a, -0x9b000003, -0x42200005, -0x04200040, -0x8000010f, -0x7c024000, -0x7e024000, -0x9a400000, -0x0a640001, -0x30ec0010, -0x9ac0000a, -0xcc000062, -0xc02a0004, -0xc82c0021, -0x7e92800c, -0xcc000041, -0xcc290000, -0xcec00021, -0x8000011f, -0xc8300004, -0xcd01216d, -0xcd41216e, -0xc8300003, -0x7f1f000b, -0x30f40007, -0x27780001, -0x9740002a, -0x07b80124, -0x9f800000, -0x00000000, -0x80000134, -0x7f1b8004, -0x80000138, -0x7f1b8005, -0x8000013c, -0x7f1b8002, -0x80000140, -0x7f1b8003, -0x80000144, -0x7f1b8007, -0x80000148, -0x7f1b8006, -0x8000014d, -0x28a40008, -0x9b800019, -0x28a40008, -0x8000015d, -0x326400ff, -0x9b800015, -0x28a40008, -0x8000015d, -0x326400ff, -0x9b800011, -0x28a40008, -0x8000015d, -0x326400ff, -0x9b80000d, -0x28a40008, -0x8000015d, -0x326400ff, -0x9b800009, -0x28a40008, -0x8000015d, -0x326400ff, -0x9b800005, -0x28a40008, -0x8000015d, -0x326400ff, -0x28a40008, -0x326400ff, -0x0e68003c, -0x9a80feb2, -0x28ec0008, -0x7c434000, -0x7c438000, -0x7c43c000, -0x96c00007, -0xcc000062, -0xcf412169, -0xcf81216a, -0xcfc1216b, -0x80000001, -0xcc01216c, -0x80000001, -0xcff50000, -0xcc00006b, -0x8400037f, -0x0e68003c, -0x9a800004, -0xc8280015, -0x80000001, -0xd040007f, -0x9680ffab, -0x7e024000, -0x84000239, -0xc00e0002, -0xcc000041, -0x80000237, -0xccc1304a, -0x7c40c000, -0x7c410000, -0xc01e0001, -0x29240012, -0xc0220002, -0x96400005, -0xc0260004, -0xc027fffb, -0x7d25000b, -0xc0260000, -0x7dd2800b, -0x7e12c00b, -0x7d25000c, -0x7c414000, -0x7c418000, -0xccc12169, -0x9a80000a, -0xcd01216a, -0xcd41216b, -0x96c0fe83, -0xcd81216c, -0xc8300018, -0x97000000, -0xc8300018, -0x80000001, -0xcc000018, -0x8400037f, -0xcc00007f, -0xc8140013, -0xc8180014, -0xcd41216b, -0x96c0fe77, -0xcd81216c, -0x80000181, -0xc8300018, -0xc80c0008, -0x98c00000, -0xc80c0008, -0x7c410000, -0x95000002, -0x00000000, -0x7c414000, -0xc8200009, -0xcc400043, -0xce01a1f4, -0xcc400044, -0xc00e8000, -0x7c424000, -0x7c428000, -0x2aac001f, -0x96c0fe64, -0xc035f000, -0xce4003e2, -0x32780003, -0x267c0008, -0x7ff7c00b, -0x7ffbc00c, -0x2a780018, -0xcfc003e3, -0xcf8003e4, -0x26b00002, -0x7f3f0000, -0xcf0003e5, -0x8000031d, -0x7c80c000, -0x7c40c000, -0x28d00008, -0x3110000f, -0x9500000f, -0x25280001, -0x06a801b2, -0x9e800000, -0x00000000, -0x800001d3, -0xc0120800, -0x800001e1, -0xc814000f, -0x800001e8, -0xc8140010, -0x800001ef, -0xccc1a2a4, -0x800001f8, -0xc8140011, -0x30d0003f, -0x0d280015, -0x9a800012, -0x0d28001e, -0x9a80001e, -0x0d280020, -0x9a800023, -0x0d24000f, -0x0d280010, -0x7e6a800c, -0x9a800026, -0x0d200004, -0x0d240014, -0x0d280028, -0x7e62400c, -0x7ea6800c, -0x9a80002a, -0xc8140011, -0x80000001, -0xccc1a2a4, -0xc0120800, -0x7c414000, -0x7d0cc00c, -0xc0120008, -0x29580003, -0x295c000c, -0x7c420000, -0x7dd1c00b, -0x26200014, -0x7e1e400c, -0x7e4e800c, -0xce81a2a4, -0x80000001, -0xcd81a1fe, -0xc814000f, -0x0410210e, -0x95400000, -0xc814000f, -0xd0510000, -0x80000001, -0xccc1a2a4, -0xc8140010, -0x04102108, -0x95400000, -0xc8140010, -0xd0510000, -0x80000001, -0xccc1a2a4, -0xccc1a2a4, -0x04100001, -0xcd000019, -0x8400037f, -0xcc00007f, -0xc8100019, -0x99000000, -0xc8100019, -0x80000002, -0x7c408000, -0x04102100, -0x95400000, -0xc8140011, -0xd0510000, -0x8000037c, -0xccc1a2a4, -0x7c40c000, -0xcc40000d, -0x94c0fe01, -0xcc40000e, -0x7c410000, -0x95000005, -0x08cc0001, -0xc8140005, -0x99400014, -0x00000000, -0x98c0fffb, -0x7c410000, -0x80000002, -0x7d008000, -0xc8140005, -0x7c40c000, -0x9940000c, -0xc818000c, -0x7c410000, -0x9580fdf0, -0xc820000e, -0xc81c000d, -0x66200020, -0x7e1e002c, -0x25240002, -0x7e624020, -0x80000001, -0xcce60000, -0x7c410000, -0xcc00006c, -0xcc00006d, -0xc818001f, -0xc81c001e, -0x65980020, -0x7dd9c02c, -0x7cd4c00c, -0xccde0000, -0x45dc0004, -0xc8280017, -0x9680000f, -0xc00e0001, -0x28680008, -0x2aac0016, -0x32a800ff, -0x0eb00049, -0x7f2f000b, -0x97000006, -0x00000000, -0xc8140005, -0x7c40c000, -0x80000221, -0x7c410000, -0x80000224, -0xd040007f, -0x84000239, -0xcc000041, -0xccc1304a, -0x94000000, -0xc83c001a, -0x043c0005, -0xcfc1a2a4, -0xc0361f90, -0xc0387fff, -0x7c03c010, -0x7f7b400c, -0xcf41217c, -0xcfc1217d, -0xcc01217e, -0xc03a0004, -0x0434217f, -0x7f7b400c, -0xcc350000, -0xc83c0004, -0x2bfc001f, -0x04380020, -0x97c00005, -0xcc000062, -0x9b800000, -0x0bb80001, -0x80000245, -0xcc000071, -0xcc01a1f4, -0x04380016, -0xc0360002, -0xcf81a2a4, -0x88000000, -0xcf412010, -0x7c40c000, -0x28d0001c, -0x95000005, -0x04d40001, -0xcd400065, -0x80000001, -0xcd400068, -0x09540002, -0x80000001, -0xcd400066, -0x8400026a, -0xc81803ea, -0x7c40c000, -0x9980fd9f, -0xc8140016, -0x08d00001, -0x9940002b, -0xcd000068, -0x7c408000, -0xa0000000, -0xcc800062, -0x043c0005, -0xcfc1a2a4, -0xcc01a1f4, -0x8400037f, -0xcc000046, -0x88000000, -0xcc00007f, -0x8400027c, -0xc81803ea, -0x7c40c000, -0x9980fd8d, -0xc8140016, -0x08d00001, -0x99400019, -0xcd000068, -0x7c408000, -0xa0000000, -0xcc800062, -0x043c0022, -0xcfc1a2a4, -0x8400037f, -0xcc000047, -0x88000000, -0xcc00007f, -0xc8100016, -0x9900000d, -0xcc400067, -0x80000002, -0x7c408000, -0xc81803ea, -0x9980fd79, -0x7c40c000, -0x94c00003, -0xc8100016, -0x99000004, -0xccc00068, -0x80000002, -0x7c408000, -0x84000239, -0xc0148000, -0xcc000041, -0xcd41304a, -0xc0148000, -0x99000000, -0xc8100016, -0x80000002, -0x7c408000, -0xc0120001, -0x7c51400c, -0x80000001, -0xd0550000, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0x291c001f, -0xccc0004a, -0xcd00004b, -0x95c00003, -0xc01c8000, -0xcdc12010, -0xdd830000, -0x055c2000, -0xcc000062, -0x80000001, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc0004c, -0xcd00004d, -0xdd830000, -0x055ca000, -0x80000001, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc0004e, -0xcd00004f, -0xdd830000, -0x055cc000, -0x80000001, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00050, -0xcd000051, -0xdd830000, -0x055cf8e0, -0x80000001, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00052, -0xcd000053, -0xdd830000, -0x055cf880, -0x80000001, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00054, -0xcd000055, -0xdd830000, -0x055ce000, -0x80000001, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00056, -0xcd000057, -0xdd830000, -0x055cf000, -0x80000001, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00058, -0xcd000059, -0xdd830000, -0x055cf3fc, -0x80000001, -0xd81f4100, -0xd0432000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043a000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043c000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043f8e0, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043f880, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043e000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043f000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043f3fc, -0x7c408000, -0xa0000000, -0xcc800062, -0xc81403e0, -0xcc430000, -0xcc430000, -0xcc430000, -0x7d45c000, -0xcdc30000, -0xd0430000, -0x7c408000, -0xa0000000, -0xcc800062, -0x7c40c000, -0xc81003e2, -0xc81403e5, -0xc81803e3, -0xc81c03e4, -0xcd812169, -0xcdc1216a, -0xccc1216b, -0xcc01216c, -0x04200004, -0x7da18000, -0x7d964002, -0x9640fcd9, -0xcd8003e3, -0x31280003, -0xc02df000, -0x25180008, -0x7dad800b, -0x7da9800c, -0x80000001, -0xcd8003e3, -0x308cffff, -0xd04d0000, -0x7c408000, -0xa0000000, -0xcc800062, -0xc8140020, -0x15580002, -0x9580ffff, -0xc8140020, -0xcc00006e, -0xcc412180, -0x7c40c000, -0xccc1218d, -0xcc412181, -0x28d0001f, -0x34588000, -0xcd81218c, -0x9500fcbf, -0xcc412182, -0xc8140020, -0x9940ffff, -0xc8140020, -0x80000002, -0x7c408000, -0x7c40c000, -0x28d00018, -0x31100001, -0xc0160080, -0x95000003, -0xc02a0004, -0x7cd4c00c, -0xccc1217c, -0xcc41217d, -0xcc41217e, -0x7c418000, -0x1db00003, -0x36a0217f, -0x9b000003, -0x419c0005, -0x041c0040, -0x99c00000, -0x09dc0001, -0xcc210000, -0xc8240004, -0x2a6c001f, -0x419c0005, -0x9ac0fffa, -0xcc800062, -0x80000002, -0x7c408000, -0x7c40c000, -0x04d403e6, -0x80000001, -0xcc540000, -0x8000037c, -0xcc4003ea, -0xc01c8000, -0x044ca000, -0xcdc12010, -0x7c410000, -0xc8140009, -0x04180000, -0x041c0008, -0xcd800071, -0x09dc0001, -0x05980001, -0xcd0d0000, -0x99c0fffc, -0xcc800062, -0x8000037c, -0xcd400071, -0xc00e0100, -0xcc000041, -0xccc1304a, -0xc83c007f, -0xcc00007f, -0x80000001, -0xcc00007f, -0xcc00007f, -0x88000000, -0xcc00007f, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00010331, -0x00100004, -0x00170006, -0x00210008, -0x00270028, -0x00280023, -0x00290029, -0x002a0026, -0x002b0029, -0x002d0038, -0x002e003f, -0x002f004a, -0x0034004c, -0x00360030, -0x003900af, -0x003a00cf, -0x003b00e4, -0x003c00fc, -0x003d016b, -0x003f00ad, -0x00410336, -0x00430349, -0x0044018e, -0x004500fc, -0x004601ac, -0x004701ac, -0x004801fe, -0x0049020c, -0x004a0255, -0x004b0282, -0x0052025f, -0x00530271, -0x00540287, -0x00570299, -0x0060029d, -0x006102ac, -0x006202b6, -0x006302c0, -0x006402ca, -0x006502d4, -0x006602de, -0x006702e8, -0x006802f2, -0x006902f6, -0x006a02fa, -0x006b02fe, -0x006c0302, -0x006d0306, -0x006e030a, -0x006f030e, -0x00700312, -0x00720363, -0x00740369, -0x00790367, -0x007c031c, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -0x000f0378, -}; - -static const u32 RV710_pfp_microcode[] = { -0x7c408000, -0xa0000000, -0x7e82800b, -0x80000000, -0xdc030000, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xc818000e, -0x31980001, -0x7c424000, -0x9580023a, -0x7c428000, -0xc81c001c, -0xc037c000, -0x7c40c000, -0x7c410000, -0x7cb4800b, -0xc0360003, -0x99c00000, -0xc81c001c, -0x7cb4800c, -0x24d40002, -0x7d654000, -0xcd400043, -0xce800043, -0xcd000043, -0xcc800040, -0xce400040, -0xce800040, -0xccc00040, -0xdc3a0000, -0x9780ffde, -0xcd000040, -0x7c40c000, -0x80000018, -0x7c410000, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xc818000e, -0x8000000c, -0x31980002, -0xd40003c0, -0xd4000fc0, -0xd4000fa2, -0xc818000e, -0x288c0008, -0x30cc000f, -0x34100001, -0x7d0d0008, -0x8000000c, -0x7d91800b, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xd40003c0, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xcc4003f9, -0x80000249, -0xcc4003f8, -0xc037ffff, -0x7c414000, -0xcf41a29e, -0xc82003f8, -0xc81c03f9, -0x66200020, -0xc81803fb, -0x7de1c02c, -0x7d58c008, -0x7cdcc020, -0x69100020, -0xc0360003, -0xcc000054, -0x7cb4800c, -0x80000069, -0xcc800040, -0x7c418000, -0xcd81a29e, -0xcc800040, -0x80000067, -0xcd800040, -0xc019ffff, -0xcc800040, -0xcd81a29e, -0x7c40c000, -0x7c410000, -0x7c414000, -0xccc1a1fa, -0xcd01a1f9, -0xcd41a29d, -0xccc00040, -0xcd000040, -0xcd400040, -0xcc400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xcc000054, -0xcc800040, -0x7c40c000, -0x7c410000, -0x7c414000, -0xccc1a1fa, -0xcd01a1f9, -0xcd41a29d, -0xccc00040, -0xcd000040, -0xcd400040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0x7c40c000, -0x30d00001, -0xccc1a29f, -0x95000003, -0x04140001, -0x04140002, -0xcd4003fb, -0xcc800040, -0x80000000, -0xccc00040, -0x7c40c000, -0xcc800040, -0xccc1a2a2, -0x80000000, -0xccc00040, -0x7c40c000, -0x28d4001f, -0xcc800040, -0x95400003, -0x7c410000, -0xccc00057, -0x2918001f, -0xccc00040, -0x95800003, -0xcd000040, -0xcd000058, -0x80000249, -0xcc00007f, -0xc8200017, -0xc8300022, -0x9a000006, -0x0e280001, -0xc824001e, -0x0a640001, -0xd4001240, -0xce400040, -0xc036c000, -0x96800007, -0x37747900, -0x041c0001, -0xcf400040, -0xcdc00040, -0xcf0003fa, -0x7c030000, -0xca0c0010, -0x7c410000, -0x94c00004, -0x7c414000, -0xd42002c4, -0xcde00044, -0x9b00000b, -0x7c418000, -0xcc00004b, -0xcda00049, -0xcd200041, -0xcd600041, -0xcda00041, -0x06200001, -0xce000056, -0x80000249, -0xcc00007f, -0xc8280020, -0xc82c0021, -0xcc000063, -0x7eea4001, -0x65740020, -0x7f53402c, -0x269c0002, -0x7df5c020, -0x69f80020, -0xce80004b, -0xce600049, -0xcde00041, -0xcfa00041, -0xce600041, -0x271c0002, -0x7df5c020, -0x69f80020, -0x7db24001, -0xcf00004b, -0xce600049, -0xcde00041, -0xcfa00041, -0x800000bc, -0xce600041, -0xc8200017, -0xc8300022, -0x9a000006, -0x0e280001, -0xc824001e, -0x0a640001, -0xd4001240, -0xce400040, -0xca0c0010, -0x7c410000, -0x94c0000b, -0xc036c000, -0x96800007, -0x37747900, -0x041c0001, -0xcf400040, -0xcdc00040, -0xcf0003fa, -0x7c030000, -0x800000b5, -0x7c414000, -0xcc000048, -0x800000ee, -0x00000000, -0xc8200017, -0xc81c0023, -0x0e240002, -0x99c00015, -0x7c418000, -0x0a200001, -0xce000056, -0xd4000440, -0xcc000040, -0xc036c000, -0xca140013, -0x96400007, -0x37747900, -0xcf400040, -0xcc000040, -0xc83003fa, -0x80000103, -0xcf000022, -0xcc000022, -0x95400146, -0xcc00007f, -0xcca00046, -0x80000000, -0xcc200046, -0x80000249, -0xcc000064, -0xc8200017, -0xc810001f, -0x96000005, -0x09100001, -0xd4000440, -0xcd000040, -0xcd000022, -0xcc800040, -0xd0400040, -0xc80c0025, -0x94c0feec, -0xc8100008, -0xcd000040, -0xd4000fc0, -0x80000000, -0xd4000fa2, -0x7c40c000, -0x7c410000, -0xccc003fd, -0xcd0003fc, -0xccc00042, -0xcd000042, -0x2914001f, -0x29180010, -0x31980007, -0x3b5c0001, -0x7d76000b, -0x99800005, -0x7d5e400b, -0xcc000042, -0x80000249, -0xcc00004d, -0x29980001, -0x292c0008, -0x9980003d, -0x32ec0001, -0x96000004, -0x2930000c, -0x80000249, -0xcc000042, -0x04140010, -0xcd400042, -0x33300001, -0x34280001, -0x8400015d, -0xc8140003, -0x9b40001b, -0x0438000c, -0x8400015d, -0xc8140003, -0x9b400017, -0x04380008, -0x8400015d, -0xc8140003, -0x9b400013, -0x04380004, -0x8400015d, -0xc8140003, -0x9b400015, -0xc80c03fd, -0x9a800009, -0xc81003fc, -0x9b000101, -0xcc00004d, -0x04140010, -0xccc00042, -0xcd000042, -0x80000135, -0xcd400042, -0x96c000fa, -0xcc00004d, -0x80000249, -0xcc00004e, -0x9ac00003, -0xcc00004d, -0xcc00004e, -0xdf830000, -0x80000000, -0xd80301ff, -0x9ac000f0, -0xcc00004d, -0x80000249, -0xcc00004e, -0xc8180003, -0xc81c0003, -0xc8200003, -0x7d5d4003, -0x7da1c003, -0x7d5d400c, -0x2a10001f, -0x299c001f, -0x7d1d000b, -0x7d17400b, -0x88000000, -0x7e92800b, -0x96400004, -0xcc00004e, -0x80000249, -0xcc000042, -0x04380008, -0xcf800042, -0xc8080003, -0xc80c0003, -0xc8100003, -0xc8140003, -0xc8180003, -0xc81c0003, -0xc8240003, -0xc8280003, -0x29fc001f, -0x2ab0001f, -0x7ff3c00b, -0x28f0001f, -0x7ff3c00b, -0x2970001f, -0x7ff3c00b, -0x7d888001, -0x7dccc001, -0x7e510001, -0x7e954001, -0x7c908002, -0x7cd4c002, -0x7cbc800b, -0x9ac00003, -0x7c8f400b, -0x38b40001, -0x9b4000c1, -0xcc00004d, -0x9bc000bf, -0xcc00004e, -0xc80c03fd, -0xc81003fc, -0xccc00042, -0x8000016e, -0xcd000042, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xcc400040, -0xcc400040, -0xcc400040, -0x7c40c000, -0xccc00040, -0xccc0000d, -0x80000000, -0xd0400040, -0x7c40c000, -0x7c410000, -0x65140020, -0x7d4d402c, -0x24580002, -0x7d598020, -0x7c41c000, -0xcd800042, -0x69980020, -0xcd800042, -0xcdc00042, -0xc023c000, -0x05e40002, -0x7ca0800b, -0x26640010, -0x7ca4800c, -0xcc800040, -0xcdc00040, -0xccc00040, -0x95c0000e, -0xcd000040, -0x09dc0001, -0xc8280003, -0x96800008, -0xce800040, -0xc834001d, -0x97400000, -0xc834001d, -0x26a80008, -0x8400024c, -0xcc2b0000, -0x99c0fff7, -0x09dc0001, -0xdc3a0000, -0x97800004, -0x7c418000, -0x800001a2, -0x25980002, -0xa0000000, -0x7d808000, -0xc818001d, -0x7c40c000, -0x64d00008, -0x95800000, -0xc818001d, -0xcc130000, -0xcc800040, -0xccc00040, -0x80000000, -0xcc400040, -0xc810001f, -0x7c40c000, -0xcc800040, -0x7cd1400c, -0xcd400040, -0x05180001, -0x80000000, -0xcd800022, -0x7c40c000, -0x64500020, -0x8400024c, -0xcc000061, -0x7cd0c02c, -0xc8200017, -0xc8d60000, -0x99400008, -0x7c438000, -0xdf830000, -0xcfa0004f, -0x8400024c, -0xcc000062, -0x80000000, -0xd040007f, -0x80000249, -0xcc000062, -0x8400024c, -0xcc000061, -0xc8200017, -0x7c40c000, -0xc036ff00, -0xc810000d, -0xc0303fff, -0x7cf5400b, -0x7d51800b, -0x7d81800f, -0x99800008, -0x7cf3800b, -0xdf830000, -0xcfa0004f, -0x8400024c, -0xcc000062, -0x80000000, -0xd040007f, -0x80000249, -0xcc000062, -0x8400024c, -0x7c40c000, -0x28dc0008, -0x95c00019, -0x30dc0010, -0x7c410000, -0x99c00004, -0x64540020, -0x80000208, -0xc91d0000, -0x7d15002c, -0xc91e0000, -0x7c420000, -0x7c424000, -0x7c418000, -0x7de5c00b, -0x7de28007, -0x9a80000e, -0x41ac0005, -0x9ac00000, -0x0aec0001, -0x30dc0010, -0x99c00004, -0x00000000, -0x8000020b, -0xc91d0000, -0x8000020b, -0xc91e0000, -0xcc800040, -0xccc00040, -0xd0400040, -0xc80c0025, -0x94c0fde4, -0xc8100008, -0xcd000040, -0xd4000fc0, -0x80000000, -0xd4000fa2, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0xd40003c0, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xd0400040, -0x7c408000, -0xa0000000, -0x7e82800b, -0x7c40c000, -0x30d00006, -0x0d100006, -0x99000007, -0xc8140015, -0x99400005, -0xcc000052, -0xd4000340, -0xd4000fc0, -0xd4000fa2, -0xcc800040, -0xccc00040, -0x80000000, -0xd0400040, -0x7c40c000, -0xcc4d0000, -0xdc3a0000, -0x9780fdbd, -0x04cc0001, -0x80000242, -0xcc4d0000, -0x80000000, -0xd040007f, -0xcc00007f, -0x80000000, -0xcc00007f, -0xcc00007f, -0x88000000, -0xcc00007f, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00030222, -0x0004022a, -0x0005009f, -0x00020003, -0x0006003c, -0x00070027, -0x00080191, -0x00090044, -0x000a002d, -0x00100247, -0x001700f0, -0x002201d7, -0x002301e8, -0x0026004c, -0x0027005f, -0x0020011a, -0x00280092, -0x0029004f, -0x002a0083, -0x002b0064, -0x002f008d, -0x003200d8, -0x00340232, -0x00360074, -0x0039010a, -0x003c01fc, -0x003f009f, -0x00410005, -0x00440194, -0x0048019d, -0x004901c5, -0x004a01cf, -0x00550225, -0x0056022d, -0x0060000a, -0x0061002a, -0x00620030, -0x00630030, -0x00640030, -0x00650030, -0x00660030, -0x00670030, -0x00680037, -0x0069003f, -0x006a0047, -0x006b0047, -0x006c0047, -0x006d0047, -0x006e0047, -0x006f0047, -0x00700047, -0x00730247, -0x007b0240, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -0x00000005, -}; - -static const u32 RV710_cp_microcode[] = { -0xcc0003ea, -0x04080003, -0xcc800043, -0x7c408000, -0xa0000000, -0xcc800062, -0x80000003, -0xd040007f, -0x80000003, -0xcc400041, -0x7c40c000, -0xc0160004, -0x30d03fff, -0x7d15000c, -0xcc110000, -0x28d8001e, -0x31980001, -0x28dc001f, -0xc8200004, -0x95c00006, -0x7c424000, -0xcc000062, -0x7e56800c, -0xcc290000, -0xc8240004, -0x7e26000b, -0x95800006, -0x7c42c000, -0xcc000062, -0x7ed7000c, -0xcc310000, -0xc82c0004, -0x7e2e000c, -0xcc000062, -0x31103fff, -0x80000003, -0xce110000, -0x7c40c000, -0x80000003, -0xcc400040, -0x80000003, -0xcc412257, -0x7c418000, -0xcc400045, -0xcc400048, -0xcc41225c, -0xcc41a1fc, -0x7c408000, -0xa0000000, -0xcc800062, -0xcc400045, -0xcc400048, -0x7c40c000, -0xcc41225c, -0xcc41a1fc, -0x7c408000, -0xa0000000, -0xcc800062, -0xcc000045, -0xcc000048, -0xcc41225c, -0xcc41a1fc, -0x7c408000, -0xa0000000, -0xcc800062, -0x040ca1fd, -0xc0120001, -0xcc000045, -0xcc000048, -0x7cd0c00c, -0xcc41225c, -0xcc41a1fc, -0xd04d0000, -0x7c408000, -0xa0000000, -0xcc800062, -0x80000003, -0xcc41225d, -0x7c408000, -0x7c40c000, -0xc02a0002, -0x7c410000, -0x7d29000c, -0x30940001, -0x30980006, -0x309c0300, -0x29dc0008, -0x7c420000, -0x7c424000, -0x9540000f, -0xc02e0004, -0x05f02258, -0x7f2f000c, -0xcc310000, -0xc8280004, -0xccc12169, -0xcd01216a, -0xce81216b, -0x0db40002, -0xcc01216c, -0x9740000e, -0x0db40000, -0x8000007d, -0xc834000a, -0x0db40002, -0x97400009, -0x0db40000, -0xc02e0004, -0x05f02258, -0x7f2f000c, -0xcc310000, -0xc8280004, -0x8000007d, -0xc834000a, -0x97400004, -0x7e028000, -0x8000007d, -0xc834000a, -0x0db40004, -0x9740ff8c, -0x00000000, -0xce01216d, -0xce41216e, -0xc8280003, -0xc834000a, -0x9b400004, -0x043c0005, -0x8400026d, -0xcc000062, -0x0df40000, -0x9740000b, -0xc82c03e6, -0xce81a2b7, -0xc0300006, -0x7ef34028, -0xc0300020, -0x7f6b8020, -0x7fb3c029, -0xcf81a2c4, -0x80000003, -0xcfc1a2d1, -0x0df40001, -0x9740000b, -0xc82c03e7, -0xce81a2bb, -0xc0300006, -0x7ef34028, -0xc0300020, -0x7f6b8020, -0x7fb3c029, -0xcf81a2c5, -0x80000003, -0xcfc1a2d2, -0x0df40002, -0x9740000b, -0xc82c03e8, -0xce81a2bf, -0xc0300006, -0x7ef34028, -0xc0300020, -0x7f6b8020, -0x7fb3c029, -0xcf81a2c6, -0x80000003, -0xcfc1a2d3, -0xc82c03e9, -0xce81a2c3, -0xc0300006, -0x7ef34028, -0xc0300020, -0x7f6b8020, -0x7fb3c029, -0xcf81a2c7, -0x80000003, -0xcfc1a2d4, -0x80000003, -0xcc400042, -0x7c40c000, -0x7c410000, -0x2914001d, -0x31540001, -0x9940000c, -0x31181000, -0xc81c0011, -0x95c00000, -0xc81c0011, -0xccc12100, -0xcd012101, -0xccc12102, -0xcd012103, -0x04180004, -0x8000037e, -0xcd81a2a4, -0xc02a0004, -0x95800008, -0x36a821a3, -0xcc290000, -0xc8280004, -0xc81c0011, -0x0de40040, -0x9640ffff, -0xc81c0011, -0xccc12170, -0xcd012171, -0xc8200012, -0x96000000, -0xc8200012, -0x8000037e, -0xcc000064, -0x7c40c000, -0x7c410000, -0xcc000045, -0xcc000048, -0x40d40003, -0xcd41225c, -0xcd01a1fc, -0xc01a0001, -0x041ca1fd, -0x7dd9c00c, -0x7c420000, -0x08cc0001, -0x06240001, -0x06280002, -0xce1d0000, -0xce5d0000, -0x98c0fffa, -0xce9d0000, -0x7c408000, -0xa0000000, -0xcc800062, -0x7c40c000, -0x30d00001, -0x28cc0001, -0x7c414000, -0x95000006, -0x7c418000, -0xcd41216d, -0xcd81216e, -0x800000f4, -0xc81c0003, -0xc0220004, -0x7e16000c, -0xcc210000, -0xc81c0004, -0x7c424000, -0x98c00004, -0x7c428000, -0x80000003, -0xcde50000, -0xce412169, -0xce81216a, -0xcdc1216b, -0x80000003, -0xcc01216c, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0x7c41c000, -0x28a40008, -0x326400ff, -0x0e68003c, -0x9680000a, -0x7c020000, -0x7c420000, -0x1e300003, -0xcc00006a, -0x9b000003, -0x42200005, -0x04200040, -0x80000111, -0x7c024000, -0x7e024000, -0x9a400000, -0x0a640001, -0x30ec0010, -0x9ac0000a, -0xcc000062, -0xc02a0004, -0xc82c0021, -0x7e92800c, -0xcc000041, -0xcc290000, -0xcec00021, -0x80000121, -0xc8300004, -0xcd01216d, -0xcd41216e, -0xc8300003, -0x7f1f000b, -0x30f40007, -0x27780001, -0x9740002a, -0x07b80126, -0x9f800000, -0x00000000, -0x80000136, -0x7f1b8004, -0x8000013a, -0x7f1b8005, -0x8000013e, -0x7f1b8002, -0x80000142, -0x7f1b8003, -0x80000146, -0x7f1b8007, -0x8000014a, -0x7f1b8006, -0x8000014f, -0x28a40008, -0x9b800019, -0x28a40008, -0x8000015f, -0x326400ff, -0x9b800015, -0x28a40008, -0x8000015f, -0x326400ff, -0x9b800011, -0x28a40008, -0x8000015f, -0x326400ff, -0x9b80000d, -0x28a40008, -0x8000015f, -0x326400ff, -0x9b800009, -0x28a40008, -0x8000015f, -0x326400ff, -0x9b800005, -0x28a40008, -0x8000015f, -0x326400ff, -0x28a40008, -0x326400ff, -0x0e68003c, -0x9a80feb2, -0x28ec0008, -0x7c434000, -0x7c438000, -0x7c43c000, -0x96c00007, -0xcc000062, -0xcf412169, -0xcf81216a, -0xcfc1216b, -0x80000003, -0xcc01216c, -0x80000003, -0xcff50000, -0xcc00006b, -0x84000381, -0x0e68003c, -0x9a800004, -0xc8280015, -0x80000003, -0xd040007f, -0x9680ffab, -0x7e024000, -0x8400023b, -0xc00e0002, -0xcc000041, -0x80000239, -0xccc1304a, -0x7c40c000, -0x7c410000, -0xc01e0001, -0x29240012, -0xc0220002, -0x96400005, -0xc0260004, -0xc027fffb, -0x7d25000b, -0xc0260000, -0x7dd2800b, -0x7e12c00b, -0x7d25000c, -0x7c414000, -0x7c418000, -0xccc12169, -0x9a80000a, -0xcd01216a, -0xcd41216b, -0x96c0fe83, -0xcd81216c, -0xc8300018, -0x97000000, -0xc8300018, -0x80000003, -0xcc000018, -0x84000381, -0xcc00007f, -0xc8140013, -0xc8180014, -0xcd41216b, -0x96c0fe77, -0xcd81216c, -0x80000183, -0xc8300018, -0xc80c0008, -0x98c00000, -0xc80c0008, -0x7c410000, -0x95000002, -0x00000000, -0x7c414000, -0xc8200009, -0xcc400043, -0xce01a1f4, -0xcc400044, -0xc00e8000, -0x7c424000, -0x7c428000, -0x2aac001f, -0x96c0fe64, -0xc035f000, -0xce4003e2, -0x32780003, -0x267c0008, -0x7ff7c00b, -0x7ffbc00c, -0x2a780018, -0xcfc003e3, -0xcf8003e4, -0x26b00002, -0x7f3f0000, -0xcf0003e5, -0x8000031f, -0x7c80c000, -0x7c40c000, -0x28d00008, -0x3110000f, -0x9500000f, -0x25280001, -0x06a801b4, -0x9e800000, -0x00000000, -0x800001d5, -0xc0120800, -0x800001e3, -0xc814000f, -0x800001ea, -0xc8140010, -0x800001f1, -0xccc1a2a4, -0x800001fa, -0xc8140011, -0x30d0003f, -0x0d280015, -0x9a800012, -0x0d28001e, -0x9a80001e, -0x0d280020, -0x9a800023, -0x0d24000f, -0x0d280010, -0x7e6a800c, -0x9a800026, -0x0d200004, -0x0d240014, -0x0d280028, -0x7e62400c, -0x7ea6800c, -0x9a80002a, -0xc8140011, -0x80000003, -0xccc1a2a4, -0xc0120800, -0x7c414000, -0x7d0cc00c, -0xc0120008, -0x29580003, -0x295c000c, -0x7c420000, -0x7dd1c00b, -0x26200014, -0x7e1e400c, -0x7e4e800c, -0xce81a2a4, -0x80000003, -0xcd81a1fe, -0xc814000f, -0x0410210e, -0x95400000, -0xc814000f, -0xd0510000, -0x80000003, -0xccc1a2a4, -0xc8140010, -0x04102108, -0x95400000, -0xc8140010, -0xd0510000, -0x80000003, -0xccc1a2a4, -0xccc1a2a4, -0x04100001, -0xcd000019, -0x84000381, -0xcc00007f, -0xc8100019, -0x99000000, -0xc8100019, -0x80000004, -0x7c408000, -0x04102100, -0x95400000, -0xc8140011, -0xd0510000, -0x8000037e, -0xccc1a2a4, -0x7c40c000, -0xcc40000d, -0x94c0fe01, -0xcc40000e, -0x7c410000, -0x95000005, -0x08cc0001, -0xc8140005, -0x99400014, -0x00000000, -0x98c0fffb, -0x7c410000, -0x80000004, -0x7d008000, -0xc8140005, -0x7c40c000, -0x9940000c, -0xc818000c, -0x7c410000, -0x9580fdf0, -0xc820000e, -0xc81c000d, -0x66200020, -0x7e1e002c, -0x25240002, -0x7e624020, -0x80000003, -0xcce60000, -0x7c410000, -0xcc00006c, -0xcc00006d, -0xc818001f, -0xc81c001e, -0x65980020, -0x7dd9c02c, -0x7cd4c00c, -0xccde0000, -0x45dc0004, -0xc8280017, -0x9680000f, -0xc00e0001, -0x28680008, -0x2aac0016, -0x32a800ff, -0x0eb00049, -0x7f2f000b, -0x97000006, -0x00000000, -0xc8140005, -0x7c40c000, -0x80000223, -0x7c410000, -0x80000226, -0xd040007f, -0x8400023b, -0xcc000041, -0xccc1304a, -0x94000000, -0xc83c001a, -0x043c0005, -0xcfc1a2a4, -0xc0361f90, -0xc0387fff, -0x7c03c010, -0x7f7b400c, -0xcf41217c, -0xcfc1217d, -0xcc01217e, -0xc03a0004, -0x0434217f, -0x7f7b400c, -0xcc350000, -0xc83c0004, -0x2bfc001f, -0x04380020, -0x97c00005, -0xcc000062, -0x9b800000, -0x0bb80001, -0x80000247, -0xcc000071, -0xcc01a1f4, -0x04380016, -0xc0360002, -0xcf81a2a4, -0x88000000, -0xcf412010, -0x7c40c000, -0x28d0001c, -0x95000005, -0x04d40001, -0xcd400065, -0x80000003, -0xcd400068, -0x09540002, -0x80000003, -0xcd400066, -0x8400026c, -0xc81803ea, -0x7c40c000, -0x9980fd9f, -0xc8140016, -0x08d00001, -0x9940002b, -0xcd000068, -0x7c408000, -0xa0000000, -0xcc800062, -0x043c0005, -0xcfc1a2a4, -0xcc01a1f4, -0x84000381, -0xcc000046, -0x88000000, -0xcc00007f, -0x8400027e, -0xc81803ea, -0x7c40c000, -0x9980fd8d, -0xc8140016, -0x08d00001, -0x99400019, -0xcd000068, -0x7c408000, -0xa0000000, -0xcc800062, -0x043c0022, -0xcfc1a2a4, -0x84000381, -0xcc000047, -0x88000000, -0xcc00007f, -0xc8100016, -0x9900000d, -0xcc400067, -0x80000004, -0x7c408000, -0xc81803ea, -0x9980fd79, -0x7c40c000, -0x94c00003, -0xc8100016, -0x99000004, -0xccc00068, -0x80000004, -0x7c408000, -0x8400023b, -0xc0148000, -0xcc000041, -0xcd41304a, -0xc0148000, -0x99000000, -0xc8100016, -0x80000004, -0x7c408000, -0xc0120001, -0x7c51400c, -0x80000003, -0xd0550000, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0x291c001f, -0xccc0004a, -0xcd00004b, -0x95c00003, -0xc01c8000, -0xcdc12010, -0xdd830000, -0x055c2000, -0xcc000062, -0x80000003, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc0004c, -0xcd00004d, -0xdd830000, -0x055ca000, -0x80000003, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc0004e, -0xcd00004f, -0xdd830000, -0x055cc000, -0x80000003, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00050, -0xcd000051, -0xdd830000, -0x055cf8e0, -0x80000003, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00052, -0xcd000053, -0xdd830000, -0x055cf880, -0x80000003, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00054, -0xcd000055, -0xdd830000, -0x055ce000, -0x80000003, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00056, -0xcd000057, -0xdd830000, -0x055cf000, -0x80000003, -0xd81f4100, -0x7c40c000, -0x7c410000, -0x7c414000, -0x7c418000, -0xccc00058, -0xcd000059, -0xdd830000, -0x055cf3fc, -0x80000003, -0xd81f4100, -0xd0432000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043a000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043c000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043f8e0, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043f880, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043e000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043f000, -0x7c408000, -0xa0000000, -0xcc800062, -0xd043f3fc, -0x7c408000, -0xa0000000, -0xcc800062, -0xc81403e0, -0xcc430000, -0xcc430000, -0xcc430000, -0x7d45c000, -0xcdc30000, -0xd0430000, -0x7c408000, -0xa0000000, -0xcc800062, -0x7c40c000, -0xc81003e2, -0xc81403e5, -0xc81803e3, -0xc81c03e4, -0xcd812169, -0xcdc1216a, -0xccc1216b, -0xcc01216c, -0x04200004, -0x7da18000, -0x7d964002, -0x9640fcd9, -0xcd8003e3, -0x31280003, -0xc02df000, -0x25180008, -0x7dad800b, -0x7da9800c, -0x80000003, -0xcd8003e3, -0x308cffff, -0xd04d0000, -0x7c408000, -0xa0000000, -0xcc800062, -0xc8140020, -0x15580002, -0x9580ffff, -0xc8140020, -0xcc00006e, -0xcc412180, -0x7c40c000, -0xccc1218d, -0xcc412181, -0x28d0001f, -0x34588000, -0xcd81218c, -0x9500fcbf, -0xcc412182, -0xc8140020, -0x9940ffff, -0xc8140020, -0x80000004, -0x7c408000, -0x7c40c000, -0x28d00018, -0x31100001, -0xc0160080, -0x95000003, -0xc02a0004, -0x7cd4c00c, -0xccc1217c, -0xcc41217d, -0xcc41217e, -0x7c418000, -0x1db00003, -0x36a0217f, -0x9b000003, -0x419c0005, -0x041c0040, -0x99c00000, -0x09dc0001, -0xcc210000, -0xc8240004, -0x2a6c001f, -0x419c0005, -0x9ac0fffa, -0xcc800062, -0x80000004, -0x7c408000, -0x7c40c000, -0x04d403e6, -0x80000003, -0xcc540000, -0x8000037e, -0xcc4003ea, -0xc01c8000, -0x044ca000, -0xcdc12010, -0x7c410000, -0xc8140009, -0x04180000, -0x041c0008, -0xcd800071, -0x09dc0001, -0x05980001, -0xcd0d0000, -0x99c0fffc, -0xcc800062, -0x8000037e, -0xcd400071, -0xc00e0100, -0xcc000041, -0xccc1304a, -0xc83c007f, -0xcc00007f, -0x80000003, -0xcc00007f, -0xcc00007f, -0x88000000, -0xcc00007f, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00000000, -0x00010333, -0x00100006, -0x00170008, -0x0021000a, -0x0027002a, -0x00280025, -0x0029002b, -0x002a0028, -0x002b002b, -0x002d003a, -0x002e0041, -0x002f004c, -0x0034004e, -0x00360032, -0x003900b1, -0x003a00d1, -0x003b00e6, -0x003c00fe, -0x003d016d, -0x003f00af, -0x00410338, -0x0043034b, -0x00440190, -0x004500fe, -0x004601ae, -0x004701ae, -0x00480200, -0x0049020e, -0x004a0257, -0x004b0284, -0x00520261, -0x00530273, -0x00540289, -0x0057029b, -0x0060029f, -0x006102ae, -0x006202b8, -0x006302c2, -0x006402cc, -0x006502d6, -0x006602e0, -0x006702ea, -0x006802f4, -0x006902f8, -0x006a02fc, -0x006b0300, -0x006c0304, -0x006d0308, -0x006e030c, -0x006f0310, -0x00700314, -0x00720365, -0x0074036b, -0x00790369, -0x007c031e, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -0x000f037a, -}; - -#endif diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cp.c b/trunk/drivers/gpu/drm/radeon/radeon_cp.c index 77a7a4d84650..92965dbb3c14 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cp.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cp.c @@ -43,78 +43,6 @@ static int radeon_do_cleanup_cp(struct drm_device * dev); static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); -u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off) -{ - u32 val; - - if (dev_priv->flags & RADEON_IS_AGP) { - val = DRM_READ32(dev_priv->ring_rptr, off); - } else { - val = *(((volatile u32 *) - dev_priv->ring_rptr->handle) + - (off / sizeof(u32))); - val = le32_to_cpu(val); - } - return val; -} - -u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv) -{ - if (dev_priv->writeback_works) - return radeon_read_ring_rptr(dev_priv, 0); - else { - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return RADEON_READ(R600_CP_RB_RPTR); - else - return RADEON_READ(RADEON_CP_RB_RPTR); - } -} - -void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val) -{ - if (dev_priv->flags & RADEON_IS_AGP) - DRM_WRITE32(dev_priv->ring_rptr, off, val); - else - *(((volatile u32 *) dev_priv->ring_rptr->handle) + - (off / sizeof(u32))) = cpu_to_le32(val); -} - -void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val) -{ - radeon_write_ring_rptr(dev_priv, 0, val); -} - -u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index) -{ - if (dev_priv->writeback_works) { - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return radeon_read_ring_rptr(dev_priv, - R600_SCRATCHOFF(index)); - else - return radeon_read_ring_rptr(dev_priv, - RADEON_SCRATCHOFF(index)); - } else { - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return RADEON_READ(R600_SCRATCH_REG0 + 4*index); - else - return RADEON_READ(RADEON_SCRATCH_REG0 + 4*index); - } -} - -u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr) -{ - u32 ret; - - if (addr < 0x10000) - ret = DRM_READ32(dev_priv->mmio, addr); - else { - DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, addr); - ret = DRM_READ32(dev_priv->mmio, RADEON_MM_DATA); - } - - return ret; -} - static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) { u32 ret; @@ -142,22 +70,11 @@ static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) return ret; } -static u32 RS600_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) -{ - u32 ret; - RADEON_WRITE(RS600_MC_INDEX, ((addr & RS600_MC_ADDR_MASK) | - RS600_MC_IND_CITF_ARB0)); - ret = RADEON_READ(RS600_MC_DATA); - return ret; -} - static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) { if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) return RS690_READ_MCIND(dev_priv, addr); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) - return RS600_READ_MCIND(dev_priv, addr); else return RS480_READ_MCIND(dev_priv, addr); } @@ -165,17 +82,11 @@ static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) { - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) - return RADEON_READ(R700_MC_VM_FB_LOCATION); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return RADEON_READ(R600_MC_VM_FB_LOCATION); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) - return RS600_READ_MCIND(dev_priv, RS600_MC_FB_LOCATION); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); else @@ -184,66 +95,42 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) { - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) - RADEON_WRITE(R700_MC_VM_FB_LOCATION, fb_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - RADEON_WRITE(R600_MC_VM_FB_LOCATION, fb_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) - RS600_WRITE_MCIND(RS600_MC_FB_LOCATION, fb_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); else RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); } -void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) +static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) { - /*R6xx/R7xx: AGP_TOP and BOT are actually 18 bits each */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { - RADEON_WRITE(R700_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ - RADEON_WRITE(R700_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { - RADEON_WRITE(R600_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ - RADEON_WRITE(R600_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) - RS600_WRITE_MCIND(RS600_MC_AGP_LOCATION, agp_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); else RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc); } -void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) +static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) { u32 agp_base_hi = upper_32_bits(agp_base); u32 agp_base_lo = agp_base & 0xffffffff; - u32 r6xx_agp_base = (agp_base >> 22) & 0x3ffff; - - /* R6xx/R7xx must be aligned to a 4MB boundry */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) - RADEON_WRITE(R700_MC_VM_AGP_BASE, r6xx_agp_base); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - RADEON_WRITE(R600_MC_VM_AGP_BASE, r6xx_agp_base); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { + + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo); RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi); - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { - RS600_WRITE_MCIND(RS600_AGP_BASE, agp_base_lo); - RS600_WRITE_MCIND(RS600_AGP_BASE_2, agp_base_hi); } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) { R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo); R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi); @@ -258,25 +145,6 @@ void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) } } -void radeon_enable_bm(struct drm_radeon_private *dev_priv) -{ - u32 tmp; - /* Turn on bus mastering */ - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { - /* rs600/rs690/rs740 */ - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { - /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); - } /* PCIE cards appears to not need this */ -} - static int RADEON_READ_PLL(struct drm_device * dev, int addr) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -434,7 +302,7 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv) if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); - RADEON_WRITE(R300_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1)); + RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1)); } RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config); radeon_do_wait_for_idle(dev_priv); @@ -514,14 +382,6 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, RS690_cp_microcode[i][0]); } - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { - DRM_INFO("Loading RS600 Microcode\n"); - for (i = 0; i < 256; i++) { - RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, - RS600_cp_microcode[i][1]); - RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, - RS600_cp_microcode[i][0]); - } } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) || @@ -702,6 +562,7 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, { struct drm_radeon_master_private *master_priv; u32 ring_start, cur_read_ptr; + u32 tmp; /* Initialize the memory controller. With new memory map, the fb location * is not changed, it should have been properly initialized already. Part @@ -750,10 +611,17 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, } else #endif { - RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, - dev_priv->ring_rptr->offset - - ((unsigned long) dev->sg->virtual) - + dev_priv->gart_vm_start); + struct drm_sg_mem *entry = dev->sg; + unsigned long tmp_ofs, page_ofs; + + tmp_ofs = dev_priv->ring_rptr->offset - + (unsigned long)dev->sg->virtual; + page_ofs = tmp_ofs >> PAGE_SHIFT; + + RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]); + DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n", + (unsigned long)entry->busaddr[page_ofs], + entry->handle + tmp_ofs); } /* Set ring buffer size */ @@ -781,17 +649,34 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) + RADEON_SCRATCH_REG_OFFSET); + dev_priv->scratch = ((__volatile__ u32 *) + dev_priv->ring_rptr->handle + + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); + RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); - radeon_enable_bm(dev_priv); + /* Turn on bus mastering */ + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { + /* rs600/rs690/rs740 */ + tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { + /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ + tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); + } /* PCIE cards appears to not need this */ - radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(0), 0); + dev_priv->scratch[0] = 0; RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); - radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); + dev_priv->scratch[1] = 0; RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0); - radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(2), 0); + dev_priv->scratch[2] = 0; RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); /* reset sarea copies of these */ @@ -823,15 +708,12 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) /* Writeback doesn't seem to work everywhere, test it here and possibly * enable it if it appears to work */ - radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); - + DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { - u32 val; - - val = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); - if (val == 0xdeadbeef) + if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) == + 0xdeadbeef) break; DRM_UDELAY(1); } @@ -927,82 +809,6 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) } } -/* Enable or disable IGP GART on the chip */ -static void rs600_set_igpgart(drm_radeon_private_t *dev_priv, int on) -{ - u32 temp; - int i; - - if (on) { - DRM_DEBUG("programming igp gart %08X %08lX %08X\n", - dev_priv->gart_vm_start, - (long)dev_priv->gart_info.bus_addr, - dev_priv->gart_size); - - IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (RS600_EFFECTIVE_L2_CACHE_SIZE(6) | - RS600_EFFECTIVE_L2_QUEUE_SIZE(6))); - - for (i = 0; i < 19; i++) - IGP_WRITE_MCIND(RS600_MC_PT0_CLIENT0_CNTL + i, - (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE | - RS600_SYSTEM_ACCESS_MODE_IN_SYS | - RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH | - RS600_EFFECTIVE_L1_CACHE_SIZE(3) | - RS600_ENABLE_FRAGMENT_PROCESSING | - RS600_EFFECTIVE_L1_QUEUE_SIZE(3))); - - IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL, (RS600_ENABLE_PAGE_TABLE | - RS600_PAGE_TABLE_TYPE_FLAT)); - - /* disable all other contexts */ - for (i = 1; i < 8; i++) - IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL + i, 0); - - /* setup the page table aperture */ - IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, - dev_priv->gart_info.bus_addr); - IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, - dev_priv->gart_vm_start); - IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, - (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); - IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); - - /* setup the system aperture */ - IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, - dev_priv->gart_vm_start); - IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, - (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); - - /* enable page tables */ - temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); - IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp | RS600_ENABLE_PT)); - - temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); - IGP_WRITE_MCIND(RS600_MC_CNTL1, (temp | RS600_ENABLE_PAGE_TABLES)); - - /* invalidate the cache */ - temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); - - temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); - IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); - temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); - - temp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE; - IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); - temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); - - temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); - IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); - temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); - - } else { - IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, 0); - temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); - temp &= ~RS600_ENABLE_PAGE_TABLES; - IGP_WRITE_MCIND(RS600_MC_CNTL1, temp); - } -} - static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) { u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); @@ -1044,11 +850,6 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) return; } - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { - rs600_set_igpgart(dev_priv, on); - return; - } - if (dev_priv->flags & RADEON_IS_PCIE) { radeon_set_pciegart(dev_priv, on); return; @@ -1080,46 +881,6 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) } } -static int radeon_setup_pcigart_surface(drm_radeon_private_t *dev_priv) -{ - struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info; - struct radeon_virt_surface *vp; - int i; - - for (i = 0; i < RADEON_MAX_SURFACES * 2; i++) { - if (!dev_priv->virt_surfaces[i].file_priv || - dev_priv->virt_surfaces[i].file_priv == PCIGART_FILE_PRIV) - break; - } - if (i >= 2 * RADEON_MAX_SURFACES) - return -ENOMEM; - vp = &dev_priv->virt_surfaces[i]; - - for (i = 0; i < RADEON_MAX_SURFACES; i++) { - struct radeon_surface *sp = &dev_priv->surfaces[i]; - if (sp->refcount) - continue; - - vp->surface_index = i; - vp->lower = gart_info->bus_addr; - vp->upper = vp->lower + gart_info->table_size; - vp->flags = 0; - vp->file_priv = PCIGART_FILE_PRIV; - - sp->refcount = 1; - sp->lower = vp->lower; - sp->upper = vp->upper; - sp->flags = 0; - - RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, sp->flags); - RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * i, sp->lower); - RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * i, sp->upper); - return 0; - } - - return -ENOMEM; -} - static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, struct drm_file *file_priv) { @@ -1301,12 +1062,11 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, } else #endif { - dev_priv->cp_ring->handle = - (void *)(unsigned long)dev_priv->cp_ring->offset; + dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset; dev_priv->ring_rptr->handle = - (void *)(unsigned long)dev_priv->ring_rptr->offset; + (void *)dev_priv->ring_rptr->offset; dev->agp_buffer_map->handle = - (void *)(unsigned long)dev->agp_buffer_map->offset; + (void *)dev->agp_buffer_map->offset; DRM_DEBUG("dev_priv->cp_ring->handle %p\n", dev_priv->cp_ring->handle); @@ -1413,14 +1173,11 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, } else #endif { - u32 sctrl; - int ret; - dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); /* if we have an offset set from userspace */ if (dev_priv->pcigart_offset_set) { dev_priv->gart_info.bus_addr = - (resource_size_t)dev_priv->pcigart_offset + dev_priv->fb_location; + dev_priv->pcigart_offset + dev_priv->fb_location; dev_priv->gart_info.mapping.offset = dev_priv->pcigart_offset + dev_priv->fb_aper_offset; dev_priv->gart_info.mapping.size = @@ -1457,31 +1214,12 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, } } - sctrl = RADEON_READ(RADEON_SURFACE_CNTL); - RADEON_WRITE(RADEON_SURFACE_CNTL, 0); - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) - ret = r600_page_table_init(dev); - else - ret = drm_ati_pcigart_init(dev, &dev_priv->gart_info); - RADEON_WRITE(RADEON_SURFACE_CNTL, sctrl); - - if (!ret) { + if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { DRM_ERROR("failed to init PCI GART!\n"); radeon_do_cleanup_cp(dev); return -ENOMEM; } - ret = radeon_setup_pcigart_surface(dev_priv); - if (ret) { - DRM_ERROR("failed to setup GART surface!\n"); - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) - r600_page_table_cleanup(dev, &dev_priv->gart_info); - else - drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info); - radeon_do_cleanup_cp(dev); - return ret; - } - /* Turn on PCI GART */ radeon_set_pcigart(dev_priv, 1); } @@ -1530,18 +1268,14 @@ static int radeon_do_cleanup_cp(struct drm_device * dev) if (dev_priv->gart_info.bus_addr) { /* Turn off PCI GART */ radeon_set_pcigart(dev_priv, 0); - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) - r600_page_table_cleanup(dev, &dev_priv->gart_info); - else { - if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) - DRM_ERROR("failed to cleanup PCI GART!\n"); - } + if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) + DRM_ERROR("failed to cleanup PCI GART!\n"); } if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); - dev_priv->gart_info.addr = NULL; + dev_priv->gart_info.addr = 0; } } /* only clear to the start of flags */ @@ -1592,7 +1326,6 @@ static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_pri int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { - drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_init_t *init = data; LOCK_TEST_WITH_RETURN(dev, file_priv); @@ -1605,13 +1338,8 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_pri case RADEON_INIT_R200_CP: case RADEON_INIT_R300_CP: return radeon_do_init_cp(dev, init, file_priv); - case RADEON_INIT_R600_CP: - return r600_do_init_cp(dev, init, file_priv); case RADEON_CLEANUP_CP: - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return r600_do_cleanup_cp(dev); - else - return radeon_do_cleanup_cp(dev); + return radeon_do_cleanup_cp(dev); } return -EINVAL; @@ -1634,10 +1362,7 @@ int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_pr return 0; } - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - r600_do_cp_start(dev_priv); - else - radeon_do_cp_start(dev_priv); + radeon_do_cp_start(dev_priv); return 0; } @@ -1668,10 +1393,7 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri * code so that the DRM ioctl wrapper can try again. */ if (stop->idle) { - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - ret = r600_do_cp_idle(dev_priv); - else - ret = radeon_do_cp_idle(dev_priv); + ret = radeon_do_cp_idle(dev_priv); if (ret) return ret; } @@ -1680,16 +1402,10 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri * we will get some dropped triangles as they won't be fully * rendered before the CP is shut down. */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - r600_do_cp_stop(dev_priv); - else - radeon_do_cp_stop(dev_priv); + radeon_do_cp_stop(dev_priv); /* Reset the engine */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - r600_do_engine_reset(dev); - else - radeon_do_engine_reset(dev); + radeon_do_engine_reset(dev); return 0; } @@ -1702,47 +1418,29 @@ void radeon_do_release(struct drm_device * dev) if (dev_priv) { if (dev_priv->cp_running) { /* Stop the cp */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { - while ((ret = r600_do_cp_idle(dev_priv)) != 0) { - DRM_DEBUG("radeon_do_cp_idle %d\n", ret); -#ifdef __linux__ - schedule(); -#else - tsleep(&ret, PZERO, "rdnrel", 1); -#endif - } - } else { - while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { - DRM_DEBUG("radeon_do_cp_idle %d\n", ret); + while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { + DRM_DEBUG("radeon_do_cp_idle %d\n", ret); #ifdef __linux__ - schedule(); + schedule(); #else - tsleep(&ret, PZERO, "rdnrel", 1); + tsleep(&ret, PZERO, "rdnrel", 1); #endif - } - } - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { - r600_do_cp_stop(dev_priv); - r600_do_engine_reset(dev); - } else { - radeon_do_cp_stop(dev_priv); - radeon_do_engine_reset(dev); } + radeon_do_cp_stop(dev_priv); + radeon_do_engine_reset(dev); } - if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) { - /* Disable *all* interrupts */ - if (dev_priv->mmio) /* remove this after permanent addmaps */ - RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); - - if (dev_priv->mmio) { /* remove all surfaces */ - for (i = 0; i < RADEON_MAX_SURFACES; i++) { - RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); - RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + - 16 * i, 0); - RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + - 16 * i, 0); - } + /* Disable *all* interrupts */ + if (dev_priv->mmio) /* remove this after permanent addmaps */ + RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); + + if (dev_priv->mmio) { /* remove all surfaces */ + for (i = 0; i < RADEON_MAX_SURFACES; i++) { + RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); + RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + + 16 * i, 0); + RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + + 16 * i, 0); } } @@ -1751,10 +1449,7 @@ void radeon_do_release(struct drm_device * dev) radeon_mem_takedown(&(dev_priv->fb_heap)); /* deallocate kernel resources */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - r600_do_cleanup_cp(dev); - else - radeon_do_cleanup_cp(dev); + radeon_do_cleanup_cp(dev); } } @@ -1772,10 +1467,7 @@ int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_pr return -EINVAL; } - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - r600_do_cp_reset(dev_priv); - else - radeon_do_cp_reset(dev_priv); + radeon_do_cp_reset(dev_priv); /* The CP is no longer running after an engine reset */ dev_priv->cp_running = 0; @@ -1790,36 +1482,23 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri LOCK_TEST_WITH_RETURN(dev, file_priv); - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return r600_do_cp_idle(dev_priv); - else - return radeon_do_cp_idle(dev_priv); + return radeon_do_cp_idle(dev_priv); } /* Added by Charl P. Botha to call radeon_do_resume_cp(). */ int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) { - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return r600_do_resume_cp(dev, file_priv); - else - return radeon_do_resume_cp(dev, file_priv); + return radeon_do_resume_cp(dev, file_priv); } int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) { - drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); LOCK_TEST_WITH_RETURN(dev, file_priv); - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return r600_do_engine_reset(dev); - else - return radeon_do_engine_reset(dev); + return radeon_do_engine_reset(dev); } /* ================================================================ @@ -1869,7 +1548,7 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev) start = dev_priv->last_buf; for (t = 0; t < dev_priv->usec_timeout; t++) { - u32 done_age = GET_SCRATCH(dev_priv, 1); + u32 done_age = GET_SCRATCH(1); DRM_DEBUG("done_age = %d\n", done_age); for (i = start; i < dma->buf_count; i++) { buf = dma->buflist[i]; @@ -1903,9 +1582,8 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev) struct drm_buf *buf; int i, t; int start; - u32 done_age; + u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)); - done_age = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); if (++dev_priv->last_buf >= dma->buf_count) dev_priv->last_buf = 0; @@ -2176,41 +1854,3 @@ int radeon_driver_unload(struct drm_device *dev) dev->dev_private = NULL; return 0; } - -void radeon_commit_ring(drm_radeon_private_t *dev_priv) -{ - int i; - u32 *ring; - int tail_aligned; - - /* check if the ring is padded out to 16-dword alignment */ - - tail_aligned = dev_priv->ring.tail & 0xf; - if (tail_aligned) { - int num_p2 = 16 - tail_aligned; - - ring = dev_priv->ring.start; - /* pad with some CP_PACKET2 */ - for (i = 0; i < num_p2; i++) - ring[dev_priv->ring.tail + i] = CP_PACKET2(); - - dev_priv->ring.tail += i; - - dev_priv->ring.space -= num_p2 * sizeof(u32); - } - - dev_priv->ring.tail &= dev_priv->ring.tail_mask; - - DRM_MEMORYBARRIER(); - GET_RING_HEAD( dev_priv ); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { - RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail); - /* read from PCI bus to ensure correct posting */ - RADEON_READ(R600_CP_RB_RPTR); - } else { - RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail); - /* read from PCI bus to ensure correct posting */ - RADEON_READ(RADEON_CP_RB_RPTR); - } -} diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.c b/trunk/drivers/gpu/drm/radeon/radeon_drv.c index 13a60f4d4227..fef207881f45 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.c @@ -41,15 +41,23 @@ int radeon_no_wb; MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); module_param_named(no_wb, radeon_no_wb, int, 0444); -static int radeon_suspend(struct drm_device *dev, pm_message_t state) +static int dri_library_name(struct drm_device *dev, char *buf) { drm_radeon_private_t *dev_priv = dev->dev_private; + int family = dev_priv->flags & RADEON_FAMILY_MASK; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return 0; + return snprintf(buf, PAGE_SIZE, "%s\n", + (family < CHIP_R200) ? "radeon" : + ((family < CHIP_R300) ? "r200" : + "r300")); +} + +static int radeon_suspend(struct drm_device *dev, pm_message_t state) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; /* Disable *all* interrupts */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) RADEON_WRITE(R500_DxMODE_INT_MASK, 0); RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); return 0; @@ -59,11 +67,8 @@ static int radeon_resume(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return 0; - /* Restore interrupt registers */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); return 0; @@ -90,6 +95,7 @@ static struct drm_driver driver = { .get_vblank_counter = radeon_get_vblank_counter, .enable_vblank = radeon_enable_vblank, .disable_vblank = radeon_disable_vblank, + .dri_library_name = dri_library_name, .master_create = radeon_master_create, .master_destroy = radeon_master_destroy, .irq_preinstall = radeon_driver_irq_preinstall, diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.h b/trunk/drivers/gpu/drm/radeon/radeon_drv.h index ed4d27e6ee6f..490bc7ceef60 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.h @@ -126,7 +126,6 @@ enum radeon_family { CHIP_RV410, CHIP_RS400, CHIP_RS480, - CHIP_RS600, CHIP_RS690, CHIP_RS740, CHIP_RV515, @@ -135,16 +134,6 @@ enum radeon_family { CHIP_RV560, CHIP_RV570, CHIP_R580, - CHIP_R600, - CHIP_RV610, - CHIP_RV630, - CHIP_RV620, - CHIP_RV635, - CHIP_RV670, - CHIP_RS780, - CHIP_RV770, - CHIP_RV730, - CHIP_RV710, CHIP_LAST, }; @@ -171,6 +160,10 @@ enum radeon_chip_flags { RADEON_IS_IGPGART = 0x01000000UL, }; +#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ + DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR)) +#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) + typedef struct drm_radeon_freelist { unsigned int age; struct drm_buf *buf; @@ -228,11 +221,10 @@ struct radeon_virt_surface { u32 upper; u32 flags; struct drm_file *file_priv; -#define PCIGART_FILE_PRIV ((void *) -1L) }; -#define RADEON_FLUSH_EMITED (1 << 0) -#define RADEON_PURGE_EMITED (1 << 1) +#define RADEON_FLUSH_EMITED (1 < 0) +#define RADEON_PURGE_EMITED (1 < 1) struct drm_radeon_master_private { drm_local_map_t *sarea; @@ -256,6 +248,7 @@ typedef struct drm_radeon_private { drm_radeon_freelist_t *head; drm_radeon_freelist_t *tail; int last_buf; + volatile u32 *scratch; int writeback_works; int usec_timeout; @@ -323,31 +316,11 @@ typedef struct drm_radeon_private { /* starting from here on, data is preserved accross an open */ uint32_t flags; /* see radeon_chip_flags */ - resource_size_t fb_aper_offset; + unsigned long fb_aper_offset; int num_gb_pipes; int track_flush; drm_local_map_t *mmio; - - /* r6xx/r7xx pipe/shader config */ - int r600_max_pipes; - int r600_max_tile_pipes; - int r600_max_simds; - int r600_max_backends; - int r600_max_gprs; - int r600_max_threads; - int r600_max_stack_entries; - int r600_max_hw_contexts; - int r600_max_gs_threads; - int r600_sx_max_export_size; - int r600_sx_max_export_pos_size; - int r600_sx_max_export_smx_size; - int r600_sq_num_cf_insts; - int r700_sx_num_of_sets; - int r700_sc_prim_fifo_size; - int r700_sc_hiz_tile_fifo_size; - int r700_sc_earlyz_tile_fifo_fize; - } drm_radeon_private_t; typedef struct drm_radeon_buf_priv { @@ -365,12 +338,6 @@ extern int radeon_no_wb; extern struct drm_ioctl_desc radeon_ioctls[]; extern int radeon_max_ioctl; -extern u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv); -extern void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val); - -#define GET_RING_HEAD(dev_priv) radeon_get_ring_head(dev_priv) -#define SET_RING_HEAD(dev_priv, val) radeon_set_ring_head(dev_priv, val) - /* Check whether the given hardware address is inside the framebuffer or the * GART area. */ @@ -397,9 +364,6 @@ extern int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_fi extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv); -extern void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc); -extern void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base); -extern u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr); extern void radeon_freelist_reset(struct drm_device * dev); extern struct drm_buf *radeon_freelist_get(struct drm_device * dev); @@ -419,10 +383,6 @@ extern void radeon_mem_takedown(struct mem_block **heap); extern void radeon_mem_release(struct drm_file *file_priv, struct mem_block *heap); -extern void radeon_enable_bm(struct drm_radeon_private *dev_priv); -extern u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off); -extern void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val); - /* radeon_irq.c */ extern void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state); extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -463,21 +423,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, struct drm_file *file_priv, drm_radeon_kcmd_buffer_t *cmdbuf); -/* r600_cp.c */ -extern int r600_do_engine_reset(struct drm_device *dev); -extern int r600_do_cleanup_cp(struct drm_device *dev); -extern int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, - struct drm_file *file_priv); -extern int r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv); -extern int r600_do_cp_idle(drm_radeon_private_t *dev_priv); -extern void r600_do_cp_start(drm_radeon_private_t *dev_priv); -extern void r600_do_cp_reset(drm_radeon_private_t *dev_priv); -extern void r600_do_cp_stop(drm_radeon_private_t *dev_priv); -extern int r600_cp_dispatch_indirect(struct drm_device *dev, - struct drm_buf *buf, int start, int end); -extern int r600_page_table_init(struct drm_device *dev); -extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info); - /* Flags for stats.boxes */ #define RADEON_BOX_DMA_IDLE 0x1 @@ -489,8 +434,6 @@ extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pciga /* Register definitions, register access macros and drmAddMap constants * for Radeon kernel driver. */ -#define RADEON_MM_INDEX 0x0000 -#define RADEON_MM_DATA 0x0004 #define RADEON_AGP_COMMAND 0x0f60 #define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */ @@ -613,56 +556,6 @@ extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pciga #define RS690_MC_AGP_BASE 0x102 #define RS690_MC_AGP_BASE_2 0x103 -#define RS600_MC_INDEX 0x70 -# define RS600_MC_ADDR_MASK 0xffff -# define RS600_MC_IND_SEQ_RBS_0 (1 << 16) -# define RS600_MC_IND_SEQ_RBS_1 (1 << 17) -# define RS600_MC_IND_SEQ_RBS_2 (1 << 18) -# define RS600_MC_IND_SEQ_RBS_3 (1 << 19) -# define RS600_MC_IND_AIC_RBS (1 << 20) -# define RS600_MC_IND_CITF_ARB0 (1 << 21) -# define RS600_MC_IND_CITF_ARB1 (1 << 22) -# define RS600_MC_IND_WR_EN (1 << 23) -#define RS600_MC_DATA 0x74 - -#define RS600_MC_STATUS 0x0 -# define RS600_MC_IDLE (1 << 1) -#define RS600_MC_FB_LOCATION 0x4 -#define RS600_MC_AGP_LOCATION 0x5 -#define RS600_AGP_BASE 0x6 -#define RS600_AGP_BASE_2 0x7 -#define RS600_MC_CNTL1 0x9 -# define RS600_ENABLE_PAGE_TABLES (1 << 26) -#define RS600_MC_PT0_CNTL 0x100 -# define RS600_ENABLE_PT (1 << 0) -# define RS600_EFFECTIVE_L2_CACHE_SIZE(x) ((x) << 15) -# define RS600_EFFECTIVE_L2_QUEUE_SIZE(x) ((x) << 21) -# define RS600_INVALIDATE_ALL_L1_TLBS (1 << 28) -# define RS600_INVALIDATE_L2_CACHE (1 << 29) -#define RS600_MC_PT0_CONTEXT0_CNTL 0x102 -# define RS600_ENABLE_PAGE_TABLE (1 << 0) -# define RS600_PAGE_TABLE_TYPE_FLAT (0 << 1) -#define RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR 0x112 -#define RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR 0x114 -#define RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR 0x11c -#define RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR 0x12c -#define RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR 0x13c -#define RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR 0x14c -#define RS600_MC_PT0_CLIENT0_CNTL 0x16c -# define RS600_ENABLE_TRANSLATION_MODE_OVERRIDE (1 << 0) -# define RS600_TRANSLATION_MODE_OVERRIDE (1 << 1) -# define RS600_SYSTEM_ACCESS_MODE_MASK (3 << 8) -# define RS600_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 8) -# define RS600_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 8) -# define RS600_SYSTEM_ACCESS_MODE_IN_SYS (2 << 8) -# define RS600_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 8) -# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH (0 << 10) -# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 10) -# define RS600_EFFECTIVE_L1_CACHE_SIZE(x) ((x) << 11) -# define RS600_ENABLE_FRAGMENT_PROCESSING (1 << 14) -# define RS600_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15) -# define RS600_INVALIDATE_L1_TLB (1 << 20) - #define R520_MC_IND_INDEX 0x70 #define R520_MC_IND_WR_EN (1 << 24) #define R520_MC_IND_DATA 0x74 @@ -687,6 +580,7 @@ extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pciga /* pipe config regs */ #define R400_GB_PIPE_SELECT 0x402c #define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */ +#define R500_SU_REG_DEST 0x42c8 #define R300_GB_TILE_CONFIG 0x4018 # define R300_ENABLE_TILING (1 << 0) # define R300_PIPE_COUNT_RV350 (0 << 1) @@ -745,22 +639,9 @@ extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pciga #define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) -extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); - -#define GET_SCRATCH(dev_priv, x) radeon_get_scratch(dev_priv, x) - -#define R600_SCRATCH_REG0 0x8500 -#define R600_SCRATCH_REG1 0x8504 -#define R600_SCRATCH_REG2 0x8508 -#define R600_SCRATCH_REG3 0x850c -#define R600_SCRATCH_REG4 0x8510 -#define R600_SCRATCH_REG5 0x8514 -#define R600_SCRATCH_REG6 0x8518 -#define R600_SCRATCH_REG7 0x851c -#define R600_SCRATCH_UMSK 0x8540 -#define R600_SCRATCH_ADDR 0x8544 - -#define R600_SCRATCHOFF(x) (R600_SCRATCH_REG_OFFSET + 4*(x)) +#define GET_SCRATCH( x ) (dev_priv->writeback_works \ + ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ + : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) #define RADEON_GEN_INT_CNTL 0x0040 # define RADEON_CRTC_VBLANK_MASK (1 << 0) @@ -1041,7 +922,6 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); #define RADEON_CP_RB_CNTL 0x0704 # define RADEON_BUF_SWAP_32BIT (2 << 16) # define RADEON_RB_NO_UPDATE (1 << 27) -# define RADEON_RB_RPTR_WR_ENA (1 << 31) #define RADEON_CP_RB_RPTR_ADDR 0x070c #define RADEON_CP_RB_RPTR 0x0710 #define RADEON_CP_RB_WPTR 0x0714 @@ -1103,14 +983,6 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); # define RADEON_CNTL_BITBLT_MULTI 0x00009B00 # define RADEON_CNTL_SET_SCISSORS 0xC0001E00 -# define R600_IT_INDIRECT_BUFFER 0x00003200 -# define R600_IT_ME_INITIALIZE 0x00004400 -# define R600_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) -# define R600_IT_EVENT_WRITE 0x00004600 -# define R600_IT_SET_CONFIG_REG 0x00006800 -# define R600_SET_CONFIG_REG_OFFSET 0x00008000 -# define R600_SET_CONFIG_REG_END 0x0000ac00 - #define RADEON_CP_PACKET_MASK 0xC0000000 #define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 #define RADEON_CP_PACKET0_REG_MASK 0x000007ff @@ -1309,422 +1181,6 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); #define R500_D1_VBLANK_INTERRUPT (1 << 4) #define R500_D2_VBLANK_INTERRUPT (1 << 5) -/* R6xx/R7xx registers */ -#define R600_MC_VM_FB_LOCATION 0x2180 -#define R600_MC_VM_AGP_TOP 0x2184 -#define R600_MC_VM_AGP_BOT 0x2188 -#define R600_MC_VM_AGP_BASE 0x218c -#define R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2190 -#define R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2194 -#define R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x2198 - -#define R700_MC_VM_FB_LOCATION 0x2024 -#define R700_MC_VM_AGP_TOP 0x2028 -#define R700_MC_VM_AGP_BOT 0x202c -#define R700_MC_VM_AGP_BASE 0x2030 -#define R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 -#define R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 -#define R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203c - -#define R600_MCD_RD_A_CNTL 0x219c -#define R600_MCD_RD_B_CNTL 0x21a0 - -#define R600_MCD_WR_A_CNTL 0x21a4 -#define R600_MCD_WR_B_CNTL 0x21a8 - -#define R600_MCD_RD_SYS_CNTL 0x2200 -#define R600_MCD_WR_SYS_CNTL 0x2214 - -#define R600_MCD_RD_GFX_CNTL 0x21fc -#define R600_MCD_RD_HDP_CNTL 0x2204 -#define R600_MCD_RD_PDMA_CNTL 0x2208 -#define R600_MCD_RD_SEM_CNTL 0x220c -#define R600_MCD_WR_GFX_CNTL 0x2210 -#define R600_MCD_WR_HDP_CNTL 0x2218 -#define R600_MCD_WR_PDMA_CNTL 0x221c -#define R600_MCD_WR_SEM_CNTL 0x2220 - -# define R600_MCD_L1_TLB (1 << 0) -# define R600_MCD_L1_FRAG_PROC (1 << 1) -# define R600_MCD_L1_STRICT_ORDERING (1 << 2) - -# define R600_MCD_SYSTEM_ACCESS_MODE_MASK (3 << 6) -# define R600_MCD_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 6) -# define R600_MCD_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 6) -# define R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS (2 << 6) -# define R600_MCD_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 6) - -# define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 8) -# define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 8) - -# define R600_MCD_SEMAPHORE_MODE (1 << 10) -# define R600_MCD_WAIT_L2_QUERY (1 << 11) -# define R600_MCD_EFFECTIVE_L1_TLB_SIZE(x) ((x) << 12) -# define R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15) - -#define R700_MC_VM_MD_L1_TLB0_CNTL 0x2654 -#define R700_MC_VM_MD_L1_TLB1_CNTL 0x2658 -#define R700_MC_VM_MD_L1_TLB2_CNTL 0x265c - -#define R700_MC_VM_MB_L1_TLB0_CNTL 0x2234 -#define R700_MC_VM_MB_L1_TLB1_CNTL 0x2238 -#define R700_MC_VM_MB_L1_TLB2_CNTL 0x223c -#define R700_MC_VM_MB_L1_TLB3_CNTL 0x2240 - -# define R700_ENABLE_L1_TLB (1 << 0) -# define R700_ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) -# define R700_SYSTEM_ACCESS_MODE_IN_SYS (2 << 3) -# define R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5) -# define R700_EFFECTIVE_L1_TLB_SIZE(x) ((x) << 15) -# define R700_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 18) - -#define R700_MC_ARB_RAMCFG 0x2760 -# define R700_NOOFBANK_SHIFT 0 -# define R700_NOOFBANK_MASK 0x3 -# define R700_NOOFRANK_SHIFT 2 -# define R700_NOOFRANK_MASK 0x1 -# define R700_NOOFROWS_SHIFT 3 -# define R700_NOOFROWS_MASK 0x7 -# define R700_NOOFCOLS_SHIFT 6 -# define R700_NOOFCOLS_MASK 0x3 -# define R700_CHANSIZE_SHIFT 8 -# define R700_CHANSIZE_MASK 0x1 -# define R700_BURSTLENGTH_SHIFT 9 -# define R700_BURSTLENGTH_MASK 0x1 -#define R600_RAMCFG 0x2408 -# define R600_NOOFBANK_SHIFT 0 -# define R600_NOOFBANK_MASK 0x1 -# define R600_NOOFRANK_SHIFT 1 -# define R600_NOOFRANK_MASK 0x1 -# define R600_NOOFROWS_SHIFT 2 -# define R600_NOOFROWS_MASK 0x7 -# define R600_NOOFCOLS_SHIFT 5 -# define R600_NOOFCOLS_MASK 0x3 -# define R600_CHANSIZE_SHIFT 7 -# define R600_CHANSIZE_MASK 0x1 -# define R600_BURSTLENGTH_SHIFT 8 -# define R600_BURSTLENGTH_MASK 0x1 - -#define R600_VM_L2_CNTL 0x1400 -# define R600_VM_L2_CACHE_EN (1 << 0) -# define R600_VM_L2_FRAG_PROC (1 << 1) -# define R600_VM_ENABLE_PTE_CACHE_LRU_W (1 << 9) -# define R600_VM_L2_CNTL_QUEUE_SIZE(x) ((x) << 13) -# define R700_VM_L2_CNTL_QUEUE_SIZE(x) ((x) << 14) - -#define R600_VM_L2_CNTL2 0x1404 -# define R600_VM_L2_CNTL2_INVALIDATE_ALL_L1_TLBS (1 << 0) -# define R600_VM_L2_CNTL2_INVALIDATE_L2_CACHE (1 << 1) -#define R600_VM_L2_CNTL3 0x1408 -# define R600_VM_L2_CNTL3_BANK_SELECT_0(x) ((x) << 0) -# define R600_VM_L2_CNTL3_BANK_SELECT_1(x) ((x) << 5) -# define R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(x) ((x) << 10) -# define R700_VM_L2_CNTL3_BANK_SELECT(x) ((x) << 0) -# define R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(x) ((x) << 6) - -#define R600_VM_L2_STATUS 0x140c - -#define R600_VM_CONTEXT0_CNTL 0x1410 -# define R600_VM_ENABLE_CONTEXT (1 << 0) -# define R600_VM_PAGE_TABLE_DEPTH_FLAT (0 << 1) - -#define R600_VM_CONTEXT0_CNTL2 0x1430 -#define R600_VM_CONTEXT0_REQUEST_RESPONSE 0x1470 -#define R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR 0x1490 -#define R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR 0x14b0 -#define R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x1574 -#define R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x1594 -#define R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x15b4 - -#define R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153c -#define R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155c -#define R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157c - -#define R600_HDP_HOST_PATH_CNTL 0x2c00 - -#define R600_GRBM_CNTL 0x8000 -# define R600_GRBM_READ_TIMEOUT(x) ((x) << 0) - -#define R600_GRBM_STATUS 0x8010 -# define R600_CMDFIFO_AVAIL_MASK 0x1f -# define R700_CMDFIFO_AVAIL_MASK 0xf -# define R600_GUI_ACTIVE (1 << 31) -#define R600_GRBM_STATUS2 0x8014 -#define R600_GRBM_SOFT_RESET 0x8020 -# define R600_SOFT_RESET_CP (1 << 0) -#define R600_WAIT_UNTIL 0x8040 - -#define R600_CP_SEM_WAIT_TIMER 0x85bc -#define R600_CP_ME_CNTL 0x86d8 -# define R600_CP_ME_HALT (1 << 28) -#define R600_CP_QUEUE_THRESHOLDS 0x8760 -# define R600_ROQ_IB1_START(x) ((x) << 0) -# define R600_ROQ_IB2_START(x) ((x) << 8) -#define R600_CP_MEQ_THRESHOLDS 0x8764 -# define R700_STQ_SPLIT(x) ((x) << 0) -# define R600_MEQ_END(x) ((x) << 16) -# define R600_ROQ_END(x) ((x) << 24) -#define R600_CP_PERFMON_CNTL 0x87fc -#define R600_CP_RB_BASE 0xc100 -#define R600_CP_RB_CNTL 0xc104 -# define R600_RB_BUFSZ(x) ((x) << 0) -# define R600_RB_BLKSZ(x) ((x) << 8) -# define R600_RB_NO_UPDATE (1 << 27) -# define R600_RB_RPTR_WR_ENA (1 << 31) -#define R600_CP_RB_RPTR_WR 0xc108 -#define R600_CP_RB_RPTR_ADDR 0xc10c -#define R600_CP_RB_RPTR_ADDR_HI 0xc110 -#define R600_CP_RB_WPTR 0xc114 -#define R600_CP_RB_WPTR_ADDR 0xc118 -#define R600_CP_RB_WPTR_ADDR_HI 0xc11c -#define R600_CP_RB_RPTR 0x8700 -#define R600_CP_RB_WPTR_DELAY 0x8704 -#define R600_CP_PFP_UCODE_ADDR 0xc150 -#define R600_CP_PFP_UCODE_DATA 0xc154 -#define R600_CP_ME_RAM_RADDR 0xc158 -#define R600_CP_ME_RAM_WADDR 0xc15c -#define R600_CP_ME_RAM_DATA 0xc160 -#define R600_CP_DEBUG 0xc1fc - -#define R600_PA_CL_ENHANCE 0x8a14 -# define R600_CLIP_VTX_REORDER_ENA (1 << 0) -# define R600_NUM_CLIP_SEQ(x) ((x) << 1) -#define R600_PA_SC_LINE_STIPPLE_STATE 0x8b10 -#define R600_PA_SC_MULTI_CHIP_CNTL 0x8b20 -#define R700_PA_SC_FORCE_EOV_MAX_CNTS 0x8b24 -# define R700_FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) -# define R700_FORCE_EOV_MAX_REZ_CNT(x) ((x) << 16) -#define R600_PA_SC_AA_SAMPLE_LOCS_2S 0x8b40 -#define R600_PA_SC_AA_SAMPLE_LOCS_4S 0x8b44 -#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0 0x8b48 -#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1 0x8b4c -# define R600_S0_X(x) ((x) << 0) -# define R600_S0_Y(x) ((x) << 4) -# define R600_S1_X(x) ((x) << 8) -# define R600_S1_Y(x) ((x) << 12) -# define R600_S2_X(x) ((x) << 16) -# define R600_S2_Y(x) ((x) << 20) -# define R600_S3_X(x) ((x) << 24) -# define R600_S3_Y(x) ((x) << 28) -# define R600_S4_X(x) ((x) << 0) -# define R600_S4_Y(x) ((x) << 4) -# define R600_S5_X(x) ((x) << 8) -# define R600_S5_Y(x) ((x) << 12) -# define R600_S6_X(x) ((x) << 16) -# define R600_S6_Y(x) ((x) << 20) -# define R600_S7_X(x) ((x) << 24) -# define R600_S7_Y(x) ((x) << 28) -#define R600_PA_SC_FIFO_SIZE 0x8bd0 -# define R600_SC_PRIM_FIFO_SIZE(x) ((x) << 0) -# define R600_SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 8) -# define R600_SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 16) -#define R700_PA_SC_FIFO_SIZE_R7XX 0x8bcc -# define R700_SC_PRIM_FIFO_SIZE(x) ((x) << 0) -# define R700_SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 12) -# define R700_SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 20) -#define R600_PA_SC_ENHANCE 0x8bf0 -# define R600_FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) -# define R600_FORCE_EOV_MAX_TILE_CNT(x) ((x) << 12) -#define R600_PA_SC_CLIPRECT_RULE 0x2820c -#define R700_PA_SC_EDGERULE 0x28230 -#define R600_PA_SC_LINE_STIPPLE 0x28a0c -#define R600_PA_SC_MODE_CNTL 0x28a4c -#define R600_PA_SC_AA_CONFIG 0x28c04 - -#define R600_SX_EXPORT_BUFFER_SIZES 0x900c -# define R600_COLOR_BUFFER_SIZE(x) ((x) << 0) -# define R600_POSITION_BUFFER_SIZE(x) ((x) << 8) -# define R600_SMX_BUFFER_SIZE(x) ((x) << 16) -#define R600_SX_DEBUG_1 0x9054 -# define R600_SMX_EVENT_RELEASE (1 << 0) -# define R600_ENABLE_NEW_SMX_ADDRESS (1 << 16) -#define R700_SX_DEBUG_1 0x9058 -# define R700_ENABLE_NEW_SMX_ADDRESS (1 << 16) -#define R600_SX_MISC 0x28350 - -#define R600_DB_DEBUG 0x9830 -# define R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31) -#define R600_DB_WATERMARKS 0x9838 -# define R600_DEPTH_FREE(x) ((x) << 0) -# define R600_DEPTH_FLUSH(x) ((x) << 5) -# define R600_DEPTH_PENDING_FREE(x) ((x) << 15) -# define R600_DEPTH_CACHELINE_FREE(x) ((x) << 20) -#define R700_DB_DEBUG3 0x98b0 -# define R700_DB_CLK_OFF_DELAY(x) ((x) << 11) -#define RV700_DB_DEBUG4 0x9b8c -# define RV700_DISABLE_TILE_COVERED_FOR_PS_ITER (1 << 6) - -#define R600_VGT_CACHE_INVALIDATION 0x88c4 -# define R600_CACHE_INVALIDATION(x) ((x) << 0) -# define R600_VC_ONLY 0 -# define R600_TC_ONLY 1 -# define R600_VC_AND_TC 2 -# define R700_AUTO_INVLD_EN(x) ((x) << 6) -# define R700_NO_AUTO 0 -# define R700_ES_AUTO 1 -# define R700_GS_AUTO 2 -# define R700_ES_AND_GS_AUTO 3 -#define R600_VGT_GS_PER_ES 0x88c8 -#define R600_VGT_ES_PER_GS 0x88cc -#define R600_VGT_GS_PER_VS 0x88e8 -#define R600_VGT_GS_VERTEX_REUSE 0x88d4 -#define R600_VGT_NUM_INSTANCES 0x8974 -#define R600_VGT_STRMOUT_EN 0x28ab0 -#define R600_VGT_EVENT_INITIATOR 0x28a90 -# define R600_CACHE_FLUSH_AND_INV_EVENT (0x16 << 0) -#define R600_VGT_VERTEX_REUSE_BLOCK_CNTL 0x28c58 -# define R600_VTX_REUSE_DEPTH_MASK 0xff -#define R600_VGT_OUT_DEALLOC_CNTL 0x28c5c -# define R600_DEALLOC_DIST_MASK 0x7f - -#define R600_CB_COLOR0_BASE 0x28040 -#define R600_CB_COLOR1_BASE 0x28044 -#define R600_CB_COLOR2_BASE 0x28048 -#define R600_CB_COLOR3_BASE 0x2804c -#define R600_CB_COLOR4_BASE 0x28050 -#define R600_CB_COLOR5_BASE 0x28054 -#define R600_CB_COLOR6_BASE 0x28058 -#define R600_CB_COLOR7_BASE 0x2805c -#define R600_CB_COLOR7_FRAG 0x280fc - -#define R600_TC_CNTL 0x9608 -# define R600_TC_L2_SIZE(x) ((x) << 5) -# define R600_L2_DISABLE_LATE_HIT (1 << 9) - -#define R600_ARB_POP 0x2418 -# define R600_ENABLE_TC128 (1 << 30) -#define R600_ARB_GDEC_RD_CNTL 0x246c - -#define R600_TA_CNTL_AUX 0x9508 -# define R600_DISABLE_CUBE_WRAP (1 << 0) -# define R600_DISABLE_CUBE_ANISO (1 << 1) -# define R700_GETLOD_SELECT(x) ((x) << 2) -# define R600_SYNC_GRADIENT (1 << 24) -# define R600_SYNC_WALKER (1 << 25) -# define R600_SYNC_ALIGNER (1 << 26) -# define R600_BILINEAR_PRECISION_6_BIT (0 << 31) -# define R600_BILINEAR_PRECISION_8_BIT (1 << 31) - -#define R700_TCP_CNTL 0x9610 - -#define R600_SMX_DC_CTL0 0xa020 -# define R700_USE_HASH_FUNCTION (1 << 0) -# define R700_CACHE_DEPTH(x) ((x) << 1) -# define R700_FLUSH_ALL_ON_EVENT (1 << 10) -# define R700_STALL_ON_EVENT (1 << 11) -#define R700_SMX_EVENT_CTL 0xa02c -# define R700_ES_FLUSH_CTL(x) ((x) << 0) -# define R700_GS_FLUSH_CTL(x) ((x) << 3) -# define R700_ACK_FLUSH_CTL(x) ((x) << 6) -# define R700_SYNC_FLUSH_CTL (1 << 8) - -#define R600_SQ_CONFIG 0x8c00 -# define R600_VC_ENABLE (1 << 0) -# define R600_EXPORT_SRC_C (1 << 1) -# define R600_DX9_CONSTS (1 << 2) -# define R600_ALU_INST_PREFER_VECTOR (1 << 3) -# define R600_DX10_CLAMP (1 << 4) -# define R600_CLAUSE_SEQ_PRIO(x) ((x) << 8) -# define R600_PS_PRIO(x) ((x) << 24) -# define R600_VS_PRIO(x) ((x) << 26) -# define R600_GS_PRIO(x) ((x) << 28) -# define R600_ES_PRIO(x) ((x) << 30) -#define R600_SQ_GPR_RESOURCE_MGMT_1 0x8c04 -# define R600_NUM_PS_GPRS(x) ((x) << 0) -# define R600_NUM_VS_GPRS(x) ((x) << 16) -# define R700_DYN_GPR_ENABLE (1 << 27) -# define R600_NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28) -#define R600_SQ_GPR_RESOURCE_MGMT_2 0x8c08 -# define R600_NUM_GS_GPRS(x) ((x) << 0) -# define R600_NUM_ES_GPRS(x) ((x) << 16) -#define R600_SQ_THREAD_RESOURCE_MGMT 0x8c0c -# define R600_NUM_PS_THREADS(x) ((x) << 0) -# define R600_NUM_VS_THREADS(x) ((x) << 8) -# define R600_NUM_GS_THREADS(x) ((x) << 16) -# define R600_NUM_ES_THREADS(x) ((x) << 24) -#define R600_SQ_STACK_RESOURCE_MGMT_1 0x8c10 -# define R600_NUM_PS_STACK_ENTRIES(x) ((x) << 0) -# define R600_NUM_VS_STACK_ENTRIES(x) ((x) << 16) -#define R600_SQ_STACK_RESOURCE_MGMT_2 0x8c14 -# define R600_NUM_GS_STACK_ENTRIES(x) ((x) << 0) -# define R600_NUM_ES_STACK_ENTRIES(x) ((x) << 16) -#define R600_SQ_MS_FIFO_SIZES 0x8cf0 -# define R600_CACHE_FIFO_SIZE(x) ((x) << 0) -# define R600_FETCH_FIFO_HIWATER(x) ((x) << 8) -# define R600_DONE_FIFO_HIWATER(x) ((x) << 16) -# define R600_ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24) -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_0 0x8db0 -# define R700_SIMDA_RING0(x) ((x) << 0) -# define R700_SIMDA_RING1(x) ((x) << 8) -# define R700_SIMDB_RING0(x) ((x) << 16) -# define R700_SIMDB_RING1(x) ((x) << 24) -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_1 0x8db4 -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_2 0x8db8 -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_3 0x8dbc -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_4 0x8dc0 -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_5 0x8dc4 -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_6 0x8dc8 -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_7 0x8dcc - -#define R600_SPI_PS_IN_CONTROL_0 0x286cc -# define R600_NUM_INTERP(x) ((x) << 0) -# define R600_POSITION_ENA (1 << 8) -# define R600_POSITION_CENTROID (1 << 9) -# define R600_POSITION_ADDR(x) ((x) << 10) -# define R600_PARAM_GEN(x) ((x) << 15) -# define R600_PARAM_GEN_ADDR(x) ((x) << 19) -# define R600_BARYC_SAMPLE_CNTL(x) ((x) << 26) -# define R600_PERSP_GRADIENT_ENA (1 << 28) -# define R600_LINEAR_GRADIENT_ENA (1 << 29) -# define R600_POSITION_SAMPLE (1 << 30) -# define R600_BARYC_AT_SAMPLE_ENA (1 << 31) -#define R600_SPI_PS_IN_CONTROL_1 0x286d0 -# define R600_GEN_INDEX_PIX (1 << 0) -# define R600_GEN_INDEX_PIX_ADDR(x) ((x) << 1) -# define R600_FRONT_FACE_ENA (1 << 8) -# define R600_FRONT_FACE_CHAN(x) ((x) << 9) -# define R600_FRONT_FACE_ALL_BITS (1 << 11) -# define R600_FRONT_FACE_ADDR(x) ((x) << 12) -# define R600_FOG_ADDR(x) ((x) << 17) -# define R600_FIXED_PT_POSITION_ENA (1 << 24) -# define R600_FIXED_PT_POSITION_ADDR(x) ((x) << 25) -# define R700_POSITION_ULC (1 << 30) -#define R600_SPI_INPUT_Z 0x286d8 - -#define R600_SPI_CONFIG_CNTL 0x9100 -# define R600_GPR_WRITE_PRIORITY(x) ((x) << 0) -# define R600_DISABLE_INTERP_1 (1 << 5) -#define R600_SPI_CONFIG_CNTL_1 0x913c -# define R600_VTX_DONE_DELAY(x) ((x) << 0) -# define R600_INTERP_ONE_PRIM_PER_ROW (1 << 4) - -#define R600_GB_TILING_CONFIG 0x98f0 -# define R600_PIPE_TILING(x) ((x) << 1) -# define R600_BANK_TILING(x) ((x) << 4) -# define R600_GROUP_SIZE(x) ((x) << 6) -# define R600_ROW_TILING(x) ((x) << 8) -# define R600_BANK_SWAPS(x) ((x) << 11) -# define R600_SAMPLE_SPLIT(x) ((x) << 14) -# define R600_BACKEND_MAP(x) ((x) << 16) -#define R600_DCP_TILING_CONFIG 0x6ca0 -#define R600_HDP_TILING_CONFIG 0x2f3c - -#define R600_CC_RB_BACKEND_DISABLE 0x98f4 -#define R700_CC_SYS_RB_BACKEND_DISABLE 0x3f88 -# define R600_BACKEND_DISABLE(x) ((x) << 16) - -#define R600_CC_GC_SHADER_PIPE_CONFIG 0x8950 -#define R600_GC_USER_SHADER_PIPE_CONFIG 0x8954 -# define R600_INACTIVE_QD_PIPES(x) ((x) << 8) -# define R600_INACTIVE_QD_PIPES_MASK (0xff << 8) -# define R600_INACTIVE_SIMDS(x) ((x) << 16) -# define R600_INACTIVE_SIMDS_MASK (0xff << 16) - -#define R700_CGTS_SYS_TCC_DISABLE 0x3f90 -#define R700_CGTS_USER_SYS_TCC_DISABLE 0x3f94 -#define R700_CGTS_TCC_DISABLE 0x9148 -#define R700_CGTS_USER_TCC_DISABLE 0x914c - /* Constants */ #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ @@ -1734,11 +1190,6 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); #define RADEON_LAST_SWI_REG RADEON_SCRATCH_REG3 #define RADEON_LAST_DISPATCH 1 -#define R600_LAST_FRAME_REG R600_SCRATCH_REG0 -#define R600_LAST_DISPATCH_REG R600_SCRATCH_REG1 -#define R600_LAST_CLEAR_REG R600_SCRATCH_REG2 -#define R600_LAST_SWI_REG R600_SCRATCH_REG3 - #define RADEON_MAX_VB_AGE 0x7fffffff #define RADEON_MAX_VB_VERTS (0xffff) @@ -1747,15 +1198,7 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); #define RADEON_PCIGART_TABLE_SIZE (32*1024) #define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) -#define RADEON_WRITE(reg, val) \ -do { \ - if (reg < 0x10000) { \ - DRM_WRITE32(dev_priv->mmio, (reg), (val)); \ - } else { \ - DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, (reg)); \ - DRM_WRITE32(dev_priv->mmio, RADEON_MM_DATA, (val)); \ - } \ -} while (0) +#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) #define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) #define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) @@ -1795,19 +1238,11 @@ do { \ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \ } while (0) -#define RS600_WRITE_MCIND(addr, val) \ -do { \ - RADEON_WRITE(RS600_MC_INDEX, RS600_MC_IND_WR_EN | RS600_MC_IND_CITF_ARB0 | ((addr) & RS600_MC_ADDR_MASK)); \ - RADEON_WRITE(RS600_MC_DATA, val); \ -} while (0) - #define IGP_WRITE_MCIND(addr, val) \ do { \ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || \ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \ RS690_WRITE_MCIND(addr, val); \ - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) \ - RS600_WRITE_MCIND(addr, val); \ else \ RS480_WRITE_MCIND(addr, val); \ } while (0) @@ -1911,11 +1346,7 @@ do { \ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; \ drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; \ if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \ - int __ret; \ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) \ - __ret = r600_do_cp_idle(dev_priv); \ - else \ - __ret = radeon_do_cp_idle(dev_priv); \ + int __ret = radeon_do_cp_idle( dev_priv ); \ if ( __ret ) return __ret; \ sarea_priv->last_dispatch = 0; \ radeon_freelist_reset( dev ); \ @@ -1937,40 +1368,21 @@ do { \ OUT_RING( age ); \ } while (0) -#define R600_DISPATCH_AGE(age) do { \ - OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ - OUT_RING((R600_LAST_DISPATCH_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ - OUT_RING(age); \ -} while (0) - -#define R600_FRAME_AGE(age) do { \ - OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ - OUT_RING((R600_LAST_FRAME_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ - OUT_RING(age); \ -} while (0) - -#define R600_CLEAR_AGE(age) do { \ - OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ - OUT_RING((R600_LAST_CLEAR_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ - OUT_RING(age); \ -} while (0) - /* ================================================================ * Ring control */ #define RADEON_VERBOSE 0 -#define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring; +#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring; #define BEGIN_RING( n ) do { \ if ( RADEON_VERBOSE ) { \ DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ } \ - _align_nr = (n + 0xf) & ~0xf; \ - if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \ + if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ COMMIT_RING(); \ - radeon_wait_ring( dev_priv, _align_nr * sizeof(u32)); \ + radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \ } \ _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ ring = dev_priv->ring.start; \ @@ -1987,16 +1399,19 @@ do { \ DRM_ERROR( \ "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ ((dev_priv->ring.tail + _nr) & mask), \ - write, __LINE__); \ + write, __LINE__); \ } else \ dev_priv->ring.tail = write; \ } while (0) -extern void radeon_commit_ring(drm_radeon_private_t *dev_priv); - #define COMMIT_RING() do { \ - radeon_commit_ring(dev_priv); \ - } while(0) + /* Flush writes to ring */ \ + DRM_MEMORYBARRIER(); \ + GET_RING_HEAD( dev_priv ); \ + RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ + /* read from PCI bus to ensure correct posting */ \ + RADEON_READ( RADEON_CP_RB_RPTR ); \ +} while (0) #define OUT_RING( x ) do { \ if ( RADEON_VERBOSE ) { \ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_irq.c b/trunk/drivers/gpu/drm/radeon/radeon_irq.c index 9836c705a952..8289e16419a8 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_irq.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_irq.c @@ -65,7 +65,7 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc) { drm_radeon_private_t *dev_priv = dev->dev_private; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { switch (crtc) { case 0: r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1); @@ -100,7 +100,7 @@ void radeon_disable_vblank(struct drm_device *dev, int crtc) { drm_radeon_private_t *dev_priv = dev->dev_private; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { switch (crtc) { case 0: r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0); @@ -135,7 +135,7 @@ static inline u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r u32 irq_mask = RADEON_SW_INT_TEST; *r500_disp_int = 0; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { /* vbl interrupts in a different place */ if (irqs & R500_DISPLAY_INT_STATUS) { @@ -202,7 +202,7 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) DRM_WAKEUP(&dev_priv->swi_queue); /* VBLANK interrupt */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { if (r500_disp_int & R500_D1_VBLANK_INTERRUPT) drm_handle_vblank(dev, 0); if (r500_disp_int & R500_D2_VBLANK_INTERRUPT) @@ -265,7 +265,7 @@ u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc) return -EINVAL; } - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { if (crtc == 0) return RADEON_READ(R500_D1CRTC_FRAME_COUNT); else @@ -327,7 +327,7 @@ void radeon_driver_irq_preinstall(struct drm_device * dev) u32 dummy; /* Disable *all* interrupts */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) RADEON_WRITE(R500_DxMODE_INT_MASK, 0); RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); @@ -357,7 +357,7 @@ void radeon_driver_irq_uninstall(struct drm_device * dev) if (!dev_priv) return; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) RADEON_WRITE(R500_DxMODE_INT_MASK, 0); /* Disable *all* interrupts */ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_state.c b/trunk/drivers/gpu/drm/radeon/radeon_state.c index fa728ec6ed34..ef940a079dcb 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_state.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_state.c @@ -1556,15 +1556,9 @@ static void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master * buf_priv->age = ++master_priv->sarea_priv->last_dispatch; /* Emit the vertex buffer age */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { - BEGIN_RING(3); - R600_DISPATCH_AGE(buf_priv->age); - ADVANCE_RING(); - } else { - BEGIN_RING(2); - RADEON_DISPATCH_AGE(buf_priv->age); - ADVANCE_RING(); - } + BEGIN_RING(2); + RADEON_DISPATCH_AGE(buf_priv->age); + ADVANCE_RING(); buf->pending = 1; buf->used = 0; @@ -1986,7 +1980,7 @@ static int alloc_surface(drm_radeon_surface_alloc_t *new, /* find a virtual surface */ for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) - if (dev_priv->virt_surfaces[i].file_priv == NULL) + if (dev_priv->virt_surfaces[i].file_priv == 0) break; if (i == 2 * RADEON_MAX_SURFACES) { return -1; @@ -2479,24 +2473,23 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil buf->used = indirect->end; + /* Wait for the 3D stream to idle before the indirect buffer + * containing 2D acceleration commands is processed. + */ + BEGIN_RING(2); + + RADEON_WAIT_UNTIL_3D_IDLE(); + + ADVANCE_RING(); + /* Dispatch the indirect buffer full of commands from the * X server. This is insecure and is thus only available to * privileged clients. */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - r600_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); - else { - /* Wait for the 3D stream to idle before the indirect buffer - * containing 2D acceleration commands is processed. - */ - BEGIN_RING(2); - RADEON_WAIT_UNTIL_3D_IDLE(); - ADVANCE_RING(); - radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); - } - - if (indirect->discard) + radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); + if (indirect->discard) { radeon_cp_discard_buffer(dev, file_priv->master, buf); + } COMMIT_RING(); return 0; @@ -3017,14 +3010,14 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil break; case RADEON_PARAM_LAST_FRAME: dev_priv->stats.last_frame_reads++; - value = GET_SCRATCH(dev_priv, 0); + value = GET_SCRATCH(0); break; case RADEON_PARAM_LAST_DISPATCH: - value = GET_SCRATCH(dev_priv, 1); + value = GET_SCRATCH(1); break; case RADEON_PARAM_LAST_CLEAR: dev_priv->stats.last_clear_reads++; - value = GET_SCRATCH(dev_priv, 2); + value = GET_SCRATCH(2); break; case RADEON_PARAM_IRQ_NR: value = drm_dev_to_irq(dev); @@ -3059,10 +3052,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil case RADEON_PARAM_SCRATCH_OFFSET: if (!dev_priv->writeback_works) return -EINVAL; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - value = R600_SCRATCH_REG_OFFSET; - else - value = RADEON_SCRATCH_REG_OFFSET; + value = RADEON_SCRATCH_REG_OFFSET; break; case RADEON_PARAM_CARD_TYPE: if (dev_priv->flags & RADEON_IS_PCIE) @@ -3165,7 +3155,6 @@ void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) void radeon_driver_lastclose(struct drm_device *dev) { - radeon_surfaces_release(PCIGART_FILE_PRIV, dev->dev_private); radeon_do_release(dev); } diff --git a/trunk/drivers/gpu/drm/savage/savage_bci.c b/trunk/drivers/gpu/drm/savage/savage_bci.c index 456cd040f31a..d465b2f9c1cd 100644 --- a/trunk/drivers/gpu/drm/savage/savage_bci.c +++ b/trunk/drivers/gpu/drm/savage/savage_bci.c @@ -599,8 +599,8 @@ int savage_driver_firstopen(struct drm_device *dev) drm_mtrr_add(dev_priv->mtrr[2].base, dev_priv->mtrr[2].size, DRM_MTRR_WC); } else { - DRM_ERROR("strange pci_resource_len %08llx\n", - (unsigned long long)drm_get_resource_len(dev, 0)); + DRM_ERROR("strange pci_resource_len %08lx\n", + drm_get_resource_len(dev, 0)); } } else if (dev_priv->chipset != S3_SUPERSAVAGE && dev_priv->chipset != S3_SAVAGE2000) { @@ -620,8 +620,8 @@ int savage_driver_firstopen(struct drm_device *dev) drm_mtrr_add(dev_priv->mtrr[0].base, dev_priv->mtrr[0].size, DRM_MTRR_WC); } else { - DRM_ERROR("strange pci_resource_len %08llx\n", - (unsigned long long)drm_get_resource_len(dev, 1)); + DRM_ERROR("strange pci_resource_len %08lx\n", + drm_get_resource_len(dev, 1)); } } else { mmio_base = drm_get_resource_start(dev, 0); diff --git a/trunk/drivers/gpu/drm/via/via_drv.c b/trunk/drivers/gpu/drm/via/via_drv.c index bc2f51843005..0993b441fc42 100644 --- a/trunk/drivers/gpu/drm/via/via_drv.c +++ b/trunk/drivers/gpu/drm/via/via_drv.c @@ -28,6 +28,11 @@ #include "drm_pciids.h" +static int dri_library_name(struct drm_device *dev, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "unichrome"); +} + static struct pci_device_id pciidlist[] = { viadrv_PCI_IDS }; @@ -47,6 +52,7 @@ static struct drm_driver driver = { .irq_uninstall = via_driver_irq_uninstall, .irq_handler = via_driver_irq_handler, .dma_quiescent = via_driver_dma_quiescent, + .dri_library_name = dri_library_name, .reclaim_buffers = drm_core_reclaim_buffers, .reclaim_buffers_locked = NULL, .reclaim_buffers_idlelocked = via_reclaim_buffers_locked, diff --git a/trunk/drivers/hwmon/Kconfig b/trunk/drivers/hwmon/Kconfig index ce52bf2f235e..b4eea0292c1a 100644 --- a/trunk/drivers/hwmon/Kconfig +++ b/trunk/drivers/hwmon/Kconfig @@ -343,13 +343,12 @@ config SENSORS_FSCPOS will be called fscpos. config SENSORS_FSCHMD - tristate "Fujitsu Siemens Computers sensor chips" + tristate "FSC Poseidon, Scylla, Hermes, Heimdall and Heracles" depends on X86 && I2C help - If you say yes here you get support for the following Fujitsu - Siemens Computers (FSC) sensor chips: Poseidon, Scylla, Hermes, - Heimdall, Heracles, Hades and Syleus including support for the - integrated watchdog. + If you say yes here you get support for various Fujitsu Siemens + Computers sensor chips, including support for the integrated + watchdog. This is a merged driver for FSC sensor chips replacing the fscpos, fscscy and fscher drivers and adding support for several other FSC @@ -571,17 +570,6 @@ config SENSORS_LM93 This driver can also be built as a module. If so, the module will be called lm93. -config SENSORS_LTC4215 - tristate "Linear Technology LTC4215" - depends on I2C && EXPERIMENTAL - default n - help - If you say yes here you get support for Linear Technology LTC4215 - Hot Swap Controller I2C interface. - - This driver can also be built as a module. If so, the module will - be called ltc4215. - config SENSORS_LTC4245 tristate "Linear Technology LTC4245" depends on I2C && EXPERIMENTAL @@ -593,15 +581,6 @@ config SENSORS_LTC4245 This driver can also be built as a module. If so, the module will be called ltc4245. -config SENSORS_LM95241 - tristate "National Semiconductor LM95241 sensor chip" - depends on I2C - help - If you say yes here you get support for LM95241 sensor chip. - - This driver can also be built as a module. If so, the module - will be called lm95241. - config SENSORS_MAX1111 tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip" depends on SPI_MASTER @@ -656,20 +635,6 @@ config SENSORS_PC87427 This driver can also be built as a module. If so, the module will be called pc87427. -config SENSORS_PCF8591 - tristate "Philips PCF8591 ADC/DAC" - depends on I2C - default n - help - If you say yes here you get support for Philips PCF8591 4-channel - ADC, 1-channel DAC chips. - - This driver can also be built as a module. If so, the module - will be called pcf8591. - - These devices are hard to detect and rarely found on mainstream - hardware. If unsure, say N. - config SENSORS_SIS5595 tristate "Silicon Integrated Systems Corp. SiS5595" depends on PCI @@ -862,7 +827,7 @@ config SENSORS_W83627HF will be called w83627hf. config SENSORS_W83627EHF - tristate "Winbond W83627EHF/EHG/DHG, W83667HG" + tristate "Winbond W83627EHF/DHG" select HWMON_VID help If you say yes here you get support for the hardware @@ -873,8 +838,6 @@ config SENSORS_W83627EHF chip suited for specific Intel processors that use PECI such as the Core 2 Duo. - This driver also supports the W83667HG chip. - This driver can also be built as a module. If so, the module will be called w83627ehf. @@ -932,22 +895,6 @@ config SENSORS_LIS3LV02D Say Y here if you have an applicable laptop and want to experience the awesome power of lis3lv02d. -config SENSORS_LIS3_SPI - tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)" - depends on !ACPI && SPI_MASTER && INPUT - default n - help - This driver provides support for the LIS3LV02Dx accelerometer connected - via SPI. The accelerometer data is readable via - /sys/devices/platform/lis3lv02d. - - This driver also provides an absolute input class device, allowing - the laptop to act as a pinball machine-esque joystick. - - This driver can also be built as modules. If so, the core module - will be called lis3lv02d and a specific module for the SPI transport - is called lis3lv02d_spi. - config SENSORS_APPLESMC tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" depends on INPUT && X86 diff --git a/trunk/drivers/hwmon/Makefile b/trunk/drivers/hwmon/Makefile index 3a6b1f06f8f4..2e80f37f39eb 100644 --- a/trunk/drivers/hwmon/Makefile +++ b/trunk/drivers/hwmon/Makefile @@ -52,7 +52,6 @@ obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o obj-$(CONFIG_SENSORS_IT87) += it87.o obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o -obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d.o lis3lv02d_spi.o obj-$(CONFIG_SENSORS_LM63) += lm63.o obj-$(CONFIG_SENSORS_LM70) += lm70.o obj-$(CONFIG_SENSORS_LM75) += lm75.o @@ -65,15 +64,12 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o obj-$(CONFIG_SENSORS_LM90) += lm90.o obj-$(CONFIG_SENSORS_LM92) += lm92.o obj-$(CONFIG_SENSORS_LM93) += lm93.o -obj-$(CONFIG_SENSORS_LM95241) += lm95241.o -obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o obj-$(CONFIG_SENSORS_MAX1111) += max1111.o obj-$(CONFIG_SENSORS_MAX1619) += max1619.o obj-$(CONFIG_SENSORS_MAX6650) += max6650.o obj-$(CONFIG_SENSORS_PC87360) += pc87360.o obj-$(CONFIG_SENSORS_PC87427) += pc87427.o -obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o diff --git a/trunk/drivers/hwmon/ds1621.c b/trunk/drivers/hwmon/ds1621.c index 53f88f511816..7415381601c3 100644 --- a/trunk/drivers/hwmon/ds1621.c +++ b/trunk/drivers/hwmon/ds1621.c @@ -81,84 +81,71 @@ struct ds1621_data { u8 conf; /* Register encoding, combined */ }; -/* Temperature registers are word-sized. +static int ds1621_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int ds1621_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info); +static void ds1621_init_client(struct i2c_client *client); +static int ds1621_remove(struct i2c_client *client); +static struct ds1621_data *ds1621_update_client(struct device *dev); + +static const struct i2c_device_id ds1621_id[] = { + { "ds1621", ds1621 }, + { "ds1625", ds1621 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ds1621_id); + +/* This is the driver that will be inserted */ +static struct i2c_driver ds1621_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "ds1621", + }, + .probe = ds1621_probe, + .remove = ds1621_remove, + .id_table = ds1621_id, + .detect = ds1621_detect, + .address_data = &addr_data, +}; + +/* All registers are word-sized, except for the configuration register. DS1621 uses a high-byte first convention, which is exactly opposite to the SMBus standard. */ -static int ds1621_read_temp(struct i2c_client *client, u8 reg) +static int ds1621_read_value(struct i2c_client *client, u8 reg) { - int ret; - - ret = i2c_smbus_read_word_data(client, reg); - if (ret < 0) - return ret; - return swab16(ret); + if (reg == DS1621_REG_CONF) + return i2c_smbus_read_byte_data(client, reg); + else + return swab16(i2c_smbus_read_word_data(client, reg)); } -static int ds1621_write_temp(struct i2c_client *client, u8 reg, u16 value) +static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value) { - return i2c_smbus_write_word_data(client, reg, swab16(value)); + if (reg == DS1621_REG_CONF) + return i2c_smbus_write_byte_data(client, reg, value); + else + return i2c_smbus_write_word_data(client, reg, swab16(value)); } static void ds1621_init_client(struct i2c_client *client) { - u8 conf, new_conf; - - new_conf = conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF); + int reg = ds1621_read_value(client, DS1621_REG_CONF); /* switch to continuous conversion mode */ - new_conf &= ~DS1621_REG_CONFIG_1SHOT; + reg &= ~ DS1621_REG_CONFIG_1SHOT; /* setup output polarity */ if (polarity == 0) - new_conf &= ~DS1621_REG_CONFIG_POLARITY; + reg &= ~DS1621_REG_CONFIG_POLARITY; else if (polarity == 1) - new_conf |= DS1621_REG_CONFIG_POLARITY; + reg |= DS1621_REG_CONFIG_POLARITY; - if (conf != new_conf) - i2c_smbus_write_byte_data(client, DS1621_REG_CONF, new_conf); + ds1621_write_value(client, DS1621_REG_CONF, reg); /* start conversion */ i2c_smbus_write_byte(client, DS1621_COM_START); } -static struct ds1621_data *ds1621_update_client(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ds1621_data *data = i2c_get_clientdata(client); - u8 new_conf; - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - int i; - - dev_dbg(&client->dev, "Starting ds1621 update\n"); - - data->conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF); - - for (i = 0; i < ARRAY_SIZE(data->temp); i++) - data->temp[i] = ds1621_read_temp(client, - DS1621_REG_TEMP[i]); - - /* reset alarms if necessary */ - new_conf = data->conf; - if (data->temp[0] > data->temp[1]) /* input > min */ - new_conf &= ~DS1621_ALARM_TEMP_LOW; - if (data->temp[0] < data->temp[2]) /* input < max */ - new_conf &= ~DS1621_ALARM_TEMP_HIGH; - if (data->conf != new_conf) - i2c_smbus_write_byte_data(client, DS1621_REG_CONF, - new_conf); - - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - - return data; -} - static ssize_t show_temp(struct device *dev, struct device_attribute *da, char *buf) { @@ -173,13 +160,13 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da, { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); - struct ds1621_data *data = i2c_get_clientdata(client); + struct ds1621_data *data = ds1621_update_client(dev); u16 val = LM75_TEMP_TO_REG(simple_strtol(buf, NULL, 10)); mutex_lock(&data->update_lock); data->temp[attr->index] = val; - ds1621_write_temp(client, DS1621_REG_TEMP[attr->index], - data->temp[attr->index]); + ds1621_write_value(client, DS1621_REG_TEMP[attr->index], + data->temp[attr->index]); mutex_unlock(&data->update_lock); return count; } @@ -241,14 +228,13 @@ static int ds1621_detect(struct i2c_client *client, int kind, /* The NVB bit should be low if no EEPROM write has been requested during the latest 10ms, which is highly improbable in our case. */ - conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF); - if (conf < 0 || conf & DS1621_REG_CONFIG_NVB) + conf = ds1621_read_value(client, DS1621_REG_CONF); + if (conf & DS1621_REG_CONFIG_NVB) return -ENODEV; /* The 7 lowest bits of a temperature should always be 0. */ for (i = 0; i < ARRAY_SIZE(DS1621_REG_TEMP); i++) { - temp = i2c_smbus_read_word_data(client, - DS1621_REG_TEMP[i]); - if (temp < 0 || (temp & 0x7f00)) + temp = ds1621_read_value(client, DS1621_REG_TEMP[i]); + if (temp & 0x007f) return -ENODEV; } } @@ -308,25 +294,45 @@ static int ds1621_remove(struct i2c_client *client) return 0; } -static const struct i2c_device_id ds1621_id[] = { - { "ds1621", ds1621 }, - { "ds1625", ds1621 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, ds1621_id); -/* This is the driver that will be inserted */ -static struct i2c_driver ds1621_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "ds1621", - }, - .probe = ds1621_probe, - .remove = ds1621_remove, - .id_table = ds1621_id, - .detect = ds1621_detect, - .address_data = &addr_data, -}; +static struct ds1621_data *ds1621_update_client(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ds1621_data *data = i2c_get_clientdata(client); + u8 new_conf; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i; + + dev_dbg(&client->dev, "Starting ds1621 update\n"); + + data->conf = ds1621_read_value(client, DS1621_REG_CONF); + + for (i = 0; i < ARRAY_SIZE(data->temp); i++) + data->temp[i] = ds1621_read_value(client, + DS1621_REG_TEMP[i]); + + /* reset alarms if necessary */ + new_conf = data->conf; + if (data->temp[0] > data->temp[1]) /* input > min */ + new_conf &= ~DS1621_ALARM_TEMP_LOW; + if (data->temp[0] < data->temp[2]) /* input < max */ + new_conf &= ~DS1621_ALARM_TEMP_HIGH; + if (data->conf != new_conf) + ds1621_write_value(client, DS1621_REG_CONF, + new_conf); + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} static int __init ds1621_init(void) { diff --git a/trunk/drivers/hwmon/fschmd.c b/trunk/drivers/hwmon/fschmd.c index ea955edde87e..d07f4ef75092 100644 --- a/trunk/drivers/hwmon/fschmd.c +++ b/trunk/drivers/hwmon/fschmd.c @@ -1,6 +1,6 @@ /* fschmd.c * - * Copyright (C) 2007 - 2009 Hans de Goede + * Copyright (C) 2007,2008 Hans de Goede * * 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 @@ -19,7 +19,7 @@ /* * Merged Fujitsu Siemens hwmon driver, supporting the Poseidon, Hermes, - * Scylla, Heracles, Heimdall, Hades and Syleus chips + * Scylla, Heracles and Heimdall chips * * Based on the original 2.4 fscscy, 2.6 fscpos, 2.6 fscher and 2.6 * (candidate) fschmd drivers: @@ -56,7 +56,7 @@ static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -I2C_CLIENT_INSMOD_7(fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl); +I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd); /* * The FSCHMD registers and other defines @@ -75,12 +75,9 @@ I2C_CLIENT_INSMOD_7(fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl); #define FSCHMD_CONTROL_ALERT_LED 0x01 /* watchdog */ -static const u8 FSCHMD_REG_WDOG_CONTROL[7] = - { 0x21, 0x21, 0x21, 0x21, 0x21, 0x28, 0x28 }; -static const u8 FSCHMD_REG_WDOG_STATE[7] = - { 0x23, 0x23, 0x23, 0x23, 0x23, 0x29, 0x29 }; -static const u8 FSCHMD_REG_WDOG_PRESET[7] = - { 0x28, 0x28, 0x28, 0x28, 0x28, 0x2a, 0x2a }; +#define FSCHMD_REG_WDOG_PRESET 0x28 +#define FSCHMD_REG_WDOG_STATE 0x23 +#define FSCHMD_REG_WDOG_CONTROL 0x21 #define FSCHMD_WDOG_CONTROL_TRIGGER 0x10 #define FSCHMD_WDOG_CONTROL_STARTED 0x10 /* the same as trigger */ @@ -90,95 +87,70 @@ static const u8 FSCHMD_REG_WDOG_PRESET[7] = #define FSCHMD_WDOG_STATE_CARDRESET 0x02 /* voltages, weird order is to keep the same order as the old drivers */ -static const u8 FSCHMD_REG_VOLT[7][6] = { - { 0x45, 0x42, 0x48 }, /* pos */ - { 0x45, 0x42, 0x48 }, /* her */ - { 0x45, 0x42, 0x48 }, /* scy */ - { 0x45, 0x42, 0x48 }, /* hrc */ - { 0x45, 0x42, 0x48 }, /* hmd */ - { 0x21, 0x20, 0x22 }, /* hds */ - { 0x21, 0x20, 0x22, 0x23, 0x24, 0x25 }, /* syl */ -}; - -static const int FSCHMD_NO_VOLT_SENSORS[7] = { 3, 3, 3, 3, 3, 3, 6 }; +static const u8 FSCHMD_REG_VOLT[3] = { 0x45, 0x42, 0x48 }; /* minimum pwm at which the fan is driven (pwm can by increased depending on the temp. Notice that for the scy some fans share there minimum speed. Also notice that with the scy the sensor order is different than with the other chips, this order was in the 2.4 driver and kept for consistency. */ -static const u8 FSCHMD_REG_FAN_MIN[7][7] = { +static const u8 FSCHMD_REG_FAN_MIN[5][6] = { { 0x55, 0x65 }, /* pos */ { 0x55, 0x65, 0xb5 }, /* her */ { 0x65, 0x65, 0x55, 0xa5, 0x55, 0xa5 }, /* scy */ { 0x55, 0x65, 0xa5, 0xb5 }, /* hrc */ { 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hmd */ - { 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hds */ - { 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb4 }, /* syl */ }; /* actual fan speed */ -static const u8 FSCHMD_REG_FAN_ACT[7][7] = { +static const u8 FSCHMD_REG_FAN_ACT[5][6] = { { 0x0e, 0x6b, 0xab }, /* pos */ { 0x0e, 0x6b, 0xbb }, /* her */ { 0x6b, 0x6c, 0x0e, 0xab, 0x5c, 0xbb }, /* scy */ { 0x0e, 0x6b, 0xab, 0xbb }, /* hrc */ { 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hmd */ - { 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hds */ - { 0x57, 0x67, 0x77, 0x87, 0x97, 0xa7, 0xb7 }, /* syl */ }; /* fan status registers */ -static const u8 FSCHMD_REG_FAN_STATE[7][7] = { +static const u8 FSCHMD_REG_FAN_STATE[5][6] = { { 0x0d, 0x62, 0xa2 }, /* pos */ { 0x0d, 0x62, 0xb2 }, /* her */ { 0x62, 0x61, 0x0d, 0xa2, 0x52, 0xb2 }, /* scy */ { 0x0d, 0x62, 0xa2, 0xb2 }, /* hrc */ { 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hmd */ - { 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hds */ - { 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0 }, /* syl */ }; /* fan ripple / divider registers */ -static const u8 FSCHMD_REG_FAN_RIPPLE[7][7] = { +static const u8 FSCHMD_REG_FAN_RIPPLE[5][6] = { { 0x0f, 0x6f, 0xaf }, /* pos */ { 0x0f, 0x6f, 0xbf }, /* her */ { 0x6f, 0x6f, 0x0f, 0xaf, 0x0f, 0xbf }, /* scy */ { 0x0f, 0x6f, 0xaf, 0xbf }, /* hrc */ { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hmd */ - { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hds */ - { 0x56, 0x66, 0x76, 0x86, 0x96, 0xa6, 0xb6 }, /* syl */ }; -static const int FSCHMD_NO_FAN_SENSORS[7] = { 3, 3, 6, 4, 5, 5, 7 }; +static const int FSCHMD_NO_FAN_SENSORS[5] = { 3, 3, 6, 4, 5 }; /* Fan status register bitmasks */ #define FSCHMD_FAN_ALARM 0x04 /* called fault by FSC! */ -#define FSCHMD_FAN_NOT_PRESENT 0x08 -#define FSCHMD_FAN_DISABLED 0x80 +#define FSCHMD_FAN_NOT_PRESENT 0x08 /* not documented */ /* actual temperature registers */ -static const u8 FSCHMD_REG_TEMP_ACT[7][11] = { +static const u8 FSCHMD_REG_TEMP_ACT[5][5] = { { 0x64, 0x32, 0x35 }, /* pos */ { 0x64, 0x32, 0x35 }, /* her */ { 0x64, 0xD0, 0x32, 0x35 }, /* scy */ { 0x64, 0x32, 0x35 }, /* hrc */ { 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hmd */ - { 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hds */ - { 0x58, 0x68, 0x78, 0x88, 0x98, 0xa8, /* syl */ - 0xb8, 0xc8, 0xd8, 0xe8, 0xf8 }, }; /* temperature state registers */ -static const u8 FSCHMD_REG_TEMP_STATE[7][11] = { +static const u8 FSCHMD_REG_TEMP_STATE[5][5] = { { 0x71, 0x81, 0x91 }, /* pos */ { 0x71, 0x81, 0x91 }, /* her */ { 0x71, 0xd1, 0x81, 0x91 }, /* scy */ { 0x71, 0x81, 0x91 }, /* hrc */ { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hmd */ - { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hds */ - { 0x59, 0x69, 0x79, 0x89, 0x99, 0xa9, /* syl */ - 0xb9, 0xc9, 0xd9, 0xe9, 0xf9 }, }; /* temperature high limit registers, FSC does not document these. Proven to be @@ -186,31 +158,24 @@ static const u8 FSCHMD_REG_TEMP_STATE[7][11] = { in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers at these addresses, but doesn't want to confirm they are the same as with the fscher?? */ -static const u8 FSCHMD_REG_TEMP_LIMIT[7][11] = { +static const u8 FSCHMD_REG_TEMP_LIMIT[5][5] = { { 0, 0, 0 }, /* pos */ { 0x76, 0x86, 0x96 }, /* her */ { 0x76, 0xd6, 0x86, 0x96 }, /* scy */ { 0x76, 0x86, 0x96 }, /* hrc */ { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hmd */ - { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hds */ - { 0x5a, 0x6a, 0x7a, 0x8a, 0x9a, 0xaa, /* syl */ - 0xba, 0xca, 0xda, 0xea, 0xfa }, }; /* These were found through experimenting with an fscher, currently they are not used, but we keep them around for future reference. - On the fscsyl AUTOP1 lives at 0x#c (so 0x5c for fan1, 0x6c for fan2, etc), - AUTOP2 lives at 0x#e, and 0x#1 is a bitmask defining which temps influence - the fan speed. static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 }; static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; */ -static const int FSCHMD_NO_TEMP_SENSORS[7] = { 3, 3, 4, 3, 5, 5, 11 }; +static const int FSCHMD_NO_TEMP_SENSORS[5] = { 3, 3, 4, 3, 5 }; /* temp status register bitmasks */ #define FSCHMD_TEMP_WORKING 0x01 #define FSCHMD_TEMP_ALERT 0x02 -#define FSCHMD_TEMP_DISABLED 0x80 /* there only really is an alarm if the sensor is working and alert == 1 */ #define FSCHMD_TEMP_ALARM_MASK \ (FSCHMD_TEMP_WORKING | FSCHMD_TEMP_ALERT) @@ -236,8 +201,6 @@ static const struct i2c_device_id fschmd_id[] = { { "fscscy", fscscy }, { "fschrc", fschrc }, { "fschmd", fschmd }, - { "fschds", fschds }, - { "fscsyl", fscsyl }, { } }; MODULE_DEVICE_TABLE(i2c, fschmd_id); @@ -279,14 +242,14 @@ struct fschmd_data { u8 watchdog_control; /* watchdog control register */ u8 watchdog_state; /* watchdog status register */ u8 watchdog_preset; /* watchdog counter preset on trigger val */ - u8 volt[6]; /* voltage */ - u8 temp_act[11]; /* temperature */ - u8 temp_status[11]; /* status of sensor */ - u8 temp_max[11]; /* high temp limit, notice: undocumented! */ - u8 fan_act[7]; /* fans revolutions per second */ - u8 fan_status[7]; /* fan status */ - u8 fan_min[7]; /* fan min value for rps */ - u8 fan_ripple[7]; /* divider for rps */ + u8 volt[3]; /* 12, 5, battery voltage */ + u8 temp_act[5]; /* temperature */ + u8 temp_status[5]; /* status of sensor */ + u8 temp_max[5]; /* high temp limit, notice: undocumented! */ + u8 fan_act[6]; /* fans revolutions per second */ + u8 fan_status[6]; /* fan status */ + u8 fan_min[6]; /* fan min value for rps */ + u8 fan_ripple[6]; /* divider for rps */ }; /* Global variables to hold information read from special DMI tables, which are @@ -294,8 +257,8 @@ struct fschmd_data { protect these with a lock as they are only modified from our attach function which always gets called with the i2c-core lock held and never accessed before the attach function is done with them. */ -static int dmi_mult[6] = { 490, 200, 100, 100, 200, 100 }; -static int dmi_offset[6] = { 0, 0, 0, 0, 0, 0 }; +static int dmi_mult[3] = { 490, 200, 100 }; +static int dmi_offset[3] = { 0, 0, 0 }; static int dmi_vref = -1; /* Somewhat ugly :( global data pointer list with all fschmd devices, so that @@ -487,11 +450,10 @@ static ssize_t show_pwm_auto_point1_pwm(struct device *dev, struct device_attribute *devattr, char *buf) { int index = to_sensor_dev_attr(devattr)->index; - struct fschmd_data *data = fschmd_update_device(dev); - int val = data->fan_min[index]; + int val = fschmd_update_device(dev)->fan_min[index]; - /* 0 = allow turning off (except on the syl), 1-255 = 50-100% */ - if (val || data->kind == fscsyl - 1) + /* 0 = allow turning off, 1-255 = 50-100% */ + if (val) val = val / 2 + 128; return sprintf(buf, "%d\n", val); @@ -504,8 +466,8 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev, struct fschmd_data *data = dev_get_drvdata(dev); unsigned long v = simple_strtoul(buf, NULL, 10); - /* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */ - if (v || data->kind == fscsyl - 1) { + /* register: 0 = allow turning off, 1-255 = 50-100% */ + if (v) { v = SENSORS_LIMIT(v, 128, 255); v = (v - 128) * 2 + 1; } @@ -560,15 +522,11 @@ static ssize_t store_alert_led(struct device *dev, return count; } -static DEVICE_ATTR(alert_led, 0644, show_alert_led, store_alert_led); - static struct sensor_device_attribute fschmd_attr[] = { SENSOR_ATTR(in0_input, 0444, show_in_value, NULL, 0), SENSOR_ATTR(in1_input, 0444, show_in_value, NULL, 1), SENSOR_ATTR(in2_input, 0444, show_in_value, NULL, 2), - SENSOR_ATTR(in3_input, 0444, show_in_value, NULL, 3), - SENSOR_ATTR(in4_input, 0444, show_in_value, NULL, 4), - SENSOR_ATTR(in5_input, 0444, show_in_value, NULL, 5), + SENSOR_ATTR(alert_led, 0644, show_alert_led, store_alert_led, 0), }; static struct sensor_device_attribute fschmd_temp_attr[] = { @@ -592,30 +550,6 @@ static struct sensor_device_attribute fschmd_temp_attr[] = { SENSOR_ATTR(temp5_max, 0644, show_temp_max, store_temp_max, 4), SENSOR_ATTR(temp5_fault, 0444, show_temp_fault, NULL, 4), SENSOR_ATTR(temp5_alarm, 0444, show_temp_alarm, NULL, 4), - SENSOR_ATTR(temp6_input, 0444, show_temp_value, NULL, 5), - SENSOR_ATTR(temp6_max, 0644, show_temp_max, store_temp_max, 5), - SENSOR_ATTR(temp6_fault, 0444, show_temp_fault, NULL, 5), - SENSOR_ATTR(temp6_alarm, 0444, show_temp_alarm, NULL, 5), - SENSOR_ATTR(temp7_input, 0444, show_temp_value, NULL, 6), - SENSOR_ATTR(temp7_max, 0644, show_temp_max, store_temp_max, 6), - SENSOR_ATTR(temp7_fault, 0444, show_temp_fault, NULL, 6), - SENSOR_ATTR(temp7_alarm, 0444, show_temp_alarm, NULL, 6), - SENSOR_ATTR(temp8_input, 0444, show_temp_value, NULL, 7), - SENSOR_ATTR(temp8_max, 0644, show_temp_max, store_temp_max, 7), - SENSOR_ATTR(temp8_fault, 0444, show_temp_fault, NULL, 7), - SENSOR_ATTR(temp8_alarm, 0444, show_temp_alarm, NULL, 7), - SENSOR_ATTR(temp9_input, 0444, show_temp_value, NULL, 8), - SENSOR_ATTR(temp9_max, 0644, show_temp_max, store_temp_max, 8), - SENSOR_ATTR(temp9_fault, 0444, show_temp_fault, NULL, 8), - SENSOR_ATTR(temp9_alarm, 0444, show_temp_alarm, NULL, 8), - SENSOR_ATTR(temp10_input, 0444, show_temp_value, NULL, 9), - SENSOR_ATTR(temp10_max, 0644, show_temp_max, store_temp_max, 9), - SENSOR_ATTR(temp10_fault, 0444, show_temp_fault, NULL, 9), - SENSOR_ATTR(temp10_alarm, 0444, show_temp_alarm, NULL, 9), - SENSOR_ATTR(temp11_input, 0444, show_temp_value, NULL, 10), - SENSOR_ATTR(temp11_max, 0644, show_temp_max, store_temp_max, 10), - SENSOR_ATTR(temp11_fault, 0444, show_temp_fault, NULL, 10), - SENSOR_ATTR(temp11_alarm, 0444, show_temp_alarm, NULL, 10), }; static struct sensor_device_attribute fschmd_fan_attr[] = { @@ -655,12 +589,6 @@ static struct sensor_device_attribute fschmd_fan_attr[] = { SENSOR_ATTR(fan6_fault, 0444, show_fan_fault, NULL, 5), SENSOR_ATTR(pwm6_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm, store_pwm_auto_point1_pwm, 5), - SENSOR_ATTR(fan7_input, 0444, show_fan_value, NULL, 6), - SENSOR_ATTR(fan7_div, 0644, show_fan_div, store_fan_div, 6), - SENSOR_ATTR(fan7_alarm, 0444, show_fan_alarm, NULL, 6), - SENSOR_ATTR(fan7_fault, 0444, show_fan_fault, NULL, 6), - SENSOR_ATTR(pwm7_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm, - store_pwm_auto_point1_pwm, 6), }; @@ -696,11 +624,10 @@ static int watchdog_set_timeout(struct fschmd_data *data, int timeout) data->watchdog_preset = DIV_ROUND_UP(timeout, resolution); /* Write new timeout value */ - i2c_smbus_write_byte_data(data->client, - FSCHMD_REG_WDOG_PRESET[data->kind], data->watchdog_preset); + i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_PRESET, + data->watchdog_preset); /* Write new control register, do not trigger! */ - i2c_smbus_write_byte_data(data->client, - FSCHMD_REG_WDOG_CONTROL[data->kind], + i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL, data->watchdog_control & ~FSCHMD_WDOG_CONTROL_TRIGGER); ret = data->watchdog_preset * resolution; @@ -735,9 +662,8 @@ static int watchdog_trigger(struct fschmd_data *data) } data->watchdog_control |= FSCHMD_WDOG_CONTROL_TRIGGER; - i2c_smbus_write_byte_data(data->client, - FSCHMD_REG_WDOG_CONTROL[data->kind], - data->watchdog_control); + i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL, + data->watchdog_control); leave: mutex_unlock(&data->watchdog_lock); return ret; @@ -756,8 +682,7 @@ static int watchdog_stop(struct fschmd_data *data) data->watchdog_control &= ~FSCHMD_WDOG_CONTROL_STARTED; /* Don't store the stop flag in our watchdog control register copy, as its a write only bit (read always returns 0) */ - i2c_smbus_write_byte_data(data->client, - FSCHMD_REG_WDOG_CONTROL[data->kind], + i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL, data->watchdog_control | FSCHMD_WDOG_CONTROL_STOP); leave: mutex_unlock(&data->watchdog_lock); @@ -931,7 +856,7 @@ static struct file_operations watchdog_fops = { /* DMI decode routine to read voltage scaling factors from special DMI tables, which are available on FSC machines with an fscher or later chip. */ -static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy) +static void fschmd_dmi_decode(const struct dmi_header *header) { int i, mult[3] = { 0 }, offset[3] = { 0 }, vref = 0, found = 0; @@ -987,15 +912,6 @@ static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy) dmi_mult[i] = mult[i] * 10; dmi_offset[i] = offset[i] * 10; } - /* According to the docs there should be separate dmi entries - for the mult's and offsets of in3-5 of the syl, but on - my test machine these are not present */ - dmi_mult[3] = dmi_mult[2]; - dmi_mult[4] = dmi_mult[1]; - dmi_mult[5] = dmi_mult[2]; - dmi_offset[3] = dmi_offset[2]; - dmi_offset[4] = dmi_offset[1]; - dmi_offset[5] = dmi_offset[2]; dmi_vref = vref; } } @@ -1004,6 +920,8 @@ static int fschmd_detect(struct i2c_client *client, int kind, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; + const char * const client_names[5] = { "fscpos", "fscher", "fscscy", + "fschrc", "fschmd" }; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; @@ -1030,15 +948,11 @@ static int fschmd_detect(struct i2c_client *client, int kind, kind = fschrc; else if (!strcmp(id, "HMD")) kind = fschmd; - else if (!strcmp(id, "HDS")) - kind = fschds; - else if (!strcmp(id, "SYL")) - kind = fscsyl; else return -ENODEV; } - strlcpy(info->type, fschmd_id[kind - 1].name, I2C_NAME_SIZE); + strlcpy(info->type, client_names[kind - 1], I2C_NAME_SIZE); return 0; } @@ -1047,8 +961,8 @@ static int fschmd_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct fschmd_data *data; - const char * const names[7] = { "Poseidon", "Hermes", "Scylla", - "Heracles", "Heimdall", "Hades", "Syleus" }; + const char * const names[5] = { "Poseidon", "Hermes", "Scylla", + "Heracles", "Heimdall" }; const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 }; int i, err; enum chips kind = id->driver_data; @@ -1077,7 +991,7 @@ static int fschmd_probe(struct i2c_client *client, /* Read the special DMI table for fscher and newer chips */ if ((kind == fscher || kind >= fschrc) && dmi_vref == -1) { - dmi_walk(fschmd_dmi_decode, NULL); + dmi_walk(fschmd_dmi_decode); if (dmi_vref == -1) { dev_warn(&client->dev, "Couldn't get voltage scaling factors from " @@ -1086,25 +1000,21 @@ static int fschmd_probe(struct i2c_client *client, } } - /* i2c kind goes from 1-6, we want from 0-5 to address arrays */ - data->kind = kind - 1; - /* Read in some never changing registers */ data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION); data->global_control = i2c_smbus_read_byte_data(client, FSCHMD_REG_CONTROL); data->watchdog_control = i2c_smbus_read_byte_data(client, - FSCHMD_REG_WDOG_CONTROL[data->kind]); + FSCHMD_REG_WDOG_CONTROL); data->watchdog_state = i2c_smbus_read_byte_data(client, - FSCHMD_REG_WDOG_STATE[data->kind]); + FSCHMD_REG_WDOG_STATE); data->watchdog_preset = i2c_smbus_read_byte_data(client, - FSCHMD_REG_WDOG_PRESET[data->kind]); + FSCHMD_REG_WDOG_PRESET); - err = device_create_file(&client->dev, &dev_attr_alert_led); - if (err) - goto exit_detach; + /* i2c kind goes from 1-5, we want from 0-4 to address arrays */ + data->kind = kind - 1; - for (i = 0; i < FSCHMD_NO_VOLT_SENSORS[data->kind]; i++) { + for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) { err = device_create_file(&client->dev, &fschmd_attr[i].dev_attr); if (err) @@ -1117,16 +1027,6 @@ static int fschmd_probe(struct i2c_client *client, show_temp_max) continue; - if (kind == fscsyl) { - if (i % 4 == 0) - data->temp_status[i / 4] = - i2c_smbus_read_byte_data(client, - FSCHMD_REG_TEMP_STATE - [data->kind][i / 4]); - if (data->temp_status[i / 4] & FSCHMD_TEMP_DISABLED) - continue; - } - err = device_create_file(&client->dev, &fschmd_temp_attr[i].dev_attr); if (err) @@ -1140,16 +1040,6 @@ static int fschmd_probe(struct i2c_client *client, "pwm3_auto_point1_pwm")) continue; - if (kind == fscsyl) { - if (i % 5 == 0) - data->fan_status[i / 5] = - i2c_smbus_read_byte_data(client, - FSCHMD_REG_FAN_STATE - [data->kind][i / 5]); - if (data->fan_status[i / 5] & FSCHMD_FAN_DISABLED) - continue; - } - err = device_create_file(&client->dev, &fschmd_fan_attr[i].dev_attr); if (err) @@ -1236,8 +1126,7 @@ static int fschmd_remove(struct i2c_client *client) if (data->hwmon_dev) hwmon_device_unregister(data->hwmon_dev); - device_remove_file(&client->dev, &dev_attr_alert_led); - for (i = 0; i < (FSCHMD_NO_VOLT_SENSORS[data->kind]); i++) + for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) device_remove_file(&client->dev, &fschmd_attr[i].dev_attr); for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->kind] * 4); i++) device_remove_file(&client->dev, @@ -1282,7 +1171,7 @@ static struct fschmd_data *fschmd_update_device(struct device *dev) data->temp_act[i] < data->temp_max[i]) i2c_smbus_write_byte_data(client, FSCHMD_REG_TEMP_STATE[data->kind][i], - data->temp_status[i]); + FSCHMD_TEMP_ALERT); } for (i = 0; i < FSCHMD_NO_FAN_SENSORS[data->kind]; i++) { @@ -1304,12 +1193,12 @@ static struct fschmd_data *fschmd_update_device(struct device *dev) data->fan_act[i]) i2c_smbus_write_byte_data(client, FSCHMD_REG_FAN_STATE[data->kind][i], - data->fan_status[i]); + FSCHMD_FAN_ALARM); } - for (i = 0; i < FSCHMD_NO_VOLT_SENSORS[data->kind]; i++) + for (i = 0; i < 3; i++) data->volt[i] = i2c_smbus_read_byte_data(client, - FSCHMD_REG_VOLT[data->kind][i]); + FSCHMD_REG_VOLT[i]); data->last_updated = jiffies; data->valid = 1; @@ -1331,8 +1220,8 @@ static void __exit fschmd_exit(void) } MODULE_AUTHOR("Hans de Goede "); -MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles, Heimdall, Hades " - "and Syleus driver"); +MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles and " + "Heimdall driver"); MODULE_LICENSE("GPL"); module_init(fschmd_init); diff --git a/trunk/drivers/hwmon/hdaps.c b/trunk/drivers/hwmon/hdaps.c index d3612a1f1981..a4d92d246d52 100644 --- a/trunk/drivers/hwmon/hdaps.c +++ b/trunk/drivers/hwmon/hdaps.c @@ -65,10 +65,6 @@ #define HDAPS_INPUT_FUZZ 4 /* input event threshold */ #define HDAPS_INPUT_FLAT 4 -#define HDAPS_X_AXIS (1 << 0) -#define HDAPS_Y_AXIS (1 << 1) -#define HDAPS_BOTH_AXES (HDAPS_X_AXIS | HDAPS_Y_AXIS) - static struct platform_device *pdev; static struct input_polled_dev *hdaps_idev; static unsigned int hdaps_invert; @@ -186,11 +182,11 @@ static int __hdaps_read_pair(unsigned int port1, unsigned int port2, km_activity = inb(HDAPS_PORT_KMACT); __device_complete(); - /* hdaps_invert is a bitvector to negate the axes */ - if (hdaps_invert & HDAPS_X_AXIS) + /* if hdaps_invert is set, negate the two values */ + if (hdaps_invert) { *x = -*x; - if (hdaps_invert & HDAPS_Y_AXIS) *y = -*y; + } return 0; } @@ -440,8 +436,7 @@ static ssize_t hdaps_invert_store(struct device *dev, { int invert; - if (sscanf(buf, "%d", &invert) != 1 || - invert < 0 || invert > HDAPS_BOTH_AXES) + if (sscanf(buf, "%d", &invert) != 1 || (invert != 1 && invert != 0)) return -EINVAL; hdaps_invert = invert; @@ -488,52 +483,56 @@ static int __init hdaps_dmi_match(const struct dmi_system_id *id) /* hdaps_dmi_match_invert - found an inverted match. */ static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id) { - hdaps_invert = (unsigned long)id->driver_data; - printk(KERN_INFO "hdaps: inverting axis (%u) readings.\n", - hdaps_invert); + hdaps_invert = 1; + printk(KERN_INFO "hdaps: inverting axis readings.\n"); return hdaps_dmi_match(id); } -#define HDAPS_DMI_MATCH_INVERT(vendor, model, axes) { \ +#define HDAPS_DMI_MATCH_NORMAL(vendor, model) { \ .ident = vendor " " model, \ - .callback = hdaps_dmi_match_invert, \ - .driver_data = (void *)axes, \ + .callback = hdaps_dmi_match, \ .matches = { \ DMI_MATCH(DMI_BOARD_VENDOR, vendor), \ DMI_MATCH(DMI_PRODUCT_VERSION, model) \ } \ } -#define HDAPS_DMI_MATCH_NORMAL(vendor, model) \ - HDAPS_DMI_MATCH_INVERT(vendor, model, 0) +#define HDAPS_DMI_MATCH_INVERT(vendor, model) { \ + .ident = vendor " " model, \ + .callback = hdaps_dmi_match_invert, \ + .matches = { \ + DMI_MATCH(DMI_BOARD_VENDOR, vendor), \ + DMI_MATCH(DMI_PRODUCT_VERSION, model) \ + } \ +} /* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match "ThinkPad T42p", so the order of the entries matters. If your ThinkPad is not recognized, please update to latest BIOS. This is especially the case for some R52 ThinkPads. */ static struct dmi_system_id __initdata hdaps_whitelist[] = { - HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p", HDAPS_BOTH_AXES), + HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"), - HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i", HDAPS_BOTH_AXES), - HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61", HDAPS_BOTH_AXES), - HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p", HDAPS_BOTH_AXES), + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i"), + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61"), + HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"), - HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p", HDAPS_BOTH_AXES), + HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"), - HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60", HDAPS_BOTH_AXES), - HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p", HDAPS_BOTH_AXES), - HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61", HDAPS_BOTH_AXES), + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"), + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p"), + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"), - HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad X41", HDAPS_Y_AXIS), - HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60", HDAPS_BOTH_AXES), - HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s", HDAPS_BOTH_AXES), - HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61", HDAPS_BOTH_AXES), + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"), + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"), + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s"), + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"), - HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m", HDAPS_BOTH_AXES), - HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p", HDAPS_BOTH_AXES), + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m"), + HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p"), { .ident = NULL } }; @@ -628,9 +627,8 @@ static void __exit hdaps_exit(void) module_init(hdaps_init); module_exit(hdaps_exit); -module_param_named(invert, hdaps_invert, int, 0); -MODULE_PARM_DESC(invert, "invert data along each axis. 1 invert x-axis, " - "2 invert y-axis, 3 invert both axes."); +module_param_named(invert, hdaps_invert, bool, 0); +MODULE_PARM_DESC(invert, "invert data along each axis"); MODULE_AUTHOR("Robert Love"); MODULE_DESCRIPTION("IBM Hard Drive Active Protection System (HDAPS) driver"); diff --git a/trunk/drivers/hwmon/hp_accel.c b/trunk/drivers/hwmon/hp_accel.c index 55d3dc565be6..29c83b5b9697 100644 --- a/trunk/drivers/hwmon/hp_accel.c +++ b/trunk/drivers/hwmon/hp_accel.c @@ -85,31 +85,25 @@ MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids); /** * lis3lv02d_acpi_init - ACPI _INI method: initialize the device. - * @lis3: pointer to the device struct + * @handle: the handle of the device * - * Returns 0 on success. + * Returns AE_OK on success. */ -int lis3lv02d_acpi_init(struct lis3lv02d *lis3) +acpi_status lis3lv02d_acpi_init(acpi_handle handle) { - struct acpi_device *dev = lis3->bus_priv; - if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI, - NULL, NULL) != AE_OK) - return -EINVAL; - - return 0; + return acpi_evaluate_object(handle, METHOD_NAME__INI, NULL, NULL); } /** * lis3lv02d_acpi_read - ACPI ALRD method: read a register - * @lis3: pointer to the device struct + * @handle: the handle of the device * @reg: the register to read * @ret: result of the operation * - * Returns 0 on success. + * Returns AE_OK on success. */ -int lis3lv02d_acpi_read(struct lis3lv02d *lis3, int reg, u8 *ret) +acpi_status lis3lv02d_acpi_read(acpi_handle handle, int reg, u8 *ret) { - struct acpi_device *dev = lis3->bus_priv; union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; unsigned long long lret; @@ -117,22 +111,21 @@ int lis3lv02d_acpi_read(struct lis3lv02d *lis3, int reg, u8 *ret) arg0.integer.value = reg; - status = acpi_evaluate_integer(dev->handle, "ALRD", &args, &lret); + status = acpi_evaluate_integer(handle, "ALRD", &args, &lret); *ret = lret; - return (status != AE_OK) ? -EINVAL : 0; + return status; } /** * lis3lv02d_acpi_write - ACPI ALWR method: write to a register - * @lis3: pointer to the device struct + * @handle: the handle of the device * @reg: the register to write to * @val: the value to write * - * Returns 0 on success. + * Returns AE_OK on success. */ -int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val) +acpi_status lis3lv02d_acpi_write(acpi_handle handle, int reg, u8 val) { - struct acpi_device *dev = lis3->bus_priv; unsigned long long ret; /* Not used when writting */ union acpi_object in_obj[2]; struct acpi_object_list args = { 2, in_obj }; @@ -142,15 +135,12 @@ int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val) in_obj[1].type = ACPI_TYPE_INTEGER; in_obj[1].integer.value = val; - if (acpi_evaluate_integer(dev->handle, "ALWR", &args, &ret) != AE_OK) - return -EINVAL; - - return 0; + return acpi_evaluate_integer(handle, "ALWR", &args, &ret); } static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi) { - lis3_dev.ac = *((struct axis_conversion *)dmi->driver_data); + adev.ac = *((struct axis_conversion *)dmi->driver_data); printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident); return 1; @@ -197,7 +187,6 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted), AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted), AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left), - AXIS_DMI_MATCH("HP2140", "HP 2140", xy_swap_inverted), AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd), AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd), AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right), @@ -212,8 +201,6 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { PRODUCT_NAME, "HP Pavilion dv5", BOARD_NAME, "3600", y_inverted), - AXIS_DMI_MATCH("DV7", "HP Pavilion dv7", x_inverted), - AXIS_DMI_MATCH("HP8710", "HP Compaq 8710", y_inverted), { NULL, } /* Laptop models without axis info (yet): * "NC6910" "HP Compaq 6910" @@ -227,7 +214,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { static void hpled_set(struct delayed_led_classdev *led_cdev, enum led_brightness value) { - struct acpi_device *dev = lis3_dev.bus_priv; + acpi_handle handle = adev.device->handle; unsigned long long ret; /* Not used when writing */ union acpi_object in_obj[1]; struct acpi_object_list args = { 1, in_obj }; @@ -235,7 +222,7 @@ static void hpled_set(struct delayed_led_classdev *led_cdev, enum led_brightness in_obj[0].type = ACPI_TYPE_INTEGER; in_obj[0].integer.value = !!value; - acpi_evaluate_integer(dev->handle, "ALED", &args, &ret); + acpi_evaluate_integer(handle, "ALED", &args, &ret); } static struct delayed_led_classdev hpled_led = { @@ -267,11 +254,28 @@ static void lis3lv02d_enum_resources(struct acpi_device *device) acpi_status status; status = acpi_walk_resources(device->handle, METHOD_NAME__CRS, - lis3lv02d_get_resource, &lis3_dev.irq); + lis3lv02d_get_resource, &adev.irq); if (ACPI_FAILURE(status)) printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n"); } +static s16 lis3lv02d_read_16(acpi_handle handle, int reg) +{ + u8 lo, hi; + + adev.read(handle, reg - 1, &lo); + adev.read(handle, reg, &hi); + /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ + return (s16)((hi << 8) | lo); +} + +static s16 lis3lv02d_read_8(acpi_handle handle, int reg) +{ + s8 lo; + adev.read(handle, reg, &lo); + return lo; +} + static int lis3lv02d_add(struct acpi_device *device) { int ret; @@ -279,35 +283,51 @@ static int lis3lv02d_add(struct acpi_device *device) if (!device) return -EINVAL; - lis3_dev.bus_priv = device; - lis3_dev.init = lis3lv02d_acpi_init; - lis3_dev.read = lis3lv02d_acpi_read; - lis3_dev.write = lis3lv02d_acpi_write; + adev.device = device; + adev.init = lis3lv02d_acpi_init; + adev.read = lis3lv02d_acpi_read; + adev.write = lis3lv02d_acpi_write; strcpy(acpi_device_name(device), DRIVER_NAME); strcpy(acpi_device_class(device), ACPI_MDPS_CLASS); - device->driver_data = &lis3_dev; - - /* obtain IRQ number of our device from ACPI */ - lis3lv02d_enum_resources(device); + device->driver_data = &adev; + + lis3lv02d_acpi_read(device->handle, WHO_AM_I, &adev.whoami); + switch (adev.whoami) { + case LIS_DOUBLE_ID: + printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n"); + adev.read_data = lis3lv02d_read_16; + adev.mdps_max_val = 2048; + break; + case LIS_SINGLE_ID: + printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n"); + adev.read_data = lis3lv02d_read_8; + adev.mdps_max_val = 128; + break; + default: + printk(KERN_ERR DRIVER_NAME + ": unknown sensor type 0x%X\n", adev.whoami); + return -EINVAL; + } /* If possible use a "standard" axes order */ if (dmi_check_system(lis3lv02d_dmi_ids) == 0) { printk(KERN_INFO DRIVER_NAME ": laptop model unknown, " "using default axes configuration\n"); - lis3_dev.ac = lis3lv02d_axis_normal; + adev.ac = lis3lv02d_axis_normal; } - /* call the core layer do its init */ - ret = lis3lv02d_init_device(&lis3_dev); + INIT_WORK(&hpled_led.work, delayed_set_status_worker); + ret = led_classdev_register(NULL, &hpled_led.led_classdev); if (ret) return ret; - INIT_WORK(&hpled_led.work, delayed_set_status_worker); - ret = led_classdev_register(NULL, &hpled_led.led_classdev); + /* obtain IRQ number of our device from ACPI */ + lis3lv02d_enum_resources(adev.device); + + ret = lis3lv02d_init_device(&adev); if (ret) { - lis3lv02d_joystick_disable(); - lis3lv02d_poweroff(&lis3_dev); flush_work(&hpled_led.work); + led_classdev_unregister(&hpled_led.led_classdev); return ret; } @@ -320,7 +340,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) return -EINVAL; lis3lv02d_joystick_disable(); - lis3lv02d_poweroff(&lis3_dev); + lis3lv02d_poweroff(device->handle); flush_work(&hpled_led.work); led_classdev_unregister(&hpled_led.led_classdev); @@ -333,19 +353,19 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) { /* make sure the device is off when we suspend */ - lis3lv02d_poweroff(&lis3_dev); + lis3lv02d_poweroff(device->handle); return 0; } static int lis3lv02d_resume(struct acpi_device *device) { /* put back the device in the right state (ACPI might turn it on) */ - mutex_lock(&lis3_dev.lock); - if (lis3_dev.usage > 0) - lis3lv02d_poweron(&lis3_dev); + mutex_lock(&adev.lock); + if (adev.usage > 0) + lis3lv02d_poweron(device->handle); else - lis3lv02d_poweroff(&lis3_dev); - mutex_unlock(&lis3_dev.lock); + lis3lv02d_poweroff(device->handle); + mutex_unlock(&adev.lock); return 0; } #else diff --git a/trunk/drivers/hwmon/lis3lv02d.c b/trunk/drivers/hwmon/lis3lv02d.c index 778eb7795983..8bb2158f0453 100644 --- a/trunk/drivers/hwmon/lis3lv02d.c +++ b/trunk/drivers/hwmon/lis3lv02d.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "lis3lv02d.h" @@ -52,30 +53,13 @@ * joystick. */ -struct lis3lv02d lis3_dev = { - .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait), +struct acpi_lis3lv02d adev = { + .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait), }; -EXPORT_SYMBOL_GPL(lis3_dev); +EXPORT_SYMBOL_GPL(adev); -static s16 lis3lv02d_read_8(struct lis3lv02d *lis3, int reg) -{ - s8 lo; - if (lis3->read(lis3, reg, &lo) < 0) - return 0; - - return lo; -} - -static s16 lis3lv02d_read_16(struct lis3lv02d *lis3, int reg) -{ - u8 lo, hi; - - lis3->read(lis3, reg - 1, &lo); - lis3->read(lis3, reg, &hi); - /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ - return (s16)((hi << 8) | lo); -} +static int lis3lv02d_add_fs(struct acpi_device *device); /** * lis3lv02d_get_axis - For the given axis, give the value converted @@ -94,36 +78,36 @@ static inline int lis3lv02d_get_axis(s8 axis, int hw_values[3]) /** * lis3lv02d_get_xyz - Get X, Y and Z axis values from the accelerometer - * @lis3: pointer to the device struct - * @x: where to store the X axis value - * @y: where to store the Y axis value - * @z: where to store the Z axis value + * @handle: the handle to the device + * @x: where to store the X axis value + * @y: where to store the Y axis value + * @z: where to store the Z axis value * * Note that 40Hz input device can eat up about 10% CPU at 800MHZ */ -static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z) +static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z) { int position[3]; - position[0] = lis3_dev.read_data(lis3, OUTX); - position[1] = lis3_dev.read_data(lis3, OUTY); - position[2] = lis3_dev.read_data(lis3, OUTZ); + position[0] = adev.read_data(handle, OUTX); + position[1] = adev.read_data(handle, OUTY); + position[2] = adev.read_data(handle, OUTZ); - *x = lis3lv02d_get_axis(lis3_dev.ac.x, position); - *y = lis3lv02d_get_axis(lis3_dev.ac.y, position); - *z = lis3lv02d_get_axis(lis3_dev.ac.z, position); + *x = lis3lv02d_get_axis(adev.ac.x, position); + *y = lis3lv02d_get_axis(adev.ac.y, position); + *z = lis3lv02d_get_axis(adev.ac.z, position); } -void lis3lv02d_poweroff(struct lis3lv02d *lis3) +void lis3lv02d_poweroff(acpi_handle handle) { - lis3_dev.is_on = 0; + adev.is_on = 0; } EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); -void lis3lv02d_poweron(struct lis3lv02d *lis3) +void lis3lv02d_poweron(acpi_handle handle) { - lis3_dev.is_on = 1; - lis3_dev.init(lis3); + adev.is_on = 1; + adev.init(handle); } EXPORT_SYMBOL_GPL(lis3lv02d_poweron); @@ -132,13 +116,13 @@ EXPORT_SYMBOL_GPL(lis3lv02d_poweron); * device will always be on until a call to lis3lv02d_decrease_use(). Not to be * used from interrupt context. */ -static void lis3lv02d_increase_use(struct lis3lv02d *dev) +static void lis3lv02d_increase_use(struct acpi_lis3lv02d *dev) { mutex_lock(&dev->lock); dev->usage++; if (dev->usage == 1) { if (!dev->is_on) - lis3lv02d_poweron(dev); + lis3lv02d_poweron(dev->device->handle); } mutex_unlock(&dev->lock); } @@ -147,12 +131,12 @@ static void lis3lv02d_increase_use(struct lis3lv02d *dev) * To be called whenever a usage of the device is stopped. * It will make sure to turn off the device when there is not usage. */ -static void lis3lv02d_decrease_use(struct lis3lv02d *dev) +static void lis3lv02d_decrease_use(struct acpi_lis3lv02d *dev) { mutex_lock(&dev->lock); dev->usage--; if (dev->usage == 0) - lis3lv02d_poweroff(dev); + lis3lv02d_poweroff(dev->device->handle); mutex_unlock(&dev->lock); } @@ -163,10 +147,10 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy) * the lid is closed. This leads to interrupts as soon as a little move * is done. */ - atomic_inc(&lis3_dev.count); + atomic_inc(&adev.count); - wake_up_interruptible(&lis3_dev.misc_wait); - kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); + wake_up_interruptible(&adev.misc_wait); + kill_fasync(&adev.async_queue, SIGIO, POLL_IN); return IRQ_HANDLED; } @@ -174,10 +158,10 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file) { int ret; - if (test_and_set_bit(0, &lis3_dev.misc_opened)) + if (test_and_set_bit(0, &adev.misc_opened)) return -EBUSY; /* already open */ - atomic_set(&lis3_dev.count, 0); + atomic_set(&adev.count, 0); /* * The sensor can generate interrupts for free-fall and direction @@ -190,25 +174,25 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file) * io-apic is not configurable (and generates a warning) but I keep it * in case of support for other hardware. */ - ret = request_irq(lis3_dev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING, - DRIVER_NAME, &lis3_dev); + ret = request_irq(adev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING, + DRIVER_NAME, &adev); if (ret) { - clear_bit(0, &lis3_dev.misc_opened); - printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", lis3_dev.irq); + clear_bit(0, &adev.misc_opened); + printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", adev.irq); return -EBUSY; } - lis3lv02d_increase_use(&lis3_dev); - printk("lis3: registered interrupt %d\n", lis3_dev.irq); + lis3lv02d_increase_use(&adev); + printk("lis3: registered interrupt %d\n", adev.irq); return 0; } static int lis3lv02d_misc_release(struct inode *inode, struct file *file) { - fasync_helper(-1, file, 0, &lis3_dev.async_queue); - lis3lv02d_decrease_use(&lis3_dev); - free_irq(lis3_dev.irq, &lis3_dev); - clear_bit(0, &lis3_dev.misc_opened); /* release the device */ + fasync_helper(-1, file, 0, &adev.async_queue); + lis3lv02d_decrease_use(&adev); + free_irq(adev.irq, &adev); + clear_bit(0, &adev.misc_opened); /* release the device */ return 0; } @@ -223,10 +207,10 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, if (count < 1) return -EINVAL; - add_wait_queue(&lis3_dev.misc_wait, &wait); + add_wait_queue(&adev.misc_wait, &wait); while (true) { set_current_state(TASK_INTERRUPTIBLE); - data = atomic_xchg(&lis3_dev.count, 0); + data = atomic_xchg(&adev.count, 0); if (data) break; @@ -256,22 +240,22 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, out: __set_current_state(TASK_RUNNING); - remove_wait_queue(&lis3_dev.misc_wait, &wait); + remove_wait_queue(&adev.misc_wait, &wait); return retval; } static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait) { - poll_wait(file, &lis3_dev.misc_wait, wait); - if (atomic_read(&lis3_dev.count)) + poll_wait(file, &adev.misc_wait, wait); + if (atomic_read(&adev.count)) return POLLIN | POLLRDNORM; return 0; } static int lis3lv02d_misc_fasync(int fd, struct file *file, int on) { - return fasync_helper(fd, file, on, &lis3_dev.async_queue); + return fasync_helper(fd, file, on, &adev.async_queue); } static const struct file_operations lis3lv02d_misc_fops = { @@ -299,12 +283,12 @@ static int lis3lv02d_joystick_kthread(void *data) int x, y, z; while (!kthread_should_stop()) { - lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); - input_report_abs(lis3_dev.idev, ABS_X, x - lis3_dev.xcalib); - input_report_abs(lis3_dev.idev, ABS_Y, y - lis3_dev.ycalib); - input_report_abs(lis3_dev.idev, ABS_Z, z - lis3_dev.zcalib); + lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z); + input_report_abs(adev.idev, ABS_X, x - adev.xcalib); + input_report_abs(adev.idev, ABS_Y, y - adev.ycalib); + input_report_abs(adev.idev, ABS_Z, z - adev.zcalib); - input_sync(lis3_dev.idev); + input_sync(adev.idev); try_to_freeze(); msleep_interruptible(MDPS_POLL_INTERVAL); @@ -315,11 +299,11 @@ static int lis3lv02d_joystick_kthread(void *data) static int lis3lv02d_joystick_open(struct input_dev *input) { - lis3lv02d_increase_use(&lis3_dev); - lis3_dev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d"); - if (IS_ERR(lis3_dev.kthread)) { - lis3lv02d_decrease_use(&lis3_dev); - return PTR_ERR(lis3_dev.kthread); + lis3lv02d_increase_use(&adev); + adev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d"); + if (IS_ERR(adev.kthread)) { + lis3lv02d_decrease_use(&adev); + return PTR_ERR(adev.kthread); } return 0; @@ -327,46 +311,45 @@ static int lis3lv02d_joystick_open(struct input_dev *input) static void lis3lv02d_joystick_close(struct input_dev *input) { - kthread_stop(lis3_dev.kthread); - lis3lv02d_decrease_use(&lis3_dev); + kthread_stop(adev.kthread); + lis3lv02d_decrease_use(&adev); } static inline void lis3lv02d_calibrate_joystick(void) { - lis3lv02d_get_xyz(&lis3_dev, - &lis3_dev.xcalib, &lis3_dev.ycalib, &lis3_dev.zcalib); + lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib); } int lis3lv02d_joystick_enable(void) { int err; - if (lis3_dev.idev) + if (adev.idev) return -EINVAL; - lis3_dev.idev = input_allocate_device(); - if (!lis3_dev.idev) + adev.idev = input_allocate_device(); + if (!adev.idev) return -ENOMEM; lis3lv02d_calibrate_joystick(); - lis3_dev.idev->name = "ST LIS3LV02DL Accelerometer"; - lis3_dev.idev->phys = DRIVER_NAME "/input0"; - lis3_dev.idev->id.bustype = BUS_HOST; - lis3_dev.idev->id.vendor = 0; - lis3_dev.idev->dev.parent = &lis3_dev.pdev->dev; - lis3_dev.idev->open = lis3lv02d_joystick_open; - lis3_dev.idev->close = lis3lv02d_joystick_close; + adev.idev->name = "ST LIS3LV02DL Accelerometer"; + adev.idev->phys = DRIVER_NAME "/input0"; + adev.idev->id.bustype = BUS_HOST; + adev.idev->id.vendor = 0; + adev.idev->dev.parent = &adev.pdev->dev; + adev.idev->open = lis3lv02d_joystick_open; + adev.idev->close = lis3lv02d_joystick_close; - set_bit(EV_ABS, lis3_dev.idev->evbit); - input_set_abs_params(lis3_dev.idev, ABS_X, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); - input_set_abs_params(lis3_dev.idev, ABS_Y, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); - input_set_abs_params(lis3_dev.idev, ABS_Z, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); + set_bit(EV_ABS, adev.idev->evbit); + input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); + input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); + input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); - err = input_register_device(lis3_dev.idev); + err = input_register_device(adev.idev); if (err) { - input_free_device(lis3_dev.idev); - lis3_dev.idev = NULL; + input_free_device(adev.idev); + adev.idev = NULL; } return err; @@ -375,40 +358,71 @@ EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable); void lis3lv02d_joystick_disable(void) { - if (!lis3_dev.idev) + if (!adev.idev) return; misc_deregister(&lis3lv02d_misc_device); - input_unregister_device(lis3_dev.idev); - lis3_dev.idev = NULL; + input_unregister_device(adev.idev); + adev.idev = NULL; } EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); +/* + * Initialise the accelerometer and the various subsystems. + * Should be rather independant of the bus system. + */ +int lis3lv02d_init_device(struct acpi_lis3lv02d *dev) +{ + mutex_init(&dev->lock); + lis3lv02d_add_fs(dev->device); + lis3lv02d_increase_use(dev); + + if (lis3lv02d_joystick_enable()) + printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); + + printk("lis3_init_device: irq %d\n", dev->irq); + + /* if we did not get an IRQ from ACPI - we have nothing more to do */ + if (!dev->irq) { + printk(KERN_ERR DRIVER_NAME + ": No IRQ in ACPI. Disabling /dev/freefall\n"); + goto out; + } + + printk("lis3: registering device\n"); + if (misc_register(&lis3lv02d_misc_device)) + printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); +out: + lis3lv02d_decrease_use(dev); + return 0; +} +EXPORT_SYMBOL_GPL(lis3lv02d_init_device); + /* Sysfs stuff */ static ssize_t lis3lv02d_position_show(struct device *dev, struct device_attribute *attr, char *buf) { int x, y, z; - lis3lv02d_increase_use(&lis3_dev); - lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); - lis3lv02d_decrease_use(&lis3_dev); + lis3lv02d_increase_use(&adev); + lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z); + lis3lv02d_decrease_use(&adev); return sprintf(buf, "(%d,%d,%d)\n", x, y, z); } static ssize_t lis3lv02d_calibrate_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "(%d,%d,%d)\n", lis3_dev.xcalib, lis3_dev.ycalib, lis3_dev.zcalib); + return sprintf(buf, "(%d,%d,%d)\n", adev.xcalib, adev.ycalib, adev.zcalib); } static ssize_t lis3lv02d_calibrate_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - lis3lv02d_increase_use(&lis3_dev); + lis3lv02d_increase_use(&adev); lis3lv02d_calibrate_joystick(); - lis3lv02d_decrease_use(&lis3_dev); + lis3lv02d_decrease_use(&adev); return count; } @@ -420,9 +434,9 @@ static ssize_t lis3lv02d_rate_show(struct device *dev, u8 ctrl; int val; - lis3lv02d_increase_use(&lis3_dev); - lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); - lis3lv02d_decrease_use(&lis3_dev); + lis3lv02d_increase_use(&adev); + adev.read(adev.device->handle, CTRL_REG1, &ctrl); + lis3lv02d_decrease_use(&adev); val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4; return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]); } @@ -444,73 +458,23 @@ static struct attribute_group lis3lv02d_attribute_group = { }; -static int lis3lv02d_add_fs(struct lis3lv02d *lis3) +static int lis3lv02d_add_fs(struct acpi_device *device) { - lis3_dev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); - if (IS_ERR(lis3_dev.pdev)) - return PTR_ERR(lis3_dev.pdev); + adev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); + if (IS_ERR(adev.pdev)) + return PTR_ERR(adev.pdev); - return sysfs_create_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group); + return sysfs_create_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group); } int lis3lv02d_remove_fs(void) { - sysfs_remove_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group); - platform_device_unregister(lis3_dev.pdev); + sysfs_remove_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group); + platform_device_unregister(adev.pdev); return 0; } EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); -/* - * Initialise the accelerometer and the various subsystems. - * Should be rather independant of the bus system. - */ -int lis3lv02d_init_device(struct lis3lv02d *dev) -{ - dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I); - - switch (dev->whoami) { - case LIS_DOUBLE_ID: - printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n"); - dev->read_data = lis3lv02d_read_16; - dev->mdps_max_val = 2048; - break; - case LIS_SINGLE_ID: - printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n"); - dev->read_data = lis3lv02d_read_8; - dev->mdps_max_val = 128; - break; - default: - printk(KERN_ERR DRIVER_NAME - ": unknown sensor type 0x%X\n", lis3_dev.whoami); - return -EINVAL; - } - - mutex_init(&dev->lock); - lis3lv02d_add_fs(dev); - lis3lv02d_increase_use(dev); - - if (lis3lv02d_joystick_enable()) - printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); - - printk("lis3_init_device: irq %d\n", dev->irq); - - /* bail if we did not get an IRQ from the bus layer */ - if (!dev->irq) { - printk(KERN_ERR DRIVER_NAME - ": No IRQ. Disabling /dev/freefall\n"); - goto out; - } - - printk("lis3: registering device\n"); - if (misc_register(&lis3lv02d_misc_device)) - printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); -out: - lis3lv02d_decrease_use(dev); - return 0; -} -EXPORT_SYMBOL_GPL(lis3lv02d_init_device); - MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver"); MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/hwmon/lis3lv02d.h b/trunk/drivers/hwmon/lis3lv02d.h index 745ec96806d4..75972bf372ff 100644 --- a/trunk/drivers/hwmon/lis3lv02d.h +++ b/trunk/drivers/hwmon/lis3lv02d.h @@ -159,14 +159,14 @@ struct axis_conversion { s8 z; }; -struct lis3lv02d { - void *bus_priv; /* used by the bus layer only */ - int (*init) (struct lis3lv02d *lis3); - int (*write) (struct lis3lv02d *lis3, int reg, u8 val); - int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret); +struct acpi_lis3lv02d { + struct acpi_device *device; /* The ACPI device */ + acpi_status (*init) (acpi_handle handle); + acpi_status (*write) (acpi_handle handle, int reg, u8 val); + acpi_status (*read) (acpi_handle handle, int reg, u8 *ret); u8 whoami; /* 3Ah: 2-byte registries, 3Bh: 1-byte registries */ - s16 (*read_data) (struct lis3lv02d *lis3, int reg); + s16 (*read_data) (acpi_handle handle, int reg); int mdps_max_val; struct input_dev *idev; /* input device */ @@ -187,11 +187,11 @@ struct lis3lv02d { unsigned long misc_opened; /* bit0: whether the device is open */ }; -int lis3lv02d_init_device(struct lis3lv02d *lis3); +int lis3lv02d_init_device(struct acpi_lis3lv02d *dev); int lis3lv02d_joystick_enable(void); void lis3lv02d_joystick_disable(void); -void lis3lv02d_poweroff(struct lis3lv02d *lis3); -void lis3lv02d_poweron(struct lis3lv02d *lis3); +void lis3lv02d_poweroff(acpi_handle handle); +void lis3lv02d_poweron(acpi_handle handle); int lis3lv02d_remove_fs(void); -extern struct lis3lv02d lis3_dev; +extern struct acpi_lis3lv02d adev; diff --git a/trunk/drivers/hwmon/lis3lv02d_spi.c b/trunk/drivers/hwmon/lis3lv02d_spi.c deleted file mode 100644 index 07ae74b0e191..000000000000 --- a/trunk/drivers/hwmon/lis3lv02d_spi.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * lis3lv02d_spi - SPI glue layer for lis3lv02d - * - * Copyright (c) 2009 Daniel Mack - * - * 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 - * publishhed by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "lis3lv02d.h" - -#define DRV_NAME "lis3lv02d_spi" -#define LIS3_SPI_READ 0x80 - -static int lis3_spi_read(struct lis3lv02d *lis3, int reg, u8 *v) -{ - struct spi_device *spi = lis3->bus_priv; - int ret = spi_w8r8(spi, reg | LIS3_SPI_READ); - if (ret < 0) - return -EINVAL; - - *v = (u8) ret; - return 0; -} - -static int lis3_spi_write(struct lis3lv02d *lis3, int reg, u8 val) -{ - u8 tmp[2] = { reg, val }; - struct spi_device *spi = lis3->bus_priv; - return spi_write(spi, tmp, sizeof(tmp)); -} - -static int lis3_spi_init(struct lis3lv02d *lis3) -{ - u8 reg; - int ret; - - /* power up the device */ - ret = lis3->read(lis3, CTRL_REG1, ®); - if (ret < 0) - return ret; - - reg |= CTRL1_PD0; - return lis3->write(lis3, CTRL_REG1, reg); -} - -static struct axis_conversion lis3lv02d_axis_normal = { 1, 2, 3 }; - -static int __devinit lis302dl_spi_probe(struct spi_device *spi) -{ - int ret; - - spi->bits_per_word = 8; - spi->mode = SPI_MODE_0; - ret = spi_setup(spi); - if (ret < 0) - return ret; - - lis3_dev.bus_priv = spi; - lis3_dev.init = lis3_spi_init; - lis3_dev.read = lis3_spi_read; - lis3_dev.write = lis3_spi_write; - lis3_dev.irq = spi->irq; - lis3_dev.ac = lis3lv02d_axis_normal; - spi_set_drvdata(spi, &lis3_dev); - - ret = lis3lv02d_init_device(&lis3_dev); - return ret; -} - -static int __devexit lis302dl_spi_remove(struct spi_device *spi) -{ - struct lis3lv02d *lis3 = spi_get_drvdata(spi); - lis3lv02d_joystick_disable(); - lis3lv02d_poweroff(lis3); - return 0; -} - -static struct spi_driver lis302dl_spi_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = lis302dl_spi_probe, - .remove = __devexit_p(lis302dl_spi_remove), -}; - -static int __init lis302dl_init(void) -{ - return spi_register_driver(&lis302dl_spi_driver); -} - -static void __exit lis302dl_exit(void) -{ - spi_unregister_driver(&lis302dl_spi_driver); -} - -module_init(lis302dl_init); -module_exit(lis302dl_exit); - -MODULE_AUTHOR("Daniel Mack "); -MODULE_DESCRIPTION("lis3lv02d SPI glue layer"); -MODULE_LICENSE("GPL"); - diff --git a/trunk/drivers/hwmon/lm95241.c b/trunk/drivers/hwmon/lm95241.c deleted file mode 100644 index 091d95f38aaa..000000000000 --- a/trunk/drivers/hwmon/lm95241.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * lm95241.c - Part of lm_sensors, Linux kernel modules for hardware - * monitoring - * Copyright (C) 2008 Davide Rizzo - * - * Based on the max1619 driver. The LM95241 is a sensor chip made by National - * Semiconductors. - * It reports up to three temperatures (its own plus up to - * two external ones). Complete datasheet can be - * obtained from National's website at: - * http://www.national.com/ds.cgi/LM/LM95241.pdf - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const unsigned short normal_i2c[] = { - 0x19, 0x2a, 0x2b, I2C_CLIENT_END}; - -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(lm95241); - -/* LM95241 registers */ -#define LM95241_REG_R_MAN_ID 0xFE -#define LM95241_REG_R_CHIP_ID 0xFF -#define LM95241_REG_R_STATUS 0x02 -#define LM95241_REG_RW_CONFIG 0x03 -#define LM95241_REG_RW_REM_FILTER 0x06 -#define LM95241_REG_RW_TRUTHERM 0x07 -#define LM95241_REG_W_ONE_SHOT 0x0F -#define LM95241_REG_R_LOCAL_TEMPH 0x10 -#define LM95241_REG_R_REMOTE1_TEMPH 0x11 -#define LM95241_REG_R_REMOTE2_TEMPH 0x12 -#define LM95241_REG_R_LOCAL_TEMPL 0x20 -#define LM95241_REG_R_REMOTE1_TEMPL 0x21 -#define LM95241_REG_R_REMOTE2_TEMPL 0x22 -#define LM95241_REG_RW_REMOTE_MODEL 0x30 - -/* LM95241 specific bitfields */ -#define CFG_STOP 0x40 -#define CFG_CR0076 0x00 -#define CFG_CR0182 0x10 -#define CFG_CR1000 0x20 -#define CFG_CR2700 0x30 -#define R1MS_SHIFT 0 -#define R2MS_SHIFT 2 -#define R1MS_MASK (0x01 << (R1MS_SHIFT)) -#define R2MS_MASK (0x01 << (R2MS_SHIFT)) -#define R1DF_SHIFT 1 -#define R2DF_SHIFT 2 -#define R1DF_MASK (0x01 << (R1DF_SHIFT)) -#define R2DF_MASK (0x01 << (R2DF_SHIFT)) -#define R1FE_MASK 0x01 -#define R2FE_MASK 0x05 -#define TT1_SHIFT 0 -#define TT2_SHIFT 4 -#define TT_OFF 0 -#define TT_ON 1 -#define TT_MASK 7 -#define MANUFACTURER_ID 0x01 -#define DEFAULT_REVISION 0xA4 - -/* Conversions and various macros */ -#define TEMP_FROM_REG(val_h, val_l) (((val_h) & 0x80 ? (val_h) - 0x100 : \ - (val_h)) * 1000 + (val_l) * 1000 / 256) - -/* Functions declaration */ -static int lm95241_attach_adapter(struct i2c_adapter *adapter); -static int lm95241_detect(struct i2c_adapter *adapter, int address, - int kind); -static void lm95241_init_client(struct i2c_client *client); -static int lm95241_detach_client(struct i2c_client *client); -static struct lm95241_data *lm95241_update_device(struct device *dev); - -/* Driver data (common to all clients) */ -static struct i2c_driver lm95241_driver = { - .driver = { - .name = "lm95241", - }, - .attach_adapter = lm95241_attach_adapter, - .detach_client = lm95241_detach_client, -}; - -/* Client data (each client gets its own) */ -struct lm95241_data { - struct i2c_client client; - struct device *hwmon_dev; - struct mutex update_lock; - unsigned long last_updated, rate; /* in jiffies */ - char valid; /* zero until following fields are valid */ - /* registers values */ - u8 local_h, local_l; /* local */ - u8 remote1_h, remote1_l; /* remote1 */ - u8 remote2_h, remote2_l; /* remote2 */ - u8 config, model, trutherm; -}; - -/* Sysfs stuff */ -#define show_temp(value) \ -static ssize_t show_##value(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct lm95241_data *data = lm95241_update_device(dev); \ - snprintf(buf, PAGE_SIZE - 1, "%d\n", \ - TEMP_FROM_REG(data->value##_h, data->value##_l)); \ - return strlen(buf); \ -} -show_temp(local); -show_temp(remote1); -show_temp(remote2); - -static ssize_t show_rate(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct lm95241_data *data = lm95241_update_device(dev); - - snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->rate / HZ); - return strlen(buf); -} - -static ssize_t set_rate(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95241_data *data = i2c_get_clientdata(client); - - strict_strtol(buf, 10, &data->rate); - data->rate = data->rate * HZ / 1000; - - return count; -} - -#define show_type(flag) \ -static ssize_t show_type##flag(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct lm95241_data *data = i2c_get_clientdata(client); \ -\ - snprintf(buf, PAGE_SIZE - 1, \ - data->model & R##flag##MS_MASK ? "1\n" : "2\n"); \ - return strlen(buf); \ -} -show_type(1); -show_type(2); - -#define show_min(flag) \ -static ssize_t show_min##flag(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct lm95241_data *data = i2c_get_clientdata(client); \ -\ - snprintf(buf, PAGE_SIZE - 1, \ - data->config & R##flag##DF_MASK ? \ - "-127000\n" : "0\n"); \ - return strlen(buf); \ -} -show_min(1); -show_min(2); - -#define show_max(flag) \ -static ssize_t show_max##flag(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct lm95241_data *data = i2c_get_clientdata(client); \ -\ - snprintf(buf, PAGE_SIZE - 1, \ - data->config & R##flag##DF_MASK ? \ - "127000\n" : "255000\n"); \ - return strlen(buf); \ -} -show_max(1); -show_max(2); - -#define set_type(flag) \ -static ssize_t set_type##flag(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct lm95241_data *data = i2c_get_clientdata(client); \ -\ - long val; \ - strict_strtol(buf, 10, &val); \ -\ - if ((val == 1) || (val == 2)) { \ -\ - mutex_lock(&data->update_lock); \ -\ - data->trutherm &= ~(TT_MASK << TT##flag##_SHIFT); \ - if (val == 1) { \ - data->model |= R##flag##MS_MASK; \ - data->trutherm |= (TT_ON << TT##flag##_SHIFT); \ - } \ - else { \ - data->model &= ~R##flag##MS_MASK; \ - data->trutherm |= (TT_OFF << TT##flag##_SHIFT); \ - } \ -\ - data->valid = 0; \ -\ - i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, \ - data->model); \ - i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, \ - data->trutherm); \ -\ - mutex_unlock(&data->update_lock); \ -\ - } \ - return count; \ -} -set_type(1); -set_type(2); - -#define set_min(flag) \ -static ssize_t set_min##flag(struct device *dev, \ - struct device_attribute *devattr, const char *buf, size_t count) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct lm95241_data *data = i2c_get_clientdata(client); \ -\ - long val; \ - strict_strtol(buf, 10, &val); \ -\ - mutex_lock(&data->update_lock); \ -\ - if (val < 0) \ - data->config |= R##flag##DF_MASK; \ - else \ - data->config &= ~R##flag##DF_MASK; \ -\ - data->valid = 0; \ -\ - i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \ - data->config); \ -\ - mutex_unlock(&data->update_lock); \ -\ - return count; \ -} -set_min(1); -set_min(2); - -#define set_max(flag) \ -static ssize_t set_max##flag(struct device *dev, \ - struct device_attribute *devattr, const char *buf, size_t count) \ -{ \ - struct i2c_client *client = to_i2c_client(dev); \ - struct lm95241_data *data = i2c_get_clientdata(client); \ -\ - long val; \ - strict_strtol(buf, 10, &val); \ -\ - mutex_lock(&data->update_lock); \ -\ - if (val <= 127000) \ - data->config |= R##flag##DF_MASK; \ - else \ - data->config &= ~R##flag##DF_MASK; \ -\ - data->valid = 0; \ -\ - i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \ - data->config); \ -\ - mutex_unlock(&data->update_lock); \ -\ - return count; \ -} -set_max(1); -set_max(2); - -static DEVICE_ATTR(temp1_input, S_IRUGO, show_local, NULL); -static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote1, NULL); -static DEVICE_ATTR(temp3_input, S_IRUGO, show_remote2, NULL); -static DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type1, set_type1); -static DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type2, set_type2); -static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min1, set_min1); -static DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min2, set_min2); -static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max1, set_max1); -static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max2, set_max2); -static DEVICE_ATTR(rate, S_IWUSR | S_IRUGO, show_rate, set_rate); - -static struct attribute *lm95241_attributes[] = { - &dev_attr_temp1_input.attr, - &dev_attr_temp2_input.attr, - &dev_attr_temp3_input.attr, - &dev_attr_temp2_type.attr, - &dev_attr_temp3_type.attr, - &dev_attr_temp2_min.attr, - &dev_attr_temp3_min.attr, - &dev_attr_temp2_max.attr, - &dev_attr_temp3_max.attr, - &dev_attr_rate.attr, - NULL -}; - -static const struct attribute_group lm95241_group = { - .attrs = lm95241_attributes, -}; - -/* Init/exit code */ -static int lm95241_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, lm95241_detect); -} - -/* - * The following function does more than just detection. If detection - * succeeds, it also registers the new chip. - */ -static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *new_client; - struct lm95241_data *data; - int err = 0; - const char *name = ""; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - goto exit; - - data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } - - /* The common I2C client data is placed right before the - LM95241-specific data. */ - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &lm95241_driver; - new_client->flags = 0; - - /* - * Now we do the remaining detection. A negative kind means that - * the driver was loaded with no force parameter (default), so we - * must both detect and identify the chip. A zero kind means that - * the driver was loaded with the force parameter, the detection - * step shall be skipped. A positive kind means that the driver - * was loaded with the force parameter and a given kind of chip is - * requested, so both the detection and the identification steps - * are skipped. - */ - if (kind < 0) { /* detection */ - if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID) - != MANUFACTURER_ID) - || (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID) - < DEFAULT_REVISION)) { - dev_dbg(&adapter->dev, - "LM95241 detection failed at 0x%02x.\n", - address); - goto exit_free; - } - } - - if (kind <= 0) { /* identification */ - if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID) - == MANUFACTURER_ID) - && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID) - >= DEFAULT_REVISION)) { - - kind = lm95241; - - if (kind <= 0) { /* identification failed */ - dev_info(&adapter->dev, "Unsupported chip\n"); - goto exit_free; - } - } - } - - if (kind == lm95241) - name = "lm95241"; - - /* We can fill in the remaining client fields */ - strlcpy(new_client->name, name, I2C_NAME_SIZE); - data->valid = 0; - mutex_init(&data->update_lock); - - /* Tell the I2C layer a new client has arrived */ - err = i2c_attach_client(new_client); - if (err) - goto exit_free; - - /* Initialize the LM95241 chip */ - lm95241_init_client(new_client); - - /* Register sysfs hooks */ - err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group); - if (err) - goto exit_detach; - - data->hwmon_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->hwmon_dev)) { - err = PTR_ERR(data->hwmon_dev); - goto exit_remove_files; - } - - return 0; - -exit_remove_files: - sysfs_remove_group(&new_client->dev.kobj, &lm95241_group); -exit_detach: - i2c_detach_client(new_client); -exit_free: - kfree(data); -exit: - return err; -} - -static void lm95241_init_client(struct i2c_client *client) -{ - struct lm95241_data *data = i2c_get_clientdata(client); - - data->rate = HZ; /* 1 sec default */ - data->valid = 0; - data->config = CFG_CR0076; - data->model = 0; - data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT); - - i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, - data->config); - i2c_smbus_write_byte_data(client, LM95241_REG_RW_REM_FILTER, - R1FE_MASK | R2FE_MASK); - i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, - data->trutherm); - i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, - data->model); -} - -static int lm95241_detach_client(struct i2c_client *client) -{ - struct lm95241_data *data = i2c_get_clientdata(client); - int err; - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &lm95241_group); - - err = i2c_detach_client(client); - if (err) - return err; - - kfree(data); - return 0; -} - -static struct lm95241_data *lm95241_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lm95241_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + data->rate) || - !data->valid) { - dev_dbg(&client->dev, "Updating lm95241 data.\n"); - data->local_h = - i2c_smbus_read_byte_data(client, - LM95241_REG_R_LOCAL_TEMPH); - data->local_l = - i2c_smbus_read_byte_data(client, - LM95241_REG_R_LOCAL_TEMPL); - data->remote1_h = - i2c_smbus_read_byte_data(client, - LM95241_REG_R_REMOTE1_TEMPH); - data->remote1_l = - i2c_smbus_read_byte_data(client, - LM95241_REG_R_REMOTE1_TEMPL); - data->remote2_h = - i2c_smbus_read_byte_data(client, - LM95241_REG_R_REMOTE2_TEMPH); - data->remote2_l = - i2c_smbus_read_byte_data(client, - LM95241_REG_R_REMOTE2_TEMPL); - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - - return data; -} - -static int __init sensors_lm95241_init(void) -{ - return i2c_add_driver(&lm95241_driver); -} - -static void __exit sensors_lm95241_exit(void) -{ - i2c_del_driver(&lm95241_driver); -} - -MODULE_AUTHOR("Davide Rizzo "); -MODULE_DESCRIPTION("LM95241 sensor driver"); -MODULE_LICENSE("GPL"); - -module_init(sensors_lm95241_init); -module_exit(sensors_lm95241_exit); diff --git a/trunk/drivers/hwmon/ltc4215.c b/trunk/drivers/hwmon/ltc4215.c deleted file mode 100644 index 9386e2a39211..000000000000 --- a/trunk/drivers/hwmon/ltc4215.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Driver for Linear Technology LTC4215 I2C Hot Swap Controller - * - * Copyright (C) 2009 Ira W. Snyder - * - * 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 of the License. - * - * Datasheet: - * http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1163,P17572,D12697 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(ltc4215); - -/* Here are names of the chip's registers (a.k.a. commands) */ -enum ltc4215_cmd { - LTC4215_CONTROL = 0x00, /* rw */ - LTC4215_ALERT = 0x01, /* rw */ - LTC4215_STATUS = 0x02, /* ro */ - LTC4215_FAULT = 0x03, /* rw */ - LTC4215_SENSE = 0x04, /* rw */ - LTC4215_SOURCE = 0x05, /* rw */ - LTC4215_ADIN = 0x06, /* rw */ -}; - -struct ltc4215_data { - struct device *hwmon_dev; - - struct mutex update_lock; - bool valid; - unsigned long last_updated; /* in jiffies */ - - /* Registers */ - u8 regs[7]; -}; - -static struct ltc4215_data *ltc4215_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ltc4215_data *data = i2c_get_clientdata(client); - s32 val; - int i; - - mutex_lock(&data->update_lock); - - /* The chip's A/D updates 10 times per second */ - if (time_after(jiffies, data->last_updated + HZ / 10) || !data->valid) { - - dev_dbg(&client->dev, "Starting ltc4215 update\n"); - - /* Read all registers */ - for (i = 0; i < ARRAY_SIZE(data->regs); i++) { - val = i2c_smbus_read_byte_data(client, i); - if (unlikely(val < 0)) - data->regs[i] = 0; - else - data->regs[i] = val; - } - - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - - return data; -} - -/* Return the voltage from the given register in millivolts */ -static int ltc4215_get_voltage(struct device *dev, u8 reg) -{ - struct ltc4215_data *data = ltc4215_update_device(dev); - const u8 regval = data->regs[reg]; - u32 voltage = 0; - - switch (reg) { - case LTC4215_SENSE: - /* 151 uV per increment */ - voltage = regval * 151 / 1000; - break; - case LTC4215_SOURCE: - /* 60.5 mV per increment */ - voltage = regval * 605 / 10; - break; - case LTC4215_ADIN: - /* The ADIN input is divided by 12.5, and has 4.82 mV - * per increment, so we have the additional multiply */ - voltage = regval * 482 * 125 / 1000; - break; - default: - /* If we get here, the developer messed up */ - WARN_ON_ONCE(1); - break; - } - - return voltage; -} - -/* Return the current from the sense resistor in mA */ -static unsigned int ltc4215_get_current(struct device *dev) -{ - struct ltc4215_data *data = ltc4215_update_device(dev); - - /* The strange looking conversions that follow are fixed-point - * math, since we cannot do floating point in the kernel. - * - * Step 1: convert sense register to microVolts - * Step 2: convert voltage to milliAmperes - * - * If you play around with the V=IR equation, you come up with - * the following: X uV / Y mOhm == Z mA - * - * With the resistors that are fractions of a milliOhm, we multiply - * the voltage and resistance by 10, to shift the decimal point. - * Now we can use the normal division operator again. - */ - - /* Calculate voltage in microVolts (151 uV per increment) */ - const unsigned int voltage = data->regs[LTC4215_SENSE] * 151; - - /* Calculate current in milliAmperes (4 milliOhm sense resistor) */ - const unsigned int curr = voltage / 4; - - return curr; -} - -static ssize_t ltc4215_show_voltage(struct device *dev, - struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - const int voltage = ltc4215_get_voltage(dev, attr->index); - - return snprintf(buf, PAGE_SIZE, "%d\n", voltage); -} - -static ssize_t ltc4215_show_current(struct device *dev, - struct device_attribute *da, - char *buf) -{ - const unsigned int curr = ltc4215_get_current(dev); - - return snprintf(buf, PAGE_SIZE, "%u\n", curr); -} - -static ssize_t ltc4215_show_power(struct device *dev, - struct device_attribute *da, - char *buf) -{ - const unsigned int curr = ltc4215_get_current(dev); - const int output_voltage = ltc4215_get_voltage(dev, LTC4215_ADIN); - - /* current in mA * voltage in mV == power in uW */ - const unsigned int power = abs(output_voltage * curr); - - return snprintf(buf, PAGE_SIZE, "%u\n", power); -} - -static ssize_t ltc4215_show_alarm(struct device *dev, - struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(da); - struct ltc4215_data *data = ltc4215_update_device(dev); - const u8 reg = data->regs[attr->index]; - const u32 mask = attr->nr; - - return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0); -} - -/* These macros are used below in constructing device attribute objects - * for use with sysfs_create_group() to make a sysfs device file - * for each register. - */ - -#define LTC4215_VOLTAGE(name, ltc4215_cmd_idx) \ - static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ - ltc4215_show_voltage, NULL, ltc4215_cmd_idx) - -#define LTC4215_CURRENT(name) \ - static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ - ltc4215_show_current, NULL, 0); - -#define LTC4215_POWER(name) \ - static SENSOR_DEVICE_ATTR(name, S_IRUGO, \ - ltc4215_show_power, NULL, 0); - -#define LTC4215_ALARM(name, mask, reg) \ - static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, \ - ltc4215_show_alarm, NULL, (mask), reg) - -/* Construct a sensor_device_attribute structure for each register */ - -/* Current */ -LTC4215_CURRENT(curr1_input); -LTC4215_ALARM(curr1_max_alarm, (1 << 2), LTC4215_STATUS); - -/* Power (virtual) */ -LTC4215_POWER(power1_input); -LTC4215_ALARM(power1_alarm, (1 << 3), LTC4215_STATUS); - -/* Input Voltage */ -LTC4215_VOLTAGE(in1_input, LTC4215_ADIN); -LTC4215_ALARM(in1_max_alarm, (1 << 0), LTC4215_STATUS); -LTC4215_ALARM(in1_min_alarm, (1 << 1), LTC4215_STATUS); - -/* Output Voltage */ -LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE); - -/* Finally, construct an array of pointers to members of the above objects, - * as required for sysfs_create_group() - */ -static struct attribute *ltc4215_attributes[] = { - &sensor_dev_attr_curr1_input.dev_attr.attr, - &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, - - &sensor_dev_attr_power1_input.dev_attr.attr, - &sensor_dev_attr_power1_alarm.dev_attr.attr, - - &sensor_dev_attr_in1_input.dev_attr.attr, - &sensor_dev_attr_in1_max_alarm.dev_attr.attr, - &sensor_dev_attr_in1_min_alarm.dev_attr.attr, - - &sensor_dev_attr_in2_input.dev_attr.attr, - - NULL, -}; - -static const struct attribute_group ltc4215_group = { - .attrs = ltc4215_attributes, -}; - -static int ltc4215_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct ltc4215_data *data; - int ret; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - ret = -ENOMEM; - goto out_kzalloc; - } - - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - /* Initialize the LTC4215 chip */ - /* TODO */ - - /* Register sysfs hooks */ - ret = sysfs_create_group(&client->dev.kobj, <c4215_group); - if (ret) - goto out_sysfs_create_group; - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - ret = PTR_ERR(data->hwmon_dev); - goto out_hwmon_device_register; - } - - return 0; - -out_hwmon_device_register: - sysfs_remove_group(&client->dev.kobj, <c4215_group); -out_sysfs_create_group: - kfree(data); -out_kzalloc: - return ret; -} - -static int ltc4215_remove(struct i2c_client *client) -{ - struct ltc4215_data *data = i2c_get_clientdata(client); - - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, <c4215_group); - - kfree(data); - - return 0; -} - -static int ltc4215_detect(struct i2c_client *client, - int kind, - struct i2c_board_info *info) -{ - struct i2c_adapter *adapter = client->adapter; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; - - if (kind < 0) { /* probed detection - check the chip type */ - s32 v; /* 8 bits from the chip, or -ERRNO */ - - /* - * Register 0x01 bit b7 is reserved, expect 0 - * Register 0x03 bit b6 and b7 are reserved, expect 0 - */ - v = i2c_smbus_read_byte_data(client, LTC4215_ALERT); - if (v < 0 || (v & (1 << 7)) != 0) - return -ENODEV; - - v = i2c_smbus_read_byte_data(client, LTC4215_FAULT); - if (v < 0 || (v & ((1 << 6) | (1 << 7))) != 0) - return -ENODEV; - } - - strlcpy(info->type, "ltc4215", I2C_NAME_SIZE); - dev_info(&adapter->dev, "ltc4215 %s at address 0x%02x\n", - kind < 0 ? "probed" : "forced", - client->addr); - - return 0; -} - -static const struct i2c_device_id ltc4215_id[] = { - { "ltc4215", ltc4215 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, ltc4215_id); - -/* This is the driver that will be inserted */ -static struct i2c_driver ltc4215_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "ltc4215", - }, - .probe = ltc4215_probe, - .remove = ltc4215_remove, - .id_table = ltc4215_id, - .detect = ltc4215_detect, - .address_data = &addr_data, -}; - -static int __init ltc4215_init(void) -{ - return i2c_add_driver(<c4215_driver); -} - -static void __exit ltc4215_exit(void) -{ - i2c_del_driver(<c4215_driver); -} - -MODULE_AUTHOR("Ira W. Snyder "); -MODULE_DESCRIPTION("LTC4215 driver"); -MODULE_LICENSE("GPL"); - -module_init(ltc4215_init); -module_exit(ltc4215_exit); diff --git a/trunk/drivers/hwmon/w83627ehf.c b/trunk/drivers/hwmon/w83627ehf.c index e64b42058b21..feae743ba991 100644 --- a/trunk/drivers/hwmon/w83627ehf.c +++ b/trunk/drivers/hwmon/w83627ehf.c @@ -36,7 +36,6 @@ w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 0x8860 0xa1 w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 - w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 */ #include @@ -53,13 +52,12 @@ #include #include "lm75.h" -enum kinds { w83627ehf, w83627dhg, w83667hg }; +enum kinds { w83627ehf, w83627dhg }; /* used to set data->name = w83627ehf_device_names[data->sio_kind] */ static const char * w83627ehf_device_names[] = { "w83627ehf", "w83627dhg", - "w83667hg", }; static unsigned short force_id; @@ -73,7 +71,6 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID"); */ #define W83627EHF_LD_HWM 0x0b -#define W83667HG_LD_VID 0x0d #define SIO_REG_LDSEL 0x07 /* Logical device select */ #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ @@ -86,7 +83,6 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID"); #define SIO_W83627EHF_ID 0x8850 #define SIO_W83627EHG_ID 0x8860 #define SIO_W83627DHG_ID 0xa020 -#define SIO_W83667HG_ID 0xa510 #define SIO_ID_MASK 0xFFF0 static inline void @@ -293,7 +289,6 @@ struct w83627ehf_data { u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ u8 pwm_enable[4]; /* 1->manual 2->thermal cruise (also called SmartFan I) */ - u8 pwm_num; /* number of pwm */ u8 pwm[4]; u8 target_temp[4]; u8 tolerance[4]; @@ -303,9 +298,6 @@ struct w83627ehf_data { u8 vid; u8 vrm; - - u8 temp3_disable; - u8 in6_skip; }; struct w83627ehf_sio_data { @@ -874,37 +866,25 @@ show_temp_type(struct device *dev, struct device_attribute *attr, char *buf) return sprintf(buf, "%d\n", (int)data->temp_type[nr]); } -static struct sensor_device_attribute sda_temp_input[] = { +static struct sensor_device_attribute sda_temp[] = { SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0), SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0), SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 1), -}; - -static struct sensor_device_attribute sda_temp_max[] = { SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1_max, store_temp1_max, 0), SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max, store_temp_max, 0), SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max, store_temp_max, 1), -}; - -static struct sensor_device_attribute sda_temp_max_hyst[] = { SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1_max_hyst, store_temp1_max_hyst, 0), SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst, store_temp_max_hyst, 0), SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst, store_temp_max_hyst, 1), -}; - -static struct sensor_device_attribute sda_temp_alarm[] = { SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4), SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5), SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), -}; - -static struct sensor_device_attribute sda_temp_type[] = { SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0), SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1), SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), @@ -1201,8 +1181,6 @@ static void w83627ehf_device_remove_files(struct device *dev) for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); for (i = 0; i < data->in_num; i++) { - if ((i == 6) && data->in6_skip) - continue; device_remove_file(dev, &sda_in_input[i].dev_attr); device_remove_file(dev, &sda_in_alarm[i].dev_attr); device_remove_file(dev, &sda_in_min[i].dev_attr); @@ -1214,22 +1192,15 @@ static void w83627ehf_device_remove_files(struct device *dev) device_remove_file(dev, &sda_fan_div[i].dev_attr); device_remove_file(dev, &sda_fan_min[i].dev_attr); } - for (i = 0; i < data->pwm_num; i++) { + for (i = 0; i < 4; i++) { device_remove_file(dev, &sda_pwm[i].dev_attr); device_remove_file(dev, &sda_pwm_mode[i].dev_attr); device_remove_file(dev, &sda_pwm_enable[i].dev_attr); device_remove_file(dev, &sda_target_temp[i].dev_attr); device_remove_file(dev, &sda_tolerance[i].dev_attr); } - for (i = 0; i < 3; i++) { - if ((i == 2) && data->temp3_disable) - continue; - device_remove_file(dev, &sda_temp_input[i].dev_attr); - device_remove_file(dev, &sda_temp_max[i].dev_attr); - device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr); - device_remove_file(dev, &sda_temp_alarm[i].dev_attr); - device_remove_file(dev, &sda_temp_type[i].dev_attr); - } + for (i = 0; i < ARRAY_SIZE(sda_temp); i++) + device_remove_file(dev, &sda_temp[i].dev_attr); device_remove_file(dev, &dev_attr_name); device_remove_file(dev, &dev_attr_cpu0_vid); @@ -1251,8 +1222,6 @@ static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data) for (i = 0; i < 2; i++) { tmp = w83627ehf_read_value(data, W83627EHF_REG_TEMP_CONFIG[i]); - if ((i == 1) && data->temp3_disable) - continue; if (tmp & 0x01) w83627ehf_write_value(data, W83627EHF_REG_TEMP_CONFIG[i], @@ -1303,17 +1272,8 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) data->name = w83627ehf_device_names[sio_data->kind]; platform_set_drvdata(pdev, data); - /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ - data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9; - /* 667HG has 3 pwms */ - data->pwm_num = (sio_data->kind == w83667hg) ? 3 : 4; - - /* Check temp3 configuration bit for 667HG */ - if (sio_data->kind == w83667hg) { - data->temp3_disable = w83627ehf_read_value(data, - W83627EHF_REG_TEMP_CONFIG[1]) & 0x01; - data->in6_skip = !data->temp3_disable; - } + /* 627EHG and 627EHF have 10 voltage inputs; DHG has 9 */ + data->in_num = (sio_data->kind == w83627dhg) ? 9 : 10; /* Initialize the chip */ w83627ehf_init_device(data); @@ -1321,64 +1281,44 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) data->vrm = vid_which_vrm(); superio_enter(sio_data->sioreg); /* Read VID value */ - if (sio_data->kind == w83667hg) { - /* W83667HG has different pins for VID input and output, so - we can get the VID input values directly at logical device D - 0xe3. */ - superio_select(sio_data->sioreg, W83667HG_LD_VID); - data->vid = superio_inb(sio_data->sioreg, 0xe3); + superio_select(sio_data->sioreg, W83627EHF_LD_HWM); + if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { + /* Set VID input sensibility if needed. In theory the BIOS + should have set it, but in practice it's not always the + case. We only do it for the W83627EHF/EHG because the + W83627DHG is more complex in this respect. */ + if (sio_data->kind == w83627ehf) { + en_vrm10 = superio_inb(sio_data->sioreg, + SIO_REG_EN_VRM10); + if ((en_vrm10 & 0x08) && data->vrm == 90) { + dev_warn(dev, "Setting VID input voltage to " + "TTL\n"); + superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, + en_vrm10 & ~0x08); + } else if (!(en_vrm10 & 0x08) && data->vrm == 100) { + dev_warn(dev, "Setting VID input voltage to " + "VRM10\n"); + superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, + en_vrm10 | 0x08); + } + } + + data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA); + if (sio_data->kind == w83627ehf) /* 6 VID pins only */ + data->vid &= 0x3f; + err = device_create_file(dev, &dev_attr_cpu0_vid); if (err) goto exit_release; } else { - superio_select(sio_data->sioreg, W83627EHF_LD_HWM); - if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { - /* Set VID input sensibility if needed. In theory the - BIOS should have set it, but in practice it's not - always the case. We only do it for the W83627EHF/EHG - because the W83627DHG is more complex in this - respect. */ - if (sio_data->kind == w83627ehf) { - en_vrm10 = superio_inb(sio_data->sioreg, - SIO_REG_EN_VRM10); - if ((en_vrm10 & 0x08) && data->vrm == 90) { - dev_warn(dev, "Setting VID input " - "voltage to TTL\n"); - superio_outb(sio_data->sioreg, - SIO_REG_EN_VRM10, - en_vrm10 & ~0x08); - } else if (!(en_vrm10 & 0x08) - && data->vrm == 100) { - dev_warn(dev, "Setting VID input " - "voltage to VRM10\n"); - superio_outb(sio_data->sioreg, - SIO_REG_EN_VRM10, - en_vrm10 | 0x08); - } - } - - data->vid = superio_inb(sio_data->sioreg, - SIO_REG_VID_DATA); - if (sio_data->kind == w83627ehf) /* 6 VID pins only */ - data->vid &= 0x3f; - - err = device_create_file(dev, &dev_attr_cpu0_vid); - if (err) - goto exit_release; - } else { - dev_info(dev, "VID pins in output mode, CPU VID not " - "available\n"); - } + dev_info(dev, "VID pins in output mode, CPU VID not " + "available\n"); } /* fan4 and fan5 share some pins with the GPIO and serial flash */ - if (sio_data->kind == w83667hg) { - fan5pin = superio_inb(sio_data->sioreg, 0x27) & 0x20; - fan4pin = superio_inb(sio_data->sioreg, 0x27) & 0x40; - } else { - fan5pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x02); - fan4pin = !(superio_inb(sio_data->sioreg, 0x29) & 0x06); - } + + fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2; + fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6; superio_exit(sio_data->sioreg); /* It looks like fan4 and fan5 pins can be alternatively used @@ -1389,9 +1329,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) data->has_fan = 0x07; /* fan1, fan2 and fan3 */ i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); - if ((i & (1 << 2)) && fan4pin) + if ((i & (1 << 2)) && (!fan4pin)) data->has_fan |= (1 << 3); - if (!(i & (1 << 1)) && fan5pin) + if (!(i & (1 << 1)) && (!fan5pin)) data->has_fan |= (1 << 4); /* Read fan clock dividers immediately */ @@ -1404,16 +1344,14 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) goto exit_remove; /* if fan4 is enabled create the sf3 files for it */ - if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4) + if (data->has_fan & (1 << 3)) for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) { if ((err = device_create_file(dev, &sda_sf3_arrays_fan4[i].dev_attr))) goto exit_remove; } - for (i = 0; i < data->in_num; i++) { - if ((i == 6) && data->in6_skip) - continue; + for (i = 0; i < data->in_num; i++) if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) || (err = device_create_file(dev, &sda_in_alarm[i].dev_attr)) @@ -1422,7 +1360,6 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) || (err = device_create_file(dev, &sda_in_max[i].dev_attr))) goto exit_remove; - } for (i = 0; i < 5; i++) { if (data->has_fan & (1 << i)) { @@ -1435,7 +1372,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) || (err = device_create_file(dev, &sda_fan_min[i].dev_attr))) goto exit_remove; - if (i < data->pwm_num && + if (i < 4 && /* w83627ehf only has 4 pwm */ ((err = device_create_file(dev, &sda_pwm[i].dev_attr)) || (err = device_create_file(dev, @@ -1450,21 +1387,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) } } - for (i = 0; i < 3; i++) { - if ((i == 2) && data->temp3_disable) - continue; - if ((err = device_create_file(dev, - &sda_temp_input[i].dev_attr)) - || (err = device_create_file(dev, - &sda_temp_max[i].dev_attr)) - || (err = device_create_file(dev, - &sda_temp_max_hyst[i].dev_attr)) - || (err = device_create_file(dev, - &sda_temp_alarm[i].dev_attr)) - || (err = device_create_file(dev, - &sda_temp_type[i].dev_attr))) + for (i = 0; i < ARRAY_SIZE(sda_temp); i++) + if ((err = device_create_file(dev, &sda_temp[i].dev_attr))) goto exit_remove; - } err = device_create_file(dev, &dev_attr_name); if (err) @@ -1517,7 +1442,6 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, static const char __initdata sio_name_W83627EHF[] = "W83627EHF"; static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; - static const char __initdata sio_name_W83667HG[] = "W83667HG"; u16 val; const char *sio_name; @@ -1542,10 +1466,6 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, sio_data->kind = w83627dhg; sio_name = sio_name_W83627DHG; break; - case SIO_W83667HG_ID: - sio_data->kind = w83667hg; - sio_name = sio_name_W83667HG; - break; default: if (val != 0xffff) pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n", diff --git a/trunk/drivers/i2c/busses/i2c-i801.c b/trunk/drivers/i2c/busses/i2c-i801.c index 10411848fd70..230238df56c4 100644 --- a/trunk/drivers/i2c/busses/i2c-i801.c +++ b/trunk/drivers/i2c/busses/i2c-i801.c @@ -65,7 +65,6 @@ #include #include #include -#include /* I801 SMBus address offsets */ #define SMBHSTSTS (0 + i801_smba) @@ -617,81 +616,10 @@ static void __init input_apanel_init(void) static void __init input_apanel_init(void) {} #endif -#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE -struct dmi_onboard_device_info { - const char *name; - u8 type; - unsigned short i2c_addr; - const char *i2c_type; -}; - -static struct dmi_onboard_device_info __devinitdata dmi_devices[] = { - { "Syleus", DMI_DEV_TYPE_OTHER, 0x73, "fscsyl" }, - { "Hermes", DMI_DEV_TYPE_OTHER, 0x73, "fscher" }, - { "Hades", DMI_DEV_TYPE_OTHER, 0x73, "fschds" }, -}; - -static void __devinit dmi_check_onboard_device(u8 type, const char *name, - struct i2c_adapter *adap) -{ - int i; - struct i2c_board_info info; - - for (i = 0; i < ARRAY_SIZE(dmi_devices); i++) { - /* & ~0x80, ignore enabled/disabled bit */ - if ((type & ~0x80) != dmi_devices[i].type) - continue; - if (strcmp(name, dmi_devices[i].name)) - continue; - - memset(&info, 0, sizeof(struct i2c_board_info)); - info.addr = dmi_devices[i].i2c_addr; - strlcpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE); - i2c_new_device(adap, &info); - break; - } -} - -/* We use our own function to check for onboard devices instead of - dmi_find_device() as some buggy BIOS's have the devices we are interested - in marked as disabled */ -static void __devinit dmi_check_onboard_devices(const struct dmi_header *dm, - void *adap) -{ - int i, count; - - if (dm->type != 10) - return; - - count = (dm->length - sizeof(struct dmi_header)) / 2; - for (i = 0; i < count; i++) { - const u8 *d = (char *)(dm + 1) + (i * 2); - const char *name = ((char *) dm) + dm->length; - u8 type = d[0]; - u8 s = d[1]; - - if (!s) - continue; - s--; - while (s > 0 && name[0]) { - name += strlen(name) + 1; - s--; - } - if (name[0] == 0) /* Bogus string reference */ - continue; - - dmi_check_onboard_device(type, name, adap); - } -} -#endif - static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) { unsigned char temp; int err; -#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE - const char *vendor; -#endif I801_dev = dev; i801_features = 0; @@ -784,11 +712,6 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id i2c_new_device(&i801_adapter, &info); } #endif -#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE - vendor = dmi_get_system_info(DMI_BOARD_VENDOR); - if (vendor && !strcmp(vendor, "FUJITSU SIEMENS")) - dmi_walk(dmi_check_onboard_devices, &i801_adapter); -#endif return 0; diff --git a/trunk/drivers/i2c/busses/i2c-mpc.c b/trunk/drivers/i2c/busses/i2c-mpc.c index 26bf37010586..2b847d875946 100644 --- a/trunk/drivers/i2c/busses/i2c-mpc.c +++ b/trunk/drivers/i2c/busses/i2c-mpc.c @@ -70,7 +70,7 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id) /* Read again to allow register to stabilise */ i2c->interrupt = readb(i2c->base + MPC_I2C_SR); writeb(0, i2c->base + MPC_I2C_SR); - wake_up(&i2c->queue); + wake_up_interruptible(&i2c->queue); } return IRQ_HANDLED; } @@ -115,10 +115,13 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) writeb(0, i2c->base + MPC_I2C_SR); } else { /* Interrupt mode */ - result = wait_event_timeout(i2c->queue, + result = wait_event_interruptible_timeout(i2c->queue, (i2c->interrupt & CSR_MIF), timeout); - if (unlikely(!(i2c->interrupt & CSR_MIF))) { + if (unlikely(result < 0)) { + pr_debug("I2C: wait interrupted\n"); + writeccr(i2c, 0); + } else if (unlikely(!(i2c->interrupt & CSR_MIF))) { pr_debug("I2C: wait timeout\n"); writeccr(i2c, 0); result = -ETIMEDOUT; diff --git a/trunk/drivers/i2c/chips/Kconfig b/trunk/drivers/i2c/chips/Kconfig index 8f8c81eb0aee..c80312c1f382 100644 --- a/trunk/drivers/i2c/chips/Kconfig +++ b/trunk/drivers/i2c/chips/Kconfig @@ -64,6 +64,19 @@ config SENSORS_PCA9539 This driver is deprecated and will be dropped soon. Use drivers/gpio/pca953x.c instead. +config SENSORS_PCF8591 + tristate "Philips PCF8591" + depends on EXPERIMENTAL + default n + help + If you say yes here you get support for Philips PCF8591 chips. + + This driver can also be built as a module. If so, the module + will be called pcf8591. + + These devices are hard to detect and rarely found on mainstream + hardware. If unsure, say N. + config SENSORS_MAX6875 tristate "Maxim MAX6875 Power supply supervisor" depends on EXPERIMENTAL diff --git a/trunk/drivers/i2c/chips/Makefile b/trunk/drivers/i2c/chips/Makefile index 55a376037183..d142f238a2de 100644 --- a/trunk/drivers/i2c/chips/Makefile +++ b/trunk/drivers/i2c/chips/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_SENSORS_MAX6875) += max6875.o obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o obj-$(CONFIG_PCF8575) += pcf8575.o +obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) diff --git a/trunk/drivers/hwmon/pcf8591.c b/trunk/drivers/i2c/chips/pcf8591.c similarity index 96% rename from trunk/drivers/hwmon/pcf8591.c rename to trunk/drivers/i2c/chips/pcf8591.c index 1d7ffebd679d..16ce3e193776 100644 --- a/trunk/drivers/hwmon/pcf8591.c +++ b/trunk/drivers/i2c/chips/pcf8591.c @@ -1,6 +1,6 @@ /* Copyright (C) 2001-2004 Aurelien Jarno - Ported to Linux 2.6 by Aurelien Jarno with + Ported to Linux 2.6 by Aurelien Jarno with the help of Jean Delvare This program is free software; you can redistribute it and/or modify @@ -41,13 +41,13 @@ MODULE_PARM_DESC(input_mode, " 3 = two differential inputs\n"); /* The PCF8591 control byte - 7 6 5 4 3 2 1 0 + 7 6 5 4 3 2 1 0 | 0 |AOEF| AIP | 0 |AINC| AICH | */ /* Analog Output Enable Flag (analog output active if 1) */ #define PCF8591_CONTROL_AOEF 0x40 - -/* Analog Input Programming + +/* Analog Input Programming 0x00 = four single ended inputs 0x10 = three differential inputs 0x20 = single ended and differential mixed @@ -58,7 +58,7 @@ MODULE_PARM_DESC(input_mode, #define PCF8591_CONTROL_AINC 0x04 /* Channel selection - 0x00 = channel 0 + 0x00 = channel 0 0x01 = channel 1 0x02 = channel 2 0x03 = channel 3 */ @@ -114,7 +114,7 @@ static ssize_t set_out0_output(struct device *dev, struct device_attribute *attr return -EINVAL; } -static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO, show_out0_ouput, set_out0_output); static ssize_t show_out0_enable(struct device *dev, struct device_attribute *attr, char *buf) @@ -139,7 +139,7 @@ static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr return count; } -static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO, show_out0_enable, set_out0_enable); static struct attribute *pcf8591_attributes[] = { @@ -196,7 +196,7 @@ static int pcf8591_probe(struct i2c_client *client, err = -ENOMEM; goto exit; } - + i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -249,8 +249,8 @@ static void pcf8591_init_client(struct i2c_client *client) data->aout = PCF8591_INIT_AOUT; i2c_smbus_write_byte_data(client, data->control, data->aout); - - /* The first byte transmitted contains the conversion code of the + + /* The first byte transmitted contains the conversion code of the previous read cycle. FLUSH IT! */ i2c_smbus_read_byte(client); } @@ -267,8 +267,8 @@ static int pcf8591_read_channel(struct device *dev, int channel) data->control = (data->control & ~PCF8591_CONTROL_AICH_MASK) | channel; i2c_smbus_write_byte(client, data->control); - - /* The first byte transmitted contains the conversion code of + + /* The first byte transmitted contains the conversion code of the previous read cycle. FLUSH IT! */ i2c_smbus_read_byte(client); } diff --git a/trunk/drivers/ide/Kconfig b/trunk/drivers/ide/Kconfig index cf06494bb744..640c99207242 100644 --- a/trunk/drivers/ide/Kconfig +++ b/trunk/drivers/ide/Kconfig @@ -222,8 +222,7 @@ comment "IDE chipset support/bugfixes" config IDE_GENERIC tristate "generic/default IDE chipset support" - depends on ALPHA || X86 || IA64 || M32R || MIPS || ARCH_RPC || ARCH_SHARK - default ARM && (ARCH_RPC || ARCH_SHARK) + depends on ALPHA || X86 || IA64 || M32R || MIPS help This is the generic IDE driver. This driver attaches to the fixed legacy ports (e.g. on PCs 0x1f0/0x170, 0x1e8/0x168 and @@ -681,7 +680,7 @@ endif # TODO: BLK_DEV_IDEDMA_PCI -> BLK_DEV_IDEDMA_SFF config BLK_DEV_IDE_PMAC tristate "PowerMac on-board IDE support" - depends on PPC_PMAC + depends on PPC_PMAC && IDE=y select IDE_TIMINGS select BLK_DEV_IDEDMA_PCI help @@ -732,6 +731,11 @@ config BLK_DEV_IDE_AT91 depends on ARM && ARCH_AT91 && !ARCH_AT91RM9200 && !ARCH_AT91X40 select IDE_TIMINGS +config IDE_ARM + tristate "ARM IDE support" + depends on ARM && (ARCH_RPC || ARCH_SHARK) + default y + config BLK_DEV_IDE_ICSIDE tristate "ICS IDE interface support" depends on ARM && ARCH_ACORN @@ -770,20 +774,27 @@ config BLK_DEV_GAYLE This includes on-board IDE interfaces on some Amiga models (A600, A1200, A4000, and A4000T), and IDE interfaces on the Zorro expansion bus (M-Tech E-Matrix 530 expansion card). + Say Y if you have an Amiga with a Gayle IDE interface and want to use + IDE devices (hard disks, CD-ROM drives, etc.) that are connected to + it. + Note that you also have to enable Zorro bus support if you want to + use Gayle IDE interfaces on the Zorro expansion bus. - It also provides support for the so-called `IDE doublers' (made +config BLK_DEV_IDEDOUBLER + bool "Amiga IDE Doubler support (EXPERIMENTAL)" + depends on BLK_DEV_GAYLE && EXPERIMENTAL + ---help--- + This feature provides support for the so-called `IDE doublers' (made by various manufacturers, e.g. Eyetech) that can be connected to the on-board IDE interface of some Amiga models. Using such an IDE doubler, you can connect up to four instead of two IDE devices to - the Amiga's on-board IDE interface. The feature is enabled at kernel - runtime using the "gayle.doubler" kernel boot parameter. + the Amiga's on-board IDE interface. - Say Y if you have an Amiga with a Gayle IDE interface and want to use - IDE devices (hard disks, CD-ROM drives, etc.) that are connected to - it. + Note that the normal Amiga Gayle IDE driver may not work correctly + if you have an IDE doubler and don't enable this feature! - Note that you also have to enable Zorro bus support if you want to - use Gayle IDE interfaces on the Zorro expansion bus. + Say Y if you have an IDE doubler. The feature is enabled at kernel + runtime using the "gayle.doubler" kernel boot parameter. config BLK_DEV_BUDDHA tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)" diff --git a/trunk/drivers/ide/Makefile b/trunk/drivers/ide/Makefile index 81df925f0e8b..9b4bbe1cdc1a 100644 --- a/trunk/drivers/ide/Makefile +++ b/trunk/drivers/ide/Makefile @@ -21,6 +21,8 @@ ide-core-$(CONFIG_IDE_LEGACY) += ide-legacy.o obj-$(CONFIG_IDE) += ide-core.o +obj-$(CONFIG_IDE_ARM) += ide_arm.o + obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o diff --git a/trunk/drivers/ide/alim15x3.c b/trunk/drivers/ide/alim15x3.c index 537da1cde16d..d3513b6b8530 100644 --- a/trunk/drivers/ide/alim15x3.c +++ b/trunk/drivers/ide/alim15x3.c @@ -189,20 +189,19 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed) } /** - * ali_dma_check - DMA check + * ali15x3_dma_setup - begin a DMA phase * @drive: target device - * @cmd: command * * Returns 1 if the DMA cannot be performed, zero on success. */ -static int ali_dma_check(ide_drive_t *drive, struct ide_cmd *cmd) +static int ali15x3_dma_setup(ide_drive_t *drive) { if (m5229_revision < 0xC2 && drive->media != ide_disk) { - if (cmd->tf_flags & IDE_TFLAG_WRITE) + if (rq_data_dir(drive->hwif->rq)) return 1; /* try PIO instead of DMA */ } - return 0; + return ide_dma_setup(drive); } /** @@ -503,13 +502,13 @@ static const struct ide_port_ops ali_port_ops = { static const struct ide_dma_ops ali_dma_ops = { .dma_host_set = ide_dma_host_set, - .dma_setup = ide_dma_setup, + .dma_setup = ali15x3_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = ide_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_check = ali_dma_check, - .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/at91_ide.c b/trunk/drivers/ide/at91_ide.c index 8eda552326e9..1bb50f46388d 100644 --- a/trunk/drivers/ide/at91_ide.c +++ b/trunk/drivers/ide/at91_ide.c @@ -143,7 +143,7 @@ static void apply_timings(const u8 chipselect, const u8 pio, set_smc_timings(chipselect, cycle, setup, pulse, data_float, use_iordy); } -static void at91_ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void at91_ide_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { ide_hwif_t *hwif = drive->hwif; @@ -156,11 +156,11 @@ static void at91_ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, len++; enter_16bit(chipselect, mode); - readsw((void __iomem *)io_ports->data_addr, buf, len / 2); + __ide_mm_insw((void __iomem *) io_ports->data_addr, buf, len / 2); leave_16bit(chipselect, mode); } -static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void at91_ide_output_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { ide_hwif_t *hwif = drive->hwif; @@ -171,7 +171,7 @@ static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, pdbg("cs %u buf %p len %d\n", chipselect, buf, len); enter_16bit(chipselect, mode); - writesw((void __iomem *)io_ports->data_addr, buf, len / 2); + __ide_mm_outsw((void __iomem *) io_ports->data_addr, buf, len / 2); leave_16bit(chipselect, mode); } @@ -185,77 +185,91 @@ static void ide_mm_outb(u8 value, unsigned long port) writeb(value, (void __iomem *) port); } -static void at91_ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +static void at91_ide_tf_load(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; - u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; + struct ide_taskfile *tf = &task->tf; + u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; - if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) + if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_DATA) { + u16 data = (tf->hob_data << 8) | tf->data; + + at91_ide_output_data(drive, NULL, &data, 2); + } + + if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) ide_mm_outb(tf->hob_feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) ide_mm_outb(tf->hob_nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) ide_mm_outb(tf->hob_lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) ide_mm_outb(tf->hob_lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) ide_mm_outb(tf->hob_lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) ide_mm_outb(tf->feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_NSECT) ide_mm_outb(tf->nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_LBAL) ide_mm_outb(tf->lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_LBAM) ide_mm_outb(tf->lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_LBAH) ide_mm_outb(tf->lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) ide_mm_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); } -static void at91_ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +static void at91_ide_tf_read(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; + + if (task->tf_flags & IDE_TFLAG_IN_DATA) { + u16 data; + + at91_ide_input_data(drive, NULL, &data, 2); + tf->data = data & 0xff; + tf->hob_data = (data >> 8) & 0xff; + } /* be sure we're looking at the low order bits */ - ide_mm_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); + ide_mm_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) - tf->error = ide_mm_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) + tf->feature = ide_mm_inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = ide_mm_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = ide_mm_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = ide_mm_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = ide_mm_inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = ide_mm_inb(io_ports->device_addr); - if (cmd->tf_flags & IDE_TFLAG_LBA48) { - ide_mm_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); - - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) - tf->hob_error = ide_mm_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) - tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) - tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) - tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) - tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr); + if (task->tf_flags & IDE_TFLAG_LBA48) { + ide_mm_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); + + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + tf->hob_feature = ide_mm_inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) + tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr); } } @@ -281,9 +295,8 @@ static const struct ide_tp_ops at91_ide_tp_ops = { .exec_command = ide_exec_command, .read_status = ide_read_status, .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, + .set_irq = ide_set_irq, - .dev_select = ide_dev_select, .tf_load = at91_ide_tf_load, .tf_read = at91_ide_tf_read, diff --git a/trunk/drivers/ide/au1xxx-ide.c b/trunk/drivers/ide/au1xxx-ide.c index 46013644c965..154ec2cf734f 100644 --- a/trunk/drivers/ide/au1xxx-ide.c +++ b/trunk/drivers/ide/au1xxx-ide.c @@ -50,7 +50,7 @@ static _auide_hwif auide_hwif; #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA) -static inline void auide_insw(unsigned long port, void *addr, u32 count) +void auide_insw(unsigned long port, void *addr, u32 count) { _auide_hwif *ahwif = &auide_hwif; chan_tab_t *ctp; @@ -68,7 +68,7 @@ static inline void auide_insw(unsigned long port, void *addr, u32 count) ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp); } -static inline void auide_outsw(unsigned long port, void *addr, u32 count) +void auide_outsw(unsigned long port, void *addr, u32 count) { _auide_hwif *ahwif = &auide_hwif; chan_tab_t *ctp; @@ -86,13 +86,13 @@ static inline void auide_outsw(unsigned long port, void *addr, u32 count) ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp); } -static void au1xxx_input_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void au1xxx_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { auide_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); } -static void au1xxx_output_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void au1xxx_output_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { auide_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); @@ -209,17 +209,23 @@ static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed) */ #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA -static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) +static int auide_build_dmatable(ide_drive_t *drive) { + int i, iswrite, count = 0; ide_hwif_t *hwif = drive->hwif; + struct request *rq = hwif->rq; _auide_hwif *ahwif = &auide_hwif; struct scatterlist *sg; - int i = cmd->sg_nents, count = 0; - int iswrite = !!(cmd->tf_flags & IDE_TFLAG_WRITE); + iswrite = (rq_data_dir(rq) == WRITE); /* Save for interrupt context */ ahwif->drive = drive; + hwif->sg_nents = i = ide_build_sglist(drive, rq); + + if (!i) + return 0; + /* fill the descriptors */ sg = hwif->sg_table; while (i && sg_dma_len(sg)) { @@ -236,7 +242,7 @@ static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) if (++count >= PRD_ENTRIES) { printk(KERN_WARNING "%s: DMA table too small\n", drive->name); - return 0; + goto use_pio_instead; } /* Lets enable intr for the last descriptor only */ @@ -272,11 +278,21 @@ static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) if (count) return 1; + use_pio_instead: + ide_destroy_dmatable(drive); + return 0; /* revert to PIO for this request */ } static int auide_dma_end(ide_drive_t *drive) { + ide_hwif_t *hwif = drive->hwif; + + if (hwif->sg_nents) { + ide_destroy_dmatable(drive); + hwif->sg_nents = 0; + } + return 0; } @@ -285,11 +301,23 @@ static void auide_dma_start(ide_drive_t *drive ) } -static int auide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command) { - if (auide_build_dmatable(drive, cmd) == 0) + /* issue cmd to drive */ + ide_execute_command(drive, command, &ide_dma_intr, + (2*WAIT_CMD), NULL); +} + +static int auide_dma_setup(ide_drive_t *drive) +{ + struct request *rq = drive->hwif->rq; + + if (!auide_build_dmatable(drive)) { + ide_map_sg(drive, rq); return 1; + } + drive->waiting_for_dma = 1; return 0; } @@ -314,11 +342,16 @@ static void auide_dma_host_set(ide_drive_t *drive, int on) static void auide_ddma_tx_callback(int irq, void *param) { + _auide_hwif *ahwif = (_auide_hwif*)param; + ahwif->drive->waiting_for_dma = 0; } static void auide_ddma_rx_callback(int irq, void *param) { + _auide_hwif *ahwif = (_auide_hwif*)param; + ahwif->drive->waiting_for_dma = 0; } + #endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags) @@ -336,10 +369,12 @@ static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 de static const struct ide_dma_ops au1xxx_dma_ops = { .dma_host_set = auide_dma_host_set, .dma_setup = auide_dma_setup, + .dma_exec_cmd = auide_dma_exec_cmd, .dma_start = auide_dma_start, .dma_end = auide_dma_end, .dma_test_irq = auide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, + .dma_timeout = ide_dma_timeout, }; static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d) @@ -467,9 +502,9 @@ static const struct ide_tp_ops au1xxx_tp_ops = { .exec_command = ide_exec_command, .read_status = ide_read_status, .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - .dev_select = ide_dev_select, + .set_irq = ide_set_irq, + .tf_load = ide_tf_load, .tf_read = ide_tf_read, diff --git a/trunk/drivers/ide/buddha.c b/trunk/drivers/ide/buddha.c index d028f8864bc1..c5a3c9ef6a5d 100644 --- a/trunk/drivers/ide/buddha.c +++ b/trunk/drivers/ide/buddha.c @@ -143,11 +143,6 @@ static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base, hw->chipset = ide_generic; } -static const struct ide_port_info buddha_port_info = { - .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, - .irq_flags = IRQF_SHARED, -}; - /* * Probe for a Buddha or Catweasel IDE interface */ @@ -177,6 +172,10 @@ static int __init buddha_init(void) board = z->resource.start; +/* + * FIXME: we now have selectable mmio v/s iomio transports. + */ + if(type != BOARD_XSURF) { if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE")) continue; @@ -225,7 +224,7 @@ static int __init buddha_init(void) hws[i] = &hw[i]; } - ide_host_add(&buddha_port_info, hws, NULL); + ide_host_add(NULL, hws, NULL); } return 0; diff --git a/trunk/drivers/ide/cmd64x.c b/trunk/drivers/ide/cmd64x.c index 80b777e4247b..aeee036b1503 100644 --- a/trunk/drivers/ide/cmd64x.c +++ b/trunk/drivers/ide/cmd64x.c @@ -318,6 +318,7 @@ static int cmd646_1_dma_end(ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; u8 dma_stat = 0, dma_cmd = 0; + drive->waiting_for_dma = 0; /* get DMA status */ dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); /* read DMA command state */ @@ -326,6 +327,8 @@ static int cmd646_1_dma_end(ide_drive_t *drive) outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD); /* clear the INTR & ERROR bits */ outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); + /* and free any DMA resources */ + ide_destroy_dmatable(drive); /* verify good DMA status */ return (dma_stat & 7) != 4; } @@ -376,33 +379,36 @@ static const struct ide_port_ops cmd64x_port_ops = { static const struct ide_dma_ops cmd64x_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = cmd64x_dma_end, .dma_test_irq = cmd64x_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; static const struct ide_dma_ops cmd646_rev1_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = cmd646_1_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; static const struct ide_dma_ops cmd648_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = cmd648_dma_end, .dma_test_irq = cmd648_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/cs5530.c b/trunk/drivers/ide/cs5530.c index 40bf05eddf6e..8e8b35a89901 100644 --- a/trunk/drivers/ide/cs5530.c +++ b/trunk/drivers/ide/cs5530.c @@ -92,7 +92,8 @@ static u8 cs5530_udma_filter(ide_drive_t *drive) if ((mateid[ATA_ID_FIELD_VALID] & 4) && (mateid[ATA_ID_UDMA_MODES] & 7)) goto out; - if (mateid[ATA_ID_MWDMA_MODES] & 7) + if ((mateid[ATA_ID_FIELD_VALID] & 2) && + (mateid[ATA_ID_MWDMA_MODES] & 7)) mask = 0; } out: diff --git a/trunk/drivers/ide/cs5536.c b/trunk/drivers/ide/cs5536.c index 353a35bbba63..7a62db719a46 100644 --- a/trunk/drivers/ide/cs5536.c +++ b/trunk/drivers/ide/cs5536.c @@ -231,11 +231,12 @@ static const struct ide_port_ops cs5536_port_ops = { static const struct ide_dma_ops cs5536_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = cs5536_dma_start, .dma_end = cs5536_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_timeout = ide_dma_timeout, }; static const struct ide_port_info cs5536_info = { diff --git a/trunk/drivers/ide/delkin_cb.c b/trunk/drivers/ide/delkin_cb.c index f153b95619bb..bacb1194c9c9 100644 --- a/trunk/drivers/ide/delkin_cb.c +++ b/trunk/drivers/ide/delkin_cb.c @@ -66,7 +66,6 @@ static const struct ide_port_info delkin_cb_port_info = { .port_ops = &delkin_cb_port_ops, .host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS | IDE_HFLAG_NO_DMA, - .irq_flags = IRQF_SHARED, .init_chipset = delkin_cb_init_chipset, }; diff --git a/trunk/drivers/ide/dtc2278.c b/trunk/drivers/ide/dtc2278.c index c6b138122981..689b2e493413 100644 --- a/trunk/drivers/ide/dtc2278.c +++ b/trunk/drivers/ide/dtc2278.c @@ -100,8 +100,7 @@ static const struct ide_port_info dtc2278_port_info __initdata = { IDE_HFLAG_IO_32BIT | /* disallow ->io_32bit changes */ IDE_HFLAG_NO_IO_32BIT | - IDE_HFLAG_NO_DMA | - IDE_HFLAG_DTC2278, + IDE_HFLAG_NO_DMA, .pio_mask = ATA_PIO4, }; diff --git a/trunk/drivers/ide/falconide.c b/trunk/drivers/ide/falconide.c index afa2af9a362b..a638e952d67a 100644 --- a/trunk/drivers/ide/falconide.c +++ b/trunk/drivers/ide/falconide.c @@ -40,48 +40,29 @@ * which is shared between several drivers. */ -static int falconide_intr_lock; +int falconide_intr_lock; +EXPORT_SYMBOL(falconide_intr_lock); -static void falconide_release_lock(void) -{ - if (falconide_intr_lock == 0) { - printk(KERN_ERR "%s: bug\n", __func__); - return; - } - falconide_intr_lock = 0; - stdma_release(); -} - -static void falconide_get_lock(irq_handler_t handler, void *data) -{ - if (falconide_intr_lock == 0) { - if (in_interrupt() > 0) - panic("Falcon IDE hasn't ST-DMA lock in interrupt"); - stdma_lock(handler, data); - falconide_intr_lock = 1; - } -} - -static void falconide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void falconide_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; - if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) + if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) return insw(data_addr, buf, (len + 1) / 2); - raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2); + insw_swapw(data_addr, buf, (len + 1) / 2); } -static void falconide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void falconide_output_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; - if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) + if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) return outsw(data_addr, buf, (len + 1) / 2); - raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2); + outsw_swapw(data_addr, buf, (len + 1) / 2); } /* Atari has a byte-swapped IDE interface */ @@ -89,9 +70,9 @@ static const struct ide_tp_ops falconide_tp_ops = { .exec_command = ide_exec_command, .read_status = ide_read_status, .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - .dev_select = ide_dev_select, + .set_irq = ide_set_irq, + .tf_load = ide_tf_load, .tf_read = ide_tf_read, @@ -100,12 +81,8 @@ static const struct ide_tp_ops falconide_tp_ops = { }; static const struct ide_port_info falconide_port_info = { - .get_lock = falconide_get_lock, - .release_lock = falconide_release_lock, .tp_ops = &falconide_tp_ops, - .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE | - IDE_HFLAG_NO_DMA, - .irq_flags = IRQF_SHARED, + .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_SERIALIZE, }; static void __init falconide_setup_ports(hw_regs_t *hw) @@ -155,9 +132,9 @@ static int __init falconide_init(void) goto err; } - falconide_get_lock(NULL, NULL); + ide_get_lock(NULL, NULL); rc = ide_host_register(host, &falconide_port_info, hws); - falconide_release_lock(); + ide_release_lock(); if (rc) goto err_free; diff --git a/trunk/drivers/ide/gayle.c b/trunk/drivers/ide/gayle.c index c7119516c5a7..59bd0be9dcb3 100644 --- a/trunk/drivers/ide/gayle.c +++ b/trunk/drivers/ide/gayle.c @@ -53,6 +53,11 @@ #define GAYLE_NEXT_PORT 0x1000 +#ifndef CONFIG_BLK_DEV_IDEDOUBLER +#define GAYLE_NUM_HWIFS 1 +#define GAYLE_NUM_PROBE_HWIFS GAYLE_NUM_HWIFS +#define GAYLE_HAS_CONTROL_REG 1 +#else /* CONFIG_BLK_DEV_IDEDOUBLER */ #define GAYLE_NUM_HWIFS 2 #define GAYLE_NUM_PROBE_HWIFS (ide_doubler ? GAYLE_NUM_HWIFS : \ GAYLE_NUM_HWIFS-1) @@ -61,6 +66,8 @@ static int ide_doubler; module_param_named(doubler, ide_doubler, bool, 0); MODULE_PARM_DESC(doubler, "enable support for IDE doublers"); +#endif /* CONFIG_BLK_DEV_IDEDOUBLER */ + /* * Check and acknowledge the interrupt status @@ -111,9 +118,7 @@ static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base, } static const struct ide_port_info gayle_port_info = { - .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE | - IDE_HFLAG_NO_DMA, - .irq_flags = IRQF_SHARED, + .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA, }; /* @@ -144,7 +149,10 @@ static int __init gayle_init(void) found: printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n", a4000 ? 4000 : 1200, - ide_doubler ? ", IDE doubler" : ""); +#ifdef CONFIG_BLK_DEV_IDEDOUBLER + ide_doubler ? ", IDE doubler" : +#endif + ""); if (a4000) { phys_base = GAYLE_BASE_4000; @@ -155,6 +163,9 @@ static int __init gayle_init(void) irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200); ack_intr = gayle_ack_intr_a1200; } +/* + * FIXME: we now have selectable modes between mmio v/s iomio + */ res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1); res_n = GAYLE_IDEREG_SIZE; diff --git a/trunk/drivers/ide/hpt366.c b/trunk/drivers/ide/hpt366.c index a0eb87f59134..d3b3e824f445 100644 --- a/trunk/drivers/ide/hpt366.c +++ b/trunk/drivers/ide/hpt366.c @@ -835,6 +835,12 @@ static int hpt370_dma_end(ide_drive_t *drive) return ide_dma_end(drive); } +static void hpt370_dma_timeout(ide_drive_t *drive) +{ + hpt370_irq_timeout(drive); + ide_dma_timeout(drive); +} + /* returns 1 if DMA IRQ issued, 0 otherwise */ static int hpt374_dma_test_irq(ide_drive_t *drive) { @@ -1412,34 +1418,36 @@ static const struct ide_port_ops hpt3xx_port_ops = { static const struct ide_dma_ops hpt37x_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = hpt374_dma_end, .dma_test_irq = hpt374_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; static const struct ide_dma_ops hpt370_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = hpt370_dma_start, .dma_end = hpt370_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, - .dma_clear = hpt370_irq_timeout, + .dma_timeout = hpt370_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; static const struct ide_dma_ops hpt36x_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = ide_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = hpt366_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/ht6560b.c b/trunk/drivers/ide/ht6560b.c index 2fb0f2965009..c7e5c2246b79 100644 --- a/trunk/drivers/ide/ht6560b.c +++ b/trunk/drivers/ide/ht6560b.c @@ -103,7 +103,7 @@ /* * This routine is invoked from ide.c to prepare for access to a given drive. */ -static void ht6560b_dev_select(ide_drive_t *drive) +static void ht6560b_selectproc (ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; unsigned long flags; @@ -143,8 +143,6 @@ static void ht6560b_dev_select(ide_drive_t *drive) #endif } local_irq_restore(flags); - - outb(drive->select | ATA_DEVICE_OBS, hwif->io_ports.device_addr); } /* @@ -307,29 +305,15 @@ static int probe_ht6560b; module_param_named(probe, probe_ht6560b, bool, 0); MODULE_PARM_DESC(probe, "probe for HT6560B chipset"); -static const struct ide_tp_ops ht6560b_tp_ops = { - .exec_command = ide_exec_command, - .read_status = ide_read_status, - .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - - .dev_select = ht6560b_dev_select, - .tf_load = ide_tf_load, - .tf_read = ide_tf_read, - - .input_data = ide_input_data, - .output_data = ide_output_data, -}; - static const struct ide_port_ops ht6560b_port_ops = { .init_dev = ht6560b_init_dev, .set_pio_mode = ht6560b_set_pio_mode, + .selectproc = ht6560b_selectproc, }; static const struct ide_port_info ht6560b_port_info __initdata = { .name = DRV_NAME, .chipset = ide_ht6560b, - .tp_ops = &ht6560b_tp_ops, .port_ops = &ht6560b_port_ops, .host_flags = IDE_HFLAG_SERIALIZE | /* is this needed? */ IDE_HFLAG_NO_DMA | diff --git a/trunk/drivers/ide/icside.c b/trunk/drivers/ide/icside.c index 4e16ce68b063..415d7e24f2b6 100644 --- a/trunk/drivers/ide/icside.c +++ b/trunk/drivers/ide/icside.c @@ -287,8 +287,13 @@ static int icside_dma_end(ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; struct expansion_card *ec = ECARD_DEV(hwif->dev); + drive->waiting_for_dma = 0; + disable_dma(ec->dma); + /* Teardown mappings after DMA has completed. */ + ide_destroy_dmatable(drive); + return get_dma_residue(ec->dma) != 0; } @@ -302,14 +307,15 @@ static void icside_dma_start(ide_drive_t *drive) enable_dma(ec->dma); } -static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +static int icside_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct expansion_card *ec = ECARD_DEV(hwif->dev); struct icside_state *state = ecard_get_drvdata(ec); + struct request *rq = hwif->rq; unsigned int dma_mode; - if (cmd->tf_flags & IDE_TFLAG_WRITE) + if (rq_data_dir(rq)) dma_mode = DMA_MODE_WRITE; else dma_mode = DMA_MODE_READ; @@ -319,6 +325,8 @@ static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) */ BUG_ON(dma_channel_active(ec->dma)); + hwif->sg_nents = ide_build_sglist(drive, rq); + /* * Ensure that we have the right interrupt routed. */ @@ -338,12 +346,20 @@ static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) * Tell the DMA engine about the SG table and * data direction. */ - set_dma_sg(ec->dma, hwif->sg_table, cmd->sg_nents); + set_dma_sg(ec->dma, hwif->sg_table, hwif->sg_nents); set_dma_mode(ec->dma, dma_mode); + drive->waiting_for_dma = 1; + return 0; } +static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd) +{ + /* issue cmd to drive */ + ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD, NULL); +} + static int icside_dma_test_irq(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; @@ -367,9 +383,11 @@ static int icside_dma_init(ide_hwif_t *hwif, const struct ide_port_info *d) static const struct ide_dma_ops icside_v6_dma_ops = { .dma_host_set = icside_dma_host_set, .dma_setup = icside_dma_setup, + .dma_exec_cmd = icside_dma_exec_cmd, .dma_start = icside_dma_start, .dma_end = icside_dma_end, .dma_test_irq = icside_dma_test_irq, + .dma_timeout = ide_dma_timeout, .dma_lost_irq = ide_dma_lost_irq, }; #else @@ -401,10 +419,6 @@ static void icside_setup_ports(hw_regs_t *hw, void __iomem *base, hw->chipset = ide_acorn; } -static const struct ide_port_info icside_v5_port_info = { - .host_flags = IDE_HFLAG_NO_DMA, -}; - static int __devinit icside_register_v5(struct icside_state *state, struct expansion_card *ec) { @@ -431,7 +445,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec); - host = ide_host_alloc(&icside_v5_port_info, hws); + host = ide_host_alloc(NULL, hws); if (host == NULL) return -ENODEV; @@ -439,7 +453,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) ecard_set_drvdata(ec, state); - ret = ide_host_register(host, &icside_v5_port_info, hws); + ret = ide_host_register(host, NULL, hws); if (ret) goto err_free; diff --git a/trunk/drivers/ide/ide-4drives.c b/trunk/drivers/ide/ide-4drives.c index 78aca75a2c48..9e85b1ec9607 100644 --- a/trunk/drivers/ide/ide-4drives.c +++ b/trunk/drivers/ide/ide-4drives.c @@ -23,8 +23,7 @@ static const struct ide_port_ops ide_4drives_port_ops = { static const struct ide_port_info ide_4drives_port_info = { .port_ops = &ide_4drives_port_ops, - .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA | - IDE_HFLAG_4DRIVES, + .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA, }; static int __init ide_4drives_init(void) diff --git a/trunk/drivers/ide/ide-acpi.c b/trunk/drivers/ide/ide-acpi.c index 12f436951bff..5b704f1ea90c 100644 --- a/trunk/drivers/ide/ide-acpi.c +++ b/trunk/drivers/ide/ide-acpi.c @@ -304,7 +304,7 @@ static int do_drive_set_taskfiles(ide_drive_t *drive, /* send all taskfile registers (0x1f1-0x1f7) *in*that*order* */ for (ix = 0; ix < gtf_count; ix++) { u8 *gtf = (u8 *)(gtf_address + ix * REGS_PER_GTF); - struct ide_cmd cmd; + ide_task_t task; DEBPRINT("(0x1f1-1f7): " "hex: %02x %02x %02x %02x %02x %02x %02x\n", @@ -317,11 +317,11 @@ static int do_drive_set_taskfiles(ide_drive_t *drive, } /* convert GTF to taskfile */ - memset(&cmd, 0, sizeof(cmd)); - memcpy(&cmd.tf_array[7], gtf, REGS_PER_GTF); - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + memset(&task, 0, sizeof(ide_task_t)); + memcpy(&task.tf_array[7], gtf, REGS_PER_GTF); + task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - err = ide_no_data_taskfile(drive, &cmd); + err = ide_no_data_taskfile(drive, &task); if (err) { printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n", __func__, err); diff --git a/trunk/drivers/ide/ide-atapi.c b/trunk/drivers/ide/ide-atapi.c index 3e43b889dd64..6adc5b4a4406 100644 --- a/trunk/drivers/ide/ide-atapi.c +++ b/trunk/drivers/ide/ide-atapi.c @@ -6,8 +6,6 @@ #include #include #include -#include - #include #ifdef DEBUG @@ -71,6 +69,56 @@ int ide_check_atapi_device(ide_drive_t *drive, const char *s) } EXPORT_SYMBOL_GPL(ide_check_atapi_device); +/* PIO data transfer routine using the scatter gather table. */ +int ide_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, + unsigned int bcount, int write) +{ + ide_hwif_t *hwif = drive->hwif; + const struct ide_tp_ops *tp_ops = hwif->tp_ops; + xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data; + struct scatterlist *sg = pc->sg; + char *buf; + int count, done = 0; + + while (bcount) { + count = min(sg->length - pc->b_count, bcount); + + if (PageHighMem(sg_page(sg))) { + unsigned long flags; + + local_irq_save(flags); + buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; + xf(drive, NULL, buf + pc->b_count, count); + kunmap_atomic(buf - sg->offset, KM_IRQ0); + local_irq_restore(flags); + } else { + buf = sg_virt(sg); + xf(drive, NULL, buf + pc->b_count, count); + } + + bcount -= count; + pc->b_count += count; + done += count; + + if (pc->b_count == sg->length) { + if (!--pc->sg_cnt) + break; + pc->sg = sg = sg_next(sg); + pc->b_count = 0; + } + } + + if (bcount) { + printk(KERN_ERR "%s: %d leftover bytes, %s\n", drive->name, + bcount, write ? "padding with zeros" + : "discarding data"); + ide_pad_transfer(drive, write, bcount); + } + + return done; +} +EXPORT_SYMBOL_GPL(ide_io_buffers); + void ide_init_pc(struct ide_atapi_pc *pc) { memset(pc, 0, sizeof(*pc)); @@ -254,16 +302,16 @@ EXPORT_SYMBOL_GPL(ide_cd_get_xferlen); void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason) { - struct ide_cmd cmd; + ide_task_t task; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM | - IDE_TFLAG_IN_NSECT; + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM | + IDE_TFLAG_IN_NSECT; - drive->hwif->tp_ops->tf_read(drive, &cmd); + drive->hwif->tp_ops->tf_read(drive, &task); - *bcount = (cmd.tf.lbah << 8) | cmd.tf.lbam; - *ireason = cmd.tf.nsect & 3; + *bcount = (task.tf.lbah << 8) | task.tf.lbam; + *ireason = task.tf.nsect & 3; } EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); @@ -276,31 +324,29 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) { struct ide_atapi_pc *pc = drive->pc; ide_hwif_t *hwif = drive->hwif; - struct ide_cmd *cmd = &hwif->cmd; struct request *rq = hwif->rq; const struct ide_tp_ops *tp_ops = hwif->tp_ops; xfer_func_t *xferfunc; - unsigned int timeout, done; + unsigned int timeout, temp; u16 bcount; u8 stat, ireason, dsc = 0; - u8 write = !!(pc->flags & PC_FLAG_WRITING); debug_log("Enter %s - interrupt handler\n", __func__); timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD : WAIT_TAPE_CMD; + if (pc->flags & PC_FLAG_TIMEDOUT) { + drive->pc_callback(drive, 0); + return ide_stopped; + } + /* Clear the interrupt */ stat = tp_ops->read_status(hwif); if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { - int rc; - - drive->waiting_for_dma = 0; - rc = hwif->dma_ops->dma_end(drive); - ide_dma_unmap_sg(drive, cmd); - - if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) { + if (hwif->dma_ops->dma_end(drive) || + (drive->media == ide_tape && (stat & ATA_ERR))) { if (drive->media == ide_floppy) printk(KERN_ERR "%s: DMA %s error\n", drive->name, rq_data_dir(pc->rq) @@ -316,9 +362,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) /* No more interrupts */ if ((stat & ATA_DRQ) == 0) { - int uptodate, error; - unsigned int done; - debug_log("Packet command completed, %d bytes transferred\n", pc->xferred); @@ -357,31 +400,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) dsc = 1; /* Command finished - Call the callback function */ - uptodate = drive->pc_callback(drive, dsc); - - if (uptodate == 0) - drive->failed_pc = NULL; - - if (blk_special_request(rq)) { - rq->errors = 0; - done = blk_rq_bytes(rq); - error = 0; - } else { - - if (blk_fs_request(rq) == 0 && uptodate <= 0) { - if (rq->errors == 0) - rq->errors = -EIO; - } - - if (drive->media == ide_tape) - done = ide_rq_bytes(rq); /* FIXME */ - else - done = blk_rq_bytes(rq); + drive->pc_callback(drive, dsc); - error = uptodate ? 0 : -EIO; - } - - ide_complete_rq(drive, error, done); return ide_stopped; } @@ -401,7 +421,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) return ide_do_reset(drive); } - if (((ireason & ATAPI_IO) == ATAPI_IO) == write) { + if (((ireason & ATAPI_IO) == ATAPI_IO) == + !!(pc->flags & PC_FLAG_WRITING)) { /* Hopefully, we will never get here */ printk(KERN_ERR "%s: We wanted to %s, but the device wants us " "to %s!\n", drive->name, @@ -410,57 +431,78 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) return ide_do_reset(drive); } - xferfunc = write ? tp_ops->output_data : tp_ops->input_data; - - if (drive->media == ide_floppy && pc->buf == NULL) { - done = min_t(unsigned int, bcount, cmd->nleft); - ide_pio_bytes(drive, cmd, write, done); - } else if (drive->media == ide_tape && pc->bh) { - done = drive->pc_io_buffers(drive, pc, bcount, write); - } else { - done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred); - xferfunc(drive, NULL, pc->cur_pos, done); - } - - /* Update the current position */ - pc->xferred += done; - pc->cur_pos += done; + if (!(pc->flags & PC_FLAG_WRITING)) { + /* Reading - Check that we have enough space */ + temp = pc->xferred + bcount; + if (temp > pc->req_xfer) { + if (temp > pc->buf_size) { + printk(KERN_ERR "%s: The device wants to send " + "us more data than expected - " + "discarding data\n", + drive->name); + + ide_pad_transfer(drive, 0, bcount); + goto next_irq; + } + debug_log("The device wants to send us more data than " + "expected - allowing transfer\n"); + } + xferfunc = tp_ops->input_data; + } else + xferfunc = tp_ops->output_data; - bcount -= done; + if ((drive->media == ide_floppy && !pc->buf) || + (drive->media == ide_tape && pc->bh)) { + int done = drive->pc_io_buffers(drive, pc, bcount, + !!(pc->flags & PC_FLAG_WRITING)); - if (bcount) - ide_pad_transfer(drive, write, bcount); + /* FIXME: don't do partial completions */ + if (drive->media == ide_floppy) + ide_end_request(drive, 1, done >> 9); + } else + xferfunc(drive, NULL, pc->cur_pos, bcount); - debug_log("[cmd %x] transferred %d bytes, padded %d bytes\n", - rq->cmd[0], done, bcount); + /* Update the current position */ + pc->xferred += bcount; + pc->cur_pos += bcount; + debug_log("[cmd %x] transferred %d bytes on that intr.\n", + rq->cmd[0], bcount); +next_irq: /* And set the interrupt handler again */ - ide_set_handler(drive, ide_pc_intr, timeout); + ide_set_handler(drive, ide_pc_intr, timeout, NULL); return ide_started; } -static void ide_init_packet_cmd(struct ide_cmd *cmd, u32 tf_flags, - u16 bcount, u8 dma) +static void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount) { - cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO; - cmd->tf_flags |= IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM | - IDE_TFLAG_OUT_FEATURE | tf_flags; - cmd->tf.command = ATA_CMD_PACKET; - cmd->tf.feature = dma; /* Use PIO/DMA */ - cmd->tf.lbam = bcount & 0xff; - cmd->tf.lbah = (bcount >> 8) & 0xff; + ide_hwif_t *hwif = drive->hwif; + ide_task_t task; + u8 dma = drive->dma; + + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM | + IDE_TFLAG_OUT_FEATURE | tf_flags; + task.tf.feature = dma; /* Use PIO/DMA */ + task.tf.lbam = bcount & 0xff; + task.tf.lbah = (bcount >> 8) & 0xff; + + ide_tf_dump(drive->name, &task.tf); + hwif->tp_ops->set_irq(hwif, 1); + SELECT_MASK(drive, 0); + hwif->tp_ops->tf_load(drive, &task); } static u8 ide_read_ireason(ide_drive_t *drive) { - struct ide_cmd cmd; + ide_task_t task; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf_flags = IDE_TFLAG_IN_NSECT; + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_IN_NSECT; - drive->hwif->tp_ops->tf_read(drive, &cmd); + drive->hwif->tp_ops->tf_read(drive, &task); - return cmd.tf.nsect & 3; + return task.tf.nsect & 3; } static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) @@ -555,17 +597,11 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) } } - hwif->expiry = expiry; - /* Set the interrupt routine */ ide_set_handler(drive, (dev_is_idecd(drive) ? drive->irq_handler : ide_pc_intr), - timeout); - - /* Send the actual packet */ - if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0) - hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len); + timeout, expiry); /* Begin DMA, if necessary */ if (dev_is_idecd(drive)) { @@ -578,28 +614,30 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) } } + /* Send the actual packet */ + if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0) + hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len); + return ide_started; } -ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) +ide_startstop_t ide_issue_pc(ide_drive_t *drive) { struct ide_atapi_pc *pc; ide_hwif_t *hwif = drive->hwif; ide_expiry_t *expiry = NULL; - struct request *rq = hwif->rq; unsigned int timeout; u32 tf_flags; u16 bcount; - u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT); if (dev_is_idecd(drive)) { tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; - bcount = ide_cd_get_xferlen(rq); + bcount = ide_cd_get_xferlen(hwif->rq); expiry = ide_cd_expiry; timeout = ATAPI_WAIT_PC; if (drive->dma) - drive->dma = !ide_dma_prepare(drive, cmd); + drive->dma = !hwif->dma_ops->dma_setup(drive); } else { pc = drive->pc; @@ -617,8 +655,9 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) ide_dma_off(drive); } - if (pc->flags & PC_FLAG_DMA_OK) - drive->dma = !ide_dma_prepare(drive, cmd); + if ((pc->flags & PC_FLAG_DMA_OK) && + (drive->dev_flags & IDE_DFLAG_USING_DMA)) + drive->dma = !hwif->dma_ops->dma_setup(drive); if (!drive->dma) pc->flags &= ~PC_FLAG_DMA_OK; @@ -627,18 +666,18 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) : WAIT_TAPE_CMD; } - ide_init_packet_cmd(cmd, tf_flags, bcount, drive->dma); - - (void)do_rw_taskfile(drive, cmd); + ide_pktcmd_tf_load(drive, tf_flags, bcount); - if (drq_int) { + /* Issue the packet command */ + if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { if (drive->dma) drive->waiting_for_dma = 0; - hwif->expiry = expiry; + ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc, + timeout, expiry); + return ide_started; + } else { + ide_execute_pkt_cmd(drive); + return ide_transfer_pc(drive); } - - ide_execute_command(drive, cmd, ide_transfer_pc, timeout); - - return drq_int ? ide_started : ide_transfer_pc(drive); } EXPORT_SYMBOL_GPL(ide_issue_pc); diff --git a/trunk/drivers/ide/ide-cd.c b/trunk/drivers/ide/ide-cd.c index 35729a47f797..2177cd11664c 100644 --- a/trunk/drivers/ide/ide-cd.c +++ b/trunk/drivers/ide/ide-cd.c @@ -4,7 +4,7 @@ * Copyright (C) 1994-1996 Scott Snyder * Copyright (C) 1996-1998 Erik Andersen * Copyright (C) 1998-2000 Jens Axboe - * Copyright (C) 2005, 2007-2009 Bartlomiej Zolnierkiewicz + * Copyright (C) 2005, 2007 Bartlomiej Zolnierkiewicz * * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. @@ -12,9 +12,12 @@ * See Documentation/cdrom/ide-cd for usage information. * * Suggestions are welcome. Patches that work are more welcome though. ;-) - * - * Documentation: - * Mt. Fuji (SFF8090 version 4) and ATAPI (SFF-8020i rev 2.6) standards. + * For those wishing to work on this driver, please be sure you download + * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI + * (SFF-8020i rev 2.6) standards. These documents can be obtained by + * anonymous ftp from: + * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps + * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf * * For historical changelog please see: * Documentation/ide/ChangeLog.ide-cd.1994-2004 @@ -97,7 +100,8 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, { int log = 0; - ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key); + ide_debug_log(IDE_DBG_SENSE, "Call %s, sense_key: 0x%x\n", __func__, + sense->sense_key); if (!sense || !rq || (rq->cmd_flags & REQ_QUIET)) return 0; @@ -147,12 +151,13 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, unsigned long bio_sectors; struct cdrom_info *info = drive->driver_data; - ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x", - sense->error_code, sense->sense_key); + ide_debug_log(IDE_DBG_SENSE, "Call %s, error_code: 0x%x, " + "sense_key: 0x%x\n", __func__, sense->error_code, + sense->sense_key); if (failed_command) - ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x", - failed_command->cmd[0]); + ide_debug_log(IDE_DBG_SENSE, "%s: failed cmd: 0x%x\n", + __func__, failed_command->cmd[0]); if (!cdrom_log_sense(drive, failed_command, sense)) return; @@ -210,9 +215,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, struct request *failed_command) { struct cdrom_info *info = drive->driver_data; - struct request *rq = &drive->request_sense_rq; + struct request *rq = &info->request_sense_request; - ide_debug_log(IDE_DBG_SENSE, "enter"); + ide_debug_log(IDE_DBG_SENSE, "Call %s\n", __func__); if (sense == NULL) sense = &info->sense_data; @@ -234,42 +239,79 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, rq->buffer = (void *) failed_command; if (failed_command) - ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x", - failed_command->cmd[0]); + ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x\n", + failed_command->cmd[0]); drive->hwif->rq = NULL; elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); } -static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) +static void cdrom_end_request(ide_drive_t *drive, int uptodate) { - /* - * For REQ_TYPE_SENSE, "rq->buffer" points to the original - * failed request - */ - struct request *failed = (struct request *)rq->buffer; - struct cdrom_info *info = drive->driver_data; - void *sense = &info->sense_data; + struct request *rq = drive->hwif->rq; + int nsectors = rq->hard_cur_sectors; - if (failed) { - if (failed->sense) { - sense = failed->sense; - failed->sense_len = rq->sense_len; - } - cdrom_analyze_sense_data(drive, failed, sense); + ide_debug_log(IDE_DBG_FUNC, "Call %s, cmd: 0x%x, uptodate: 0x%x, " + "nsectors: %d\n", __func__, rq->cmd[0], uptodate, + nsectors); - if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed))) - BUG(); - } else - cdrom_analyze_sense_data(drive, NULL, sense); + if (blk_sense_request(rq) && uptodate) { + /* + * For REQ_TYPE_SENSE, "rq->buffer" points to the original + * failed request + */ + struct request *failed = (struct request *) rq->buffer; + struct cdrom_info *info = drive->driver_data; + void *sense = &info->sense_data; + + if (failed) { + if (failed->sense) { + sense = failed->sense; + failed->sense_len = rq->sense_len; + } + cdrom_analyze_sense_data(drive, failed, sense); + /* + * now end the failed request + */ + if (blk_fs_request(failed)) { + if (ide_end_dequeued_request(drive, failed, 0, + failed->hard_nr_sectors)) + BUG(); + } else { + if (blk_end_request(failed, -EIO, + failed->data_len)) + BUG(); + } + } else + cdrom_analyze_sense_data(drive, NULL, sense); + } + + if (!rq->current_nr_sectors && blk_fs_request(rq)) + uptodate = 1; + /* make sure it's fully ended */ + if (blk_pc_request(rq)) + nsectors = (rq->data_len + 511) >> 9; + if (!nsectors) + nsectors = 1; + + ide_debug_log(IDE_DBG_FUNC, "Exit %s, uptodate: 0x%x, nsectors: %d\n", + __func__, uptodate, nsectors); + + ide_end_request(drive, uptodate, nsectors); +} + +static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st) +{ + if (st & 0x80) + return; + ide_dump_status(drive, msg, st); } /* * Returns: * 0: if the request should be continued. - * 1: if the request will be going through error recovery. - * 2: if the request should be ended. + * 1: if the request was ended. */ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) { @@ -290,10 +332,15 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) err = ide_read_error(drive); sense_key = err >> 4; - ide_debug_log(IDE_DBG_RQ, "stat: 0x%x, good_stat: 0x%x, cmd[0]: 0x%x, " - "rq->cmd_type: 0x%x, err: 0x%x", - stat, good_stat, rq->cmd[0], rq->cmd_type, - err); + if (rq == NULL) { + printk(KERN_ERR PFX "%s: missing rq in %s\n", + drive->name, __func__); + return 1; + } + + ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, " + "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x\n", + __func__, stat, good_stat, rq->cmd[0], rq->cmd_type, err); if (blk_sense_request(rq)) { /* @@ -302,7 +349,10 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) * Just give up. */ rq->cmd_flags |= REQ_FAILED; - return 2; + cdrom_end_request(drive, 0); + ide_error(drive, "request sense failure", stat); + return 1; + } else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { /* All other functions, except for READ. */ @@ -405,19 +455,21 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) * No point in retrying after an illegal request or data * protect error. */ - ide_dump_status(drive, "command error", stat); + ide_dump_status_no_sense(drive, "command error", stat); do_end_request = 1; } else if (sense_key == MEDIUM_ERROR) { /* * No point in re-trying a zillion times on a bad * sector. If we got here the error is not correctable. */ - ide_dump_status(drive, "media error (bad sector)", - stat); + ide_dump_status_no_sense(drive, + "media error (bad sector)", + stat); do_end_request = 1; } else if (sense_key == BLANK_CHECK) { /* disk appears blank ?? */ - ide_dump_status(drive, "media error (blank)", stat); + ide_dump_status_no_sense(drive, "media error (blank)", + stat); do_end_request = 1; } else if ((err & ~ATA_ABORTED) != 0) { /* go to the default handler for other errors */ @@ -442,12 +494,14 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) */ if (stat & ATA_ERR) cdrom_queue_request_sense(drive, NULL, NULL); - return 1; } else { blk_dump_rq_flags(rq, PFX "bad rq"); - return 2; + cdrom_end_request(drive, 0); } + /* retry, or handle the next request */ + return 1; + end_request: if (stat & ATA_ERR) { struct request_queue *q = drive->queue; @@ -460,9 +514,10 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) hwif->rq = NULL; cdrom_queue_request_sense(drive, rq->sense, rq); - return 1; } else - return 2; + cdrom_end_request(drive, 0); + + return 1; } /* @@ -475,7 +530,8 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, { ide_hwif_t *hwif = drive->hwif; - ide_debug_log(IDE_DBG_FUNC, "ireason: 0x%x, rw: 0x%x", ireason, rw); + ide_debug_log(IDE_DBG_FUNC, "Call %s, ireason: 0x%x, rw: 0x%x\n", + __func__, ireason, rw); /* * ireason == 0: the drive wants to receive data from us @@ -506,28 +562,115 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, if (rq->cmd_type == REQ_TYPE_ATA_PC) rq->cmd_flags |= REQ_FAILED; + cdrom_end_request(drive, 0); return -1; } -static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd) +/* + * Assume that the drive will always provide data in multiples of at least + * SECTOR_SIZE, as it gets hairy to keep track of the transfers otherwise. + */ +static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) +{ + ide_debug_log(IDE_DBG_FUNC, "Call %s, len: %d\n", __func__, len); + + if ((len % SECTOR_SIZE) == 0) + return 0; + + printk(KERN_ERR PFX "%s: %s: Bad transfer size %d\n", drive->name, + __func__, len); + + if (drive->atapi_flags & IDE_AFLAG_LIMIT_NFRAMES) + printk(KERN_ERR PFX "This drive is not supported by this " + "version of the driver\n"); + else { + printk(KERN_ERR PFX "Trying to limit transfer sizes\n"); + drive->atapi_flags |= IDE_AFLAG_LIMIT_NFRAMES; + } + + return 1; +} + +static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, + struct request *rq) { - struct request *rq = cmd->rq; + ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd_flags: 0x%x\n", __func__, + rq->cmd_flags); + + if (rq_data_dir(rq) == READ) { + unsigned short sectors_per_frame = + queue_hardsect_size(drive->queue) >> SECTOR_BITS; + int nskip = rq->sector & (sectors_per_frame - 1); - ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]); + /* + * If the requested sector doesn't start on a frame boundary, + * we must adjust the start of the transfer so that it does, + * and remember to skip the first few sectors. + * + * If the rq->current_nr_sectors field is larger than the size + * of the buffer, it will mean that we're to skip a number of + * sectors equal to the amount by which rq->current_nr_sectors + * is larger than the buffer size. + */ + if (nskip > 0) { + /* sanity check... */ + if (rq->current_nr_sectors != + bio_cur_sectors(rq->bio)) { + printk(KERN_ERR PFX "%s: %s: buffer botch (%u)\n", + drive->name, __func__, + rq->current_nr_sectors); + cdrom_end_request(drive, 0); + return ide_stopped; + } + rq->current_nr_sectors += nskip; + } + } + + /* set up the command */ + rq->timeout = ATAPI_WAIT_PC; + + return ide_started; +} + +/* + * Fix up a possibly partially-processed request so that we can start it over + * entirely, or even put it back on the request queue. + */ +static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq) +{ + + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + + if (rq->buffer != bio_data(rq->bio)) { + sector_t n = + (rq->buffer - (char *)bio_data(rq->bio)) / SECTOR_SIZE; + + rq->buffer = bio_data(rq->bio); + rq->nr_sectors += n; + rq->sector -= n; + } + rq->current_nr_sectors = bio_cur_sectors(rq->bio); + rq->hard_cur_sectors = rq->current_nr_sectors; + rq->hard_nr_sectors = rq->nr_sectors; + rq->hard_sector = rq->sector; + rq->q->prep_rq_fn(rq->q, rq); +} + +static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) +{ + ide_debug_log(IDE_DBG_FUNC, "Call %s, rq->cmd[0]: 0x%x\n", + __func__, rq->cmd[0]); /* * Some of the trailing request sense fields are optional, * and some drives don't send them. Sigh. */ if (rq->cmd[0] == GPCMD_REQUEST_SENSE && - cmd->nleft > 0 && cmd->nleft <= 5) { - unsigned int ofs = cmd->nbytes - cmd->nleft; - - while (cmd->nleft > 0) { - *((u8 *)rq->data + ofs++) = 0; - cmd->nleft--; + rq->data_len > 0 && rq->data_len <= 5) + while (rq->data_len > 0) { + *(u8 *)rq->data++ = 0; + --rq->data_len; } - } } int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, @@ -543,9 +686,9 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, if (!sense) sense = &local_sense; - ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, " - "cmd_flags: 0x%x", - cmd[0], write, timeout, cmd_flags); + ide_debug_log(IDE_DBG_PC, "Call %s, cmd[0]: 0x%x, write: 0x%x, " + "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write, + timeout, cmd_flags); /* start of retry loop */ do { @@ -607,40 +750,36 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, return (flags & REQ_FAILED) ? -EIO : 0; } -static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd) +/* + * Called from blk_end_request_callback() after the data of the request is + * completed and before the request itself is completed. By returning value '1', + * blk_end_request_callback() returns immediately without completing it. + */ +static int cdrom_newpc_intr_dummy_cb(struct request *rq) { - unsigned int nr_bytes = cmd->nbytes - cmd->nleft; - - if (cmd->tf_flags & IDE_TFLAG_WRITE) - nr_bytes -= cmd->last_xfer_len; - - if (nr_bytes > 0) - ide_complete_rq(drive, 0, nr_bytes); + return 1; } static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - struct ide_cmd *cmd = &hwif->cmd; struct request *rq = hwif->rq; + xfer_func_t *xferfunc; ide_expiry_t *expiry = NULL; int dma_error = 0, dma, stat, thislen, uptodate = 0; - int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc, nsectors; - int sense = blk_sense_request(rq); + int write = (rq_data_dir(rq) == WRITE) ? 1 : 0; unsigned int timeout; u16 len; u8 ireason; - ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x", - rq->cmd[0], write); + ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x\n", + __func__, rq->cmd[0], write); /* check for errors */ dma = drive->dma; if (dma) { drive->dma = 0; - drive->waiting_for_dma = 0; dma_error = hwif->dma_ops->dma_end(drive); - ide_dma_unmap_sg(drive, cmd); if (dma_error) { printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name, write ? "write" : "read"); @@ -648,29 +787,31 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) } } - rc = cdrom_decode_status(drive, 0, &stat); - if (rc) { - if (rc == 2) - goto out_end; + if (cdrom_decode_status(drive, 0, &stat)) return ide_stopped; - } /* using dma, transfer is complete now */ if (dma) { if (dma_error) return ide_error(drive, "dma error", stat); - uptodate = 1; - goto out_end; + if (blk_fs_request(rq)) { + ide_end_request(drive, 1, rq->nr_sectors); + return ide_stopped; + } else if (rq->cmd_type == REQ_TYPE_ATA_PC && !rq->bio) { + ide_end_request(drive, 1, 1); + return ide_stopped; + } + goto end_request; } ide_read_bcount_and_ireason(drive, &len, &ireason); - thislen = blk_fs_request(rq) ? len : cmd->nleft; + thislen = blk_fs_request(rq) ? len : rq->data_len; if (thislen > len) thislen = len; - ide_debug_log(IDE_DBG_PC, "DRQ: stat: 0x%x, thislen: %d", - stat, thislen); + ide_debug_log(IDE_DBG_PC, "%s: DRQ: stat: 0x%x, thislen: %d\n", + __func__, stat, thislen); /* If DRQ is clear, the command has completed. */ if ((stat & ATA_DRQ) == 0) { @@ -680,62 +821,135 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) * Otherwise, complete the command normally. */ uptodate = 1; - if (cmd->nleft > 0) { + if (rq->current_nr_sectors > 0) { printk(KERN_ERR PFX "%s: %s: data underrun " - "(%u bytes)\n", drive->name, __func__, - cmd->nleft); + "(%d blocks)\n", + drive->name, __func__, + rq->current_nr_sectors); if (!write) rq->cmd_flags |= REQ_FAILED; uptodate = 0; } + cdrom_end_request(drive, uptodate); + return ide_stopped; } else if (!blk_pc_request(rq)) { - ide_cd_request_sense_fixup(drive, cmd); + ide_cd_request_sense_fixup(drive, rq); /* complain if we still have data left to transfer */ - uptodate = cmd->nleft ? 0 : 1; - if (uptodate == 0) - rq->cmd_flags |= REQ_FAILED; + uptodate = rq->data_len ? 0 : 1; } - goto out_end; + goto end_request; } /* check which way to transfer data */ - rc = ide_cd_check_ireason(drive, rq, len, ireason, write); - if (rc) - goto out_end; + if (ide_cd_check_ireason(drive, rq, len, ireason, write)) + return ide_stopped; - cmd->last_xfer_len = 0; + if (blk_fs_request(rq)) { + if (write == 0) { + int nskip; + + if (ide_cd_check_transfer_size(drive, len)) { + cdrom_end_request(drive, 0); + return ide_stopped; + } - ide_debug_log(IDE_DBG_PC, "data transfer, rq->cmd_type: 0x%x, " - "ireason: 0x%x", - rq->cmd_type, ireason); + /* + * First, figure out if we need to bit-bucket + * any of the leading sectors. + */ + nskip = min_t(int, rq->current_nr_sectors + - bio_cur_sectors(rq->bio), + thislen >> 9); + if (nskip > 0) { + ide_pad_transfer(drive, write, nskip << 9); + rq->current_nr_sectors -= nskip; + thislen -= (nskip << 9); + } + } + } + + if (ireason == 0) { + write = 1; + xferfunc = hwif->tp_ops->output_data; + } else { + write = 0; + xferfunc = hwif->tp_ops->input_data; + } + + ide_debug_log(IDE_DBG_PC, "%s: data transfer, rq->cmd_type: 0x%x, " + "ireason: 0x%x\n", __func__, rq->cmd_type, ireason); /* transfer data */ while (thislen > 0) { - int blen = min_t(int, thislen, cmd->nleft); + u8 *ptr = blk_fs_request(rq) ? NULL : rq->data; + int blen = rq->data_len; + + /* bio backed? */ + if (rq->bio) { + if (blk_fs_request(rq)) { + ptr = rq->buffer; + blen = rq->current_nr_sectors << 9; + } else { + ptr = bio_data(rq->bio); + blen = bio_iovec(rq->bio)->bv_len; + } + } - if (cmd->nleft == 0) + if (!ptr) { + if (blk_fs_request(rq) && !write) + /* + * If the buffers are full, pipe the rest into + * oblivion. + */ + ide_pad_transfer(drive, 0, thislen); + else { + printk(KERN_ERR PFX "%s: confused, missing data\n", + drive->name); + blk_dump_rq_flags(rq, rq_data_dir(rq) + ? "cdrom_newpc_intr, write" + : "cdrom_newpc_intr, read"); + } break; + } + + if (blen > thislen) + blen = thislen; - ide_pio_bytes(drive, cmd, write, blen); - cmd->last_xfer_len += blen; + xferfunc(drive, NULL, ptr, blen); thislen -= blen; len -= blen; - if (sense && write == 0) + if (blk_fs_request(rq)) { + rq->buffer += blen; + rq->nr_sectors -= (blen >> 9); + rq->current_nr_sectors -= (blen >> 9); + rq->sector += (blen >> 9); + + if (rq->current_nr_sectors == 0 && rq->nr_sectors) + cdrom_end_request(drive, 1); + } else { + rq->data_len -= blen; + + /* + * The request can't be completed until DRQ is cleared. + * So complete the data, but don't complete the request + * using the dummy function for the callback feature + * of blk_end_request_callback(). + */ + if (rq->bio) + blk_end_request_callback(rq, 0, blen, + cdrom_newpc_intr_dummy_cb); + else + rq->data += blen; + } + if (!write && blk_sense_request(rq)) rq->sense_len += blen; } /* pad, if necessary */ - if (len > 0) { - if (blk_fs_request(rq) == 0 || write == 0) - ide_pad_transfer(drive, write, len); - else { - printk(KERN_ERR PFX "%s: confused, missing data\n", - drive->name); - blk_dump_rq_flags(rq, "cdrom_newpc_intr"); - } - } + if (!blk_fs_request(rq) && len > 0) + ide_pad_transfer(drive, write, len); if (blk_pc_request(rq)) { timeout = rq->timeout; @@ -745,54 +959,24 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) expiry = ide_cd_expiry; } - hwif->expiry = expiry; - ide_set_handler(drive, cdrom_newpc_intr, timeout); + ide_set_handler(drive, cdrom_newpc_intr, timeout, expiry); return ide_started; -out_end: - if (blk_pc_request(rq) && rc == 0) { +end_request: + if (blk_pc_request(rq)) { unsigned int dlen = rq->data_len; - rq->data_len = 0; + if (dma) + rq->data_len = 0; if (blk_end_request(rq, 0, dlen)) BUG(); hwif->rq = NULL; } else { - if (sense && uptodate) - ide_cd_complete_failed_rq(drive, rq); - - if (blk_fs_request(rq)) { - if (cmd->nleft == 0) - uptodate = 1; - } else { - if (uptodate <= 0 && rq->errors == 0) - rq->errors = -EIO; - } - - if (uptodate == 0) - ide_cd_error_cmd(drive, cmd); - - /* make sure it's fully ended */ - if (blk_pc_request(rq)) - nsectors = (rq->data_len + 511) >> 9; - else - nsectors = rq->hard_nr_sectors; - - if (nsectors == 0) - nsectors = 1; - - if (blk_fs_request(rq) == 0) { - rq->data_len -= (cmd->nbytes - cmd->nleft); - if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE)) - rq->data_len += cmd->last_xfer_len; - } - - ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9); - - if (sense && rc == 2) - ide_error(drive, "request sense failure", stat); + if (!uptodate) + rq->cmd_flags |= REQ_FAILED; + cdrom_end_request(drive, uptodate); } return ide_stopped; } @@ -800,48 +984,51 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) { struct cdrom_info *cd = drive->driver_data; - struct request_queue *q = drive->queue; int write = rq_data_dir(rq) == WRITE; unsigned short sectors_per_frame = - queue_hardsect_size(q) >> SECTOR_BITS; + queue_hardsect_size(drive->queue) >> SECTOR_BITS; - ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, " - "secs_per_frame: %u", - rq->cmd[0], rq->cmd_flags, sectors_per_frame); + ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, " + "secs_per_frame: %u\n", + __func__, rq->cmd[0], write, sectors_per_frame); if (write) { /* disk has become write protected */ - if (get_disk_ro(cd->disk)) + if (get_disk_ro(cd->disk)) { + cdrom_end_request(drive, 0); return ide_stopped; + } } else { /* * We may be retrying this request after an error. Fix up any * weirdness which might be present in the request packet. */ - q->prep_rq_fn(q, rq); + ide_cd_restore_request(drive, rq); } - /* fs requests *must* be hardware frame aligned */ + /* use DMA, if possible / writes *must* be hardware frame aligned */ if ((rq->nr_sectors & (sectors_per_frame - 1)) || - (rq->sector & (sectors_per_frame - 1))) - return ide_stopped; - - /* use DMA, if possible */ - drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); + (rq->sector & (sectors_per_frame - 1))) { + if (write) { + cdrom_end_request(drive, 0); + return ide_stopped; + } + drive->dma = 0; + } else + drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); if (write) cd->devinfo.media_written = 1; - rq->timeout = ATAPI_WAIT_PC; - return ide_started; } static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) { - ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x", - rq->cmd[0], rq->cmd_type); + ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, " + "rq->cmd_type: 0x%x\n", __func__, rq->cmd[0], + rq->cmd_type); if (blk_pc_request(rq)) rq->cmd_flags |= REQ_QUIET; @@ -880,18 +1067,17 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, sector_t block) { - struct ide_cmd cmd; - int uptodate = 0, nsectors; - - ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu", - rq->cmd[0], (unsigned long long)block); - - if (drive->debug_mask & IDE_DBG_RQ) - blk_dump_rq_flags(rq, "ide_cd_do_request"); + ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, " + "rq->cmd_type: 0x%x, block: %llu\n", + __func__, rq->cmd[0], rq->cmd_type, + (unsigned long long)block); if (blk_fs_request(rq)) { if (cdrom_start_rw(drive, rq) == ide_stopped) - goto out_end; + return ide_stopped; + + if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped) + return ide_stopped; } else if (blk_sense_request(rq) || blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { if (!rq->timeout) @@ -900,38 +1086,15 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, cdrom_do_block_pc(drive, rq); } else if (blk_special_request(rq)) { /* right now this can only be a reset... */ - uptodate = 1; - goto out_end; + cdrom_end_request(drive, 1); + return ide_stopped; } else { blk_dump_rq_flags(rq, DRV_NAME " bad flags"); - if (rq->errors == 0) - rq->errors = -EIO; - goto out_end; - } - - memset(&cmd, 0, sizeof(cmd)); - - if (rq_data_dir(rq)) - cmd.tf_flags |= IDE_TFLAG_WRITE; - - cmd.rq = rq; - - if (blk_fs_request(rq) || rq->data_len) { - ide_init_sg_cmd(&cmd, blk_fs_request(rq) ? (rq->nr_sectors << 9) - : rq->data_len); - ide_map_sg(drive, &cmd); + cdrom_end_request(drive, 0); + return ide_stopped; } - return ide_issue_pc(drive, &cmd); -out_end: - nsectors = rq->hard_nr_sectors; - - if (nsectors == 0) - nsectors = 1; - - ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9); - - return ide_stopped; + return ide_issue_pc(drive); } /* @@ -956,7 +1119,7 @@ int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) struct cdrom_device_info *cdi = &info->devinfo; unsigned char cmd[BLK_MAX_CDB]; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_TEST_UNIT_READY; @@ -984,7 +1147,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, unsigned len = sizeof(capbuf); u32 blocklen; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_READ_CDVD_CAPACITY; @@ -1016,8 +1179,8 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, *capacity = 1 + be32_to_cpu(capbuf.lba); *sectors_per_frame = blocklen >> SECTOR_BITS; - ide_debug_log(IDE_DBG_PROBE, "cap: %lu, sectors_per_frame: %lu", - *capacity, *sectors_per_frame); + ide_debug_log(IDE_DBG_PROBE, "%s: cap: %lu, sectors_per_frame: %lu\n", + __func__, *capacity, *sectors_per_frame); return 0; } @@ -1028,7 +1191,7 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, { unsigned char cmd[BLK_MAX_CDB]; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); memset(cmd, 0, BLK_MAX_CDB); @@ -1058,7 +1221,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense) long last_written; unsigned long sectors_per_frame = SECTORS_PER_FRAME; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); if (toc == NULL) { /* try to allocate space */ @@ -1220,7 +1383,7 @@ int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf) struct packet_command cgc; int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0) size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE; @@ -1240,7 +1403,7 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) struct cdrom_info *cd = drive->driver_data; u16 curspeed, maxspeed; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) { curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]); @@ -1250,8 +1413,8 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]); } - ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u", - curspeed, maxspeed); + ide_debug_log(IDE_DBG_PROBE, "%s: curspeed: %u, maxspeed: %u\n", + __func__, curspeed, maxspeed); cd->current_speed = (curspeed + (176/2)) / 176; cd->max_speed = (maxspeed + (176/2)) / 176; @@ -1285,7 +1448,7 @@ static int ide_cdrom_register(ide_drive_t *drive, int nslots) struct cdrom_info *info = drive->driver_data; struct cdrom_device_info *devinfo = &info->devinfo; - ide_debug_log(IDE_DBG_PROBE, "nslots: %d", nslots); + ide_debug_log(IDE_DBG_PROBE, "Call %s, nslots: %d\n", __func__, nslots); devinfo->ops = &ide_cdrom_dops; devinfo->speed = info->current_speed; @@ -1308,8 +1471,9 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) mechtype_t mechtype; int nslots = 1; - ide_debug_log(IDE_DBG_PROBE, "media: 0x%x, atapi_flags: 0x%lx", - drive->media, drive->atapi_flags); + ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->media: 0x%x, " + "drive->atapi_flags: 0x%lx\n", __func__, drive->media, + drive->atapi_flags); cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO | @@ -1523,6 +1687,9 @@ static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive) #endif static const struct cd_list_entry ide_cd_quirks_list[] = { + /* Limit transfer size per interrupt. */ + { "SAMSUNG CD-ROM SCR-2430", NULL, IDE_AFLAG_LIMIT_NFRAMES }, + { "SAMSUNG CD-ROM SCR-2432", NULL, IDE_AFLAG_LIMIT_NFRAMES }, /* SCR-3231 doesn't support the SET_CD_SPEED command. */ { "SAMSUNG CD-ROM SCR-3231", NULL, IDE_AFLAG_NO_SPEED_SELECT }, /* Old NEC260 (not R) was released before ATAPI 1.2 spec. */ @@ -1583,18 +1750,18 @@ static int ide_cdrom_setup(ide_drive_t *drive) { struct cdrom_info *cd = drive->driver_data; struct cdrom_device_info *cdi = &cd->devinfo; - struct request_queue *q = drive->queue; u16 *id = drive->id; char *fw_rev = (char *)&id[ATA_ID_FW_REV]; int nslots; - ide_debug_log(IDE_DBG_PROBE, "enter"); + ide_debug_log(IDE_DBG_PROBE, "Call %s\n", __func__); - blk_queue_prep_rq(q, ide_cdrom_prep_fn); - blk_queue_dma_alignment(q, 31); - blk_queue_update_dma_pad(q, 15); - - q->unplug_delay = max((1 * HZ) / 1000, 1); + blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn); + blk_queue_dma_alignment(drive->queue, 31); + blk_queue_update_dma_pad(drive->queue, 15); + drive->queue->unplug_delay = (1 * HZ) / 1000; + if (!drive->queue->unplug_delay) + drive->queue->unplug_delay = 1; drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id); @@ -1612,7 +1779,8 @@ static int ide_cdrom_setup(ide_drive_t *drive) nslots = ide_cdrom_probe_capabilities(drive); - blk_queue_hardsect_size(q, CD_FRAMESIZE); + /* set correct block size */ + blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE); if (ide_cdrom_register(drive, nslots)) { printk(KERN_ERR PFX "%s: %s failed to register device with the" @@ -1629,7 +1797,7 @@ static void ide_cd_remove(ide_drive_t *drive) { struct cdrom_info *info = drive->driver_data; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); ide_proc_unregister_driver(drive, info->driver); device_del(&info->dev); @@ -1647,7 +1815,7 @@ static void ide_cd_release(struct device *dev) ide_drive_t *drive = info->drive; struct gendisk *g = info->disk; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); kfree(info->toc); if (devinfo->handle == drive) @@ -1671,6 +1839,7 @@ static struct ide_driver ide_cdrom_driver = { .remove = ide_cd_remove, .version = IDECD_VERSION, .do_request = ide_cd_do_request, + .end_request = ide_end_request, #ifdef CONFIG_IDE_PROC_FS .proc_entries = ide_cd_proc_entries, .proc_devsets = ide_cd_proc_devsets, @@ -1791,6 +1960,9 @@ static struct block_device_operations idecd_ops = { }; /* module options */ +static char *ignore; +module_param(ignore, charp, 0400); + static unsigned long debug_mask; module_param(debug_mask, ulong, 0644); @@ -1802,8 +1974,9 @@ static int ide_cd_probe(ide_drive_t *drive) struct gendisk *g; struct request_sense sense; - ide_debug_log(IDE_DBG_PROBE, "driver_req: %s, media: 0x%x", - drive->driver_req, drive->media); + ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->driver_req: %s, " + "drive->media: 0x%x\n", __func__, drive->driver_req, + drive->media); if (!strstr("ide-cdrom", drive->driver_req)) goto failed; @@ -1811,6 +1984,15 @@ static int ide_cd_probe(ide_drive_t *drive) if (drive->media != ide_cdrom && drive->media != ide_optical) goto failed; + /* skip drives that we were told to ignore */ + if (ignore != NULL) { + if (strstr(ignore, drive->name)) { + printk(KERN_INFO PFX "ignoring drive %s\n", + drive->name); + goto failed; + } + } + drive->debug_mask = debug_mask; drive->irq_handler = cdrom_newpc_intr; diff --git a/trunk/drivers/ide/ide-cd.h b/trunk/drivers/ide/ide-cd.h index 1d97101099ce..c878bfcf1116 100644 --- a/trunk/drivers/ide/ide-cd.h +++ b/trunk/drivers/ide/ide-cd.h @@ -11,7 +11,7 @@ #define IDECD_DEBUG_LOG 0 #if IDECD_DEBUG_LOG -#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args) +#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) #else #define ide_debug_log(lvl, fmt, args...) do {} while (0) #endif @@ -91,6 +91,8 @@ struct cdrom_info { on this device. */ struct request_sense sense_data; + struct request request_sense_request; + u8 max_speed; /* Max speed of the drive. */ u8 current_speed; /* Current speed of the drive. */ diff --git a/trunk/drivers/ide/ide-cs.c b/trunk/drivers/ide/ide-cs.c index 9e47f3529d55..f50210fe558f 100644 --- a/trunk/drivers/ide/ide-cs.c +++ b/trunk/drivers/ide/ide-cs.c @@ -154,7 +154,6 @@ static const struct ide_port_ops idecs_port_ops = { static const struct ide_port_info idecs_port_info = { .port_ops = &idecs_port_ops, .host_flags = IDE_HFLAG_NO_DMA, - .irq_flags = IRQF_SHARED, }; static struct ide_host *idecs_register(unsigned long io, unsigned long ctl, diff --git a/trunk/drivers/ide/ide-devsets.c b/trunk/drivers/ide/ide-devsets.c index 5bf958e5b1d5..7c3953414d47 100644 --- a/trunk/drivers/ide/ide-devsets.c +++ b/trunk/drivers/ide/ide-devsets.c @@ -183,6 +183,8 @@ ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq) err = setfunc(drive, *(int *)&rq->cmd[1]); if (err) rq->errors = err; - ide_complete_rq(drive, err, ide_rq_bytes(rq)); + else + err = 1; + ide_end_request(drive, err, 0); return ide_stopped; } diff --git a/trunk/drivers/ide/ide-disk.c b/trunk/drivers/ide/ide-disk.c index c998cf8e971a..806760d24cef 100644 --- a/trunk/drivers/ide/ide-disk.c +++ b/trunk/drivers/ide/ide-disk.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -52,26 +53,33 @@ static const u8 ide_rw_cmds[] = { ATA_CMD_WRITE_EXT, }; -static void ide_tf_set_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 dma) +static const u8 ide_data_phases[] = { + TASKFILE_MULTI_IN, + TASKFILE_MULTI_OUT, + TASKFILE_IN, + TASKFILE_OUT, + TASKFILE_IN_DMA, + TASKFILE_OUT_DMA, +}; + +static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma) { u8 index, lba48, write; - lba48 = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0; - write = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0; + lba48 = (task->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0; + write = (task->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0; - if (dma) { - cmd->protocol = ATA_PROT_DMA; + if (dma) index = 8; - } else { - cmd->protocol = ATA_PROT_PIO; - if (drive->mult_count) { - cmd->tf_flags |= IDE_TFLAG_MULTI_PIO; - index = 0; - } else - index = 4; - } + else + index = drive->mult_count ? 0 : 4; + + task->tf.command = ide_rw_cmds[index + lba48 + write]; + + if (dma) + index = 8; /* fixup index */ - cmd->tf.command = ide_rw_cmds[index + lba48 + write]; + task->data_phase = ide_data_phases[index / 2 + write]; } /* @@ -85,8 +93,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, u16 nsectors = (u16)rq->nr_sectors; u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t task; + struct ide_taskfile *tf = &task.tf; ide_startstop_t rc; if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) { @@ -96,8 +104,13 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, lba48 = 0; } - memset(&cmd, 0, sizeof(cmd)); - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + if (!dma) { + ide_init_sg_cmd(drive, rq); + ide_map_sg(drive, rq); + } + + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; if (drive->dev_flags & IDE_DFLAG_LBA) { if (lba48) { @@ -116,7 +129,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, tf->lbam = (u8)(block >> 8); tf->lbah = (u8)(block >> 16); - cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); + task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); } else { tf->nsect = nsectors & 0xff; tf->lbal = block; @@ -143,27 +156,23 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, tf->device = head; } - cmd.tf_flags |= IDE_TFLAG_FS; - if (rq_data_dir(rq)) - cmd.tf_flags |= IDE_TFLAG_WRITE; - - ide_tf_set_cmd(drive, &cmd, dma); - cmd.rq = rq; + task.tf_flags |= IDE_TFLAG_WRITE; - if (dma == 0) { - ide_init_sg_cmd(&cmd, nsectors << 9); - ide_map_sg(drive, &cmd); - } + ide_tf_set_cmd(drive, &task, dma); + if (!dma) + hwif->data_phase = task.data_phase; + task.rq = rq; - rc = do_rw_taskfile(drive, &cmd); + rc = do_rw_taskfile(drive, &task); if (rc == ide_stopped && dma) { /* fallback to PIO */ - cmd.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK; - ide_tf_set_cmd(drive, &cmd, 0); - ide_init_sg_cmd(&cmd, nsectors << 9); - rc = do_rw_taskfile(drive, &cmd); + task.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK; + ide_tf_set_cmd(drive, &task, 0); + hwif->data_phase = task.data_phase; + ide_init_sg_cmd(drive, rq); + rc = do_rw_taskfile(drive, &task); } return rc; @@ -184,9 +193,7 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, if (!blk_fs_request(rq)) { blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command"); - if (rq->errors == 0) - rq->errors = -EIO; - ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); + ide_end_request(drive, 0, 0); return ide_stopped; } @@ -209,25 +216,25 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, */ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48) { - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t args; + struct ide_taskfile *tf = &args.tf; u64 addr = 0; - memset(&cmd, 0, sizeof(cmd)); + /* Create IDE/ATA command request structure */ + memset(&args, 0, sizeof(ide_task_t)); if (lba48) tf->command = ATA_CMD_READ_NATIVE_MAX_EXT; else tf->command = ATA_CMD_READ_NATIVE_MAX; tf->device = ATA_LBA; - - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; if (lba48) - cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); - - ide_no_data_taskfile(drive, &cmd); + args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); + /* submit command request */ + ide_no_data_taskfile(drive, &args); /* if OK, compute maximum address value */ - if (!(tf->status & ATA_ERR)) + if ((tf->status & 0x01) == 0) addr = ide_get_lba_addr(tf, lba48) + 1; return addr; @@ -239,13 +246,13 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48) */ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48) { - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t args; + struct ide_taskfile *tf = &args.tf; u64 addr_set = 0; addr_req--; - - memset(&cmd, 0, sizeof(cmd)); + /* Create IDE/ATA command request structure */ + memset(&args, 0, sizeof(ide_task_t)); tf->lbal = (addr_req >> 0) & 0xff; tf->lbam = (addr_req >>= 8) & 0xff; tf->lbah = (addr_req >>= 8) & 0xff; @@ -259,15 +266,13 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48) tf->command = ATA_CMD_SET_MAX; } tf->device |= ATA_LBA; - - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; if (lba48) - cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); - - ide_no_data_taskfile(drive, &cmd); - + args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); + /* submit command request */ + ide_no_data_taskfile(drive, &args); /* if OK, compute maximum address value */ - if (!(tf->status & ATA_ERR)) + if ((tf->status & 0x01) == 0) addr_set = ide_get_lba_addr(tf, lba48) + 1; return addr_set; @@ -384,24 +389,24 @@ static int ide_disk_get_capacity(ide_drive_t *drive) static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) { ide_drive_t *drive = q->queuedata; - struct ide_cmd *cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC); + ide_task_t *task = kmalloc(sizeof(*task), GFP_ATOMIC); /* FIXME: map struct ide_taskfile on rq->cmd[] */ - BUG_ON(cmd == NULL); + BUG_ON(task == NULL); - memset(cmd, 0, sizeof(*cmd)); + memset(task, 0, sizeof(*task)); if (ata_id_flush_ext_enabled(drive->id) && (drive->capacity64 >= (1UL << 28))) - cmd->tf.command = ATA_CMD_FLUSH_EXT; + task->tf.command = ATA_CMD_FLUSH_EXT; else - cmd->tf.command = ATA_CMD_FLUSH; - cmd->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | - IDE_TFLAG_DYN; - cmd->protocol = ATA_PROT_NODATA; + task->tf.command = ATA_CMD_FLUSH; + task->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | + IDE_TFLAG_DYN; + task->data_phase = TASKFILE_NO_DATA; rq->cmd_type = REQ_TYPE_ATA_TASKFILE; rq->cmd_flags |= REQ_SOFTBARRIER; - rq->special = cmd; + rq->special = task; } ide_devset_get(multcount, mult_count); @@ -451,15 +456,15 @@ static int set_nowerr(ide_drive_t *drive, int arg) static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect) { - struct ide_cmd cmd; + ide_task_t task; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf.feature = feature; - cmd.tf.nsect = nsect; - cmd.tf.command = ATA_CMD_SET_FEATURES; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + memset(&task, 0, sizeof(task)); + task.tf.feature = feature; + task.tf.nsect = nsect; + task.tf.command = ATA_CMD_SET_FEATURES; + task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - return ide_no_data_taskfile(drive, &cmd); + return ide_no_data_taskfile(drive, &task); } static void update_ordered(ide_drive_t *drive) @@ -526,16 +531,15 @@ static int set_wcache(ide_drive_t *drive, int arg) static int do_idedisk_flushcache(ide_drive_t *drive) { - struct ide_cmd cmd; + ide_task_t args; - memset(&cmd, 0, sizeof(cmd)); + memset(&args, 0, sizeof(ide_task_t)); if (ata_id_flush_ext_enabled(drive->id)) - cmd.tf.command = ATA_CMD_FLUSH_EXT; + args.tf.command = ATA_CMD_FLUSH_EXT; else - cmd.tf.command = ATA_CMD_FLUSH; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - - return ide_no_data_taskfile(drive, &cmd); + args.tf.command = ATA_CMD_FLUSH; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + return ide_no_data_taskfile(drive, &args); } ide_devset_get(acoustic, acoustic); @@ -707,17 +711,17 @@ static int ide_disk_init_media(ide_drive_t *drive, struct gendisk *disk) static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk, int on) { - struct ide_cmd cmd; + ide_task_t task; int ret; if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) return 0; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + memset(&task, 0, sizeof(task)); + task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK; + task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - ret = ide_no_data_taskfile(drive, &cmd); + ret = ide_no_data_taskfile(drive, &task); if (ret) drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; @@ -733,5 +737,6 @@ const struct ide_disk_ops ide_ata_disk_ops = { .init_media = ide_disk_init_media, .set_doorlock = ide_disk_set_doorlock, .do_request = ide_do_rw_disk, + .end_request = ide_end_request, .ioctl = ide_disk_ioctl, }; diff --git a/trunk/drivers/ide/ide-disk_proc.c b/trunk/drivers/ide/ide-disk_proc.c index eaea3bef2073..1f86dcbd2b1c 100644 --- a/trunk/drivers/ide/ide-disk_proc.c +++ b/trunk/drivers/ide/ide-disk_proc.c @@ -1,38 +1,38 @@ #include #include +#include #include "ide-disk.h" static int smart_enable(ide_drive_t *drive) { - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t args; + struct ide_taskfile *tf = &args.tf; - memset(&cmd, 0, sizeof(cmd)); + memset(&args, 0, sizeof(ide_task_t)); tf->feature = ATA_SMART_ENABLE; tf->lbam = ATA_SMART_LBAM_PASS; tf->lbah = ATA_SMART_LBAH_PASS; tf->command = ATA_CMD_SMART; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - - return ide_no_data_taskfile(drive, &cmd); + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + return ide_no_data_taskfile(drive, &args); } static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) { - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t args; + struct ide_taskfile *tf = &args.tf; - memset(&cmd, 0, sizeof(cmd)); + memset(&args, 0, sizeof(ide_task_t)); tf->feature = sub_cmd; tf->nsect = 0x01; tf->lbam = ATA_SMART_LBAM_PASS; tf->lbah = ATA_SMART_LBAH_PASS; tf->command = ATA_CMD_SMART; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - cmd.protocol = ATA_PROT_PIO; - - return ide_raw_taskfile(drive, &cmd, buf, 1); + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + args.data_phase = TASKFILE_IN; + (void) smart_enable(drive); + return ide_raw_taskfile(drive, &args, buf, 1); } static int proc_idedisk_read_cache @@ -67,8 +67,6 @@ static int proc_idedisk_read_smart(char *page, char **start, off_t off, ide_drive_t *drive = (ide_drive_t *)data; int len = 0, i = 0; - (void)smart_enable(drive); - if (get_smart_data(drive, page, sub_cmd) == 0) { unsigned short *val = (unsigned short *) page; char *out = (char *)val + SECTOR_SIZE; diff --git a/trunk/drivers/ide/ide-dma-sff.c b/trunk/drivers/ide/ide-dma-sff.c index 16fc46edc32d..123d393658af 100644 --- a/trunk/drivers/ide/ide-dma-sff.c +++ b/trunk/drivers/ide/ide-dma-sff.c @@ -38,9 +38,10 @@ int config_drive_for_dma(ide_drive_t *drive) * Enable DMA on any drive that has mode2 DMA * (multi or single) enabled */ - if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 || - (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404) - return 1; + if (id[ATA_ID_FIELD_VALID] & 2) /* regular DMA */ + if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 || + (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404) + return 1; /* Consult the list of known "good" drives */ if (ide_dma_good_drive(drive)) @@ -110,7 +111,7 @@ EXPORT_SYMBOL_GPL(ide_dma_host_set); * May also be invoked from trm290.c */ -int ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) +int ide_build_dmatable(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = drive->hwif; __le32 *table = (__le32 *)hwif->dmatable_cpu; @@ -119,7 +120,11 @@ int ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) struct scatterlist *sg; u8 is_trm290 = !!(hwif->host_flags & IDE_HFLAG_TRM290); - for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) { + hwif->sg_nents = ide_build_sglist(drive, rq); + if (hwif->sg_nents == 0) + return 0; + + for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) { u32 cur_addr, cur_len, xcount, bcount; cur_addr = sg_dma_address(sg); @@ -165,6 +170,8 @@ int ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) printk(KERN_ERR "%s: %s\n", drive->name, count ? "DMA table too small" : "empty DMA table?"); + ide_destroy_dmatable(drive); + return 0; /* revert to PIO for this request */ } EXPORT_SYMBOL_GPL(ide_build_dmatable); @@ -172,7 +179,6 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable); /** * ide_dma_setup - begin a DMA phase * @drive: target device - * @cmd: command * * Build an IDE DMA PRD (IDE speak for scatter gather table) * and then set up the DMA transfer registers for a device @@ -183,16 +189,17 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable); * is returned. */ -int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +int ide_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; + struct request *rq = hwif->rq; + unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; - u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR; u8 dma_stat; /* fall back to pio! */ - if (ide_build_dmatable(drive, cmd) == 0) { - ide_map_sg(drive, cmd); + if (!ide_build_dmatable(drive, rq)) { + ide_map_sg(drive, rq); return 1; } @@ -205,9 +212,9 @@ int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) /* specify r/w */ if (mmio) - writeb(rw, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); + writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); else - outb(rw, hwif->dma_base + ATA_DMA_CMD); + outb(reading, hwif->dma_base + ATA_DMA_CMD); /* read DMA status for INTR & ERROR flags */ dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); @@ -215,12 +222,13 @@ int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) /* clear INTR & ERROR flags */ ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR); + drive->waiting_for_dma = 1; return 0; } EXPORT_SYMBOL_GPL(ide_dma_setup); /** - * ide_dma_sff_timer_expiry - handle a DMA timeout + * dma_timer_expiry - handle a DMA timeout * @drive: Drive that timed out * * An IDE DMA transfer timed out. In the event of an error we ask @@ -233,7 +241,7 @@ EXPORT_SYMBOL_GPL(ide_dma_setup); * This can occur if an interrupt is lost or due to hang or bugs. */ -int ide_dma_sff_timer_expiry(ide_drive_t *drive) +static int dma_timer_expiry(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); @@ -257,7 +265,14 @@ int ide_dma_sff_timer_expiry(ide_drive_t *drive) return 0; /* Status is unknown -- reset the bus */ } -EXPORT_SYMBOL_GPL(ide_dma_sff_timer_expiry); + +void ide_dma_exec_cmd(ide_drive_t *drive, u8 command) +{ + /* issue cmd to drive */ + ide_execute_command(drive, command, &ide_dma_intr, 2 * WAIT_CMD, + dma_timer_expiry); +} +EXPORT_SYMBOL_GPL(ide_dma_exec_cmd); void ide_dma_start(ide_drive_t *drive) { @@ -288,6 +303,8 @@ int ide_dma_end(ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; u8 dma_stat = 0, dma_cmd = 0, mask; + drive->waiting_for_dma = 0; + /* stop DMA */ if (hwif->host_flags & IDE_HFLAG_MMIO) { dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); @@ -304,6 +321,8 @@ int ide_dma_end(ide_drive_t *drive) /* clear INTR & ERROR bits */ ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR); + /* purge DMA mappings */ + ide_destroy_dmatable(drive); wmb(); /* verify good DMA status */ @@ -327,11 +346,12 @@ EXPORT_SYMBOL_GPL(ide_dma_test_irq); const struct ide_dma_ops sff_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = ide_dma_end, .dma_test_irq = ide_dma_test_irq, + .dma_timeout = ide_dma_timeout, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_sff_read_status = ide_dma_sff_read_status, }; EXPORT_SYMBOL_GPL(sff_dma_ops); diff --git a/trunk/drivers/ide/ide-dma.c b/trunk/drivers/ide/ide-dma.c index a0b8cab1d9a6..a878f4734f81 100644 --- a/trunk/drivers/ide/ide-dma.c +++ b/trunk/drivers/ide/ide-dma.c @@ -89,21 +89,16 @@ static const struct drive_list_entry drive_blacklist[] = { ide_startstop_t ide_dma_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - struct ide_cmd *cmd = &hwif->cmd; u8 stat = 0, dma_stat = 0; - drive->waiting_for_dma = 0; dma_stat = hwif->dma_ops->dma_end(drive); - ide_dma_unmap_sg(drive, cmd); stat = hwif->tp_ops->read_status(hwif); if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) { if (!dma_stat) { - if ((cmd->tf_flags & IDE_TFLAG_FS) == 0) - ide_finish_cmd(drive, cmd, stat); - else - ide_complete_rq(drive, 0, - cmd->rq->nr_sectors << 9); + struct request *rq = hwif->rq; + + task_end_request(drive, rq, stat); return ide_stopped; } printk(KERN_ERR "%s: %s: bad DMA status (0x%02x)\n", @@ -111,6 +106,7 @@ ide_startstop_t ide_dma_intr(ide_drive_t *drive) } return ide_error(drive, "dma_intr", stat); } +EXPORT_SYMBOL_GPL(ide_dma_intr); int ide_dma_good_drive(ide_drive_t *drive) { @@ -118,9 +114,9 @@ int ide_dma_good_drive(ide_drive_t *drive) } /** - * ide_dma_map_sg - map IDE scatter gather for DMA I/O - * @drive: the drive to map the DMA table for - * @cmd: command + * ide_build_sglist - map IDE scatter gather for DMA I/O + * @drive: the drive to build the DMA table for + * @rq: the request holding the sg list * * Perform the DMA mapping magic necessary to access the source or * target buffers of a request via DMA. The lower layers of the @@ -128,28 +124,31 @@ int ide_dma_good_drive(ide_drive_t *drive) * operate in a portable fashion. */ -static int ide_dma_map_sg(ide_drive_t *drive, struct ide_cmd *cmd) +int ide_build_sglist(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = drive->hwif; struct scatterlist *sg = hwif->sg_table; int i; - if (cmd->tf_flags & IDE_TFLAG_WRITE) - cmd->sg_dma_direction = DMA_TO_DEVICE; + ide_map_sg(drive, rq); + + if (rq_data_dir(rq) == READ) + hwif->sg_dma_direction = DMA_FROM_DEVICE; else - cmd->sg_dma_direction = DMA_FROM_DEVICE; + hwif->sg_dma_direction = DMA_TO_DEVICE; - i = dma_map_sg(hwif->dev, sg, cmd->sg_nents, cmd->sg_dma_direction); + i = dma_map_sg(hwif->dev, sg, hwif->sg_nents, hwif->sg_dma_direction); if (i) { - cmd->orig_sg_nents = cmd->sg_nents; - cmd->sg_nents = i; + hwif->orig_sg_nents = hwif->sg_nents; + hwif->sg_nents = i; } return i; } +EXPORT_SYMBOL_GPL(ide_build_sglist); /** - * ide_dma_unmap_sg - clean up DMA mapping + * ide_destroy_dmatable - clean up DMA mapping * @drive: The drive to unmap * * Teardown mappings after DMA has completed. This must be called @@ -159,14 +158,14 @@ static int ide_dma_map_sg(ide_drive_t *drive, struct ide_cmd *cmd) * time. */ -void ide_dma_unmap_sg(ide_drive_t *drive, struct ide_cmd *cmd) +void ide_destroy_dmatable(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - dma_unmap_sg(hwif->dev, hwif->sg_table, cmd->orig_sg_nents, - cmd->sg_dma_direction); + dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->orig_sg_nents, + hwif->sg_dma_direction); } -EXPORT_SYMBOL_GPL(ide_dma_unmap_sg); +EXPORT_SYMBOL_GPL(ide_destroy_dmatable); /** * ide_dma_off_quietly - Generic DMA kill @@ -245,11 +244,12 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode) case XFER_UDMA_0: if ((id[ATA_ID_FIELD_VALID] & 4) == 0) break; - mask = id[ATA_ID_UDMA_MODES]; + if (port_ops && port_ops->udma_filter) - mask &= port_ops->udma_filter(drive); + mask = port_ops->udma_filter(drive); else - mask &= hwif->ultra_mask; + mask = hwif->ultra_mask; + mask &= id[ATA_ID_UDMA_MODES]; /* * avoid false cable warning from eighty_ninty_three() @@ -260,23 +260,18 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode) } break; case XFER_MW_DMA_0: - mask = id[ATA_ID_MWDMA_MODES]; - - /* Also look for the CF specific MWDMA modes... */ - if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 0x38)) { - u8 mode = ((id[ATA_ID_CFA_MODES] & 0x38) >> 3) - 1; - - mask |= ((2 << mode) - 1) << 3; - } - + if ((id[ATA_ID_FIELD_VALID] & 2) == 0) + break; if (port_ops && port_ops->mdma_filter) - mask &= port_ops->mdma_filter(drive); + mask = port_ops->mdma_filter(drive); else - mask &= hwif->mwdma_mask; + mask = hwif->mwdma_mask; + mask &= id[ATA_ID_MWDMA_MODES]; break; case XFER_SW_DMA_0: - mask = id[ATA_ID_SWDMA_MODES]; - if (!(mask & ATA_SWDMA2) && (id[ATA_ID_OLD_DMA_MODES] >> 8)) { + if (id[ATA_ID_FIELD_VALID] & 2) { + mask = id[ATA_ID_SWDMA_MODES] & hwif->swdma_mask; + } else if (id[ATA_ID_OLD_DMA_MODES] >> 8) { u8 mode = id[ATA_ID_OLD_DMA_MODES] >> 8; /* @@ -284,9 +279,8 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode) * (the maximum allowed mode is XFER_SW_DMA_2) */ if (mode <= 2) - mask = (2 << mode) - 1; + mask = ((2 << mode) - 1) & hwif->swdma_mask; } - mask &= hwif->swdma_mask; break; default: BUG(); @@ -403,10 +397,11 @@ int ide_id_dma_bug(ide_drive_t *drive) if ((id[ATA_ID_UDMA_MODES] >> 8) && (id[ATA_ID_MWDMA_MODES] >> 8)) goto err_out; - } else if ((id[ATA_ID_MWDMA_MODES] >> 8) && - (id[ATA_ID_SWDMA_MODES] >> 8)) - goto err_out; - + } else if (id[ATA_ID_FIELD_VALID] & 2) { + if ((id[ATA_ID_MWDMA_MODES] >> 8) && + (id[ATA_ID_SWDMA_MODES] >> 8)) + goto err_out; + } return 0; err_out: printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name); @@ -460,6 +455,21 @@ void ide_dma_lost_irq(ide_drive_t *drive) } EXPORT_SYMBOL_GPL(ide_dma_lost_irq); +void ide_dma_timeout(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + + printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name); + + if (hwif->dma_ops->dma_test_irq(drive)) + return; + + ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif)); + + hwif->dma_ops->dma_end(drive); +} +EXPORT_SYMBOL_GPL(ide_dma_timeout); + /* * un-busy the port etc, and clear any pending DMA status. we want to * retry the current request in pio mode instead of risking tossing it @@ -468,8 +478,6 @@ EXPORT_SYMBOL_GPL(ide_dma_lost_irq); ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) { ide_hwif_t *hwif = drive->hwif; - const struct ide_dma_ops *dma_ops = hwif->dma_ops; - struct ide_cmd *cmd = &hwif->cmd; struct request *rq; ide_startstop_t ret = ide_stopped; @@ -479,23 +487,12 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) if (error < 0) { printk(KERN_WARNING "%s: DMA timeout error\n", drive->name); - drive->waiting_for_dma = 0; - (void)dma_ops->dma_end(drive); - ide_dma_unmap_sg(drive, cmd); + (void)hwif->dma_ops->dma_end(drive); ret = ide_error(drive, "dma timeout error", hwif->tp_ops->read_status(hwif)); } else { printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name); - if (dma_ops->dma_clear) - dma_ops->dma_clear(drive); - printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name); - if (dma_ops->dma_test_irq(drive) == 0) { - ide_dump_status(drive, "DMA timeout", - hwif->tp_ops->read_status(hwif)); - drive->waiting_for_dma = 0; - (void)dma_ops->dma_end(drive); - ide_dma_unmap_sg(drive, cmd); - } + hwif->dma_ops->dma_timeout(drive); } /* @@ -565,25 +562,3 @@ int ide_allocate_dma_engine(ide_hwif_t *hwif) return 0; } EXPORT_SYMBOL_GPL(ide_allocate_dma_engine); - -int ide_dma_prepare(ide_drive_t *drive, struct ide_cmd *cmd) -{ - const struct ide_dma_ops *dma_ops = drive->hwif->dma_ops; - - if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 || - (dma_ops->dma_check && dma_ops->dma_check(drive, cmd))) - goto out; - ide_map_sg(drive, cmd); - if (ide_dma_map_sg(drive, cmd) == 0) - goto out_map; - if (dma_ops->dma_setup(drive, cmd)) - goto out_dma_unmap; - drive->waiting_for_dma = 1; - return 0; -out_dma_unmap: - ide_dma_unmap_sg(drive, cmd); -out_map: - ide_map_sg(drive, cmd); -out: - return 1; -} diff --git a/trunk/drivers/ide/ide-eh.c b/trunk/drivers/ide/ide-eh.c index 5d5fb961b5ce..1231b5e486f2 100644 --- a/trunk/drivers/ide/ide-eh.c +++ b/trunk/drivers/ide/ide-eh.c @@ -123,18 +123,8 @@ ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat) /* retry only "normal" I/O: */ if (!blk_fs_request(rq)) { - if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { - struct ide_cmd *cmd = rq->special; - - if (cmd) - ide_complete_cmd(drive, cmd, stat, err); - } else if (blk_pm_request(rq)) { - rq->errors = 1; - ide_complete_pm_rq(drive, rq); - return ide_stopped; - } - rq->errors = err; - ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq)); + rq->errors = 1; + ide_end_drive_cmd(drive, stat, err); return ide_stopped; } @@ -146,11 +136,8 @@ static inline void ide_complete_drive_reset(ide_drive_t *drive, int err) { struct request *rq = drive->hwif->rq; - if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) { - if (err <= 0 && rq->errors == 0) - rq->errors = -EIO; - ide_complete_rq(drive, err ? err : 0, ide_rq_bytes(rq)); - } + if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) + ide_end_request(drive, err ? err : 1, 0); } /* needed below */ @@ -165,18 +152,18 @@ static ide_startstop_t do_reset1(ide_drive_t *, int); static ide_startstop_t atapi_reset_pollfunc(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - const struct ide_tp_ops *tp_ops = hwif->tp_ops; u8 stat; - tp_ops->dev_select(drive); + SELECT_DRIVE(drive); udelay(10); - stat = tp_ops->read_status(hwif); + stat = hwif->tp_ops->read_status(hwif); if (OK_STAT(stat, 0, ATA_BUSY)) printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name); else { if (time_before(jiffies, hwif->poll_timeout)) { - ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20); + ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, + NULL); /* continue polling */ return ide_started; } @@ -238,7 +225,7 @@ static ide_startstop_t reset_pollfunc(ide_drive_t *drive) if (!OK_STAT(tmp, 0, ATA_BUSY)) { if (time_before(jiffies, hwif->poll_timeout)) { - ide_set_handler(drive, &reset_pollfunc, HZ/20); + ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); /* continue polling */ return ide_started; } @@ -349,13 +336,13 @@ static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi) /* For an ATAPI device, first try an ATAPI SRST. */ if (drive->media != ide_disk && !do_not_try_atapi) { pre_reset(drive); - tp_ops->dev_select(drive); + SELECT_DRIVE(drive); udelay(20); tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); ndelay(400); hwif->poll_timeout = jiffies + WAIT_WORSTCASE; hwif->polling = 1; - __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20); + __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); spin_unlock_irqrestore(&hwif->lock, flags); return ide_started; } @@ -402,19 +389,20 @@ static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi) * immediate interrupt due to the edge transition it produces. * This single interrupt gives us a "fast poll" for drives that * recover from reset very quickly, saving us the first 50ms wait time. + * + * TODO: add ->softreset method and stop abusing ->set_irq */ /* set SRST and nIEN */ - tp_ops->write_devctl(hwif, ATA_SRST | ATA_NIEN | ATA_DEVCTL_OBS); + tp_ops->set_irq(hwif, 4); /* more than enough time */ udelay(10); /* clear SRST, leave nIEN (unless device is on the quirk list) */ - tp_ops->write_devctl(hwif, (drive->quirk_list == 2 ? 0 : ATA_NIEN) | - ATA_DEVCTL_OBS); + tp_ops->set_irq(hwif, drive->quirk_list == 2); /* more than enough time */ udelay(10); hwif->poll_timeout = jiffies + WAIT_WORSTCASE; hwif->polling = 1; - __ide_set_handler(drive, &reset_pollfunc, HZ/20); + __ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); /* * Some weird controller like resetting themselves to a strange diff --git a/trunk/drivers/ide/ide-floppy.c b/trunk/drivers/ide/ide-floppy.c index 2b4868d95f8b..317ec62c33d4 100644 --- a/trunk/drivers/ide/ide-floppy.c +++ b/trunk/drivers/ide/ide-floppy.c @@ -61,20 +61,73 @@ */ #define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */ -static int ide_floppy_callback(ide_drive_t *drive, int dsc) +/* Error code returned in rq->errors to the higher part of the driver. */ +#define IDEFLOPPY_ERROR_GENERAL 101 + +/* + * Used to finish servicing a request. For read/write requests, we will call + * ide_end_request to pass to the next buffer. + */ +static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) { struct ide_disk_obj *floppy = drive->driver_data; - struct ide_atapi_pc *pc = drive->pc; + struct request *rq = drive->hwif->rq; + int error; + + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + + switch (uptodate) { + case 0: + error = IDEFLOPPY_ERROR_GENERAL; + break; + + case 1: + error = 0; + break; + + default: + error = uptodate; + } + + if (error) + floppy->failed_pc = NULL; + /* Why does this happen? */ + if (!rq) + return 0; + if (!blk_special_request(rq)) { + /* our real local end request function */ + ide_end_request(drive, uptodate, nsecs); + return 0; + } + rq->errors = error; + /* fixme: need to move this local also */ + ide_end_drive_cmd(drive, 0, 0); + return 0; +} + +static void idefloppy_update_buffers(ide_drive_t *drive, + struct ide_atapi_pc *pc) +{ struct request *rq = pc->rq; + struct bio *bio = rq->bio; + + while ((bio = rq->bio) != NULL) + ide_floppy_end_request(drive, 1, 0); +} + +static void ide_floppy_callback(ide_drive_t *drive, int dsc) +{ + struct ide_disk_obj *floppy = drive->driver_data; + struct ide_atapi_pc *pc = drive->pc; int uptodate = pc->error ? 0 : 1; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - if (drive->failed_pc == pc) - drive->failed_pc = NULL; + if (floppy->failed_pc == pc) + floppy->failed_pc = NULL; if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 || - (rq && blk_pc_request(rq))) + (pc->rq && blk_pc_request(pc->rq))) uptodate = 1; /* FIXME */ else if (pc->c[0] == GPCMD_REQUEST_SENSE) { u8 *buf = pc->buf; @@ -86,22 +139,19 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc) floppy->progress_indication = buf[15] & 0x80 ? (u16)get_unaligned((u16 *)&buf[16]) : 0x10000; - if (drive->failed_pc) - ide_debug_log(IDE_DBG_PC, "pc = %x", - drive->failed_pc->c[0]); + if (floppy->failed_pc) + ide_debug_log(IDE_DBG_PC, "pc = %x, ", + floppy->failed_pc->c[0]); ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x," - "ascq = %x", floppy->sense_key, + "ascq = %x\n", floppy->sense_key, floppy->asc, floppy->ascq); } else printk(KERN_ERR PFX "Error in REQUEST SENSE itself - " "Aborting request!\n"); } - if (blk_special_request(rq)) - rq->errors = uptodate ? 0 : IDE_DRV_ERROR_GENERAL; - - return uptodate; + ide_floppy_end_request(drive, uptodate, 0); } static void ide_floppy_report_error(struct ide_disk_obj *floppy, @@ -120,15 +170,14 @@ static void ide_floppy_report_error(struct ide_disk_obj *floppy, } -static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive, - struct ide_cmd *cmd, - struct ide_atapi_pc *pc) +static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, + struct ide_atapi_pc *pc) { struct ide_disk_obj *floppy = drive->driver_data; - if (drive->failed_pc == NULL && + if (floppy->failed_pc == NULL && pc->c[0] != GPCMD_REQUEST_SENSE) - drive->failed_pc = pc; + floppy->failed_pc = pc; /* Set the current packet command */ drive->pc = pc; @@ -137,18 +186,18 @@ static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive, if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) ide_floppy_report_error(floppy, pc); /* Giving up */ - pc->error = IDE_DRV_ERROR_GENERAL; + pc->error = IDEFLOPPY_ERROR_GENERAL; - drive->failed_pc = NULL; + floppy->failed_pc = NULL; drive->pc_callback(drive, 0); return ide_stopped; } - ide_debug_log(IDE_DBG_FUNC, "retry #%d", pc->retries); + ide_debug_log(IDE_DBG_FUNC, "%s: Retry #%d\n", __func__, pc->retries); pc->retries++; - return ide_issue_pc(drive, cmd); + return ide_issue_pc(drive); } void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) @@ -193,7 +242,8 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive, int blocks = rq->nr_sectors / floppy->bs_factor; int cmd = rq_data_dir(rq); - ide_debug_log(IDE_DBG_FUNC, "block: %d, blocks: %d", block, blocks); + ide_debug_log(IDE_DBG_FUNC, "%s: block: %d, blocks: %d\n", __func__, + block, blocks); ide_init_pc(pc); pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; @@ -203,6 +253,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive, memcpy(rq->cmd, pc->c, 12); pc->rq = rq; + pc->b_count = 0; if (rq->cmd_flags & REQ_RW) pc->flags |= PC_FLAG_WRITING; pc->buf = NULL; @@ -216,6 +267,7 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, ide_init_pc(pc); memcpy(pc->c, rq->cmd, sizeof(pc->c)); pc->rq = rq; + pc->b_count = 0; if (rq->data_len && rq_data_dir(rq) == WRITE) pc->flags |= PC_FLAG_WRITING; pc->buf = rq->data; @@ -232,36 +284,35 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, struct request *rq, sector_t block) { struct ide_disk_obj *floppy = drive->driver_data; - struct ide_cmd cmd; + ide_hwif_t *hwif = drive->hwif; struct ide_atapi_pc *pc; - ide_debug_log(IDE_DBG_FUNC, "enter, cmd: 0x%x\n", rq->cmd[0]); + ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " + "errors: %d\n", + __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?", + rq->cmd[0], rq->cmd_type, rq->errors); - if (drive->debug_mask & IDE_DBG_RQ) - blk_dump_rq_flags(rq, (rq->rq_disk - ? rq->rq_disk->disk_name - : "dev?")); + ide_debug_log(IDE_DBG_FUNC, "%s: sector: %ld, nr_sectors: %ld, " + "current_nr_sectors: %d\n", + __func__, (long)rq->sector, rq->nr_sectors, + rq->current_nr_sectors); if (rq->errors >= ERROR_MAX) { - if (drive->failed_pc) { - ide_floppy_report_error(floppy, drive->failed_pc); - drive->failed_pc = NULL; - } else + if (floppy->failed_pc) + ide_floppy_report_error(floppy, floppy->failed_pc); + else printk(KERN_ERR PFX "%s: I/O error\n", drive->name); - if (blk_special_request(rq)) { - rq->errors = 0; - ide_complete_rq(drive, 0, blk_rq_bytes(rq)); - return ide_stopped; - } else - goto out_end; + ide_floppy_end_request(drive, 0, 0); + return ide_stopped; } if (blk_fs_request(rq)) { if (((long)rq->sector % floppy->bs_factor) || (rq->nr_sectors % floppy->bs_factor)) { printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", drive->name); - goto out_end; + ide_floppy_end_request(drive, 0, 0); + return ide_stopped; } pc = &floppy->queued_pc; idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); @@ -272,30 +323,21 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, idefloppy_blockpc_cmd(floppy, pc, rq); } else { blk_dump_rq_flags(rq, PFX "unsupported command in queue"); - goto out_end; + ide_floppy_end_request(drive, 0, 0); + return ide_stopped; } - memset(&cmd, 0, sizeof(cmd)); - - if (rq_data_dir(rq)) - cmd.tf_flags |= IDE_TFLAG_WRITE; - - cmd.rq = rq; - if (blk_fs_request(rq) || pc->req_xfer) { - ide_init_sg_cmd(&cmd, pc->req_xfer); - ide_map_sg(drive, &cmd); + ide_init_sg_cmd(drive, rq); + ide_map_sg(drive, rq); } + pc->sg = hwif->sg_table; + pc->sg_cnt = hwif->sg_nents; + pc->rq = rq; - return ide_floppy_issue_pc(drive, &cmd, pc); -out_end: - drive->failed_pc = NULL; - if (blk_fs_request(rq) == 0 && rq->errors == 0) - rq->errors = -EIO; - ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); - return ide_stopped; + return idefloppy_issue_pc(drive, pc); } /* @@ -371,11 +413,9 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) struct gendisk *disk = floppy->disk; struct ide_atapi_pc pc; u8 *cap_desc; - u8 pc_buf[256], header_len, desc_cnt; + u8 header_len, desc_cnt; int i, rc = 1, blocks, length; - ide_debug_log(IDE_DBG_FUNC, "enter"); - drive->bios_cyl = 0; drive->bios_head = drive->bios_sect = 0; floppy->blocks = 0; @@ -383,9 +423,6 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) drive->capacity64 = 0; ide_floppy_create_read_capacity_cmd(&pc); - pc.buf = &pc_buf[0]; - pc.buf_size = sizeof(pc_buf); - if (ide_queue_pc_tail(drive, disk, &pc)) { printk(KERN_ERR PFX "Can't get floppy parameters\n"); return 1; @@ -401,9 +438,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, " - "%d sector size", - i, blocks * length / 1024, - blocks, length); + "%d sector size\n", + i, blocks * length / 1024, blocks, length); if (i) continue; @@ -459,8 +495,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) "in drive\n", drive->name); break; } - ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d", - pc.buf[desc_start + 4] & 0x03); + ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d\n", + pc.buf[desc_start + 4] & 0x03); } /* Clik! disk does not support get_flexible_disk_page */ @@ -476,6 +512,8 @@ static void ide_floppy_setup(ide_drive_t *drive) u16 *id = drive->id; drive->pc_callback = ide_floppy_callback; + drive->pc_update_buffers = idefloppy_update_buffers; + drive->pc_io_buffers = ide_io_buffers; /* * We used to check revisions here. At this point however I'm giving up. @@ -537,5 +575,6 @@ const struct ide_disk_ops ide_atapi_disk_ops = { .init_media = ide_floppy_init_media, .set_doorlock = ide_set_media_lock, .do_request = ide_floppy_do_request, + .end_request = ide_floppy_end_request, .ioctl = ide_floppy_ioctl, }; diff --git a/trunk/drivers/ide/ide-floppy_ioctl.c b/trunk/drivers/ide/ide-floppy_ioctl.c index cd8a42027ede..8f8be8546038 100644 --- a/trunk/drivers/ide/ide-floppy_ioctl.c +++ b/trunk/drivers/ide/ide-floppy_ioctl.c @@ -36,9 +36,9 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) { struct ide_disk_obj *floppy = drive->driver_data; + u8 header_len, desc_cnt; int i, blocks, length, u_array_size, u_index; int __user *argp; - u8 pc_buf[256], header_len, desc_cnt; if (get_user(u_array_size, arg)) return -EFAULT; @@ -47,9 +47,6 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, return -EINVAL; ide_floppy_create_read_capacity_cmd(pc); - pc->buf = &pc_buf[0]; - pc->buf_size = sizeof(pc_buf); - if (ide_queue_pc_tail(drive, floppy->disk, pc)) { printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); return -EIO; diff --git a/trunk/drivers/ide/ide-gd.c b/trunk/drivers/ide/ide-gd.c index 1aebdf1a4f58..047109419902 100644 --- a/trunk/drivers/ide/ide-gd.c +++ b/trunk/drivers/ide/ide-gd.c @@ -145,6 +145,11 @@ static ide_startstop_t ide_gd_do_request(ide_drive_t *drive, return drive->disk_ops->do_request(drive, rq, sector); } +static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs) +{ + return drive->disk_ops->end_request(drive, uptodate, nrsecs); +} + static struct ide_driver ide_gd_driver = { .gen_driver = { .owner = THIS_MODULE, @@ -157,6 +162,7 @@ static struct ide_driver ide_gd_driver = { .shutdown = ide_gd_shutdown, .version = IDE_GD_VERSION, .do_request = ide_gd_do_request, + .end_request = ide_gd_end_request, #ifdef CONFIG_IDE_PROC_FS .proc_entries = ide_disk_proc_entries, .proc_devsets = ide_disk_proc_devsets, @@ -176,7 +182,7 @@ static int ide_gd_open(struct block_device *bdev, fmode_t mode) drive = idkp->drive; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); idkp->openers++; @@ -226,7 +232,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode) struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; - ide_debug_log(IDE_DBG_FUNC, "enter"); + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); if (idkp->openers == 1) drive->disk_ops->flush(drive); diff --git a/trunk/drivers/ide/ide-gd.h b/trunk/drivers/ide/ide-gd.h index 55970772bd04..b604bdd318a1 100644 --- a/trunk/drivers/ide/ide-gd.h +++ b/trunk/drivers/ide/ide-gd.h @@ -8,7 +8,7 @@ #define IDE_GD_DEBUG_LOG 0 #if IDE_GD_DEBUG_LOG -#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args) +#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) #else #define ide_debug_log(lvl, fmt, args...) do {} while (0) #endif @@ -20,6 +20,8 @@ struct ide_disk_obj { struct device dev; unsigned int openers; /* protected by BKL for now */ + /* Last failed packet command */ + struct ide_atapi_pc *failed_pc; /* used for blk_{fs,pc}_request() requests */ struct ide_atapi_pc queued_pc; diff --git a/trunk/drivers/ide/ide-generic.c b/trunk/drivers/ide/ide-generic.c index 7812ca0be13b..81a5282ce1eb 100644 --- a/trunk/drivers/ide/ide-generic.c +++ b/trunk/drivers/ide/ide-generic.c @@ -1,22 +1,27 @@ /* * generic/default IDE host driver * - * Copyright (C) 2004, 2008-2009 Bartlomiej Zolnierkiewicz + * Copyright (C) 2004, 2008 Bartlomiej Zolnierkiewicz * This code was split off from ide.c. See it for original copyrights. * * May be copied or modified under the terms of the GNU General Public License. */ +/* + * For special cases new interfaces may be added using sysfs, i.e. + * + * echo -n "0x168:0x36e:10" > /sys/class/ide_generic/add + * + * will add an interface using I/O ports 0x168-0x16f/0x36e and IRQ 10. + */ + #include #include #include #include #include -/* FIXME: convert arm and m32r to use ide_platform host driver */ -#ifdef CONFIG_ARM -#include -#endif +/* FIXME: convert m32r to use ide_platform host driver */ #ifdef CONFIG_M32R #include #endif @@ -27,15 +32,62 @@ static int probe_mask; module_param(probe_mask, int, 0); MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports"); -static const struct ide_port_info ide_generic_port_info = { - .host_flags = IDE_HFLAG_NO_DMA, +static ssize_t store_add(struct class *cls, const char *buf, size_t n) +{ + unsigned int base, ctl; + int irq, rc; + hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; + + if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3) + return -EINVAL; + + memset(&hw, 0, sizeof(hw)); + ide_std_init_ports(&hw, base, ctl); + hw.irq = irq; + hw.chipset = ide_generic; + + rc = ide_host_add(NULL, hws, NULL); + if (rc) + return rc; + + return n; }; -#ifdef CONFIG_ARM -static const u16 legacy_bases[] = { 0x1f0 }; -static const int legacy_irqs[] = { IRQ_HARDDISK }; -#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) || \ - defined(CONFIG_PLAT_OPSPUT) +static struct class_attribute ide_generic_class_attrs[] = { + __ATTR(add, S_IWUSR, NULL, store_add), + __ATTR_NULL +}; + +static void ide_generic_class_release(struct class *cls) +{ + kfree(cls); +} + +static int __init ide_generic_sysfs_init(void) +{ + struct class *cls; + int rc; + + cls = kzalloc(sizeof(*cls), GFP_KERNEL); + if (!cls) + return -ENOMEM; + + cls->name = DRV_NAME; + cls->owner = THIS_MODULE; + cls->class_release = ide_generic_class_release; + cls->class_attrs = ide_generic_class_attrs; + + rc = class_register(cls); + if (rc) { + kfree(cls); + return rc; + } + + return 0; +} + +#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) \ + || defined(CONFIG_PLAT_OPSPUT) static const u16 legacy_bases[] = { 0x1f0 }; static const int legacy_irqs[] = { PLD_IRQ_CFIREQ }; #elif defined(CONFIG_PLAT_MAPPI3) @@ -51,11 +103,11 @@ static const int legacy_irqs[] = { 14, 15, 11, 10, 8, 12 }; static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary) { -#ifdef CONFIG_PCI struct pci_dev *p = NULL; u16 val; for_each_pci_dev(p) { + if (pci_resource_start(p, 0) == 0x1f0) *primary = 1; if (pci_resource_start(p, 2) == 0x170) @@ -70,6 +122,7 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary) /* Intel MPIIX - PIO ATA on non PCI side of bridge */ if (p->vendor == PCI_VENDOR_ID_INTEL && p->device == PCI_DEVICE_ID_INTEL_82371MX) { + pci_read_config_word(p, 0x6C, &val); if (val & 0x8000) { /* ATA port enabled */ @@ -80,7 +133,6 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary) } } } -#endif } static int __init ide_generic_init(void) @@ -112,7 +164,6 @@ static int __init ide_generic_init(void) printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX " "not free.\n", DRV_NAME, io_addr, io_addr + 7); - rc = -EBUSY; continue; } @@ -121,7 +172,6 @@ static int __init ide_generic_init(void) "not free.\n", DRV_NAME, io_addr + 0x206); release_region(io_addr, 8); - rc = -EBUSY; continue; } @@ -134,7 +184,7 @@ static int __init ide_generic_init(void) #endif hw.chipset = ide_generic; - rc = ide_host_add(&ide_generic_port_info, hws, NULL); + rc = ide_host_add(NULL, hws, NULL); if (rc) { release_region(io_addr + 0x206, 1); release_region(io_addr, 8); @@ -142,6 +192,10 @@ static int __init ide_generic_init(void) } } + if (ide_generic_sysfs_init()) + printk(KERN_ERR DRV_NAME ": failed to create ide_generic " + "class\n"); + return rc; } diff --git a/trunk/drivers/ide/ide-h8300.c b/trunk/drivers/ide/ide-h8300.c index dac9a6d44963..9270d3255ee0 100644 --- a/trunk/drivers/ide/ide-h8300.c +++ b/trunk/drivers/ide/ide-h8300.c @@ -44,78 +44,88 @@ static u16 mm_inw(unsigned long a) return r; } -static void h8300_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +static void h8300_tf_load(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; - u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; + struct ide_taskfile *tf = &task->tf; + u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; - if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) + if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_DATA) + mm_outw((tf->hob_data << 8) | tf->data, io_ports->data_addr); + + if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) outb(tf->hob_feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) outb(tf->hob_nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) outb(tf->hob_lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) outb(tf->hob_lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) outb(tf->hob_lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) outb(tf->feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_NSECT) outb(tf->nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_LBAL) outb(tf->lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_LBAM) outb(tf->lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_LBAH) outb(tf->lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) outb((tf->device & HIHI) | drive->select, io_ports->device_addr); } -static void h8300_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; + + if (task->tf_flags & IDE_TFLAG_IN_DATA) { + u16 data = mm_inw(io_ports->data_addr); + + tf->data = data & 0xff; + tf->hob_data = (data >> 8) & 0xff; + } /* be sure we're looking at the low order bits */ - outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); + outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) - tf->error = inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) + tf->feature = inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = inb(io_ports->device_addr); - if (cmd->tf_flags & IDE_TFLAG_LBA48) { - outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); - - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) - tf->hob_error = inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) - tf->hob_nsect = inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) - tf->hob_lbal = inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) - tf->hob_lbam = inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) - tf->hob_lbah = inb(io_ports->lbah_addr); + if (task->tf_flags & IDE_TFLAG_LBA48) { + outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); + + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + tf->hob_feature = inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) + tf->hob_nsect = inb(io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + tf->hob_lbal = inb(io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + tf->hob_lbam = inb(io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + tf->hob_lbah = inb(io_ports->lbah_addr); } } @@ -133,13 +143,13 @@ static void mm_insw(unsigned long addr, void *buf, u32 len) *bp = bswap(*(volatile u16 *)addr); } -static void h8300_input_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void h8300_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { mm_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); } -static void h8300_output_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void h8300_output_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); @@ -149,9 +159,9 @@ static const struct ide_tp_ops h8300_tp_ops = { .exec_command = ide_exec_command, .read_status = ide_read_status, .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - .dev_select = ide_dev_select, + .set_irq = ide_set_irq, + .tf_load = h8300_tf_load, .tf_read = h8300_tf_read, diff --git a/trunk/drivers/ide/ide-io-std.c b/trunk/drivers/ide/ide-io-std.c index 9cac281d82c4..45b43dd49cda 100644 --- a/trunk/drivers/ide/ide-io-std.c +++ b/trunk/drivers/ide/ide-io-std.c @@ -2,13 +2,6 @@ #include #include -#if defined(CONFIG_ARM) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) || \ - defined(CONFIG_PARISC) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) -#include -#else -#include -#endif - /* * Conventional PIO operations for ATA devices */ @@ -64,77 +57,83 @@ u8 ide_read_altstatus(ide_hwif_t *hwif) } EXPORT_SYMBOL_GPL(ide_read_altstatus); -void ide_write_devctl(ide_hwif_t *hwif, u8 ctl) +void ide_set_irq(ide_hwif_t *hwif, int on) { - if (hwif->host_flags & IDE_HFLAG_MMIO) - writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr); - else - outb(ctl, hwif->io_ports.ctl_addr); -} -EXPORT_SYMBOL_GPL(ide_write_devctl); + u8 ctl = ATA_DEVCTL_OBS; -void ide_dev_select(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - u8 select = drive->select | ATA_DEVICE_OBS; + if (on == 4) { /* hack for SRST */ + ctl |= 4; + on &= ~4; + } + + ctl |= on ? 0 : 2; if (hwif->host_flags & IDE_HFLAG_MMIO) - writeb(select, (void __iomem *)hwif->io_ports.device_addr); + writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr); else - outb(select, hwif->io_ports.device_addr); + outb(ctl, hwif->io_ports.ctl_addr); } -EXPORT_SYMBOL_GPL(ide_dev_select); +EXPORT_SYMBOL_GPL(ide_set_irq); -void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +void ide_tf_load(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; void (*tf_outb)(u8 addr, unsigned long port); u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; - u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; + u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; if (mmio) tf_outb = ide_mm_outb; else tf_outb = ide_outb; - if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) + if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_DATA) { + u16 data = (tf->hob_data << 8) | tf->data; + + if (mmio) + writew(data, (void __iomem *)io_ports->data_addr); + else + outw(data, io_ports->data_addr); + } + + if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) tf_outb(tf->hob_feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) tf_outb(tf->hob_nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) tf_outb(tf->hob_lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) tf_outb(tf->hob_lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) tf_outb(tf->hob_lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) tf_outb(tf->feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_NSECT) tf_outb(tf->nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_LBAL) tf_outb(tf->lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_LBAM) tf_outb(tf->lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_LBAH) tf_outb(tf->lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) tf_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); } EXPORT_SYMBOL_GPL(ide_tf_load); -void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +void ide_tf_read(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; void (*tf_outb)(u8 addr, unsigned long port); u8 (*tf_inb)(unsigned long port); u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; @@ -147,35 +146,47 @@ void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) tf_inb = ide_inb; } + if (task->tf_flags & IDE_TFLAG_IN_DATA) { + u16 data; + + if (mmio) + data = readw((void __iomem *)io_ports->data_addr); + else + data = inw(io_ports->data_addr); + + tf->data = data & 0xff; + tf->hob_data = (data >> 8) & 0xff; + } + /* be sure we're looking at the low order bits */ - tf_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); + tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) - tf->error = tf_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) + tf->feature = tf_inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = tf_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = tf_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = tf_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = tf_inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = tf_inb(io_ports->device_addr); - if (cmd->tf_flags & IDE_TFLAG_LBA48) { - tf_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); - - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) - tf->hob_error = tf_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) - tf->hob_nsect = tf_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) - tf->hob_lbal = tf_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) - tf->hob_lbam = tf_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) - tf->hob_lbah = tf_inb(io_ports->lbah_addr); + if (task->tf_flags & IDE_TFLAG_LBA48) { + tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); + + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + tf->hob_feature = tf_inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) + tf->hob_nsect = tf_inb(io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + tf->hob_lbal = tf_inb(io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + tf->hob_lbam = tf_inb(io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + tf->hob_lbah = tf_inb(io_ports->lbah_addr); } } EXPORT_SYMBOL_GPL(ide_tf_read); @@ -201,16 +212,17 @@ static void ata_vlb_sync(unsigned long port) * so if an odd len is specified, be sure that there's at least one * extra byte allocated for the buffer. */ -void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, +void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; unsigned long data_addr = io_ports->data_addr; - unsigned int words = (len + 1) >> 1; u8 io_32bit = drive->io_32bit; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; + len++; + if (io_32bit) { unsigned long uninitialized_var(flags); @@ -219,42 +231,44 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, ata_vlb_sync(io_ports->nsect_addr); } - words >>= 1; if (mmio) - __ide_mm_insl((void __iomem *)data_addr, buf, words); + __ide_mm_insl((void __iomem *)data_addr, buf, len / 4); else - insl(data_addr, buf, words); + insl(data_addr, buf, len / 4); if ((io_32bit & 2) && !mmio) local_irq_restore(flags); - if (((len + 1) & 3) < 2) - return; - - buf += len & ~3; - words = 1; + if ((len & 3) >= 2) { + if (mmio) + __ide_mm_insw((void __iomem *)data_addr, + (u8 *)buf + (len & ~3), 1); + else + insw(data_addr, (u8 *)buf + (len & ~3), 1); + } + } else { + if (mmio) + __ide_mm_insw((void __iomem *)data_addr, buf, len / 2); + else + insw(data_addr, buf, len / 2); } - - if (mmio) - __ide_mm_insw((void __iomem *)data_addr, buf, words); - else - insw(data_addr, buf, words); } EXPORT_SYMBOL_GPL(ide_input_data); /* * This is used for most PIO data transfers *to* the IDE interface */ -void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, +void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; unsigned long data_addr = io_ports->data_addr; - unsigned int words = (len + 1) >> 1; u8 io_32bit = drive->io_32bit; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; + len++; + if (io_32bit) { unsigned long uninitialized_var(flags); @@ -263,26 +277,27 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, ata_vlb_sync(io_ports->nsect_addr); } - words >>= 1; if (mmio) - __ide_mm_outsl((void __iomem *)data_addr, buf, words); + __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4); else - outsl(data_addr, buf, words); + outsl(data_addr, buf, len / 4); if ((io_32bit & 2) && !mmio) local_irq_restore(flags); - if (((len + 1) & 3) < 2) - return; - - buf += len & ~3; - words = 1; + if ((len & 3) >= 2) { + if (mmio) + __ide_mm_outsw((void __iomem *)data_addr, + (u8 *)buf + (len & ~3), 1); + else + outsw(data_addr, (u8 *)buf + (len & ~3), 1); + } + } else { + if (mmio) + __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2); + else + outsw(data_addr, buf, len / 2); } - - if (mmio) - __ide_mm_outsw((void __iomem *)data_addr, buf, words); - else - outsw(data_addr, buf, words); } EXPORT_SYMBOL_GPL(ide_output_data); @@ -290,9 +305,9 @@ const struct ide_tp_ops default_tp_ops = { .exec_command = ide_exec_command, .read_status = ide_read_status, .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - .dev_select = ide_dev_select, + .set_irq = ide_set_irq, + .tf_load = ide_tf_load, .tf_read = ide_tf_read, diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index 1deb6d29b186..2e92497b58aa 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -54,9 +55,25 @@ #include #include -int ide_end_rq(ide_drive_t *drive, struct request *rq, int error, - unsigned int nr_bytes) +static int __ide_end_request(ide_drive_t *drive, struct request *rq, + int uptodate, unsigned int nr_bytes, int dequeue) { + int ret = 1; + int error = 0; + + if (uptodate <= 0) + error = uptodate ? uptodate : -EIO; + + /* + * if failfast is set on a request, override number of sectors and + * complete the whole request right now + */ + if (blk_noretry_request(rq) && error) + nr_bytes = rq->hard_nr_sectors << 9; + + if (!blk_fs_request(rq) && error && !rq->errors) + rq->errors = -EIO; + /* * decide whether to reenable DMA -- 3 is a random magic for now, * if we DMA timeout more than 3 times, just stay in PIO @@ -67,96 +84,127 @@ int ide_end_rq(ide_drive_t *drive, struct request *rq, int error, ide_dma_on(drive); } - return blk_end_request(rq, error, nr_bytes); -} -EXPORT_SYMBOL_GPL(ide_end_rq); - -void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err) -{ - const struct ide_tp_ops *tp_ops = drive->hwif->tp_ops; - struct ide_taskfile *tf = &cmd->tf; - struct request *rq = cmd->rq; - u8 tf_cmd = tf->command; - - tf->error = err; - tf->status = stat; + if (!blk_end_request(rq, error, nr_bytes)) + ret = 0; - if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) { - u8 data[2]; + if (ret == 0 && dequeue) + drive->hwif->rq = NULL; - tp_ops->input_data(drive, cmd, data, 2); + return ret; +} - tf->data = data[0]; - tf->hob_data = data[1]; - } +/** + * ide_end_request - complete an IDE I/O + * @drive: IDE device for the I/O + * @uptodate: + * @nr_sectors: number of sectors completed + * + * This is our end_request wrapper function. We complete the I/O + * update random number input and dequeue the request, which if + * it was tagged may be out of order. + */ - tp_ops->tf_read(drive, cmd); +int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) +{ + unsigned int nr_bytes = nr_sectors << 9; + struct request *rq = drive->hwif->rq; - if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) && - tf_cmd == ATA_CMD_IDLEIMMEDIATE) { - if (tf->lbal != 0xc4) { - printk(KERN_ERR "%s: head unload failed!\n", - drive->name); - ide_tf_dump(drive->name, tf); - } else - drive->dev_flags |= IDE_DFLAG_PARKED; + if (!nr_bytes) { + if (blk_pc_request(rq)) + nr_bytes = rq->data_len; + else + nr_bytes = rq->hard_cur_sectors << 9; } - if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE) - memcpy(rq->special, cmd, sizeof(*cmd)); - - if (cmd->tf_flags & IDE_TFLAG_DYN) - kfree(cmd); + return __ide_end_request(drive, rq, uptodate, nr_bytes, 1); } +EXPORT_SYMBOL(ide_end_request); -/* obsolete, blk_rq_bytes() should be used instead */ -unsigned int ide_rq_bytes(struct request *rq) +/** + * ide_end_dequeued_request - complete an IDE I/O + * @drive: IDE device for the I/O + * @uptodate: + * @nr_sectors: number of sectors completed + * + * Complete an I/O that is no longer on the request queue. This + * typically occurs when we pull the request and issue a REQUEST_SENSE. + * We must still finish the old request but we must not tamper with the + * queue in the meantime. + * + * NOTE: This path does not handle barrier, but barrier is not supported + * on ide-cd anyway. + */ + +int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, + int uptodate, int nr_sectors) { - if (blk_pc_request(rq)) - return rq->data_len; - else - return rq->hard_cur_sectors << 9; + BUG_ON(!blk_rq_started(rq)); + + return __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0); } -EXPORT_SYMBOL_GPL(ide_rq_bytes); +EXPORT_SYMBOL_GPL(ide_end_dequeued_request); -int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes) +/** + * ide_end_drive_cmd - end an explicit drive command + * @drive: command + * @stat: status bits + * @err: error bits + * + * Clean up after success/failure of an explicit drive command. + * These get thrown onto the queue so they are synchronized with + * real I/O operations on the drive. + * + * In LBA48 mode we have to read the register set twice to get + * all the extra information out. + */ + +void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) { ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->rq; - int rc; - /* - * if failfast is set on a request, override number of sectors - * and complete the whole request right now - */ - if (blk_noretry_request(rq) && error <= 0) - nr_bytes = rq->hard_nr_sectors << 9; + if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { + ide_task_t *task = (ide_task_t *)rq->special; - rc = ide_end_rq(drive, rq, error, nr_bytes); - if (rc == 0) - hwif->rq = NULL; + if (task) { + struct ide_taskfile *tf = &task->tf; - return rc; + tf->error = err; + tf->status = stat; + + drive->hwif->tp_ops->tf_read(drive, task); + + if (task->tf_flags & IDE_TFLAG_DYN) + kfree(task); + } + } else if (blk_pm_request(rq)) { + struct request_pm_state *pm = rq->data; + + ide_complete_power_step(drive, rq); + if (pm->pm_step == IDE_PM_COMPLETED) + ide_complete_pm_request(drive, rq); + return; + } + + hwif->rq = NULL; + + rq->errors = err; + + if (unlikely(blk_end_request(rq, (rq->errors ? -EIO : 0), + blk_rq_bytes(rq)))) + BUG(); } -EXPORT_SYMBOL(ide_complete_rq); +EXPORT_SYMBOL(ide_end_drive_cmd); void ide_kill_rq(ide_drive_t *drive, struct request *rq) { - u8 drv_req = blk_special_request(rq) && rq->rq_disk; - u8 media = drive->media; - - drive->failed_pc = NULL; + if (rq->rq_disk) { + struct ide_driver *drv; - if ((media == ide_floppy || media == ide_tape) && drv_req) { - rq->errors = 0; - ide_complete_rq(drive, 0, blk_rq_bytes(rq)); - } else { - if (media == ide_tape) - rq->errors = IDE_DRV_ERROR_GENERAL; - else if (blk_fs_request(rq) == 0 && rq->errors == 0) - rq->errors = -EIO; - ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); - } + drv = *(struct ide_driver **)rq->rq_disk->private_data; + drv->end_request(drive, 0, 0); + } else + ide_end_request(drive, 0, 0); } static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) @@ -184,20 +232,20 @@ static void ide_tf_set_setmult_cmd(ide_drive_t *drive, struct ide_taskfile *tf) static ide_startstop_t ide_disk_special(ide_drive_t *drive) { special_t *s = &drive->special; - struct ide_cmd cmd; + ide_task_t args; - memset(&cmd, 0, sizeof(cmd)); - cmd.protocol = ATA_PROT_NODATA; + memset(&args, 0, sizeof(ide_task_t)); + args.data_phase = TASKFILE_NO_DATA; if (s->b.set_geometry) { s->b.set_geometry = 0; - ide_tf_set_specify_cmd(drive, &cmd.tf); + ide_tf_set_specify_cmd(drive, &args.tf); } else if (s->b.recalibrate) { s->b.recalibrate = 0; - ide_tf_set_restore_cmd(drive, &cmd.tf); + ide_tf_set_restore_cmd(drive, &args.tf); } else if (s->b.set_multmode) { s->b.set_multmode = 0; - ide_tf_set_setmult_cmd(drive, &cmd.tf); + ide_tf_set_setmult_cmd(drive, &args.tf); } else if (s->all) { int special = s->all; s->all = 0; @@ -205,10 +253,10 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive) return ide_stopped; } - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE | - IDE_TFLAG_CUSTOM_HANDLER; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE | + IDE_TFLAG_CUSTOM_HANDLER; - do_rw_taskfile(drive, &cmd); + do_rw_taskfile(drive, &args); return ide_started; } @@ -238,29 +286,33 @@ static ide_startstop_t do_special (ide_drive_t *drive) return ide_stopped; } -void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd) +void ide_map_sg(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = drive->hwif; struct scatterlist *sg = hwif->sg_table; - struct request *rq = cmd->rq; if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE); - cmd->sg_nents = 1; + hwif->sg_nents = 1; } else if (!rq->bio) { sg_init_one(sg, rq->data, rq->data_len); - cmd->sg_nents = 1; - } else - cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); + hwif->sg_nents = 1; + } else { + hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); + } } + EXPORT_SYMBOL_GPL(ide_map_sg); -void ide_init_sg_cmd(struct ide_cmd *cmd, unsigned int nr_bytes) +void ide_init_sg_cmd(ide_drive_t *drive, struct request *rq) { - cmd->nbytes = cmd->nleft = nr_bytes; - cmd->cursg_ofs = 0; - cmd->cursg = NULL; + ide_hwif_t *hwif = drive->hwif; + + hwif->nsect = hwif->nleft = rq->nr_sectors; + hwif->cursg_ofs = 0; + hwif->cursg = NULL; } + EXPORT_SYMBOL_GPL(ide_init_sg_cmd); /** @@ -278,15 +330,24 @@ EXPORT_SYMBOL_GPL(ide_init_sg_cmd); static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq) { - struct ide_cmd *cmd = rq->special; - - if (cmd) { - if (cmd->protocol == ATA_PROT_PIO) { - ide_init_sg_cmd(cmd, rq->nr_sectors << 9); - ide_map_sg(drive, cmd); + ide_hwif_t *hwif = drive->hwif; + ide_task_t *task = rq->special; + + if (task) { + hwif->data_phase = task->data_phase; + + switch (hwif->data_phase) { + case TASKFILE_MULTI_OUT: + case TASKFILE_OUT: + case TASKFILE_MULTI_IN: + case TASKFILE_IN: + ide_init_sg_cmd(drive, rq); + ide_map_sg(drive, rq); + default: + break; } - return do_rw_taskfile(drive, cmd); + return do_rw_taskfile(drive, task); } /* @@ -296,8 +357,8 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, #ifdef DEBUG printk("%s: DRIVE_CMD (null)\n", drive->name); #endif - rq->errors = 0; - ide_complete_rq(drive, 0, blk_rq_bytes(rq)); + ide_end_drive_cmd(drive, hwif->tp_ops->read_status(hwif), + ide_read_error(drive)); return ide_stopped; } @@ -315,7 +376,9 @@ static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) case REQ_DRIVE_RESET: return ide_do_reset(drive); default: - BUG(); + blk_dump_rq_flags(rq, "ide_special_rq - bad request"); + ide_end_request(drive, 0, 0); + return ide_stopped; } } @@ -348,7 +411,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) if (blk_pm_request(rq)) ide_check_pm_state(drive, rq); - drive->hwif->tp_ops->dev_select(drive); + SELECT_DRIVE(drive); if (ide_wait_stat(&startstop, drive, drive->ready_stat, ATA_BUSY | ATA_DRQ, WAIT_READY)) { printk(KERN_ERR "%s: drive not ready for command\n", drive->name); @@ -375,7 +438,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) startstop = ide_start_power_step(drive, rq); if (startstop == ide_stopped && pm->pm_step == IDE_PM_COMPLETED) - ide_complete_pm_rq(drive, rq); + ide_complete_pm_request(drive, rq); return startstop; } else if (!rq->rq_disk && blk_special_request(rq)) /* @@ -438,8 +501,8 @@ static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif) if (host->host_flags & IDE_HFLAG_SERIALIZE) { rc = test_and_set_bit_lock(IDE_HOST_BUSY, &host->host_busy); if (rc == 0) { - if (host->get_lock) - host->get_lock(ide_intr, hwif); + /* for atari only */ + ide_get_lock(ide_intr, hwif); } } return rc; @@ -448,8 +511,8 @@ static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif) static inline void ide_unlock_host(struct ide_host *host) { if (host->host_flags & IDE_HFLAG_SERIALIZE) { - if (host->release_lock) - host->release_lock(); + /* for atari only */ + ide_release_lock(); clear_bit_unlock(IDE_HOST_BUSY, &host->host_busy); } } @@ -491,10 +554,11 @@ void do_ide_request(struct request_queue *q) prev_port = hwif->host->cur_port; hwif->rq = NULL; - if (drive->dev_flags & IDE_DFLAG_SLEEPING && - time_after(drive->sleep, jiffies)) { - ide_unlock_port(hwif); - goto plug_device; + if (drive->dev_flags & IDE_DFLAG_SLEEPING) { + if (time_before(drive->sleep, jiffies)) { + ide_unlock_port(hwif); + goto plug_device; + } } if ((hwif->host->host_flags & IDE_HFLAG_SERIALIZE) && @@ -504,9 +568,7 @@ void do_ide_request(struct request_queue *q) * quirk_list may not like intr setups/cleanups */ if (prev_port && prev_port->cur_dev->quirk_list == 0) - prev_port->tp_ops->write_devctl(prev_port, - ATA_NIEN | - ATA_DEVCTL_OBS); + prev_port->tp_ops->set_irq(prev_port, 0); hwif->host->cur_port = hwif; } @@ -662,7 +724,6 @@ void ide_timer_expiry (unsigned long data) } } hwif->handler = NULL; - hwif->expiry = NULL; /* * We need to simulate a real interrupt when invoking * the handler() function, which means we need to @@ -678,8 +739,7 @@ void ide_timer_expiry (unsigned long data) } else if (drive_is_ready(drive)) { if (drive->waiting_for_dma) hwif->dma_ops->dma_lost_irq(drive); - if (hwif->ack_intr) - hwif->ack_intr(hwif); + (void)ide_ack_intr(hwif); printk(KERN_WARNING "%s: lost interrupt\n", drive->name); startstop = handler(drive); @@ -780,7 +840,6 @@ static void unexpected_intr(int irq, ide_hwif_t *hwif) irqreturn_t ide_intr (int irq, void *dev_id) { ide_hwif_t *hwif = (ide_hwif_t *)dev_id; - struct ide_host *host = hwif->host; ide_drive_t *uninitialized_var(drive); ide_handler_t *handler; unsigned long flags; @@ -788,14 +847,14 @@ irqreturn_t ide_intr (int irq, void *dev_id) irqreturn_t irq_ret = IRQ_NONE; int plug_device = 0; - if (host->host_flags & IDE_HFLAG_SERIALIZE) { - if (hwif != host->cur_port) + if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE) { + if (hwif != hwif->host->cur_port) goto out_early; } spin_lock_irqsave(&hwif->lock, flags); - if (hwif->ack_intr && hwif->ack_intr(hwif) == 0) + if (!ide_ack_intr(hwif)) goto out; handler = hwif->handler; @@ -812,19 +871,27 @@ irqreturn_t ide_intr (int irq, void *dev_id) * * For PCI, we cannot tell the difference, * so in that case we just ignore it and hope it goes away. + * + * FIXME: unexpected_intr should be hwif-> then we can + * remove all the ifdef PCI crap */ - if ((host->irq_flags & IRQF_SHARED) == 0) { +#ifdef CONFIG_BLK_DEV_IDEPCI + if (hwif->chipset != ide_pci) +#endif /* CONFIG_BLK_DEV_IDEPCI */ + { /* * Probably not a shared PCI interrupt, * so we can safely try to do something about it: */ unexpected_intr(irq, hwif); +#ifdef CONFIG_BLK_DEV_IDEPCI } else { /* * Whack the status register, just in case * we have a leftover pending IRQ. */ (void)hwif->tp_ops->read_status(hwif); +#endif /* CONFIG_BLK_DEV_IDEPCI */ } goto out; } @@ -842,7 +909,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) goto out; hwif->handler = NULL; - hwif->expiry = NULL; hwif->req_gen++; del_timer(&hwif->timer); spin_unlock(&hwif->lock); diff --git a/trunk/drivers/ide/ide-ioctls.c b/trunk/drivers/ide/ide-ioctls.c index 770142767437..1be263eb9c07 100644 --- a/trunk/drivers/ide/ide-ioctls.c +++ b/trunk/drivers/ide/ide-ioctls.c @@ -111,13 +111,13 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg) return 0; } -static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) +static int ide_cmd_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg) { u8 *buf = NULL; int bufsize = 0, err = 0; u8 args[4], xfer_rate = 0; - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t tfargs; + struct ide_taskfile *tf = &tfargs.tf; u16 *id = drive->id; if (NULL == (void *) arg) { @@ -134,24 +134,24 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) if (copy_from_user(args, (void __user *)arg, 4)) return -EFAULT; - memset(&cmd, 0, sizeof(cmd)); + memset(&tfargs, 0, sizeof(ide_task_t)); tf->feature = args[2]; if (args[0] == ATA_CMD_SMART) { tf->nsect = args[3]; tf->lbal = args[1]; tf->lbam = 0x4f; tf->lbah = 0xc2; - cmd.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT; + tfargs.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT; } else { tf->nsect = args[1]; - cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT | - IDE_TFLAG_IN_NSECT; + tfargs.tf_flags = IDE_TFLAG_OUT_FEATURE | + IDE_TFLAG_OUT_NSECT | IDE_TFLAG_IN_NSECT; } tf->command = args[0]; - cmd.protocol = args[3] ? ATA_PROT_PIO : ATA_PROT_NODATA; + tfargs.data_phase = args[3] ? TASKFILE_IN : TASKFILE_NO_DATA; if (args[3]) { - cmd.tf_flags |= IDE_TFLAG_IO_16BIT; + tfargs.tf_flags |= IDE_TFLAG_IO_16BIT; bufsize = SECTOR_SIZE * args[3]; buf = kzalloc(bufsize, GFP_KERNEL); if (buf == NULL) @@ -172,7 +172,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) } } - err = ide_raw_taskfile(drive, &cmd, buf, args[3]); + err = ide_raw_taskfile(drive, &tfargs, buf, args[3]); args[0] = tf->status; args[1] = tf->error; @@ -194,25 +194,25 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) return err; } -static int ide_task_ioctl(ide_drive_t *drive, unsigned long arg) +static int ide_task_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg) { void __user *p = (void __user *)arg; int err = 0; u8 args[7]; - struct ide_cmd cmd; + ide_task_t task; if (copy_from_user(args, p, 7)) return -EFAULT; - memset(&cmd, 0, sizeof(cmd)); - memcpy(&cmd.tf_array[7], &args[1], 6); - cmd.tf.command = args[0]; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + memset(&task, 0, sizeof(task)); + memcpy(&task.tf_array[7], &args[1], 6); + task.tf.command = args[0]; + task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - err = ide_no_data_taskfile(drive, &cmd); + err = ide_no_data_taskfile(drive, &task); - args[0] = cmd.tf.command; - memcpy(&args[1], &cmd.tf_array[7], 6); + args[0] = task.tf.command; + memcpy(&args[1], &task.tf_array[7], 6); if (copy_to_user(p, args, 7)) err = -EFAULT; @@ -262,17 +262,17 @@ int generic_ide_ioctl(ide_drive_t *drive, struct block_device *bdev, if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES; if (drive->media == ide_disk) - return ide_taskfile_ioctl(drive, arg); + return ide_taskfile_ioctl(drive, cmd, arg); return -ENOMSG; #endif case HDIO_DRIVE_CMD: if (!capable(CAP_SYS_RAWIO)) return -EACCES; - return ide_cmd_ioctl(drive, arg); + return ide_cmd_ioctl(drive, cmd, arg); case HDIO_DRIVE_TASK: if (!capable(CAP_SYS_RAWIO)) return -EACCES; - return ide_task_ioctl(drive, arg); + return ide_task_ioctl(drive, cmd, arg); case HDIO_DRIVE_RESET: if (!capable(CAP_SYS_ADMIN)) return -EACCES; diff --git a/trunk/drivers/ide/ide-iops.c b/trunk/drivers/ide/ide-iops.c index 27bb70ddd459..317c5dadd7c0 100644 --- a/trunk/drivers/ide/ide-iops.c +++ b/trunk/drivers/ide/ide-iops.c @@ -27,6 +27,21 @@ #include #include +void SELECT_DRIVE(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + const struct ide_port_ops *port_ops = hwif->port_ops; + ide_task_t task; + + if (port_ops && port_ops->selectproc) + port_ops->selectproc(drive); + + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_OUT_DEVICE; + + drive->hwif->tp_ops->tf_load(drive, &task); +} + void SELECT_MASK(ide_drive_t *drive, int mask) { const struct ide_port_ops *port_ops = drive->hwif->port_ops; @@ -37,14 +52,14 @@ void SELECT_MASK(ide_drive_t *drive, int mask) u8 ide_read_error(ide_drive_t *drive) { - struct ide_cmd cmd; + ide_task_t task; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf_flags = IDE_TFLAG_IN_ERROR; + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_IN_FEATURE; - drive->hwif->tp_ops->tf_read(drive, &cmd); + drive->hwif->tp_ops->tf_read(drive, &task); - return cmd.tf.error; + return task.tf.error; } EXPORT_SYMBOL_GPL(ide_read_error); @@ -291,7 +306,6 @@ int ide_driveid_update(ide_drive_t *drive) drive->id[ATA_ID_UDMA_MODES] = id[ATA_ID_UDMA_MODES]; drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES]; drive->id[ATA_ID_SWDMA_MODES] = id[ATA_ID_SWDMA_MODES]; - drive->id[ATA_ID_CFA_MODES] = id[ATA_ID_CFA_MODES]; /* anything more ? */ kfree(id); @@ -315,7 +329,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) u16 *id = drive->id, i; int error = 0; u8 stat; - struct ide_cmd cmd; + ide_task_t task; #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_ops) /* check if host supports DMA */ @@ -342,22 +356,22 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) disable_irq_nosync(hwif->irq); udelay(1); - tp_ops->dev_select(drive); + SELECT_DRIVE(drive); SELECT_MASK(drive, 1); udelay(1); - tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS); + tp_ops->set_irq(hwif, 0); - memset(&cmd, 0, sizeof(cmd)); - cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT; - cmd.tf.feature = SETFEATURES_XFER; - cmd.tf.nsect = speed; + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT; + task.tf.feature = SETFEATURES_XFER; + task.tf.nsect = speed; - tp_ops->tf_load(drive, &cmd); + tp_ops->tf_load(drive, &task); tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES); if (drive->quirk_list == 2) - tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); + tp_ops->set_irq(hwif, 1); error = __ide_wait_stat(drive, drive->ready_stat, ATA_BUSY | ATA_DRQ | ATA_ERR, @@ -372,14 +386,9 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) return error; } - if (speed >= XFER_SW_DMA_0) { - id[ATA_ID_UDMA_MODES] &= ~0xFF00; - id[ATA_ID_MWDMA_MODES] &= ~0x0700; - id[ATA_ID_SWDMA_MODES] &= ~0x0700; - if (ata_id_is_cfa(id)) - id[ATA_ID_CFA_MODES] &= ~0x0E00; - } else if (ata_id_is_cfa(id)) - id[ATA_ID_CFA_MODES] &= ~0x01C0; + id[ATA_ID_UDMA_MODES] &= ~0xFF00; + id[ATA_ID_MWDMA_MODES] &= ~0x0F00; + id[ATA_ID_SWDMA_MODES] &= ~0x0F00; skip: #ifdef CONFIG_BLK_DEV_IDEDMA @@ -392,18 +401,12 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) if (speed >= XFER_UDMA_0) { i = 1 << (speed - XFER_UDMA_0); id[ATA_ID_UDMA_MODES] |= (i << 8 | i); - } else if (ata_id_is_cfa(id) && speed >= XFER_MW_DMA_3) { - i = speed - XFER_MW_DMA_2; - id[ATA_ID_CFA_MODES] |= i << 9; } else if (speed >= XFER_MW_DMA_0) { i = 1 << (speed - XFER_MW_DMA_0); id[ATA_ID_MWDMA_MODES] |= (i << 8 | i); } else if (speed >= XFER_SW_DMA_0) { i = 1 << (speed - XFER_SW_DMA_0); id[ATA_ID_SWDMA_MODES] |= (i << 8 | i); - } else if (ata_id_is_cfa(id) && speed >= XFER_PIO_5) { - i = speed - XFER_PIO_4; - id[ATA_ID_CFA_MODES] |= i << 6; } if (!drive->init_speed) @@ -422,25 +425,26 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) * See also ide_execute_command */ void __ide_set_handler(ide_drive_t *drive, ide_handler_t *handler, - unsigned int timeout) + unsigned int timeout, ide_expiry_t *expiry) { ide_hwif_t *hwif = drive->hwif; BUG_ON(hwif->handler); hwif->handler = handler; + hwif->expiry = expiry; hwif->timer.expires = jiffies + timeout; hwif->req_gen_timer = hwif->req_gen; add_timer(&hwif->timer); } -void ide_set_handler(ide_drive_t *drive, ide_handler_t *handler, - unsigned int timeout) +void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, + unsigned int timeout, ide_expiry_t *expiry) { ide_hwif_t *hwif = drive->hwif; unsigned long flags; spin_lock_irqsave(&hwif->lock, flags); - __ide_set_handler(drive, handler, timeout); + __ide_set_handler(drive, handler, timeout, expiry); spin_unlock_irqrestore(&hwif->lock, flags); } EXPORT_SYMBOL(ide_set_handler); @@ -448,9 +452,10 @@ EXPORT_SYMBOL(ide_set_handler); /** * ide_execute_command - execute an IDE command * @drive: IDE drive to issue the command against - * @cmd: command + * @command: command byte to write * @handler: handler for next phase * @timeout: timeout for command + * @expiry: handler to run on timeout * * Helper function to issue an IDE command. This handles the * atomicity requirements, command timing and ensures that the @@ -458,18 +463,15 @@ EXPORT_SYMBOL(ide_set_handler); * should go via this function or do equivalent locking. */ -void ide_execute_command(ide_drive_t *drive, struct ide_cmd *cmd, - ide_handler_t *handler, unsigned timeout) +void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, + unsigned timeout, ide_expiry_t *expiry) { ide_hwif_t *hwif = drive->hwif; unsigned long flags; spin_lock_irqsave(&hwif->lock, flags); - if ((cmd->protocol != ATAPI_PROT_DMA && - cmd->protocol != ATAPI_PROT_PIO) || - (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT)) - __ide_set_handler(drive, handler, timeout); - hwif->tp_ops->exec_command(hwif, cmd->tf.command); + __ide_set_handler(drive, handler, timeout, expiry); + hwif->tp_ops->exec_command(hwif, cmd); /* * Drive takes 400nS to respond, we must avoid the IRQ being * serviced before that. @@ -479,6 +481,19 @@ void ide_execute_command(ide_drive_t *drive, struct ide_cmd *cmd, ndelay(400); spin_unlock_irqrestore(&hwif->lock, flags); } +EXPORT_SYMBOL(ide_execute_command); + +void ide_execute_pkt_cmd(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + unsigned long flags; + + spin_lock_irqsave(&hwif->lock, flags); + hwif->tp_ops->exec_command(hwif, ATA_CMD_PACKET); + ndelay(400); + spin_unlock_irqrestore(&hwif->lock, flags); +} +EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd); /* * ide_wait_not_busy() waits for the currently selected device on the hwif diff --git a/trunk/drivers/ide/ide-lib.c b/trunk/drivers/ide/ide-lib.c index 217b7fdf2b17..f6c683dd2987 100644 --- a/trunk/drivers/ide/ide-lib.c +++ b/trunk/drivers/ide/ide-lib.c @@ -34,19 +34,19 @@ void ide_toggle_bounce(ide_drive_t *drive, int on) static void ide_dump_opcode(ide_drive_t *drive) { struct request *rq = drive->hwif->rq; - struct ide_cmd *cmd = NULL; + ide_task_t *task = NULL; if (!rq) return; if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) - cmd = rq->special; + task = rq->special; printk(KERN_ERR "ide: failed opcode was: "); - if (cmd == NULL) + if (task == NULL) printk(KERN_CONT "unknown\n"); else - printk(KERN_CONT "0x%02x\n", cmd->tf.command); + printk(KERN_CONT "0x%02x\n", task->tf.command); } u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48) @@ -66,18 +66,18 @@ EXPORT_SYMBOL_GPL(ide_get_lba_addr); static void ide_dump_sector(ide_drive_t *drive) { - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t task; + struct ide_taskfile *tf = &task.tf; u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); - memset(&cmd, 0, sizeof(cmd)); + memset(&task, 0, sizeof(task)); if (lba48) - cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA | + task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA | IDE_TFLAG_LBA48; else - cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE; + task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE; - drive->hwif->tp_ops->tf_read(drive, &cmd); + drive->hwif->tp_ops->tf_read(drive, &task); if (lba48 || (tf->device & ATA_LBA)) printk(KERN_CONT ", LBAsect=%llu", diff --git a/trunk/drivers/ide/ide-park.c b/trunk/drivers/ide/ide-park.c index 9490b446519f..f30e52152fcb 100644 --- a/trunk/drivers/ide/ide-park.c +++ b/trunk/drivers/ide/ide-park.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -62,10 +63,10 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq) { - struct ide_cmd cmd; - struct ide_taskfile *tf = &cmd.tf; + ide_task_t task; + struct ide_taskfile *tf = &task.tf; - memset(&cmd, 0, sizeof(cmd)); + memset(&task, 0, sizeof(task)); if (rq->cmd[0] == REQ_PARK_HEADS) { drive->sleep = *(unsigned long *)rq->special; drive->dev_flags |= IDE_DFLAG_SLEEPING; @@ -74,16 +75,14 @@ ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq) tf->lbal = 0x4c; tf->lbam = 0x4e; tf->lbah = 0x55; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + task.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER; } else /* cmd == REQ_UNPARK_HEADS */ tf->command = ATA_CMD_CHK_POWER; - cmd.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER; - cmd.protocol = ATA_PROT_NODATA; - - cmd.rq = rq; - - return do_rw_taskfile(drive, &cmd); + task.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + task.rq = rq; + drive->hwif->data_phase = task.data_phase = TASKFILE_NO_DATA; + return do_rw_taskfile(drive, &task); } ssize_t ide_park_show(struct device *dev, struct device_attribute *attr, diff --git a/trunk/drivers/ide/ide-pm.c b/trunk/drivers/ide/ide-pm.c index bb7858ebb7d1..60538d9c84ee 100644 --- a/trunk/drivers/ide/ide-pm.c +++ b/trunk/drivers/ide/ide-pm.c @@ -1,5 +1,6 @@ #include #include +#include int generic_ide_suspend(struct device *dev, pm_message_t mesg) { @@ -7,7 +8,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) ide_hwif_t *hwif = drive->hwif; struct request *rq; struct request_pm_state rqpm; - struct ide_cmd cmd; + ide_task_t args; int ret; /* call ACPI _GTM only once */ @@ -15,10 +16,10 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) ide_acpi_get_timing(hwif); memset(&rqpm, 0, sizeof(rqpm)); - memset(&cmd, 0, sizeof(cmd)); + memset(&args, 0, sizeof(args)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_PM_SUSPEND; - rq->special = &cmd; + rq->special = &args; rq->data = &rqpm; rqpm.pm_step = IDE_PM_START_SUSPEND; if (mesg.event == PM_EVENT_PRETHAW) @@ -41,7 +42,7 @@ int generic_ide_resume(struct device *dev) ide_hwif_t *hwif = drive->hwif; struct request *rq; struct request_pm_state rqpm; - struct ide_cmd cmd; + ide_task_t args; int err; /* call ACPI _PS0 / _STM only once */ @@ -53,11 +54,11 @@ int generic_ide_resume(struct device *dev) ide_acpi_exec_tfs(drive); memset(&rqpm, 0, sizeof(rqpm)); - memset(&cmd, 0, sizeof(cmd)); + memset(&args, 0, sizeof(args)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_PM_RESUME; rq->cmd_flags |= REQ_PREEMPT; - rq->special = &cmd; + rq->special = &args; rq->data = &rqpm; rqpm.pm_step = IDE_PM_START_RESUME; rqpm.pm_state = PM_EVENT_ON; @@ -108,9 +109,9 @@ void ide_complete_power_step(ide_drive_t *drive, struct request *rq) ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) { struct request_pm_state *pm = rq->data; - struct ide_cmd *cmd = rq->special; + ide_task_t *args = rq->special; - memset(cmd, 0, sizeof(*cmd)); + memset(args, 0, sizeof(*args)); switch (pm->pm_step) { case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ @@ -123,12 +124,12 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) return ide_stopped; } if (ata_id_flush_ext_enabled(drive->id)) - cmd->tf.command = ATA_CMD_FLUSH_EXT; + args->tf.command = ATA_CMD_FLUSH_EXT; else - cmd->tf.command = ATA_CMD_FLUSH; + args->tf.command = ATA_CMD_FLUSH; goto out_do_tf; case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ - cmd->tf.command = ATA_CMD_STANDBYNOW1; + args->tf.command = ATA_CMD_STANDBYNOW1; goto out_do_tf; case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ ide_set_max_pio(drive); @@ -141,7 +142,7 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) ide_complete_power_step(drive, rq); return ide_stopped; case IDE_PM_IDLE: /* Resume step 2 (idle) */ - cmd->tf.command = ATA_CMD_IDLEIMMEDIATE; + args->tf.command = ATA_CMD_IDLEIMMEDIATE; goto out_do_tf; case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */ /* @@ -159,34 +160,27 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) } pm->pm_step = IDE_PM_COMPLETED; - return ide_stopped; out_do_tf: - cmd->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - cmd->protocol = ATA_PROT_NODATA; - - return do_rw_taskfile(drive, cmd); + args->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + args->data_phase = TASKFILE_NO_DATA; + return do_rw_taskfile(drive, args); } /** - * ide_complete_pm_rq - end the current Power Management request + * ide_complete_pm_request - end the current Power Management request * @drive: target drive * @rq: request * * This function cleans up the current PM request and stops the queue * if necessary. */ -void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq) +void ide_complete_pm_request(ide_drive_t *drive, struct request *rq) { struct request_queue *q = drive->queue; - struct request_pm_state *pm = rq->data; unsigned long flags; - ide_complete_power_step(drive, rq); - if (pm->pm_step != IDE_PM_COMPLETED) - return; - #ifdef DEBUG_PM printk("%s: completing PM request, %s\n", drive->name, blk_pm_suspend_request(rq) ? "suspend" : "resume"); @@ -223,7 +217,6 @@ void ide_check_pm_state(ide_drive_t *drive, struct request *rq) * point. */ ide_hwif_t *hwif = drive->hwif; - const struct ide_tp_ops *tp_ops = hwif->tp_ops; struct request_queue *q = drive->queue; unsigned long flags; int rc; @@ -233,8 +226,8 @@ void ide_check_pm_state(ide_drive_t *drive, struct request *rq) rc = ide_wait_not_busy(hwif, 35000); if (rc) printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name); - tp_ops->dev_select(drive); - tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); + SELECT_DRIVE(drive); + hwif->tp_ops->set_irq(hwif, 1); rc = ide_wait_not_busy(hwif, 100000); if (rc) printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); diff --git a/trunk/drivers/ide/ide-pnp.c b/trunk/drivers/ide/ide-pnp.c index 6e80b774e88a..bac9b392b689 100644 --- a/trunk/drivers/ide/ide-pnp.c +++ b/trunk/drivers/ide/ide-pnp.c @@ -27,10 +27,6 @@ static struct pnp_device_id idepnp_devices[] = { {.id = ""} }; -static const struct ide_port_info ide_pnp_port_info = { - .host_flags = IDE_HFLAG_NO_DMA, -}; - static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { struct ide_host *host; @@ -64,7 +60,7 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) hw.irq = pnp_irq(dev, 0); hw.chipset = ide_generic; - rc = ide_host_add(&ide_pnp_port_info, hws, &host); + rc = ide_host_add(NULL, hws, &host); if (rc) goto out; diff --git a/trunk/drivers/ide/ide-probe.c b/trunk/drivers/ide/ide-probe.c index d8c1c3e735bb..974067043fba 100644 --- a/trunk/drivers/ide/ide-probe.c +++ b/trunk/drivers/ide/ide-probe.c @@ -228,9 +228,15 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id) m[ATA_ID_PROD_LEN - 1] = '\0'; if (strstr(m, "E X A B Y T E N E S T")) - drive->dev_flags &= ~IDE_DFLAG_PRESENT; - else - drive->dev_flags |= IDE_DFLAG_PRESENT; + goto err_misc; + + drive->dev_flags |= IDE_DFLAG_PRESENT; + drive->dev_flags &= ~IDE_DFLAG_DEAD; + + return; +err_misc: + kfree(id); + drive->dev_flags &= ~IDE_DFLAG_PRESENT; } /** @@ -260,7 +266,7 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id) * during the identify phase that the IRQ handler isn't expecting. */ if (io_ports->ctl_addr) - tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS); + tp_ops->set_irq(hwif, 0); /* take a deep breath */ msleep(50); @@ -283,13 +289,13 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id) * identify command to be sure of reply */ if (cmd == ATA_CMD_ID_ATAPI) { - struct ide_cmd cmd; + ide_task_t task; - memset(&cmd, 0, sizeof(cmd)); + memset(&task, 0, sizeof(task)); /* disable DMA & overlap */ - cmd.tf_flags = IDE_TFLAG_OUT_FEATURE; + task.tf_flags = IDE_TFLAG_OUT_FEATURE; - tp_ops->tf_load(drive, &cmd); + tp_ops->tf_load(drive, &task); } /* ask drive for ID */ @@ -337,14 +343,14 @@ int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus) static u8 ide_read_device(ide_drive_t *drive) { - struct ide_cmd cmd; + ide_task_t task; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf_flags = IDE_TFLAG_IN_DEVICE; + memset(&task, 0, sizeof(task)); + task.tf_flags = IDE_TFLAG_IN_DEVICE; - drive->hwif->tp_ops->tf_read(drive, &cmd); + drive->hwif->tp_ops->tf_read(drive, &task); - return cmd.tf.device; + return task.tf.device; } /** @@ -390,13 +396,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd) * (e.g. crw9624 as drive0 with disk as slave) */ msleep(50); - tp_ops->dev_select(drive); + SELECT_DRIVE(drive); msleep(50); if (ide_read_device(drive) != drive->select && present == 0) { if (drive->dn & 1) { /* exit with drive0 selected */ - tp_ops->dev_select(hwif->devices[0]); + SELECT_DRIVE(hwif->devices[0]); /* allow ATA_BUSY to assert & clear */ msleep(50); } @@ -422,7 +428,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) printk(KERN_ERR "%s: no response (status = 0x%02x), " "resetting drive\n", drive->name, stat); msleep(50); - tp_ops->dev_select(drive); + SELECT_DRIVE(drive); msleep(50); tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); (void)ide_busy_sleep(hwif, WAIT_WORSTCASE, 0); @@ -441,7 +447,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) } if (drive->dn & 1) { /* exit with drive0 selected */ - tp_ops->dev_select(hwif->devices[0]); + SELECT_DRIVE(hwif->devices[0]); msleep(50); /* ensure drive irq is clear */ (void)tp_ops->read_status(hwif); @@ -499,7 +505,8 @@ static u8 probe_for_drive(ide_drive_t *drive) } if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) - goto out_free; + /* drive not found */ + return 0; /* identification failed? */ if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) { @@ -523,7 +530,7 @@ static u8 probe_for_drive(ide_drive_t *drive) } if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) - goto out_free; + return 0; /* The drive wasn't being helpful. Add generic info only */ if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) { @@ -536,10 +543,7 @@ static u8 probe_for_drive(ide_drive_t *drive) ide_disk_init_mult_count(drive); } - return 1; -out_free: - kfree(drive->id); - return 0; + return !!(drive->dev_flags & IDE_DFLAG_PRESENT); } static void hwif_release_dev(struct device *dev) @@ -605,7 +609,6 @@ static int ide_register_port(ide_hwif_t *hwif) static int ide_port_wait_ready(ide_hwif_t *hwif) { - const struct ide_tp_ops *tp_ops = hwif->tp_ops; ide_drive_t *drive; int i, rc; @@ -628,8 +631,8 @@ static int ide_port_wait_ready(ide_hwif_t *hwif) /* Ignore disks that we will not probe for later. */ if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 || (drive->dev_flags & IDE_DFLAG_PRESENT)) { - tp_ops->dev_select(drive); - tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); + SELECT_DRIVE(drive); + hwif->tp_ops->set_irq(hwif, 1); mdelay(2); rc = ide_wait_not_busy(hwif, 35000); if (rc) @@ -641,7 +644,7 @@ static int ide_port_wait_ready(ide_hwif_t *hwif) out: /* Exit function with master reselected (let's be sane) */ if (i) - tp_ops->dev_select(hwif->devices[0]); + SELECT_DRIVE(hwif->devices[0]); return rc; } @@ -838,19 +841,34 @@ static int ide_port_setup_devices(ide_hwif_t *hwif) static int init_irq (ide_hwif_t *hwif) { struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_host *host = hwif->host; - irq_handler_t irq_handler = host->irq_handler; - int sa = host->irq_flags; + irq_handler_t irq_handler; + int sa = 0; + irq_handler = hwif->host->irq_handler; if (irq_handler == NULL) irq_handler = ide_intr; +#if defined(__mc68000__) + sa = IRQF_SHARED; +#endif /* __mc68000__ */ + + if (hwif->chipset == ide_pci) + sa = IRQF_SHARED; + if (io_ports->ctl_addr) - hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); + hwif->tp_ops->set_irq(hwif, 1); if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif)) goto out_up; + if (!hwif->rqsize) { + if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) || + (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA)) + hwif->rqsize = 256; + else + hwif->rqsize = 65536; + } + #if !defined(__mc68000__) printk(KERN_INFO "%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name, io_ports->data_addr, io_ports->status_addr, @@ -943,16 +961,20 @@ EXPORT_SYMBOL_GPL(ide_init_disk); static void drive_release_dev (struct device *dev) { ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); + ide_hwif_t *hwif = drive->hwif; ide_proc_unregister_device(drive); - blk_cleanup_queue(drive->queue); - drive->queue = NULL; - + spin_lock_irq(&hwif->lock); kfree(drive->id); drive->id = NULL; - drive->dev_flags &= ~IDE_DFLAG_PRESENT; + /* Messed up locking ... */ + spin_unlock_irq(&hwif->lock); + blk_cleanup_queue(drive->queue); + spin_lock_irq(&hwif->lock); + drive->queue = NULL; + spin_unlock_irq(&hwif->lock); complete(&drive->gendev_rel_comp); } @@ -1058,7 +1080,7 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, hwif->tp_ops = d->tp_ops; /* ->set_pio_mode for DTC2278 is currently limited to port 0 */ - if ((hwif->host_flags & IDE_HFLAG_DTC2278) == 0 || hwif->channel == 0) + if (hwif->chipset != ide_dtc2278 || hwif->channel == 0) hwif->port_ops = d->port_ops; hwif->swdma_mask = d->swdma_mask; @@ -1092,13 +1114,6 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, if (d->max_sectors) hwif->rqsize = d->max_sectors; - else { - if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) || - (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA)) - hwif->rqsize = 256; - else - hwif->rqsize = 65536; - } /* call chipset specific routine for each enabled port */ if (d->init_hwif) @@ -1311,8 +1326,6 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) if (d) { host->init_chipset = d->init_chipset; - host->get_lock = d->get_lock; - host->release_lock = d->release_lock; host->host_flags = d->host_flags; } @@ -1359,15 +1372,20 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, ide_init_port_hw(hwif, hws[i]); ide_port_apply_params(hwif); - if ((i & 1) && mate) { - hwif->mate = mate; - mate->mate = hwif; - } + if (d == NULL) { + mate = NULL; + } else { + if ((i & 1) && mate) { + hwif->mate = mate; + mate->mate = hwif; + } - mate = (i & 1) ? NULL : hwif; + mate = (i & 1) ? NULL : hwif; + + ide_init_port(hwif, i & 1, d); + ide_port_cable_detect(hwif); + } - ide_init_port(hwif, i & 1, d); - ide_port_cable_detect(hwif); ide_port_init_devices(hwif); } @@ -1378,8 +1396,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, if (ide_probe_port(hwif) == 0) hwif->present = 1; - if ((hwif->host_flags & IDE_HFLAG_4DRIVES) == 0 || - hwif->mate == NULL || hwif->mate->present == 0) { + if (hwif->chipset != ide_4drives || !hwif->mate || + !hwif->mate->present) { if (ide_register_port(hwif)) { ide_disable_port(hwif); continue; diff --git a/trunk/drivers/ide/ide-proc.c b/trunk/drivers/ide/ide-proc.c index 10a88bf3eefa..417cde56eafd 100644 --- a/trunk/drivers/ide/ide-proc.c +++ b/trunk/drivers/ide/ide-proc.c @@ -194,20 +194,20 @@ ide_devset_get(xfer_rate, current_speed); static int set_xfer_rate (ide_drive_t *drive, int arg) { - struct ide_cmd cmd; + ide_task_t task; int err; if (arg < XFER_PIO_0 || arg > XFER_UDMA_6) return -EINVAL; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf.command = ATA_CMD_SET_FEATURES; - cmd.tf.feature = SETFEATURES_XFER; - cmd.tf.nsect = (u8)arg; - cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT | - IDE_TFLAG_IN_NSECT; + memset(&task, 0, sizeof(task)); + task.tf.command = ATA_CMD_SET_FEATURES; + task.tf.feature = SETFEATURES_XFER; + task.tf.nsect = (u8)arg; + task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT | + IDE_TFLAG_IN_NSECT; - err = ide_no_data_taskfile(drive, &cmd); + err = ide_no_data_taskfile(drive, &task); if (!err) { ide_set_xfer_rate(drive, (u8) arg); diff --git a/trunk/drivers/ide/ide-tape.c b/trunk/drivers/ide/ide-tape.c index cb942a9b580f..4e6181c7bbda 100644 --- a/trunk/drivers/ide/ide-tape.c +++ b/trunk/drivers/ide/ide-tape.c @@ -152,6 +152,11 @@ struct idetape_bh { #define IDETAPE_LU_RETENSION_MASK 2 #define IDETAPE_LU_EOT_MASK 4 +/* Error codes returned in rq->errors to the higher part of the driver. */ +#define IDETAPE_ERROR_GENERAL 101 +#define IDETAPE_ERROR_FILEMARK 102 +#define IDETAPE_ERROR_EOD 103 + /* Structures related to the SELECT SENSE / MODE SENSE packet commands. */ #define IDETAPE_BLOCK_DESCRIPTOR 0 #define IDETAPE_CAPABILITIES_PAGE 0x2a @@ -166,6 +171,14 @@ typedef struct ide_tape_obj { struct gendisk *disk; struct device dev; + /* + * failed_pc points to the last failed packet command, or contains + * NULL if we do not need to retry any packet command. This is + * required since an additional packet command is needed before the + * retry, to get detailed information on what went wrong. + */ + /* Last failed packet command */ + struct ide_atapi_pc *failed_pc; /* used by REQ_IDETAPE_{READ,WRITE} requests */ struct ide_atapi_pc queued_pc; @@ -232,6 +245,9 @@ typedef struct ide_tape_obj { /* Wasted space in each stage */ int excess_bh_size; + /* protects the ide-tape queue */ + spinlock_t lock; + /* Measures average tape speed */ unsigned long avg_time; int avg_size; @@ -297,15 +313,19 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) return tape; } -static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, +static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, unsigned int bcount) { struct idetape_bh *bh = pc->bh; int count; while (bcount) { - if (bh == NULL) - break; + if (bh == NULL) { + printk(KERN_ERR "ide-tape: bh == NULL in " + "idetape_input_buffers\n"); + ide_pad_transfer(drive, 0, bcount); + return; + } count = min( (unsigned int)(bh->b_size - atomic_read(&bh->b_count)), bcount); @@ -319,21 +339,21 @@ static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, atomic_set(&bh->b_count, 0); } } - pc->bh = bh; - - return bcount; } -static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, +static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, unsigned int bcount) { struct idetape_bh *bh = pc->bh; int count; while (bcount) { - if (bh == NULL) - break; + if (bh == NULL) { + printk(KERN_ERR "ide-tape: bh == NULL in %s\n", + __func__); + return; + } count = min((unsigned int)pc->b_count, (unsigned int)bcount); drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count); bcount -= count; @@ -348,8 +368,6 @@ static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, } } } - - return bcount; } static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) @@ -382,7 +400,7 @@ static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) { idetape_tape_t *tape = drive->driver_data; - struct ide_atapi_pc *pc = drive->failed_pc; + struct ide_atapi_pc *pc = tape->failed_pc; tape->sense_key = sense[2] & 0xF; tape->asc = sense[12]; @@ -415,19 +433,19 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) } } if (pc->c[0] == READ_6 && (sense[2] & 0x80)) { - pc->error = IDE_DRV_ERROR_FILEMARK; + pc->error = IDETAPE_ERROR_FILEMARK; pc->flags |= PC_FLAG_ABORT; } if (pc->c[0] == WRITE_6) { if ((sense[2] & 0x40) || (tape->sense_key == 0xd && tape->asc == 0x0 && tape->ascq == 0x2)) { - pc->error = IDE_DRV_ERROR_EOD; + pc->error = IDETAPE_ERROR_EOD; pc->flags |= PC_FLAG_ABORT; } } if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { if (tape->sense_key == 8) { - pc->error = IDE_DRV_ERROR_EOD; + pc->error = IDETAPE_ERROR_EOD; pc->flags |= PC_FLAG_ABORT; } if (!(pc->flags & PC_FLAG_ABORT) && @@ -459,23 +477,52 @@ static void ide_tape_kfree_buffer(idetape_tape_t *tape) } } +static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) +{ + struct request *rq = drive->hwif->rq; + idetape_tape_t *tape = drive->driver_data; + unsigned long flags; + int error; + + debug_log(DBG_PROCS, "Enter %s\n", __func__); + + switch (uptodate) { + case 0: error = IDETAPE_ERROR_GENERAL; break; + case 1: error = 0; break; + default: error = uptodate; + } + rq->errors = error; + if (error) + tape->failed_pc = NULL; + + if (!blk_special_request(rq)) { + ide_end_request(drive, uptodate, nr_sects); + return 0; + } + + spin_lock_irqsave(&tape->lock, flags); + + ide_end_drive_cmd(drive, 0, 0); + + spin_unlock_irqrestore(&tape->lock, flags); + return 0; +} + static void ide_tape_handle_dsc(ide_drive_t *); -static int ide_tape_callback(ide_drive_t *drive, int dsc) +static void ide_tape_callback(ide_drive_t *drive, int dsc) { idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc *pc = drive->pc; - struct request *rq = drive->hwif->rq; int uptodate = pc->error ? 0 : 1; - int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL; debug_log(DBG_PROCS, "Enter %s\n", __func__); if (dsc) ide_tape_handle_dsc(drive); - if (drive->failed_pc == pc) - drive->failed_pc = NULL; + if (tape->failed_pc == pc) + tape->failed_pc = NULL; if (pc->c[0] == REQUEST_SENSE) { if (uptodate) @@ -484,6 +531,7 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) printk(KERN_ERR "ide-tape: Error in REQUEST SENSE " "itself - Aborting request!\n"); } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { + struct request *rq = drive->hwif->rq; int blocks = pc->xferred / tape->blk_size; tape->avg_size += blocks * tape->blk_size; @@ -498,10 +546,8 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) tape->first_frame += blocks; rq->current_nr_sectors -= blocks; - if (pc->error) { - uptodate = 0; - err = pc->error; - } + if (pc->error) + uptodate = pc->error; } else if (pc->c[0] == READ_POSITION && uptodate) { u8 *readpos = pc->buf; @@ -515,7 +561,6 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) "to the tape\n"); clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); uptodate = 0; - err = IDE_DRV_ERROR_GENERAL; } else { debug_log(DBG_SENSE, "Block Location - %u\n", be32_to_cpup((__be32 *)&readpos[4])); @@ -526,9 +571,7 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) } } - rq->errors = err; - - return uptodate; + idetape_end_request(drive, uptodate, 0); } /* @@ -561,14 +604,12 @@ static void ide_tape_handle_dsc(ide_drive_t *drive) static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, unsigned int bcount, int write) { - unsigned int bleft; - if (write) - bleft = idetape_output_buffers(drive, pc, bcount); + idetape_output_buffers(drive, pc, bcount); else - bleft = idetape_input_buffers(drive, pc, bcount); + idetape_input_buffers(drive, pc, bcount); - return bcount - bleft; + return bcount; } /* @@ -580,7 +621,7 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, * * The handling will be done in three stages: * - * 1. ide_tape_issue_pc will send the packet command to the drive, and will set + * 1. idetape_issue_pc will send the packet command to the drive, and will set * the interrupt handler to ide_pc_intr. * * 2. On each interrupt, ide_pc_intr will be called. This step will be @@ -608,9 +649,8 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, * request. */ -static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, - struct ide_cmd *cmd, - struct ide_atapi_pc *pc) +static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, + struct ide_atapi_pc *pc) { idetape_tape_t *tape = drive->driver_data; @@ -620,8 +660,8 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, "Two request sense in serial were issued\n"); } - if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) - drive->failed_pc = pc; + if (tape->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) + tape->failed_pc = pc; /* Set the current packet command */ drive->pc = pc; @@ -645,9 +685,9 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, tape->ascq); } /* Giving up */ - pc->error = IDE_DRV_ERROR_GENERAL; + pc->error = IDETAPE_ERROR_GENERAL; } - drive->failed_pc = NULL; + tape->failed_pc = NULL; drive->pc_callback(drive, 0); return ide_stopped; } @@ -655,7 +695,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, pc->retries++; - return ide_issue_pc(drive, cmd); + return ide_issue_pc(drive); } /* A mode sense command is used to "sense" tape parameters. */ @@ -706,8 +746,8 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) } pc->error = 0; } else { - pc->error = IDE_DRV_ERROR_GENERAL; - drive->failed_pc = NULL; + pc->error = IDETAPE_ERROR_GENERAL; + tape->failed_pc = NULL; } drive->pc_callback(drive, 0); return ide_stopped; @@ -750,7 +790,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc *pc = NULL; struct request *postponed_rq = tape->postponed_rq; - struct ide_cmd cmd; u8 stat; debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu," @@ -762,15 +801,13 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, /* We do not support buffer cache originated requests. */ printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " "request queue (%d)\n", drive->name, rq->cmd_type); - if (blk_fs_request(rq) == 0 && rq->errors == 0) - rq->errors = -EIO; - ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); + ide_end_request(drive, 0, 0); return ide_stopped; } /* Retry a failed packet command */ - if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) { - pc = drive->failed_pc; + if (tape->failed_pc && drive->pc->c[0] == REQUEST_SENSE) { + pc = tape->failed_pc; goto out; } @@ -778,9 +815,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, if (rq != postponed_rq) { printk(KERN_ERR "ide-tape: ide-tape.c bug - " "Two DSC requests were queued\n"); - drive->failed_pc = NULL; - rq->errors = 0; - ide_complete_rq(drive, 0, blk_rq_bytes(rq)); + idetape_end_request(drive, 0, 0); return ide_stopped; } @@ -846,14 +881,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, BUG(); out: - memset(&cmd, 0, sizeof(cmd)); - - if (rq_data_dir(rq)) - cmd.tf_flags |= IDE_TFLAG_WRITE; - - cmd.rq = rq; - - return ide_tape_issue_pc(drive, &cmd, pc); + return idetape_issue_pc(drive, pc); } /* @@ -1198,7 +1226,7 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, if (tape->merge_bh) idetape_init_merge_buffer(tape); - if (errors == IDE_DRV_ERROR_GENERAL) + if (errors == IDETAPE_ERROR_GENERAL) return -EIO; return ret; } @@ -2014,13 +2042,9 @@ static void idetape_get_inquiry_results(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc pc; - u8 pc_buf[256]; char fw_rev[4], vendor_id[8], product_id[16]; idetape_create_inquiry_cmd(&pc); - pc.buf = &pc_buf[0]; - pc.buf_size = sizeof(pc_buf); - if (ide_queue_pc_tail(drive, tape->disk, &pc)) { printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n", tape->name); @@ -2168,6 +2192,8 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) drive->pc_update_buffers = idetape_update_buffers; drive->pc_io_buffers = ide_tape_io_buffers; + spin_lock_init(&tape->lock); + drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) { @@ -2299,6 +2325,7 @@ static struct ide_driver idetape_driver = { .remove = ide_tape_remove, .version = IDETAPE_VERSION, .do_request = idetape_do_request, + .end_request = idetape_end_request, #ifdef CONFIG_IDE_PROC_FS .proc_entries = ide_tape_proc_entries, .proc_devsets = ide_tape_proc_devsets, diff --git a/trunk/drivers/ide/ide-taskfile.c b/trunk/drivers/ide/ide-taskfile.c index 243421ce40d0..16138bce84a7 100644 --- a/trunk/drivers/ide/ide-taskfile.c +++ b/trunk/drivers/ide/ide-taskfile.c @@ -39,90 +39,88 @@ void ide_tf_dump(const char *s, struct ide_taskfile *tf) int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) { - struct ide_cmd cmd; + ide_task_t args; - memset(&cmd, 0, sizeof(cmd)); - cmd.tf.nsect = 0x01; + memset(&args, 0, sizeof(ide_task_t)); + args.tf.nsect = 0x01; if (drive->media == ide_disk) - cmd.tf.command = ATA_CMD_ID_ATA; + args.tf.command = ATA_CMD_ID_ATA; else - cmd.tf.command = ATA_CMD_ID_ATAPI; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - cmd.protocol = ATA_PROT_PIO; - - return ide_raw_taskfile(drive, &cmd, buf, 1); + args.tf.command = ATA_CMD_ID_ATAPI; + args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + args.data_phase = TASKFILE_IN; + return ide_raw_taskfile(drive, &args, buf, 1); } static ide_startstop_t task_no_data_intr(ide_drive_t *); -static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct ide_cmd *); -static ide_startstop_t task_pio_intr(ide_drive_t *); +static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *); +static ide_startstop_t task_in_intr(ide_drive_t *); -ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd) +ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; - struct ide_cmd *cmd = &hwif->cmd; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; ide_handler_t *handler = NULL; const struct ide_tp_ops *tp_ops = hwif->tp_ops; const struct ide_dma_ops *dma_ops = hwif->dma_ops; - if (orig_cmd->protocol == ATA_PROT_PIO && - (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) && - drive->mult_count == 0) { - printk(KERN_ERR "%s: multimode not set!\n", drive->name); - return ide_stopped; + if (task->data_phase == TASKFILE_MULTI_IN || + task->data_phase == TASKFILE_MULTI_OUT) { + if (!drive->mult_count) { + printk(KERN_ERR "%s: multimode not set!\n", + drive->name); + return ide_stopped; + } } - if (orig_cmd->ftf_flags & IDE_FTFLAG_FLAGGED) - orig_cmd->ftf_flags |= IDE_FTFLAG_SET_IN_FLAGS; + if (task->tf_flags & IDE_TFLAG_FLAGGED) + task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS; - memcpy(cmd, orig_cmd, sizeof(*cmd)); + memcpy(&hwif->task, task, sizeof(*task)); - if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { + if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { ide_tf_dump(drive->name, tf); - tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); + tp_ops->set_irq(hwif, 1); SELECT_MASK(drive, 0); - - if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) { - u8 data[2] = { tf->data, tf->hob_data }; - - tp_ops->output_data(drive, cmd, data, 2); - } - tp_ops->tf_load(drive, cmd); + tp_ops->tf_load(drive, task); } - switch (cmd->protocol) { - case ATA_PROT_PIO: - if (cmd->tf_flags & IDE_TFLAG_WRITE) { - tp_ops->exec_command(hwif, tf->command); - ndelay(400); /* FIXME */ - return pre_task_out_intr(drive, cmd); - } - handler = task_pio_intr; + switch (task->data_phase) { + case TASKFILE_MULTI_OUT: + case TASKFILE_OUT: + tp_ops->exec_command(hwif, tf->command); + ndelay(400); /* FIXME */ + return pre_task_out_intr(drive, task->rq); + case TASKFILE_MULTI_IN: + case TASKFILE_IN: + handler = task_in_intr; /* fall-through */ - case ATA_PROT_NODATA: + case TASKFILE_NO_DATA: if (handler == NULL) handler = task_no_data_intr; - ide_execute_command(drive, cmd, handler, WAIT_WORSTCASE); + ide_execute_command(drive, tf->command, handler, + WAIT_WORSTCASE, NULL); return ide_started; - case ATA_PROT_DMA: - if (ide_dma_prepare(drive, cmd)) + default: + if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 || + dma_ops->dma_setup(drive)) return ide_stopped; - hwif->expiry = dma_ops->dma_timer_expiry; - ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD); + dma_ops->dma_exec_cmd(drive, tf->command); dma_ops->dma_start(drive); - default: return ide_started; } } EXPORT_SYMBOL_GPL(do_rw_taskfile); +/* + * Handler for commands without a data phase + */ static ide_startstop_t task_no_data_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - struct ide_cmd *cmd = &hwif->cmd; - struct ide_taskfile *tf = &cmd->tf; - int custom = (cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0; + ide_task_t *task = &hwif->task; + struct ide_taskfile *tf = &task->tf; + int custom = (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0; int retries = (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) ? 5 : 1; u8 stat; @@ -144,26 +142,28 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive) } else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) { if ((stat & (ATA_ERR | ATA_DRQ)) == 0) { ide_set_handler(drive, &task_no_data_intr, - WAIT_WORSTCASE); + WAIT_WORSTCASE, NULL); return ide_started; } } return ide_error(drive, "task_no_data_intr", stat); + /* calls ide_end_drive_cmd */ } - if (custom && tf->command == ATA_CMD_SET_MULTI) + if (!custom) + ide_end_drive_cmd(drive, stat, ide_read_error(drive)); + else if (tf->command == ATA_CMD_IDLEIMMEDIATE) { + hwif->tp_ops->tf_read(drive, task); + if (tf->lbal != 0xc4) { + printk(KERN_ERR "%s: head unload failed!\n", + drive->name); + ide_tf_dump(drive->name, tf); + } else + drive->dev_flags |= IDE_DFLAG_PARKED; + ide_end_drive_cmd(drive, stat, ide_read_error(drive)); + } else if (tf->command == ATA_CMD_SET_MULTI) drive->mult_count = drive->mult_req; - if (custom == 0 || tf->command == ATA_CMD_IDLEIMMEDIATE || - tf->command == ATA_CMD_CHK_POWER) { - struct request *rq = hwif->rq; - - if (blk_pm_request(rq)) - ide_complete_pm_rq(drive, rq); - else - ide_finish_cmd(drive, cmd, stat); - } - return ide_stopped; } @@ -192,188 +192,239 @@ static u8 wait_drive_not_busy(ide_drive_t *drive) return stat; } -void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, - unsigned int write, unsigned int len) +static void ide_pio_sector(ide_drive_t *drive, struct request *rq, + unsigned int write) { ide_hwif_t *hwif = drive->hwif; struct scatterlist *sg = hwif->sg_table; - struct scatterlist *cursg = cmd->cursg; + struct scatterlist *cursg = hwif->cursg; struct page *page; +#ifdef CONFIG_HIGHMEM unsigned long flags; +#endif unsigned int offset; u8 *buf; - cursg = cmd->cursg; - if (cursg == NULL) - cursg = cmd->cursg = sg; - - while (len) { - unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs); - - if (nr_bytes > PAGE_SIZE) - nr_bytes = PAGE_SIZE; - - page = sg_page(cursg); - offset = cursg->offset + cmd->cursg_ofs; + cursg = hwif->cursg; + if (!cursg) { + cursg = sg; + hwif->cursg = sg; + } - /* get the current page and offset */ - page = nth_page(page, (offset >> PAGE_SHIFT)); - offset %= PAGE_SIZE; + page = sg_page(cursg); + offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE; - if (PageHighMem(page)) - local_irq_save(flags); + /* get the current page and offset */ + page = nth_page(page, (offset >> PAGE_SHIFT)); + offset %= PAGE_SIZE; - buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset; +#ifdef CONFIG_HIGHMEM + local_irq_save(flags); +#endif + buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset; - cmd->nleft -= nr_bytes; - cmd->cursg_ofs += nr_bytes; + hwif->nleft--; + hwif->cursg_ofs++; - if (cmd->cursg_ofs == cursg->length) { - cursg = cmd->cursg = sg_next(cmd->cursg); - cmd->cursg_ofs = 0; - } + if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) { + hwif->cursg = sg_next(hwif->cursg); + hwif->cursg_ofs = 0; + } - /* do the actual data transfer */ - if (write) - hwif->tp_ops->output_data(drive, cmd, buf, nr_bytes); - else - hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes); + /* do the actual data transfer */ + if (write) + hwif->tp_ops->output_data(drive, rq, buf, SECTOR_SIZE); + else + hwif->tp_ops->input_data(drive, rq, buf, SECTOR_SIZE); - kunmap_atomic(buf, KM_BIO_SRC_IRQ); + kunmap_atomic(buf, KM_BIO_SRC_IRQ); +#ifdef CONFIG_HIGHMEM + local_irq_restore(flags); +#endif +} - if (PageHighMem(page)) - local_irq_restore(flags); +static void ide_pio_multi(ide_drive_t *drive, struct request *rq, + unsigned int write) +{ + unsigned int nsect; - len -= nr_bytes; - } + nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count); + while (nsect--) + ide_pio_sector(drive, rq, write); } -EXPORT_SYMBOL_GPL(ide_pio_bytes); -static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd, - unsigned int write) +static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, + unsigned int write) { - unsigned int nr_bytes; - u8 saved_io_32bit = drive->io_32bit; - if (cmd->tf_flags & IDE_TFLAG_FS) - cmd->rq->errors = 0; + if (rq->bio) /* fs request */ + rq->errors = 0; - if (cmd->tf_flags & IDE_TFLAG_IO_16BIT) - drive->io_32bit = 0; + if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { + ide_task_t *task = rq->special; - touch_softlockup_watchdog(); + if (task->tf_flags & IDE_TFLAG_IO_16BIT) + drive->io_32bit = 0; + } - if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) - nr_bytes = min_t(unsigned, cmd->nleft, drive->mult_count << 9); - else - nr_bytes = SECTOR_SIZE; + touch_softlockup_watchdog(); - ide_pio_bytes(drive, cmd, write, nr_bytes); + switch (drive->hwif->data_phase) { + case TASKFILE_MULTI_IN: + case TASKFILE_MULTI_OUT: + ide_pio_multi(drive, rq, write); + break; + default: + ide_pio_sector(drive, rq, write); + break; + } drive->io_32bit = saved_io_32bit; } -static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd) +static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, + const char *s, u8 stat) { - if (cmd->tf_flags & IDE_TFLAG_FS) { - int nr_bytes = cmd->nbytes - cmd->nleft; - - if (cmd->protocol == ATA_PROT_PIO && - ((cmd->tf_flags & IDE_TFLAG_WRITE) || cmd->nleft == 0)) { - if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) - nr_bytes -= drive->mult_count << 9; - else - nr_bytes -= SECTOR_SIZE; + if (rq->bio) { + ide_hwif_t *hwif = drive->hwif; + int sectors = hwif->nsect - hwif->nleft; + + switch (hwif->data_phase) { + case TASKFILE_IN: + if (hwif->nleft) + break; + /* fall through */ + case TASKFILE_OUT: + sectors--; + break; + case TASKFILE_MULTI_IN: + if (hwif->nleft) + break; + /* fall through */ + case TASKFILE_MULTI_OUT: + sectors -= drive->mult_count; + default: + break; } - if (nr_bytes > 0) - ide_complete_rq(drive, 0, nr_bytes); + if (sectors > 0) { + struct ide_driver *drv; + + drv = *(struct ide_driver **)rq->rq_disk->private_data; + drv->end_request(drive, 1, sectors); + } } + return ide_error(drive, s, stat); } -void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat) +void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) { - struct request *rq = drive->hwif->rq; - u8 err = ide_read_error(drive); + if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { + u8 err = ide_read_error(drive); + + ide_end_drive_cmd(drive, stat, err); + return; + } + + if (rq->rq_disk) { + struct ide_driver *drv; - ide_complete_cmd(drive, cmd, stat, err); - rq->errors = err; - ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq)); + drv = *(struct ide_driver **)rq->rq_disk->private_data;; + drv->end_request(drive, 1, rq->nr_sectors); + } else + ide_end_request(drive, 1, rq->nr_sectors); } /* - * Handler for command with PIO data phase. + * We got an interrupt on a task_in case, but no errors and no DRQ. + * + * It might be a spurious irq (shared irq), but it might be a + * command that had no output. */ -static ide_startstop_t task_pio_intr(ide_drive_t *drive) +static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq, u8 stat) +{ + /* Command all done? */ + if (OK_STAT(stat, ATA_DRDY, ATA_BUSY)) { + task_end_request(drive, rq, stat); + return ide_stopped; + } + + /* Assume it was a spurious irq */ + ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); + return ide_started; +} + +/* + * Handler for command with PIO data-in phase (Read/Read Multiple). + */ +static ide_startstop_t task_in_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - struct ide_cmd *cmd = &drive->hwif->cmd; + struct request *rq = hwif->rq; u8 stat = hwif->tp_ops->read_status(hwif); - u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE); - if (write == 0) { - /* Error? */ - if (stat & ATA_ERR) - goto out_err; + /* Error? */ + if (stat & ATA_ERR) + return task_error(drive, rq, __func__, stat); - /* Didn't want any data? Odd. */ - if ((stat & ATA_DRQ) == 0) { - /* Command all done? */ - if (OK_STAT(stat, ATA_DRDY, ATA_BUSY)) - goto out_end; + /* Didn't want any data? Odd. */ + if ((stat & ATA_DRQ) == 0) + return task_in_unexpected(drive, rq, stat); - /* Assume it was a spurious irq */ - goto out_wait; - } - } else { - if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat)) - goto out_err; + ide_pio_datablock(drive, rq, 0); - /* Deal with unexpected ATA data phase. */ - if (((stat & ATA_DRQ) == 0) ^ (cmd->nleft == 0)) - goto out_err; + /* Are we done? Check status and finish transfer. */ + if (!hwif->nleft) { + stat = wait_drive_not_busy(drive); + if (!OK_STAT(stat, 0, BAD_STAT)) + return task_error(drive, rq, __func__, stat); + task_end_request(drive, rq, stat); + return ide_stopped; } - if (write && cmd->nleft == 0) - goto out_end; - /* Still data left to transfer. */ - ide_pio_datablock(drive, cmd, write); + ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); - /* Are we done? Check status and finish transfer. */ - if (write == 0 && cmd->nleft == 0) { - stat = wait_drive_not_busy(drive); - if (!OK_STAT(stat, 0, BAD_STAT)) - goto out_err; + return ide_started; +} + +/* + * Handler for command with PIO data-out phase (Write/Write Multiple). + */ +static ide_startstop_t task_out_intr (ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + struct request *rq = hwif->rq; + u8 stat = hwif->tp_ops->read_status(hwif); + + if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat)) + return task_error(drive, rq, __func__, stat); - goto out_end; + /* Deal with unexpected ATA data phase. */ + if (((stat & ATA_DRQ) == 0) ^ !hwif->nleft) + return task_error(drive, rq, __func__, stat); + + if (!hwif->nleft) { + task_end_request(drive, rq, stat); + return ide_stopped; } -out_wait: + /* Still data left to transfer. */ - ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE); + ide_pio_datablock(drive, rq, 1); + ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); + return ide_started; -out_end: - if ((cmd->tf_flags & IDE_TFLAG_FS) == 0) - ide_finish_cmd(drive, cmd, stat); - else - ide_complete_rq(drive, 0, cmd->rq->nr_sectors << 9); - return ide_stopped; -out_err: - ide_error_cmd(drive, cmd); - return ide_error(drive, __func__, stat); } -static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, - struct ide_cmd *cmd) +static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) { ide_startstop_t startstop; if (ide_wait_stat(&startstop, drive, ATA_DRQ, drive->bad_wstat, WAIT_DRQ)) { printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", - drive->name, - (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "", + drive->name, drive->hwif->data_phase ? "MULT" : "", (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : ""); return startstop; } @@ -381,15 +432,13 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0) local_irq_disable(); - ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE); - - ide_pio_datablock(drive, cmd, 1); + ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); + ide_pio_datablock(drive, rq, 1); return ide_started; } -int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, - u16 nsect) +int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect) { struct request *rq; int error; @@ -407,11 +456,11 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, rq->hard_nr_sectors = rq->nr_sectors = nsect; rq->hard_cur_sectors = rq->current_nr_sectors = nsect; - if (cmd->tf_flags & IDE_TFLAG_WRITE) + if (task->tf_flags & IDE_TFLAG_WRITE) rq->cmd_flags |= REQ_RW; - rq->special = cmd; - cmd->rq = rq; + rq->special = task; + task->rq = rq; error = blk_execute_rq(drive->queue, NULL, rq, 0); blk_put_request(rq); @@ -421,19 +470,19 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, EXPORT_SYMBOL(ide_raw_taskfile); -int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd) +int ide_no_data_taskfile(ide_drive_t *drive, ide_task_t *task) { - cmd->protocol = ATA_PROT_NODATA; + task->data_phase = TASKFILE_NO_DATA; - return ide_raw_taskfile(drive, cmd, NULL, 0); + return ide_raw_taskfile(drive, task, NULL, 0); } EXPORT_SYMBOL_GPL(ide_no_data_taskfile); #ifdef CONFIG_IDE_TASK_IOCTL -int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) +int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) { ide_task_request_t *req_task; - struct ide_cmd cmd; + ide_task_t args; u8 *outbuf = NULL; u8 *inbuf = NULL; u8 *data_buf = NULL; @@ -487,63 +536,53 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) } } - memset(&cmd, 0, sizeof(cmd)); + memset(&args, 0, sizeof(ide_task_t)); - memcpy(&cmd.tf_array[0], req_task->hob_ports, - HDIO_DRIVE_HOB_HDR_SIZE - 2); - memcpy(&cmd.tf_array[6], req_task->io_ports, - HDIO_DRIVE_TASK_HDR_SIZE); + memcpy(&args.tf_array[0], req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2); + memcpy(&args.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE); - cmd.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE | - IDE_TFLAG_IN_TF; + args.data_phase = req_task->data_phase; + args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE | + IDE_TFLAG_IN_TF; if (drive->dev_flags & IDE_DFLAG_LBA48) - cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB); + args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB); if (req_task->out_flags.all) { - cmd.ftf_flags |= IDE_FTFLAG_FLAGGED; + args.tf_flags |= IDE_TFLAG_FLAGGED; if (req_task->out_flags.b.data) - cmd.ftf_flags |= IDE_FTFLAG_OUT_DATA; + args.tf_flags |= IDE_TFLAG_OUT_DATA; if (req_task->out_flags.b.nsector_hob) - cmd.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT; + args.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT; if (req_task->out_flags.b.sector_hob) - cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL; + args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL; if (req_task->out_flags.b.lcyl_hob) - cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM; + args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM; if (req_task->out_flags.b.hcyl_hob) - cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH; + args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH; if (req_task->out_flags.b.error_feature) - cmd.tf_flags |= IDE_TFLAG_OUT_FEATURE; + args.tf_flags |= IDE_TFLAG_OUT_FEATURE; if (req_task->out_flags.b.nsector) - cmd.tf_flags |= IDE_TFLAG_OUT_NSECT; + args.tf_flags |= IDE_TFLAG_OUT_NSECT; if (req_task->out_flags.b.sector) - cmd.tf_flags |= IDE_TFLAG_OUT_LBAL; + args.tf_flags |= IDE_TFLAG_OUT_LBAL; if (req_task->out_flags.b.lcyl) - cmd.tf_flags |= IDE_TFLAG_OUT_LBAM; + args.tf_flags |= IDE_TFLAG_OUT_LBAM; if (req_task->out_flags.b.hcyl) - cmd.tf_flags |= IDE_TFLAG_OUT_LBAH; + args.tf_flags |= IDE_TFLAG_OUT_LBAH; } else { - cmd.tf_flags |= IDE_TFLAG_OUT_TF; - if (cmd.tf_flags & IDE_TFLAG_LBA48) - cmd.tf_flags |= IDE_TFLAG_OUT_HOB; + args.tf_flags |= IDE_TFLAG_OUT_TF; + if (args.tf_flags & IDE_TFLAG_LBA48) + args.tf_flags |= IDE_TFLAG_OUT_HOB; } if (req_task->in_flags.b.data) - cmd.ftf_flags |= IDE_FTFLAG_IN_DATA; - - if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE) { - /* fixup data phase if needed */ - if (req_task->data_phase == TASKFILE_IN_DMAQ || - req_task->data_phase == TASKFILE_IN_DMA) - cmd.tf_flags |= IDE_TFLAG_WRITE; - } + args.tf_flags |= IDE_TFLAG_IN_DATA; - cmd.protocol = ATA_PROT_DMA; - - switch (req_task->data_phase) { + switch(req_task->data_phase) { case TASKFILE_MULTI_OUT: if (!drive->mult_count) { /* (hs): give up if multcount is not set */ @@ -553,14 +592,11 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) err = -EPERM; goto abort; } - cmd.tf_flags |= IDE_TFLAG_MULTI_PIO; /* fall through */ case TASKFILE_OUT: - cmd.protocol = ATA_PROT_PIO; /* fall through */ case TASKFILE_OUT_DMAQ: case TASKFILE_OUT_DMA: - cmd.tf_flags |= IDE_TFLAG_WRITE; nsect = taskout / SECTOR_SIZE; data_buf = outbuf; break; @@ -573,10 +609,8 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) err = -EPERM; goto abort; } - cmd.tf_flags |= IDE_TFLAG_MULTI_PIO; /* fall through */ case TASKFILE_IN: - cmd.protocol = ATA_PROT_PIO; /* fall through */ case TASKFILE_IN_DMAQ: case TASKFILE_IN_DMA: @@ -584,7 +618,6 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) data_buf = inbuf; break; case TASKFILE_NO_DATA: - cmd.protocol = ATA_PROT_NODATA; break; default: err = -EFAULT; @@ -594,7 +627,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA) nsect = 0; else if (!nsect) { - nsect = (cmd.tf.hob_nsect << 8) | cmd.tf.nsect; + nsect = (args.tf.hob_nsect << 8) | args.tf.nsect; if (!nsect) { printk(KERN_ERR "%s: in/out command without data\n", @@ -604,14 +637,15 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) } } - err = ide_raw_taskfile(drive, &cmd, data_buf, nsect); + if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE) + args.tf_flags |= IDE_TFLAG_WRITE; + + err = ide_raw_taskfile(drive, &args, data_buf, nsect); - memcpy(req_task->hob_ports, &cmd.tf_array[0], - HDIO_DRIVE_HOB_HDR_SIZE - 2); - memcpy(req_task->io_ports, &cmd.tf_array[6], - HDIO_DRIVE_TASK_HDR_SIZE); + memcpy(req_task->hob_ports, &args.tf_array[0], HDIO_DRIVE_HOB_HDR_SIZE - 2); + memcpy(req_task->io_ports, &args.tf_array[6], HDIO_DRIVE_TASK_HDR_SIZE); - if ((cmd.ftf_flags & IDE_FTFLAG_SET_IN_FLAGS) && + if ((args.tf_flags & IDE_TFLAG_FLAGGED_SET_IN_FLAGS) && req_task->in_flags.all == 0) { req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS; if (drive->dev_flags & IDE_DFLAG_LBA48) diff --git a/trunk/drivers/ide/ide-timings.c b/trunk/drivers/ide/ide-timings.c index 001a56365be5..81f527af8fae 100644 --- a/trunk/drivers/ide/ide-timings.c +++ b/trunk/drivers/ide/ide-timings.c @@ -43,8 +43,6 @@ static struct ide_timing ide_timing[] = { { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 }, { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 }, - { XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 80, 0 }, - { XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 100, 0 }, { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 }, { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 }, { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 }, @@ -53,8 +51,7 @@ static struct ide_timing ide_timing[] = { { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 }, { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 }, - { XFER_PIO_6, 10, 55, 20, 80, 55, 20, 80, 0 }, - { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 100, 0 }, + { XFER_PIO_5, 20, 50, 30, 100, 50, 30, 100, 0 }, { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 }, { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 }, @@ -93,10 +90,6 @@ u16 ide_pio_cycle_time(ide_drive_t *drive, u8 pio) /* conservative "downgrade" for all pre-ATA2 drives */ if (pio < 3 && cycle < t->cycle) cycle = 0; /* use standard timing */ - - /* Use the standard timing for the CF specific modes too */ - if (pio > 4 && ata_id_is_cfa(id)) - cycle = 0; } return cycle ? cycle : t->cycle; @@ -168,8 +161,7 @@ int ide_timing_compute(ide_drive_t *drive, u8 speed, if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO]; - else if ((speed <= XFER_PIO_4) || - (speed == XFER_PIO_5 && !ata_id_is_cfa(id))) + else if (speed <= XFER_PIO_5) p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY]; else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) p.cycle = id[ATA_ID_EIDE_DMA_MIN]; diff --git a/trunk/drivers/ide/ide-xfer-mode.c b/trunk/drivers/ide/ide-xfer-mode.c index af44be9d546c..6910f6a257e8 100644 --- a/trunk/drivers/ide/ide-xfer-mode.c +++ b/trunk/drivers/ide/ide-xfer-mode.c @@ -9,11 +9,11 @@ static const char *udma_str[] = { "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44", "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" }; static const char *mwdma_str[] = - { "MWDMA0", "MWDMA1", "MWDMA2", "MWDMA3", "MWDMA4" }; + { "MWDMA0", "MWDMA1", "MWDMA2" }; static const char *swdma_str[] = { "SWDMA0", "SWDMA1", "SWDMA2" }; static const char *pio_str[] = - { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5", "PIO6" }; + { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" }; /** * ide_xfer_verbose - return IDE mode names @@ -30,11 +30,11 @@ const char *ide_xfer_verbose(u8 mode) if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7) s = udma_str[i]; - else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_4) + else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2) s = mwdma_str[i]; else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2) s = swdma_str[i]; - else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_6) + else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5) s = pio_str[i & 0x7]; else if (mode == XFER_PIO_SLOW) s = "PIO SLOW"; @@ -79,10 +79,7 @@ u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode) } if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */ - if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 7)) - pio_mode = 4 + min_t(int, 2, - id[ATA_ID_CFA_MODES] & 7); - else if (ata_id_has_iordy(id)) { + if (ata_id_has_iordy(id)) { if (id[ATA_ID_PIO_MODES] & 7) { overridden = 0; if (id[ATA_ID_PIO_MODES] & 4) @@ -242,7 +239,7 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) BUG_ON(rate < XFER_PIO_0); - if (rate >= XFER_PIO_0 && rate <= XFER_PIO_6) + if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5) return ide_set_pio_mode(drive, rate); return ide_set_dma_mode(drive, rate); diff --git a/trunk/drivers/ide/ide_arm.c b/trunk/drivers/ide/ide_arm.c new file mode 100644 index 000000000000..bdcac94d7c1f --- /dev/null +++ b/trunk/drivers/ide/ide_arm.c @@ -0,0 +1,49 @@ +/* + * ARM default IDE host driver + * + * Copyright (C) 2004 Bartlomiej Zolnierkiewicz + * Based on code by: Russell King, Ian Molton and Alexander Schulz. + * + * May be copied or modified under the terms of the GNU General Public License. + */ + +#include +#include +#include + +#include + +#define DRV_NAME "ide_arm" + +#define IDE_ARM_IO 0x1f0 +#define IDE_ARM_IRQ IRQ_HARDDISK + +static int __init ide_arm_init(void) +{ + unsigned long base = IDE_ARM_IO, ctl = IDE_ARM_IO + 0x206; + hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; + + if (!request_region(base, 8, DRV_NAME)) { + printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", + DRV_NAME, base, base + 7); + return -EBUSY; + } + + if (!request_region(ctl, 1, DRV_NAME)) { + printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", + DRV_NAME, ctl); + release_region(base, 8); + return -EBUSY; + } + + memset(&hw, 0, sizeof(hw)); + ide_std_init_ports(&hw, base, ctl); + hw.irq = IDE_ARM_IRQ; + hw.chipset = ide_generic; + + return ide_host_add(NULL, hws, NULL); +} + +module_init(ide_arm_init); + +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/ide/it821x.c b/trunk/drivers/ide/it821x.c index 51aa745246dc..6b9fc950b4af 100644 --- a/trunk/drivers/ide/it821x.c +++ b/trunk/drivers/ide/it821x.c @@ -508,11 +508,12 @@ static void it821x_quirkproc(ide_drive_t *drive) static struct ide_dma_ops it821x_pass_through_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = it821x_dma_start, .dma_end = it821x_dma_end, .dma_test_irq = ide_dma_test_irq, + .dma_timeout = ide_dma_timeout, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/macide.c b/trunk/drivers/ide/macide.c index 4b1718e83283..3c60064f1d4f 100644 --- a/trunk/drivers/ide/macide.c +++ b/trunk/drivers/ide/macide.c @@ -80,11 +80,6 @@ static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base, hw->chipset = ide_generic; } -static const struct ide_port_info macide_port_info = { - .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, - .irq_flags = IRQF_SHARED, -}; - static const char *mac_ide_name[] = { "Quadra", "Powerbook", "Powerbook Baboon" }; @@ -127,7 +122,7 @@ static int __init macide_init(void) macide_setup_ports(&hw, base, irq, ack_intr); - return ide_host_add(&macide_port_info, hws, NULL); + return ide_host_add(NULL, hws, NULL); } module_init(macide_init); diff --git a/trunk/drivers/ide/ns87415.c b/trunk/drivers/ide/ns87415.c index 71a39fb3856f..ea48a3ee8063 100644 --- a/trunk/drivers/ide/ns87415.c +++ b/trunk/drivers/ide/ns87415.c @@ -61,52 +61,57 @@ static u8 superio_dma_sff_read_status(ide_hwif_t *hwif) return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS); } -static void superio_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +static void superio_tf_read(ide_drive_t *drive, ide_task_t *task) { struct ide_io_ports *io_ports = &drive->hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; + + if (task->tf_flags & IDE_TFLAG_IN_DATA) { + u16 data = inw(io_ports->data_addr); + + tf->data = data & 0xff; + tf->hob_data = (data >> 8) & 0xff; + } /* be sure we're looking at the low order bits */ - outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); + outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) - tf->error = inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) + tf->feature = inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = superio_ide_inb(io_ports->device_addr); - if (cmd->tf_flags & IDE_TFLAG_LBA48) { - outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); - - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) - tf->hob_error = inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) - tf->hob_nsect = inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) - tf->hob_lbal = inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) - tf->hob_lbam = inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) - tf->hob_lbah = inb(io_ports->lbah_addr); + if (task->tf_flags & IDE_TFLAG_LBA48) { + outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); + + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + tf->hob_feature = inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) + tf->hob_nsect = inb(io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + tf->hob_lbal = inb(io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + tf->hob_lbam = inb(io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + tf->hob_lbah = inb(io_ports->lbah_addr); } } -static void ns87415_dev_select(ide_drive_t *drive); - static const struct ide_tp_ops superio_tp_ops = { .exec_command = ide_exec_command, .read_status = superio_read_status, .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - .dev_select = ns87415_dev_select, + .set_irq = ide_set_irq, + .tf_load = ide_tf_load, .tf_read = superio_tf_read, @@ -185,18 +190,10 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma) local_irq_restore(flags); } -static void ns87415_dev_select(ide_drive_t *drive) +static void ns87415_selectproc (ide_drive_t *drive) { ns87415_prepare_drive(drive, !!(drive->dev_flags & IDE_DFLAG_USING_DMA)); - - outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr); -} - -static void ns87415_dma_start(ide_drive_t *drive) -{ - ns87415_prepare_drive(drive, 1); - ide_dma_start(drive); } static int ns87415_dma_end(ide_drive_t *drive) @@ -204,6 +201,7 @@ static int ns87415_dma_end(ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; u8 dma_stat = 0, dma_cmd = 0; + drive->waiting_for_dma = 0; dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); /* get DMA command mode */ dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); @@ -212,13 +210,23 @@ static int ns87415_dma_end(ide_drive_t *drive) /* from ERRATA: clear the INTR & ERROR bits */ dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); outb(dma_cmd | 6, hwif->dma_base + ATA_DMA_CMD); - - ns87415_prepare_drive(drive, 0); - + /* and free any DMA resources */ + ide_destroy_dmatable(drive); /* verify good DMA status */ return (dma_stat & 7) != 4; } +static int ns87415_dma_setup(ide_drive_t *drive) +{ + /* select DMA xfer */ + ns87415_prepare_drive(drive, 1); + if (!ide_dma_setup(drive)) + return 0; + /* DMA failed: select PIO xfer */ + ns87415_prepare_drive(drive, 0); + return 1; +} + static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) { struct pci_dev *dev = to_pci_dev(hwif->dev); @@ -234,7 +242,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) * Also, leave IRQ masked during drive probing, to prevent infinite * interrupts from a potentially floating INTA.. * - * IRQs get unmasked in dev_select() when drive is first used. + * IRQs get unmasked in selectproc when drive is first used. */ (void) pci_read_config_dword(dev, 0x40, &ctrl); (void) pci_read_config_byte(dev, 0x09, &progif); @@ -262,7 +270,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) #ifdef __sparc_v9__ /* * XXX: Reset the device, if we don't it will not respond to - * dev_select() properly during first ide_probe_port(). + * SELECT_DRIVE() properly during first ide_probe_port(). */ timeout = 10000; outb(12, hwif->io_ports.ctl_addr); @@ -286,35 +294,26 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) outb(0x60, hwif->dma_base + ATA_DMA_STATUS); } -static const struct ide_tp_ops ns87415_tp_ops = { - .exec_command = ide_exec_command, - .read_status = ide_read_status, - .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - - .dev_select = ns87415_dev_select, - .tf_load = ide_tf_load, - .tf_read = ide_tf_read, - - .input_data = ide_input_data, - .output_data = ide_output_data, +static const struct ide_port_ops ns87415_port_ops = { + .selectproc = ns87415_selectproc, }; static const struct ide_dma_ops ns87415_dma_ops = { .dma_host_set = ide_dma_host_set, - .dma_setup = ide_dma_setup, - .dma_start = ns87415_dma_start, + .dma_setup = ns87415_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, + .dma_start = ide_dma_start, .dma_end = ns87415_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_timeout = ide_dma_timeout, .dma_sff_read_status = superio_dma_sff_read_status, }; static const struct ide_port_info ns87415_chipset __devinitdata = { .name = DRV_NAME, .init_hwif = init_hwif_ns87415, - .tp_ops = &ns87415_tp_ops, + .port_ops = &ns87415_port_ops, .dma_ops = &ns87415_dma_ops, .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | IDE_HFLAG_NO_ATAPI_DMA, diff --git a/trunk/drivers/ide/palm_bk3710.c b/trunk/drivers/ide/palm_bk3710.c index c7acca0b8733..f38aac78044c 100644 --- a/trunk/drivers/ide/palm_bk3710.c +++ b/trunk/drivers/ide/palm_bk3710.c @@ -347,7 +347,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev) struct clk *clk; struct resource *mem, *irq; void __iomem *base; - unsigned long rate, mem_size; + unsigned long rate; int i, rc; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; @@ -374,18 +374,13 @@ static int __init palm_bk3710_probe(struct platform_device *pdev) return -ENODEV; } - mem_size = mem->end - mem->start + 1; - if (request_mem_region(mem->start, mem_size, "palm_bk3710") == NULL) { + if (request_mem_region(mem->start, mem->end - mem->start + 1, + "palm_bk3710") == NULL) { printk(KERN_ERR "failed to request memory region\n"); return -EBUSY; } - base = ioremap(mem->start, mem_size); - if (!base) { - printk(KERN_ERR "failed to map IO memory\n"); - release_mem_region(mem->start, mem_size); - return -ENOMEM; - } + base = IO_ADDRESS(mem->start); /* Configure the Palm Chip controller */ palm_bk3710_chipinit(base); diff --git a/trunk/drivers/ide/pdc202xx_old.c b/trunk/drivers/ide/pdc202xx_old.c index 248a54bd2386..cba66ebce4e3 100644 --- a/trunk/drivers/ide/pdc202xx_old.c +++ b/trunk/drivers/ide/pdc202xx_old.c @@ -258,6 +258,12 @@ static void pdc202xx_dma_lost_irq(ide_drive_t *drive) ide_dma_lost_irq(drive); } +static void pdc202xx_dma_timeout(ide_drive_t *drive) +{ + pdc202xx_reset(drive); + ide_dma_timeout(drive); +} + static int init_chipset_pdc202xx(struct pci_dev *dev) { unsigned long dmabase = pci_resource_start(dev, 4); @@ -325,24 +331,24 @@ static const struct ide_port_ops pdc2026x_port_ops = { static const struct ide_dma_ops pdc20246_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = ide_dma_end, .dma_test_irq = pdc202xx_dma_test_irq, .dma_lost_irq = pdc202xx_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, - .dma_clear = pdc202xx_reset, + .dma_timeout = pdc202xx_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; static const struct ide_dma_ops pdc2026x_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = pdc202xx_dma_start, .dma_end = pdc202xx_dma_end, .dma_test_irq = pdc202xx_dma_test_irq, .dma_lost_irq = pdc202xx_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, - .dma_clear = pdc202xx_reset, + .dma_timeout = pdc202xx_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/pmac.c b/trunk/drivers/ide/pmac.c index 052b9bf1f8fb..74625e821a43 100644 --- a/trunk/drivers/ide/pmac.c +++ b/trunk/drivers/ide/pmac.c @@ -404,6 +404,9 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time) #define IDE_WAKEUP_DELAY (1*HZ) static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *); +static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq); +static void pmac_ide_selectproc(ide_drive_t *drive); +static void pmac_ide_kauai_selectproc(ide_drive_t *drive); #define PMAC_IDE_REG(x) \ ((void __iomem *)((drive)->hwif->io_ports.data_addr + (x))) @@ -413,7 +416,8 @@ static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *); * timing register when selecting that unit. This version is for * ASICs with a single timing register */ -static void pmac_ide_apply_timings(ide_drive_t *drive) +static void +pmac_ide_selectproc(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; pmac_ide_hwif_t *pmif = @@ -431,7 +435,8 @@ static void pmac_ide_apply_timings(ide_drive_t *drive) * timing register when selecting that unit. This version is for * ASICs with a dual timing register (Kauai) */ -static void pmac_ide_kauai_apply_timings(ide_drive_t *drive) +static void +pmac_ide_kauai_selectproc(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; pmac_ide_hwif_t *pmif = @@ -460,25 +465,9 @@ pmac_ide_do_update_timings(ide_drive_t *drive) if (pmif->kind == controller_sh_ata6 || pmif->kind == controller_un_ata6 || pmif->kind == controller_k2_ata6) - pmac_ide_kauai_apply_timings(drive); + pmac_ide_kauai_selectproc(drive); else - pmac_ide_apply_timings(drive); -} - -static void pmac_dev_select(ide_drive_t *drive) -{ - pmac_ide_apply_timings(drive); - - writeb(drive->select | ATA_DEVICE_OBS, - (void __iomem *)drive->hwif->io_ports.device_addr); -} - -static void pmac_kauai_dev_select(ide_drive_t *drive) -{ - pmac_ide_kauai_apply_timings(drive); - - writeb(drive->select | ATA_DEVICE_OBS, - (void __iomem *)drive->hwif->io_ports.device_addr); + pmac_ide_selectproc(drive); } static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd) @@ -488,8 +477,17 @@ static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd) + IDE_TIMING_CONFIG)); } -static void pmac_write_devctl(ide_hwif_t *hwif, u8 ctl) +static void pmac_set_irq(ide_hwif_t *hwif, int on) { + u8 ctl = ATA_DEVCTL_OBS; + + if (on == 4) { /* hack for SRST */ + ctl |= 4; + on &= ~4; + } + + ctl |= on ? 0 : 2; + writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr); (void)readl((void __iomem *)(hwif->io_ports.data_addr + IDE_TIMING_CONFIG)); @@ -919,18 +917,10 @@ static u8 pmac_ide_cable_detect(ide_hwif_t *hwif) (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); struct device_node *np = pmif->node; const char *cable = of_get_property(np, "cable-type", NULL); - struct device_node *root = of_find_node_by_path("/"); - const char *model = of_get_property(root, "model", NULL); /* Get cable type from device-tree. */ - if (cable && !strncmp(cable, "80-", 3)) { - /* Some drives fail to detect 80c cable in PowerBook */ - /* These machine use proprietary short IDE cable anyway */ - if (!strncmp(model, "PowerBook", 9)) - return ATA_CBL_PATA40_SHORT; - else - return ATA_CBL_PATA80; - } + if (cable && !strncmp(cable, "80-", 3)) + return ATA_CBL_PATA80; /* * G5's seem to have incorrect cable type in device-tree. @@ -965,9 +955,9 @@ static const struct ide_tp_ops pmac_tp_ops = { .exec_command = pmac_exec_command, .read_status = ide_read_status, .read_altstatus = ide_read_altstatus, - .write_devctl = pmac_write_devctl, - .dev_select = pmac_dev_select, + .set_irq = pmac_set_irq, + .tf_load = ide_tf_load, .tf_read = ide_tf_read, @@ -975,24 +965,19 @@ static const struct ide_tp_ops pmac_tp_ops = { .output_data = ide_output_data, }; -static const struct ide_tp_ops pmac_ata6_tp_ops = { - .exec_command = pmac_exec_command, - .read_status = ide_read_status, - .read_altstatus = ide_read_altstatus, - .write_devctl = pmac_write_devctl, - - .dev_select = pmac_kauai_dev_select, - .tf_load = ide_tf_load, - .tf_read = ide_tf_read, - - .input_data = ide_input_data, - .output_data = ide_output_data, +static const struct ide_port_ops pmac_ide_ata6_port_ops = { + .init_dev = pmac_ide_init_dev, + .set_pio_mode = pmac_ide_set_pio_mode, + .set_dma_mode = pmac_ide_set_dma_mode, + .selectproc = pmac_ide_kauai_selectproc, + .cable_detect = pmac_ide_cable_detect, }; static const struct ide_port_ops pmac_ide_ata4_port_ops = { .init_dev = pmac_ide_init_dev, .set_pio_mode = pmac_ide_set_pio_mode, .set_dma_mode = pmac_ide_set_dma_mode, + .selectproc = pmac_ide_selectproc, .cable_detect = pmac_ide_cable_detect, }; @@ -1000,6 +985,7 @@ static const struct ide_port_ops pmac_ide_port_ops = { .init_dev = pmac_ide_init_dev, .set_pio_mode = pmac_ide_set_pio_mode, .set_dma_mode = pmac_ide_set_dma_mode, + .selectproc = pmac_ide_selectproc, }; static const struct ide_dma_ops pmac_dma_ops; @@ -1036,18 +1022,15 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, hw_regs_t *hw) pmif->broken_dma = pmif->broken_dma_warn = 0; if (of_device_is_compatible(np, "shasta-ata")) { pmif->kind = controller_sh_ata6; - d.tp_ops = &pmac_ata6_tp_ops; - d.port_ops = &pmac_ide_ata4_port_ops; + d.port_ops = &pmac_ide_ata6_port_ops; d.udma_mask = ATA_UDMA6; } else if (of_device_is_compatible(np, "kauai-ata")) { pmif->kind = controller_un_ata6; - d.tp_ops = &pmac_ata6_tp_ops; - d.port_ops = &pmac_ide_ata4_port_ops; + d.port_ops = &pmac_ide_ata6_port_ops; d.udma_mask = ATA_UDMA5; } else if (of_device_is_compatible(np, "K2-UATA")) { pmif->kind = controller_k2_ata6; - d.tp_ops = &pmac_ata6_tp_ops; - d.port_ops = &pmac_ide_ata4_port_ops; + d.port_ops = &pmac_ide_ata6_port_ops; d.udma_mask = ATA_UDMA5; } else if (of_device_is_compatible(np, "keylargo-ata")) { if (strcmp(np->name, "ata-4") == 0) { @@ -1439,16 +1422,17 @@ int __init pmac_ide_probe(void) * pmac_ide_build_dmatable builds the DBDMA command list * for a transfer and sets the DBDMA channel to point to it. */ -static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) +static int +pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = drive->hwif; pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); struct dbdma_cmd *table; + int i, count = 0; volatile struct dbdma_regs __iomem *dma = pmif->dma_regs; struct scatterlist *sg; - int wr = !!(cmd->tf_flags & IDE_TFLAG_WRITE); - int i = cmd->sg_nents, count = 0; + int wr = (rq_data_dir(rq) == WRITE); /* DMA table is already aligned */ table = (struct dbdma_cmd *) pmif->dma_table_cpu; @@ -1458,6 +1442,11 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) while (readl(&dma->status) & RUN) udelay(1); + hwif->sg_nents = i = ide_build_sglist(drive, rq); + + if (!i) + return 0; + /* Build DBDMA commands list */ sg = hwif->sg_table; while (i && sg_dma_len(sg)) { @@ -1473,7 +1462,7 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) "switching to PIO on Ohare chipset\n", drive->name); pmif->broken_dma_warn = 1; } - return 0; + goto use_pio_instead; } while (cur_len) { unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00; @@ -1481,7 +1470,7 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) if (count++ >= MAX_DCMDS) { printk(KERN_WARNING "%s: DMA table too small\n", drive->name); - return 0; + goto use_pio_instead; } st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE); st_le16(&table->req_count, tc); @@ -1510,6 +1499,9 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name); +use_pio_instead: + ide_destroy_dmatable(drive); + return 0; /* revert to PIO for this request */ } @@ -1517,27 +1509,39 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) * Prepare a DMA transfer. We build the DMA table, adjust the timings for * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion */ -static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +static int +pmac_ide_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); + struct request *rq = hwif->rq; u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4); - u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE); - if (pmac_ide_build_dmatable(drive, cmd) == 0) + if (!pmac_ide_build_dmatable(drive, rq)) { + ide_map_sg(drive, rq); return 1; + } /* Apple adds 60ns to wrDataSetup on reads */ if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) { - writel(pmif->timings[unit] + (write ? 0 : 0x00800000UL), + writel(pmif->timings[unit] + (!rq_data_dir(rq) ? 0x00800000UL : 0), PMAC_IDE_REG(IDE_TIMING_CONFIG)); (void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG)); } + drive->waiting_for_dma = 1; + return 0; } +static void +pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command) +{ + /* issue cmd to drive */ + ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL); +} + /* * Kick the DMA controller into life after the DMA command has been issued * to the drive. @@ -1569,9 +1573,12 @@ pmac_ide_dma_end (ide_drive_t *drive) volatile struct dbdma_regs __iomem *dma = pmif->dma_regs; u32 dstat; + drive->waiting_for_dma = 0; dstat = readl(&dma->status); writel(((RUN|WAKE|DEAD) << 16), &dma->control); + ide_destroy_dmatable(drive); + /* verify good dma status. we don't check for ACTIVE beeing 0. We should... * in theory, but with ATAPI decices doing buffer underruns, that would * cause us to disable DMA, which isn't what we want @@ -1655,9 +1662,11 @@ pmac_ide_dma_lost_irq (ide_drive_t *drive) static const struct ide_dma_ops pmac_dma_ops = { .dma_host_set = pmac_ide_dma_host_set, .dma_setup = pmac_ide_dma_setup, + .dma_exec_cmd = pmac_ide_dma_exec_cmd, .dma_start = pmac_ide_dma_start, .dma_end = pmac_ide_dma_end, .dma_test_irq = pmac_ide_dma_test_irq, + .dma_timeout = ide_dma_timeout, .dma_lost_irq = pmac_ide_dma_lost_irq, }; diff --git a/trunk/drivers/ide/q40ide.c b/trunk/drivers/ide/q40ide.c index d007e7f66598..9f9c0b3cc3a3 100644 --- a/trunk/drivers/ide/q40ide.c +++ b/trunk/drivers/ide/q40ide.c @@ -72,26 +72,26 @@ static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base, hw->chipset = ide_generic; } -static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void q40ide_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; - if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) + if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) return insw(data_addr, buf, (len + 1) / 2); - raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2); + insw_swapw(data_addr, buf, (len + 1) / 2); } -static void q40ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void q40ide_output_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; - if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) + if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) return outsw(data_addr, buf, (len + 1) / 2); - raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2); + outsw_swapw(data_addr, buf, (len + 1) / 2); } /* Q40 has a byte-swapped IDE interface */ @@ -99,9 +99,9 @@ static const struct ide_tp_ops q40ide_tp_ops = { .exec_command = ide_exec_command, .read_status = ide_read_status, .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - .dev_select = ide_dev_select, + .set_irq = ide_set_irq, + .tf_load = ide_tf_load, .tf_read = ide_tf_read, @@ -111,8 +111,7 @@ static const struct ide_tp_ops q40ide_tp_ops = { static const struct ide_port_info q40ide_port_info = { .tp_ops = &q40ide_tp_ops, - .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, - .irq_flags = IRQF_SHARED, + .host_flags = IDE_HFLAG_NO_DMA, }; /* diff --git a/trunk/drivers/ide/qd65xx.c b/trunk/drivers/ide/qd65xx.c index c9a134986891..08c4fa35e9b1 100644 --- a/trunk/drivers/ide/qd65xx.c +++ b/trunk/drivers/ide/qd65xx.c @@ -90,15 +90,13 @@ static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */ * This routine is invoked to prepare for access to a given drive. */ -static void qd65xx_dev_select(ide_drive_t *drive) +static void qd65xx_select(ide_drive_t *drive) { u8 index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) | (QD_TIMREG(drive) & 0x02); if (timings[index] != QD_TIMING(drive)) outb(timings[index] = QD_TIMING(drive), QD_TIMREG(drive)); - - outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr); } /* @@ -311,33 +309,20 @@ static void __init qd6580_init_dev(ide_drive_t *drive) drive->drive_data = (drive->dn & 1) ? t2 : t1; } -static const struct ide_tp_ops qd65xx_tp_ops = { - .exec_command = ide_exec_command, - .read_status = ide_read_status, - .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - - .dev_select = qd65xx_dev_select, - .tf_load = ide_tf_load, - .tf_read = ide_tf_read, - - .input_data = ide_input_data, - .output_data = ide_output_data, -}; - static const struct ide_port_ops qd6500_port_ops = { .init_dev = qd6500_init_dev, .set_pio_mode = qd6500_set_pio_mode, + .selectproc = qd65xx_select, }; static const struct ide_port_ops qd6580_port_ops = { .init_dev = qd6580_init_dev, .set_pio_mode = qd6580_set_pio_mode, + .selectproc = qd65xx_select, }; static const struct ide_port_info qd65xx_port_info __initdata = { .name = DRV_NAME, - .tp_ops = &qd65xx_tp_ops, .chipset = ide_qd65xx, .host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_NO_DMA, diff --git a/trunk/drivers/ide/sc1200.c b/trunk/drivers/ide/sc1200.c index d467478d68da..dbdd2985a0d8 100644 --- a/trunk/drivers/ide/sc1200.c +++ b/trunk/drivers/ide/sc1200.c @@ -115,7 +115,8 @@ static u8 sc1200_udma_filter(ide_drive_t *drive) if ((mateid[ATA_ID_FIELD_VALID] & 4) && (mateid[ATA_ID_UDMA_MODES] & 7)) goto out; - if (mateid[ATA_ID_MWDMA_MODES] & 7) + if ((mateid[ATA_ID_FIELD_VALID] & 2) && + (mateid[ATA_ID_MWDMA_MODES] & 7)) mask = 0; } out: @@ -182,6 +183,9 @@ static int sc1200_dma_end(ide_drive_t *drive) outb(dma_stat|0x1b, dma_base+2); /* clear the INTR & ERROR bits */ outb(inb(dma_base)&~1, dma_base); /* !! DO THIS HERE !! stop DMA */ + drive->waiting_for_dma = 0; + ide_destroy_dmatable(drive); /* purge DMA mappings */ + return (dma_stat & 7) != 4; /* verify good DMA status */ } @@ -282,11 +286,12 @@ static const struct ide_port_ops sc1200_port_ops = { static const struct ide_dma_ops sc1200_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = sc1200_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/scc_pata.c b/trunk/drivers/ide/scc_pata.c index 6d8dbd9c10bc..8d2314b6327c 100644 --- a/trunk/drivers/ide/scc_pata.c +++ b/trunk/drivers/ide/scc_pata.c @@ -148,8 +148,17 @@ static u8 scc_dma_sff_read_status(ide_hwif_t *hwif) return (u8)in_be32((void *)(hwif->dma_base + 4)); } -static void scc_write_devctl(ide_hwif_t *hwif, u8 ctl) +static void scc_set_irq(ide_hwif_t *hwif, int on) { + u8 ctl = ATA_DEVCTL_OBS; + + if (on == 4) { /* hack for SRST */ + ctl |= 4; + on &= ~4; + } + + ctl |= on ? 0 : 2; + out_be32((void *)hwif->io_ports.ctl_addr, ctl); eieio(); in_be32((void *)(hwif->dma_base + 0x01c)); @@ -294,9 +303,8 @@ static void scc_dma_host_set(ide_drive_t *drive, int on) } /** - * scc_dma_setup - begin a DMA phase + * scc_ide_dma_setup - begin a DMA phase * @drive: target device - * @cmd: command * * Build an IDE DMA PRD (IDE speak for scatter gather table) * and then set up the DMA transfer registers. @@ -305,28 +313,36 @@ static void scc_dma_host_set(ide_drive_t *drive, int on) * is returned. */ -static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +static int scc_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - u32 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR; + struct request *rq = hwif->rq; + unsigned int reading; u8 dma_stat; + if (rq_data_dir(rq)) + reading = 0; + else + reading = 1 << 3; + /* fall back to pio! */ - if (ide_build_dmatable(drive, cmd) == 0) + if (!ide_build_dmatable(drive, rq)) { + ide_map_sg(drive, rq); return 1; + } /* PRD table */ out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma); /* specify r/w */ - out_be32((void __iomem *)hwif->dma_base, rw); + out_be32((void __iomem *)hwif->dma_base, reading); /* read DMA status for INTR & ERROR flags */ dma_stat = scc_dma_sff_read_status(hwif); /* clear INTR & ERROR flags */ out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6); - + drive->waiting_for_dma = 1; return 0; } @@ -345,6 +361,7 @@ static int __scc_dma_end(ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; u8 dma_stat, dma_cmd; + drive->waiting_for_dma = 0; /* get DMA command mode */ dma_cmd = scc_ide_inb(hwif->dma_base); /* stop DMA */ @@ -353,6 +370,8 @@ static int __scc_dma_end(ide_drive_t *drive) dma_stat = scc_dma_sff_read_status(hwif); /* clear the INTR & ERROR bits */ scc_ide_outb(dma_stat | 6, hwif->dma_base + 4); + /* purge DMA mappings */ + ide_destroy_dmatable(drive); /* verify good DMA status */ wmb(); return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; @@ -647,80 +666,91 @@ static int __devinit init_setup_scc(struct pci_dev *dev, return rc; } -static void scc_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +static void scc_tf_load(ide_drive_t *drive, ide_task_t *task) { struct ide_io_ports *io_ports = &drive->hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; - u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; + struct ide_taskfile *tf = &task->tf; + u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; - if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) + if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_DATA) + out_be32((void *)io_ports->data_addr, + (tf->hob_data << 8) | tf->data); + + if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) scc_ide_outb(tf->hob_feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) scc_ide_outb(tf->hob_nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) scc_ide_outb(tf->hob_lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) scc_ide_outb(tf->hob_lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) scc_ide_outb(tf->hob_lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) scc_ide_outb(tf->feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_NSECT) scc_ide_outb(tf->nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_LBAL) scc_ide_outb(tf->lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_LBAM) scc_ide_outb(tf->lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_LBAH) scc_ide_outb(tf->lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) scc_ide_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); } -static void scc_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +static void scc_tf_read(ide_drive_t *drive, ide_task_t *task) { struct ide_io_ports *io_ports = &drive->hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; + + if (task->tf_flags & IDE_TFLAG_IN_DATA) { + u16 data = (u16)in_be32((void *)io_ports->data_addr); + + tf->data = data & 0xff; + tf->hob_data = (data >> 8) & 0xff; + } /* be sure we're looking at the low order bits */ - scc_ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); + scc_ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) - tf->error = scc_ide_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) + tf->feature = scc_ide_inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = scc_ide_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = scc_ide_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = scc_ide_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = scc_ide_inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = scc_ide_inb(io_ports->device_addr); - if (cmd->tf_flags & IDE_TFLAG_LBA48) { - scc_ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); - - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) - tf->hob_error = scc_ide_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) - tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) - tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) - tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) - tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr); + if (task->tf_flags & IDE_TFLAG_LBA48) { + scc_ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); + + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + tf->hob_feature = scc_ide_inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) + tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr); } } -static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void scc_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; @@ -736,7 +766,7 @@ static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd, scc_ide_insw(data_addr, buf, len / 2); } -static void scc_output_data(ide_drive_t *drive, struct ide_cmd *cmd, +static void scc_output_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long data_addr = drive->hwif->io_ports.data_addr; @@ -823,9 +853,9 @@ static const struct ide_tp_ops scc_tp_ops = { .exec_command = scc_exec_command, .read_status = scc_read_status, .read_altstatus = scc_read_altstatus, - .write_devctl = scc_write_devctl, - .dev_select = ide_dev_select, + .set_irq = scc_set_irq, + .tf_load = scc_tf_load, .tf_read = scc_tf_read, @@ -843,25 +873,30 @@ static const struct ide_port_ops scc_port_ops = { static const struct ide_dma_ops scc_dma_ops = { .dma_host_set = scc_dma_host_set, .dma_setup = scc_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = scc_dma_start, .dma_end = scc_dma_end, .dma_test_irq = scc_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_timeout = ide_dma_timeout, .dma_sff_read_status = scc_dma_sff_read_status, }; -static const struct ide_port_info scc_chipset __devinitdata = { - .name = "sccIDE", - .init_iops = init_iops_scc, - .init_dma = scc_init_dma, - .init_hwif = init_hwif_scc, - .tp_ops = &scc_tp_ops, - .port_ops = &scc_port_ops, - .dma_ops = &scc_dma_ops, - .host_flags = IDE_HFLAG_SINGLE, - .irq_flags = IRQF_SHARED, - .pio_mask = ATA_PIO4, +#define DECLARE_SCC_DEV(name_str) \ + { \ + .name = name_str, \ + .init_iops = init_iops_scc, \ + .init_dma = scc_init_dma, \ + .init_hwif = init_hwif_scc, \ + .tp_ops = &scc_tp_ops, \ + .port_ops = &scc_port_ops, \ + .dma_ops = &scc_dma_ops, \ + .host_flags = IDE_HFLAG_SINGLE, \ + .pio_mask = ATA_PIO4, \ + } + +static const struct ide_port_info scc_chipsets[] __devinitdata = { + /* 0 */ DECLARE_SCC_DEV("sccIDE"), }; /** @@ -875,7 +910,7 @@ static const struct ide_port_info scc_chipset __devinitdata = { static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - return init_setup_scc(dev, &scc_chipset); + return init_setup_scc(dev, &scc_chipsets[id->driver_data]); } /** diff --git a/trunk/drivers/ide/setup-pci.c b/trunk/drivers/ide/setup-pci.c index a19dbccd7617..24bc884826fc 100644 --- a/trunk/drivers/ide/setup-pci.c +++ b/trunk/drivers/ide/setup-pci.c @@ -558,8 +558,6 @@ int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d, host->host_priv = priv; - host->irq_flags = IRQF_SHARED; - pci_set_drvdata(dev, host); ret = do_ide_setup_pci_device(dev, d, 1); @@ -608,8 +606,6 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, host->host_priv = priv; - host->irq_flags = IRQF_SHARED; - pci_set_drvdata(pdev[0], host); pci_set_drvdata(pdev[1], host); diff --git a/trunk/drivers/ide/sgiioc4.c b/trunk/drivers/ide/sgiioc4.c index e5d2a48a84de..fdb9d7037694 100644 --- a/trunk/drivers/ide/sgiioc4.c +++ b/trunk/drivers/ide/sgiioc4.c @@ -258,6 +258,9 @@ static int sgiioc4_dma_end(ide_drive_t *drive) } } + drive->waiting_for_dma = 0; + ide_destroy_dmatable(drive); + return dma_stat; } @@ -277,12 +280,10 @@ static void sgiioc4_dma_host_set(ide_drive_t *drive, int on) sgiioc4_clearirq(drive); } -static void sgiioc4_resetproc(ide_drive_t *drive) +static void +sgiioc4_resetproc(ide_drive_t * drive) { - struct ide_cmd *cmd = &drive->hwif->cmd; - sgiioc4_dma_end(drive); - ide_dma_unmap_sg(drive, cmd); sgiioc4_clearirq(drive); } @@ -411,6 +412,7 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4)); writel(dma_direction, (void __iomem *)ioc4_dma_addr); + drive->waiting_for_dma = 1; } /* IOC4 Scatter Gather list Format */ @@ -422,13 +424,20 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) /* | Upper 32 bits - Zero |EOL| 15 unused | 16 Bit Length| */ /* --------------------------------------------------------------------- */ /* Creates the scatter gather list, DMA Table */ -static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) +static unsigned int +sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir) { ide_hwif_t *hwif = drive->hwif; unsigned int *table = hwif->dmatable_cpu; - unsigned int count = 0, i = cmd->sg_nents; - struct scatterlist *sg = hwif->sg_table; + unsigned int count = 0, i = 1; + struct scatterlist *sg; + + hwif->sg_nents = i = ide_build_sglist(drive, rq); + + if (!i) + return 0; /* sglist of length Zero */ + sg = hwif->sg_table; while (i && sg_dma_len(sg)) { dma_addr_t cur_addr; int cur_len; @@ -440,7 +449,7 @@ static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) printk(KERN_WARNING "%s: DMA table too small\n", drive->name); - return 0; + goto use_pio_instead; } else { u32 bcount = 0x10000 - (cur_addr & 0xffff); @@ -475,19 +484,30 @@ static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) return count; } +use_pio_instead: + ide_destroy_dmatable(drive); + return 0; /* revert to PIO for this request */ } -static int sgiioc4_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +static int sgiioc4_dma_setup(ide_drive_t *drive) { + struct request *rq = drive->hwif->rq; + unsigned int count = 0; int ddir; - u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE); - if (sgiioc4_build_dmatable(drive, cmd) == 0) + if (rq_data_dir(rq)) + ddir = PCI_DMA_TODEVICE; + else + ddir = PCI_DMA_FROMDEVICE; + + if (!(count = sgiioc4_build_dma_table(drive, rq, ddir))) { /* try PIO instead of DMA */ + ide_map_sg(drive, rq); return 1; + } - if (write) + if (rq_data_dir(rq)) /* Writes TO the IOC4 FROM Main Memory */ ddir = IOC4_DMA_READ; else @@ -503,9 +523,9 @@ static const struct ide_tp_ops sgiioc4_tp_ops = { .exec_command = ide_exec_command, .read_status = sgiioc4_read_status, .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - .dev_select = ide_dev_select, + .set_irq = ide_set_irq, + .tf_load = ide_tf_load, .tf_read = ide_tf_read, @@ -526,6 +546,7 @@ static const struct ide_dma_ops sgiioc4_dma_ops = { .dma_end = sgiioc4_dma_end, .dma_test_irq = sgiioc4_dma_test_irq, .dma_lost_irq = sgiioc4_dma_lost_irq, + .dma_timeout = ide_dma_timeout, }; static const struct ide_port_info sgiioc4_port_info __devinitconst = { @@ -536,7 +557,6 @@ static const struct ide_port_info sgiioc4_port_info __devinitconst = { .port_ops = &sgiioc4_port_ops, .dma_ops = &sgiioc4_dma_ops, .host_flags = IDE_HFLAG_MMIO, - .irq_flags = IRQF_SHARED, .mwdma_mask = ATA_MWDMA2_ONLY, }; diff --git a/trunk/drivers/ide/siimage.c b/trunk/drivers/ide/siimage.c index e4973cd1fba9..1811ae9cd843 100644 --- a/trunk/drivers/ide/siimage.c +++ b/trunk/drivers/ide/siimage.c @@ -711,10 +711,11 @@ static const struct ide_port_ops sil_sata_port_ops = { static const struct ide_dma_ops sil_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = ide_dma_end, .dma_test_irq = siimage_dma_test_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_timeout = ide_dma_timeout, .dma_lost_irq = ide_dma_lost_irq, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/sl82c105.c b/trunk/drivers/ide/sl82c105.c index b0a460625335..dba213c51baa 100644 --- a/trunk/drivers/ide/sl82c105.c +++ b/trunk/drivers/ide/sl82c105.c @@ -61,8 +61,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio) if (cmd_off == 0) cmd_off = 1; - if ((pio > 2 || ata_id_has_iordy(drive->id)) && - !(pio > 4 && ata_id_is_cfa(drive->id))) + if (pio > 2 || ata_id_has_iordy(drive->id)) iordy = 0x40; return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy; @@ -190,13 +189,14 @@ static void sl82c105_dma_start(ide_drive_t *drive) ide_dma_start(drive); } -static void sl82c105_dma_clear(ide_drive_t *drive) +static void sl82c105_dma_timeout(ide_drive_t *drive) { struct pci_dev *dev = to_pci_dev(drive->hwif->dev); - DBG(("sl82c105_dma_clear(drive:%s)\n", drive->name)); + DBG(("sl82c105_dma_timeout(drive:%s)\n", drive->name)); sl82c105_reset_host(dev); + ide_dma_timeout(drive); } static int sl82c105_dma_end(ide_drive_t *drive) @@ -293,12 +293,12 @@ static const struct ide_port_ops sl82c105_port_ops = { static const struct ide_dma_ops sl82c105_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = sl82c105_dma_start, .dma_end = sl82c105_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = sl82c105_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, - .dma_clear = sl82c105_dma_clear, + .dma_timeout = sl82c105_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/tc86c001.c b/trunk/drivers/ide/tc86c001.c index b4cf42dc8a6f..84109f5a1632 100644 --- a/trunk/drivers/ide/tc86c001.c +++ b/trunk/drivers/ide/tc86c001.c @@ -182,11 +182,12 @@ static const struct ide_port_ops tc86c001_port_ops = { static const struct ide_dma_ops tc86c001_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = tc86c001_dma_start, .dma_end = ide_dma_end, .dma_test_irq = ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_timeout = ide_dma_timeout, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/ide/trm290.c b/trunk/drivers/ide/trm290.c index 4b42ca091534..1c09e549c423 100644 --- a/trunk/drivers/ide/trm290.c +++ b/trunk/drivers/ide/trm290.c @@ -171,51 +171,58 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma) local_irq_restore(flags); } -static void trm290_dev_select(ide_drive_t *drive) +static void trm290_selectproc (ide_drive_t *drive) { trm290_prepare_drive(drive, !!(drive->dev_flags & IDE_DFLAG_USING_DMA)); +} - outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr); +static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command) +{ + ide_execute_command(drive, command, &ide_dma_intr, WAIT_CMD, NULL); } -static int trm290_dma_check(ide_drive_t *drive, struct ide_cmd *cmd) +static int trm290_dma_setup(ide_drive_t *drive) { - if (cmd->tf_flags & IDE_TFLAG_WRITE) { + ide_hwif_t *hwif = drive->hwif; + struct request *rq = hwif->rq; + unsigned int count, rw; + + if (rq_data_dir(rq)) { #ifdef TRM290_NO_DMA_WRITES /* always use PIO for writes */ + trm290_prepare_drive(drive, 0); /* select PIO xfer */ return 1; #endif - } - return 0; -} - -static int trm290_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) -{ - ide_hwif_t *hwif = drive->hwif; - unsigned int count, rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 2; + rw = 1; + } else + rw = 2; - count = ide_build_dmatable(drive, cmd); - if (count == 0) + if (!(count = ide_build_dmatable(drive, rq))) { /* try PIO instead of DMA */ + trm290_prepare_drive(drive, 0); /* select PIO xfer */ return 1; - + } + /* select DMA xfer */ + trm290_prepare_drive(drive, 1); outl(hwif->dmatable_dma | rw, hwif->dma_base); + drive->waiting_for_dma = 1; /* start DMA */ outw(count * 2 - 1, hwif->dma_base + 2); - return 0; } static void trm290_dma_start(ide_drive_t *drive) { - trm290_prepare_drive(drive, 1); } static int trm290_dma_end(ide_drive_t *drive) { - u16 status = inw(drive->hwif->dma_base + 2); + u16 status; - trm290_prepare_drive(drive, 0); + drive->waiting_for_dma = 0; + /* purge DMA mappings */ + ide_destroy_dmatable(drive); + status = inw(drive->hwif->dma_base + 2); return status != 0x00ff; } @@ -300,34 +307,25 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif) #endif } -static const struct ide_tp_ops trm290_tp_ops = { - .exec_command = ide_exec_command, - .read_status = ide_read_status, - .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - - .dev_select = trm290_dev_select, - .tf_load = ide_tf_load, - .tf_read = ide_tf_read, - - .input_data = ide_input_data, - .output_data = ide_output_data, +static const struct ide_port_ops trm290_port_ops = { + .selectproc = trm290_selectproc, }; static struct ide_dma_ops trm290_dma_ops = { .dma_host_set = trm290_dma_host_set, .dma_setup = trm290_dma_setup, + .dma_exec_cmd = trm290_dma_exec_cmd, .dma_start = trm290_dma_start, .dma_end = trm290_dma_end, .dma_test_irq = trm290_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_check = trm290_dma_check, + .dma_timeout = ide_dma_timeout, }; static const struct ide_port_info trm290_chipset __devinitdata = { .name = DRV_NAME, .init_hwif = init_hwif_trm290, - .tp_ops = &trm290_tp_ops, + .port_ops = &trm290_port_ops, .dma_ops = &trm290_dma_ops, .host_flags = IDE_HFLAG_TRM290 | IDE_HFLAG_NO_ATAPI_DMA | diff --git a/trunk/drivers/ide/tx4938ide.c b/trunk/drivers/ide/tx4938ide.c index 4cb79c4c2604..d9095345f7ca 100644 --- a/trunk/drivers/ide/tx4938ide.c +++ b/trunk/drivers/ide/tx4938ide.c @@ -15,8 +15,6 @@ #include #include #include - -#include #include static void tx4938ide_tune_ebusc(unsigned int ebus_ch, @@ -82,82 +80,99 @@ static void tx4938ide_outb(u8 value, unsigned long port) __raw_writeb(value, (void __iomem *)port); } -static void tx4938ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +static void tx4938ide_tf_load(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; - u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF; + struct ide_taskfile *tf = &task->tf; + u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF; - if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) + if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_DATA) { + u16 data = (tf->hob_data << 8) | tf->data; + + /* no endian swap */ + __raw_writew(data, (void __iomem *)io_ports->data_addr); + } + + if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) tx4938ide_outb(tf->hob_feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) tx4938ide_outb(tf->hob_nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) tx4938ide_outb(tf->hob_lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) tx4938ide_outb(tf->hob_lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) tx4938ide_outb(tf->hob_lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) tx4938ide_outb(tf->feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_NSECT) tx4938ide_outb(tf->nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_LBAL) tx4938ide_outb(tf->lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_LBAM) tx4938ide_outb(tf->lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_LBAH) tx4938ide_outb(tf->lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) tx4938ide_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); } -static void tx4938ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +static void tx4938ide_tf_read(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; + + if (task->tf_flags & IDE_TFLAG_IN_DATA) { + u16 data; + + /* no endian swap */ + data = __raw_readw((void __iomem *)io_ports->data_addr); + tf->data = data & 0xff; + tf->hob_data = (data >> 8) & 0xff; + } /* be sure we're looking at the low order bits */ - tx4938ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); + tx4938ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) - tf->error = tx4938ide_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) + tf->feature = tx4938ide_inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = tx4938ide_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = tx4938ide_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = tx4938ide_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = tx4938ide_inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = tx4938ide_inb(io_ports->device_addr); - if (cmd->tf_flags & IDE_TFLAG_LBA48) { - tx4938ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); - - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) - tf->hob_error = tx4938ide_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) - tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) - tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) - tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) - tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr); + if (task->tf_flags & IDE_TFLAG_LBA48) { + tx4938ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); + + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + tf->hob_feature = + tx4938ide_inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) + tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr); } } -static void tx4938ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd, +static void tx4938ide_input_data_swap(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long port = drive->hwif->io_ports.data_addr; @@ -169,7 +184,7 @@ static void tx4938ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd, __ide_flush_dcache_range((unsigned long)buf, roundup(len, 2)); } -static void tx4938ide_output_data_swap(ide_drive_t *drive, struct ide_cmd *cmd, +static void tx4938ide_output_data_swap(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { unsigned long port = drive->hwif->io_ports.data_addr; @@ -187,9 +202,9 @@ static const struct ide_tp_ops tx4938ide_tp_ops = { .exec_command = ide_exec_command, .read_status = ide_read_status, .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - .dev_select = ide_dev_select, + .set_irq = ide_set_irq, + .tf_load = tx4938ide_tf_load, .tf_read = tx4938ide_tf_read, diff --git a/trunk/drivers/ide/tx4939ide.c b/trunk/drivers/ide/tx4939ide.c index 0040a9a3e26e..40b0812a045c 100644 --- a/trunk/drivers/ide/tx4939ide.c +++ b/trunk/drivers/ide/tx4939ide.c @@ -18,8 +18,6 @@ #include #include -#include - #define MODNAME "tx4939ide" /* ATA Shadow Registers (8-bit except for Data which is 16-bit) */ @@ -232,7 +230,7 @@ static u8 tx4939ide_clear_dma_status(void __iomem *base) #ifdef __BIG_ENDIAN /* custom ide_build_dmatable to handle swapped layout */ -static int tx4939ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) +static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = drive->hwif; u32 *table = (u32 *)hwif->dmatable_cpu; @@ -240,7 +238,11 @@ static int tx4939ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) int i; struct scatterlist *sg; - for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) { + hwif->sg_nents = ide_build_sglist(drive, rq); + if (hwif->sg_nents == 0) + return 0; + + for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) { u32 cur_addr, cur_len, bcount; cur_addr = sg_dma_address(sg); @@ -279,36 +281,48 @@ static int tx4939ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) printk(KERN_ERR "%s: %s\n", drive->name, count ? "DMA table too small" : "empty DMA table?"); + ide_destroy_dmatable(drive); + return 0; /* revert to PIO for this request */ } #else #define tx4939ide_build_dmatable ide_build_dmatable #endif -static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) +static int tx4939ide_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; void __iomem *base = TX4939IDE_BASE(hwif); - u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR; + struct request *rq = hwif->rq; + u8 reading; + int nent; + + if (rq_data_dir(rq)) + reading = 0; + else + reading = ATA_DMA_WR; /* fall back to PIO! */ - if (tx4939ide_build_dmatable(drive, cmd) == 0) + nent = tx4939ide_build_dmatable(drive, rq); + if (!nent) { + ide_map_sg(drive, rq); return 1; + } /* PRD table */ tx4939ide_writel(hwif->dmatable_dma, base, TX4939IDE_PRD_Ptr); /* specify r/w */ - tx4939ide_writeb(rw, base, TX4939IDE_DMA_Cmd); + tx4939ide_writeb(reading, base, TX4939IDE_DMA_Cmd); /* clear INTR & ERROR flags */ tx4939ide_clear_dma_status(base); + drive->waiting_for_dma = 1; + tx4939ide_writew(SECTOR_SIZE / 2, base, drive->dn ? TX4939IDE_Xfer_Cnt_2 : TX4939IDE_Xfer_Cnt_1); - - tx4939ide_writew(cmd->rq->nr_sectors, base, TX4939IDE_Sec_Cnt); - + tx4939ide_writew(rq->nr_sectors, base, TX4939IDE_Sec_Cnt); return 0; } @@ -319,6 +333,8 @@ static int tx4939ide_dma_end(ide_drive_t *drive) void __iomem *base = TX4939IDE_BASE(hwif); u16 ctl = tx4939ide_readw(base, TX4939IDE_Int_Ctl); + drive->waiting_for_dma = 0; + /* get DMA command mode */ dma_cmd = tx4939ide_readb(base, TX4939IDE_DMA_Cmd); /* stop DMA */ @@ -327,9 +343,11 @@ static int tx4939ide_dma_end(ide_drive_t *drive) /* read and clear the INTR & ERROR bits */ dma_stat = tx4939ide_clear_dma_status(base); + /* purge DMA mappings */ + ide_destroy_dmatable(drive); + /* verify good DMA status */ wmb(); - /* verify good DMA status */ if ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) == 0 && (ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) == (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) @@ -419,7 +437,7 @@ static int tx4939ide_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d) return ide_allocate_dma_engine(hwif); } -static void tx4939ide_tf_load_fixup(ide_drive_t *drive) +static void tx4939ide_tf_load_fixup(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; void __iomem *base = TX4939IDE_BASE(hwif); @@ -429,7 +447,7 @@ static void tx4939ide_tf_load_fixup(ide_drive_t *drive) * Fix ATA100 CORE System Control Register. (The write to the * Device/Head register may write wrong data to the System * Control Register) - * While Sys_Ctl is written here, dev_select() is not needed. + * While Sys_Ctl is written here, selectproc is not needed. */ tx4939ide_writew(sysctl, base, TX4939IDE_Sys_Ctl); } @@ -447,80 +465,97 @@ static void tx4939ide_outb(u8 value, unsigned long port) __raw_writeb(value, (void __iomem *)port); } -static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; - u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF; + struct ide_taskfile *tf = &task->tf; + u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF; - if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) + if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_DATA) { + u16 data = (tf->hob_data << 8) | tf->data; + + /* no endian swap */ + __raw_writew(data, (void __iomem *)io_ports->data_addr); + } + + if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) tx4939ide_outb(tf->hob_feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) tx4939ide_outb(tf->hob_nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) tx4939ide_outb(tf->hob_lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) tx4939ide_outb(tf->hob_lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) tx4939ide_outb(tf->hob_lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) + if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) tx4939ide_outb(tf->feature, io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) + if (task->tf_flags & IDE_TFLAG_OUT_NSECT) tx4939ide_outb(tf->nsect, io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) + if (task->tf_flags & IDE_TFLAG_OUT_LBAL) tx4939ide_outb(tf->lbal, io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) + if (task->tf_flags & IDE_TFLAG_OUT_LBAM) tx4939ide_outb(tf->lbam, io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) + if (task->tf_flags & IDE_TFLAG_OUT_LBAH) tx4939ide_outb(tf->lbah, io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) { + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) { tx4939ide_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); - tx4939ide_tf_load_fixup(drive); + tx4939ide_tf_load_fixup(drive, task); } } -static void tx4939ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) +static void tx4939ide_tf_read(ide_drive_t *drive, ide_task_t *task) { ide_hwif_t *hwif = drive->hwif; struct ide_io_ports *io_ports = &hwif->io_ports; - struct ide_taskfile *tf = &cmd->tf; + struct ide_taskfile *tf = &task->tf; + + if (task->tf_flags & IDE_TFLAG_IN_DATA) { + u16 data; + + /* no endian swap */ + data = __raw_readw((void __iomem *)io_ports->data_addr); + tf->data = data & 0xff; + tf->hob_data = (data >> 8) & 0xff; + } /* be sure we're looking at the low order bits */ - tx4939ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); + tx4939ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) - tf->error = tx4939ide_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) + if (task->tf_flags & IDE_TFLAG_IN_FEATURE) + tf->feature = tx4939ide_inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = tx4939ide_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) + if (task->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = tx4939ide_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) + if (task->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = tx4939ide_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) + if (task->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = tx4939ide_inb(io_ports->lbah_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) + if (task->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = tx4939ide_inb(io_ports->device_addr); - if (cmd->tf_flags & IDE_TFLAG_LBA48) { - tx4939ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); - - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) - tf->hob_error = tx4939ide_inb(io_ports->feature_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) - tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) - tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) - tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr); - if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) - tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr); + if (task->tf_flags & IDE_TFLAG_LBA48) { + tx4939ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); + + if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) + tf->hob_feature = + tx4939ide_inb(io_ports->feature_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) + tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) + tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) + tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr); + if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) + tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr); } } @@ -554,9 +589,9 @@ static const struct ide_tp_ops tx4939ide_tp_ops = { .exec_command = ide_exec_command, .read_status = ide_read_status, .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - .dev_select = ide_dev_select, + .set_irq = ide_set_irq, + .tf_load = tx4939ide_tf_load, .tf_read = tx4939ide_tf_read, @@ -566,21 +601,20 @@ static const struct ide_tp_ops tx4939ide_tp_ops = { #else /* __LITTLE_ENDIAN */ -static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) +static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task) { - ide_tf_load(drive, cmd); - - if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) - tx4939ide_tf_load_fixup(drive); + ide_tf_load(drive, task); + if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) + tx4939ide_tf_load_fixup(drive, task); } static const struct ide_tp_ops tx4939ide_tp_ops = { .exec_command = ide_exec_command, .read_status = ide_read_status, .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - .dev_select = ide_dev_select, + .set_irq = ide_set_irq, + .tf_load = tx4939ide_tf_load, .tf_read = ide_tf_read, @@ -600,11 +634,12 @@ static const struct ide_port_ops tx4939ide_port_ops = { static const struct ide_dma_ops tx4939ide_dma_ops = { .dma_host_set = tx4939ide_dma_host_set, .dma_setup = tx4939ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = ide_dma_start, .dma_end = tx4939ide_dma_end, .dma_test_irq = tx4939ide_dma_test_irq, .dma_lost_irq = ide_dma_lost_irq, - .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_timeout = ide_dma_timeout, .dma_sff_read_status = tx4939ide_dma_sff_read_status, }; diff --git a/trunk/drivers/input/input.c b/trunk/drivers/input/input.c index ec3db3ade118..1730d7331a5d 100644 --- a/trunk/drivers/input/input.c +++ b/trunk/drivers/input/input.c @@ -903,6 +903,8 @@ static int __init input_proc_init(void) if (!proc_bus_input_dir) return -ENOMEM; + proc_bus_input_dir->owner = THIS_MODULE; + entry = proc_create("devices", 0, proc_bus_input_dir, &input_devices_fileops); if (!entry) diff --git a/trunk/drivers/input/mouse/hgpk.c b/trunk/drivers/input/mouse/hgpk.c index 55cd0fa68339..81e6ebf323e9 100644 --- a/trunk/drivers/input/mouse/hgpk.c +++ b/trunk/drivers/input/mouse/hgpk.c @@ -381,7 +381,7 @@ static void hgpk_disconnect(struct psmouse *psmouse) static void hgpk_recalib_work(struct work_struct *work) { - struct delayed_work *w = to_delayed_work(work); + struct delayed_work *w = container_of(work, struct delayed_work, work); struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq); struct psmouse *psmouse = priv->psmouse; diff --git a/trunk/drivers/isdn/capi/capi.c b/trunk/drivers/isdn/capi/capi.c index 2d8352419c0d..3e468d2cf730 100644 --- a/trunk/drivers/isdn/capi/capi.c +++ b/trunk/drivers/isdn/capi/capi.c @@ -1331,6 +1331,12 @@ static void capinc_tty_send_xchar(struct tty_struct *tty, char ch) #endif } +static int capinc_tty_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + return 0; +} + static struct tty_driver *capinc_tty_driver; static const struct tty_operations capinc_ops = { @@ -1352,6 +1358,7 @@ static const struct tty_operations capinc_ops = { .flush_buffer = capinc_tty_flush_buffer, .set_ldisc = capinc_tty_set_ldisc, .send_xchar = capinc_tty_send_xchar, + .read_proc = capinc_tty_read_proc, }; static int capinc_tty_init(void) diff --git a/trunk/drivers/isdn/hardware/eicon/divasi.c b/trunk/drivers/isdn/hardware/eicon/divasi.c index 69e71ebe7841..f4969fe0a055 100644 --- a/trunk/drivers/isdn/hardware/eicon/divasi.c +++ b/trunk/drivers/isdn/hardware/eicon/divasi.c @@ -118,6 +118,7 @@ static int DIVA_INIT_FUNCTION create_um_idi_proc(void) return (0); um_idi_proc_entry->read_proc = um_idi_proc_read; + um_idi_proc_entry->owner = THIS_MODULE; return (1); } diff --git a/trunk/drivers/lguest/core.c b/trunk/drivers/lguest/core.c index 4845fb3cf74b..60156dfdc608 100644 --- a/trunk/drivers/lguest/core.c +++ b/trunk/drivers/lguest/core.c @@ -152,8 +152,8 @@ static void unmap_switcher(void) * code. We have to check that the range is below the pfn_limit the Launcher * gave us. We have to make sure that addr + len doesn't give us a false * positive by overflowing, too. */ -bool lguest_address_ok(const struct lguest *lg, - unsigned long addr, unsigned long len) +int lguest_address_ok(const struct lguest *lg, + unsigned long addr, unsigned long len) { return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr); } diff --git a/trunk/drivers/lguest/interrupts_and_traps.c b/trunk/drivers/lguest/interrupts_and_traps.c index 6e99adbe1946..415fab0125ac 100644 --- a/trunk/drivers/lguest/interrupts_and_traps.c +++ b/trunk/drivers/lguest/interrupts_and_traps.c @@ -34,7 +34,7 @@ static int idt_type(u32 lo, u32 hi) } /* An IDT entry can't be used unless the "present" bit is set. */ -static bool idt_present(u32 lo, u32 hi) +static int idt_present(u32 lo, u32 hi) { return (hi & 0x8000); } @@ -60,8 +60,7 @@ static void push_guest_stack(struct lg_cpu *cpu, unsigned long *gstack, u32 val) * We set up the stack just like the CPU does for a real interrupt, so it's * identical for the Guest (and the standard "iret" instruction will undo * it). */ -static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi, - bool has_err) +static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi, int has_err) { unsigned long gstack, origstack; u32 eflags, ss, irq_enable; @@ -185,7 +184,7 @@ void maybe_do_interrupt(struct lg_cpu *cpu) /* set_guest_interrupt() takes the interrupt descriptor and a * flag to say whether this interrupt pushes an error code onto * the stack as well: virtual interrupts never do. */ - set_guest_interrupt(cpu, idt->a, idt->b, false); + set_guest_interrupt(cpu, idt->a, idt->b, 0); } /* Every time we deliver an interrupt, we update the timestamp in the @@ -245,26 +244,26 @@ void free_interrupts(void) /*H:220 Now we've got the routines to deliver interrupts, delivering traps like * page fault is easy. The only trick is that Intel decided that some traps * should have error codes: */ -static bool has_err(unsigned int trap) +static int has_err(unsigned int trap) { return (trap == 8 || (trap >= 10 && trap <= 14) || trap == 17); } /* deliver_trap() returns true if it could deliver the trap. */ -bool deliver_trap(struct lg_cpu *cpu, unsigned int num) +int deliver_trap(struct lg_cpu *cpu, unsigned int num) { /* Trap numbers are always 8 bit, but we set an impossible trap number * for traps inside the Switcher, so check that here. */ if (num >= ARRAY_SIZE(cpu->arch.idt)) - return false; + return 0; /* Early on the Guest hasn't set the IDT entries (or maybe it put a * bogus one in): if we fail here, the Guest will be killed. */ if (!idt_present(cpu->arch.idt[num].a, cpu->arch.idt[num].b)) - return false; + return 0; set_guest_interrupt(cpu, cpu->arch.idt[num].a, cpu->arch.idt[num].b, has_err(num)); - return true; + return 1; } /*H:250 Here's the hard part: returning to the Host every time a trap happens @@ -280,19 +279,18 @@ bool deliver_trap(struct lg_cpu *cpu, unsigned int num) * * This routine indicates if a particular trap number could be delivered * directly. */ -static bool direct_trap(unsigned int num) +static int direct_trap(unsigned int num) { /* Hardware interrupts don't go to the Guest at all (except system * call). */ if (num >= FIRST_EXTERNAL_VECTOR && !could_be_syscall(num)) - return false; + return 0; /* The Host needs to see page faults (for shadow paging and to save the * fault address), general protection faults (in/out emulation) and - * device not available (TS handling), invalid opcode fault (kvm hcall), - * and of course, the hypercall trap. */ - return num != 14 && num != 13 && num != 7 && - num != 6 && num != LGUEST_TRAP_ENTRY; + * device not available (TS handling), and of course, the hypercall + * trap. */ + return num != 14 && num != 13 && num != 7 && num != LGUEST_TRAP_ENTRY; } /*:*/ diff --git a/trunk/drivers/lguest/lg.h b/trunk/drivers/lguest/lg.h index ac8a4a3741b8..f2c641e0bdde 100644 --- a/trunk/drivers/lguest/lg.h +++ b/trunk/drivers/lguest/lg.h @@ -109,8 +109,8 @@ struct lguest extern struct mutex lguest_lock; /* core.c: */ -bool lguest_address_ok(const struct lguest *lg, - unsigned long addr, unsigned long len); +int lguest_address_ok(const struct lguest *lg, + unsigned long addr, unsigned long len); void __lgread(struct lg_cpu *, void *, unsigned long, unsigned); void __lgwrite(struct lg_cpu *, unsigned long, const void *, unsigned); @@ -140,7 +140,7 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user); /* interrupts_and_traps.c: */ void maybe_do_interrupt(struct lg_cpu *cpu); -bool deliver_trap(struct lg_cpu *cpu, unsigned int num); +int deliver_trap(struct lg_cpu *cpu, unsigned int num); void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int i, u32 low, u32 hi); void guest_set_stack(struct lg_cpu *cpu, u32 seg, u32 esp, unsigned int pages); @@ -173,7 +173,7 @@ void guest_pagetable_flush_user(struct lg_cpu *cpu); void guest_set_pte(struct lg_cpu *cpu, unsigned long gpgdir, unsigned long vaddr, pte_t val); void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages); -bool demand_page(struct lg_cpu *cpu, unsigned long cr2, int errcode); +int demand_page(struct lg_cpu *cpu, unsigned long cr2, int errcode); void pin_page(struct lg_cpu *cpu, unsigned long vaddr); unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr); void page_table_guest_data_init(struct lg_cpu *cpu); diff --git a/trunk/drivers/lguest/lguest_device.c b/trunk/drivers/lguest/lguest_device.c index df44d962626d..8132533d71f9 100644 --- a/trunk/drivers/lguest/lguest_device.c +++ b/trunk/drivers/lguest/lguest_device.c @@ -161,7 +161,7 @@ static void set_status(struct virtio_device *vdev, u8 status) /* We set the status. */ to_lgdev(vdev)->desc->status = status; - kvm_hypercall1(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset); + hcall(LHCALL_NOTIFY, (max_pfn<priv; - kvm_hypercall1(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT); + hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0); } /* An extern declaration inside a C file is bad form. Don't do it. */ diff --git a/trunk/drivers/lguest/page_tables.c b/trunk/drivers/lguest/page_tables.c index a059cf9980f7..576a8318221c 100644 --- a/trunk/drivers/lguest/page_tables.c +++ b/trunk/drivers/lguest/page_tables.c @@ -199,7 +199,7 @@ static void check_gpgd(struct lg_cpu *cpu, pgd_t gpgd) * * If we fixed up the fault (ie. we mapped the address), this routine returns * true. Otherwise, it was a real fault and we need to tell the Guest. */ -bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode) +int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode) { pgd_t gpgd; pgd_t *spgd; @@ -211,7 +211,7 @@ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode) gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t); /* Toplevel not present? We can't map it in. */ if (!(pgd_flags(gpgd) & _PAGE_PRESENT)) - return false; + return 0; /* Now look at the matching shadow entry. */ spgd = spgd_addr(cpu, cpu->cpu_pgd, vaddr); @@ -222,7 +222,7 @@ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode) * simple for this corner case. */ if (!ptepage) { kill_guest(cpu, "out of memory allocating pte page"); - return false; + return 0; } /* We check that the Guest pgd is OK. */ check_gpgd(cpu, gpgd); @@ -238,16 +238,16 @@ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode) /* If this page isn't in the Guest page tables, we can't page it in. */ if (!(pte_flags(gpte) & _PAGE_PRESENT)) - return false; + return 0; /* Check they're not trying to write to a page the Guest wants * read-only (bit 2 of errcode == write). */ if ((errcode & 2) && !(pte_flags(gpte) & _PAGE_RW)) - return false; + return 0; /* User access to a kernel-only page? (bit 3 == user access) */ if ((errcode & 4) && !(pte_flags(gpte) & _PAGE_USER)) - return false; + return 0; /* Check that the Guest PTE flags are OK, and the page number is below * the pfn_limit (ie. not mapping the Launcher binary). */ @@ -283,7 +283,7 @@ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode) * manipulated, the result returned and the code complete. A small * delay and a trace of alliteration are the only indications the Guest * has that a page fault occurred at all. */ - return true; + return 1; } /*H:360 @@ -296,7 +296,7 @@ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode) * * This is a quick version which answers the question: is this virtual address * mapped by the shadow page tables, and is it writable? */ -static bool page_writable(struct lg_cpu *cpu, unsigned long vaddr) +static int page_writable(struct lg_cpu *cpu, unsigned long vaddr) { pgd_t *spgd; unsigned long flags; @@ -304,7 +304,7 @@ static bool page_writable(struct lg_cpu *cpu, unsigned long vaddr) /* Look at the current top level entry: is it present? */ spgd = spgd_addr(cpu, cpu->cpu_pgd, vaddr); if (!(pgd_flags(*spgd) & _PAGE_PRESENT)) - return false; + return 0; /* Check the flags on the pte entry itself: it must be present and * writable. */ @@ -373,10 +373,8 @@ unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr) /* First step: get the top-level Guest page table entry. */ gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t); /* Toplevel not present? We can't map it in. */ - if (!(pgd_flags(gpgd) & _PAGE_PRESENT)) { + if (!(pgd_flags(gpgd) & _PAGE_PRESENT)) kill_guest(cpu, "Bad address %#lx", vaddr); - return -1UL; - } gpte = lgread(cpu, gpte_addr(gpgd, vaddr), pte_t); if (!(pte_flags(gpte) & _PAGE_PRESENT)) diff --git a/trunk/drivers/lguest/segments.c b/trunk/drivers/lguest/segments.c index 4f15439b7f12..ec6aa3f1c36b 100644 --- a/trunk/drivers/lguest/segments.c +++ b/trunk/drivers/lguest/segments.c @@ -45,7 +45,7 @@ * "Task State Segment" which controls all kinds of delicate things. The * LGUEST_CS and LGUEST_DS entries are reserved for the Switcher, and the * the Guest can't be trusted to deal with double faults. */ -static bool ignored_gdt(unsigned int num) +static int ignored_gdt(unsigned int num) { return (num == GDT_ENTRY_TSS || num == GDT_ENTRY_LGUEST_CS diff --git a/trunk/drivers/lguest/x86/core.c b/trunk/drivers/lguest/x86/core.c index a6b717644be0..bf7942327bda 100644 --- a/trunk/drivers/lguest/x86/core.c +++ b/trunk/drivers/lguest/x86/core.c @@ -290,57 +290,6 @@ static int emulate_insn(struct lg_cpu *cpu) return 1; } -/* Our hypercalls mechanism used to be based on direct software interrupts. - * After Anthony's "Refactor hypercall infrastructure" kvm patch, we decided to - * change over to using kvm hypercalls. - * - * KVM_HYPERCALL is actually a "vmcall" instruction, which generates an invalid - * opcode fault (fault 6) on non-VT cpus, so the easiest solution seemed to be - * an *emulation approach*: if the fault was really produced by an hypercall - * (is_hypercall() does exactly this check), we can just call the corresponding - * hypercall host implementation function. - * - * But these invalid opcode faults are notably slower than software interrupts. - * So we implemented the *patching (or rewriting) approach*: every time we hit - * the KVM_HYPERCALL opcode in Guest code, we patch it to the old "int 0x1f" - * opcode, so next time the Guest calls this hypercall it will use the - * faster trap mechanism. - * - * Matias even benchmarked it to convince you: this shows the average cycle - * cost of a hypercall. For each alternative solution mentioned above we've - * made 5 runs of the benchmark: - * - * 1) direct software interrupt: 2915, 2789, 2764, 2721, 2898 - * 2) emulation technique: 3410, 3681, 3466, 3392, 3780 - * 3) patching (rewrite) technique: 2977, 2975, 2891, 2637, 2884 - * - * One two-line function is worth a 20% hypercall speed boost! - */ -static void rewrite_hypercall(struct lg_cpu *cpu) -{ - /* This are the opcodes we use to patch the Guest. The opcode for "int - * $0x1f" is "0xcd 0x1f" but vmcall instruction is 3 bytes long, so we - * complete the sequence with a NOP (0x90). */ - u8 insn[3] = {0xcd, 0x1f, 0x90}; - - __lgwrite(cpu, guest_pa(cpu, cpu->regs->eip), insn, sizeof(insn)); -} - -static bool is_hypercall(struct lg_cpu *cpu) -{ - u8 insn[3]; - - /* This must be the Guest kernel trying to do something. - * The bottom two bits of the CS segment register are the privilege - * level. */ - if ((cpu->regs->cs & 3) != GUEST_PL) - return false; - - /* Is it a vmcall? */ - __lgread(cpu, insn, guest_pa(cpu, cpu->regs->eip), sizeof(insn)); - return insn[0] == 0x0f && insn[1] == 0x01 && insn[2] == 0xc1; -} - /*H:050 Once we've re-enabled interrupts, we look at why the Guest exited. */ void lguest_arch_handle_trap(struct lg_cpu *cpu) { @@ -388,7 +337,7 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu) break; case 32 ... 255: /* These values mean a real interrupt occurred, in which case - * the Host handler has already been run. We just do a + * the Host handler has already been run. We just do a * friendly check if another process should now be run, then * return to run the Guest again */ cond_resched(); @@ -398,15 +347,6 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu) * up the pointer now to indicate a hypercall is pending. */ cpu->hcall = (struct hcall_args *)cpu->regs; return; - case 6: - /* kvm hypercalls trigger an invalid opcode fault (6). - * We need to check if ring == GUEST_PL and - * faulting instruction == vmcall. */ - if (is_hypercall(cpu)) { - rewrite_hypercall(cpu); - return; - } - break; } /* We didn't handle the trap, so it needs to go to the Guest. */ diff --git a/trunk/drivers/macintosh/therm_adt746x.c b/trunk/drivers/macintosh/therm_adt746x.c index c0621d50c8a0..82607add69a9 100644 --- a/trunk/drivers/macintosh/therm_adt746x.c +++ b/trunk/drivers/macintosh/therm_adt746x.c @@ -498,8 +498,8 @@ static ssize_t store_##name(struct device *dev, struct device_attribute *attr, c #define BUILD_STORE_FUNC_INT(name, data) \ static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \ { \ - int val; \ - val = simple_strtol(buf, NULL, 10); \ + u32 val; \ + val = simple_strtoul(buf, NULL, 10); \ if (val < 0 || val > 255) \ return -EINVAL; \ printk(KERN_INFO "Setting specified fan speed to %d\n", val); \ diff --git a/trunk/drivers/media/Kconfig b/trunk/drivers/media/Kconfig index 223c36ede5ae..93ea201f426c 100644 --- a/trunk/drivers/media/Kconfig +++ b/trunk/drivers/media/Kconfig @@ -117,7 +117,7 @@ source "drivers/media/dvb/Kconfig" config DAB boolean "DAB adapters" ---help--- - Allow selecting support for Digital Audio Broadcasting (DAB) + Allow selecting support for for Digital Audio Broadcasting (DAB) Receiver adapters. if DAB diff --git a/trunk/drivers/media/common/ir-keymaps.c b/trunk/drivers/media/common/ir-keymaps.c index 3fe158ac7bbf..d8229a0e9a9c 100644 --- a/trunk/drivers/media/common/ir-keymaps.c +++ b/trunk/drivers/media/common/ir-keymaps.c @@ -153,65 +153,6 @@ IR_KEYTAB_TYPE ir_codes_avermedia_m135a[IR_KEYTAB_SIZE] = { }; EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a); -/* Oldrich Jedlicka */ -IR_KEYTAB_TYPE ir_codes_avermedia_cardbus[IR_KEYTAB_SIZE] = { - [0x00] = KEY_POWER, - [0x01] = KEY_TUNER, /* TV/FM */ - [0x03] = KEY_TEXT, /* Teletext */ - [0x04] = KEY_EPG, - [0x05] = KEY_1, - [0x06] = KEY_2, - [0x07] = KEY_3, - [0x08] = KEY_AUDIO, - [0x09] = KEY_4, - [0x0a] = KEY_5, - [0x0b] = KEY_6, - [0x0c] = KEY_ZOOM, /* Full screen */ - [0x0d] = KEY_7, - [0x0e] = KEY_8, - [0x0f] = KEY_9, - [0x10] = KEY_PAGEUP, /* 16-CH PREV */ - [0x11] = KEY_0, - [0x12] = KEY_INFO, - [0x13] = KEY_AGAIN, /* CH RTN - channel return */ - [0x14] = KEY_MUTE, - [0x15] = KEY_EDIT, /* Autoscan */ - [0x17] = KEY_SAVE, /* Screenshot */ - [0x18] = KEY_PLAYPAUSE, - [0x19] = KEY_RECORD, - [0x1a] = KEY_PLAY, - [0x1b] = KEY_STOP, - [0x1c] = KEY_FASTFORWARD, - [0x1d] = KEY_REWIND, - [0x1e] = KEY_VOLUMEDOWN, - [0x1f] = KEY_VOLUMEUP, - [0x22] = KEY_SLEEP, /* Sleep */ - [0x23] = KEY_ZOOM, /* Aspect */ - [0x26] = KEY_SCREEN, /* Pos */ - [0x27] = KEY_ANGLE, /* Size */ - [0x28] = KEY_SELECT, /* Select */ - [0x29] = KEY_BLUE, /* Blue/Picture */ - [0x2a] = KEY_BACKSPACE, /* Back */ - [0x2b] = KEY_MEDIA, /* PIP (Picture-in-picture) */ - [0x2c] = KEY_DOWN, - [0x2e] = KEY_DOT, - [0x2f] = KEY_TV, /* Live TV */ - [0x32] = KEY_LEFT, - [0x33] = KEY_CLEAR, /* Clear */ - [0x35] = KEY_RED, /* Red/TV */ - [0x36] = KEY_UP, - [0x37] = KEY_HOME, /* Home */ - [0x39] = KEY_GREEN, /* Green/Video */ - [0x3d] = KEY_YELLOW, /* Yellow/Music */ - [0x3e] = KEY_OK, /* Ok */ - [0x3f] = KEY_RIGHT, - [0x40] = KEY_NEXT, /* Next */ - [0x41] = KEY_PREVIOUS, /* Previous */ - [0x42] = KEY_CHANNELDOWN, /* Channel down */ - [0x43] = KEY_CHANNELUP /* Channel up */ -}; -EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus); - /* Attila Kondoros */ IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { @@ -2511,55 +2452,6 @@ IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE] = { }; EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog); -/* Kaiomy TVnPC U2 - Mauro Carvalho Chehab - */ -IR_KEYTAB_TYPE ir_codes_kaiomy[IR_KEYTAB_SIZE] = { - [0x43] = KEY_POWER2, - [0x01] = KEY_LIST, - [0x0b] = KEY_ZOOM, - [0x03] = KEY_POWER, - - [0x04] = KEY_1, - [0x08] = KEY_2, - [0x02] = KEY_3, - - [0x0f] = KEY_4, - [0x05] = KEY_5, - [0x06] = KEY_6, - - [0x0c] = KEY_7, - [0x0d] = KEY_8, - [0x0a] = KEY_9, - - [0x11] = KEY_0, - - [0x09] = KEY_CHANNELUP, - [0x07] = KEY_CHANNELDOWN, - - [0x0e] = KEY_VOLUMEUP, - [0x13] = KEY_VOLUMEDOWN, - - [0x10] = KEY_HOME, - [0x12] = KEY_ENTER, - - [0x14] = KEY_RECORD, - [0x15] = KEY_STOP, - [0x16] = KEY_PLAY, - [0x17] = KEY_MUTE, - - [0x18] = KEY_UP, - [0x19] = KEY_DOWN, - [0x1a] = KEY_LEFT, - [0x1b] = KEY_RIGHT, - - [0x1c] = KEY_RED, - [0x1d] = KEY_GREEN, - [0x1e] = KEY_YELLOW, - [0x1f] = KEY_BLUE, -}; -EXPORT_SYMBOL_GPL(ir_codes_kaiomy); - IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = { [0x20] = KEY_LIST, [0x00] = KEY_POWER, @@ -2712,41 +2604,3 @@ IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE] = { }; EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600); - -/* DVBWorld remotes - Igor M. Liplianin - */ -IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE] = { - [0x0a] = KEY_Q, /*power*/ - [0x0c] = KEY_M, /*mute*/ - [0x11] = KEY_1, - [0x12] = KEY_2, - [0x13] = KEY_3, - [0x14] = KEY_4, - [0x15] = KEY_5, - [0x16] = KEY_6, - [0x17] = KEY_7, - [0x18] = KEY_8, - [0x19] = KEY_9, - [0x10] = KEY_0, - [0x1c] = KEY_PAGEUP, /*ch+*/ - [0x0f] = KEY_PAGEDOWN, /*ch-*/ - [0x1a] = KEY_O, /*vol+*/ - [0x0e] = KEY_Z, /*vol-*/ - [0x04] = KEY_R, /*rec*/ - [0x09] = KEY_D, /*fav*/ - [0x08] = KEY_BACKSPACE, /*rewind*/ - [0x07] = KEY_A, /*fast*/ - [0x0b] = KEY_P, /*pause*/ - [0x02] = KEY_ESC, /*cancel*/ - [0x03] = KEY_G, /*tab*/ - [0x00] = KEY_UP, /*up*/ - [0x1f] = KEY_ENTER, /*ok*/ - [0x01] = KEY_DOWN, /*down*/ - [0x05] = KEY_C, /*cap*/ - [0x06] = KEY_S, /*stop*/ - [0x40] = KEY_F, /*full*/ - [0x1e] = KEY_W, /*tvmode*/ - [0x1b] = KEY_B, /*recall*/ -}; -EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec); diff --git a/trunk/drivers/media/common/saa7146_core.c b/trunk/drivers/media/common/saa7146_core.c index 982f000a57ff..d599d360da3f 100644 --- a/trunk/drivers/media/common/saa7146_core.c +++ b/trunk/drivers/media/common/saa7146_core.c @@ -452,6 +452,8 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device)); dev->ext = ext; + pci_set_drvdata(pci, dev); + mutex_init(&dev->lock); spin_lock_init(&dev->int_slock); spin_lock_init(&dev->slock); @@ -475,12 +477,8 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent if (ext->attach(dev, pci_ext)) { DEB_D(("ext->attach() failed for %p. skipping device.\n",dev)); - goto err_free_i2c; + goto err_unprobe; } - /* V4L extensions will set the pci drvdata to the v4l2_device in the - attach() above. So for those cards that do not use V4L we have to - set it explicitly. */ - pci_set_drvdata(pci, &dev->v4l2_dev); INIT_LIST_HEAD(&dev->item); list_add_tail(&dev->item,&saa7146_devices); @@ -490,6 +488,8 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent out: return err; +err_unprobe: + pci_set_drvdata(pci, NULL); err_free_i2c: pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle); @@ -514,8 +514,7 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent static void saa7146_remove_one(struct pci_dev *pdev) { - struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); - struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev); + struct saa7146_dev* dev = pci_get_drvdata(pdev); struct { void *addr; dma_addr_t dma; @@ -529,8 +528,6 @@ static void saa7146_remove_one(struct pci_dev *pdev) DEB_EE(("dev:%p\n",dev)); dev->ext->detach(dev); - /* Zero the PCI drvdata after use. */ - pci_set_drvdata(pdev, NULL); /* shut down all video dma transfers */ saa7146_write(dev, MC1, 0x00ff0000); diff --git a/trunk/drivers/media/common/saa7146_fops.c b/trunk/drivers/media/common/saa7146_fops.c index 620f655fa9c5..cf06f4d10ad4 100644 --- a/trunk/drivers/media/common/saa7146_fops.c +++ b/trunk/drivers/media/common/saa7146_fops.c @@ -308,6 +308,14 @@ static int fops_release(struct file *file) return 0; } +static long fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ +/* + DEB_EE(("file:%p, cmd:%d, arg:%li\n", file, cmd, arg)); +*/ + return video_usercopy(file, cmd, arg, saa7146_video_do_ioctl); +} + static int fops_mmap(struct file *file, struct vm_area_struct * vma) { struct saa7146_fh *fh = file->private_data; @@ -417,7 +425,7 @@ static const struct v4l2_file_operations video_fops = .write = fops_write, .poll = fops_poll, .mmap = fops_mmap, - .ioctl = video_ioctl2, + .ioctl = fops_ioctl, }; static void vv_callback(struct saa7146_dev *dev, unsigned long status) @@ -444,22 +452,19 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status) } } -int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) +static struct video_device device_template = { - struct saa7146_vv *vv; - int err; - - err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev); - if (err) - return err; + .fops = &video_fops, + .minor = -1, +}; - vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL); - if (vv == NULL) { +int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) +{ + struct saa7146_vv *vv = kzalloc (sizeof(struct saa7146_vv),GFP_KERNEL); + if( NULL == vv ) { ERR(("out of memory. aborting.\n")); - return -ENOMEM; + return -1; } - ext_vv->ops = saa7146_video_ioctl_ops; - ext_vv->core_ops = &saa7146_video_ioctl_ops; DEB_EE(("dev:%p\n",dev)); @@ -502,7 +507,6 @@ int saa7146_vv_release(struct saa7146_dev* dev) DEB_EE(("dev:%p\n",dev)); - v4l2_device_unregister(&dev->v4l2_dev); pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle); kfree(vv); dev->vv_data = NULL; @@ -517,8 +521,6 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, { struct saa7146_vv *vv = dev->vv_data; struct video_device *vfd; - int err; - int i; DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type)); @@ -527,20 +529,16 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, if (vfd == NULL) return -ENOMEM; - vfd->fops = &video_fops; - vfd->ioctl_ops = &dev->ext_vv_data->ops; - vfd->release = video_device_release; - vfd->tvnorms = 0; - for (i = 0; i < dev->ext_vv_data->num_stds; i++) - vfd->tvnorms |= dev->ext_vv_data->stds[i].id; + memcpy(vfd, &device_template, sizeof(struct video_device)); strlcpy(vfd->name, name, sizeof(vfd->name)); + vfd->release = video_device_release; video_set_drvdata(vfd, dev); - err = video_register_device(vfd, type, -1); - if (err < 0) { + // fixme: -1 should be an insmod parameter *for the extension* (like "video_nr"); + if (video_register_device(vfd, type, -1) < 0) { ERR(("cannot register v4l2 device. skipping.\n")); video_device_release(vfd); - return err; + return -1; } if( VFL_TYPE_GRABBER == type ) { diff --git a/trunk/drivers/media/common/saa7146_i2c.c b/trunk/drivers/media/common/saa7146_i2c.c index 7e8f56815998..c11da4d09cd0 100644 --- a/trunk/drivers/media/common/saa7146_i2c.c +++ b/trunk/drivers/media/common/saa7146_i2c.c @@ -293,6 +293,7 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m int i = 0, count = 0; __le32 *buffer = dev->d_i2c.cpu_addr; int err = 0; + int address_err = 0; int short_delay = 0; if (mutex_lock_interruptible(&dev->i2c_lock)) @@ -332,10 +333,17 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m i2c address probing, however, and address errors indicate that a device is really *not* there. retrying in that case increases the time the device needs to probe greatly, so - it should be avoided. So we bail out in irq mode after an - address error and trust the saa7146 address error detection. */ - if (-EREMOTEIO == err && 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) - goto out; + it should be avoided. because of the fact, that only + analog based cards use irq based i2c transactions (for dvb + cards, this screwes up other interrupt sources), we bail out + completely for analog cards after an address error and trust + the saa7146 address error detection. */ + if ( -EREMOTEIO == err ) { + if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) { + goto out; + } + address_err++; + } DEB_I2C(("error while sending message(s). starting again.\n")); break; } @@ -350,9 +358,10 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m } while (err != num && retries--); - /* quit if any error occurred */ - if (err != num) + /* if every retry had an address error, exit right away */ + if (address_err == retries) { goto out; + } /* if any things had to be read, get the results */ if ( 0 != saa7146_i2c_msg_cleanup(msgs, num, buffer)) { @@ -381,8 +390,7 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m /* utility functions */ static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num) { - struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter); - struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev); + struct saa7146_dev* dev = i2c_get_adapdata(adapter); /* use helper function to transfer data */ return saa7146_i2c_transfer(dev, msg, num, adapter->retries); @@ -409,8 +417,9 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c dev->i2c_bitrate = bitrate; saa7146_i2c_reset(dev); - if (i2c_adapter) { - i2c_set_adapdata(i2c_adapter, &dev->v4l2_dev); + if( NULL != i2c_adapter ) { + BUG_ON(!i2c_adapter->class); + i2c_set_adapdata(i2c_adapter,dev); i2c_adapter->dev.parent = &dev->pci->dev; i2c_adapter->algo = &saa7146_algo; i2c_adapter->algo_data = NULL; diff --git a/trunk/drivers/media/common/saa7146_video.c b/trunk/drivers/media/common/saa7146_video.c index 552dab442d78..47fee05eaefb 100644 --- a/trunk/drivers/media/common/saa7146_video.c +++ b/trunk/drivers/media/common/saa7146_video.c @@ -1,5 +1,4 @@ #include -#include static int max_memory = 32; @@ -98,13 +97,172 @@ struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc) return NULL; } -static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f); +static int g_fmt(struct saa7146_fh *fh, struct v4l2_format *f) +{ + struct saa7146_dev *dev = fh->dev; + DEB_EE(("dev:%p, fh:%p\n",dev,fh)); + + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + f->fmt.pix = fh->video_fmt; + return 0; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + f->fmt.win = fh->ov.win; + return 0; + case V4L2_BUF_TYPE_VBI_CAPTURE: + { + f->fmt.vbi = fh->vbi_fmt; + return 0; + } + default: + DEB_D(("invalid format type '%d'.\n",f->type)); + return -EINVAL; + } +} + +static int try_win(struct saa7146_dev *dev, struct v4l2_window *win) +{ + struct saa7146_vv *vv = dev->vv_data; + enum v4l2_field field; + int maxw, maxh; + + DEB_EE(("dev:%p\n",dev)); + + if (NULL == vv->ov_fb.base) { + DEB_D(("no fb base set.\n")); + return -EINVAL; + } + if (NULL == vv->ov_fmt) { + DEB_D(("no fb fmt set.\n")); + return -EINVAL; + } + if (win->w.width < 48 || win->w.height < 32) { + DEB_D(("min width/height. (%d,%d)\n",win->w.width,win->w.height)); + return -EINVAL; + } + if (win->clipcount > 16) { + DEB_D(("clipcount too big.\n")); + return -EINVAL; + } + + field = win->field; + maxw = vv->standard->h_max_out; + maxh = vv->standard->v_max_out; + + if (V4L2_FIELD_ANY == field) { + field = (win->w.height > maxh/2) + ? V4L2_FIELD_INTERLACED + : V4L2_FIELD_TOP; + } + switch (field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_ALTERNATE: + maxh = maxh / 2; + break; + case V4L2_FIELD_INTERLACED: + break; + default: { + DEB_D(("no known field mode '%d'.\n",field)); + return -EINVAL; + } + } + + win->field = field; + if (win->w.width > maxw) + win->w.width = maxw; + if (win->w.height > maxh) + win->w.height = maxh; + + return 0; +} + +static int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f) +{ + struct saa7146_dev *dev = fh->dev; + struct saa7146_vv *vv = dev->vv_data; + int err; + + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + { + struct saa7146_format *fmt; + enum v4l2_field field; + int maxw, maxh; + int calc_bpl; + + DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh)); + + fmt = format_by_fourcc(dev,f->fmt.pix.pixelformat); + if (NULL == fmt) { + return -EINVAL; + } + + field = f->fmt.pix.field; + maxw = vv->standard->h_max_out; + maxh = vv->standard->v_max_out; + + if (V4L2_FIELD_ANY == field) { + field = (f->fmt.pix.height > maxh/2) + ? V4L2_FIELD_INTERLACED + : V4L2_FIELD_BOTTOM; + } + switch (field) { + case V4L2_FIELD_ALTERNATE: { + vv->last_field = V4L2_FIELD_TOP; + maxh = maxh / 2; + break; + } + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + vv->last_field = V4L2_FIELD_INTERLACED; + maxh = maxh / 2; + break; + case V4L2_FIELD_INTERLACED: + vv->last_field = V4L2_FIELD_INTERLACED; + break; + default: { + DEB_D(("no known field mode '%d'.\n",field)); + return -EINVAL; + } + } + + f->fmt.pix.field = field; + if (f->fmt.pix.width > maxw) + f->fmt.pix.width = maxw; + if (f->fmt.pix.height > maxh) + f->fmt.pix.height = maxh; + + calc_bpl = (f->fmt.pix.width * fmt->depth)/8; + + if (f->fmt.pix.bytesperline < calc_bpl) + f->fmt.pix.bytesperline = calc_bpl; + + if (f->fmt.pix.bytesperline > (2*PAGE_SIZE * fmt->depth)/8) /* arbitrary constraint */ + f->fmt.pix.bytesperline = calc_bpl; + + f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; + DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n",f->fmt.pix.width,f->fmt.pix.height,f->fmt.pix.bytesperline,f->fmt.pix.sizeimage)); + + return 0; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh)); + err = try_win(dev,&f->fmt.win); + if (0 != err) { + return err; + } + return 0; + default: + DEB_EE(("unknown format type '%d'\n",f->type)); + return -EINVAL; + } +} int saa7146_start_preview(struct saa7146_fh *fh) { struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; - struct v4l2_format fmt; int ret = 0, err = 0; DEB_EE(("dev:%p, fh:%p\n",dev,fh)); @@ -136,13 +294,12 @@ int saa7146_start_preview(struct saa7146_fh *fh) return -EBUSY; } - fmt.fmt.win = fh->ov.win; - err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt); + err = try_win(dev,&fh->ov.win); if (0 != err) { saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); return -EBUSY; } - fh->ov.win = fmt.fmt.win; + vv->ov_data = &fh->ov; DEB_D(("%dx%d+%d+%d %s field=%s\n", @@ -198,6 +355,58 @@ int saa7146_stop_preview(struct saa7146_fh *fh) } EXPORT_SYMBOL_GPL(saa7146_stop_preview); +static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f) +{ + struct saa7146_dev *dev = fh->dev; + struct saa7146_vv *vv = dev->vv_data; + + int err; + + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh)); + if (IS_CAPTURE_ACTIVE(fh) != 0) { + DEB_EE(("streaming capture is active\n")); + return -EBUSY; + } + err = try_fmt(fh,f); + if (0 != err) + return err; + fh->video_fmt = f->fmt.pix; + DEB_EE(("set to pixelformat '%4.4s'\n",(char *)&fh->video_fmt.pixelformat)); + return 0; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh)); + err = try_win(dev,&f->fmt.win); + if (0 != err) + return err; + mutex_lock(&dev->lock); + fh->ov.win = f->fmt.win; + fh->ov.nclips = f->fmt.win.clipcount; + if (fh->ov.nclips > 16) + fh->ov.nclips = 16; + if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) { + mutex_unlock(&dev->lock); + return -EFAULT; + } + + /* fh->ov.fh is used to indicate that we have valid overlay informations, too */ + fh->ov.fh = fh; + + mutex_unlock(&dev->lock); + + /* check if our current overlay is active */ + if (IS_OVERLAY_ACTIVE(fh) != 0) { + saa7146_stop_preview(fh); + saa7146_start_preview(fh); + } + return 0; + default: + DEB_D(("unknown format type '%d'\n",f->type)); + return -EINVAL; + } +} + /********************************************************************************/ /* device controls */ @@ -210,7 +419,6 @@ static struct v4l2_queryctrl controls[] = { .step = 1, .default_value = 128, .type = V4L2_CTRL_TYPE_INTEGER, - .flags = V4L2_CTRL_FLAG_SLIDER, },{ .id = V4L2_CID_CONTRAST, .name = "Contrast", @@ -219,7 +427,6 @@ static struct v4l2_queryctrl controls[] = { .step = 1, .default_value = 64, .type = V4L2_CTRL_TYPE_INTEGER, - .flags = V4L2_CTRL_FLAG_SLIDER, },{ .id = V4L2_CID_SATURATION, .name = "Saturation", @@ -228,16 +435,15 @@ static struct v4l2_queryctrl controls[] = { .step = 1, .default_value = 64, .type = V4L2_CTRL_TYPE_INTEGER, - .flags = V4L2_CTRL_FLAG_SLIDER, },{ .id = V4L2_CID_VFLIP, - .name = "Vertical Flip", + .name = "Vertical flip", .minimum = 0, .maximum = 1, .type = V4L2_CTRL_TYPE_BOOLEAN, },{ .id = V4L2_CID_HFLIP, - .name = "Horizontal Flip", + .name = "Horizontal flip", .minimum = 0, .maximum = 1, .type = V4L2_CTRL_TYPE_BOOLEAN, @@ -257,6 +463,132 @@ static struct v4l2_queryctrl* ctrl_by_id(int id) return NULL; } +static int get_control(struct saa7146_fh *fh, struct v4l2_control *c) +{ + struct saa7146_dev *dev = fh->dev; + struct saa7146_vv *vv = dev->vv_data; + + const struct v4l2_queryctrl* ctrl; + u32 value = 0; + + ctrl = ctrl_by_id(c->id); + if (NULL == ctrl) + return -EINVAL; + switch (c->id) { + case V4L2_CID_BRIGHTNESS: + value = saa7146_read(dev, BCS_CTRL); + c->value = 0xff & (value >> 24); + DEB_D(("V4L2_CID_BRIGHTNESS: %d\n",c->value)); + break; + case V4L2_CID_CONTRAST: + value = saa7146_read(dev, BCS_CTRL); + c->value = 0x7f & (value >> 16); + DEB_D(("V4L2_CID_CONTRAST: %d\n",c->value)); + break; + case V4L2_CID_SATURATION: + value = saa7146_read(dev, BCS_CTRL); + c->value = 0x7f & (value >> 0); + DEB_D(("V4L2_CID_SATURATION: %d\n",c->value)); + break; + case V4L2_CID_VFLIP: + c->value = vv->vflip; + DEB_D(("V4L2_CID_VFLIP: %d\n",c->value)); + break; + case V4L2_CID_HFLIP: + c->value = vv->hflip; + DEB_D(("V4L2_CID_HFLIP: %d\n",c->value)); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int set_control(struct saa7146_fh *fh, struct v4l2_control *c) +{ + struct saa7146_dev *dev = fh->dev; + struct saa7146_vv *vv = dev->vv_data; + + const struct v4l2_queryctrl* ctrl; + + ctrl = ctrl_by_id(c->id); + if (NULL == ctrl) { + DEB_D(("unknown control %d\n",c->id)); + return -EINVAL; + } + + mutex_lock(&dev->lock); + + switch (ctrl->type) { + case V4L2_CTRL_TYPE_BOOLEAN: + case V4L2_CTRL_TYPE_MENU: + case V4L2_CTRL_TYPE_INTEGER: + if (c->value < ctrl->minimum) + c->value = ctrl->minimum; + if (c->value > ctrl->maximum) + c->value = ctrl->maximum; + break; + default: + /* nothing */; + }; + + switch (c->id) { + case V4L2_CID_BRIGHTNESS: { + u32 value = saa7146_read(dev, BCS_CTRL); + value &= 0x00ffffff; + value |= (c->value << 24); + saa7146_write(dev, BCS_CTRL, value); + saa7146_write(dev, MC2, MASK_22 | MASK_06 ); + break; + } + case V4L2_CID_CONTRAST: { + u32 value = saa7146_read(dev, BCS_CTRL); + value &= 0xff00ffff; + value |= (c->value << 16); + saa7146_write(dev, BCS_CTRL, value); + saa7146_write(dev, MC2, MASK_22 | MASK_06 ); + break; + } + case V4L2_CID_SATURATION: { + u32 value = saa7146_read(dev, BCS_CTRL); + value &= 0xffffff00; + value |= (c->value << 0); + saa7146_write(dev, BCS_CTRL, value); + saa7146_write(dev, MC2, MASK_22 | MASK_06 ); + break; + } + case V4L2_CID_HFLIP: + /* fixme: we can support changing VFLIP and HFLIP here... */ + if (IS_CAPTURE_ACTIVE(fh) != 0) { + DEB_D(("V4L2_CID_HFLIP while active capture.\n")); + mutex_unlock(&dev->lock); + return -EINVAL; + } + vv->hflip = c->value; + break; + case V4L2_CID_VFLIP: + if (IS_CAPTURE_ACTIVE(fh) != 0) { + DEB_D(("V4L2_CID_VFLIP while active capture.\n")); + mutex_unlock(&dev->lock); + return -EINVAL; + } + vv->vflip = c->value; + break; + default: { + mutex_unlock(&dev->lock); + return -EINVAL; + } + } + mutex_unlock(&dev->lock); + + if (IS_OVERLAY_ACTIVE(fh) != 0) { + saa7146_stop_preview(fh); + saa7146_start_preview(fh); + } + return 0; +} + /********************************************************************************/ /* common pagetable functions */ @@ -497,446 +829,231 @@ static int video_end(struct saa7146_fh *fh, struct file *file) return 0; } -static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - - strcpy((char *)cap->driver, "saa7146 v4l2"); - strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); - sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci)); - cap->version = SAA7146_VERSION_CODE; - cap->capabilities = - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_VIDEO_OVERLAY | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING; - cap->capabilities |= dev->ext_vv_data->capabilities; - return 0; -} +/* + * This function is _not_ called directly, but from + * video_generic_ioctl (and maybe others). userspace + * copying is done already, arg is a kernel pointer. + */ -static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) +long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_fh *fh = file->private_data; + struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; - *fb = vv->ov_fb; - fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; - return 0; -} - -static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - struct saa7146_format *fmt; + long err = 0; + int result = 0, ee = 0; - DEB_EE(("VIDIOC_S_FBUF\n")); + struct saa7146_use_ops *ops; + struct videobuf_queue *q; - if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) - return -EPERM; + /* check if extension handles the command */ + for(ee = 0; dev->ext_vv_data->ioctls[ee].flags != 0; ee++) { + if( cmd == dev->ext_vv_data->ioctls[ee].cmd ) + break; + } - /* check args */ - fmt = format_by_fourcc(dev, fb->fmt.pixelformat); - if (NULL == fmt) - return -EINVAL; + if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) { + DEB_D(("extension handles ioctl exclusive.\n")); + result = dev->ext_vv_data->ioctl(fh, cmd, arg); + return result; + } + if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_BEFORE) ) { + DEB_D(("extension handles ioctl before.\n")); + result = dev->ext_vv_data->ioctl(fh, cmd, arg); + if( -EAGAIN != result ) { + return result; + } + } - /* planar formats are not allowed for overlay video, clipping and video dma would clash */ - if (fmt->flags & FORMAT_IS_PLANAR) - DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n", - (char *)&fmt->pixelformat)); + /* fixme: add handle "after" case (is it still needed?) */ - /* check if overlay is running */ - if (IS_OVERLAY_ACTIVE(fh) != 0) { - if (vv->video_fh != fh) { - DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n")); - return -EBUSY; - } - } - - mutex_lock(&dev->lock); - - /* ok, accept it */ - vv->ov_fb = *fb; - vv->ov_fmt = fmt; - if (0 == vv->ov_fb.fmt.bytesperline) - vv->ov_fb.fmt.bytesperline = - vv->ov_fb.fmt.width * fmt->depth / 8; - - mutex_unlock(&dev->lock); - return 0; -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) -{ - if (f->index >= NUM_FORMATS) - return -EINVAL; - strlcpy((char *)f->description, formats[f->index].name, - sizeof(f->description)); - f->pixelformat = formats[f->index].pixelformat; - return 0; -} - -static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) -{ - const struct v4l2_queryctrl *ctrl; - - if ((c->id < V4L2_CID_BASE || - c->id >= V4L2_CID_LASTP1) && - (c->id < V4L2_CID_PRIVATE_BASE || - c->id >= V4L2_CID_PRIVATE_LASTP1)) - return -EINVAL; - - ctrl = ctrl_by_id(c->id); - if (ctrl == NULL) - return -EINVAL; - - DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n", c->id)); - *c = *ctrl; - return 0; -} - -static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - const struct v4l2_queryctrl *ctrl; - u32 value = 0; - - ctrl = ctrl_by_id(c->id); - if (NULL == ctrl) - return -EINVAL; - switch (c->id) { - case V4L2_CID_BRIGHTNESS: - value = saa7146_read(dev, BCS_CTRL); - c->value = 0xff & (value >> 24); - DEB_D(("V4L2_CID_BRIGHTNESS: %d\n", c->value)); - break; - case V4L2_CID_CONTRAST: - value = saa7146_read(dev, BCS_CTRL); - c->value = 0x7f & (value >> 16); - DEB_D(("V4L2_CID_CONTRAST: %d\n", c->value)); - break; - case V4L2_CID_SATURATION: - value = saa7146_read(dev, BCS_CTRL); - c->value = 0x7f & (value >> 0); - DEB_D(("V4L2_CID_SATURATION: %d\n", c->value)); - break; - case V4L2_CID_VFLIP: - c->value = vv->vflip; - DEB_D(("V4L2_CID_VFLIP: %d\n", c->value)); - break; - case V4L2_CID_HFLIP: - c->value = vv->hflip; - DEB_D(("V4L2_CID_HFLIP: %d\n", c->value)); - break; - default: - return -EINVAL; - } - return 0; -} - -static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - const struct v4l2_queryctrl *ctrl; - - ctrl = ctrl_by_id(c->id); - if (NULL == ctrl) { - DEB_D(("unknown control %d\n", c->id)); - return -EINVAL; - } - - mutex_lock(&dev->lock); - - switch (ctrl->type) { - case V4L2_CTRL_TYPE_BOOLEAN: - case V4L2_CTRL_TYPE_MENU: - case V4L2_CTRL_TYPE_INTEGER: - if (c->value < ctrl->minimum) - c->value = ctrl->minimum; - if (c->value > ctrl->maximum) - c->value = ctrl->maximum; - break; - default: - /* nothing */; - } - - switch (c->id) { - case V4L2_CID_BRIGHTNESS: { - u32 value = saa7146_read(dev, BCS_CTRL); - value &= 0x00ffffff; - value |= (c->value << 24); - saa7146_write(dev, BCS_CTRL, value); - saa7146_write(dev, MC2, MASK_22 | MASK_06); - break; - } - case V4L2_CID_CONTRAST: { - u32 value = saa7146_read(dev, BCS_CTRL); - value &= 0xff00ffff; - value |= (c->value << 16); - saa7146_write(dev, BCS_CTRL, value); - saa7146_write(dev, MC2, MASK_22 | MASK_06); + switch (fh->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + ops = &saa7146_video_uops; + q = &fh->video_q; break; - } - case V4L2_CID_SATURATION: { - u32 value = saa7146_read(dev, BCS_CTRL); - value &= 0xffffff00; - value |= (c->value << 0); - saa7146_write(dev, BCS_CTRL, value); - saa7146_write(dev, MC2, MASK_22 | MASK_06); - break; - } - case V4L2_CID_HFLIP: - /* fixme: we can support changing VFLIP and HFLIP here... */ - if (IS_CAPTURE_ACTIVE(fh) != 0) { - DEB_D(("V4L2_CID_HFLIP while active capture.\n")); - mutex_unlock(&dev->lock); - return -EBUSY; } - vv->hflip = c->value; + case V4L2_BUF_TYPE_VBI_CAPTURE: { + ops = &saa7146_vbi_uops; + q = &fh->vbi_q; break; - case V4L2_CID_VFLIP: - if (IS_CAPTURE_ACTIVE(fh) != 0) { - DEB_D(("V4L2_CID_VFLIP while active capture.\n")); - mutex_unlock(&dev->lock); - return -EBUSY; } - vv->vflip = c->value; - break; default: - mutex_unlock(&dev->lock); - return -EINVAL; + BUG(); + return 0; } - mutex_unlock(&dev->lock); - if (IS_OVERLAY_ACTIVE(fh) != 0) { - saa7146_stop_preview(fh); - saa7146_start_preview(fh); + switch (cmd) { + case VIDIOC_QUERYCAP: + { + struct v4l2_capability *cap = arg; + memset(cap,0,sizeof(*cap)); + + DEB_EE(("VIDIOC_QUERYCAP\n")); + + strcpy((char *)cap->driver, "saa7146 v4l2"); + strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); + sprintf((char *)cap->bus_info,"PCI:%s", pci_name(dev->pci)); + cap->version = SAA7146_VERSION_CODE; + cap->capabilities = + V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_VIDEO_OVERLAY | + V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING; + cap->capabilities |= dev->ext_vv_data->capabilities; + return 0; } - return 0; -} - -static int vidioc_g_parm(struct file *file, void *fh, - struct v4l2_streamparm *parm) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - - parm->parm.capture.readbuffers = 1; - v4l2_video_std_frame_period(vv->standard->id, - &parm->parm.capture.timeperframe); - return 0; -} - -static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) -{ - f->fmt.pix = ((struct saa7146_fh *)fh)->video_fmt; - return 0; -} - -static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) -{ - f->fmt.win = ((struct saa7146_fh *)fh)->ov.win; - return 0; -} - -static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f) -{ - f->fmt.vbi = ((struct saa7146_fh *)fh)->vbi_fmt; - return 0; -} + case VIDIOC_G_FBUF: + { + struct v4l2_framebuffer *fb = arg; -static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - struct saa7146_format *fmt; - enum v4l2_field field; - int maxw, maxh; - int calc_bpl; + DEB_EE(("VIDIOC_G_FBUF\n")); - DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh)); + *fb = vv->ov_fb; + fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; + return 0; + } + case VIDIOC_S_FBUF: + { + struct v4l2_framebuffer *fb = arg; + struct saa7146_format *fmt; - fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat); - if (NULL == fmt) - return -EINVAL; + DEB_EE(("VIDIOC_S_FBUF\n")); - field = f->fmt.pix.field; - maxw = vv->standard->h_max_out; - maxh = vv->standard->v_max_out; + if(!capable(CAP_SYS_ADMIN) && + !capable(CAP_SYS_RAWIO)) + return -EPERM; - if (V4L2_FIELD_ANY == field) { - field = (f->fmt.pix.height > maxh / 2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_BOTTOM; - } - switch (field) { - case V4L2_FIELD_ALTERNATE: - vv->last_field = V4L2_FIELD_TOP; - maxh = maxh / 2; - break; - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - vv->last_field = V4L2_FIELD_INTERLACED; - maxh = maxh / 2; - break; - case V4L2_FIELD_INTERLACED: - vv->last_field = V4L2_FIELD_INTERLACED; - break; - default: - DEB_D(("no known field mode '%d'.\n", field)); - return -EINVAL; - } + /* check args */ + fmt = format_by_fourcc(dev,fb->fmt.pixelformat); + if (NULL == fmt) { + return -EINVAL; + } - f->fmt.pix.field = field; - if (f->fmt.pix.width > maxw) - f->fmt.pix.width = maxw; - if (f->fmt.pix.height > maxh) - f->fmt.pix.height = maxh; + /* planar formats are not allowed for overlay video, clipping and video dma would clash */ + if (0 != (fmt->flags & FORMAT_IS_PLANAR)) { + DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",(char *)&fmt->pixelformat)); + } - calc_bpl = (f->fmt.pix.width * fmt->depth) / 8; + /* check if overlay is running */ + if (IS_OVERLAY_ACTIVE(fh) != 0) { + if (vv->video_fh != fh) { + DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n")); + return -EBUSY; + } + } - if (f->fmt.pix.bytesperline < calc_bpl) - f->fmt.pix.bytesperline = calc_bpl; + mutex_lock(&dev->lock); - if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */ - f->fmt.pix.bytesperline = calc_bpl; + /* ok, accept it */ + vv->ov_fb = *fb; + vv->ov_fmt = fmt; + if (0 == vv->ov_fb.fmt.bytesperline) + vv->ov_fb.fmt.bytesperline = + vv->ov_fb.fmt.width*fmt->depth/8; - f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; - DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n", f->fmt.pix.width, - f->fmt.pix.height, f->fmt.pix.bytesperline, f->fmt.pix.sizeimage)); + mutex_unlock(&dev->lock); - return 0; -} + return 0; + } + case VIDIOC_ENUM_FMT: + { + struct v4l2_fmtdesc *f = arg; + + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + if (f->index >= NUM_FORMATS) + return -EINVAL; + strlcpy((char *)f->description, formats[f->index].name, + sizeof(f->description)); + f->pixelformat = formats[f->index].pixelformat; + f->flags = 0; + memset(f->reserved, 0, sizeof(f->reserved)); + break; + default: + return -EINVAL; + } + DEB_EE(("VIDIOC_ENUM_FMT: type:%d, index:%d\n",f->type,f->index)); + return 0; + } + case VIDIOC_QUERYCTRL: + { + const struct v4l2_queryctrl *ctrl; + struct v4l2_queryctrl *c = arg; -static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - struct v4l2_window *win = &f->fmt.win; - enum v4l2_field field; - int maxw, maxh; + if ((c->id < V4L2_CID_BASE || + c->id >= V4L2_CID_LASTP1) && + (c->id < V4L2_CID_PRIVATE_BASE || + c->id >= V4L2_CID_PRIVATE_LASTP1)) + return -EINVAL; - DEB_EE(("dev:%p\n", dev)); + ctrl = ctrl_by_id(c->id); + if( NULL == ctrl ) { + return -EINVAL; +/* + c->flags = V4L2_CTRL_FLAG_DISABLED; + return 0; +*/ + } - if (NULL == vv->ov_fb.base) { - DEB_D(("no fb base set.\n")); - return -EINVAL; + DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n",c->id)); + *c = *ctrl; + return 0; } - if (NULL == vv->ov_fmt) { - DEB_D(("no fb fmt set.\n")); - return -EINVAL; + case VIDIOC_G_CTRL: { + DEB_EE(("VIDIOC_G_CTRL\n")); + return get_control(fh,arg); } - if (win->w.width < 48 || win->w.height < 32) { - DEB_D(("min width/height. (%d,%d)\n", win->w.width, win->w.height)); - return -EINVAL; - } - if (win->clipcount > 16) { - DEB_D(("clipcount too big.\n")); - return -EINVAL; + case VIDIOC_S_CTRL: + { + DEB_EE(("VIDIOC_S_CTRL\n")); + err = set_control(fh,arg); + return err; } - - field = win->field; - maxw = vv->standard->h_max_out; - maxh = vv->standard->v_max_out; - - if (V4L2_FIELD_ANY == field) { - field = (win->w.height > maxh / 2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_TOP; + case VIDIOC_G_PARM: + { + struct v4l2_streamparm *parm = arg; + if( parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ) { + return -EINVAL; } - switch (field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - case V4L2_FIELD_ALTERNATE: - maxh = maxh / 2; - break; - case V4L2_FIELD_INTERLACED: - break; - default: - DEB_D(("no known field mode '%d'.\n", field)); - return -EINVAL; + memset(&parm->parm.capture,0,sizeof(struct v4l2_captureparm)); + parm->parm.capture.readbuffers = 1; + // fixme: only for PAL! + parm->parm.capture.timeperframe.numerator = 1; + parm->parm.capture.timeperframe.denominator = 25; + return 0; } - - win->field = field; - if (win->w.width > maxw) - win->w.width = maxw; - if (win->w.height > maxh) - win->w.height = maxh; - - return 0; -} - -static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f) -{ - struct saa7146_fh *fh = __fh; - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - int err; - - DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh)); - if (IS_CAPTURE_ACTIVE(fh) != 0) { - DEB_EE(("streaming capture is active\n")); - return -EBUSY; + case VIDIOC_G_FMT: + { + struct v4l2_format *f = arg; + DEB_EE(("VIDIOC_G_FMT\n")); + return g_fmt(fh,f); } - err = vidioc_try_fmt_vid_cap(file, fh, f); - if (0 != err) - return err; - fh->video_fmt = f->fmt.pix; - DEB_EE(("set to pixelformat '%4.4s'\n", (char *)&fh->video_fmt.pixelformat)); - return 0; -} - -static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f) -{ - struct saa7146_fh *fh = __fh; - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - int err; - - DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh)); - err = vidioc_try_fmt_vid_overlay(file, fh, f); - if (0 != err) - return err; - mutex_lock(&dev->lock); - fh->ov.win = f->fmt.win; - fh->ov.nclips = f->fmt.win.clipcount; - if (fh->ov.nclips > 16) - fh->ov.nclips = 16; - if (copy_from_user(fh->ov.clips, f->fmt.win.clips, - sizeof(struct v4l2_clip) * fh->ov.nclips)) { - mutex_unlock(&dev->lock); - return -EFAULT; + case VIDIOC_S_FMT: + { + struct v4l2_format *f = arg; + DEB_EE(("VIDIOC_S_FMT\n")); + return s_fmt(fh,f); } - - /* fh->ov.fh is used to indicate that we have valid overlay informations, too */ - fh->ov.fh = fh; - - mutex_unlock(&dev->lock); - - /* check if our current overlay is active */ - if (IS_OVERLAY_ACTIVE(fh) != 0) { - saa7146_stop_preview(fh); - saa7146_start_preview(fh); + case VIDIOC_TRY_FMT: + { + struct v4l2_format *f = arg; + DEB_EE(("VIDIOC_TRY_FMT\n")); + return try_fmt(fh,f); + } + case VIDIOC_G_STD: + { + v4l2_std_id *id = arg; + DEB_EE(("VIDIOC_G_STD\n")); + *id = vv->standard->id; + return 0; } - return 0; -} - -static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - - *norm = vv->standard->id; - return 0; -} - /* the saa7146 supfhrts (used in conjunction with the saa7111a for example) PAL / NTSC / SECAM. if your hardware does not (or does more) -- override this function in your extension */ -/* case VIDIOC_ENUMSTD: { struct v4l2_standard *e = arg; @@ -949,245 +1066,162 @@ static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm) } return -EINVAL; } - */ + case VIDIOC_S_STD: + { + v4l2_std_id *id = arg; + int found = 0; + int i; -static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - int found = 0; - int err, i; + DEB_EE(("VIDIOC_S_STD\n")); - DEB_EE(("VIDIOC_S_STD\n")); + if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) { + DEB_D(("cannot change video standard while streaming capture is active\n")); + return -EBUSY; + } - if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) { - DEB_D(("cannot change video standard while streaming capture is active\n")); - return -EBUSY; - } + if ((vv->video_status & STATUS_OVERLAY) != 0) { + vv->ov_suspend = vv->video_fh; + err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ + if (0 != err) { + DEB_D(("suspending video failed. aborting\n")); + return err; + } + } - if ((vv->video_status & STATUS_OVERLAY) != 0) { - vv->ov_suspend = vv->video_fh; - err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ - if (0 != err) { - DEB_D(("suspending video failed. aborting\n")); - return err; + mutex_lock(&dev->lock); + + for(i = 0; i < dev->ext_vv_data->num_stds; i++) + if (*id & dev->ext_vv_data->stds[i].id) + break; + if (i != dev->ext_vv_data->num_stds) { + vv->standard = &dev->ext_vv_data->stds[i]; + if( NULL != dev->ext_vv_data->std_callback ) + dev->ext_vv_data->std_callback(dev, vv->standard); + found = 1; } - } - mutex_lock(&dev->lock); + mutex_unlock(&dev->lock); - for (i = 0; i < dev->ext_vv_data->num_stds; i++) - if (*id & dev->ext_vv_data->stds[i].id) - break; - if (i != dev->ext_vv_data->num_stds) { - vv->standard = &dev->ext_vv_data->stds[i]; - if (NULL != dev->ext_vv_data->std_callback) - dev->ext_vv_data->std_callback(dev, vv->standard); - found = 1; - } + if (vv->ov_suspend != NULL) { + saa7146_start_preview(vv->ov_suspend); + vv->ov_suspend = NULL; + } - mutex_unlock(&dev->lock); + if( 0 == found ) { + DEB_EE(("VIDIOC_S_STD: standard not found.\n")); + return -EINVAL; + } - if (vv->ov_suspend != NULL) { - saa7146_start_preview(vv->ov_suspend); - vv->ov_suspend = NULL; + DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n",vv->standard->name)); + return 0; } + case VIDIOC_OVERLAY: + { + int on = *(int *)arg; - if (!found) { - DEB_EE(("VIDIOC_S_STD: standard not found.\n")); - return -EINVAL; + DEB_D(("VIDIOC_OVERLAY on:%d\n",on)); + if (on != 0) { + err = saa7146_start_preview(fh); + } else { + err = saa7146_stop_preview(fh); + } + return err; } + case VIDIOC_REQBUFS: { + struct v4l2_requestbuffers *req = arg; + DEB_D(("VIDIOC_REQBUFS, type:%d\n",req->type)); + return videobuf_reqbufs(q,req); + } + case VIDIOC_QUERYBUF: { + struct v4l2_buffer *buf = arg; + DEB_D(("VIDIOC_QUERYBUF, type:%d, offset:%d\n",buf->type,buf->m.offset)); + return videobuf_querybuf(q,buf); + } + case VIDIOC_QBUF: { + struct v4l2_buffer *buf = arg; + int ret = 0; + ret = videobuf_qbuf(q,buf); + DEB_D(("VIDIOC_QBUF: ret:%d, index:%d\n",ret,buf->index)); + return ret; + } + case VIDIOC_DQBUF: { + struct v4l2_buffer *buf = arg; + int ret = 0; + ret = videobuf_dqbuf(q,buf,file->f_flags & O_NONBLOCK); + DEB_D(("VIDIOC_DQBUF: ret:%d, index:%d\n",ret,buf->index)); + return ret; + } + case VIDIOC_STREAMON: { + int *type = arg; + DEB_D(("VIDIOC_STREAMON, type:%d\n",*type)); - DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name)); - return 0; -} - -static int vidioc_overlay(struct file *file, void *fh, unsigned int on) -{ - int err; - - DEB_D(("VIDIOC_OVERLAY on:%d\n", on)); - if (on) - err = saa7146_start_preview(fh); - else - err = saa7146_stop_preview(fh); - return err; -} - -static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b) -{ - struct saa7146_fh *fh = __fh; - - if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - return videobuf_reqbufs(&fh->video_q, b); - if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE) - return videobuf_reqbufs(&fh->vbi_q, b); - return -EINVAL; -} - -static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf) -{ - struct saa7146_fh *fh = __fh; - - if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - return videobuf_querybuf(&fh->video_q, buf); - if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) - return videobuf_querybuf(&fh->vbi_q, buf); - return -EINVAL; -} - -static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) -{ - struct saa7146_fh *fh = __fh; - - if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - return videobuf_qbuf(&fh->video_q, buf); - if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) - return videobuf_qbuf(&fh->vbi_q, buf); - return -EINVAL; -} - -static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) -{ - struct saa7146_fh *fh = __fh; - - if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK); - if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) - return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK); - return -EINVAL; -} - -static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type) -{ - struct saa7146_fh *fh = __fh; - int err; - - DEB_D(("VIDIOC_STREAMON, type:%d\n", type)); - - err = video_begin(fh); - if (err) + err = video_begin(fh); + if( 0 != err) { + return err; + } + err = videobuf_streamon(q); return err; - if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - return videobuf_streamon(&fh->video_q); - if (type == V4L2_BUF_TYPE_VBI_CAPTURE) - return videobuf_streamon(&fh->vbi_q); - return -EINVAL; -} - -static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type) -{ - struct saa7146_fh *fh = __fh; - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - int err; - - DEB_D(("VIDIOC_STREAMOFF, type:%d\n", type)); - - /* ugly: we need to copy some checks from video_end(), - because videobuf_streamoff() relies on the capture running. - check and fix this */ - if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) { - DEB_S(("not capturing.\n")); - return 0; } + case VIDIOC_STREAMOFF: { + int *type = arg; - if (vv->video_fh != fh) { - DEB_S(("capturing, but in another open.\n")); - return -EBUSY; - } + DEB_D(("VIDIOC_STREAMOFF, type:%d\n",*type)); - err = -EINVAL; - if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - err = videobuf_streamoff(&fh->video_q); - else if (type == V4L2_BUF_TYPE_VBI_CAPTURE) - err = videobuf_streamoff(&fh->vbi_q); - if (0 != err) { - DEB_D(("warning: videobuf_streamoff() failed.\n")); - video_end(fh, file); - } else { - err = video_end(fh, file); - } - return err; -} + /* ugly: we need to copy some checks from video_end(), + because videobuf_streamoff() relies on the capture running. + check and fix this */ + if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) { + DEB_S(("not capturing.\n")); + return 0; + } -static int vidioc_g_chip_ident(struct file *file, void *__fh, - struct v4l2_dbg_chip_ident *chip) -{ - struct saa7146_fh *fh = __fh; - struct saa7146_dev *dev = fh->dev; + if (vv->video_fh != fh) { + DEB_S(("capturing, but in another open.\n")); + return -EBUSY; + } - chip->ident = V4L2_IDENT_NONE; - chip->revision = 0; - if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) { - chip->ident = V4L2_IDENT_SAA7146; - return 0; + err = videobuf_streamoff(q); + if (0 != err) { + DEB_D(("warning: videobuf_streamoff() failed.\n")); + video_end(fh, file); + } else { + err = video_end(fh, file); + } + return err; } - return v4l2_device_call_until_err(&dev->v4l2_dev, 0, - core, g_chip_ident, chip); -} - #ifdef CONFIG_VIDEO_V4L1_COMPAT -static int vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *mbuf) -{ - struct saa7146_fh *fh = __fh; - struct videobuf_queue *q = &fh->video_q; - int err, i; + case VIDIOCGMBUF: + { + struct video_mbuf *mbuf = arg; + int i; - /* fixme: number of capture buffers and sizes for v4l apps */ - int gbuffers = 2; - int gbufsize = 768 * 576 * 4; + /* fixme: number of capture buffers and sizes for v4l apps */ + int gbuffers = 2; + int gbufsize = 768*576*4; - DEB_D(("VIDIOCGMBUF \n")); + DEB_D(("VIDIOCGMBUF \n")); - q = &fh->video_q; - err = videobuf_mmap_setup(q, gbuffers, gbufsize, - V4L2_MEMORY_MMAP); - if (err < 0) - return err; + q = &fh->video_q; + err = videobuf_mmap_setup(q,gbuffers,gbufsize, + V4L2_MEMORY_MMAP); + if (err < 0) + return err; - gbuffers = err; - memset(mbuf, 0, sizeof(*mbuf)); - mbuf->frames = gbuffers; - mbuf->size = gbuffers * gbufsize; - for (i = 0; i < gbuffers; i++) - mbuf->offsets[i] = i * gbufsize; + gbuffers = err; + memset(mbuf,0,sizeof(*mbuf)); + mbuf->frames = gbuffers; + mbuf->size = gbuffers * gbufsize; + for (i = 0; i < gbuffers; i++) + mbuf->offsets[i] = i * gbufsize; + return 0; + } +#endif + default: + return v4l_compat_translate_ioctl(file, cmd, arg, + saa7146_video_do_ioctl); + } return 0; } -#endif - -const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay, - .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, - .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, - .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, - .vidioc_g_chip_ident = vidioc_g_chip_ident, - - .vidioc_overlay = vidioc_overlay, - .vidioc_g_fbuf = vidioc_g_fbuf, - .vidioc_s_fbuf = vidioc_s_fbuf, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_g_std = vidioc_g_std, - .vidioc_s_std = vidioc_s_std, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, - .vidioc_g_parm = vidioc_g_parm, -#ifdef CONFIG_VIDEO_V4L1_COMPAT - .vidiocgmbuf = vidiocgmbuf, -#endif -}; /*********************************************************************************/ /* buffer handling functions */ diff --git a/trunk/drivers/media/common/tuners/Kconfig b/trunk/drivers/media/common/tuners/Kconfig index 52c3f65b12d6..6f92beaa5ac8 100644 --- a/trunk/drivers/media/common/tuners/Kconfig +++ b/trunk/drivers/media/common/tuners/Kconfig @@ -21,17 +21,16 @@ config MEDIA_TUNER tristate default VIDEO_MEDIA && I2C depends on VIDEO_MEDIA && I2C - select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE - -menuconfig MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMIZE + +menuconfig MEDIA_TUNER_CUSTOMIZE bool "Customize analog and hybrid tuner modules to build" depends on MEDIA_TUNER default n @@ -44,13 +43,13 @@ menuconfig MEDIA_TUNER_CUSTOMISE If unsure say N. -if MEDIA_TUNER_CUSTOMISE +if MEDIA_TUNER_CUSTOMIZE config MEDIA_TUNER_SIMPLE tristate "Simple tuner support" depends on VIDEO_MEDIA && I2C select MEDIA_TUNER_TDA9887 - default m if MEDIA_TUNER_CUSTOMISE + default m if MEDIA_TUNER_CUSTOMIZE help Say Y here to include support for various simple tuners. @@ -59,28 +58,28 @@ config MEDIA_TUNER_TDA8290 depends on VIDEO_MEDIA && I2C select MEDIA_TUNER_TDA827X select MEDIA_TUNER_TDA18271 - default m if MEDIA_TUNER_CUSTOMISE + default m if MEDIA_TUNER_CUSTOMIZE help Say Y here to include support for Philips TDA8290+8275(a) tuner. config MEDIA_TUNER_TDA827X tristate "Philips TDA827X silicon tuner" depends on VIDEO_MEDIA && I2C - default m if MEDIA_TUNER_CUSTOMISE + default m if DVB_FE_CUSTOMISE help A DVB-T silicon tuner module. Say Y when you want to support this tuner. config MEDIA_TUNER_TDA18271 tristate "NXP TDA18271 silicon tuner" depends on VIDEO_MEDIA && I2C - default m if MEDIA_TUNER_CUSTOMISE + default m if DVB_FE_CUSTOMISE help A silicon tuner module. Say Y when you want to support this tuner. config MEDIA_TUNER_TDA9887 tristate "TDA 9885/6/7 analog IF demodulator" depends on VIDEO_MEDIA && I2C - default m if MEDIA_TUNER_CUSTOMISE + default m if MEDIA_TUNER_CUSTOMIZE help Say Y here to include support for Philips TDA9885/6/7 analog IF demodulator. @@ -89,63 +88,63 @@ config MEDIA_TUNER_TEA5761 tristate "TEA 5761 radio tuner (EXPERIMENTAL)" depends on VIDEO_MEDIA && I2C depends on EXPERIMENTAL - default m if MEDIA_TUNER_CUSTOMISE + default m if MEDIA_TUNER_CUSTOMIZE help Say Y here to include support for the Philips TEA5761 radio tuner. config MEDIA_TUNER_TEA5767 tristate "TEA 5767 radio tuner" depends on VIDEO_MEDIA && I2C - default m if MEDIA_TUNER_CUSTOMISE + default m if MEDIA_TUNER_CUSTOMIZE help Say Y here to include support for the Philips TEA5767 radio tuner. config MEDIA_TUNER_MT20XX tristate "Microtune 2032 / 2050 tuners" depends on VIDEO_MEDIA && I2C - default m if MEDIA_TUNER_CUSTOMISE + default m if MEDIA_TUNER_CUSTOMIZE help Say Y here to include support for the MT2032 / MT2050 tuner. config MEDIA_TUNER_MT2060 tristate "Microtune MT2060 silicon IF tuner" depends on VIDEO_MEDIA && I2C - default m if MEDIA_TUNER_CUSTOMISE + default m if DVB_FE_CUSTOMISE help A driver for the silicon IF tuner MT2060 from Microtune. config MEDIA_TUNER_MT2266 tristate "Microtune MT2266 silicon tuner" depends on VIDEO_MEDIA && I2C - default m if MEDIA_TUNER_CUSTOMISE + default m if DVB_FE_CUSTOMISE help A driver for the silicon baseband tuner MT2266 from Microtune. config MEDIA_TUNER_MT2131 tristate "Microtune MT2131 silicon tuner" depends on VIDEO_MEDIA && I2C - default m if MEDIA_TUNER_CUSTOMISE + default m if DVB_FE_CUSTOMISE help A driver for the silicon baseband tuner MT2131 from Microtune. config MEDIA_TUNER_QT1010 tristate "Quantek QT1010 silicon tuner" depends on VIDEO_MEDIA && I2C - default m if MEDIA_TUNER_CUSTOMISE + default m if DVB_FE_CUSTOMISE help A driver for the silicon tuner QT1010 from Quantek. config MEDIA_TUNER_XC2028 tristate "XCeive xc2028/xc3028 tuners" depends on VIDEO_MEDIA && I2C - default m if MEDIA_TUNER_CUSTOMISE + default m if MEDIA_TUNER_CUSTOMIZE help Say Y here to include support for the xc2028/xc3028 tuners. config MEDIA_TUNER_XC5000 tristate "Xceive XC5000 silicon tuner" depends on VIDEO_MEDIA && I2C - default m if MEDIA_TUNER_CUSTOMISE + default m if DVB_FE_CUSTOMISE help A driver for the silicon tuner XC5000 from Xceive. This device is only used inside a SiP called togther with a @@ -154,22 +153,15 @@ config MEDIA_TUNER_XC5000 config MEDIA_TUNER_MXL5005S tristate "MaxLinear MSL5005S silicon tuner" depends on VIDEO_MEDIA && I2C - default m if MEDIA_TUNER_CUSTOMISE + default m if DVB_FE_CUSTOMISE help A driver for the silicon tuner MXL5005S from MaxLinear. config MEDIA_TUNER_MXL5007T tristate "MaxLinear MxL5007T silicon tuner" depends on VIDEO_MEDIA && I2C - default m if MEDIA_TUNER_CUSTOMISE + default m if DVB_FE_CUSTOMISE help A driver for the silicon tuner MxL5007T from MaxLinear. -config MEDIA_TUNER_MC44S803 - tristate "Freescale MC44S803 Low Power CMOS Broadband tuners" - depends on VIDEO_MEDIA && I2C - default m if MEDIA_TUNER_CUSTOMISE - help - Say Y here to support the Freescale MC44S803 based tuners - -endif # MEDIA_TUNER_CUSTOMISE +endif # MEDIA_TUNER_CUSTOMIZE diff --git a/trunk/drivers/media/common/tuners/Makefile b/trunk/drivers/media/common/tuners/Makefile index 4132b2be79e5..4dfbe5b8264f 100644 --- a/trunk/drivers/media/common/tuners/Makefile +++ b/trunk/drivers/media/common/tuners/Makefile @@ -22,7 +22,6 @@ obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o -obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends diff --git a/trunk/drivers/media/common/tuners/mc44s803.c b/trunk/drivers/media/common/tuners/mc44s803.c deleted file mode 100644 index 20c4485ce16a..000000000000 --- a/trunk/drivers/media/common/tuners/mc44s803.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner - * - * Copyright (c) 2009 Jochen Friedrich - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#include -#include -#include -#include - -#include "dvb_frontend.h" - -#include "mc44s803.h" -#include "mc44s803_priv.h" - -#define mc_printk(level, format, arg...) \ - printk(level "mc44s803: " format , ## arg) - -/* Writes a single register */ -static int mc44s803_writereg(struct mc44s803_priv *priv, u32 val) -{ - u8 buf[3]; - struct i2c_msg msg = { - .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 3 - }; - - buf[0] = (val & 0xff0000) >> 16; - buf[1] = (val & 0xff00) >> 8; - buf[2] = (val & 0xff); - - if (i2c_transfer(priv->i2c, &msg, 1) != 1) { - mc_printk(KERN_WARNING, "I2C write failed\n"); - return -EREMOTEIO; - } - return 0; -} - -/* Reads a single register */ -static int mc44s803_readreg(struct mc44s803_priv *priv, u8 reg, u32 *val) -{ - u32 wval; - u8 buf[3]; - int ret; - struct i2c_msg msg[] = { - { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, - .buf = buf, .len = 3 }, - }; - - wval = MC44S803_REG_SM(MC44S803_REG_DATAREG, MC44S803_ADDR) | - MC44S803_REG_SM(reg, MC44S803_D); - - ret = mc44s803_writereg(priv, wval); - if (ret) - return ret; - - if (i2c_transfer(priv->i2c, msg, 1) != 1) { - mc_printk(KERN_WARNING, "I2C read failed\n"); - return -EREMOTEIO; - } - - *val = (buf[0] << 16) | (buf[1] << 8) | buf[2]; - - return 0; -} - -static int mc44s803_release(struct dvb_frontend *fe) -{ - struct mc44s803_priv *priv = fe->tuner_priv; - - fe->tuner_priv = NULL; - kfree(priv); - - return 0; -} - -static int mc44s803_init(struct dvb_frontend *fe) -{ - struct mc44s803_priv *priv = fe->tuner_priv; - u32 val; - int err; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - -/* Reset chip */ - val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR) | - MC44S803_REG_SM(1, MC44S803_RS); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - - val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - -/* Power Up and Start Osc */ - - val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) | - MC44S803_REG_SM(0xC0, MC44S803_REFOSC) | - MC44S803_REG_SM(1, MC44S803_OSCSEL); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - - val = MC44S803_REG_SM(MC44S803_REG_POWER, MC44S803_ADDR) | - MC44S803_REG_SM(0x200, MC44S803_POWER); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - - msleep(10); - - val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) | - MC44S803_REG_SM(0x40, MC44S803_REFOSC) | - MC44S803_REG_SM(1, MC44S803_OSCSEL); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - - msleep(20); - -/* Setup Mixer */ - - val = MC44S803_REG_SM(MC44S803_REG_MIXER, MC44S803_ADDR) | - MC44S803_REG_SM(1, MC44S803_TRI_STATE) | - MC44S803_REG_SM(0x7F, MC44S803_MIXER_RES); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - -/* Setup Cirquit Adjust */ - - val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) | - MC44S803_REG_SM(1, MC44S803_G1) | - MC44S803_REG_SM(1, MC44S803_G3) | - MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) | - MC44S803_REG_SM(1, MC44S803_G6) | - MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) | - MC44S803_REG_SM(0x3, MC44S803_LP) | - MC44S803_REG_SM(1, MC44S803_CLRF) | - MC44S803_REG_SM(1, MC44S803_CLIF); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - - val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) | - MC44S803_REG_SM(1, MC44S803_G1) | - MC44S803_REG_SM(1, MC44S803_G3) | - MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) | - MC44S803_REG_SM(1, MC44S803_G6) | - MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) | - MC44S803_REG_SM(0x3, MC44S803_LP); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - -/* Setup Digtune */ - - val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) | - MC44S803_REG_SM(3, MC44S803_XOD); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - -/* Setup AGC */ - - val = MC44S803_REG_SM(MC44S803_REG_LNAAGC, MC44S803_ADDR) | - MC44S803_REG_SM(1, MC44S803_AT1) | - MC44S803_REG_SM(1, MC44S803_AT2) | - MC44S803_REG_SM(1, MC44S803_AGC_AN_DIG) | - MC44S803_REG_SM(1, MC44S803_AGC_READ_EN) | - MC44S803_REG_SM(1, MC44S803_LNA0); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - return 0; - -exit: - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - mc_printk(KERN_WARNING, "I/O Error\n"); - return err; -} - -static int mc44s803_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct mc44s803_priv *priv = fe->tuner_priv; - u32 r1, r2, n1, n2, lo1, lo2, freq, val; - int err; - - priv->frequency = params->frequency; - - r1 = MC44S803_OSC / 1000000; - r2 = MC44S803_OSC / 100000; - - n1 = (params->frequency + MC44S803_IF1 + 500000) / 1000000; - freq = MC44S803_OSC / r1 * n1; - lo1 = ((60 * n1) + (r1 / 2)) / r1; - freq = freq - params->frequency; - - n2 = (freq - MC44S803_IF2 + 50000) / 100000; - lo2 = ((60 * n2) + (r2 / 2)) / r2; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - val = MC44S803_REG_SM(MC44S803_REG_REFDIV, MC44S803_ADDR) | - MC44S803_REG_SM(r1-1, MC44S803_R1) | - MC44S803_REG_SM(r2-1, MC44S803_R2) | - MC44S803_REG_SM(1, MC44S803_REFBUF_EN); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - - val = MC44S803_REG_SM(MC44S803_REG_LO1, MC44S803_ADDR) | - MC44S803_REG_SM(n1-2, MC44S803_LO1); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - - val = MC44S803_REG_SM(MC44S803_REG_LO2, MC44S803_ADDR) | - MC44S803_REG_SM(n2-2, MC44S803_LO2); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - - val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) | - MC44S803_REG_SM(1, MC44S803_DA) | - MC44S803_REG_SM(lo1, MC44S803_LO_REF) | - MC44S803_REG_SM(1, MC44S803_AT); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - - val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) | - MC44S803_REG_SM(2, MC44S803_DA) | - MC44S803_REG_SM(lo2, MC44S803_LO_REF) | - MC44S803_REG_SM(1, MC44S803_AT); - - err = mc44s803_writereg(priv, val); - if (err) - goto exit; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return 0; - -exit: - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - mc_printk(KERN_WARNING, "I/O Error\n"); - return err; -} - -static int mc44s803_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct mc44s803_priv *priv = fe->tuner_priv; - *frequency = priv->frequency; - return 0; -} - -static const struct dvb_tuner_ops mc44s803_tuner_ops = { - .info = { - .name = "Freescale MC44S803", - .frequency_min = 48000000, - .frequency_max = 1000000000, - .frequency_step = 100000, - }, - - .release = mc44s803_release, - .init = mc44s803_init, - .set_params = mc44s803_set_params, - .get_frequency = mc44s803_get_frequency -}; - -/* This functions tries to identify a MC44S803 tuner by reading the ID - register. This is hasty. */ -struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, struct mc44s803_config *cfg) -{ - struct mc44s803_priv *priv; - u32 reg; - u8 id; - int ret; - - reg = 0; - - priv = kzalloc(sizeof(struct mc44s803_priv), GFP_KERNEL); - if (priv == NULL) - return NULL; - - priv->cfg = cfg; - priv->i2c = i2c; - priv->fe = fe; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ - - ret = mc44s803_readreg(priv, MC44S803_REG_ID, ®); - if (ret) - goto error; - - id = MC44S803_REG_MS(reg, MC44S803_ID); - - if (id != 0x14) { - mc_printk(KERN_ERR, "unsupported ID " - "(%x should be 0x14)\n", id); - goto error; - } - - mc_printk(KERN_INFO, "successfully identified (ID = %x)\n", id); - memcpy(&fe->ops.tuner_ops, &mc44s803_tuner_ops, - sizeof(struct dvb_tuner_ops)); - - fe->tuner_priv = priv; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ - - return fe; - -error: - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ - - kfree(priv); - return NULL; -} -EXPORT_SYMBOL(mc44s803_attach); - -MODULE_AUTHOR("Jochen Friedrich"); -MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/common/tuners/mc44s803.h b/trunk/drivers/media/common/tuners/mc44s803.h deleted file mode 100644 index 34f3892d3f6d..000000000000 --- a/trunk/drivers/media/common/tuners/mc44s803.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner - * - * Copyright (c) 2009 Jochen Friedrich - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef MC44S803_H -#define MC44S803_H - -struct dvb_frontend; -struct i2c_adapter; - -struct mc44s803_config { - u8 i2c_address; - u8 dig_out; -}; - -#if defined(CONFIG_MEDIA_TUNER_MC44S803) || \ - (defined(CONFIG_MEDIA_TUNER_MC44S803_MODULE) && defined(MODULE)) -extern struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, struct mc44s803_config *cfg); -#else -static inline struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, struct mc44s803_config *cfg) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_MEDIA_TUNER_MC44S803 */ - -#endif diff --git a/trunk/drivers/media/common/tuners/mc44s803_priv.h b/trunk/drivers/media/common/tuners/mc44s803_priv.h deleted file mode 100644 index 14a92780906d..000000000000 --- a/trunk/drivers/media/common/tuners/mc44s803_priv.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner - * - * Copyright (c) 2009 Jochen Friedrich - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef MC44S803_PRIV_H -#define MC44S803_PRIV_H - -/* This driver is based on the information available in the datasheet - http://www.freescale.com/files/rf_if/doc/data_sheet/MC44S803.pdf - - SPI or I2C Address : 0xc0-0xc6 - - Reg.No | Function - ------------------------------------------- - 00 | Power Down - 01 | Reference Oszillator - 02 | Reference Dividers - 03 | Mixer and Reference Buffer - 04 | Reset/Serial Out - 05 | LO 1 - 06 | LO 2 - 07 | Circuit Adjust - 08 | Test - 09 | Digital Tune - 0A | LNA AGC - 0B | Data Register Address - 0C | Regulator Test - 0D | VCO Test - 0E | LNA Gain/Input Power - 0F | ID Bits - -*/ - -#define MC44S803_OSC 26000000 /* 26 MHz */ -#define MC44S803_IF1 1086000000 /* 1086 MHz */ -#define MC44S803_IF2 36125000 /* 36.125 MHz */ - -#define MC44S803_REG_POWER 0 -#define MC44S803_REG_REFOSC 1 -#define MC44S803_REG_REFDIV 2 -#define MC44S803_REG_MIXER 3 -#define MC44S803_REG_RESET 4 -#define MC44S803_REG_LO1 5 -#define MC44S803_REG_LO2 6 -#define MC44S803_REG_CIRCADJ 7 -#define MC44S803_REG_TEST 8 -#define MC44S803_REG_DIGTUNE 9 -#define MC44S803_REG_LNAAGC 0x0A -#define MC44S803_REG_DATAREG 0x0B -#define MC44S803_REG_REGTEST 0x0C -#define MC44S803_REG_VCOTEST 0x0D -#define MC44S803_REG_LNAGAIN 0x0E -#define MC44S803_REG_ID 0x0F - -/* Register definitions */ -#define MC44S803_ADDR 0x0F -#define MC44S803_ADDR_S 0 -/* REG_POWER */ -#define MC44S803_POWER 0xFFFFF0 -#define MC44S803_POWER_S 4 -/* REG_REFOSC */ -#define MC44S803_REFOSC 0x1FF0 -#define MC44S803_REFOSC_S 4 -#define MC44S803_OSCSEL 0x2000 -#define MC44S803_OSCSEL_S 13 -/* REG_REFDIV */ -#define MC44S803_R2 0x1FF0 -#define MC44S803_R2_S 4 -#define MC44S803_REFBUF_EN 0x2000 -#define MC44S803_REFBUF_EN_S 13 -#define MC44S803_R1 0x7C000 -#define MC44S803_R1_S 14 -/* REG_MIXER */ -#define MC44S803_R3 0x70 -#define MC44S803_R3_S 4 -#define MC44S803_MUX3 0x80 -#define MC44S803_MUX3_S 7 -#define MC44S803_MUX4 0x100 -#define MC44S803_MUX4_S 8 -#define MC44S803_OSC_SCR 0x200 -#define MC44S803_OSC_SCR_S 9 -#define MC44S803_TRI_STATE 0x400 -#define MC44S803_TRI_STATE_S 10 -#define MC44S803_BUF_GAIN 0x800 -#define MC44S803_BUF_GAIN_S 11 -#define MC44S803_BUF_IO 0x1000 -#define MC44S803_BUF_IO_S 12 -#define MC44S803_MIXER_RES 0xFE000 -#define MC44S803_MIXER_RES_S 13 -/* REG_RESET */ -#define MC44S803_RS 0x10 -#define MC44S803_RS_S 4 -#define MC44S803_SO 0x20 -#define MC44S803_SO_S 5 -/* REG_LO1 */ -#define MC44S803_LO1 0xFFF0 -#define MC44S803_LO1_S 4 -/* REG_LO2 */ -#define MC44S803_LO2 0x7FFF0 -#define MC44S803_LO2_S 4 -/* REG_CIRCADJ */ -#define MC44S803_G1 0x20 -#define MC44S803_G1_S 5 -#define MC44S803_G3 0x80 -#define MC44S803_G3_S 7 -#define MC44S803_CIRCADJ_RES 0x300 -#define MC44S803_CIRCADJ_RES_S 8 -#define MC44S803_G6 0x400 -#define MC44S803_G6_S 10 -#define MC44S803_G7 0x800 -#define MC44S803_G7_S 11 -#define MC44S803_S1 0x1000 -#define MC44S803_S1_S 12 -#define MC44S803_LP 0x7E000 -#define MC44S803_LP_S 13 -#define MC44S803_CLRF 0x80000 -#define MC44S803_CLRF_S 19 -#define MC44S803_CLIF 0x100000 -#define MC44S803_CLIF_S 20 -/* REG_TEST */ -/* REG_DIGTUNE */ -#define MC44S803_DA 0xF0 -#define MC44S803_DA_S 4 -#define MC44S803_XOD 0x300 -#define MC44S803_XOD_S 8 -#define MC44S803_RST 0x10000 -#define MC44S803_RST_S 16 -#define MC44S803_LO_REF 0x1FFF00 -#define MC44S803_LO_REF_S 8 -#define MC44S803_AT 0x200000 -#define MC44S803_AT_S 21 -#define MC44S803_MT 0x400000 -#define MC44S803_MT_S 22 -/* REG_LNAAGC */ -#define MC44S803_G 0x3F0 -#define MC44S803_G_S 4 -#define MC44S803_AT1 0x400 -#define MC44S803_AT1_S 10 -#define MC44S803_AT2 0x800 -#define MC44S803_AT2_S 11 -#define MC44S803_HL_GR_EN 0x8000 -#define MC44S803_HL_GR_EN_S 15 -#define MC44S803_AGC_AN_DIG 0x10000 -#define MC44S803_AGC_AN_DIG_S 16 -#define MC44S803_ATTEN_EN 0x20000 -#define MC44S803_ATTEN_EN_S 17 -#define MC44S803_AGC_READ_EN 0x40000 -#define MC44S803_AGC_READ_EN_S 18 -#define MC44S803_LNA0 0x80000 -#define MC44S803_LNA0_S 19 -#define MC44S803_AGC_SEL 0x100000 -#define MC44S803_AGC_SEL_S 20 -#define MC44S803_AT0 0x200000 -#define MC44S803_AT0_S 21 -#define MC44S803_B 0xC00000 -#define MC44S803_B_S 22 -/* REG_DATAREG */ -#define MC44S803_D 0xF0 -#define MC44S803_D_S 4 -/* REG_REGTEST */ -/* REG_VCOTEST */ -/* REG_LNAGAIN */ -#define MC44S803_IF_PWR 0x700 -#define MC44S803_IF_PWR_S 8 -#define MC44S803_RF_PWR 0x3800 -#define MC44S803_RF_PWR_S 11 -#define MC44S803_LNA_GAIN 0xFC000 -#define MC44S803_LNA_GAIN_S 14 -/* REG_ID */ -#define MC44S803_ID 0x3E00 -#define MC44S803_ID_S 9 - -/* Some macros to read/write fields */ - -/* First shift, then mask */ -#define MC44S803_REG_SM(_val, _reg) \ - (((_val) << _reg##_S) & (_reg)) - -/* First mask, then shift */ -#define MC44S803_REG_MS(_val, _reg) \ - (((_val) & (_reg)) >> _reg##_S) - -struct mc44s803_priv { - struct mc44s803_config *cfg; - struct i2c_adapter *i2c; - struct dvb_frontend *fe; - - u32 frequency; -}; - -#endif diff --git a/trunk/drivers/media/common/tuners/mt2060.c b/trunk/drivers/media/common/tuners/mt2060.c index c7abe3d8f90e..12206d75dd4e 100644 --- a/trunk/drivers/media/common/tuners/mt2060.c +++ b/trunk/drivers/media/common/tuners/mt2060.c @@ -278,7 +278,7 @@ static void mt2060_calibrate(struct mt2060_priv *priv) while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0) msleep(20); - if (i <= 10) { + if (i < 10) { mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :) dprintk("calibration was successful: %d", (int)priv->fmfreq); } else diff --git a/trunk/drivers/media/common/tuners/mt20xx.c b/trunk/drivers/media/common/tuners/mt20xx.c index 44608ad4e2d2..35b763a16d53 100644 --- a/trunk/drivers/media/common/tuners/mt20xx.c +++ b/trunk/drivers/media/common/tuners/mt20xx.c @@ -6,7 +6,7 @@ */ #include #include -#include +#include #include "tuner-i2c.h" #include "mt20xx.h" diff --git a/trunk/drivers/media/common/tuners/mxl5005s.c b/trunk/drivers/media/common/tuners/mxl5005s.c index 0803dab58fff..31522d2e318e 100644 --- a/trunk/drivers/media/common/tuners/mxl5005s.c +++ b/trunk/drivers/media/common/tuners/mxl5005s.c @@ -4003,11 +4003,12 @@ static int mxl5005s_set_params(struct dvb_frontend *fe, /* Change tuner for new modulation type if reqd */ if (req_mode != state->current_mode) { switch (req_mode) { - case MXL_ATSC: - case MXL_QAM: + case VSB_8: + case QAM_64: + case QAM_256: + case QAM_AUTO: req_bw = MXL5005S_BANDWIDTH_6MHZ; break; - case MXL_DVBT: default: /* Assume DVB-T */ switch (params->u.ofdm.bandwidth) { diff --git a/trunk/drivers/media/common/tuners/mxl5007t.c b/trunk/drivers/media/common/tuners/mxl5007t.c index 2d02698d4f4f..3ec28945c26f 100644 --- a/trunk/drivers/media/common/tuners/mxl5007t.c +++ b/trunk/drivers/media/common/tuners/mxl5007t.c @@ -1,7 +1,7 @@ /* * mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner * - * Copyright (C) 2008, 2009 Michael Krufky + * Copyright (C) 2008 Michael Krufky * * 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 @@ -66,17 +66,22 @@ MODULE_PARM_DESC(debug, "set debug level"); #define MHz 1000000 enum mxl5007t_mode { - MxL_MODE_ISDBT = 0, - MxL_MODE_DVBT = 1, - MxL_MODE_ATSC = 2, - MxL_MODE_CABLE = 0x10, + MxL_MODE_OTA_DVBT_ATSC = 0, + MxL_MODE_OTA_NTSC_PAL_GH = 1, + MxL_MODE_OTA_PAL_IB = 2, + MxL_MODE_OTA_PAL_D_SECAM_KL = 3, + MxL_MODE_OTA_ISDBT = 4, + MxL_MODE_CABLE_DIGITAL = 0x10, + MxL_MODE_CABLE_NTSC_PAL_GH = 0x11, + MxL_MODE_CABLE_PAL_IB = 0x12, + MxL_MODE_CABLE_PAL_D_SECAM_KL = 0x13, + MxL_MODE_CABLE_SCTE40 = 0x14, }; enum mxl5007t_chip_version { MxL_UNKNOWN_ID = 0x00, MxL_5007_V1_F1 = 0x11, MxL_5007_V1_F2 = 0x12, - MxL_5007_V4 = 0x14, MxL_5007_V2_100_F1 = 0x21, MxL_5007_V2_100_F2 = 0x22, MxL_5007_V2_200_F1 = 0x23, @@ -91,61 +96,67 @@ struct reg_pair_t { /* ------------------------------------------------------------------------- */ static struct reg_pair_t init_tab[] = { - { 0x02, 0x06 }, - { 0x03, 0x48 }, - { 0x05, 0x04 }, - { 0x06, 0x10 }, - { 0x2e, 0x15 }, /* OVERRIDE */ - { 0x30, 0x10 }, /* OVERRIDE */ - { 0x45, 0x58 }, /* OVERRIDE */ - { 0x48, 0x19 }, /* OVERRIDE */ - { 0x52, 0x03 }, /* OVERRIDE */ - { 0x53, 0x44 }, /* OVERRIDE */ - { 0x6a, 0x4b }, /* OVERRIDE */ - { 0x76, 0x00 }, /* OVERRIDE */ - { 0x78, 0x18 }, /* OVERRIDE */ - { 0x7a, 0x17 }, /* OVERRIDE */ - { 0x85, 0x06 }, /* OVERRIDE */ - { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */ + { 0x0b, 0x44 }, /* XTAL */ + { 0x0c, 0x60 }, /* IF */ + { 0x10, 0x00 }, /* MISC */ + { 0x12, 0xca }, /* IDAC */ + { 0x16, 0x90 }, /* MODE */ + { 0x32, 0x38 }, /* MODE Analog/Digital */ + { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */ + { 0x2c, 0x34 }, /* OVERRIDE */ + { 0x4d, 0x40 }, /* OVERRIDE */ + { 0x7f, 0x02 }, /* OVERRIDE */ + { 0x9a, 0x52 }, /* OVERRIDE */ + { 0x48, 0x5a }, /* OVERRIDE */ + { 0x76, 0x1a }, /* OVERRIDE */ + { 0x6a, 0x48 }, /* OVERRIDE */ + { 0x64, 0x28 }, /* OVERRIDE */ + { 0x66, 0xe6 }, /* OVERRIDE */ + { 0x35, 0x0e }, /* OVERRIDE */ + { 0x7e, 0x01 }, /* OVERRIDE */ + { 0x83, 0x00 }, /* OVERRIDE */ + { 0x04, 0x0b }, /* OVERRIDE */ + { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */ { 0, 0 } }; static struct reg_pair_t init_tab_cable[] = { - { 0x02, 0x06 }, - { 0x03, 0x48 }, - { 0x05, 0x04 }, - { 0x06, 0x10 }, - { 0x09, 0x3f }, - { 0x0a, 0x3f }, - { 0x0b, 0x3f }, - { 0x2e, 0x15 }, /* OVERRIDE */ - { 0x30, 0x10 }, /* OVERRIDE */ - { 0x45, 0x58 }, /* OVERRIDE */ - { 0x48, 0x19 }, /* OVERRIDE */ - { 0x52, 0x03 }, /* OVERRIDE */ - { 0x53, 0x44 }, /* OVERRIDE */ - { 0x6a, 0x4b }, /* OVERRIDE */ - { 0x76, 0x00 }, /* OVERRIDE */ - { 0x78, 0x18 }, /* OVERRIDE */ - { 0x7a, 0x17 }, /* OVERRIDE */ - { 0x85, 0x06 }, /* OVERRIDE */ - { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */ + { 0x0b, 0x44 }, /* XTAL */ + { 0x0c, 0x60 }, /* IF */ + { 0x10, 0x00 }, /* MISC */ + { 0x12, 0xca }, /* IDAC */ + { 0x16, 0x90 }, /* MODE */ + { 0x32, 0x38 }, /* MODE A/D */ + { 0x71, 0x3f }, /* TOP1 */ + { 0x72, 0x3f }, /* TOP2 */ + { 0x74, 0x3f }, /* TOP3 */ + { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */ + { 0x2c, 0x34 }, /* OVERRIDE */ + { 0x4d, 0x40 }, /* OVERRIDE */ + { 0x7f, 0x02 }, /* OVERRIDE */ + { 0x9a, 0x52 }, /* OVERRIDE */ + { 0x48, 0x5a }, /* OVERRIDE */ + { 0x76, 0x1a }, /* OVERRIDE */ + { 0x6a, 0x48 }, /* OVERRIDE */ + { 0x64, 0x28 }, /* OVERRIDE */ + { 0x66, 0xe6 }, /* OVERRIDE */ + { 0x35, 0x0e }, /* OVERRIDE */ + { 0x7e, 0x01 }, /* OVERRIDE */ + { 0x04, 0x0b }, /* OVERRIDE */ + { 0x68, 0xb4 }, /* OVERRIDE */ + { 0x36, 0x00 }, /* OVERRIDE */ + { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */ { 0, 0 } }; /* ------------------------------------------------------------------------- */ static struct reg_pair_t reg_pair_rftune[] = { - { 0x0f, 0x00 }, /* abort tune */ - { 0x0c, 0x15 }, - { 0x0d, 0x40 }, - { 0x0e, 0x0e }, - { 0x1f, 0x87 }, /* OVERRIDE */ - { 0x20, 0x1f }, /* OVERRIDE */ - { 0x21, 0x87 }, /* OVERRIDE */ - { 0x22, 0x1f }, /* OVERRIDE */ - { 0x80, 0x01 }, /* freq dependent */ - { 0x0f, 0x01 }, /* start tune */ + { 0x11, 0x00 }, /* abort tune */ + { 0x13, 0x15 }, + { 0x14, 0x40 }, + { 0x15, 0x0e }, + { 0x11, 0x02 }, /* start tune */ { 0, 0 } }; @@ -216,20 +227,63 @@ static void mxl5007t_set_mode_bits(struct mxl5007t_state *state, s32 if_diff_out_level) { switch (mode) { - case MxL_MODE_ATSC: - set_reg_bits(state->tab_init, 0x06, 0x1f, 0x12); + case MxL_MODE_OTA_DVBT_ATSC: + set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06); + set_reg_bits(state->tab_init, 0x35, 0xff, 0x0e); break; - case MxL_MODE_DVBT: - set_reg_bits(state->tab_init, 0x06, 0x1f, 0x11); + case MxL_MODE_OTA_ISDBT: + set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06); + set_reg_bits(state->tab_init, 0x35, 0xff, 0x12); break; - case MxL_MODE_ISDBT: - set_reg_bits(state->tab_init, 0x06, 0x1f, 0x10); + case MxL_MODE_OTA_NTSC_PAL_GH: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x00); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); break; - case MxL_MODE_CABLE: - set_reg_bits(state->tab_init_cable, 0x09, 0xff, 0xc1); - set_reg_bits(state->tab_init_cable, 0x0a, 0xff, + case MxL_MODE_OTA_PAL_IB: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x10); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + break; + case MxL_MODE_OTA_PAL_D_SECAM_KL: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x20); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + break; + case MxL_MODE_CABLE_DIGITAL: + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, + 8 - if_diff_out_level); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + break; + case MxL_MODE_CABLE_NTSC_PAL_GH: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x00); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, + 8 - if_diff_out_level); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + break; + case MxL_MODE_CABLE_PAL_IB: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x10); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, 8 - if_diff_out_level); - set_reg_bits(state->tab_init_cable, 0x0b, 0xff, 0x17); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + break; + case MxL_MODE_CABLE_PAL_D_SECAM_KL: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x20); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, + 8 - if_diff_out_level); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + break; + case MxL_MODE_CABLE_SCTE40: + set_reg_bits(state->tab_init_cable, 0x36, 0xff, 0x08); + set_reg_bits(state->tab_init_cable, 0x68, 0xff, 0xbc); + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, + 8 - if_diff_out_level); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); break; default: mxl_fail(-EINVAL); @@ -248,43 +302,43 @@ static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state, val = 0x00; break; case MxL_IF_4_5_MHZ: - val = 0x02; + val = 0x20; break; case MxL_IF_4_57_MHZ: - val = 0x03; + val = 0x30; break; case MxL_IF_5_MHZ: - val = 0x04; + val = 0x40; break; case MxL_IF_5_38_MHZ: - val = 0x05; + val = 0x50; break; case MxL_IF_6_MHZ: - val = 0x06; + val = 0x60; break; case MxL_IF_6_28_MHZ: - val = 0x07; + val = 0x70; break; case MxL_IF_9_1915_MHZ: - val = 0x08; + val = 0x80; break; case MxL_IF_35_25_MHZ: - val = 0x09; + val = 0x90; break; case MxL_IF_36_15_MHZ: - val = 0x0a; + val = 0xa0; break; case MxL_IF_44_MHZ: - val = 0x0b; + val = 0xb0; break; default: mxl_fail(-EINVAL); return; } - set_reg_bits(state->tab_init, 0x02, 0x0f, val); + set_reg_bits(state->tab_init, 0x0c, 0xf0, val); /* set inverted IF or normal IF */ - set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00); + set_reg_bits(state->tab_init, 0x0c, 0x08, invert_if ? 0x08 : 0x00); return; } @@ -292,68 +346,56 @@ static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state, static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state, enum mxl5007t_xtal_freq xtal_freq) { + u8 val; + switch (xtal_freq) { case MxL_XTAL_16_MHZ: - /* select xtal freq & ref freq */ - set_reg_bits(state->tab_init, 0x03, 0xf0, 0x00); - set_reg_bits(state->tab_init, 0x05, 0x0f, 0x00); + val = 0x00; /* select xtal freq & Ref Freq */ break; case MxL_XTAL_20_MHZ: - set_reg_bits(state->tab_init, 0x03, 0xf0, 0x10); - set_reg_bits(state->tab_init, 0x05, 0x0f, 0x01); + val = 0x11; break; case MxL_XTAL_20_25_MHZ: - set_reg_bits(state->tab_init, 0x03, 0xf0, 0x20); - set_reg_bits(state->tab_init, 0x05, 0x0f, 0x02); + val = 0x22; break; case MxL_XTAL_20_48_MHZ: - set_reg_bits(state->tab_init, 0x03, 0xf0, 0x30); - set_reg_bits(state->tab_init, 0x05, 0x0f, 0x03); + val = 0x33; break; case MxL_XTAL_24_MHZ: - set_reg_bits(state->tab_init, 0x03, 0xf0, 0x40); - set_reg_bits(state->tab_init, 0x05, 0x0f, 0x04); + val = 0x44; break; case MxL_XTAL_25_MHZ: - set_reg_bits(state->tab_init, 0x03, 0xf0, 0x50); - set_reg_bits(state->tab_init, 0x05, 0x0f, 0x05); + val = 0x55; break; case MxL_XTAL_25_14_MHZ: - set_reg_bits(state->tab_init, 0x03, 0xf0, 0x60); - set_reg_bits(state->tab_init, 0x05, 0x0f, 0x06); + val = 0x66; break; case MxL_XTAL_27_MHZ: - set_reg_bits(state->tab_init, 0x03, 0xf0, 0x70); - set_reg_bits(state->tab_init, 0x05, 0x0f, 0x07); + val = 0x77; break; case MxL_XTAL_28_8_MHZ: - set_reg_bits(state->tab_init, 0x03, 0xf0, 0x80); - set_reg_bits(state->tab_init, 0x05, 0x0f, 0x08); + val = 0x88; break; case MxL_XTAL_32_MHZ: - set_reg_bits(state->tab_init, 0x03, 0xf0, 0x90); - set_reg_bits(state->tab_init, 0x05, 0x0f, 0x09); + val = 0x99; break; case MxL_XTAL_40_MHZ: - set_reg_bits(state->tab_init, 0x03, 0xf0, 0xa0); - set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0a); + val = 0xaa; break; case MxL_XTAL_44_MHZ: - set_reg_bits(state->tab_init, 0x03, 0xf0, 0xb0); - set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0b); + val = 0xbb; break; case MxL_XTAL_48_MHZ: - set_reg_bits(state->tab_init, 0x03, 0xf0, 0xc0); - set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0c); + val = 0xcc; break; case MxL_XTAL_49_3811_MHZ: - set_reg_bits(state->tab_init, 0x03, 0xf0, 0xd0); - set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0d); + val = 0xdd; break; default: mxl_fail(-EINVAL); return; } + set_reg_bits(state->tab_init, 0x0b, 0xff, val); return; } @@ -370,11 +412,16 @@ static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state, mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if); mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz); - set_reg_bits(state->tab_init, 0x04, 0x01, cfg->loop_thru_enable); - set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3); - set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp); + set_reg_bits(state->tab_init, 0x10, 0x40, cfg->loop_thru_enable << 6); + + set_reg_bits(state->tab_init, 0xd8, 0x08, cfg->clk_out_enable << 3); + + set_reg_bits(state->tab_init, 0x10, 0x07, cfg->clk_out_amp); - if (mode >= MxL_MODE_CABLE) { + /* set IDAC to automatic mode control by AGC */ + set_reg_bits(state->tab_init, 0x12, 0x80, 0x00); + + if (mode >= MxL_MODE_CABLE_DIGITAL) { copy_reg_bits(state->tab_init, state->tab_init_cable); return state->tab_init_cable; } else @@ -400,7 +447,7 @@ static void mxl5007t_set_bw_bits(struct mxl5007t_state *state, * and DIG_MODEINDEX_CSF */ break; case MxL_BW_7MHz: - val = 0x2a; + val = 0x21; break; case MxL_BW_8MHz: val = 0x3f; @@ -409,7 +456,7 @@ static void mxl5007t_set_bw_bits(struct mxl5007t_state *state, mxl_fail(-EINVAL); return; } - set_reg_bits(state->tab_rftune, 0x0c, 0x3f, val); + set_reg_bits(state->tab_rftune, 0x13, 0x3f, val); return; } @@ -446,11 +493,8 @@ reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state, if (temp > 7812) dig_rf_freq++; - set_reg_bits(state->tab_rftune, 0x0d, 0xff, (u8) dig_rf_freq); - set_reg_bits(state->tab_rftune, 0x0e, 0xff, (u8) (dig_rf_freq >> 8)); - - if (rf_freq >= 333000000) - set_reg_bits(state->tab_rftune, 0x80, 0x40, 0x40); + set_reg_bits(state->tab_rftune, 0x14, 0xff, (u8)dig_rf_freq); + set_reg_bits(state->tab_rftune, 0x15, 0xff, (u8)(dig_rf_freq >> 8)); return state->tab_rftune; } @@ -507,10 +551,9 @@ static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val) static int mxl5007t_soft_reset(struct mxl5007t_state *state) { u8 d = 0xff; - struct i2c_msg msg = { - .addr = state->i2c_props.addr, .flags = 0, - .buf = &d, .len = 1 - }; + struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0, + .buf = &d, .len = 1 }; + int ret = i2c_transfer(state->i2c_props.adap, &msg, 1); if (ret != 1) { @@ -537,6 +580,9 @@ static int mxl5007t_tuner_init(struct mxl5007t_state *state, if (mxl_fail(ret)) goto fail; mdelay(1); + + ret = mxl5007t_write_reg(state, 0x2c, 0x35); + mxl_fail(ret); fail: return ret; } @@ -569,7 +615,7 @@ static int mxl5007t_synth_lock_status(struct mxl5007t_state *state, *rf_locked = 0; *ref_locked = 0; - ret = mxl5007t_read_reg(state, 0xd8, &d); + ret = mxl5007t_read_reg(state, 0xcf, &d); if (mxl_fail(ret)) goto fail; @@ -582,14 +628,37 @@ static int mxl5007t_synth_lock_status(struct mxl5007t_state *state, return ret; } +static int mxl5007t_check_rf_input_power(struct mxl5007t_state *state, + s32 *rf_input_level) +{ + u8 d1, d2; + int ret; + + ret = mxl5007t_read_reg(state, 0xb7, &d1); + if (mxl_fail(ret)) + goto fail; + + ret = mxl5007t_read_reg(state, 0xbf, &d2); + if (mxl_fail(ret)) + goto fail; + + d2 = d2 >> 4; + if (d2 > 7) + d2 += 0xf0; + + *rf_input_level = (s32)(d1 + d2 - 113); +fail: + return ret; +} + /* ------------------------------------------------------------------------- */ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) { struct mxl5007t_state *state = fe->tuner_priv; - int rf_locked, ref_locked, ret; - - *status = 0; + int rf_locked, ref_locked; + s32 rf_input_level = 0; + int ret; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); @@ -600,8 +669,10 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) mxl_debug("%s%s", rf_locked ? "rf locked " : "", ref_locked ? "ref locked" : ""); - if ((rf_locked) || (ref_locked)) - *status |= TUNER_STATUS_LOCKED; + ret = mxl5007t_check_rf_input_power(state, &rf_input_level); + if (mxl_fail(ret)) + goto fail; + mxl_debug("rf input power: %d", rf_input_level); fail: if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -624,11 +695,11 @@ static int mxl5007t_set_params(struct dvb_frontend *fe, switch (params->u.vsb.modulation) { case VSB_8: case VSB_16: - mode = MxL_MODE_ATSC; + mode = MxL_MODE_OTA_DVBT_ATSC; break; case QAM_64: case QAM_256: - mode = MxL_MODE_CABLE; + mode = MxL_MODE_CABLE_DIGITAL; break; default: mxl_err("modulation not set!"); @@ -650,7 +721,7 @@ static int mxl5007t_set_params(struct dvb_frontend *fe, mxl_err("bandwidth not set!"); return -EINVAL; } - mode = MxL_MODE_DVBT; + mode = MxL_MODE_OTA_DVBT_ATSC; } else { mxl_err("modulation type not supported!"); return -EINVAL; @@ -681,20 +752,96 @@ static int mxl5007t_set_params(struct dvb_frontend *fe, return ret; } +static int mxl5007t_set_analog_params(struct dvb_frontend *fe, + struct analog_parameters *params) +{ + struct mxl5007t_state *state = fe->tuner_priv; + enum mxl5007t_bw_mhz bw = 0; /* FIXME */ + enum mxl5007t_mode cbl_mode; + enum mxl5007t_mode ota_mode; + char *mode_name; + int ret; + u32 freq = params->frequency * 62500; + +#define cable 1 + if (params->std & V4L2_STD_MN) { + cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; + ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; + mode_name = "MN"; + } else if (params->std & V4L2_STD_B) { + cbl_mode = MxL_MODE_CABLE_PAL_IB; + ota_mode = MxL_MODE_OTA_PAL_IB; + mode_name = "B"; + } else if (params->std & V4L2_STD_GH) { + cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; + ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; + mode_name = "GH"; + } else if (params->std & V4L2_STD_PAL_I) { + cbl_mode = MxL_MODE_CABLE_PAL_IB; + ota_mode = MxL_MODE_OTA_PAL_IB; + mode_name = "I"; + } else if (params->std & V4L2_STD_DK) { + cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; + ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; + mode_name = "DK"; + } else if (params->std & V4L2_STD_SECAM_L) { + cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; + ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; + mode_name = "L"; + } else if (params->std & V4L2_STD_SECAM_LC) { + cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; + ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; + mode_name = "L'"; + } else { + mode_name = "xx"; + /* FIXME */ + cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; + ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; + } + mxl_debug("setting mxl5007 to system %s", mode_name); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + mutex_lock(&state->lock); + + ret = mxl5007t_tuner_init(state, cable ? cbl_mode : ota_mode); + if (mxl_fail(ret)) + goto fail; + + ret = mxl5007t_tuner_rf_tune(state, freq, bw); + if (mxl_fail(ret)) + goto fail; + + state->frequency = freq; + state->bandwidth = 0; +fail: + mutex_unlock(&state->lock); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + return ret; +} + /* ------------------------------------------------------------------------- */ static int mxl5007t_init(struct dvb_frontend *fe) { struct mxl5007t_state *state = fe->tuner_priv; int ret; + u8 d; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - /* wake from standby */ - ret = mxl5007t_write_reg(state, 0x01, 0x01); - mxl_fail(ret); + ret = mxl5007t_read_reg(state, 0x05, &d); + if (mxl_fail(ret)) + goto fail; + ret = mxl5007t_write_reg(state, 0x05, d | 0x01); + mxl_fail(ret); +fail: if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -705,16 +852,18 @@ static int mxl5007t_sleep(struct dvb_frontend *fe) { struct mxl5007t_state *state = fe->tuner_priv; int ret; + u8 d; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - /* enter standby mode */ - ret = mxl5007t_write_reg(state, 0x01, 0x00); - mxl_fail(ret); - ret = mxl5007t_write_reg(state, 0x0f, 0x00); - mxl_fail(ret); + ret = mxl5007t_read_reg(state, 0x05, &d); + if (mxl_fail(ret)) + goto fail; + ret = mxl5007t_write_reg(state, 0x05, d & ~0x01); + mxl_fail(ret); +fail: if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -762,6 +911,7 @@ static struct dvb_tuner_ops mxl5007t_tuner_ops = { .init = mxl5007t_init, .sleep = mxl5007t_sleep, .set_params = mxl5007t_set_params, + .set_analog_params = mxl5007t_set_analog_params, .get_status = mxl5007t_get_status, .get_frequency = mxl5007t_get_frequency, .get_bandwidth = mxl5007t_get_bandwidth, @@ -774,7 +924,7 @@ static int mxl5007t_get_chip_id(struct mxl5007t_state *state) int ret; u8 id; - ret = mxl5007t_read_reg(state, 0xd9, &id); + ret = mxl5007t_read_reg(state, 0xd3, &id); if (mxl_fail(ret)) goto fail; @@ -797,12 +947,8 @@ static int mxl5007t_get_chip_id(struct mxl5007t_state *state) case MxL_5007_V2_200_F2: name = "MxL5007.v2.200.f2"; break; - case MxL_5007_V4: - name = "MxL5007T.v4"; - break; default: name = "MxL5007T"; - printk(KERN_WARNING "%s: unknown rev (%02x)\n", __func__, id); id = MxL_UNKNOWN_ID; } state->chip_id = id; @@ -829,7 +975,7 @@ struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, mutex_lock(&mxl5007t_list_mutex); instance = hybrid_tuner_request_state(struct mxl5007t_state, state, hybrid_tuner_instance_list, - i2c, addr, "mxl5007t"); + i2c, addr, "mxl5007"); switch (instance) { case 0: goto fail; @@ -872,7 +1018,7 @@ EXPORT_SYMBOL_GPL(mxl5007t_attach); MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver"); MODULE_AUTHOR("Michael Krufky "); MODULE_LICENSE("GPL"); -MODULE_VERSION("0.2"); +MODULE_VERSION("0.1"); /* * Overrides for Emacs so that we follow Linus's tabbing style. diff --git a/trunk/drivers/media/common/tuners/tda18271-common.c b/trunk/drivers/media/common/tuners/tda18271-common.c index fc76c30e24f1..6fb5b4586569 100644 --- a/trunk/drivers/media/common/tuners/tda18271-common.c +++ b/trunk/drivers/media/common/tuners/tda18271-common.c @@ -490,9 +490,9 @@ int tda18271_set_standby_mode(struct dvb_frontend *fe, tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt); regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */ - regs[R_EP3] |= (sm ? (1 << 7) : 0) | - (sm_lt ? (1 << 6) : 0) | - (sm_xt ? (1 << 5) : 0); + regs[R_EP3] |= sm ? (1 << 7) : 0 | + sm_lt ? (1 << 6) : 0 | + sm_xt ? (1 << 5) : 0; return tda18271_write_regs(fe, R_EP3, 1); } diff --git a/trunk/drivers/media/common/tuners/tda18271-fe.c b/trunk/drivers/media/common/tuners/tda18271-fe.c index b10935630154..1b48b5d0bf1e 100644 --- a/trunk/drivers/media/common/tuners/tda18271-fe.c +++ b/trunk/drivers/media/common/tuners/tda18271-fe.c @@ -818,38 +818,6 @@ static int tda18271_init(struct dvb_frontend *fe) return ret; } -/* ------------------------------------------------------------------ */ - -static int tda18271_agc(struct dvb_frontend *fe) -{ - struct tda18271_priv *priv = fe->tuner_priv; - int ret = 0; - - switch (priv->config) { - case 0: - /* no LNA */ - tda_dbg("no agc configuration provided\n"); - break; - case 3: - /* switch with GPIO of saa713x */ - tda_dbg("invoking callback\n"); - if (fe->callback) - ret = fe->callback(priv->i2c_props.adap->algo_data, - DVB_FRONTEND_COMPONENT_TUNER, - TDA18271_CALLBACK_CMD_AGC_ENABLE, - priv->mode); - break; - case 1: - case 2: - default: - /* n/a - currently not supported */ - tda_err("unsupported configuration: %d\n", priv->config); - ret = -EINVAL; - break; - } - return ret; -} - static int tda18271_tune(struct dvb_frontend *fe, struct tda18271_std_map_item *map, u32 freq, u32 bw) { @@ -859,10 +827,6 @@ static int tda18271_tune(struct dvb_frontend *fe, tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n", freq, map->if_freq, bw, map->agc_mode, map->std); - ret = tda18271_agc(fe); - if (tda_fail(ret)) - tda_warn("failed to configure agc\n"); - ret = tda18271_init(fe); if (tda_fail(ret)) goto fail; @@ -1195,7 +1159,6 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, /* new tuner instance */ priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; priv->role = (cfg) ? cfg->role : TDA18271_MASTER; - priv->config = (cfg) ? cfg->config : 0; priv->cal_initialized = false; mutex_init(&priv->lock); diff --git a/trunk/drivers/media/common/tuners/tda18271-priv.h b/trunk/drivers/media/common/tuners/tda18271-priv.h index 74beb28806f8..81a739365f8c 100644 --- a/trunk/drivers/media/common/tuners/tda18271-priv.h +++ b/trunk/drivers/media/common/tuners/tda18271-priv.h @@ -91,6 +91,11 @@ enum tda18271_pll { TDA18271_CAL_PLL, }; +enum tda18271_mode { + TDA18271_ANALOG, + TDA18271_DIGITAL, +}; + struct tda18271_map_layout; enum tda18271_ver { @@ -109,7 +114,6 @@ struct tda18271_priv { enum tda18271_i2c_gate gate; enum tda18271_ver id; - unsigned int config; /* interface to saa713x / tda829x */ unsigned int tm_rfcal; unsigned int cal_initialized:1; unsigned int small_i2c:1; diff --git a/trunk/drivers/media/common/tuners/tda18271.h b/trunk/drivers/media/common/tuners/tda18271.h index 53a9892a18d0..7db9831c0cb0 100644 --- a/trunk/drivers/media/common/tuners/tda18271.h +++ b/trunk/drivers/media/common/tuners/tda18271.h @@ -79,16 +79,6 @@ struct tda18271_config { /* some i2c providers cant write all 39 registers at once */ unsigned int small_i2c:1; - - /* interface to saa713x / tda829x */ - unsigned int config; -}; - -#define TDA18271_CALLBACK_CMD_AGC_ENABLE 0 - -enum tda18271_mode { - TDA18271_ANALOG = 0, - TDA18271_DIGITAL, }; #if defined(CONFIG_MEDIA_TUNER_TDA18271) || (defined(CONFIG_MEDIA_TUNER_TDA18271_MODULE) && defined(MODULE)) diff --git a/trunk/drivers/media/common/tuners/tda827x.c b/trunk/drivers/media/common/tuners/tda827x.c index 36a7bc7585ab..f4d931f14fad 100644 --- a/trunk/drivers/media/common/tuners/tda827x.c +++ b/trunk/drivers/media/common/tuners/tda827x.c @@ -132,31 +132,11 @@ static const struct tda827x_data tda827x_table[] = { { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} }; -static int tuner_transfer(struct dvb_frontend *fe, - struct i2c_msg *msg, - const int size) -{ - int rc; - struct tda827x_priv *priv = fe->tuner_priv; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - rc = i2c_transfer(priv->i2c_adap, msg, size); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - if (rc >= 0 && rc != size) - return -EIO; - - return rc; -} - static int tda827xo_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct tda827x_priv *priv = fe->tuner_priv; u8 buf[14]; - int rc; struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, .buf = buf, .len = sizeof(buf) }; @@ -203,29 +183,27 @@ static int tda827xo_set_params(struct dvb_frontend *fe, buf[13] = 0x40; msg.len = 14; - rc = tuner_transfer(fe, &msg, 1); - if (rc < 0) - goto err; - + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { + printk("%s: could not write to tuner at addr: 0x%02x\n", + __func__, priv->i2c_addr << 1); + return -EIO; + } msleep(500); /* correct CP value */ buf[0] = 0x30; buf[1] = 0x50 + tda827x_table[i].cp; msg.len = 2; - rc = tuner_transfer(fe, &msg, 1); - if (rc < 0) - goto err; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); priv->frequency = params->frequency; priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; return 0; - -err: - printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n", - __func__, priv->i2c_addr << 1); - return rc; } static int tda827xo_sleep(struct dvb_frontend *fe) @@ -236,7 +214,9 @@ static int tda827xo_sleep(struct dvb_frontend *fe) .buf = buf, .len = sizeof(buf) }; dprintk("%s:\n", __func__); - tuner_transfer(fe, &msg, 1); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); if (priv->cfg && priv->cfg->sleep) priv->cfg->sleep(fe); @@ -286,44 +266,44 @@ static int tda827xo_set_analog_params(struct dvb_frontend *fe, msg.buf = tuner_reg; msg.len = 8; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); msg.buf = reg2; msg.len = 2; reg2[0] = 0x80; reg2[1] = 0; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); reg2[0] = 0x60; reg2[1] = 0xbf; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); reg2[0] = 0x30; reg2[1] = tuner_reg[4] + 0x80; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); msleep(1); reg2[0] = 0x30; reg2[1] = tuner_reg[4] + 4; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); msleep(1); reg2[0] = 0x30; reg2[1] = tuner_reg[4]; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); msleep(550); reg2[0] = 0x30; reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); reg2[0] = 0x60; reg2[1] = 0x3f; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); reg2[0] = 0x80; reg2[1] = 0x08; /* Vsync en */ - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); priv->frequency = params->frequency; @@ -337,7 +317,7 @@ static void tda827xo_agcf(struct dvb_frontend *fe) struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, .buf = data, .len = 2}; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); } /* ------------------------------------------------------------------ */ @@ -351,7 +331,7 @@ struct tda827xa_data { u8 gc3; }; -static struct tda827xa_data tda827xa_dvbt[] = { +static const struct tda827xa_data tda827xa_dvbt[] = { { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1}, { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, @@ -381,36 +361,6 @@ static struct tda827xa_data tda827xa_dvbt[] = { { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} }; -static struct tda827xa_data tda827xa_dvbc[] = { - { .lomax = 50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3}, - { .lomax = 58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3}, - { .lomax = 69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3}, - { .lomax = 83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3}, - { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3}, - { .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1}, - { .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1}, - { .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1}, - { .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1}, - { .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1}, - { .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1}, - { .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3}, - { .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3}, - { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1}, - { .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3}, - { .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3}, - { .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1}, - { .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, - { .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1}, - { .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, - { .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1}, - { .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, - { .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1}, - { .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, - { .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, - { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1}, - { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} -}; - static struct tda827xa_data tda827xa_analog[] = { { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3}, { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, @@ -448,8 +398,13 @@ static int tda827xa_sleep(struct dvb_frontend *fe) .buf = buf, .len = sizeof(buf) }; dprintk("%s:\n", __func__); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); if (priv->cfg && priv->cfg->sleep) priv->cfg->sleep(fe); @@ -500,7 +455,7 @@ static void tda827xa_lna_gain(struct dvb_frontend *fe, int high, buf[1] = high ? 0 : 1; if (priv->cfg->config == 2) buf[1] = high ? 1 : 0; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); break; case 3: /* switch with GPIO of saa713x */ if (fe->callback) @@ -514,13 +469,12 @@ static int tda827xa_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct tda827x_priv *priv = fe->tuner_priv; - struct tda827xa_data *frequency_map = tda827xa_dvbt; u8 buf[11]; struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, .buf = buf, .len = sizeof(buf) }; - int i, tuner_freq, if_freq, rc; + int i, tuner_freq, if_freq; u32 N; dprintk("%s:\n", __func__); @@ -541,58 +495,56 @@ static int tda827xa_set_params(struct dvb_frontend *fe, } tuner_freq = params->frequency + if_freq; - if (fe->ops.info.type == FE_QAM) { - dprintk("%s select tda827xa_dvbc\n", __func__); - frequency_map = tda827xa_dvbc; - } - i = 0; - while (frequency_map[i].lomax < tuner_freq) { - if (frequency_map[i + 1].lomax == 0) + while (tda827xa_dvbt[i].lomax < tuner_freq) { + if(tda827xa_dvbt[i + 1].lomax == 0) break; i++; } - N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd; + N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd; buf[0] = 0; // subaddress buf[1] = N >> 8; buf[2] = N & 0xff; buf[3] = 0; buf[4] = 0x16; - buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) + - frequency_map[i].sbs; - buf[6] = 0x4b + (frequency_map[i].gc3 << 4); + buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) + + tda827xa_dvbt[i].sbs; + buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4); buf[7] = 0x1c; buf[8] = 0x06; buf[9] = 0x24; buf[10] = 0x00; msg.len = 11; - rc = tuner_transfer(fe, &msg, 1); - if (rc < 0) - goto err; - + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { + printk("%s: could not write to tuner at addr: 0x%02x\n", + __func__, priv->i2c_addr << 1); + return -EIO; + } buf[0] = 0x90; buf[1] = 0xff; buf[2] = 0x60; buf[3] = 0x00; buf[4] = 0x59; // lpsel, for 6MHz + 2 msg.len = 5; - rc = tuner_transfer(fe, &msg, 1); - if (rc < 0) - goto err; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); buf[0] = 0xa0; buf[1] = 0x40; msg.len = 2; - rc = tuner_transfer(fe, &msg, 1); - if (rc < 0) - goto err; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); msleep(11); msg.flags = I2C_M_RD; - rc = tuner_transfer(fe, &msg, 1); - if (rc < 0) - goto err; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); msg.flags = 0; buf[1] >>= 4; @@ -601,55 +553,49 @@ static int tda827xa_set_params(struct dvb_frontend *fe, tda827xa_lna_gain(fe, 0, NULL); buf[0] = 0x60; buf[1] = 0x0c; - rc = tuner_transfer(fe, &msg, 1); - if (rc < 0) - goto err; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); } buf[0] = 0xc0; buf[1] = 0x99; // lpsel, for 6MHz + 2 - rc = tuner_transfer(fe, &msg, 1); - if (rc < 0) - goto err; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); buf[0] = 0x60; buf[1] = 0x3c; - rc = tuner_transfer(fe, &msg, 1); - if (rc < 0) - goto err; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); /* correct CP value */ buf[0] = 0x30; - buf[1] = 0x10 + frequency_map[i].scr; - rc = tuner_transfer(fe, &msg, 1); - if (rc < 0) - goto err; + buf[1] = 0x10 + tda827xa_dvbt[i].scr; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); msleep(163); buf[0] = 0xc0; buf[1] = 0x39; // lpsel, for 6MHz + 2 - rc = tuner_transfer(fe, &msg, 1); - if (rc < 0) - goto err; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); msleep(3); /* freeze AGC1 */ buf[0] = 0x50; - buf[1] = 0x4f + (frequency_map[i].gc3 << 4); - rc = tuner_transfer(fe, &msg, 1); - if (rc < 0) - goto err; + buf[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); priv->frequency = params->frequency; priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; - return 0; - -err: - printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n", - __func__, priv->i2c_addr << 1); - return rc; } @@ -697,7 +643,7 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe, tuner_reg[9] = 0x20; tuner_reg[10] = 0x00; msg.len = 11; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); tuner_reg[0] = 0x90; tuner_reg[1] = 0xff; @@ -705,19 +651,19 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe, tuner_reg[3] = 0; tuner_reg[4] = 0x99 + (priv->lpsel << 1); msg.len = 5; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); tuner_reg[0] = 0xa0; tuner_reg[1] = 0xc0; msg.len = 2; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); tuner_reg[0] = 0x30; tuner_reg[1] = 0x10 + tda827xa_analog[i].scr; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); msg.flags = I2C_M_RD; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); msg.flags = 0; tuner_reg[1] >>= 4; dprintk("AGC2 gain is: %d\n", tuner_reg[1]); @@ -727,24 +673,24 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe, msleep(100); tuner_reg[0] = 0x60; tuner_reg[1] = 0x3c; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); msleep(163); tuner_reg[0] = 0x50; tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4); - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); tuner_reg[0] = 0x80; tuner_reg[1] = 0x28; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); tuner_reg[0] = 0xb0; tuner_reg[1] = 0x01; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); tuner_reg[0] = 0xc0; tuner_reg[1] = 0x19 + (priv->lpsel << 1); - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); priv->frequency = params->frequency; @@ -757,7 +703,7 @@ static void tda827xa_agcf(struct dvb_frontend *fe) unsigned char data[] = {0x80, 0x2c}; struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0, .buf = data, .len = 2}; - tuner_transfer(fe, &msg, 1); + i2c_transfer(priv->i2c_adap, &msg, 1); } /* ------------------------------------------------------------------ */ @@ -846,19 +792,16 @@ static struct dvb_tuner_ops tda827xa_tuner_ops = { }; static int tda827x_probe_version(struct dvb_frontend *fe) -{ - u8 data; - int rc; +{ u8 data; struct tda827x_priv *priv = fe->tuner_priv; struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD, .buf = &data, .len = 1 }; - - rc = tuner_transfer(fe, &msg, 1); - - if (rc < 0) { + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { printk("%s: could not read from tuner at addr: 0x%02x\n", __func__, msg.addr << 1); - return rc; + return -EIO; } if ((data & 0x3c) == 0) { dprintk("tda827x tuner found\n"); diff --git a/trunk/drivers/media/common/tuners/tda8290.c b/trunk/drivers/media/common/tuners/tda8290.c index 064d14c8d7b2..4b8662edb7cb 100644 --- a/trunk/drivers/media/common/tuners/tda8290.c +++ b/trunk/drivers/media/common/tuners/tda8290.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include "tuner-i2c.h" #include "tda8290.h" #include "tda827x.h" @@ -566,11 +566,8 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) u8 data; struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 }; - if (!analog_ops->i2c_gate_ctrl) { - printk(KERN_ERR "tda8290: no gate control were provided!\n"); - + if (NULL == analog_ops->i2c_gate_ctrl) return -EINVAL; - } analog_ops->i2c_gate_ctrl(fe, 1); @@ -618,13 +615,11 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) if (ret != 1) { tuner_warn("tuner access failed!\n"); - analog_ops->i2c_gate_ctrl(fe, 0); return -EREMOTEIO; } if ((data == 0x83) || (data == 0x84)) { priv->ver |= TDA18271; - tda829x_tda18271_config.config = priv->cfg.config; dvb_attach(tda18271_attach, fe, priv->tda827x_addr, priv->i2c_props.adap, &tda829x_tda18271_config); } else { diff --git a/trunk/drivers/media/common/tuners/tea5761.c b/trunk/drivers/media/common/tuners/tea5761.c index 60ed872f3d44..b23dadeecd05 100644 --- a/trunk/drivers/media/common/tuners/tea5761.c +++ b/trunk/drivers/media/common/tuners/tea5761.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include "tuner-i2c.h" #include "tea5761.h" diff --git a/trunk/drivers/media/common/tuners/tea5767.c b/trunk/drivers/media/common/tuners/tea5767.c index 223a226d20a1..1f5646334a8f 100644 --- a/trunk/drivers/media/common/tuners/tea5767.c +++ b/trunk/drivers/media/common/tuners/tea5767.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include "tuner-i2c.h" #include "tea5767.h" diff --git a/trunk/drivers/media/common/tuners/xc5000.c b/trunk/drivers/media/common/tuners/xc5000.c index b54598550dc4..493ce93caf43 100644 --- a/trunk/drivers/media/common/tuners/xc5000.c +++ b/trunk/drivers/media/common/tuners/xc5000.c @@ -739,10 +739,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe, dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", __func__, params->frequency); - /* Fix me: it could be air. */ - priv->rf_mode = params->mode; - if (params->mode > XC_RF_MODE_CABLE) - priv->rf_mode = XC_RF_MODE_CABLE; + priv->rf_mode = XC_RF_MODE_CABLE; /* Fix me: it could be air. */ /* params->frequency is in units of 62.5khz */ priv->freq_hz = params->frequency * 62500; @@ -973,6 +970,8 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, case 1: /* new tuner instance */ priv->bandwidth = BANDWIDTH_6_MHZ; + priv->if_khz = cfg->if_khz; + fe->tuner_priv = priv; break; default: @@ -981,13 +980,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, break; } - if (priv->if_khz == 0) { - /* If the IF hasn't been set yet, use the value provided by - the caller (occurs in hybrid devices where the analog - call to xc5000_attach occurs before the digital side) */ - priv->if_khz = cfg->if_khz; - } - /* Check if firmware has been loaded. It is possible that another instance of the driver has loaded the firmware. */ diff --git a/trunk/drivers/media/dvb/b2c2/Kconfig b/trunk/drivers/media/dvb/b2c2/Kconfig index 9e5781400744..a8c6249c4099 100644 --- a/trunk/drivers/media/dvb/b2c2/Kconfig +++ b/trunk/drivers/media/dvb/b2c2/Kconfig @@ -13,7 +13,7 @@ config DVB_B2C2_FLEXCOP select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE select DVB_ISL6421 if !DVB_FE_CUSTOMISE select DVB_CX24123 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE select DVB_TUNER_CX24113 if !DVB_FE_CUSTOMISE help Support for the digital TV receiver chip made by B2C2 Inc. included in diff --git a/trunk/drivers/media/dvb/b2c2/Makefile b/trunk/drivers/media/dvb/b2c2/Makefile index b97cf7208a18..d9db066f9854 100644 --- a/trunk/drivers/media/dvb/b2c2/Makefile +++ b/trunk/drivers/media/dvb/b2c2/Makefile @@ -2,6 +2,7 @@ b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \ flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o + ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),) b2c2-flexcop-objs += flexcop-dma.o endif diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-common.h b/trunk/drivers/media/dvb/b2c2/flexcop-common.h index 3e1c472092ab..8ce06336e76f 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-common.h +++ b/trunk/drivers/media/dvb/b2c2/flexcop-common.h @@ -28,14 +28,11 @@ /* Steal from usb.h */ #undef err -#define err(format, arg...) \ - printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg) +#define err(format, arg...) printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg) #undef info -#define info(format, arg...) \ - printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg) +#define info(format, arg...) printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg) #undef warn -#define warn(format, arg...) \ - printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg) +#define warn(format, arg...) printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg) struct flexcop_dma { struct pci_dev *pdev; @@ -94,14 +91,16 @@ struct flexcop_device { int fullts_streaming_state; /* bus specific callbacks */ - flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *, - flexcop_ibi_register); - int (*write_ibi_reg) (struct flexcop_device *, - flexcop_ibi_register, flexcop_ibi_value); - int (*i2c_request) (struct flexcop_i2c_adapter *, + flexcop_ibi_value (*read_ibi_reg) (struct flexcop_device *, flexcop_ibi_register); + int (*write_ibi_reg) (struct flexcop_device *, flexcop_ibi_register, flexcop_ibi_value); + + + int (*i2c_request) (struct flexcop_i2c_adapter*, flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len); - int (*stream_control) (struct flexcop_device *, int); + int (*stream_control) (struct flexcop_device*, int); + int (*get_mac_addr) (struct flexcop_device *fc, int extended); + void *bus_specific; }; @@ -112,28 +111,22 @@ void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len); void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no); struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len); -void flexcop_device_kfree(struct flexcop_device *); +void flexcop_device_kfree(struct flexcop_device*); -int flexcop_device_initialize(struct flexcop_device *); +int flexcop_device_initialize(struct flexcop_device*); void flexcop_device_exit(struct flexcop_device *fc); + void flexcop_reset_block_300(struct flexcop_device *fc); /* from flexcop-dma.c */ -int flexcop_dma_allocate(struct pci_dev *pdev, - struct flexcop_dma *dma, u32 size); +int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size); void flexcop_dma_free(struct flexcop_dma *dma); -int flexcop_dma_control_timer_irq(struct flexcop_device *fc, - flexcop_dma_index_t no, int onoff); -int flexcop_dma_control_size_irq(struct flexcop_device *fc, - flexcop_dma_index_t no, int onoff); -int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, - flexcop_dma_index_t dma_idx); -int flexcop_dma_xfer_control(struct flexcop_device *fc, - flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, - int onoff); -int flexcop_dma_config_timer(struct flexcop_device *fc, - flexcop_dma_index_t dma_idx, u8 cycles); +int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); +int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); +int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx); +int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff); +int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles); /* from flexcop-eeprom.c */ /* the PCI part uses this call to get the MAC address, the USB part has its own */ @@ -148,15 +141,13 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter*, flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len); /* from flexcop-sram.c */ -int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, - flexcop_sram_dest_target_t target); +int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target); void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s); -void flexcop_sram_ctrl(struct flexcop_device *fc, - int usb_wan, int sramdma, int maximumfill); +void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill); /* global prototypes for the flexcop-chip */ /* from flexcop-fe-tuner.c */ -int flexcop_frontend_init(struct flexcop_device *fc); +int flexcop_frontend_init(struct flexcop_device *card); void flexcop_frontend_exit(struct flexcop_device *fc); /* from flexcop-i2c.c */ @@ -168,14 +159,11 @@ int flexcop_sram_init(struct flexcop_device *fc); /* from flexcop-misc.c */ void flexcop_determine_revision(struct flexcop_device *fc); -void flexcop_device_name(struct flexcop_device *fc, - const char *prefix, const char *suffix); -void flexcop_dump_reg(struct flexcop_device *fc, - flexcop_ibi_register reg, int num); +void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const char *suffix); +void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num); /* from flexcop-hw-filter.c */ -int flexcop_pid_feed_control(struct flexcop_device *fc, - struct dvb_demux_feed *dvbdmxfeed, int onoff); +int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff); void flexcop_hw_filter_init(struct flexcop_device *fc); void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff); diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-dma.c b/trunk/drivers/media/dvb/b2c2/flexcop-dma.c index 2881e0d956ad..26f0011a5078 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-dma.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-dma.c @@ -1,12 +1,13 @@ /* - * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * flexcop-dma.c - configuring and controlling the DMA of the FlexCop - * see flexcop.c for copyright information + * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III + * + * flexcop-dma.c - methods for configuring and controlling the DMA of the FlexCop. + * + * see flexcop.c for copyright information. */ #include "flexcop.h" -int flexcop_dma_allocate(struct pci_dev *pdev, - struct flexcop_dma *dma, u32 size) +int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size) { u8 *tcpu; dma_addr_t tdma = 0; @@ -31,8 +32,7 @@ EXPORT_SYMBOL(flexcop_dma_allocate); void flexcop_dma_free(struct flexcop_dma *dma) { - pci_free_consistent(dma->pdev, dma->size*2, - dma->cpu_addr0, dma->dma_addr0); + pci_free_consistent(dma->pdev, dma->size*2,dma->cpu_addr0, dma->dma_addr0); memset(dma,0,sizeof(struct flexcop_dma)); } EXPORT_SYMBOL(flexcop_dma_free); @@ -44,8 +44,8 @@ int flexcop_dma_config(struct flexcop_device *fc, flexcop_ibi_value v0x0,v0x4,v0xc; v0x0.raw = v0x4.raw = v0xc.raw = 0; - v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2; - v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2; + v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2; + v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2; v0x4.dma_0x4_write.dma_addr_size = dma->size / 4; if ((dma_idx & FC_DMA_1) == dma_idx) { @@ -57,8 +57,7 @@ int flexcop_dma_config(struct flexcop_device *fc, fc->write_ibi_reg(fc,dma2_014,v0x4); fc->write_ibi_reg(fc,dma2_01c,v0xc); } else { - err("either DMA1 or DMA2 can be configured within one " - "flexcop_dma_config call."); + err("either DMA1 or DMA2 can be configured at the within one flexcop_dma_config call."); return -EINVAL; } @@ -82,8 +81,7 @@ int flexcop_dma_xfer_control(struct flexcop_device *fc, r0x0 = dma2_010; r0xc = dma2_01c; } else { - err("either transfer DMA1 or DMA2 can be started within one " - "flexcop_dma_xfer_control call."); + err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call."); return -EINVAL; } @@ -156,7 +154,8 @@ EXPORT_SYMBOL(flexcop_dma_control_timer_irq); /* 1 cycles = 1.97 msec */ int flexcop_dma_config_timer(struct flexcop_device *fc, - flexcop_dma_index_t dma_idx, u8 cycles) + flexcop_dma_index_t dma_idx, + u8 cycles) { flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014; flexcop_ibi_value v = fc->read_ibi_reg(fc,r); diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-eeprom.c b/trunk/drivers/media/dvb/b2c2/flexcop-eeprom.c index a25373a9bd84..8a8ae8a3e6ba 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-eeprom.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-eeprom.c @@ -1,7 +1,9 @@ /* - * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading) - * see flexcop.c for copyright information + * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III + * + * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading is used) + * + * see flexcop.c for copyright information. */ #include "flexcop.h" @@ -12,17 +14,17 @@ static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len) return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len); } -static int eeprom_lrc_write(struct adapter *adapter, u32 addr, - u32 len, u8 *wbuf, u8 *rbuf, int retries) +static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries) { -int i; + int i; -for (i = 0; i < retries; i++) { - if (eeprom_write(adapter, addr, wbuf, len) == len) { - if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1) - return 1; + for (i = 0; i < retries; i++) { + if (eeprom_write(adapter, addr, wbuf, len) == len) { + if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1) + return 1; } } + return 0; } @@ -37,10 +39,12 @@ static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len) return 0; memcpy(wbuf, key, len); + wbuf[16] = 0; wbuf[17] = 0; wbuf[18] = 0; wbuf[19] = calc_lrc(wbuf, 19); + return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4); } @@ -55,6 +59,7 @@ static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len) return 0; memcpy(key, buf, len); + return 1; } @@ -69,7 +74,9 @@ static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac) tmp[3] = mac[5]; tmp[4] = mac[6]; tmp[5] = mac[7]; + } else { + tmp[0] = mac[0]; tmp[1] = mac[1]; tmp[2] = mac[2]; @@ -83,11 +90,11 @@ static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac) if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8) return 1; + return 0; } -static int flexcop_eeprom_read(struct flexcop_device *fc, - u16 addr, u8 *buf, u16 len) +static int flexcop_eeprom_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len) { return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len); } @@ -103,8 +110,7 @@ static u8 calc_lrc(u8 *buf, int len) return sum; } -static int flexcop_eeprom_request(struct flexcop_device *fc, - flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries) +static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries) { int i,ret = 0; u8 chipaddr = 0x50 | ((addr >> 8) & 3); @@ -117,8 +123,7 @@ static int flexcop_eeprom_request(struct flexcop_device *fc, return ret; } -static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, - u8 *buf, u16 len, int retries) +static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len, int retries) { int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries); if (ret == 0) @@ -128,7 +133,8 @@ static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, } /* JJ's comment about extended == 1: it is not presently used anywhere but was - * added to the low-level functions for possible support of EUI64 */ + * added to the low-level functions for possible support of EUI64 + */ int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended) { u8 buf[8]; @@ -136,9 +142,12 @@ int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended) if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) { if (extended != 0) { - err("TODO: extended (EUI64) MAC addresses aren't " - "completely supported yet"); + err("TODO: extended (EUI64) MAC addresses aren't completely supported yet"); ret = -EINVAL; +/* memcpy(fc->dvb_adapter.proposed_mac,buf,3); + mac[3] = 0xfe; + mac[4] = 0xff; + memcpy(&fc->dvb_adapter.proposed_mac[3],&buf[5],3); */ } else memcpy(fc->dvb_adapter.proposed_mac,buf,6); } diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/trunk/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index f7afab5944cf..5cded3708541 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-fe-tuner.c @@ -592,14 +592,14 @@ int flexcop_frontend_init(struct flexcop_device *fc) fc->fe_sleep = ops->sleep; ops->sleep = flexcop_sleep; - fc->dev_type = FC_SKY_REV26; + fc->dev_type = FC_SKY; goto fe_found; } /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */ fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c); if (fc->fe != NULL) { - fc->dev_type = FC_AIR_DVBT; + fc->dev_type = FC_AIR_DVB; fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; goto fe_found; } @@ -653,7 +653,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) fc->fe_sleep = ops->sleep; ops->sleep = flexcop_sleep; - fc->dev_type = FC_SKY_REV23; + fc->dev_type = FC_SKY_OLD; goto fe_found; } diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/trunk/drivers/media/dvb/b2c2/flexcop-hw-filter.c index 77e45475f4c7..451974ba32f3 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-hw-filter.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-hw-filter.c @@ -1,30 +1,33 @@ /* - * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * flexcop-hw-filter.c - pid and mac address filtering and control functions - * see flexcop.c for copyright information + * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III + * + * flexcop-hw-filter.c - pid and mac address filtering and corresponding control functions. + * + * see flexcop.c for copyright information. */ #include "flexcop.h" static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff) { - flexcop_set_ibi_value(ctrl_208, Rcv_Data_sig, onoff); - deb_ts("rcv_data is now: '%s'\n", onoff ? "on" : "off"); + flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff); + + deb_ts("rcv_data is now: '%s'\n",onoff ? "on" : "off"); } void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff) { - flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff); + flexcop_set_ibi_value(ctrl_208,SMC_Enable_sig,onoff); } static void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff) { - flexcop_set_ibi_value(ctrl_208, Null_filter_sig, onoff); + flexcop_set_ibi_value(ctrl_208,Null_filter_sig,onoff); } void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]) { - flexcop_ibi_value v418, v41c; - v41c = fc->read_ibi_reg(fc, mac_address_41c); + flexcop_ibi_value v418,v41c; + v41c = fc->read_ibi_reg(fc,mac_address_41c); v418.mac_address_418.MAC1 = mac[0]; v418.mac_address_418.MAC2 = mac[1]; @@ -33,28 +36,27 @@ void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]) v41c.mac_address_41c.MAC7 = mac[4]; v41c.mac_address_41c.MAC8 = mac[5]; - fc->write_ibi_reg(fc, mac_address_418, v418); - fc->write_ibi_reg(fc, mac_address_41c, v41c); + fc->write_ibi_reg(fc,mac_address_418,v418); + fc->write_ibi_reg(fc,mac_address_41c,v41c); } void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff) { - flexcop_set_ibi_value(ctrl_208, MAC_filter_Mode_sig, onoff); + flexcop_set_ibi_value(ctrl_208,MAC_filter_Mode_sig,onoff); } -static void flexcop_pid_group_filter(struct flexcop_device *fc, - u16 pid, u16 mask) +static void flexcop_pid_group_filter(struct flexcop_device *fc, u16 pid, u16 mask) { /* index_reg_310.extra_index_reg need to 0 or 7 to work */ flexcop_ibi_value v30c; v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid; v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask; - fc->write_ibi_reg(fc, pid_filter_30c, v30c); + fc->write_ibi_reg(fc,pid_filter_30c,v30c); } static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff) { - flexcop_set_ibi_value(ctrl_208, Mask_filter_sig, onoff); + flexcop_set_ibi_value(ctrl_208,Mask_filter_sig,onoff); } /* this fancy define reduces the code size of the quite similar PID controlling of @@ -63,112 +65,91 @@ static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff) #define pid_ctrl(vregname,field,enablefield,trans_field,transval) \ flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \ -v208 = fc->read_ibi_reg(fc, ctrl_208); \ -vpid.vregname.field = onoff ? pid : 0x1fff; \ -vpid.vregname.trans_field = transval; \ -v208.ctrl_208.enablefield = onoff; \ -fc->write_ibi_reg(fc, vregname, vpid); \ -fc->write_ibi_reg(fc, ctrl_208, v208); + v208 = fc->read_ibi_reg(fc, ctrl_208); \ +\ + vpid.vregname.field = onoff ? pid : 0x1fff; \ + vpid.vregname.trans_field = transval; \ + v208.ctrl_208.enablefield = onoff; \ +\ + fc->write_ibi_reg(fc,vregname,vpid); \ + fc->write_ibi_reg(fc,ctrl_208,v208); -static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc, - u16 pid, int onoff) +static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) { - pid_ctrl(pid_filter_300, Stream1_PID, Stream1_filter_sig, - Stream1_trans, 0); + pid_ctrl(pid_filter_300,Stream1_PID,Stream1_filter_sig,Stream1_trans,0); } -static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc, - u16 pid, int onoff) +static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) { - pid_ctrl(pid_filter_300, Stream2_PID, Stream2_filter_sig, - Stream2_trans, 0); + pid_ctrl(pid_filter_300,Stream2_PID,Stream2_filter_sig,Stream2_trans,0); } -static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc, - u16 pid, int onoff) +static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) { - pid_ctrl(pid_filter_304, PCR_PID, PCR_filter_sig, PCR_trans, 0); + pid_ctrl(pid_filter_304,PCR_PID,PCR_filter_sig,PCR_trans,0); } -static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc, - u16 pid, int onoff) +static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) { - pid_ctrl(pid_filter_304, PMT_PID, PMT_filter_sig, PMT_trans, 0); + pid_ctrl(pid_filter_304,PMT_PID,PMT_filter_sig,PMT_trans,0); } -static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc, - u16 pid, int onoff) +static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) { - pid_ctrl(pid_filter_308, EMM_PID, EMM_filter_sig, EMM_trans, 0); + pid_ctrl(pid_filter_308,EMM_PID,EMM_filter_sig,EMM_trans,0); } -static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc, - u16 pid, int onoff) +static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) { - pid_ctrl(pid_filter_308, ECM_PID, ECM_filter_sig, ECM_trans, 0); + pid_ctrl(pid_filter_308,ECM_PID,ECM_filter_sig,ECM_trans,0); } -static void flexcop_pid_control(struct flexcop_device *fc, - int index, u16 pid, int onoff) +static void flexcop_pid_control(struct flexcop_device *fc, int index, u16 pid,int onoff) { if (pid == 0x2000) return; - deb_ts("setting pid: %5d %04x at index %d '%s'\n", - pid, pid, index, onoff ? "on" : "off"); + deb_ts("setting pid: %5d %04x at index %d '%s'\n",pid,pid,index,onoff ? "on" : "off"); /* We could use bit magic here to reduce source code size. * I decided against it, but to use the real register names */ switch (index) { - case 0: - flexcop_pid_Stream1_PID_ctrl(fc, pid, onoff); - break; - case 1: - flexcop_pid_Stream2_PID_ctrl(fc, pid, onoff); - break; - case 2: - flexcop_pid_PCR_PID_ctrl(fc, pid, onoff); - break; - case 3: - flexcop_pid_PMT_PID_ctrl(fc, pid, onoff); - break; - case 4: - flexcop_pid_EMM_PID_ctrl(fc, pid, onoff); - break; - case 5: - flexcop_pid_ECM_PID_ctrl(fc, pid, onoff); - break; - default: - if (fc->has_32_hw_pid_filter && index < 38) { - flexcop_ibi_value vpid, vid; - - /* set the index */ - vid = fc->read_ibi_reg(fc, index_reg_310); - vid.index_reg_310.index_reg = index - 6; - fc->write_ibi_reg(fc, index_reg_310, vid); - - vpid = fc->read_ibi_reg(fc, pid_n_reg_314); - vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff; - vpid.pid_n_reg_314.PID_enable_bit = onoff; - fc->write_ibi_reg(fc, pid_n_reg_314, vpid); - } - break; + case 0: flexcop_pid_Stream1_PID_ctrl(fc,pid,onoff); break; + case 1: flexcop_pid_Stream2_PID_ctrl(fc,pid,onoff); break; + case 2: flexcop_pid_PCR_PID_ctrl(fc,pid,onoff); break; + case 3: flexcop_pid_PMT_PID_ctrl(fc,pid,onoff); break; + case 4: flexcop_pid_EMM_PID_ctrl(fc,pid,onoff); break; + case 5: flexcop_pid_ECM_PID_ctrl(fc,pid,onoff); break; + default: + if (fc->has_32_hw_pid_filter && index < 38) { + flexcop_ibi_value vpid,vid; + + /* set the index */ + vid = fc->read_ibi_reg(fc,index_reg_310); + vid.index_reg_310.index_reg = index - 6; + fc->write_ibi_reg(fc,index_reg_310, vid); + + vpid = fc->read_ibi_reg(fc,pid_n_reg_314); + vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff; + vpid.pid_n_reg_314.PID_enable_bit = onoff; + fc->write_ibi_reg(fc,pid_n_reg_314, vpid); + } + break; } } -static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff) +static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc,int onoff) { if (fc->fullts_streaming_state != onoff) { deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling"); flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff)); - flexcop_pid_group_filter_ctrl(fc, onoff); + flexcop_pid_group_filter_ctrl(fc,onoff); fc->fullts_streaming_state = onoff; } return 0; } -int flexcop_pid_feed_control(struct flexcop_device *fc, - struct dvb_demux_feed *dvbdmxfeed, int onoff) +int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff) { int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32; @@ -183,25 +164,24 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, * - or the requested pid is 0x2000 */ if (!fc->pid_filtering && fc->feedcount == onoff) - flexcop_toggle_fullts_streaming(fc, onoff); + flexcop_toggle_fullts_streaming(fc,onoff); if (fc->pid_filtering) { - flexcop_pid_control \ - (fc, dvbdmxfeed->index, dvbdmxfeed->pid, onoff); + flexcop_pid_control(fc,dvbdmxfeed->index,dvbdmxfeed->pid,onoff); if (fc->extra_feedcount > 0) - flexcop_toggle_fullts_streaming(fc, 1); + flexcop_toggle_fullts_streaming(fc,1); else if (dvbdmxfeed->pid == 0x2000) - flexcop_toggle_fullts_streaming(fc, onoff); + flexcop_toggle_fullts_streaming(fc,onoff); else - flexcop_toggle_fullts_streaming(fc, 0); + flexcop_toggle_fullts_streaming(fc,0); } /* if it was the first or last feed request change the stream-status */ if (fc->feedcount == onoff) { - flexcop_rcv_data_ctrl(fc, onoff); + flexcop_rcv_data_ctrl(fc,onoff); if (fc->stream_control) /* device specific stream control */ - fc->stream_control(fc, onoff); + fc->stream_control(fc,onoff); /* feeding stopped -> reset the flexcop filter*/ if (onoff == 0) { @@ -209,6 +189,7 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, flexcop_hw_filter_init(fc); } } + return 0; } EXPORT_SYMBOL(flexcop_pid_feed_control); @@ -218,15 +199,15 @@ void flexcop_hw_filter_init(struct flexcop_device *fc) int i; flexcop_ibi_value v; for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++) - flexcop_pid_control(fc, i, 0x1fff, 0); + flexcop_pid_control(fc,i,0x1fff,0); flexcop_pid_group_filter(fc, 0, 0x1fe0); - flexcop_pid_group_filter_ctrl(fc, 0); + flexcop_pid_group_filter_ctrl(fc,0); - v = fc->read_ibi_reg(fc, pid_filter_308); + v = fc->read_ibi_reg(fc,pid_filter_308); v.pid_filter_308.EMM_filter_4 = 1; v.pid_filter_308.EMM_filter_6 = 0; - fc->write_ibi_reg(fc, pid_filter_308, v); + fc->write_ibi_reg(fc,pid_filter_308,v); flexcop_null_filter_ctrl(fc, 1); } diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-i2c.c b/trunk/drivers/media/dvb/b2c2/flexcop-i2c.c index e2bed5076485..f13783f08f0f 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -1,14 +1,17 @@ /* - * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III + * * flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization - * see flexcop.c for copyright information + * + * see flexcop.c for copyright information. */ #include "flexcop.h" #define FC_MAX_I2C_RETRIES 100000 -static int flexcop_i2c_operation(struct flexcop_device *fc, - flexcop_ibi_value *r100) +/* #define DUMP_I2C_MESSAGES */ + +static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r100) { int i; flexcop_ibi_value r; @@ -23,7 +26,7 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, r = fc->read_ibi_reg(fc, tw_sm_c_100); if (!r.tw_sm_c_100.no_base_addr_ack_error) { - if (r.tw_sm_c_100.st_done) { + if (r.tw_sm_c_100.st_done) { /* && !r.tw_sm_c_100.working_start */ *r100 = r; deb_i2c("i2c success\n"); return 0; @@ -33,31 +36,17 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, return -EREMOTEIO; } } - deb_i2c("tried %d times i2c operation, " - "never finished or too many ack errors.\n", i); + deb_i2c("tried %d times i2c operation, never finished or too many ack errors.\n",i); return -EREMOTEIO; } static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c, - flexcop_ibi_value r100, u8 *buf) + flexcop_ibi_value r100, u8 *buf) { flexcop_ibi_value r104; - int len = r100.tw_sm_c_100.total_bytes, - /* remember total_bytes is buflen-1 */ + int len = r100.tw_sm_c_100.total_bytes, /* remember total_bytes is buflen-1 */ ret; - /* work-around to have CableStar2 and SkyStar2 rev 2.7 work - * correctly: - * - * the ITD1000 is behind an i2c-gate which closes automatically - * after an i2c-transaction the STV0297 needs 2 consecutive reads - * one with no_base_addr = 0 and one with 1 - * - * those two work-arounds are conflictin: we check for the card - * type, it is set when probing the ITD1000 */ - if (i2c->fc->dev_type == FC_SKY_REV27) - r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr; - ret = flexcop_i2c_operation(i2c->fc, &r100); if (ret != 0) { deb_i2c("Retrying operation\n"); @@ -80,11 +69,11 @@ static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c, if (len > 1) buf[2] = r104.tw_sm_c_104.data3_reg; if (len > 2) buf[3] = r104.tw_sm_c_104.data4_reg; } + return 0; } -static int flexcop_i2c_write4(struct flexcop_device *fc, - flexcop_ibi_value r100, u8 *buf) +static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100, u8 *buf) { flexcop_ibi_value r104; int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */ @@ -92,6 +81,7 @@ static int flexcop_i2c_write4(struct flexcop_device *fc, /* there is at least one byte, otherwise we wouldn't be here */ r100.tw_sm_c_100.data1_reg = buf[0]; + r104.tw_sm_c_104.data2_reg = len > 0 ? buf[1] : 0; r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0; r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0; @@ -104,7 +94,7 @@ static int flexcop_i2c_write4(struct flexcop_device *fc, } int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c, - flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len) + flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len) { int ret; @@ -127,6 +117,7 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c, printk("rd("); else printk("wr("); + printk("%02x): %02x ", chipaddr, addr); #endif @@ -172,8 +163,7 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c, EXPORT_SYMBOL(flexcop_i2c_request); /* master xfer callback for demodulator */ -static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msgs[], int num) +static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) { struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap); int i, ret = 0; @@ -192,13 +182,12 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, /* reading */ if (i+1 < num && (msgs[i+1].flags == I2C_M_RD)) { ret = i2c->fc->i2c_request(i2c, FC_READ, msgs[i].addr, - msgs[i].buf[0], msgs[i+1].buf, - msgs[i+1].len); + msgs[i].buf[0], msgs[i+1].buf, msgs[i+1].len); i++; /* skip the following message */ } else /* writing */ ret = i2c->fc->i2c_request(i2c, FC_WRITE, msgs[i].addr, - msgs[i].buf[0], &msgs[i].buf[1], - msgs[i].len - 1); + msgs[i].buf[0], &msgs[i].buf[1], + msgs[i].len - 1); if (ret < 0) { err("i2c master_xfer failed"); break; @@ -225,21 +214,23 @@ static struct i2c_algorithm flexcop_algo = { int flexcop_i2c_init(struct flexcop_device *fc) { int ret; + mutex_init(&fc->i2c_mutex); fc->fc_i2c_adap[0].fc = fc; fc->fc_i2c_adap[1].fc = fc; fc->fc_i2c_adap[2].fc = fc; + fc->fc_i2c_adap[0].port = FC_I2C_PORT_DEMOD; fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM; fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER; strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod", - sizeof(fc->fc_i2c_adap[0].i2c_adap.name)); + sizeof(fc->fc_i2c_adap[0].i2c_adap.name)); strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom", - sizeof(fc->fc_i2c_adap[1].i2c_adap.name)); + sizeof(fc->fc_i2c_adap[1].i2c_adap.name)); strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner", - sizeof(fc->fc_i2c_adap[2].i2c_adap.name)); + sizeof(fc->fc_i2c_adap[2].i2c_adap.name)); i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]); i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]); @@ -277,6 +268,7 @@ int flexcop_i2c_init(struct flexcop_device *fc) i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap); adap_1_failed: i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap); + return ret; } @@ -287,5 +279,6 @@ void flexcop_i2c_exit(struct flexcop_device *fc) i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap); i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap); } + fc->init_state &= ~FC_STATE_I2C_INIT; } diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-misc.c b/trunk/drivers/media/dvb/b2c2/flexcop-misc.c index e56627d2f0f4..93d20e56f909 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-misc.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-misc.c @@ -1,7 +1,9 @@ /* - * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * flexcop-misc.c - miscellaneous functions - * see flexcop.c for copyright information + * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III + * + * flexcop-misc.c - miscellaneous functions. + * + * see flexcop.c for copyright information. */ #include "flexcop.h" @@ -10,43 +12,39 @@ void flexcop_determine_revision(struct flexcop_device *fc) flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); switch (v.misc_204.Rev_N_sig_revision_hi) { - case 0x2: - deb_info("found a FlexCopII.\n"); - fc->rev = FLEXCOP_II; - break; - case 0x3: - deb_info("found a FlexCopIIb.\n"); - fc->rev = FLEXCOP_IIB; - break; - case 0x0: - deb_info("found a FlexCopIII.\n"); - fc->rev = FLEXCOP_III; - break; - default: - err("unknown FlexCop Revision: %x. Please report this to " - "linux-dvb@linuxtv.org.", - v.misc_204.Rev_N_sig_revision_hi); - break; + case 0x2: + deb_info("found a FlexCopII.\n"); + fc->rev = FLEXCOP_II; + break; + case 0x3: + deb_info("found a FlexCopIIb.\n"); + fc->rev = FLEXCOP_IIB; + break; + case 0x0: + deb_info("found a FlexCopIII.\n"); + fc->rev = FLEXCOP_III; + break; + default: + err("unkown FlexCop Revision: %x. Please report the linux-dvb@linuxtv.org.",v.misc_204.Rev_N_sig_revision_hi); + break; } if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps)) - deb_info("this FlexCop has " - "the additional 32 hardware pid filter.\n"); + deb_info("this FlexCop has the additional 32 hardware pid filter.\n"); else - deb_info("this FlexCop has " - "the 6 basic main hardware pid filter.\n"); + deb_info("this FlexCop has only the 6 basic main hardware pid filter.\n"); /* bus parts have to decide if hw pid filtering is used or not. */ } static const char *flexcop_revision_names[] = { - "Unknown chip", + "Unkown chip", "FlexCopII", "FlexCopIIb", "FlexCopIII", }; static const char *flexcop_device_names[] = { - "Unknown device", + "Unkown device", "Air2PC/AirStar 2 DVB-T", "Air2PC/AirStar 2 ATSC 1st generation", "Air2PC/AirStar 2 ATSC 2nd generation", @@ -63,23 +61,21 @@ static const char *flexcop_bus_names[] = { "PCI", }; -void flexcop_device_name(struct flexcop_device *fc, - const char *prefix, const char *suffix) +void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const + char *suffix) { - info("%s '%s' at the '%s' bus controlled by a '%s' %s", - prefix, flexcop_device_names[fc->dev_type], - flexcop_bus_names[fc->bus_type], - flexcop_revision_names[fc->rev], suffix); + info("%s '%s' at the '%s' bus controlled by a '%s' %s",prefix, + flexcop_device_names[fc->dev_type],flexcop_bus_names[fc->bus_type], + flexcop_revision_names[fc->rev],suffix); } -void flexcop_dump_reg(struct flexcop_device *fc, - flexcop_ibi_register reg, int num) +void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num) { flexcop_ibi_value v; int i; for (i = 0; i < num; i++) { - v = fc->read_ibi_reg(fc, reg+4*i); - deb_rdump("0x%03x: %08x, ", reg+4*i, v.raw); + v = fc->read_ibi_reg(fc,reg+4*i); + deb_rdump("0x%03x: %08x, ",reg+4*i, v.raw); } deb_rdump("\n"); } diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-pci.c b/trunk/drivers/media/dvb/b2c2/flexcop-pci.c index 227c0200b70a..76e37fd96bb6 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-pci.c @@ -1,7 +1,9 @@ /* - * Linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * flexcop-pci.c - covers the PCI part including DMA transfers - * see flexcop.c for copyright information + * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III + * + * flexcop-pci.c - covers the PCI part including DMA transfers. + * + * see flexcop.c for copyright information. */ #define FC_LOG_PREFIX "flexcop-pci" @@ -9,8 +11,7 @@ static int enable_pid_filtering = 1; module_param(enable_pid_filtering, int, 0444); -MODULE_PARM_DESC(enable_pid_filtering, - "enable hardware pid filtering: supported values: 0 (fullts), 1"); +MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1"); static int irq_chk_intv = 100; module_param(irq_chk_intv, int, 0644); @@ -25,17 +26,17 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog."); #define DEBSTATUS " (debugging is not enabled)" #endif -#define deb_info(args...) dprintk(0x01, args) -#define deb_reg(args...) dprintk(0x02, args) -#define deb_ts(args...) dprintk(0x04, args) -#define deb_irq(args...) dprintk(0x08, args) -#define deb_chk(args...) dprintk(0x10, args) +#define deb_info(args...) dprintk(0x01,args) +#define deb_reg(args...) dprintk(0x02,args) +#define deb_ts(args...) dprintk(0x04,args) +#define deb_irq(args...) dprintk(0x08,args) +#define deb_chk(args...) dprintk(0x10,args) static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))." - DEBSTATUS); + DEBSTATUS); #define DRIVER_VERSION "0.1" #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver" @@ -50,30 +51,30 @@ struct flexcop_pci { void __iomem *io_mem; u32 irq; - /* buffersize (at least for DMA1, need to be % 188 == 0, - * this logic is required */ +/* buffersize (at least for DMA1, need to be % 188 == 0, + * this logic is required */ #define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188) #define FC_DEFAULT_DMA2_BUFSIZE (10 * 188) struct flexcop_dma dma[2]; int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */ - u32 last_dma1_cur_pos; - /* position of the pointer last time the timer/packet irq occured */ + u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */ int count; int count_prev; int stream_problem; spinlock_t irq_lock; + unsigned long last_irq; struct delayed_work irq_check_work; + struct flexcop_device *fc_dev; }; -static int lastwreg, lastwval, lastrreg, lastrval; +static int lastwreg,lastwval,lastrreg,lastrval; -static flexcop_ibi_value flexcop_pci_read_ibi_reg(struct flexcop_device *fc, - flexcop_ibi_register r) +static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, flexcop_ibi_register r) { struct flexcop_pci *fc_pci = fc->bus_specific; flexcop_ibi_value v; @@ -81,20 +82,19 @@ static flexcop_ibi_value flexcop_pci_read_ibi_reg(struct flexcop_device *fc, if (lastrreg != r || lastrval != v.raw) { lastrreg = r; lastrval = v.raw; - deb_reg("new rd: %3x: %08x\n", r, v.raw); + deb_reg("new rd: %3x: %08x\n",r,v.raw); } return v; } -static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, - flexcop_ibi_register r, flexcop_ibi_value v) +static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register r, flexcop_ibi_value v) { struct flexcop_pci *fc_pci = fc->bus_specific; if (lastwreg != r || lastwval != v.raw) { lastwreg = r; lastwval = v.raw; - deb_reg("new wr: %3x: %08x\n", r, v.raw); + deb_reg("new wr: %3x: %08x\n",r,v.raw); } writel(v.raw, fc_pci->io_mem + r); @@ -113,16 +113,15 @@ static void flexcop_pci_irq_check_work(struct work_struct *work) deb_chk("no IRQ since the last check\n"); if (fc_pci->stream_problem++ == 3) { struct dvb_demux_feed *feed; - deb_info("flexcop-pci: stream problem, resetting pid filter\n"); spin_lock_irq(&fc->demux.lock); list_for_each_entry(feed, &fc->demux.feed_list, - list_head) { + list_head) { flexcop_pid_feed_control(fc, feed, 0); } list_for_each_entry(feed, &fc->demux.feed_list, - list_head) { + list_head) { flexcop_pid_feed_control(fc, feed, 1); } spin_unlock_irq(&fc->demux.lock); @@ -150,10 +149,11 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) flexcop_ibi_value v; irqreturn_t ret = IRQ_HANDLED; - spin_lock_irqsave(&fc_pci->irq_lock, flags); - v = fc->read_ibi_reg(fc, irq_20c); + spin_lock_irqsave(&fc_pci->irq_lock,flags); + + v = fc->read_ibi_reg(fc,irq_20c); - /* errors */ + /* errors */ if (v.irq_20c.Data_receiver_error) deb_chk("data receiver error\n"); if (v.irq_20c.Continuity_error_flag) @@ -164,29 +164,24 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) deb_chk("Transport error\n"); if ((fc_pci->count % 1000) == 0) - deb_chk("%d valid irq took place so far\n", fc_pci->count); + deb_chk("%d valid irq took place so far\n",fc_pci->count); if (v.irq_20c.DMA1_IRQ_Status == 1) { if (fc_pci->active_dma1_addr == 0) - flexcop_pass_dmx_packets(fc_pci->fc_dev, - fc_pci->dma[0].cpu_addr0, - fc_pci->dma[0].size / 188); + flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188); else - flexcop_pass_dmx_packets(fc_pci->fc_dev, - fc_pci->dma[0].cpu_addr1, - fc_pci->dma[0].size / 188); + flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr1,fc_pci->dma[0].size / 188); deb_irq("page change to page: %d\n",!fc_pci->active_dma1_addr); fc_pci->active_dma1_addr = !fc_pci->active_dma1_addr; + } else if (v.irq_20c.DMA1_Timer_Status == 1) { /* for the timer IRQ we only can use buffer dmx feeding, because we don't have * complete TS packets when reading from the DMA memory */ - } else if (v.irq_20c.DMA1_Timer_Status == 1) { dma_addr_t cur_addr = fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; - deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, " - "last_cur_pos: %08x ", + deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ", jiffies_to_usecs(jiffies - fc_pci->last_irq), v.raw, (unsigned long long)cur_addr, cur_pos, fc_pci->last_dma1_cur_pos); @@ -196,36 +191,30 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) * pass the data from last_cur_pos to the buffer end to the demux */ if (cur_pos < fc_pci->last_dma1_cur_pos) { - deb_irq(" end was reached: passing %d bytes ", - (fc_pci->dma[0].size*2 - 1) - - fc_pci->last_dma1_cur_pos); + deb_irq(" end was reached: passing %d bytes ",(fc_pci->dma[0].size*2 - 1) - fc_pci->last_dma1_cur_pos); flexcop_pass_dmx_data(fc_pci->fc_dev, - fc_pci->dma[0].cpu_addr0 + - fc_pci->last_dma1_cur_pos, - (fc_pci->dma[0].size*2) - - fc_pci->last_dma1_cur_pos); + fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos, + (fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos); fc_pci->last_dma1_cur_pos = 0; } if (cur_pos > fc_pci->last_dma1_cur_pos) { - deb_irq(" passing %d bytes ", - cur_pos - fc_pci->last_dma1_cur_pos); + deb_irq(" passing %d bytes ",cur_pos - fc_pci->last_dma1_cur_pos); flexcop_pass_dmx_data(fc_pci->fc_dev, - fc_pci->dma[0].cpu_addr0 + - fc_pci->last_dma1_cur_pos, - cur_pos - fc_pci->last_dma1_cur_pos); + fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos, + cur_pos - fc_pci->last_dma1_cur_pos); } deb_irq("\n"); fc_pci->last_dma1_cur_pos = cur_pos; fc_pci->count++; } else { - deb_irq("isr for flexcop called, " - "apparently without reason (%08x)\n", v.raw); + deb_irq("isr for flexcop called, apparently without reason (%08x)\n",v.raw); ret = IRQ_NONE; } - spin_unlock_irqrestore(&fc_pci->irq_lock, flags); + spin_unlock_irqrestore(&fc_pci->irq_lock,flags); + return ret; } @@ -233,48 +222,52 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff) { struct flexcop_pci *fc_pci = fc->bus_specific; if (onoff) { - flexcop_dma_config(fc, &fc_pci->dma[0], FC_DMA_1); - flexcop_dma_config(fc, &fc_pci->dma[1], FC_DMA_2); - flexcop_dma_config_timer(fc, FC_DMA_1, 0); - flexcop_dma_xfer_control(fc, FC_DMA_1, - FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 1); + flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1); + flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2); + + flexcop_dma_config_timer(fc,FC_DMA_1,0); + + flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,1); deb_irq("DMA xfer enabled\n"); fc_pci->last_dma1_cur_pos = 0; - flexcop_dma_control_timer_irq(fc, FC_DMA_1, 1); + flexcop_dma_control_timer_irq(fc,FC_DMA_1,1); deb_irq("IRQ enabled\n"); + fc_pci->count_prev = fc_pci->count; + +// fc_pci->active_dma1_addr = 0; +// flexcop_dma_control_size_irq(fc,FC_DMA_1,1); + } else { - flexcop_dma_control_timer_irq(fc, FC_DMA_1, 0); + flexcop_dma_control_timer_irq(fc,FC_DMA_1,0); deb_irq("IRQ disabled\n"); - flexcop_dma_xfer_control(fc, FC_DMA_1, - FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 0); +// flexcop_dma_control_size_irq(fc,FC_DMA_1,0); + + flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,0); deb_irq("DMA xfer disabled\n"); } + return 0; } static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci) { int ret; - ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[0], - FC_DEFAULT_DMA1_BUFSIZE); - if (ret != 0) + if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0) return ret; - ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[1], - FC_DEFAULT_DMA2_BUFSIZE); - if (ret != 0) { + if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) { flexcop_dma_free(&fc_pci->dma[0]); return ret; } - flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_MEDIA | - FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1); - flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_CAO | - FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2); + flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1); + flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2); + fc_pci->init_state |= FC_PCI_DMA_INIT; + return ret; } @@ -297,8 +290,12 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci) if ((ret = pci_enable_device(fc_pci->pdev)) != 0) return ret; + pci_set_master(fc_pci->pdev); + /* enable interrupts */ + // pci_write_config_dword(pdev, 0x6c, 0x8000); + if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0) goto err_pci_disable_device; @@ -341,8 +338,8 @@ static void flexcop_pci_exit(struct flexcop_pci *fc_pci) fc_pci->init_state &= ~FC_PCI_INIT; } -static int flexcop_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) + +static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct flexcop_device *fc; struct flexcop_pci *fc_pci; @@ -353,7 +350,7 @@ static int flexcop_pci_probe(struct pci_dev *pdev, return -ENOMEM; } - /* general flexcop init */ +/* general flexcop init */ fc_pci = fc->bus_specific; fc_pci->fc_dev = fc; @@ -361,6 +358,7 @@ static int flexcop_pci_probe(struct pci_dev *pdev, fc->write_ibi_reg = flexcop_pci_write_ibi_reg; fc->i2c_request = flexcop_i2c_request; fc->get_mac_addr = flexcop_eeprom_check_mac_addr; + fc->stream_control = flexcop_pci_stream_control; if (enable_pid_filtering) @@ -370,29 +368,29 @@ static int flexcop_pci_probe(struct pci_dev *pdev, fc->pid_filtering = enable_pid_filtering; fc->bus_type = FC_PCI; + fc->dev = &pdev->dev; fc->owner = THIS_MODULE; - /* bus specific part */ +/* bus specific part */ fc_pci->pdev = pdev; if ((ret = flexcop_pci_init(fc_pci)) != 0) goto err_kfree; - /* init flexcop */ +/* init flexcop */ if ((ret = flexcop_device_initialize(fc)) != 0) goto err_pci_exit; - /* init dma */ +/* init dma */ if ((ret = flexcop_pci_dma_init(fc_pci)) != 0) goto err_fc_exit; INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work); - if (irq_chk_intv > 0) - schedule_delayed_work(&fc_pci->irq_check_work, - msecs_to_jiffies(irq_chk_intv < 100 ? - 100 : - irq_chk_intv)); + if (irq_chk_intv > 0) + schedule_delayed_work(&fc_pci->irq_check_work, + msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); + return ret; err_fc_exit: @@ -422,6 +420,7 @@ static void flexcop_pci_remove(struct pci_dev *pdev) static struct pci_device_id flexcop_pci_tbl[] = { { PCI_DEVICE(0x13d0, 0x2103) }, +/* { PCI_DEVICE(0x13d0, 0x2200) }, ? */ { }, }; diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-reg.h b/trunk/drivers/media/dvb/b2c2/flexcop-reg.h index dc4528dcbb98..7599fccc1a5b 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-reg.h +++ b/trunk/drivers/media/dvb/b2c2/flexcop-reg.h @@ -1,11 +1,14 @@ /* - * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III + * * flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII - * see flexcop.c for copyright information + * + * see flexcop.c for copyright information. */ #ifndef __FLEXCOP_REG_H__ #define __FLEXCOP_REG_H__ + typedef enum { FLEXCOP_UNK = 0, FLEXCOP_II, @@ -15,13 +18,13 @@ typedef enum { typedef enum { FC_UNK = 0, - FC_CABLE, - FC_AIR_DVBT, + FC_AIR_DVB, FC_AIR_ATSC1, FC_AIR_ATSC2, + FC_SKY, + FC_SKY_OLD, + FC_CABLE, FC_AIR_ATSC3, - FC_SKY_REV23, - FC_SKY_REV26, FC_SKY_REV27, FC_SKY_REV28, } flexcop_device_type_t; @@ -33,12 +36,12 @@ typedef enum { /* FlexCop IBI Registers */ #if defined(__LITTLE_ENDIAN) -#include "flexcop_ibi_value_le.h" + #include "flexcop_ibi_value_le.h" #else #if defined(__BIG_ENDIAN) -#include "flexcop_ibi_value_be.h" + #include "flexcop_ibi_value_be.h" #else -#error no endian defined + #error no endian defined #endif #endif diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-sram.c b/trunk/drivers/media/dvb/b2c2/flexcop-sram.c index f2199e43e803..cda69528548a 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-sram.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-sram.c @@ -1,43 +1,45 @@ /* - * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * flexcop-sram.c - functions for controlling the SRAM - * see flexcop.c for copyright information + * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III + * + * flexcop-sram.c - functions for controlling the SRAM. + * + * see flexcop.c for copyright information. */ #include "flexcop.h" -static void flexcop_sram_set_chip(struct flexcop_device *fc, - flexcop_sram_type_t type) +static void flexcop_sram_set_chip (struct flexcop_device *fc, flexcop_sram_type_t type) { - flexcop_set_ibi_value(wan_ctrl_reg_71c, sram_chip, type); + flexcop_set_ibi_value(wan_ctrl_reg_71c,sram_chip,type); } int flexcop_sram_init(struct flexcop_device *fc) { switch (fc->rev) { - case FLEXCOP_II: - case FLEXCOP_IIB: - flexcop_sram_set_chip(fc, FC_SRAM_1_32KB); - break; - case FLEXCOP_III: - flexcop_sram_set_chip(fc, FC_SRAM_1_48KB); - break; - default: - return -EINVAL; + case FLEXCOP_II: + case FLEXCOP_IIB: + flexcop_sram_set_chip(fc,FC_SRAM_1_32KB); + break; + case FLEXCOP_III: + flexcop_sram_set_chip(fc,FC_SRAM_1_48KB); + break; + default: + return -EINVAL; } return 0; } -int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, - flexcop_sram_dest_target_t target) +int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target) { flexcop_ibi_value v; - v = fc->read_ibi_reg(fc, sram_dest_reg_714); + + v = fc->read_ibi_reg(fc,sram_dest_reg_714); if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) { err("SRAM destination target to available on FlexCopII(b)\n"); return -EINVAL; } - deb_sram("sram dest: %x target: %x\n", dest, target); + + deb_sram("sram dest: %x target: %x\n",dest, target); if (dest & FC_SRAM_DEST_NET) v.sram_dest_reg_714.NET_Dest = target; @@ -152,12 +154,14 @@ static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len else bank = 0x10000000; } + flex_sram_write(adapter, bank, addr & 0x7fff, buf, len); } static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len) { u32 bank; + bank = 0; if (adapter->dw_sram_type == 0x20000) { @@ -170,22 +174,26 @@ static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len) else bank = 0x10000000; } + flex_sram_read(adapter, bank, addr & 0x7fff, buf, len); } static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len) { u32 length; + while (len != 0) { length = len; - /* check if the address range belongs to the same - * 32K memory chip. If not, the data is read - * from one chip at a time */ + + // check if the address range belongs to the same + // 32K memory chip. If not, the data is read from + // one chip at a time. if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) { length = (((addr >> 0x0f) + 1) << 0x0f) - addr; } sram_read_chunk(adapter, addr, buf, length); + addr = addr + length; buf = buf + length; len = len - length; @@ -195,17 +203,19 @@ static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len) static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len) { u32 length; + while (len != 0) { length = len; - /* check if the address range belongs to the same - * 32K memory chip. If not, the data is - * written to one chip at a time */ + // check if the address range belongs to the same + // 32K memory chip. If not, the data is written to + // one chip at a time. if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) { length = (((addr >> 0x0f) + 1) << 0x0f) - addr; } sram_write_chunk(adapter, addr, buf, length); + addr = addr + length; buf = buf + length; len = len - length; @@ -214,29 +224,39 @@ static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len) static void sram_set_size(struct adapter *adapter, u32 mask) { - write_reg_dw(adapter, 0x71c, - (mask | (~0x30000 & read_reg_dw(adapter, 0x71c)))); + write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c)))); } static void sram_init(struct adapter *adapter) { u32 tmp; + tmp = read_reg_dw(adapter, 0x71c); + write_reg_dw(adapter, 0x71c, 1); if (read_reg_dw(adapter, 0x71c) != 0) { write_reg_dw(adapter, 0x71c, tmp); + adapter->dw_sram_type = tmp & 0x30000; + ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type); + } else { + adapter->dw_sram_type = 0x10000; + ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type); } + + /* return value is never used? */ +/* return adapter->dw_sram_type; */ } static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr) { u8 tmp1, tmp2; + dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr); sram_set_size(adapter, mask); @@ -249,6 +269,7 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr) sram_write(adapter, addr + 4, &tmp1, 1); tmp2 = 0; + mdelay(20); sram_read(adapter, addr, &tmp2, 1); @@ -266,6 +287,7 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr) sram_write(adapter, addr + 4, &tmp1, 1); tmp2 = 0; + mdelay(20); sram_read(adapter, addr, &tmp2, 1); @@ -275,24 +297,26 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr) if (tmp2 != 0x5a) return 0; + return 1; } static u32 sram_length(struct adapter *adapter) { if (adapter->dw_sram_type == 0x10000) - return 32768; /* 32K */ + return 32768; // 32K if (adapter->dw_sram_type == 0x00000) - return 65536; /* 64K */ + return 65536; // 64K if (adapter->dw_sram_type == 0x20000) - return 131072; /* 128K */ - return 32768; /* 32K */ + return 131072; // 128K + + return 32768; // 32K } /* FlexcopII can work with 32K, 64K or 128K of external SRAM memory. - - for 128K there are 4x32K chips at bank 0,1,2,3. - - for 64K there are 2x32K chips at bank 1,2. - - for 32K there is one 32K chip at bank 0. + - for 128K there are 4x32K chips at bank 0,1,2,3. + - for 64K there are 2x32K chips at bank 1,2. + - for 32K there is one 32K chip at bank 0. FlexCop works only with one bank at a time. The bank is selected by bits 28-29 of the 0x700 register. @@ -300,18 +324,24 @@ static u32 sram_length(struct adapter *adapter) bank 0 covers addresses 0x00000-0x07fff bank 1 covers addresses 0x08000-0x0ffff bank 2 covers addresses 0x10000-0x17fff - bank 3 covers addresses 0x18000-0x1ffff */ + bank 3 covers addresses 0x18000-0x1ffff +*/ static int flexcop_sram_detect(struct flexcop_device *fc) { - flexcop_ibi_value r208, r71c_0, vr71c_1; + flexcop_ibi_value r208,r71c_0,vr71c_1; + r208 = fc->read_ibi_reg(fc, ctrl_208); fc->write_ibi_reg(fc, ctrl_208, ibi_zero); r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c); + write_reg_dw(adapter, 0x71c, 1); + tmp3 = read_reg_dw(adapter, 0x71c); + dprintk("%s: tmp3 = %x\n", __func__, tmp3); + write_reg_dw(adapter, 0x71c, tmp2); // check for internal SRAM ??? @@ -320,7 +350,9 @@ static int flexcop_sram_detect(struct flexcop_device *fc) sram_set_size(adapter, 0x10000); sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); + dprintk("%s: sram size = 32K\n", __func__); + return 32; } @@ -328,7 +360,9 @@ static int flexcop_sram_detect(struct flexcop_device *fc) sram_set_size(adapter, 0x20000); sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); + dprintk("%s: sram size = 128K\n", __func__); + return 128; } @@ -336,7 +370,9 @@ static int flexcop_sram_detect(struct flexcop_device *fc) sram_set_size(adapter, 0x00000); sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); + dprintk("%s: sram size = 64K\n", __func__); + return 64; } @@ -344,14 +380,18 @@ static int flexcop_sram_detect(struct flexcop_device *fc) sram_set_size(adapter, 0x10000); sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); + dprintk("%s: sram size = 32K\n", __func__); + return 32; } sram_set_size(adapter, 0x10000); sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); + dprintk("%s: SRAM detection failed. Set to 32K \n", __func__); + return 0; } diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-usb.c b/trunk/drivers/media/dvb/b2c2/flexcop-usb.c index bedcfb671624..ae0d76a5d51d 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-usb.c @@ -1,8 +1,11 @@ /* - * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * flexcop-usb.c - covers the USB part - * see flexcop.c for copyright information + * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III + * + * flexcop-usb.c - covers the USB part. + * + * see flexcop.c for copyright information. */ + #define FC_LOG_PREFIX "flexcop_usb" #include "flexcop-usb.h" #include "flexcop-common.h" @@ -15,47 +18,42 @@ /* debug */ #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG #define dprintk(level,args...) \ - do { if ((debug & level)) printk(args); } while (0) - -#define debug_dump(b, l, method) do {\ + do { if ((debug & level)) { printk(args); } } while (0) +#define debug_dump(b,l,method) {\ int i; \ - for (i = 0; i < l; i++) \ - method("%02x ", b[i]); \ - method("\n"); \ -} while (0) + for (i = 0; i < l; i++) method("%02x ", b[i]); \ + method("\n");\ +} #define DEBSTATUS "" #else -#define dprintk(level, args...) -#define debug_dump(b, l, method) +#define dprintk(level,args...) +#define debug_dump(b,l,method) #define DEBSTATUS " (debugging is not enabled)" #endif static int debug; module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2," - "ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS); +MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS); #undef DEBSTATUS -#define deb_info(args...) dprintk(0x01, args) -#define deb_ts(args...) dprintk(0x02, args) -#define deb_ctrl(args...) dprintk(0x04, args) -#define deb_i2c(args...) dprintk(0x08, args) -#define deb_v8(args...) dprintk(0x10, args) +#define deb_info(args...) dprintk(0x01,args) +#define deb_ts(args...) dprintk(0x02,args) +#define deb_ctrl(args...) dprintk(0x04,args) +#define deb_i2c(args...) dprintk(0x08,args) +#define deb_v8(args...) dprintk(0x10,args) /* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits * in the IBI address, to make the V8 code simpler. - * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (the six bits used) + * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used) * in general: 0000 0HHH 000L LL00 * IBI ADDRESS FORMAT: RHHH BLLL * * where R is the read(1)/write(0) bit, B is the busy bit * and HHH and LLL are the two sets of three bits from the PCI address. */ -#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) \ - (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70)) -#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) \ - (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4)) +#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70)) +#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4)) /* * DKT 020228 @@ -71,13 +69,12 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI, struct flexcop_usb *fc_usb = fc->bus_specific; u8 request = read ? B2C2_USB_READ_REG : B2C2_USB_WRITE_REG; u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR; - u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | - (read ? 0x80 : 0); + u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | (read ? 0x80 : 0); int len = usb_control_msg(fc_usb->udev, read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT, request, - request_type, /* 0xc0 read or 0x40 write */ + request_type, /* 0xc0 read or 0x40 write*/ wAddress, 0, val, @@ -85,49 +82,55 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI, B2C2_WAIT_FOR_OPERATION_RDW * HZ); if (len != sizeof(u32)) { - err("error while %s dword from %d (%d).", read ? "reading" : - "writing", wAddress, wRegOffsPCI); + err("error while %s dword from %d (%d).",read ? "reading" : "writing", + wAddress,wRegOffsPCI); return -EIO; } return 0; } + /* * DKT 010817 - add support for V8 memory read/write and flash update */ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb, flexcop_usb_request_t req, u8 page, u16 wAddress, - u8 *pbBuffer, u32 buflen) + u8 *pbBuffer,u32 buflen) { +// u8 dwRequestType; u8 request_type = USB_TYPE_VENDOR; u16 wIndex; - int nWaitTime, pipe, len; + int nWaitTime,pipe,len; + wIndex = page << 8; switch (req) { - case B2C2_USB_READ_V8_MEM: - nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ; - request_type |= USB_DIR_IN; - pipe = B2C2_USB_CTRL_PIPE_IN; + case B2C2_USB_READ_V8_MEM: + nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ; + request_type |= USB_DIR_IN; +// dwRequestType = (u8) RTYPE_READ_V8_MEMORY; + pipe = B2C2_USB_CTRL_PIPE_IN; break; - case B2C2_USB_WRITE_V8_MEM: - wIndex |= pbBuffer[0]; - request_type |= USB_DIR_OUT; - nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE; - pipe = B2C2_USB_CTRL_PIPE_OUT; + case B2C2_USB_WRITE_V8_MEM: + wIndex |= pbBuffer[0]; + request_type |= USB_DIR_OUT; + nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE; +// dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY; + pipe = B2C2_USB_CTRL_PIPE_OUT; break; - case B2C2_USB_FLASH_BLOCK: - request_type |= USB_DIR_OUT; - nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH; - pipe = B2C2_USB_CTRL_PIPE_OUT; + case B2C2_USB_FLASH_BLOCK: + request_type |= USB_DIR_OUT; + nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH; +// dwRequestType = (u8) RTYPE_WRITE_V8_FLASH; + pipe = B2C2_USB_CTRL_PIPE_OUT; break; - default: - deb_info("unsupported request for v8_mem_req %x.\n", req); + default: + deb_info("unsupported request for v8_mem_req %x.\n",req); return -EINVAL; } - deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req, - wAddress, wIndex, buflen); + deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n",request_type,req, + wAddress,wIndex,buflen); - len = usb_control_msg(fc_usb->udev, pipe, + len = usb_control_msg(fc_usb->udev,pipe, req, request_type, wAddress, @@ -136,53 +139,39 @@ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb, buflen, nWaitTime * HZ); - debug_dump(pbBuffer, len, deb_v8); + debug_dump(pbBuffer,len,deb_v8); + return len == buflen ? 0 : -EIO; } #define bytes_left_to_read_on_page(paddr,buflen) \ - ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \ - ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK))) + ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \ + ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK))) -static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb, - flexcop_usb_request_t req, flexcop_usb_mem_page_t page_start, - u32 addr, int extended, u8 *buf, u32 len) +static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,flexcop_usb_request_t req, + flexcop_usb_mem_page_t page_start, u32 addr, int extended, u8 *buf, u32 len) { int i,ret = 0; u16 wMax; u32 pagechunk = 0; switch(req) { - case B2C2_USB_READ_V8_MEM: - wMax = USB_MEM_READ_MAX; - break; - case B2C2_USB_WRITE_V8_MEM: - wMax = USB_MEM_WRITE_MAX; - break; - case B2C2_USB_FLASH_BLOCK: - wMax = USB_FLASH_MAX; - break; - default: - return -EINVAL; + case B2C2_USB_READ_V8_MEM: wMax = USB_MEM_READ_MAX; break; + case B2C2_USB_WRITE_V8_MEM: wMax = USB_MEM_WRITE_MAX; break; + case B2C2_USB_FLASH_BLOCK: wMax = USB_FLASH_MAX; break; + default: + return -EINVAL; break; } for (i = 0; i < len;) { - pagechunk = - wMax < bytes_left_to_read_on_page(addr, len) ? - wMax : - bytes_left_to_read_on_page(addr, len); - deb_info("%x\n", - (addr & V8_MEMORY_PAGE_MASK) | - (V8_MEMORY_EXTENDED*extended)); - - ret = flexcop_usb_v8_memory_req(fc_usb, req, - page_start + (addr / V8_MEMORY_PAGE_SIZE), - (addr & V8_MEMORY_PAGE_MASK) | - (V8_MEMORY_EXTENDED*extended), - &buf[i], pagechunk); - - if (ret < 0) + pagechunk = wMax < bytes_left_to_read_on_page(addr,len) ? wMax : bytes_left_to_read_on_page(addr,len); + deb_info("%x\n",(addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended)); + if ((ret = flexcop_usb_v8_memory_req(fc_usb,req, + page_start + (addr / V8_MEMORY_PAGE_SIZE), /* actual page */ + (addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended), + &buf[i],pagechunk)) < 0) return ret; + addr += pagechunk; len -= pagechunk; } @@ -191,9 +180,8 @@ static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb, static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended) { - return flexcop_usb_memory_req(fc->bus_specific, B2C2_USB_READ_V8_MEM, - V8_MEMORY_PAGE_FLASH, 0x1f010, 1, - fc->dvb_adapter.proposed_mac, 6); + return flexcop_usb_memory_req(fc->bus_specific,B2C2_USB_READ_V8_MEM, + V8_MEMORY_PAGE_FLASH,0x1f010,1,fc->dvb_adapter.proposed_mac,6); } #if 0 @@ -203,8 +191,11 @@ static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set, { u16 wValue; u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR; +// u8 dwRequestType = (u8) RTYPE_GENERIC, int nWaitTime = 2, - pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, len; + pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, + len; + wValue = (func << 8) | extra; len = usb_control_msg(fc_usb->udev,pipe, @@ -227,35 +218,36 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c, struct flexcop_usb *fc_usb = i2c->fc->bus_specific; u16 wValue, wIndex; int nWaitTime,pipe,len; +// u8 dwRequestType; u8 request_type = USB_TYPE_VENDOR; switch (func) { - case USB_FUNC_I2C_WRITE: - case USB_FUNC_I2C_MULTIWRITE: - case USB_FUNC_I2C_REPEATWRITE: + case USB_FUNC_I2C_WRITE: + case USB_FUNC_I2C_MULTIWRITE: + case USB_FUNC_I2C_REPEATWRITE: /* DKT 020208 - add this to support special case of DiSEqC */ - case USB_FUNC_I2C_CHECKWRITE: - pipe = B2C2_USB_CTRL_PIPE_OUT; - nWaitTime = 2; - request_type |= USB_DIR_OUT; + case USB_FUNC_I2C_CHECKWRITE: + pipe = B2C2_USB_CTRL_PIPE_OUT; + nWaitTime = 2; +// dwRequestType = (u8) RTYPE_GENERIC; + request_type |= USB_DIR_OUT; break; - case USB_FUNC_I2C_READ: - case USB_FUNC_I2C_REPEATREAD: - pipe = B2C2_USB_CTRL_PIPE_IN; - nWaitTime = 2; - request_type |= USB_DIR_IN; + case USB_FUNC_I2C_READ: + case USB_FUNC_I2C_REPEATREAD: + pipe = B2C2_USB_CTRL_PIPE_IN; + nWaitTime = 2; +// dwRequestType = (u8) RTYPE_GENERIC; + request_type |= USB_DIR_IN; break; - default: - deb_info("unsupported function for i2c_req %x\n", func); - return -EINVAL; + default: + deb_info("unsupported function for i2c_req %x\n",func); + return -EINVAL; } wValue = (func << 8) | (i2c->port << 4); wIndex = (chipaddr << 8 ) | addr; - deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n", - func, request_type, req, - wValue & 0xff, wValue >> 8, - wIndex & 0xff, wIndex >> 8); + deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req, + wValue & 0xff, wValue >> 8, wIndex & 0xff, wIndex >> 8); len = usb_control_msg(fc_usb->udev,pipe, req, @@ -265,49 +257,44 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c, buf, buflen, nWaitTime * HZ); + return len == buflen ? 0 : -EREMOTEIO; } -/* actual bus specific access functions, - make sure prototype are/will be equal to pci */ -static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc, - flexcop_ibi_register reg) +/* actual bus specific access functions, make sure prototype are/will be equal to pci */ +static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg) { flexcop_ibi_value val; val.raw = 0; - flexcop_usb_readwrite_dw(fc, reg, &val.raw, 1); + flexcop_usb_readwrite_dw(fc,reg, &val.raw, 1); return val; } -static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc, - flexcop_ibi_register reg, flexcop_ibi_value val) +static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg, flexcop_ibi_value val) { - return flexcop_usb_readwrite_dw(fc, reg, &val.raw, 0); + return flexcop_usb_readwrite_dw(fc,reg, &val.raw, 0); } static int flexcop_usb_i2c_request(struct flexcop_i2c_adapter *i2c, - flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len) + flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len) { if (op == FC_READ) return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST, - USB_FUNC_I2C_READ, chipaddr, addr, buf, len); + USB_FUNC_I2C_READ, chipaddr, addr, buf, len); else return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST, - USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len); + USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len); } -static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, - u8 *buffer, int buffer_length) +static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length) { u8 *b; int l; - deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", - fc_usb->tmp_buffer_length, buffer_length); + deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", fc_usb->tmp_buffer_length, buffer_length); if (fc_usb->tmp_buffer_length > 0) { - memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, - buffer_length); + memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, buffer_length); fc_usb->tmp_buffer_length += buffer_length; b = fc_usb->tmp_buffer; l = fc_usb->tmp_buffer_length; @@ -317,26 +304,23 @@ static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, } while (l >= 190) { - if (*b == 0xff) { + if (*b == 0xff) switch (*(b+1) & 0x03) { - case 0x01: /* media packet */ - if (*(b+2) == 0x47) - flexcop_pass_dmx_packets( - fc_usb->fc_dev, b+2, 1); - else - deb_ts( - "not ts packet %02x %02x %02x %02x \n", - *(b+2), *(b+3), - *(b+4), *(b+5)); - b += 190; - l -= 190; + case 0x01: /* media packet */ + if ( *(b+2) == 0x47 ) + flexcop_pass_dmx_packets(fc_usb->fc_dev, b+2, 1); + else + deb_ts("not ts packet %02x %02x %02x %02x \n", *(b+2), *(b+3), *(b+4), *(b+5) ); + + b += 190; + l -= 190; break; - default: - deb_ts("wrong packet type\n"); - l = 0; + default: + deb_ts("wrong packet type\n"); + l = 0; break; } - } else { + else { deb_ts("wrong header\n"); l = 0; } @@ -353,26 +337,23 @@ static void flexcop_usb_urb_complete(struct urb *urb) int i; if (urb->actual_length > 0) - deb_ts("urb completed, bufsize: %d actlen; %d\n", - urb->transfer_buffer_length, urb->actual_length); + deb_ts("urb completed, bufsize: %d actlen; %d\n",urb->transfer_buffer_length, urb->actual_length); for (i = 0; i < urb->number_of_packets; i++) { if (urb->iso_frame_desc[i].status < 0) { - err("iso frame descriptor %d has an error: %d\n", i, - urb->iso_frame_desc[i].status); + err("iso frame descriptor %d has an error: %d\n",i,urb->iso_frame_desc[i].status); } else if (urb->iso_frame_desc[i].actual_length > 0) { - deb_ts("passed %d bytes to the demux\n", - urb->iso_frame_desc[i].actual_length); + deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length); flexcop_usb_process_frame(fc_usb, - urb->transfer_buffer + - urb->iso_frame_desc[i].offset, + urb->transfer_buffer + urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].actual_length); - } + } urb->iso_frame_desc[i].status = 0; urb->iso_frame_desc[i].actual_length = 0; } + usb_submit_urb(urb,GFP_ATOMIC); } @@ -393,47 +374,35 @@ static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb) } if (fc_usb->iso_buffer != NULL) - pci_free_consistent(NULL, - fc_usb->buffer_size, fc_usb->iso_buffer, - fc_usb->dma_addr); + pci_free_consistent(NULL,fc_usb->buffer_size, fc_usb->iso_buffer, fc_usb->dma_addr); } static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) { - u16 frame_size = le16_to_cpu( - fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize); - int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * - frame_size, i, j, ret; + u16 frame_size = le16_to_cpu(fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize); + int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret; int buffer_offset = 0; - deb_ts("creating %d iso-urbs with %d frames " - "each of %d bytes size = %d.\n", B2C2_USB_NUM_ISO_URB, - B2C2_USB_FRAMES_PER_ISO, frame_size, bufsize); + deb_ts("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n", + B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize); - fc_usb->iso_buffer = pci_alloc_consistent(NULL, - bufsize, &fc_usb->dma_addr); + fc_usb->iso_buffer = pci_alloc_consistent(NULL,bufsize,&fc_usb->dma_addr); if (fc_usb->iso_buffer == NULL) return -ENOMEM; - memset(fc_usb->iso_buffer, 0, bufsize); fc_usb->buffer_size = bufsize; /* creating iso urbs */ - for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) { - fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO, - GFP_ATOMIC); - if (fc_usb->iso_urb[i] == NULL) { + for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) + if (!(fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) { ret = -ENOMEM; goto urb_error; } - } - /* initialising and submitting iso urbs */ for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) { int frame_offset = 0; struct urb *urb = fc_usb->iso_urb[i]; - deb_ts("initializing and submitting urb no. %d " - "(buf_offset: %d).\n", i, buffer_offset); + deb_ts("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset); urb->dev = fc_usb->udev; urb->context = fc_usb; @@ -447,26 +416,26 @@ static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO; for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) { - deb_ts("urb no: %d, frame: %d, frame_offset: %d\n", - i, j, frame_offset); + deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset); urb->iso_frame_desc[j].offset = frame_offset; urb->iso_frame_desc[j].length = frame_size; frame_offset += frame_size; } if ((ret = usb_submit_urb(fc_usb->iso_urb[i],GFP_ATOMIC))) { - err("submitting urb %d failed with %d.", i, ret); + err("submitting urb %d failed with %d.",i,ret); goto urb_error; } deb_ts("submitted urb no. %d.\n",i); } - /* SRAM */ - flexcop_sram_set_dest(fc_usb->fc_dev, FC_SRAM_DEST_MEDIA | - FC_SRAM_DEST_NET | FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, - FC_SRAM_DEST_TARGET_WAN_USB); - flexcop_wan_set_speed(fc_usb->fc_dev, FC_WAN_SPEED_8MBITS); - flexcop_sram_ctrl(fc_usb->fc_dev, 1, 1, 1); +/* SRAM */ + + flexcop_sram_set_dest(fc_usb->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET | + FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_WAN_USB); + flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS); + flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1); + return 0; urb_error: @@ -479,20 +448,20 @@ static int flexcop_usb_init(struct flexcop_usb *fc_usb) /* use the alternate setting with the larges buffer */ usb_set_interface(fc_usb->udev,0,1); switch (fc_usb->udev->speed) { - case USB_SPEED_LOW: - err("cannot handle USB speed because it is too slow."); - return -ENODEV; - break; - case USB_SPEED_FULL: - info("running at FULL speed."); - break; - case USB_SPEED_HIGH: - info("running at HIGH speed."); - break; - case USB_SPEED_UNKNOWN: /* fall through */ - default: - err("cannot handle USB speed because it is unknown."); - return -ENODEV; + case USB_SPEED_LOW: + err("cannot handle USB speed because it is to sLOW."); + return -ENODEV; + break; + case USB_SPEED_FULL: + info("running at FULL speed."); + break; + case USB_SPEED_HIGH: + info("running at HIGH speed."); + break; + case USB_SPEED_UNKNOWN: /* fall through */ + default: + err("cannot handle USB speed because it is unkown."); + return -ENODEV; } usb_set_intfdata(fc_usb->uintf, fc_usb); return 0; @@ -516,7 +485,7 @@ static int flexcop_usb_probe(struct usb_interface *intf, return -ENOMEM; } - /* general flexcop init */ +/* general flexcop init */ fc_usb = fc->bus_specific; fc_usb->fc_dev = fc; @@ -533,21 +502,21 @@ static int flexcop_usb_probe(struct usb_interface *intf, fc->dev = &udev->dev; fc->owner = THIS_MODULE; - /* bus specific part */ +/* bus specific part */ fc_usb->udev = udev; fc_usb->uintf = intf; if ((ret = flexcop_usb_init(fc_usb)) != 0) goto err_kfree; - /* init flexcop */ +/* init flexcop */ if ((ret = flexcop_device_initialize(fc)) != 0) goto err_usb_exit; - /* xfer init */ +/* xfer init */ if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0) goto err_fc_exit; - info("%s successfully initialized and connected.", DRIVER_NAME); + info("%s successfully initialized and connected.",DRIVER_NAME); return 0; err_fc_exit: @@ -566,12 +535,12 @@ static void flexcop_usb_disconnect(struct usb_interface *intf) flexcop_device_exit(fc_usb->fc_dev); flexcop_usb_exit(fc_usb); flexcop_device_kfree(fc_usb->fc_dev); - info("%s successfully deinitialized and disconnected.", DRIVER_NAME); + info("%s successfully deinitialized and disconnected.",DRIVER_NAME); } static struct usb_device_id flexcop_usb_table [] = { - { USB_DEVICE(0x0af7, 0x0101) }, - { } + { USB_DEVICE(0x0af7, 0x0101) }, + { } }; MODULE_DEVICE_TABLE (usb, flexcop_usb_table); @@ -588,9 +557,10 @@ static int __init flexcop_usb_module_init(void) { int result; if ((result = usb_register(&flexcop_usb_driver))) { - err("usb_register failed. (%d)", result); + err("usb_register failed. (%d)",result); return result; } + return 0; } diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-usb.h b/trunk/drivers/media/dvb/b2c2/flexcop-usb.h index 92529a9c4475..630e647a2caa 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-usb.h +++ b/trunk/drivers/media/dvb/b2c2/flexcop-usb.h @@ -1,20 +1,15 @@ -/* - * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * flexcop-usb.h - header file for the USB part - * see flexcop.c for copyright information - */ #ifndef __FLEXCOP_USB_H_INCLUDED__ #define __FLEXCOP_USB_H_INCLUDED__ #include /* transfer parameters */ -#define B2C2_USB_FRAMES_PER_ISO 4 -#define B2C2_USB_NUM_ISO_URB 4 +#define B2C2_USB_FRAMES_PER_ISO 4 +#define B2C2_USB_NUM_ISO_URB 4 -#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev, 0) -#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev, 0) -#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev, 0x81) +#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev,0) +#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev,0) +#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev,0x81) struct flexcop_usb { struct usb_device *udev; @@ -23,8 +18,8 @@ struct flexcop_usb { u8 *iso_buffer; int buffer_size; dma_addr_t dma_addr; - struct urb *iso_urb[B2C2_USB_NUM_ISO_URB]; + struct flexcop_device *fc_dev; u8 tmp_buffer[1023+190]; @@ -35,6 +30,14 @@ struct flexcop_usb { /* request types TODO What is its use?*/ typedef enum { +/* something is wrong with this part + RTYPE_READ_DW = (1 << 6), + RTYPE_WRITE_DW_1 = (3 << 6), + RTYPE_READ_V8_MEMORY = (6 << 6), + RTYPE_WRITE_V8_MEMORY = (7 << 6), + RTYPE_WRITE_V8_FLASH = (8 << 6), + RTYPE_GENERIC = (9 << 6), +*/ } flexcop_usb_request_type_t; #endif @@ -44,6 +47,7 @@ typedef enum { B2C2_USB_READ_V8_MEM = 0x05, B2C2_USB_READ_REG = 0x08, B2C2_USB_WRITE_REG = 0x0A, +/* B2C2_USB_WRITEREGLO = 0x0A, */ B2C2_USB_WRITEREGHI = 0x0B, B2C2_USB_FLASH_BLOCK = 0x10, B2C2_USB_I2C_REQUEST = 0x11, @@ -58,13 +62,15 @@ typedef enum { USB_FUNC_I2C_REPEATWRITE = 0x04, USB_FUNC_GET_DESCRIPTOR = 0x05, USB_FUNC_I2C_REPEATREAD = 0x06, - /* DKT 020208 - add this to support special case of DiSEqC */ +/* DKT 020208 - add this to support special case of DiSEqC */ USB_FUNC_I2C_CHECKWRITE = 0x07, USB_FUNC_I2C_CHECKRESULT = 0x08, } flexcop_usb_i2c_function_t; -/* function definition for UTILITY request 0x12 - * DKT 020304 - new utility function */ +/* + * function definition for UTILITY request 0x12 + * DKT 020304 - new utility function + */ typedef enum { UTILITY_SET_FILTER = 0x01, UTILITY_DATA_ENABLE = 0x02, @@ -78,7 +84,7 @@ typedef enum { UTILITY_DATA_RESET = 0x0A, UTILITY_GET_DATA_STATUS = 0x10, UTILITY_GET_V8_REG = 0x11, - /* DKT 020326 - add function for v1.14 */ +/* DKT 020326 - add function for v1.14 */ UTILITY_SRAM_WRITE = 0x12, UTILITY_SRAM_READ = 0x13, UTILITY_SRAM_TESTFILL = 0x14, @@ -86,13 +92,13 @@ typedef enum { UTILITY_SRAM_TESTVERIFY = 0x16, } flexcop_usb_utility_function_t; -#define B2C2_WAIT_FOR_OPERATION_RW (1*HZ) -#define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ) -#define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ) +#define B2C2_WAIT_FOR_OPERATION_RW 1*HZ /* 1 s */ +#define B2C2_WAIT_FOR_OPERATION_RDW 3*HZ /* 3 s */ +#define B2C2_WAIT_FOR_OPERATION_WDW 1*HZ /* 1 s */ -#define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ) -#define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ) -#define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ) +#define B2C2_WAIT_FOR_OPERATION_V8READ 3*HZ /* 3 s */ +#define B2C2_WAIT_FOR_OPERATION_V8WRITE 3*HZ /* 3 s */ +#define B2C2_WAIT_FOR_OPERATION_V8FLASH 3*HZ /* 3 s */ typedef enum { V8_MEMORY_PAGE_DVB_CI = 0x20, @@ -101,11 +107,13 @@ typedef enum { V8_MEMORY_PAGE_FLASH = 0x80 } flexcop_usb_mem_page_t; -#define V8_MEMORY_EXTENDED (1 << 15) -#define USB_MEM_READ_MAX 32 -#define USB_MEM_WRITE_MAX 1 -#define USB_FLASH_MAX 8 -#define V8_MEMORY_PAGE_SIZE 0x8000 /* 32K */ -#define V8_MEMORY_PAGE_MASK 0x7FFF +#define V8_MEMORY_EXTENDED (1 << 15) + +#define USB_MEM_READ_MAX 32 +#define USB_MEM_WRITE_MAX 1 +#define USB_FLASH_MAX 8 + +#define V8_MEMORY_PAGE_SIZE 0x8000 // 32K +#define V8_MEMORY_PAGE_MASK 0x7FFF #endif diff --git a/trunk/drivers/media/dvb/b2c2/flexcop.c b/trunk/drivers/media/dvb/b2c2/flexcop.c index 2df1b0214dcd..91068952b502 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop.c @@ -1,20 +1,22 @@ /* - * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * flexcop.c - main module part - * Copyright (C) 2004-9 Patrick Boettcher - * based on skystar2-driver Copyright (C) 2003 Vadim Catana, skystar@moldova.cc + * flexcop.c - driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * + * Copyright (C) 2004-5 Patrick Boettcher + * + * based on the skystar2-driver + * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc * * Acknowledgements: - * John Jurrius from BBTI, Inc. for extensive support - * with code examples and data books - * Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting) + * John Jurrius from BBTI, Inc. for extensive support with + * code examples and data books + * + * Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting) * * Contributions to the skystar2-driver have been done by - * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes) - * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code) - * Uwe Bugla, uwe.bugla at gmx.de (doing tests, restyling code, writing docu) - * Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac - * filtering) + * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes) + * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code) + * Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac filtering) + * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -44,10 +46,7 @@ int b2c2_flexcop_debug; module_param_named(debug, b2c2_flexcop_debug, int, 0644); -MODULE_PARM_DESC(debug, - "set debug level (1=info,2=tuner,4=i2c,8=ts," - "16=sram,32=reg (|-able))." - DEBSTATUS); +MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram,32=reg (|-able))." DEBSTATUS); #undef DEBSTATUS DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -58,36 +57,37 @@ flexcop_ibi_value ibi_zero; static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) { struct flexcop_device *fc = dvbdmxfeed->demux->priv; - return flexcop_pid_feed_control(fc, dvbdmxfeed, 1); + return flexcop_pid_feed_control(fc,dvbdmxfeed,1); } static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) { struct flexcop_device *fc = dvbdmxfeed->demux->priv; - return flexcop_pid_feed_control(fc, dvbdmxfeed, 0); + return flexcop_pid_feed_control(fc,dvbdmxfeed,0); } static int flexcop_dvb_init(struct flexcop_device *fc) { int ret = dvb_register_adapter(&fc->dvb_adapter, - "FlexCop Digital TV device", fc->owner, - fc->dev, adapter_nr); + "FlexCop Digital TV device", fc->owner, + fc->dev, adapter_nr); if (ret < 0) { err("error registering DVB adapter"); return ret; } fc->dvb_adapter.priv = fc; - fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING - | DMX_MEMORY_BASED_FILTERING); + fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); fc->demux.priv = fc; + fc->demux.filternum = fc->demux.feednum = FC_MAX_FEED; + fc->demux.start_feed = flexcop_dvb_start_feed; fc->demux.stop_feed = flexcop_dvb_stop_feed; fc->demux.write_to_decoder = NULL; if ((ret = dvb_dmx_init(&fc->demux)) < 0) { - err("dvb_dmx failed: error %d", ret); + err("dvb_dmx failed: error %d",ret); goto err_dmx; } @@ -97,23 +97,23 @@ static int flexcop_dvb_init(struct flexcop_device *fc) fc->dmxdev.demux = &fc->demux.dmx; fc->dmxdev.capabilities = 0; if ((ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter)) < 0) { - err("dvb_dmxdev_init failed: error %d", ret); + err("dvb_dmxdev_init failed: error %d",ret); goto err_dmx_dev; } if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) { - err("adding hw_frontend to dmx failed: error %d", ret); + err("adding hw_frontend to dmx failed: error %d",ret); goto err_dmx_add_hw_frontend; } fc->mem_frontend.source = DMX_MEMORY_FE; if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend)) < 0) { - err("adding mem_frontend to dmx failed: error %d", ret); + err("adding mem_frontend to dmx failed: error %d",ret); goto err_dmx_add_mem_frontend; } if ((ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) { - err("connect frontend failed: error %d", ret); + err("connect frontend failed: error %d",ret); goto err_connect_frontend; } @@ -123,9 +123,9 @@ static int flexcop_dvb_init(struct flexcop_device *fc) return 0; err_connect_frontend: - fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->mem_frontend); + fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend); err_dmx_add_mem_frontend: - fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->hw_frontend); + fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend); err_dmx_add_hw_frontend: dvb_dmxdev_release(&fc->dmxdev); err_dmx_dev: @@ -141,13 +141,12 @@ static void flexcop_dvb_exit(struct flexcop_device *fc) dvb_net_release(&fc->dvbnet); fc->demux.dmx.close(&fc->demux.dmx); - fc->demux.dmx.remove_frontend(&fc->demux.dmx, - &fc->mem_frontend); - fc->demux.dmx.remove_frontend(&fc->demux.dmx, - &fc->hw_frontend); + fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend); + fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend); dvb_dmxdev_release(&fc->dmxdev); dvb_dmx_release(&fc->demux); dvb_unregister_adapter(&fc->dvb_adapter); + deb_info("deinitialized dvb stuff\n"); } fc->init_state &= ~FC_STATE_DVB_INIT; @@ -169,9 +168,9 @@ EXPORT_SYMBOL(flexcop_pass_dmx_packets); static void flexcop_reset(struct flexcop_device *fc) { - flexcop_ibi_value v210, v204; + flexcop_ibi_value v210,v204; - /* reset the flexcop itself */ +/* reset the flexcop itself */ fc->write_ibi_reg(fc,ctrl_208,ibi_zero); v210.raw = 0; @@ -184,11 +183,13 @@ static void flexcop_reset(struct flexcop_device *fc) v210.sw_reset_210.reset_block_600 = 1; v210.sw_reset_210.reset_block_700 = 1; v210.sw_reset_210.Block_reset_enable = 0xb2; + v210.sw_reset_210.Special_controls = 0xc259; + fc->write_ibi_reg(fc,sw_reset_210,v210); msleep(1); - /* reset the periphical devices */ +/* reset the periphical devices */ v204 = fc->read_ibi_reg(fc,misc_204); v204.misc_204.Per_reset_sig = 0; @@ -200,24 +201,25 @@ static void flexcop_reset(struct flexcop_device *fc) void flexcop_reset_block_300(struct flexcop_device *fc) { - flexcop_ibi_value v208_save = fc->read_ibi_reg(fc, ctrl_208), - v210 = fc->read_ibi_reg(fc, sw_reset_210); + flexcop_ibi_value v208_save = fc->read_ibi_reg(fc,ctrl_208), + v210 = fc->read_ibi_reg(fc,sw_reset_210); + + deb_rdump("208: %08x, 210: %08x\n",v208_save.raw,v210.raw); - deb_rdump("208: %08x, 210: %08x\n", v208_save.raw, v210.raw); fc->write_ibi_reg(fc,ctrl_208,ibi_zero); v210.sw_reset_210.reset_block_300 = 1; v210.sw_reset_210.Block_reset_enable = 0xb2; fc->write_ibi_reg(fc,sw_reset_210,v210); + udelay(1000); fc->write_ibi_reg(fc,ctrl_208,v208_save); } struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len) { void *bus; - struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device), - GFP_KERNEL); + struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device), GFP_KERNEL); if (!fc) { err("no memory"); return NULL; @@ -252,6 +254,7 @@ int flexcop_device_initialize(struct flexcop_device *fc) flexcop_determine_revision(fc); flexcop_sram_init(fc); flexcop_hw_filter_init(fc); + flexcop_smc_ctrl(fc, 0); if ((ret = flexcop_dvb_init(fc))) @@ -276,6 +279,7 @@ int flexcop_device_initialize(struct flexcop_device *fc) goto error; flexcop_device_name(fc,"initialization of","complete"); + return 0; error: diff --git a/trunk/drivers/media/dvb/b2c2/flexcop.h b/trunk/drivers/media/dvb/b2c2/flexcop.h index 897b10c85ad9..0cebe1d92e0b 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop.h +++ b/trunk/drivers/media/dvb/b2c2/flexcop.h @@ -1,7 +1,9 @@ /* - * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * flexcop.h - private header file for all flexcop-chip-source files - * see flexcop.c for copyright information + * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III + * + * flexcop.h - private header file for all flexcop-chip-source files. + * + * see flexcop.c for copyright information. */ #ifndef __FLEXCOP_H__ #define __FLEXCOP_H___ @@ -19,11 +21,11 @@ extern int b2c2_flexcop_debug; #define dprintk(level,args...) #endif -#define deb_info(args...) dprintk(0x01, args) -#define deb_tuner(args...) dprintk(0x02, args) -#define deb_i2c(args...) dprintk(0x04, args) -#define deb_ts(args...) dprintk(0x08, args) -#define deb_sram(args...) dprintk(0x10, args) -#define deb_rdump(args...) dprintk(0x20, args) +#define deb_info(args...) dprintk(0x01,args) +#define deb_tuner(args...) dprintk(0x02,args) +#define deb_i2c(args...) dprintk(0x04,args) +#define deb_ts(args...) dprintk(0x08,args) +#define deb_sram(args...) dprintk(0x10,args) +#define deb_rdump(args...) dprintk(0x20,args) #endif diff --git a/trunk/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h b/trunk/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h index 8f64bdbd72bb..ed9a6756b194 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h +++ b/trunk/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h @@ -1,7 +1,10 @@ -/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III +/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * * register descriptions - * see flexcop.c for copyright information + * + * see flexcop.c for copyright information. */ + /* This file is automatically generated, do not edit things here. */ #ifndef __FLEXCOP_IBI_VALUE_INCLUDED__ #define __FLEXCOP_IBI_VALUE_INCLUDED__ diff --git a/trunk/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h b/trunk/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h index c75830d7d942..49f2315b6e58 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h +++ b/trunk/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h @@ -1,7 +1,10 @@ -/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III +/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * * register descriptions - * see flexcop.c for copyright information + * + * see flexcop.c for copyright information. */ + /* This file is automatically generated, do not edit things here. */ #ifndef __FLEXCOP_IBI_VALUE_INCLUDED__ #define __FLEXCOP_IBI_VALUE_INCLUDED__ diff --git a/trunk/drivers/media/dvb/bt8xx/Kconfig b/trunk/drivers/media/dvb/bt8xx/Kconfig index 8668e634c7ec..27edb0ece587 100644 --- a/trunk/drivers/media/dvb/bt8xx/Kconfig +++ b/trunk/drivers/media/dvb/bt8xx/Kconfig @@ -8,7 +8,7 @@ config DVB_BT8XX select DVB_OR51211 if !DVB_FE_CUSTOMISE select DVB_LGDT330X if !DVB_FE_CUSTOMISE select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE help Support for PCI cards based on the Bt8xx PCI bridge. Examples are the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, diff --git a/trunk/drivers/media/dvb/bt8xx/dst_ca.c b/trunk/drivers/media/dvb/bt8xx/dst_ca.c index 4601b059b2b2..0258451423ad 100644 --- a/trunk/drivers/media/dvb/bt8xx/dst_ca.c +++ b/trunk/drivers/media/dvb/bt8xx/dst_ca.c @@ -552,19 +552,16 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, return result; } -static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioctl_arg) +static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg) { - struct dvb_device *dvbdev; - struct dst_state *state; + struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; + struct dst_state* state = (struct dst_state*) dvbdev->priv; struct ca_slot_info *p_ca_slot_info; struct ca_caps *p_ca_caps; struct ca_msg *p_ca_message; void __user *arg = (void __user *)ioctl_arg; int result = 0; - lock_kernel(); - dvbdev = (struct dvb_device *)file->private_data; - state = (struct dst_state *)dvbdev->priv; p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL); p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL); p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL); @@ -650,7 +647,6 @@ static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioct kfree (p_ca_slot_info); kfree (p_ca_caps); - unlock_kernel(); return result; } @@ -686,9 +682,9 @@ static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t return 0; } -static const struct file_operations dst_ca_fops = { +static struct file_operations dst_ca_fops = { .owner = THIS_MODULE, - .unlocked_ioctl = dst_ca_ioctl, + .ioctl = dst_ca_ioctl, .open = dst_ca_open, .release = dst_ca_release, .read = dst_ca_read, diff --git a/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c index b1857c19bbd2..48762a2b9e42 100644 --- a/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -814,7 +814,7 @@ static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) mutex_init(&card->lock); card->bttv_nr = sub->core->nr; - strlcpy(card->card_name, sub->core->v4l2_dev.name, sizeof(card->card_name)); + strncpy(card->card_name, sub->core->name, sizeof(sub->core->name)); card->i2c_adapter = &sub->core->i2c_adap; switch(sub->core->type) { diff --git a/trunk/drivers/media/dvb/dm1105/Kconfig b/trunk/drivers/media/dvb/dm1105/Kconfig index de3eeb0a8d6e..43f4d44edca6 100644 --- a/trunk/drivers/media/dvb/dm1105/Kconfig +++ b/trunk/drivers/media/dvb/dm1105/Kconfig @@ -8,7 +8,6 @@ config DVB_DM1105 select DVB_STB6000 if !DVB_FE_CUSTOMISE select DVB_CX24116 if !DVB_FE_CUSTOMISE select DVB_SI21XX if !DVB_FE_CUSTOMISE - select VIDEO_IR help Support for cards based on the SDMC DM1105 PCI chip like DvbWorld 2002 diff --git a/trunk/drivers/media/dvb/dm1105/dm1105.c b/trunk/drivers/media/dvb/dm1105/dm1105.c index 5b20cf5a29f0..f48f73aff195 100644 --- a/trunk/drivers/media/dvb/dm1105/dm1105.c +++ b/trunk/drivers/media/dvb/dm1105/dm1105.c @@ -156,12 +156,46 @@ MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); +static u16 ir_codes_dm1105_nec[128] = { + [0x0a] = KEY_Q, /*power*/ + [0x0c] = KEY_M, /*mute*/ + [0x11] = KEY_1, + [0x12] = KEY_2, + [0x13] = KEY_3, + [0x14] = KEY_4, + [0x15] = KEY_5, + [0x16] = KEY_6, + [0x17] = KEY_7, + [0x18] = KEY_8, + [0x19] = KEY_9, + [0x10] = KEY_0, + [0x1c] = KEY_PAGEUP, /*ch+*/ + [0x0f] = KEY_PAGEDOWN, /*ch-*/ + [0x1a] = KEY_O, /*vol+*/ + [0x0e] = KEY_Z, /*vol-*/ + [0x04] = KEY_R, /*rec*/ + [0x09] = KEY_D, /*fav*/ + [0x08] = KEY_BACKSPACE, /*rewind*/ + [0x07] = KEY_A, /*fast*/ + [0x0b] = KEY_P, /*pause*/ + [0x02] = KEY_ESC, /*cancel*/ + [0x03] = KEY_G, /*tab*/ + [0x00] = KEY_UP, /*up*/ + [0x1f] = KEY_ENTER, /*ok*/ + [0x01] = KEY_DOWN, /*down*/ + [0x05] = KEY_C, /*cap*/ + [0x06] = KEY_S, /*stop*/ + [0x40] = KEY_F, /*full*/ + [0x1e] = KEY_W, /*tvmode*/ + [0x1b] = KEY_B, /*recall*/ +}; + /* infrared remote control */ struct infrared { + u16 key_map[128]; struct input_dev *input_dev; - struct ir_input_state ir; char input_phys[32]; - struct work_struct work; + struct tasklet_struct ir_tasklet; u32 ir_command; }; @@ -186,14 +220,10 @@ struct dm1105dvb { /* i2c */ struct i2c_adapter i2c_adap; - /* irq */ - struct work_struct work; - /* dma */ dma_addr_t dma_addr; unsigned char *ts_buf; u32 wrp; - u32 nextwrp; u32 buffer_size; unsigned int PacketErrorCount; unsigned int dmarst; @@ -203,6 +233,8 @@ struct dm1105dvb { #define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg])) +static struct dm1105dvb *dm1105dvb_local; + static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { @@ -375,61 +407,38 @@ static int dm1105dvb_stop_feed(struct dvb_demux_feed *f) return 0; } -/* ir work handler */ -static void dm1105_emit_key(struct work_struct *work) +/* ir tasklet */ +static void dm1105_emit_key(unsigned long parm) { - struct infrared *ir = container_of(work, struct infrared, work); + struct infrared *ir = (struct infrared *) parm; u32 ircom = ir->ir_command; u8 data; - - if (ir_debug) - printk(KERN_INFO "%s: received byte 0x%04x\n", __func__, ircom); + u16 keycode; data = (ircom >> 8) & 0x7f; - ir_input_keydown(ir->input_dev, &ir->ir, data, data); - ir_input_nokey(ir->input_dev, &ir->ir); -} + input_event(ir->input_dev, EV_MSC, MSC_RAW, (0x0000f8 << 16) | data); + input_event(ir->input_dev, EV_MSC, MSC_SCAN, data); + keycode = ir->key_map[data]; -/* work handler */ -static void dm1105_dmx_buffer(struct work_struct *work) -{ - struct dm1105dvb *dm1105dvb = - container_of(work, struct dm1105dvb, work); - unsigned int nbpackets; - u32 oldwrp = dm1105dvb->wrp; - u32 nextwrp = dm1105dvb->nextwrp; - - if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) && - (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) && - (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) { - dm1105dvb->PacketErrorCount++; - /* bad packet found */ - if ((dm1105dvb->PacketErrorCount >= 2) && - (dm1105dvb->dmarst == 0)) { - outb(1, dm_io_mem(DM1105_RST)); - dm1105dvb->wrp = 0; - dm1105dvb->PacketErrorCount = 0; - dm1105dvb->dmarst = 0; - return; - } - } + if (!keycode) + return; - if (nextwrp < oldwrp) { - memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size, - dm1105dvb->ts_buf, nextwrp); - nbpackets = ((dm1105dvb->buffer_size - oldwrp) + nextwrp) / 188; - } else - nbpackets = (nextwrp - oldwrp) / 188; + input_event(ir->input_dev, EV_KEY, keycode, 1); + input_sync(ir->input_dev); + input_event(ir->input_dev, EV_KEY, keycode, 0); + input_sync(ir->input_dev); - dm1105dvb->wrp = nextwrp; - dvb_dmx_swfilter_packets(&dm1105dvb->demux, - &dm1105dvb->ts_buf[oldwrp], nbpackets); } static irqreturn_t dm1105dvb_irq(int irq, void *dev_id) { struct dm1105dvb *dm1105dvb = dev_id; + unsigned int piece; + unsigned int nbpackets; + u32 command; + u32 nextwrp; + u32 oldwrp; /* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */ unsigned int intsts = inb(dm_io_mem(DM1105_INTSTS)); @@ -438,25 +447,71 @@ static irqreturn_t dm1105dvb_irq(int irq, void *dev_id) switch (intsts) { case INTSTS_TSIRQ: case (INTSTS_TSIRQ | INTSTS_IR): - dm1105dvb->nextwrp = inl(dm_io_mem(DM1105_WRP)) - - inl(dm_io_mem(DM1105_STADR)); - schedule_work(&dm1105dvb->work); + nextwrp = inl(dm_io_mem(DM1105_WRP)) - + inl(dm_io_mem(DM1105_STADR)) ; + oldwrp = dm1105dvb->wrp; + spin_lock(&dm1105dvb->lock); + if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) && + (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) && + (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) { + dm1105dvb->PacketErrorCount++; + /* bad packet found */ + if ((dm1105dvb->PacketErrorCount >= 2) && + (dm1105dvb->dmarst == 0)) { + outb(1, dm_io_mem(DM1105_RST)); + dm1105dvb->wrp = 0; + dm1105dvb->PacketErrorCount = 0; + dm1105dvb->dmarst = 0; + spin_unlock(&dm1105dvb->lock); + return IRQ_HANDLED; + } + } + if (nextwrp < oldwrp) { + piece = dm1105dvb->buffer_size - oldwrp; + memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size, dm1105dvb->ts_buf, nextwrp); + nbpackets = (piece + nextwrp)/188; + } else { + nbpackets = (nextwrp - oldwrp)/188; + } + dvb_dmx_swfilter_packets(&dm1105dvb->demux, &dm1105dvb->ts_buf[oldwrp], nbpackets); + dm1105dvb->wrp = nextwrp; + spin_unlock(&dm1105dvb->lock); break; case INTSTS_IR: - dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE)); - schedule_work(&dm1105dvb->ir.work); + command = inl(dm_io_mem(DM1105_IRCODE)); + if (ir_debug) + printk("dm1105: received byte 0x%04x\n", command); + + dm1105dvb->ir.ir_command = command; + tasklet_schedule(&dm1105dvb->ir.ir_tasklet); break; } - return IRQ_HANDLED; + + +} + +/* register with input layer */ +static void input_register_keys(struct infrared *ir) +{ + int i; + + memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit)); + + for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) + set_bit(ir->key_map[i], ir->input_dev->keybit); + + ir->input_dev->keycode = ir->key_map; + ir->input_dev->keycodesize = sizeof(ir->key_map[0]); + ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map); } int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) { struct input_dev *input_dev; - IR_KEYTAB_TYPE *ir_codes = ir_codes_dm1105_nec; - int ir_type = IR_TYPE_OTHER; - int err = -ENOMEM; + int err; + + dm1105dvb_local = dm1105; input_dev = input_allocate_device(); if (!input_dev) @@ -466,11 +521,12 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys), "pci-%s/ir0", pci_name(dm1105->pdev)); - ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes); + input_dev->evbit[0] = BIT(EV_KEY); input_dev->name = "DVB on-card IR receiver"; + input_dev->phys = dm1105->ir.input_phys; input_dev->id.bustype = BUS_PCI; - input_dev->id.version = 1; + input_dev->id.version = 2; if (dm1105->pdev->subsystem_vendor) { input_dev->id.vendor = dm1105->pdev->subsystem_vendor; input_dev->id.product = dm1105->pdev->subsystem_device; @@ -478,22 +534,25 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) input_dev->id.vendor = dm1105->pdev->vendor; input_dev->id.product = dm1105->pdev->device; } - input_dev->dev.parent = &dm1105->pdev->dev; - - INIT_WORK(&dm1105->ir.work, dm1105_emit_key); - + /* initial keymap */ + memcpy(dm1105->ir.key_map, ir_codes_dm1105_nec, sizeof dm1105->ir.key_map); + input_register_keys(&dm1105->ir); err = input_register_device(input_dev); if (err) { input_free_device(input_dev); return err; } + tasklet_init(&dm1105->ir.ir_tasklet, dm1105_emit_key, (unsigned long) &dm1105->ir); + return 0; } + void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105) { + tasklet_kill(&dm1105->ir.ir_tasklet); input_unregister_device(dm1105->ir.input_dev); } @@ -651,7 +710,7 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL); if (!dm1105dvb) - return -ENOMEM; + goto out; dm1105dvb->pdev = pdev; dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES; @@ -681,10 +740,14 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, spin_lock_init(&dm1105dvb->lock); pci_set_drvdata(pdev, dm1105dvb); - ret = dm1105dvb_hw_init(dm1105dvb); + ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, DRIVER_NAME, dm1105dvb); if (ret < 0) goto err_pci_iounmap; + ret = dm1105dvb_hw_init(dm1105dvb); + if (ret < 0) + goto err_free_irq; + /* i2c */ i2c_set_adapdata(&dm1105dvb->i2c_adap, dm1105dvb); strcpy(dm1105dvb->i2c_adap.name, DRIVER_NAME); @@ -750,15 +813,8 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, dvb_net_init(dvb_adapter, &dm1105dvb->dvbnet, dmx); dm1105_ir_init(dm1105dvb); - - INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer); - - ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, - DRIVER_NAME, dm1105dvb); - if (ret < 0) - goto err_free_irq; - - return 0; +out: + return ret; err_disconnect_frontend: dmx->disconnect_frontend(dmx); @@ -787,7 +843,7 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, err_kfree: pci_set_drvdata(pdev, NULL); kfree(dm1105dvb); - return ret; + goto out; } static void __devexit dm1105_remove(struct pci_dev *pdev) diff --git a/trunk/drivers/media/dvb/dvb-core/dmxdev.c b/trunk/drivers/media/dvb/dvb-core/dmxdev.c index c35fbb8d8f4a..069d847ba887 100644 --- a/trunk/drivers/media/dvb/dvb-core/dmxdev.c +++ b/trunk/drivers/media/dvb/dvb-core/dmxdev.c @@ -1024,7 +1024,7 @@ static int dvb_demux_release(struct inode *inode, struct file *file) return ret; } -static const struct file_operations dvb_demux_fops = { +static struct file_operations dvb_demux_fops = { .owner = THIS_MODULE, .read = dvb_demux_read, .ioctl = dvb_demux_ioctl, diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/trunk/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index cb22da53bfb0..7e3aeaa7370f 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_ca_en50221.c @@ -1607,7 +1607,7 @@ static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait) EXPORT_SYMBOL(dvb_ca_en50221_init); -static const struct file_operations dvb_ca_fops = { +static struct file_operations dvb_ca_fops = { .owner = THIS_MODULE, .read = dvb_ca_en50221_io_read, .write = dvb_ca_en50221_io_write, diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c index ebc78157b9b8..8dcb3fbf7acd 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1875,7 +1875,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) return ret; } -static const struct file_operations dvb_frontend_fops = { +static struct file_operations dvb_frontend_fops = { .owner = THIS_MODULE, .ioctl = dvb_generic_ioctl, .poll = dvb_frontend_poll, diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_net.c b/trunk/drivers/media/dvb/dvb-core/dvb_net.c index 8280f8d66a38..f6ba8468858e 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_net.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_net.c @@ -1459,7 +1459,7 @@ static int dvb_net_close(struct inode *inode, struct file *file) } -static const struct file_operations dvb_net_fops = { +static struct file_operations dvb_net_fops = { .owner = THIS_MODULE, .ioctl = dvb_net_ioctl, .open = dvb_generic_open, diff --git a/trunk/drivers/media/dvb/dvb-core/dvbdev.c b/trunk/drivers/media/dvb/dvb-core/dvbdev.c index a454ee8f1e43..6a32680dbb1b 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvbdev.c +++ b/trunk/drivers/media/dvb/dvb-core/dvbdev.c @@ -228,8 +228,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, dvbdev->fops = dvbdevfops; init_waitqueue_head (&dvbdev->wait_queue); - memcpy(dvbdevfops, template->fops, sizeof(struct file_operations)); - dvbdevfops->owner = adap->module; + memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations)); + dvbdev->fops->owner = adap->module; list_add_tail (&dvbdev->list_head, &adap->device_list); diff --git a/trunk/drivers/media/dvb/dvb-core/dvbdev.h b/trunk/drivers/media/dvb/dvb-core/dvbdev.h index 79927305e84d..dca49cf962e8 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvbdev.h +++ b/trunk/drivers/media/dvb/dvb-core/dvbdev.h @@ -71,7 +71,7 @@ struct dvb_adapter { struct dvb_device { struct list_head list_head; - const struct file_operations *fops; + struct file_operations *fops; struct dvb_adapter *adapter; int type; int minor; diff --git a/trunk/drivers/media/dvb/dvb-usb/Kconfig b/trunk/drivers/media/dvb/dvb-usb/Kconfig index 6103caad1644..49f7b20c25d6 100644 --- a/trunk/drivers/media/dvb/dvb-usb/Kconfig +++ b/trunk/drivers/media/dvb/dvb-usb/Kconfig @@ -25,7 +25,7 @@ config DVB_USB_A800 depends on DVB_USB select DVB_DIB3000MC select DVB_PLL if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE help Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. @@ -34,7 +34,7 @@ config DVB_USB_DIBUSB_MB depends on DVB_USB select DVB_PLL if !DVB_FE_CUSTOMISE select DVB_DIB3000MB - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE help Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by DiBcom () equipped with a DiB3000M-B demodulator. @@ -55,7 +55,7 @@ config DVB_USB_DIBUSB_MC tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" depends on DVB_USB select DVB_DIB3000MC - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE help Support for USB2.0 DVB-T receivers based on reference designs made by DiBcom () equipped with a DiB3000M-C/P demodulator. @@ -69,17 +69,15 @@ config DVB_USB_DIBUSB_MC config DVB_USB_DIB0700 tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)" depends on DVB_USB - select DVB_DIB7000P if !DVB_FE_CUSTOMISE - select DVB_DIB7000M if !DVB_FE_CUSTOMISE - select DVB_DIB3000MC if !DVB_FE_CUSTOMISE + select DVB_DIB7000P + select DVB_DIB7000M + select DVB_DIB3000MC select DVB_S5H1411 if !DVB_FE_CUSTOMISE - select DVB_LGDT3305 if !DVB_FE_CUSTOMISE - select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE + select DVB_TUNER_DIB0070 + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE help Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The USB bridge is also present in devices having the DiB7700 DVB-T-USB @@ -97,8 +95,7 @@ config DVB_USB_UMT_010 depends on DVB_USB select DVB_PLL if !DVB_FE_CUSTOMISE select DVB_DIB3000MC - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE - select DVB_MT352 if !DVB_FE_CUSTOMISE + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE help Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. @@ -111,11 +108,10 @@ config DVB_USB_CXUSB select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_ZL10353 if !DVB_FE_CUSTOMISE select DVB_DIB7000P if !DVB_FE_CUSTOMISE - select DVB_LGS8GL5 if !DVB_FE_CUSTOMISE select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE help Say Y here to support the Conexant USB2.0 hybrid reference design. Currently, only DVB and ATSC modes are supported, analog mode @@ -129,8 +125,8 @@ config DVB_USB_M920X depends on DVB_USB select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE help Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver. Currently, only devices with a product id of @@ -141,7 +137,7 @@ config DVB_USB_GL861 tristate "Genesys Logic GL861 USB2.0 support" depends on DVB_USB select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE help Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0 receiver with USB ID 0db0:5581. @@ -150,7 +146,7 @@ config DVB_USB_AU6610 tristate "Alcor Micro AU6610 USB2.0 support" depends on DVB_USB select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE help Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver. @@ -203,7 +199,7 @@ config DVB_USB_NOVA_T_USB2 depends on DVB_USB select DVB_DIB3000MC select DVB_PLL if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE help Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. @@ -239,8 +235,8 @@ config DVB_USB_OPERA1 config DVB_USB_AF9005 tristate "Afatech AF9005 DVB-T USB1.1 support" depends on DVB_USB && EXPERIMENTAL - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE help Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver and the TerraTec Cinergy T USB XE (Rev.1) @@ -288,7 +284,7 @@ config DVB_USB_DTV5100 tristate "AME DTV-5100 USB2.0 DVB-T support" depends on DVB_USB select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE help Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver. @@ -297,18 +293,9 @@ config DVB_USB_AF9015 depends on DVB_USB && EXPERIMENTAL select DVB_AF9013 select DVB_PLL if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE - help - Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver - -config DVB_USB_CE6230 - tristate "Intel CE6230 DVB-T USB2.0 support" - depends on DVB_USB && EXPERIMENTAL - select DVB_ZL10353 + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE help - Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver + Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver diff --git a/trunk/drivers/media/dvb/dvb-usb/Makefile b/trunk/drivers/media/dvb/dvb-usb/Makefile index f92734ed777a..3122b7cc2c23 100644 --- a/trunk/drivers/media/dvb/dvb-usb/Makefile +++ b/trunk/drivers/media/dvb/dvb-usb/Makefile @@ -76,8 +76,6 @@ obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o -dvb-usb-ce6230-objs = ce6230.o -obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ # due to tuner-xc3028 diff --git a/trunk/drivers/media/dvb/dvb-usb/af9015.c b/trunk/drivers/media/dvb/dvb-usb/af9015.c index f0ba8b07b84f..6a97a40d3dfb 100644 --- a/trunk/drivers/media/dvb/dvb-usb/af9015.c +++ b/trunk/drivers/media/dvb/dvb-usb/af9015.c @@ -27,7 +27,9 @@ #include "qt1010.h" #include "tda18271.h" #include "mxl5005s.h" -#include "mc44s803.h" +#if 0 +#include "mc44s80x.h" +#endif static int dvb_usb_af9015_debug; module_param_named(debug, dvb_usb_af9015_debug, int, 0644); @@ -35,6 +37,9 @@ MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); static int dvb_usb_af9015_remote; module_param_named(remote, dvb_usb_af9015_remote, int, 0644); MODULE_PARM_DESC(remote, "select remote"); +static int dvb_usb_af9015_dual_mode; +module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644); +MODULE_PARM_DESC(dual_mode, "enable dual mode"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); static DEFINE_MUTEX(af9015_usb_mutex); @@ -278,21 +283,6 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. req.data = &msg[i+1].buf[0]; ret = af9015_ctrl_msg(d, &req); i += 2; - } else if (msg[i].flags & I2C_M_RD) { - ret = -EINVAL; - if (msg[i].addr == - af9015_af9013_config[0].demod_address) - goto error; - else - req.cmd = READ_I2C; - req.i2c_addr = msg[i].addr; - req.addr = addr; - req.mbox = mbox; - req.addr_len = addr_len; - req.data_len = msg[i].len; - req.data = &msg[i].buf[0]; - ret = af9015_ctrl_msg(d, &req); - i += 1; } else { if (msg[i].addr == af9015_af9013_config[0].demod_address) @@ -758,16 +748,6 @@ static int af9015_read_config(struct usb_device *udev) af9015_config.ir_table_size = ARRAY_SIZE(af9015_ir_table_digittrade); break; - case AF9015_REMOTE_AVERMEDIA_KS: - af9015_properties[i].rc_key_map = - af9015_rc_keys_avermedia; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_avermedia); - af9015_config.ir_table = - af9015_ir_table_avermedia_ks; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_avermedia_ks); - break; } } else { switch (le16_to_cpu(udev->descriptor.idVendor)) { @@ -856,6 +836,9 @@ static int af9015_read_config(struct usb_device *udev) goto error; af9015_config.dual_mode = val; deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode); + /* disable dual mode by default because it is buggy */ + if (!dvb_usb_af9015_dual_mode) + af9015_config.dual_mode = 0; /* Set adapter0 buffer size according to USB port speed, adapter1 buffer size can be static because it is enabled only USB2.0 */ @@ -952,6 +935,7 @@ static int af9015_read_config(struct usb_device *udev) switch (val) { case AF9013_TUNER_ENV77H11D5: case AF9013_TUNER_MT2060: + case AF9013_TUNER_MC44S803: case AF9013_TUNER_QT1010: case AF9013_TUNER_UNKNOWN: case AF9013_TUNER_MT2060_2: @@ -964,10 +948,6 @@ static int af9015_read_config(struct usb_device *udev) case AF9013_TUNER_MXL5005R: af9015_af9013_config[i].rf_spec_inv = 0; break; - case AF9013_TUNER_MC44S803: - af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO; - af9015_af9013_config[i].rf_spec_inv = 1; - break; default: warn("tuner id:%d not supported, please report!", val); return -ENODEV; @@ -1155,11 +1135,6 @@ static struct mxl5005s_config af9015_mxl5005_config = { .AgcMasterByte = 0x00, }; -static struct mc44s803_config af9015_mc44s803_config = { - .i2c_address = 0xc0, - .dig_out = 1, -}; - static int af9015_tuner_attach(struct dvb_usb_adapter *adap) { struct af9015_state *state = adap->dev->priv; @@ -1204,8 +1179,15 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) DVB_PLL_TDA665X) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_MC44S803: - ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap, - &af9015_mc44s803_config) == NULL ? -ENODEV : 0; +#if 0 + ret = dvb_attach(mc44s80x_attach, adap->fe, i2c_adap) + == NULL ? -ENODEV : 0; +#else + ret = -ENODEV; + info("Freescale MC44S803 tuner found but no driver for that" \ + "tuner. Look at the Linuxtv.org for tuner driver" \ + "status."); +#endif break; case AF9013_TUNER_UNKNOWN: default: @@ -1236,7 +1218,6 @@ static struct usb_device_id af9015_usb_table[] = { {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)}, /* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)}, {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)}, {0}, }; MODULE_DEVICE_TABLE(usb, af9015_usb_table); @@ -1436,8 +1417,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { { .name = "KWorld USB DVB-T TV Stick II " \ "(VS-DVB-T 395U)", - .cold_ids = {&af9015_usb_table[16], - &af9015_usb_table[17], NULL}, + .cold_ids = {&af9015_usb_table[16], NULL}, .warm_ids = {NULL}, }, } diff --git a/trunk/drivers/media/dvb/dvb-usb/af9015.h b/trunk/drivers/media/dvb/dvb-usb/af9015.h index 00e25714662a..21c7782f4889 100644 --- a/trunk/drivers/media/dvb/dvb-usb/af9015.h +++ b/trunk/drivers/media/dvb/dvb-usb/af9015.h @@ -124,7 +124,6 @@ enum af9015_remote { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, AF9015_REMOTE_MYGICTV_U718, AF9015_REMOTE_DIGITTRADE_DVB_T, - AF9015_REMOTE_AVERMEDIA_KS, }; /* Leadtek WinFast DTV Dongle Gold */ @@ -598,36 +597,6 @@ static u8 af9015_ir_table_avermedia[] = { 0x03, 0xfc, 0x03, 0xfc, 0x0e, 0x05, 0x00, }; -static u8 af9015_ir_table_avermedia_ks[] = { - 0x05, 0xfa, 0x01, 0xfe, 0x12, 0x05, 0x00, - 0x05, 0xfa, 0x02, 0xfd, 0x0e, 0x05, 0x00, - 0x05, 0xfa, 0x03, 0xfc, 0x0d, 0x05, 0x00, - 0x05, 0xfa, 0x04, 0xfb, 0x2e, 0x05, 0x00, - 0x05, 0xfa, 0x05, 0xfa, 0x2d, 0x05, 0x00, - 0x05, 0xfa, 0x06, 0xf9, 0x10, 0x05, 0x00, - 0x05, 0xfa, 0x07, 0xf8, 0x0f, 0x05, 0x00, - 0x05, 0xfa, 0x08, 0xf7, 0x3d, 0x05, 0x00, - 0x05, 0xfa, 0x09, 0xf6, 0x1e, 0x05, 0x00, - 0x05, 0xfa, 0x0a, 0xf5, 0x1f, 0x05, 0x00, - 0x05, 0xfa, 0x0b, 0xf4, 0x20, 0x05, 0x00, - 0x05, 0xfa, 0x0c, 0xf3, 0x21, 0x05, 0x00, - 0x05, 0xfa, 0x0d, 0xf2, 0x22, 0x05, 0x00, - 0x05, 0xfa, 0x0e, 0xf1, 0x23, 0x05, 0x00, - 0x05, 0xfa, 0x0f, 0xf0, 0x24, 0x05, 0x00, - 0x05, 0xfa, 0x10, 0xef, 0x25, 0x05, 0x00, - 0x05, 0xfa, 0x11, 0xee, 0x26, 0x05, 0x00, - 0x05, 0xfa, 0x12, 0xed, 0x27, 0x05, 0x00, - 0x05, 0xfa, 0x13, 0xec, 0x04, 0x05, 0x00, - 0x05, 0xfa, 0x15, 0xea, 0x0a, 0x05, 0x00, - 0x05, 0xfa, 0x16, 0xe9, 0x11, 0x05, 0x00, - 0x05, 0xfa, 0x17, 0xe8, 0x15, 0x05, 0x00, - 0x05, 0xfa, 0x18, 0xe7, 0x16, 0x05, 0x00, - 0x05, 0xfa, 0x1c, 0xe3, 0x05, 0x05, 0x00, - 0x05, 0xfa, 0x1d, 0xe2, 0x09, 0x05, 0x00, - 0x05, 0xfa, 0x4d, 0xb2, 0x3f, 0x05, 0x00, - 0x05, 0xfa, 0x56, 0xa9, 0x3e, 0x05, 0x00 -}; - /* Digittrade DVB-T USB Stick */ static struct dvb_usb_rc_key af9015_rc_keys_digittrade[] = { { 0x01, 0x0f, KEY_LAST }, /* RETURN */ diff --git a/trunk/drivers/media/dvb/dvb-usb/ce6230.c b/trunk/drivers/media/dvb/dvb-usb/ce6230.c deleted file mode 100644 index 5862820f109f..000000000000 --- a/trunk/drivers/media/dvb/dvb-usb/ce6230.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver - * - * Copyright (C) 2009 Antti Palosaari - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include "ce6230.h" -#include "zl10353.h" -#include "mxl5005s.h" - -/* debug */ -static int dvb_usb_ce6230_debug; -module_param_named(debug, dvb_usb_ce6230_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static struct zl10353_config ce6230_zl10353_config; - -static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req) -{ - int ret; - unsigned int pipe; - u8 request; - u8 requesttype; - u16 value; - u16 index; - u8 buf[req->data_len]; - - request = req->cmd; - value = req->value; - index = req->index; - - switch (req->cmd) { - case I2C_READ: - case DEMOD_READ: - case REG_READ: - requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); - break; - case I2C_WRITE: - case DEMOD_WRITE: - case REG_WRITE: - requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT); - break; - default: - err("unknown command:%02x", req->cmd); - ret = -EPERM; - goto error; - } - - if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) { - /* write */ - memcpy(buf, req->data, req->data_len); - pipe = usb_sndctrlpipe(udev, 0); - } else { - /* read */ - pipe = usb_rcvctrlpipe(udev, 0); - } - - msleep(1); /* avoid I2C errors */ - - ret = usb_control_msg(udev, pipe, request, requesttype, value, index, - buf, sizeof(buf), CE6230_USB_TIMEOUT); - - ce6230_debug_dump(request, requesttype, value, index, buf, - req->data_len, deb_xfer); - - if (ret < 0) - deb_info("%s: usb_control_msg failed:%d\n", __func__, ret); - else - ret = 0; - - /* read request, copy returned data to return buf */ - if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN)) - memcpy(req->data, buf, req->data_len); - -error: - return ret; -} - -static int ce6230_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) -{ - return ce6230_rw_udev(d->udev, req); -} - -/* I2C */ -static int ce6230_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i = 0; - struct req_t req; - int ret = 0; - memset(&req, 0, sizeof(&req)); - - if (num > 2) - return -EINVAL; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - while (i < num) { - if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { - if (msg[i].addr == - ce6230_zl10353_config.demod_address) { - req.cmd = DEMOD_READ; - req.value = msg[i].addr >> 1; - req.index = msg[i].buf[0]; - req.data_len = msg[i+1].len; - req.data = &msg[i+1].buf[0]; - ret = ce6230_ctrl_msg(d, &req); - } else { - err("i2c read not implemented"); - ret = -EPERM; - } - i += 2; - } else { - if (msg[i].addr == - ce6230_zl10353_config.demod_address) { - req.cmd = DEMOD_WRITE; - req.value = msg[i].addr >> 1; - req.index = msg[i].buf[0]; - req.data_len = msg[i].len-1; - req.data = &msg[i].buf[1]; - ret = ce6230_ctrl_msg(d, &req); - } else { - req.cmd = I2C_WRITE; - req.value = 0x2000 + (msg[i].addr >> 1); - req.index = 0x0000; - req.data_len = msg[i].len; - req.data = &msg[i].buf[0]; - ret = ce6230_ctrl_msg(d, &req); - } - i += 1; - } - if (ret) - break; - } - - mutex_unlock(&d->i2c_mutex); - return ret ? ret : i; -} - -static u32 ce6230_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm ce6230_i2c_algo = { - .master_xfer = ce6230_i2c_xfer, - .functionality = ce6230_i2c_func, -}; - -/* Callbacks for DVB USB */ -static struct zl10353_config ce6230_zl10353_config = { - .demod_address = 0x1e, - .adc_clock = 450000, - .if2 = 45700, - .no_tuner = 1, - .parallel_ts = 1, - .clock_ctl_1 = 0x34, - .pll_0 = 0x0e, -}; - -static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter *adap) -{ - deb_info("%s:\n", __func__); - adap->fe = dvb_attach(zl10353_attach, &ce6230_zl10353_config, - &adap->dev->i2c_adap); - if (adap->fe == NULL) - return -ENODEV; - return 0; -} - -static struct mxl5005s_config ce6230_mxl5003s_config = { - .i2c_address = 0xc6, - .if_freq = IF_FREQ_4570000HZ, - .xtal_freq = CRYSTAL_FREQ_16000000HZ, - .agc_mode = MXL_SINGLE_AGC, - .tracking_filter = MXL_TF_DEFAULT, - .rssi_enable = MXL_RSSI_ENABLE, - .cap_select = MXL_CAP_SEL_ENABLE, - .div_out = MXL_DIV_OUT_4, - .clock_out = MXL_CLOCK_OUT_DISABLE, - .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, - .top = MXL5005S_TOP_25P2, - .mod_mode = MXL_DIGITAL_MODE, - .if_mode = MXL_ZERO_IF, - .AgcMasterByte = 0x00, -}; - -static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) -{ - int ret; - deb_info("%s:\n", __func__); - ret = dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap, - &ce6230_mxl5003s_config) == NULL ? -ENODEV : 0; - return ret; -} - -static int ce6230_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - int ret; - deb_info("%s: onoff:%d\n", __func__, onoff); - - /* InterfaceNumber 1 / AlternateSetting 0 idle - InterfaceNumber 1 / AlternateSetting 1 streaming */ - ret = usb_set_interface(d->udev, 1, onoff); - if (ret) - err("usb_set_interface failed with error:%d", ret); - - return ret; -} - -/* DVB USB Driver stuff */ -static struct dvb_usb_device_properties ce6230_properties; - -static int ce6230_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - int ret = 0; - struct dvb_usb_device *d = NULL; - - deb_info("%s: interface:%d\n", __func__, - intf->cur_altsetting->desc.bInterfaceNumber); - - if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { - ret = dvb_usb_device_init(intf, &ce6230_properties, THIS_MODULE, - &d, adapter_nr); - if (ret) - err("init failed with error:%d\n", ret); - } - - return ret; -} - -static struct usb_device_id ce6230_table[] = { - { USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, ce6230_table); - -static struct dvb_usb_device_properties ce6230_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .no_reconnect = 1, - - .size_of_priv = 0, - - .num_adapters = 1, - .adapter = { - { - .frontend_attach = ce6230_zl10353_frontend_attach, - .tuner_attach = ce6230_mxl5003s_tuner_attach, - .stream = { - .type = USB_BULK, - .count = 6, - .endpoint = 0x82, - .u = { - .bulk = { - .buffersize = 512, - } - } - }, - } - }, - - .power_ctrl = ce6230_power_ctrl, - - .i2c_algo = &ce6230_i2c_algo, - - .num_device_descs = 1, - .devices = { - { - .name = "Intel CE9500 reference design", - .cold_ids = {NULL}, - .warm_ids = {&ce6230_table[0], NULL}, - }, - } -}; - -static struct usb_driver ce6230_driver = { - .name = "dvb_usb_ce6230", - .probe = ce6230_probe, - .disconnect = dvb_usb_device_exit, - .id_table = ce6230_table, -}; - -/* module stuff */ -static int __init ce6230_module_init(void) -{ - int ret; - deb_info("%s:\n", __func__); - ret = usb_register(&ce6230_driver); - if (ret) - err("usb_register failed with error:%d", ret); - - return ret; -} - -static void __exit ce6230_module_exit(void) -{ - deb_info("%s:\n", __func__); - /* deregister this driver from the USB subsystem */ - usb_deregister(&ce6230_driver); -} - -module_init(ce6230_module_init); -module_exit(ce6230_module_exit); - -MODULE_AUTHOR("Antti Palosaari "); -MODULE_DESCRIPTION("Driver for Intel CE6230 DVB-T USB2.0"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/dvb-usb/ce6230.h b/trunk/drivers/media/dvb/dvb-usb/ce6230.h deleted file mode 100644 index 97c42482ccb3..000000000000 --- a/trunk/drivers/media/dvb/dvb-usb/ce6230.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver - * - * Copyright (C) 2009 Antti Palosaari - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _DVB_USB_CE6230_H_ -#define _DVB_USB_CE6230_H_ - -#define DVB_USB_LOG_PREFIX "ce6230" -#include "dvb-usb.h" - -#define deb_info(args...) dprintk(dvb_usb_ce6230_debug, 0x01, args) -#define deb_rc(args...) dprintk(dvb_usb_ce6230_debug, 0x02, args) -#define deb_xfer(args...) dprintk(dvb_usb_ce6230_debug, 0x04, args) -#define deb_reg(args...) dprintk(dvb_usb_ce6230_debug, 0x08, args) -#define deb_i2c(args...) dprintk(dvb_usb_ce6230_debug, 0x10, args) -#define deb_fw(args...) dprintk(dvb_usb_ce6230_debug, 0x20, args) - -#define ce6230_debug_dump(r, t, v, i, b, l, func) { \ - int loop_; \ - func("%02x %02x %02x %02x %02x %02x %02x %02x", \ - t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \ - if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \ - func(" >>> "); \ - else \ - func(" <<< "); \ - for (loop_ = 0; loop_ < l; loop_++) \ - func("%02x ", b[loop_]); \ - func("\n");\ -} - -#define CE6230_USB_TIMEOUT 1000 - -struct req_t { - u8 cmd; /* [1] */ - u16 value; /* [2|3] */ - u16 index; /* [4|5] */ - u16 data_len; /* [6|7] */ - u8 *data; -}; - -enum ce6230_cmd { - CONFIG_READ = 0xd0, /* rd 0 (unclear) */ - UNKNOWN_WRITE = 0xc7, /* wr 7 (unclear) */ - I2C_READ = 0xd9, /* rd 9 (unclear) */ - I2C_WRITE = 0xca, /* wr a */ - DEMOD_READ = 0xdb, /* rd b */ - DEMOD_WRITE = 0xcc, /* wr c */ - REG_READ = 0xde, /* rd e */ - REG_WRITE = 0xcf, /* wr f */ -}; - -#endif diff --git a/trunk/drivers/media/dvb/dvb-usb/dib0700_core.c b/trunk/drivers/media/dvb/dvb-usb/dib0700_core.c index db7f7f79a66c..200b215f4d8b 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/trunk/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -158,10 +158,6 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, err("i2c read error (status = %d)\n", result); break; } - - deb_data("<<< "); - debug_dump(msg[i].buf, msg[i].len, deb_data); - } else { /* Write request */ buf[0] = REQUEST_NEW_I2C_WRITE; @@ -173,9 +169,6 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, /* The Actual i2c payload */ memcpy(&buf[4], msg[i].buf, msg[i].len); - deb_data(">>> "); - debug_dump(buf, msg[i].len + 4, deb_data); - result = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0), REQUEST_NEW_I2C_WRITE, @@ -218,8 +211,7 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap, /* special thing in the current firmware: when length is zero the read-failed */ if ((len = dib0700_ctrl_rd(d, buf, msg[i].len + 2, msg[i+1].buf, msg[i+1].len)) <= 0) { - deb_info("I2C read failed on address 0x%02x\n", - msg[i].addr); + deb_info("I2C read failed on address %x\n", msg[i].addr); break; } diff --git a/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c b/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c index 8ddbadf62194..635d30a55078 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -17,8 +17,6 @@ #include "xc5000.h" #include "s5h1411.h" #include "dib0070.h" -#include "lgdt3305.h" -#include "mxl5007t.h" static int force_lna_activation; module_param(force_lna_activation, int, 0644); @@ -264,12 +262,7 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap) msleep(10); dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, - stk7700d_dib7000p_mt2266_config) - != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); - return -ENODEV; - } + dib7000p_i2c_enumeration(&adap->dev->i2c_adap,1,18,stk7700d_dib7000p_mt2266_config); } adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1), @@ -291,12 +284,7 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, - stk7700d_dib7000p_mt2266_config) - != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); - return -ENODEV; - } + dib7000p_i2c_enumeration(&adap->dev->i2c_adap,2,18,stk7700d_dib7000p_mt2266_config); } adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1), @@ -433,12 +421,8 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); msleep(10); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, - &stk7700ph_dib7700_xc3028_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", - __func__); - return -ENODEV; - } + dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + &stk7700ph_dib7700_xc3028_config); adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7700ph_dib7700_xc3028_config); @@ -1203,12 +1187,8 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, - &dib7070p_dib7000p_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", - __func__); - return -ENODEV; - } + dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + &dib7070p_dib7000p_config); adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &dib7070p_dib7000p_config); @@ -1264,12 +1244,7 @@ static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap) msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, - stk7070pd_dib7000p_config) != 0) { - err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", - __func__); - return -ENODEV; - } + dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config); adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]); return adap->fe == NULL ? -ENODEV : 0; @@ -1372,72 +1347,6 @@ static int xc5000_tuner_attach(struct dvb_usb_adapter *adap) == NULL ? -ENODEV : 0; } -static struct lgdt3305_config hcw_lgdt3305_config = { - .i2c_addr = 0x0e, - .mpeg_mode = LGDT3305_MPEG_PARALLEL, - .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE, - .tpvalid_polarity = LGDT3305_TP_VALID_LOW, - .deny_i2c_rptr = 0, - .spectral_inversion = 1, - .qam_if_khz = 6000, - .vsb_if_khz = 6000, - .usref_8vsb = 0x0500, -}; - -static struct mxl5007t_config hcw_mxl5007t_config = { - .xtal_freq_hz = MxL_XTAL_25_MHZ, - .if_freq_hz = MxL_IF_6_MHZ, - .invert_if = 1, -}; - -/* TIGER-ATSC map: - GPIO0 - LNA_CTR (H: LNA power enabled, L: LNA power disabled) - GPIO1 - ANT_SEL (H: VPA, L: MCX) - GPIO4 - SCL2 - GPIO6 - EN_TUNER - GPIO7 - SDA2 - GPIO10 - DEM_RST - - MXL is behind LG's i2c repeater. LG is on SCL2/SDA2 gpios on the DIB - */ -static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap) -{ - struct dib0700_state *st = adap->dev->priv; - - /* Make use of the new i2c functions from FW 1.20 */ - st->fw_use_new_i2c_api = 1; - - st->disable_streaming_master_mode = 1; - - /* fe power enable */ - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); - msleep(30); - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); - msleep(30); - - /* demod reset */ - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); - msleep(30); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); - msleep(30); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); - msleep(30); - - adap->fe = dvb_attach(lgdt3305_attach, - &hcw_lgdt3305_config, - &adap->dev->i2c_adap); - - return adap->fe == NULL ? -ENODEV : 0; -} - -static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap) -{ - return dvb_attach(mxl5007t_attach, adap->fe, - &adap->dev->i2c_adap, 0x60, - &hcw_mxl5007t_config) == NULL ? -ENODEV : 0; -} - - /* DVB-USB and USB stuff follows */ struct usb_device_id dib0700_usb_id_table[] = { /* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) }, @@ -1487,12 +1396,6 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_EXPRESS) }, { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) }, - { USB_DEVICE(USB_VID_SONY, USB_PID_SONY_PLAYTV) }, -/* 45 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_PD378S) }, - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) }, - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) }, - { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) }, - { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1692,7 +1595,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 11, + .num_device_descs = 9, .devices = { { "DiBcom STK7070P reference design", { &dib0700_usb_id_table[15], NULL }, @@ -1730,14 +1633,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[33], NULL }, { NULL }, }, - { "Elgato EyeTV DTT", - { &dib0700_usb_id_table[49], NULL }, - { NULL }, - }, - { "Yuan PD378S", - { &dib0700_usb_id_table[45], NULL }, - { NULL }, - }, }, .rc_interval = DEFAULT_RC_INTERVAL, @@ -1766,7 +1661,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { } }, - .num_device_descs = 6, + .num_device_descs = 5, .devices = { { "DiBcom STK7070PD reference design", { &dib0700_usb_id_table[17], NULL }, @@ -1787,16 +1682,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { { "Terratec Cinergy DT USB XS Diversity", { &dib0700_usb_id_table[43], NULL }, { NULL }, - }, - { "Sony PlayTV", - { &dib0700_usb_id_table[44], NULL }, - { NULL }, } - }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dib0700_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), - .rc_query = dib0700_rc_query + } }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, .num_adapters = 1, @@ -1812,7 +1699,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 7, + .num_device_descs = 5, .devices = { { "Terratec Cinergy HT USB XE", { &dib0700_usb_id_table[27], NULL }, @@ -1838,10 +1725,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[39], NULL }, { NULL }, }, - { "YUAN High-Tech MC770", - { &dib0700_usb_id_table[48], NULL }, - { NULL }, - }, }, .rc_interval = DEFAULT_RC_INTERVAL, .rc_key_map = dib0700_rc_keys, @@ -1876,31 +1759,6 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_key_map = dib0700_rc_keys, .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), .rc_query = dib0700_rc_query - }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, - .num_adapters = 1, - .adapter = { - { - .frontend_attach = lgdt3305_frontend_attach, - .tuner_attach = mxl5007t_tuner_attach, - - DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - - .size_of_priv = sizeof(struct - dib0700_adapter_state), - }, - }, - - .num_device_descs = 2, - .devices = { - { "Hauppauge ATSC MiniCard (B200)", - { &dib0700_usb_id_table[46], NULL }, - { NULL }, - }, - { "Hauppauge ATSC MiniCard (B210)", - { &dib0700_usb_id_table[47], NULL }, - { NULL }, - }, - }, }, }; diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index dc7ea21cd139..0db0c06ee6f2 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -27,14 +27,12 @@ #define USB_VID_DIBCOM 0x10b8 #define USB_VID_DPOSH 0x1498 #define USB_VID_DVICO 0x0fe9 -#define USB_VID_ELGATO 0x0fd9 #define USB_VID_EMPIA 0xeb1a #define USB_VID_GENPIX 0x09c0 #define USB_VID_GRANDTEC 0x5032 #define USB_VID_HANFTEK 0x15f4 #define USB_VID_HAUPPAUGE 0x2040 #define USB_VID_HYPER_PALTEK 0x1025 -#define USB_VID_INTEL 0x8086 #define USB_VID_KWORLD 0xeb2a #define USB_VID_KWORLD_2 0x1b80 #define USB_VID_KYE 0x0458 @@ -50,7 +48,6 @@ #define USB_VID_TERRATEC 0x0ccd #define USB_VID_TELESTAR 0x10b9 #define USB_VID_VISIONPLUS 0x13d3 -#define USB_VID_SONY 0x1415 #define USB_VID_TWINHAN 0x1822 #define USB_VID_ULTIMA_ELECTRONIC 0x05d8 #define USB_VID_UNIWILL 0x1584 @@ -98,10 +95,8 @@ #define USB_PID_UNIWILL_STK7700P 0x6003 #define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 -#define USB_PID_INTEL_CE9500 0x9500 #define USB_PID_KWORLD_399U 0xe399 #define USB_PID_KWORLD_395U 0xe396 -#define USB_PID_KWORLD_395U_2 0xe39b #define USB_PID_KWORLD_PC160_2T 0xc160 #define USB_PID_KWORLD_VSTREAM_COLD 0x17de #define USB_PID_KWORLD_VSTREAM_WARM 0x17df @@ -154,8 +149,6 @@ #define USB_PID_HAUPPAUGE_MYTV_T 0x7080 #define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580 #define USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009 0x5200 -#define USB_PID_HAUPPAUGE_TIGER_ATSC 0xb200 -#define USB_PID_HAUPPAUGE_TIGER_ATSC_B210 0xb210 #define USB_PID_AVERMEDIA_EXPRESS 0xb568 #define USB_PID_AVERMEDIA_VOLAR 0xa807 #define USB_PID_AVERMEDIA_VOLAR_2 0xb808 @@ -239,13 +232,9 @@ #define USB_PID_ASUS_U3100 0x173f #define USB_PID_YUAN_EC372S 0x1edc #define USB_PID_YUAN_STK7700PH 0x1f08 -#define USB_PID_YUAN_PD378S 0x2edc -#define USB_PID_YUAN_MC770 0x0871 #define USB_PID_DW2102 0x2102 #define USB_PID_XTENSIONS_XD_380 0x0381 #define USB_PID_TELESTAR_STARSTICK_2 0x8000 #define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 -#define USB_PID_SONY_PLAYTV 0x0003 -#define USB_PID_ELGATO_EYETV_DTT 0x0021 #endif diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h b/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h index 2d5352e54dc0..b1de0f7e26e8 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -223,7 +223,7 @@ struct dvb_usb_device_properties { int generic_bulk_ctrl_endpoint; int num_device_descs; - struct dvb_usb_device_description devices[11]; + struct dvb_usb_device_description devices[9]; }; /** diff --git a/trunk/drivers/media/dvb/firewire/firedtv-avc.c b/trunk/drivers/media/dvb/firewire/firedtv-avc.c index 12f7730184ad..32526f103b59 100644 --- a/trunk/drivers/media/dvb/firewire/firedtv-avc.c +++ b/trunk/drivers/media/dvb/firewire/firedtv-avc.c @@ -151,7 +151,7 @@ static void debug_fcp(const u8 *data, int length) subunit_type = data[1] >> 3; subunit_id = data[1] & 7; op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2]; - printk(KERN_INFO "%ssu=%x.%x l=%zu: %-8s - %s\n", + printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n", prefix, subunit_type, subunit_id, length, debug_fcp_ctype(data[0]), debug_fcp_opcode(op, data, length)); diff --git a/trunk/drivers/media/dvb/frontends/Kconfig b/trunk/drivers/media/dvb/frontends/Kconfig index a206cee23f73..00269560793a 100644 --- a/trunk/drivers/media/dvb/frontends/Kconfig +++ b/trunk/drivers/media/dvb/frontends/Kconfig @@ -1,21 +1,17 @@ +menu "Customise DVB Frontends" + depends on DVB_CORE + config DVB_FE_CUSTOMISE bool "Customise the frontend modules to build" - depends on DVB_CORE default N help - This allows the user to select/deselect frontend drivers for their - hardware from the build. - - Use this option with care as deselecting frontends which are in fact - necessary will result in DVB devices which cannot be tuned due to lack - of driver support. + This allows the user to deselect frontend drivers unnecessary + for their hardware from the build. Use this option with care + as deselecting frontends which are in fact necessary will result + in DVB devices which cannot be tuned due to lack of driver support. If unsure say N. -if DVB_FE_CUSTOMISE - -menu "Customise DVB Frontends" - comment "Multistandard (satellite) frontends" depends on DVB_CORE @@ -59,13 +55,6 @@ config DVB_MT312 help A DVB-S tuner module. Say Y when you want to support this frontend. -config DVB_ZL10036 - tristate "Zarlink ZL10036 silicon tuner" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - config DVB_S5H1420 tristate "Samsung S5H1420 based" depends on DVB_CORE && I2C @@ -94,20 +83,6 @@ config DVB_STV0299 help A DVB-S tuner module. Say Y when you want to support this frontend. -config DVB_STV6110 - tristate "ST STV6110 silicon tuner" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S silicon tuner module. Say Y when you want to support this tuner. - -config DVB_STV0900 - tristate "ST STV0900 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S/S2 demodulator. Say Y when you want to support this frontend. - config DVB_TDA8083 tristate "Philips TDA8083 based" depends on DVB_CORE && I2C @@ -313,13 +288,6 @@ config DVB_TDA10048 help A DVB-T tuner module. Say Y when you want to support this frontend. -config DVB_AF9013 - tristate "Afatech AF9013 demodulator" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - Say Y when you want to support this frontend. - comment "DVB-C (cable) frontends" depends on DVB_CORE @@ -419,14 +387,6 @@ config DVB_LGDT3304 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. -config DVB_LGDT3305 - tristate "LG Electronics LGDT3305 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want - to support this frontend. - config DVB_S5H1409 tristate "Samsung S5H1409 based" depends on DVB_CORE && I2C @@ -437,7 +397,7 @@ config DVB_S5H1409 config DVB_AU8522 tristate "Auvitek AU8522 based" - depends on DVB_CORE && I2C && VIDEO_V4L2 + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want @@ -486,11 +446,11 @@ comment "SEC control devices for DVB-S" depends on DVB_CORE config DVB_LNBP21 - tristate "LNBP21/LNBH24 SEC controllers" + tristate "LNBP21 SEC controller" depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help - An SEC control chips. + An SEC control chip. config DVB_ISL6405 tristate "ISL6405 SEC controller" @@ -518,6 +478,11 @@ comment "Tools to develop new frontends" config DVB_DUMMY_FE tristate "Dummy frontend driver" default n -endmenu -endif +config DVB_AF9013 + tristate "Afatech AF9013 demodulator" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + Say Y when you want to support this frontend. +endmenu diff --git a/trunk/drivers/media/dvb/frontends/Makefile b/trunk/drivers/media/dvb/frontends/Makefile index 65a336aa1db6..af7bdf0ad4c7 100644 --- a/trunk/drivers/media/dvb/frontends/Makefile +++ b/trunk/drivers/media/dvb/frontends/Makefile @@ -7,8 +7,6 @@ EXTRA_CFLAGS += -Idrivers/media/common/tuners/ s921-objs := s921_module.o s921_core.o stb0899-objs = stb0899_drv.o stb0899_algo.o -stv0900-objs = stv0900_core.o stv0900_sw.o -au8522-objs = au8522_dig.o au8522_decoder.o obj-$(CONFIG_DVB_PLL) += dvb-pll.o obj-$(CONFIG_DVB_STV0299) += stv0299.o @@ -30,7 +28,6 @@ obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o obj-$(CONFIG_DVB_SP887X) += sp887x.o obj-$(CONFIG_DVB_NXT6000) += nxt6000.o obj-$(CONFIG_DVB_MT352) += mt352.o -obj-$(CONFIG_DVB_ZL10036) += zl10036.o obj-$(CONFIG_DVB_ZL10353) += zl10353.o obj-$(CONFIG_DVB_CX22702) += cx22702.o obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o @@ -44,7 +41,6 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o obj-$(CONFIG_DVB_S5H1420) += s5h1420.o obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o obj-$(CONFIG_DVB_LGDT3304) += lgdt3304.o -obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o obj-$(CONFIG_DVB_CX24123) += cx24123.o obj-$(CONFIG_DVB_LNBP21) += lnbp21.o obj-$(CONFIG_DVB_ISL6405) += isl6405.o @@ -68,6 +64,4 @@ obj-$(CONFIG_DVB_SI21XX) += si21xx.o obj-$(CONFIG_DVB_STV0288) += stv0288.o obj-$(CONFIG_DVB_STB6000) += stb6000.o obj-$(CONFIG_DVB_S921) += s921.o -obj-$(CONFIG_DVB_STV6110) += stv6110.o -obj-$(CONFIG_DVB_STV0900) += stv0900.o diff --git a/trunk/drivers/media/dvb/frontends/au8522_dig.c b/trunk/drivers/media/dvb/frontends/au8522.c similarity index 91% rename from trunk/drivers/media/dvb/frontends/au8522_dig.c rename to trunk/drivers/media/dvb/frontends/au8522.c index 35731258bb0a..eabf9a68e7ec 100644 --- a/trunk/drivers/media/dvb/frontends/au8522_dig.c +++ b/trunk/drivers/media/dvb/frontends/au8522.c @@ -27,25 +27,35 @@ #include #include "dvb_frontend.h" #include "au8522.h" -#include "au8522_priv.h" -static int debug; +struct au8522_state { + + struct i2c_adapter *i2c; + + /* configuration settings */ + const struct au8522_config *config; + + struct dvb_frontend frontend; -/* Despite the name "hybrid_tuner", the framework works just as well for - hybrid demodulators as well... */ -static LIST_HEAD(hybrid_tuner_instance_list); -static DEFINE_MUTEX(au8522_list_mutex); + u32 current_frequency; + fe_modulation_t current_modulation; + + u32 fe_status; + unsigned int led_state; +}; + +static int debug; -#define dprintk(arg...)\ - do { if (debug)\ - printk(arg);\ +#define dprintk(arg...) do { \ + if (debug) \ + printk(arg); \ } while (0) /* 16 bit registers, 8 bit values */ -int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) +static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) { int ret; - u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data }; + u8 buf [] = { reg >> 8, reg & 0xff, data }; struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 }; @@ -59,13 +69,13 @@ int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) return (ret != 1) ? -1 : 0; } -u8 au8522_readreg(struct au8522_state *state, u16 reg) +static u8 au8522_readreg(struct au8522_state *state, u16 reg) { int ret; - u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff }; - u8 b1[] = { 0 }; + u8 b0 [] = { reg >> 8, reg & 0xff }; + u8 b1 [] = { 0 }; - struct i2c_msg msg[] = { + struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 }, { .addr = state->config->demod_address, .flags = I2C_M_RD, @@ -518,7 +528,7 @@ static int au8522_set_frontend(struct dvb_frontend *fe, /* Reset the demod hardware and reset all of the configuration registers to a default state. */ -int au8522_init(struct dvb_frontend *fe) +static int au8522_init(struct dvb_frontend *fe) { struct au8522_state *state = fe->demodulator_priv; dprintk("%s()\n", __func__); @@ -614,7 +624,7 @@ static int au8522_led_ctrl(struct au8522_state *state, int led) return 0; } -int au8522_sleep(struct dvb_frontend *fe) +static int au8522_sleep(struct dvb_frontend *fe) { struct au8522_state *state = fe->demodulator_priv; dprintk("%s()\n", __func__); @@ -622,9 +632,6 @@ int au8522_sleep(struct dvb_frontend *fe) /* turn off led */ au8522_led_ctrl(state, 0); - /* Power down the chip */ - au8522_writereg(state, 0xa4, 1 << 5); - state->current_frequency = 0; return 0; @@ -791,58 +798,23 @@ static int au8522_get_tune_settings(struct dvb_frontend *fe, return 0; } -static struct dvb_frontend_ops au8522_ops; - -int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, - u8 client_address) -{ - int ret; - - mutex_lock(&au8522_list_mutex); - ret = hybrid_tuner_request_state(struct au8522_state, (*state), - hybrid_tuner_instance_list, - i2c, client_address, "au8522"); - mutex_unlock(&au8522_list_mutex); - - return ret; -} - -void au8522_release_state(struct au8522_state *state) -{ - mutex_lock(&au8522_list_mutex); - if (state != NULL) - hybrid_tuner_release_state(state); - mutex_unlock(&au8522_list_mutex); -} - - static void au8522_release(struct dvb_frontend *fe) { struct au8522_state *state = fe->demodulator_priv; - au8522_release_state(state); + kfree(state); } +static struct dvb_frontend_ops au8522_ops; + struct dvb_frontend *au8522_attach(const struct au8522_config *config, struct i2c_adapter *i2c) { struct au8522_state *state = NULL; - int instance; /* allocate memory for the internal state */ - instance = au8522_get_state(&state, i2c, config->demod_address); - switch (instance) { - case 0: - dprintk("%s state allocation failed\n", __func__); - break; - case 1: - /* new demod instance */ - dprintk("%s using new instance\n", __func__); - break; - default: - /* existing demod instance */ - dprintk("%s using existing instance\n", __func__); - break; - } + state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL); + if (state == NULL) + goto error; /* setup the state */ state->config = config; @@ -864,7 +836,7 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config, return &state->frontend; error: - au8522_release_state(state); + kfree(state); return NULL; } EXPORT_SYMBOL(au8522_attach); diff --git a/trunk/drivers/media/dvb/frontends/au8522.h b/trunk/drivers/media/dvb/frontends/au8522.h index 565dcf31af57..7b94f554a093 100644 --- a/trunk/drivers/media/dvb/frontends/au8522.h +++ b/trunk/drivers/media/dvb/frontends/au8522.h @@ -74,22 +74,6 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config, } #endif /* CONFIG_DVB_AU8522 */ -/* Other modes may need to be added later */ -enum au8522_video_input { - AU8522_COMPOSITE_CH1 = 1, - AU8522_COMPOSITE_CH2, - AU8522_COMPOSITE_CH3, - AU8522_COMPOSITE_CH4, - AU8522_COMPOSITE_CH4_SIF, - AU8522_SVIDEO_CH13, - AU8522_SVIDEO_CH24, -}; - -enum au8522_audio_input { - AU8522_AUDIO_NONE, - AU8522_AUDIO_SIF, -}; - #endif /* __AU8522_H__ */ /* diff --git a/trunk/drivers/media/dvb/frontends/au8522_decoder.c b/trunk/drivers/media/dvb/frontends/au8522_decoder.c deleted file mode 100644 index d63e1527dc88..000000000000 --- a/trunk/drivers/media/dvb/frontends/au8522_decoder.c +++ /dev/null @@ -1,835 +0,0 @@ -/* - * Auvitek AU8522 QAM/8VSB demodulator driver and video decoder - * - * Copyright (C) 2009 Devin Heitmueller - * Copyright (C) 2005-2008 Auvitek International, Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * As published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/* Developer notes: - * - * VBI support is not yet working - * Saturation and hue setting are not yet working - * Enough is implemented here for CVBS and S-Video inputs, but the actual - * analog demodulator code isn't implemented (not needed for xc5000 since it - * has its own demodulator and outputs CVBS) - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "au8522.h" -#include "au8522_priv.h" - -MODULE_AUTHOR("Devin Heitmueller"); -MODULE_LICENSE("GPL"); - -static int au8522_analog_debug; - - -module_param_named(analog_debug, au8522_analog_debug, int, 0644); - -MODULE_PARM_DESC(analog_debug, - "Analog debugging messages [0=Off (default) 1=On]"); - -struct au8522_register_config { - u16 reg_name; - u8 reg_val[8]; -}; - - -/* Video Decoder Filter Coefficients - The values are as follows from left to right - 0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13" -*/ -struct au8522_register_config filter_coef[] = { - {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} }, - {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} }, - {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} }, - {AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00} }, - {AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00} }, - {AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00} }, - {AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00} }, - {AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00} }, - {AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00} }, - {AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40} }, - {AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09} }, - {AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38} }, - {AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff} }, - {AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7} }, - {AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf} }, - {AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06} }, - {AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30} }, - {AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01} }, - {AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd} }, - {AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf} }, - {AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7} }, - {AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb} }, - {AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0} }, - {AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f} }, - {AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8} }, - {AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb} }, - {AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5} }, - {AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e} }, - {AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15} }, - {AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34} }, - -}; -#define NUM_FILTER_COEF (sizeof(filter_coef)\ - / sizeof(struct au8522_register_config)) - - -/* Registers 0x060b through 0x0652 are the LP Filter coefficients - The values are as follows from left to right - 0="SIF" 1="ATVRF/ATVRF13" - Note: the "ATVRF/ATVRF13" mode has never been tested -*/ -struct au8522_register_config lpfilter_coef[] = { - {0x060b, {0x21, 0x0b} }, - {0x060c, {0xad, 0xad} }, - {0x060d, {0x70, 0xf0} }, - {0x060e, {0xea, 0xe9} }, - {0x060f, {0xdd, 0xdd} }, - {0x0610, {0x08, 0x64} }, - {0x0611, {0x60, 0x60} }, - {0x0612, {0xf8, 0xb2} }, - {0x0613, {0x01, 0x02} }, - {0x0614, {0xe4, 0xb4} }, - {0x0615, {0x19, 0x02} }, - {0x0616, {0xae, 0x2e} }, - {0x0617, {0xee, 0xc5} }, - {0x0618, {0x56, 0x56} }, - {0x0619, {0x30, 0x58} }, - {0x061a, {0xf9, 0xf8} }, - {0x061b, {0x24, 0x64} }, - {0x061c, {0x07, 0x07} }, - {0x061d, {0x30, 0x30} }, - {0x061e, {0xa9, 0xed} }, - {0x061f, {0x09, 0x0b} }, - {0x0620, {0x42, 0xc2} }, - {0x0621, {0x1d, 0x2a} }, - {0x0622, {0xd6, 0x56} }, - {0x0623, {0x95, 0x8b} }, - {0x0624, {0x2b, 0x2b} }, - {0x0625, {0x30, 0x24} }, - {0x0626, {0x3e, 0x3e} }, - {0x0627, {0x62, 0xe2} }, - {0x0628, {0xe9, 0xf5} }, - {0x0629, {0x99, 0x19} }, - {0x062a, {0xd4, 0x11} }, - {0x062b, {0x03, 0x04} }, - {0x062c, {0xb5, 0x85} }, - {0x062d, {0x1e, 0x20} }, - {0x062e, {0x2a, 0xea} }, - {0x062f, {0xd7, 0xd2} }, - {0x0630, {0x15, 0x15} }, - {0x0631, {0xa3, 0xa9} }, - {0x0632, {0x1f, 0x1f} }, - {0x0633, {0xf9, 0xd1} }, - {0x0634, {0xc0, 0xc3} }, - {0x0635, {0x4d, 0x8d} }, - {0x0636, {0x21, 0x31} }, - {0x0637, {0x83, 0x83} }, - {0x0638, {0x08, 0x8c} }, - {0x0639, {0x19, 0x19} }, - {0x063a, {0x45, 0xa5} }, - {0x063b, {0xef, 0xec} }, - {0x063c, {0x8a, 0x8a} }, - {0x063d, {0xf4, 0xf6} }, - {0x063e, {0x8f, 0x8f} }, - {0x063f, {0x44, 0x0c} }, - {0x0640, {0xef, 0xf0} }, - {0x0641, {0x66, 0x66} }, - {0x0642, {0xcc, 0xd2} }, - {0x0643, {0x41, 0x41} }, - {0x0644, {0x63, 0x93} }, - {0x0645, {0x8e, 0x8e} }, - {0x0646, {0xa2, 0x42} }, - {0x0647, {0x7b, 0x7b} }, - {0x0648, {0x04, 0x04} }, - {0x0649, {0x00, 0x00} }, - {0x064a, {0x40, 0x40} }, - {0x064b, {0x8c, 0x98} }, - {0x064c, {0x00, 0x00} }, - {0x064d, {0x63, 0xc3} }, - {0x064e, {0x04, 0x04} }, - {0x064f, {0x20, 0x20} }, - {0x0650, {0x00, 0x00} }, - {0x0651, {0x40, 0x40} }, - {0x0652, {0x01, 0x01} }, -}; -#define NUM_LPFILTER_COEF (sizeof(lpfilter_coef)\ - / sizeof(struct au8522_register_config)) - -static inline struct au8522_state *to_state(struct v4l2_subdev *sd) -{ - return container_of(sd, struct au8522_state, sd); -} - -static void setup_vbi(struct au8522_state *state, int aud_input) -{ - int i; - - /* These are set to zero regardless of what mode we're in */ - au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, 0x00); - au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_L_REG018H, 0x00); - au8522_writereg(state, AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H, 0x00); - au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH, 0x00); - au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH, 0x00); - au8522_writereg(state, AU8522_TVDEC_VBI_USER_THRESH1_REG01CH, 0x00); - au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00); - au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00); - au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00); - au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H, - 0x00); - au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H, - 0x00); - au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H, - 0x00); - - /* Setup the VBI registers */ - for (i = 0x30; i < 0x60; i++) - au8522_writereg(state, i, 0x40); - - /* For some reason, every register is 0x40 except register 0x44 - (confirmed via the HVR-950q USB capture) */ - au8522_writereg(state, 0x44, 0x60); - - /* Enable VBI (we always do this regardless of whether the user is - viewing closed caption info) */ - au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, - AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON); - -} - -static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode) -{ - int i; - int filter_coef_type; - - /* Provide reasonable defaults for picture tuning values */ - au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07); - au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed); - state->brightness = 0xed - 128; - au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79); - state->contrast = 0x79; - au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80); - au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80); - au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00); - au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00); - - /* Other decoder registers */ - au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00); - - if (input_mode == 0x23) { - /* S-Video input mapping */ - au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04); - } else { - /* All other modes (CVBS/ATVRF etc.) */ - au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00); - } - - au8522_writereg(state, AU8522_TVDEC_PGA_REG012H, - AU8522_TVDEC_PGA_REG012H_CVBS); - au8522_writereg(state, AU8522_TVDEC_COMB_MODE_REG015H, - AU8522_TVDEC_COMB_MODE_REG015H_CVBS); - au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H, - AU8522_TVDED_DBG_MODE_REG060H_CVBS); - au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H, - AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13); - au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H, - AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13); - au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H, - AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS); - au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H, - AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS); - au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR1_REG065H, - AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS); - au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR2_REG066H, - AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS); - au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR3_REG067H, - AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS); - au8522_writereg(state, AU8522_TVDEC_COMB_NOTCH_THR_REG068H, - AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS); - au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR1_REG069H, - AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS); - au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR2_REG06AH, - AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS); - au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH, - AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS); - au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH, - AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS); - au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH, - AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS); - au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH, - AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS); - au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH, - AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS); - au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H, - AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS); - au8522_writereg(state, AU8522_REG071H, AU8522_REG071H_CVBS); - au8522_writereg(state, AU8522_REG072H, AU8522_REG072H_CVBS); - au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H, - AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS); - au8522_writereg(state, AU8522_REG074H, AU8522_REG074H_CVBS); - au8522_writereg(state, AU8522_REG075H, AU8522_REG075H_CVBS); - au8522_writereg(state, AU8522_TVDEC_DCAGC_CTRL_REG077H, - AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS); - au8522_writereg(state, AU8522_TVDEC_PIC_START_ADJ_REG078H, - AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS); - au8522_writereg(state, AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H, - AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS); - au8522_writereg(state, AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH, - AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS); - au8522_writereg(state, AU8522_TVDEC_INTRP_CTRL_REG07BH, - AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS); - au8522_writereg(state, AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H, - AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS); - au8522_writereg(state, AU8522_TOREGAAGC_REG0E5H, - AU8522_TOREGAAGC_REG0E5H_CVBS); - au8522_writereg(state, AU8522_REG016H, AU8522_REG016H_CVBS); - - setup_vbi(state, 0); - - if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 || - input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) { - /* Despite what the table says, for the HVR-950q we still need - to be in CVBS mode for the S-Video input (reason uknown). */ - /* filter_coef_type = 3; */ - filter_coef_type = 5; - } else { - filter_coef_type = 5; - } - - /* Load the Video Decoder Filter Coefficients */ - for (i = 0; i < NUM_FILTER_COEF; i++) { - au8522_writereg(state, filter_coef[i].reg_name, - filter_coef[i].reg_val[filter_coef_type]); - } - - /* It's not clear what these registers are for, but they are always - set to the same value regardless of what mode we're in */ - au8522_writereg(state, AU8522_REG42EH, 0x87); - au8522_writereg(state, AU8522_REG42FH, 0xa2); - au8522_writereg(state, AU8522_REG430H, 0xbf); - au8522_writereg(state, AU8522_REG431H, 0xcb); - au8522_writereg(state, AU8522_REG432H, 0xa1); - au8522_writereg(state, AU8522_REG433H, 0x41); - au8522_writereg(state, AU8522_REG434H, 0x88); - au8522_writereg(state, AU8522_REG435H, 0xc2); - au8522_writereg(state, AU8522_REG436H, 0x3c); -} - -static void au8522_setup_cvbs_mode(struct au8522_state *state) -{ - /* here we're going to try the pre-programmed route */ - au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H, - AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS); - - au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00); - au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e); - au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10); - - au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, - AU8522_INPUT_CONTROL_REG081H_CVBS_CH1); - - setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1); - - au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, - AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); -} - -static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state) -{ - /* here we're going to try the pre-programmed route */ - au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H, - AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS); - - /* It's not clear why they turn off the PGA before enabling the clamp - control, but the Windows trace does it so we will too... */ - au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00); - - /* Enable clamping control */ - au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e); - - /* Turn on the PGA */ - au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10); - - /* Set input mode to CVBS on channel 4 with SIF audio input enabled */ - au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, - AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF); - - setup_decoder_defaults(state, - AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF); - - au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, - AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); -} - -static void au8522_setup_svideo_mode(struct au8522_state *state) -{ - au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H, - AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO); - - /* Set input to Y on Channe1, C on Channel 3 */ - au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, - AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13); - - /* Disable clamping control (required for S-video) */ - au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00); - - setup_decoder_defaults(state, - AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13); - - au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, - AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); -} - -/* ----------------------------------------------------------------------- */ - -static void disable_audio_input(struct au8522_state *state) -{ - /* This can probably be optimized */ - au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00); - au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00); - au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00); - au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80); - au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84); - - au8522_writereg(state, AU8522_ENA_USB_REG101H, 0x00); - au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F); - au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F); - au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO); - au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x40); - - au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x11); - msleep(5); - au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x00); - - au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04); - au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03); - au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02); - - au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, - AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); -} - -/* 0=disable, 1=SIF */ -static void set_audio_input(struct au8522_state *state, int aud_input) -{ - int i; - - /* Note that this function needs to be used in conjunction with setting - the input routing via register 0x81 */ - - if (aud_input == AU8522_AUDIO_NONE) { - disable_audio_input(state); - return; - } - - if (aud_input != AU8522_AUDIO_SIF) { - /* The caller asked for a mode we don't currently support */ - printk(KERN_ERR "Unsupported audio mode requested! mode=%d\n", - aud_input); - return; - } - - /* Load the Audio Decoder Filter Coefficients */ - for (i = 0; i < NUM_LPFILTER_COEF; i++) { - au8522_writereg(state, lpfilter_coef[i].reg_name, - lpfilter_coef[i].reg_val[0]); - } - - /* Setup audio */ - au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00); - au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00); - au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00); - au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80); - au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84); - msleep(150); - au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00); - msleep(1); - au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d); - msleep(50); - au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F); - au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F); - au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0xff); - msleep(80); - au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F); - au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F); - au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO); - au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x82); - msleep(70); - au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09); - au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03); - au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0xc2); -} - -/* ----------------------------------------------------------------------- */ - -static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct au8522_state *state = to_state(sd); - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - state->brightness = ctrl->value; - au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, - ctrl->value - 128); - break; - case V4L2_CID_CONTRAST: - state->contrast = ctrl->value; - au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, - ctrl->value); - break; - case V4L2_CID_SATURATION: - case V4L2_CID_HUE: - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_MUTE: - /* Not yet implemented */ - default: - return -EINVAL; - } - - return 0; -} - -static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct au8522_state *state = to_state(sd); - - /* Note that we are using values cached in the state structure instead - of reading the registers due to issues with i2c reads not working - properly/consistently yet on the HVR-950q */ - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = state->brightness; - break; - case V4L2_CID_CONTRAST: - ctrl->value = state->contrast; - break; - case V4L2_CID_SATURATION: - case V4L2_CID_HUE: - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_MUTE: - /* Not yet supported */ - default: - return -EINVAL; - } - - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static int au8522_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - switch (fmt->type) { - default: - return -EINVAL; - } - return 0; -} - -static int au8522_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - /* Not yet implemented */ - break; - default: - return -EINVAL; - } - - return 0; -} - -/* ----------------------------------------------------------------------- */ - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int au8522_g_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct au8522_state *state = to_state(sd); - - if (!v4l2_chip_match_i2c_client(client, ®->match)) - return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - reg->val = au8522_readreg(state, reg->reg & 0xffff); - return 0; -} - -static int au8522_s_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct au8522_state *state = to_state(sd); - - if (!v4l2_chip_match_i2c_client(client, ®->match)) - return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - au8522_writereg(state, reg->reg, reg->val & 0xff); - return 0; -} -#endif - -static int au8522_s_stream(struct v4l2_subdev *sd, int enable) -{ - struct au8522_state *state = to_state(sd); - - if (enable) { - au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, - 0x01); - msleep(1); - au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, - AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); - } else { - /* This does not completely power down the device - (it only reduces it from around 140ma to 80ma) */ - au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, - 1 << 5); - } - return 0; -} - -static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) -{ - switch (qc->id) { - case V4L2_CID_CONTRAST: - return v4l2_ctrl_query_fill(qc, 0, 255, 1, - AU8522_TVDEC_CONTRAST_REG00BH_CVBS); - case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); - case V4L2_CID_SATURATION: - case V4L2_CID_HUE: - /* Not yet implemented */ - default: - break; - } - - qc->type = 0; - return -EINVAL; -} - -static int au8522_reset(struct v4l2_subdev *sd, u32 val) -{ - struct au8522_state *state = to_state(sd); - - au8522_writereg(state, 0xa4, 1 << 5); - - return 0; -} - -static int au8522_s_video_routing(struct v4l2_subdev *sd, - const struct v4l2_routing *route) -{ - struct au8522_state *state = to_state(sd); - - au8522_reset(sd, 0); - - /* Jam open the i2c gate to the tuner. We do this here to handle the - case where the user went into digital mode (causing the gate to be - closed), and then came back to analog mode */ - au8522_writereg(state, 0x106, 1); - - if (route->input == AU8522_COMPOSITE_CH1) { - au8522_setup_cvbs_mode(state); - } else if (route->input == AU8522_SVIDEO_CH13) { - au8522_setup_svideo_mode(state); - } else if (route->input == AU8522_COMPOSITE_CH4_SIF) { - au8522_setup_cvbs_tuner_mode(state); - } else { - printk(KERN_ERR "au8522 mode not currently supported\n"); - return -EINVAL; - } - return 0; -} - -static int au8522_s_audio_routing(struct v4l2_subdev *sd, - const struct v4l2_routing *route) -{ - struct au8522_state *state = to_state(sd); - set_audio_input(state, route->input); - return 0; -} - -static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) -{ - int val = 0; - struct au8522_state *state = to_state(sd); - u8 lock_status; - - /* Interrogate the decoder to see if we are getting a real signal */ - lock_status = au8522_readreg(state, 0x00); - if (lock_status == 0xa2) - vt->signal = 0x01; - else - vt->signal = 0x00; - - vt->capability |= - V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | - V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; - - val = V4L2_TUNER_SUB_MONO; - vt->rxsubchans = val; - vt->audmode = V4L2_TUNER_MODE_STEREO; - return 0; -} - -static int au8522_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *chip) -{ - struct au8522_state *state = to_state(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev); -} - -static int au8522_log_status(struct v4l2_subdev *sd) -{ - /* FIXME: Add some status info here */ - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static const struct v4l2_subdev_core_ops au8522_core_ops = { - .log_status = au8522_log_status, - .g_chip_ident = au8522_g_chip_ident, - .g_ctrl = au8522_g_ctrl, - .s_ctrl = au8522_s_ctrl, - .queryctrl = au8522_queryctrl, - .reset = au8522_reset, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .g_register = au8522_g_register, - .s_register = au8522_s_register, -#endif -}; - -static const struct v4l2_subdev_tuner_ops au8522_tuner_ops = { - .g_tuner = au8522_g_tuner, -}; - -static const struct v4l2_subdev_audio_ops au8522_audio_ops = { - .s_routing = au8522_s_audio_routing, -}; - -static const struct v4l2_subdev_video_ops au8522_video_ops = { - .s_routing = au8522_s_video_routing, - .g_fmt = au8522_g_fmt, - .s_fmt = au8522_s_fmt, - .s_stream = au8522_s_stream, -}; - -static const struct v4l2_subdev_ops au8522_ops = { - .core = &au8522_core_ops, - .tuner = &au8522_tuner_ops, - .audio = &au8522_audio_ops, - .video = &au8522_video_ops, -}; - -/* ----------------------------------------------------------------------- */ - -static int au8522_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct au8522_state *state; - struct v4l2_subdev *sd; - int instance; - struct au8522_config *demod_config; - - /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) { - return -EIO; - } - - /* allocate memory for the internal state */ - instance = au8522_get_state(&state, client->adapter, client->addr); - switch (instance) { - case 0: - printk(KERN_ERR "au8522_decoder allocation failed\n"); - return -EIO; - case 1: - /* new demod instance */ - printk(KERN_INFO "au8522_decoder creating new instance...\n"); - break; - default: - /* existing demod instance */ - printk(KERN_INFO "au8522_decoder attach existing instance.\n"); - break; - } - - demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL); - demod_config->demod_address = 0x8e >> 1; - - state->config = demod_config; - state->i2c = client->adapter; - - sd = &state->sd; - v4l2_i2c_subdev_init(sd, client, &au8522_ops); - - state->c = client; - state->vid_input = AU8522_COMPOSITE_CH1; - state->aud_input = AU8522_AUDIO_NONE; - state->id = 8522; - state->rev = 0; - - /* Jam open the i2c gate to the tuner */ - au8522_writereg(state, 0x106, 1); - - return 0; -} - -static int au8522_remove(struct i2c_client *client) -{ - struct v4l2_subdev *sd = i2c_get_clientdata(client); - v4l2_device_unregister_subdev(sd); - au8522_release_state(to_state(sd)); - return 0; -} - -static const struct i2c_device_id au8522_id[] = { - {"au8522", 0}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, au8522_id); - -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "au8522", - .probe = au8522_probe, - .remove = au8522_remove, - .id_table = au8522_id, -}; diff --git a/trunk/drivers/media/dvb/frontends/au8522_priv.h b/trunk/drivers/media/dvb/frontends/au8522_priv.h deleted file mode 100644 index f328f2b3ad3d..000000000000 --- a/trunk/drivers/media/dvb/frontends/au8522_priv.h +++ /dev/null @@ -1,412 +0,0 @@ -/* - Auvitek AU8522 QAM/8VSB demodulator driver - - Copyright (C) 2008 Steven Toth - Copyright (C) 2008 Devin Heitmueller - Copyright (C) 2005-2008 Auvitek International, Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "dvb_frontend.h" -#include "au8522.h" -#include "tuner-i2c.h" - -struct au8522_state { - struct i2c_client *c; - struct i2c_adapter *i2c; - - /* Used for sharing of the state between analog and digital mode */ - struct tuner_i2c_props i2c_props; - struct list_head hybrid_tuner_instance_list; - - /* configuration settings */ - const struct au8522_config *config; - - struct dvb_frontend frontend; - - u32 current_frequency; - fe_modulation_t current_modulation; - - u32 fe_status; - unsigned int led_state; - - /* Analog settings */ - struct v4l2_subdev sd; - v4l2_std_id std; - int vid_input; - int aud_input; - u32 id; - u32 rev; - u8 brightness; - u8 contrast; -}; - -/* These are routines shared by both the VSB/QAM demodulator and the analog - decoder */ -int au8522_writereg(struct au8522_state *state, u16 reg, u8 data); -u8 au8522_readreg(struct au8522_state *state, u16 reg); -int au8522_init(struct dvb_frontend *fe); -int au8522_sleep(struct dvb_frontend *fe); - -int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, - u8 client_address); -void au8522_release_state(struct au8522_state *state); - -/* REGISTERS */ -#define AU8522_INPUT_CONTROL_REG081H 0x081 -#define AU8522_PGA_CONTROL_REG082H 0x082 -#define AU8522_CLAMPING_CONTROL_REG083H 0x083 - -#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H 0x0A3 -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H 0x0A4 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H 0x0A5 -#define AU8522_AGC_CONTROL_RANGE_REG0A6H 0x0A6 -#define AU8522_SYSTEM_GAIN_CONTROL_REG0A7H 0x0A7 -#define AU8522_TUNER_AGC_RF_STOP_REG0A8H 0x0A8 -#define AU8522_TUNER_AGC_RF_START_REG0A9H 0x0A9 -#define AU8522_TUNER_RF_AGC_DEFAULT_REG0AAH 0x0AA -#define AU8522_TUNER_AGC_IF_STOP_REG0ABH 0x0AB -#define AU8522_TUNER_AGC_IF_START_REG0ACH 0x0AC -#define AU8522_TUNER_AGC_IF_DEFAULT_REG0ADH 0x0AD -#define AU8522_TUNER_AGC_STEP_REG0AEH 0x0AE -#define AU8522_TUNER_GAIN_STEP_REG0AFH 0x0AF - -/* Receiver registers */ -#define AU8522_FRMREGTHRD1_REG0B0H 0x0B0 -#define AU8522_FRMREGAGC1H_REG0B1H 0x0B1 -#define AU8522_FRMREGSHIFT1_REG0B2H 0x0B2 -#define AU8522_TOREGAGC1_REG0B3H 0x0B3 -#define AU8522_TOREGASHIFT1_REG0B4H 0x0B4 -#define AU8522_FRMREGBBH_REG0B5H 0x0B5 -#define AU8522_FRMREGBBM_REG0B6H 0x0B6 -#define AU8522_FRMREGBBL_REG0B7H 0x0B7 -/* 0xB8 TO 0xD7 are the filter coefficients */ -#define AU8522_FRMREGTHRD2_REG0D8H 0x0D8 -#define AU8522_FRMREGAGC2H_REG0D9H 0x0D9 -#define AU8522_TOREGAGC2_REG0DAH 0x0DA -#define AU8522_TOREGSHIFT2_REG0DBH 0x0DB -#define AU8522_FRMREGPILOTH_REG0DCH 0x0DC -#define AU8522_FRMREGPILOTM_REG0DDH 0x0DD -#define AU8522_FRMREGPILOTL_REG0DEH 0x0DE -#define AU8522_TOREGFREQ_REG0DFH 0x0DF - -#define AU8522_RX_PGA_RFOUT_REG0EBH 0x0EB -#define AU8522_RX_PGA_IFOUT_REG0ECH 0x0EC -#define AU8522_RX_PGA_PGAOUT_REG0EDH 0x0ED - -#define AU8522_CHIP_MODE_REG0FEH 0x0FE - -/* I2C bus control registers */ -#define AU8522_I2C_CONTROL_REG0_REG090H 0x090 -#define AU8522_I2C_CONTROL_REG1_REG091H 0x091 -#define AU8522_I2C_STATUS_REG092H 0x092 -#define AU8522_I2C_WR_DATA0_REG093H 0x093 -#define AU8522_I2C_WR_DATA1_REG094H 0x094 -#define AU8522_I2C_WR_DATA2_REG095H 0x095 -#define AU8522_I2C_WR_DATA3_REG096H 0x096 -#define AU8522_I2C_WR_DATA4_REG097H 0x097 -#define AU8522_I2C_WR_DATA5_REG098H 0x098 -#define AU8522_I2C_WR_DATA6_REG099H 0x099 -#define AU8522_I2C_WR_DATA7_REG09AH 0x09A -#define AU8522_I2C_RD_DATA0_REG09BH 0x09B -#define AU8522_I2C_RD_DATA1_REG09CH 0x09C -#define AU8522_I2C_RD_DATA2_REG09DH 0x09D -#define AU8522_I2C_RD_DATA3_REG09EH 0x09E -#define AU8522_I2C_RD_DATA4_REG09FH 0x09F -#define AU8522_I2C_RD_DATA5_REG0A0H 0x0A0 -#define AU8522_I2C_RD_DATA6_REG0A1H 0x0A1 -#define AU8522_I2C_RD_DATA7_REG0A2H 0x0A2 - -#define AU8522_ENA_USB_REG101H 0x101 - -#define AU8522_I2S_CTRL_0_REG110H 0x110 -#define AU8522_I2S_CTRL_1_REG111H 0x111 -#define AU8522_I2S_CTRL_2_REG112H 0x112 - -#define AU8522_FRMREGFFECONTROL_REG121H 0x121 -#define AU8522_FRMREGDFECONTROL_REG122H 0x122 - -#define AU8522_CARRFREQOFFSET0_REG201H 0x201 -#define AU8522_CARRFREQOFFSET1_REG202H 0x202 - -#define AU8522_DECIMATION_GAIN_REG21AH 0x21A -#define AU8522_FRMREGIFSLP_REG21BH 0x21B -#define AU8522_FRMREGTHRDL2_REG21CH 0x21C -#define AU8522_FRMREGSTEP3DB_REG21DH 0x21D -#define AU8522_DAGC_GAIN_ADJUSTMENT_REG21EH 0x21E -#define AU8522_FRMREGPLLMODE_REG21FH 0x21F -#define AU8522_FRMREGCSTHRD_REG220H 0x220 -#define AU8522_FRMREGCRLOCKDMAX_REG221H 0x221 -#define AU8522_FRMREGCRPERIODMASK_REG222H 0x222 -#define AU8522_FRMREGCRLOCK0THH_REG223H 0x223 -#define AU8522_FRMREGCRLOCK1THH_REG224H 0x224 -#define AU8522_FRMREGCRLOCK0THL_REG225H 0x225 -#define AU8522_FRMREGCRLOCK1THL_REG226H 0x226 -#define AU_FRMREGPLLACQPHASESCL_REG227H 0x227 -#define AU8522_FRMREGFREQFBCTRL_REG228H 0x228 - -/* Analog TV Decoder */ -#define AU8522_TVDEC_STATUS_REG000H 0x000 -#define AU8522_TVDEC_INT_STATUS_REG001H 0x001 -#define AU8522_TVDEC_MACROVISION_STATUS_REG002H 0x002 -#define AU8522_TVDEC_SHARPNESSREG009H 0x009 -#define AU8522_TVDEC_BRIGHTNESS_REG00AH 0x00A -#define AU8522_TVDEC_CONTRAST_REG00BH 0x00B -#define AU8522_TVDEC_SATURATION_CB_REG00CH 0x00C -#define AU8522_TVDEC_SATURATION_CR_REG00DH 0x00D -#define AU8522_TVDEC_HUE_H_REG00EH 0x00E -#define AU8522_TVDEC_HUE_L_REG00FH 0x00F -#define AU8522_TVDEC_INT_MASK_REG010H 0x010 -#define AU8522_VIDEO_MODE_REG011H 0x011 -#define AU8522_TVDEC_PGA_REG012H 0x012 -#define AU8522_TVDEC_COMB_MODE_REG015H 0x015 -#define AU8522_REG016H 0x016 -#define AU8522_TVDED_DBG_MODE_REG060H 0x060 -#define AU8522_TVDEC_FORMAT_CTRL1_REG061H 0x061 -#define AU8522_TVDEC_FORMAT_CTRL2_REG062H 0x062 -#define AU8522_TVDEC_VCR_DET_LLIM_REG063H 0x063 -#define AU8522_TVDEC_VCR_DET_HLIM_REG064H 0x064 -#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H 0x065 -#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H 0x066 -#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H 0x067 -#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H 0x068 -#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H 0x069 -#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH 0x06A -#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH 0x06B -#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH 0x06C -#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH 0x06D -#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH 0x06E -#define AU8522_TVDEC_UV_SEP_THR_REG06FH 0x06F -#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H 0x070 -#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H 0x073 -#define AU8522_TVDEC_DCAGC_CTRL_REG077H 0x077 -#define AU8522_TVDEC_PIC_START_ADJ_REG078H 0x078 -#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H 0x079 -#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH 0x07A -#define AU8522_TVDEC_INTRP_CTRL_REG07BH 0x07B -#define AU8522_TVDEC_PLL_STATUS_REG07EH 0x07E -#define AU8522_TVDEC_FSC_FREQ_REG07FH 0x07F - -#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H 0x0E4 -#define AU8522_TOREGAAGC_REG0E5H 0x0E5 - -#define AU8522_TVDEC_CHROMA_AGC_REG401H 0x401 -#define AU8522_TVDEC_CHROMA_SFT_REG402H 0x402 -#define AU8522_FILTER_COEF_R410 0x410 -#define AU8522_FILTER_COEF_R411 0x411 -#define AU8522_FILTER_COEF_R412 0x412 -#define AU8522_FILTER_COEF_R413 0x413 -#define AU8522_FILTER_COEF_R414 0x414 -#define AU8522_FILTER_COEF_R415 0x415 -#define AU8522_FILTER_COEF_R416 0x416 -#define AU8522_FILTER_COEF_R417 0x417 -#define AU8522_FILTER_COEF_R418 0x418 -#define AU8522_FILTER_COEF_R419 0x419 -#define AU8522_FILTER_COEF_R41A 0x41A -#define AU8522_FILTER_COEF_R41B 0x41B -#define AU8522_FILTER_COEF_R41C 0x41C -#define AU8522_FILTER_COEF_R41D 0x41D -#define AU8522_FILTER_COEF_R41E 0x41E -#define AU8522_FILTER_COEF_R41F 0x41F -#define AU8522_FILTER_COEF_R420 0x420 -#define AU8522_FILTER_COEF_R421 0x421 -#define AU8522_FILTER_COEF_R422 0x422 -#define AU8522_FILTER_COEF_R423 0x423 -#define AU8522_FILTER_COEF_R424 0x424 -#define AU8522_FILTER_COEF_R425 0x425 -#define AU8522_FILTER_COEF_R426 0x426 -#define AU8522_FILTER_COEF_R427 0x427 -#define AU8522_FILTER_COEF_R428 0x428 -#define AU8522_FILTER_COEF_R429 0x429 -#define AU8522_FILTER_COEF_R42A 0x42A -#define AU8522_FILTER_COEF_R42B 0x42B -#define AU8522_FILTER_COEF_R42C 0x42C -#define AU8522_FILTER_COEF_R42D 0x42D - -/* VBI Control Registers */ -#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H 0x004 -#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H 0x005 -#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H 0x006 -#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H 0x007 -#define AU8522_TVDEC_VBI_CTRL_H_REG017H 0x017 -#define AU8522_TVDEC_VBI_CTRL_L_REG018H 0x018 -#define AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H 0x019 -#define AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH 0x01A -#define AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH 0x01B -#define AU8522_TVDEC_VBI_USER_THRESH1_REG01CH 0x01C -#define AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH 0x01E -#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH 0x01F -#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H 0x020 -#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H 0x021 -#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H 0x022 -#define AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H 0x023 - -#define AU8522_REG071H 0x071 -#define AU8522_REG072H 0x072 -#define AU8522_REG074H 0x074 -#define AU8522_REG075H 0x075 - -/* Digital Demodulator Registers */ -#define AU8522_FRAME_COUNT0_REG084H 0x084 -#define AU8522_RS_STATUS_G0_REG085H 0x085 -#define AU8522_RS_STATUS_B0_REG086H 0x086 -#define AU8522_RS_STATUS_E_REG087H 0x087 -#define AU8522_DEMODULATION_STATUS_REG088H 0x088 -#define AU8522_TOREGTRESTATUS_REG0E6H 0x0E6 -#define AU8522_TSPORT_CONTROL_REG10BH 0x10B -#define AU8522_TSTHES_REG10CH 0x10C -#define AU8522_FRMREGDFEKEEP_REG301H 0x301 -#define AU8522_DFE_AVERAGE_REG302H 0x302 -#define AU8522_FRMREGEQLERRWIN_REG303H 0x303 -#define AU8522_FRMREGFFEKEEP_REG304H 0x304 -#define AU8522_FRMREGDFECONTROL1_REG305H 0x305 -#define AU8522_FRMREGEQLERRLOW_REG306H 0x306 - -#define AU8522_REG42EH 0x42E -#define AU8522_REG42FH 0x42F -#define AU8522_REG430H 0x430 -#define AU8522_REG431H 0x431 -#define AU8522_REG432H 0x432 -#define AU8522_REG433H 0x433 -#define AU8522_REG434H 0x434 -#define AU8522_REG435H 0x435 -#define AU8522_REG436H 0x436 - -/* GPIO Registers */ -#define AU8522_GPIO_CONTROL_REG0E0H 0x0E0 -#define AU8522_GPIO_STATUS_REG0E1H 0x0E1 -#define AU8522_GPIO_DATA_REG0E2H 0x0E2 - -/* Audio Control Registers */ -#define AU8522_AUDIOAGC_REG0EEH 0x0EE -#define AU8522_AUDIO_STATUS_REG0F0H 0x0F0 -#define AU8522_AUDIO_MODE_REG0F1H 0x0F1 -#define AU8522_AUDIO_VOLUME_L_REG0F2H 0x0F2 -#define AU8522_AUDIO_VOLUME_R_REG0F3H 0x0F3 -#define AU8522_AUDIO_VOLUME_REG0F4H 0x0F4 -#define AU8522_FRMREGAUPHASE_REG0F7H 0x0F7 -#define AU8522_REG0F9H 0x0F9 - -#define AU8522_AUDIOAGC2_REG605H 0x605 -#define AU8522_AUDIOFREQ_REG606H 0x606 - - -/**************************************************************/ - -#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4 -#define AU8522_INPUT_CONTROL_REG081H_ATVRF 0xC4 -#define AU8522_INPUT_CONTROL_REG081H_ATVRF13 0xC4 -#define AU8522_INPUT_CONTROL_REG081H_J83B64 0xC4 -#define AU8522_INPUT_CONTROL_REG081H_J83B256 0xC4 -#define AU8522_INPUT_CONTROL_REG081H_CVBS 0x20 -#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH1 0xA2 -#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH2 0xA0 -#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH3 0x69 -#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4 0x68 -#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF 0x28 -/* CH1 AS Y,CH3 AS C */ -#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 0x23 -/* CH2 AS Y,CH4 AS C */ -#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24 0x20 -#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC 0x0C -#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64 0x09 -#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256 0x09 -#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS 0x12 -#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF 0x1A -#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF13 0x1A -#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO 0x02 - -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CLEAR 0x00 -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO 0x9C -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS 0x9D -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATSC 0xE8 -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256 0xCA -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64 0xCA -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF 0xDD -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF13 0xDD -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_PAL 0xDD -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_FM 0xDD - -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATSC 0x80 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256 0x80 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64 0x80 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_ATSC 0x40 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B256 0x40 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B64 0x40 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_CLEAR 0x00 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF 0x01 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF13 0x01 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO 0x04 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_CVBS 0x01 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM 0x03 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS 0x09 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PAL 0x01 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_FM 0x01 - -/* STILL NEED TO BE REFACTORED @@@@@@@@@@@@@@ */ -#define AU8522_TVDEC_CONTRAST_REG00BH_CVBS 0x79 -#define AU8522_TVDEC_SATURATION_CB_REG00CH_CVBS 0x80 -#define AU8522_TVDEC_SATURATION_CR_REG00DH_CVBS 0x80 -#define AU8522_TVDEC_HUE_H_REG00EH_CVBS 0x00 -#define AU8522_TVDEC_HUE_L_REG00FH_CVBS 0x00 -#define AU8522_TVDEC_PGA_REG012H_CVBS 0x0F -#define AU8522_TVDEC_COMB_MODE_REG015H_CVBS 0x00 -#define AU8522_REG016H_CVBS 0x00 -#define AU8522_TVDED_DBG_MODE_REG060H_CVBS 0x00 -#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS 0x0B -#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13 0x03 -#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13 0x00 -#define AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS 0x19 -#define AU8522_REG0F9H_AUDIO 0x20 -#define AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS 0xA7 -#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS 0x0A -#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS 0x32 -#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS 0x19 -#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS 0x23 -#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS 0x41 -#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS 0x0A -#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS 0x32 -#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS 0x34 -#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS 0x05 -#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS 0x6E -#define AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS 0x0F -#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS 0x80 -#define AU8522_REG071H_CVBS 0x18 -#define AU8522_REG072H_CVBS 0x30 -#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS 0xF0 -#define AU8522_REG074H_CVBS 0x80 -#define AU8522_REG075H_CVBS 0xF0 -#define AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS 0xFB -#define AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS 0x04 -#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS 0x00 -#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS 0x00 -#define AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS 0xEE -#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS 0xFE -#define AU8522_TOREGAAGC_REG0E5H_CVBS 0x00 -#define AU8522_TVDEC_VBI6A_REG035H_CVBS 0x40 - -/* Enables Closed captioning */ -#define AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON 0x21 diff --git a/trunk/drivers/media/dvb/frontends/cx24113.c b/trunk/drivers/media/dvb/frontends/cx24113.c index e4fd533a427c..f6e7b0380a5a 100644 --- a/trunk/drivers/media/dvb/frontends/cx24113.c +++ b/trunk/drivers/media/dvb/frontends/cx24113.c @@ -559,7 +559,7 @@ struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe, kzalloc(sizeof(struct cx24113_state), GFP_KERNEL); int rc; if (state == NULL) { - err("Unable to kzalloc\n"); + err("Unable to kmalloc\n"); goto error; } diff --git a/trunk/drivers/media/dvb/frontends/cx24116.c b/trunk/drivers/media/dvb/frontends/cx24116.c index 9b9f57264cef..28ad609e73f4 100644 --- a/trunk/drivers/media/dvb/frontends/cx24116.c +++ b/trunk/drivers/media/dvb/frontends/cx24116.c @@ -15,9 +15,6 @@ September, 9th 2008 Fixed locking on high symbol rates (>30000). Implement MPEG initialization parameter. - January, 17th 2009 - Fill set_voltage with actually control voltage code. - Correct set tone to not affect voltage. 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 @@ -149,7 +146,7 @@ enum cmds { CMD_GETAGC = 0x19, CMD_LNBCONFIG = 0x20, CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */ - CMD_LNBDCLEVEL = 0x22, + CMD_SET_TONEPRE = 0x22, CMD_SET_TONE = 0x23, CMD_UPDFWVERS = 0x35, CMD_TUNERSLEEP = 0x36, @@ -670,6 +667,16 @@ static int cx24116_load_firmware(struct dvb_frontend *fe, return 0; } +static int cx24116_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage) +{ + /* The isl6421 module will override this function in the fops. */ + dprintk("%s() This should never appear if the isl6421 module " + "is loaded correctly\n", __func__); + + return -EOPNOTSUPP; +} + static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct cx24116_state *state = fe->demodulator_priv; @@ -830,34 +837,6 @@ static int cx24116_wait_for_lnb(struct dvb_frontend *fe) return -ETIMEDOUT; /* -EBUSY ? */ } -static int cx24116_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) -{ - struct cx24116_cmd cmd; - int ret; - - dprintk("%s: %s\n", __func__, - voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : - voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); - - /* Wait for LNB ready */ - ret = cx24116_wait_for_lnb(fe); - if (ret != 0) - return ret; - - /* Wait for voltage/min repeat delay */ - msleep(100); - - cmd.args[0x00] = CMD_LNBDCLEVEL; - cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00); - cmd.len = 0x02; - - /* Min delay time before DiSEqC send */ - msleep(15); - - return cx24116_cmd_execute(fe, &cmd); -} - static int cx24116_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) { @@ -878,6 +857,14 @@ static int cx24116_set_tone(struct dvb_frontend *fe, /* Min delay time after DiSEqC send */ msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */ + /* This is always done before the tone is set */ + cmd.args[0x00] = CMD_SET_TONEPRE; + cmd.args[0x01] = 0x00; + cmd.len = 0x02; + ret = cx24116_cmd_execute(fe, &cmd); + if (ret != 0) + return ret; + /* Now we set the tone */ cmd.args[0x00] = CMD_SET_TONE; cmd.args[0x01] = 0x00; @@ -1112,10 +1099,13 @@ struct dvb_frontend *cx24116_attach(const struct cx24116_config *config, dprintk("%s\n", __func__); /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL); + state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL); if (state == NULL) goto error1; + /* setup the state */ + memset(state, 0, sizeof(struct cx24116_state)); + state->config = config; state->i2c = i2c; @@ -1164,12 +1154,7 @@ static int cx24116_initfe(struct dvb_frontend *fe) if (ret != 0) return ret; - ret = cx24116_diseqc_init(fe); - if (ret != 0) - return ret; - - /* HVR-4000 needs this */ - return cx24116_set_voltage(fe, SEC_VOLTAGE_13); + return cx24116_diseqc_init(fe); } /* diff --git a/trunk/drivers/media/dvb/frontends/cx24123.c b/trunk/drivers/media/dvb/frontends/cx24123.c index 0592f043ea64..1a8c36f76061 100644 --- a/trunk/drivers/media/dvb/frontends/cx24123.c +++ b/trunk/drivers/media/dvb/frontends/cx24123.c @@ -1069,13 +1069,13 @@ static struct dvb_frontend_ops cx24123_ops; struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, struct i2c_adapter *i2c) { - /* allocate memory for the internal state */ struct cx24123_state *state = kzalloc(sizeof(struct cx24123_state), GFP_KERNEL); dprintk("\n"); + /* allocate memory for the internal state */ if (state == NULL) { - err("Unable to kzalloc\n"); + err("Unable to kmalloc\n"); goto error; } diff --git a/trunk/drivers/media/dvb/frontends/dib0070.h b/trunk/drivers/media/dvb/frontends/dib0070.h index 9670f5d20cfb..21f2c5161af4 100644 --- a/trunk/drivers/media/dvb/frontends/dib0070.h +++ b/trunk/drivers/media/dvb/frontends/dib0070.h @@ -58,4 +58,6 @@ static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe) } #endif +extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open); + #endif diff --git a/trunk/drivers/media/dvb/frontends/dib3000mc.h b/trunk/drivers/media/dvb/frontends/dib3000mc.h index d75ffad2d752..4142ed7a47d0 100644 --- a/trunk/drivers/media/dvb/frontends/dib3000mc.h +++ b/trunk/drivers/media/dvb/frontends/dib3000mc.h @@ -39,43 +39,19 @@ struct dib3000mc_config { #define DEFAULT_DIB3000MC_I2C_ADDRESS 16 #define DEFAULT_DIB3000P_I2C_ADDRESS 24 -#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && \ - defined(MODULE)) -extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap, - u8 i2c_addr, - struct dib3000mc_config *cfg); -extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, - int no_of_demods, u8 default_addr, - struct dib3000mc_config cfg[]); -extern -struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, - int gating); +#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE)) +extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg); #else -static inline -struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, - struct dib3000mc_config *cfg) +static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } +#endif // CONFIG_DVB_DIB3000MC -static inline -int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, - int no_of_demods, u8 default_addr, - struct dib3000mc_config cfg[]) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} +extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[]); -static inline -struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, - int gating) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_DIB3000MC +extern struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating); extern int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff); extern int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff); diff --git a/trunk/drivers/media/dvb/frontends/dib7000m.h b/trunk/drivers/media/dvb/frontends/dib7000m.h index 113819ce9f0d..597e9cc2da62 100644 --- a/trunk/drivers/media/dvb/frontends/dib7000m.h +++ b/trunk/drivers/media/dvb/frontends/dib7000m.h @@ -38,32 +38,8 @@ struct dib7000m_config { #define DEFAULT_DIB7000M_I2C_ADDRESS 18 -#if defined(CONFIG_DVB_DIB7000M) || (defined(CONFIG_DVB_DIB7000M_MODULE) && \ - defined(MODULE)) -extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap, - u8 i2c_addr, - struct dib7000m_config *cfg); -extern struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *, - enum dibx000_i2c_interface, - int); -#else -static inline -struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap, - u8 i2c_addr, struct dib7000m_config *cfg) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} - -static inline -struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *demod, - enum dibx000_i2c_interface intf, - int gating) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif +extern struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg); +extern struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); /* TODO extern INT dib7000m_set_gpio(struct dibDemod *demod, UCHAR num, UCHAR dir, UCHAR val); diff --git a/trunk/drivers/media/dvb/frontends/dib7000p.h b/trunk/drivers/media/dvb/frontends/dib7000p.h index 02a4c82f0c70..aab8112e2db2 100644 --- a/trunk/drivers/media/dvb/frontends/dib7000p.h +++ b/trunk/drivers/media/dvb/frontends/dib7000p.h @@ -37,8 +37,7 @@ struct dib7000p_config { #define DEFAULT_DIB7000P_I2C_ADDRESS 18 -#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && \ - defined(MODULE)) +#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && defined(MODULE)) extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg); @@ -50,11 +49,10 @@ extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, struct dib7000p_config cfg[]); extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value); -extern int dib7000pc_detection(struct i2c_adapter *i2c_adap); #else -static inline -struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, - struct dib7000p_config *cfg) +static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, + u8 i2c_addr, + struct dib7000p_config *cfg) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; @@ -62,39 +60,36 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, static inline struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe, - enum dibx000_i2c_interface i, - int x) + enum dibx000_i2c_interface i, int x) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } -static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, - int no_of_demods, u8 default_addr, - struct dib7000p_config cfg[]) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} - -static inline int dib7000p_set_gpio(struct dvb_frontend *fe, - u8 num, u8 dir, u8 val) +static inline +int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, + int no_of_demods, u8 default_addr, + struct dib7000p_config cfg[]) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } -static inline int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value) +static inline +int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } -static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap) +static inline +int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } #endif +extern int dib7000pc_detection(struct i2c_adapter *i2c_adap); + #endif diff --git a/trunk/drivers/media/dvb/frontends/dvb_dummy_fe.h b/trunk/drivers/media/dvb/frontends/dvb_dummy_fe.h index 1fcb987d6386..8210f19d56ce 100644 --- a/trunk/drivers/media/dvb/frontends/dvb_dummy_fe.h +++ b/trunk/drivers/media/dvb/frontends/dvb_dummy_fe.h @@ -25,27 +25,8 @@ #include #include "dvb_frontend.h" -#if defined(CONFIG_DVB_DUMMY_FE) || (defined(CONFIG_DVB_DUMMY_FE_MODULE) && \ -defined(MODULE)) extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void); extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void); extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void); -#else -static inline struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -static inline struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -static inline struct dvb_frontend *dvb_dummy_fe_qam_attach(void) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_DUMMY_FE */ #endif // DVB_DUMMY_FE_H diff --git a/trunk/drivers/media/dvb/frontends/itd1000_priv.h b/trunk/drivers/media/dvb/frontends/itd1000_priv.h index 08ca851223c9..8cdc54e57903 100644 --- a/trunk/drivers/media/dvb/frontends/itd1000_priv.h +++ b/trunk/drivers/media/dvb/frontends/itd1000_priv.h @@ -31,7 +31,7 @@ struct itd1000_state { /* ugly workaround for flexcop's incapable i2c-controller * FIXME, if possible */ - u8 shadow[256]; + u8 shadow[255]; }; enum itd1000_register { diff --git a/trunk/drivers/media/dvb/frontends/lgdt3304.c b/trunk/drivers/media/dvb/frontends/lgdt3304.c index eb72a9866c93..3bb0c4394f8a 100644 --- a/trunk/drivers/media/dvb/frontends/lgdt3304.c +++ b/trunk/drivers/media/dvb/frontends/lgdt3304.c @@ -363,6 +363,7 @@ struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, struct lgdt3304_state *state; state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL); + memset(state, 0x0, sizeof(struct lgdt3304_state)); state->addr = config->i2c_address; state->i2c = i2c; diff --git a/trunk/drivers/media/dvb/frontends/lgdt3305.c b/trunk/drivers/media/dvb/frontends/lgdt3305.c deleted file mode 100644 index d92d0557a80b..000000000000 --- a/trunk/drivers/media/dvb/frontends/lgdt3305.c +++ /dev/null @@ -1,1087 +0,0 @@ -/* - * Support for LGDT3305 - VSB/QAM - * - * Copyright (C) 2008, 2009 Michael Krufky - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include "dvb_math.h" -#include "lgdt3305.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))"); - -#define DBG_INFO 1 -#define DBG_REG 2 - -#define lg_printk(kern, fmt, arg...) \ - printk(kern "%s: " fmt, __func__, ##arg) - -#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3305: " fmt, ##arg) -#define lg_warn(fmt, arg...) lg_printk(KERN_WARNING, fmt, ##arg) -#define lg_err(fmt, arg...) lg_printk(KERN_ERR, fmt, ##arg) -#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \ - lg_printk(KERN_DEBUG, fmt, ##arg) -#define lg_reg(fmt, arg...) if (debug & DBG_REG) \ - lg_printk(KERN_DEBUG, fmt, ##arg) - -#define lg_fail(ret) \ -({ \ - int __ret; \ - __ret = (ret < 0); \ - if (__ret) \ - lg_err("error %d on line %d\n", ret, __LINE__); \ - __ret; \ -}) - -struct lgdt3305_state { - struct i2c_adapter *i2c_adap; - const struct lgdt3305_config *cfg; - - struct dvb_frontend frontend; - - fe_modulation_t current_modulation; - u32 current_frequency; - u32 snr; -}; - -/* ------------------------------------------------------------------------ */ - -#define LGDT3305_GEN_CTRL_1 0x0000 -#define LGDT3305_GEN_CTRL_2 0x0001 -#define LGDT3305_GEN_CTRL_3 0x0002 -#define LGDT3305_GEN_STATUS 0x0003 -#define LGDT3305_GEN_CONTROL 0x0007 -#define LGDT3305_GEN_CTRL_4 0x000a -#define LGDT3305_DGTL_AGC_REF_1 0x0012 -#define LGDT3305_DGTL_AGC_REF_2 0x0013 -#define LGDT3305_CR_CTR_FREQ_1 0x0106 -#define LGDT3305_CR_CTR_FREQ_2 0x0107 -#define LGDT3305_CR_CTR_FREQ_3 0x0108 -#define LGDT3305_CR_CTR_FREQ_4 0x0109 -#define LGDT3305_CR_MSE_1 0x011b -#define LGDT3305_CR_MSE_2 0x011c -#define LGDT3305_CR_LOCK_STATUS 0x011d -#define LGDT3305_CR_CTRL_7 0x0126 -#define LGDT3305_AGC_POWER_REF_1 0x0300 -#define LGDT3305_AGC_POWER_REF_2 0x0301 -#define LGDT3305_AGC_DELAY_PT_1 0x0302 -#define LGDT3305_AGC_DELAY_PT_2 0x0303 -#define LGDT3305_RFAGC_LOOP_FLTR_BW_1 0x0306 -#define LGDT3305_RFAGC_LOOP_FLTR_BW_2 0x0307 -#define LGDT3305_IFBW_1 0x0308 -#define LGDT3305_IFBW_2 0x0309 -#define LGDT3305_AGC_CTRL_1 0x030c -#define LGDT3305_AGC_CTRL_4 0x0314 -#define LGDT3305_EQ_MSE_1 0x0413 -#define LGDT3305_EQ_MSE_2 0x0414 -#define LGDT3305_EQ_MSE_3 0x0415 -#define LGDT3305_PT_MSE_1 0x0417 -#define LGDT3305_PT_MSE_2 0x0418 -#define LGDT3305_PT_MSE_3 0x0419 -#define LGDT3305_FEC_BLOCK_CTRL 0x0504 -#define LGDT3305_FEC_LOCK_STATUS 0x050a -#define LGDT3305_FEC_PKT_ERR_1 0x050c -#define LGDT3305_FEC_PKT_ERR_2 0x050d -#define LGDT3305_TP_CTRL_1 0x050e -#define LGDT3305_BERT_PERIOD 0x0801 -#define LGDT3305_BERT_ERROR_COUNT_1 0x080a -#define LGDT3305_BERT_ERROR_COUNT_2 0x080b -#define LGDT3305_BERT_ERROR_COUNT_3 0x080c -#define LGDT3305_BERT_ERROR_COUNT_4 0x080d - -static int lgdt3305_write_reg(struct lgdt3305_state *state, u16 reg, u8 val) -{ - int ret; - u8 buf[] = { reg >> 8, reg & 0xff, val }; - struct i2c_msg msg = { - .addr = state->cfg->i2c_addr, .flags = 0, - .buf = buf, .len = 3, - }; - - lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val); - - ret = i2c_transfer(state->i2c_adap, &msg, 1); - - if (ret != 1) { - lg_err("error (addr %02x %02x <- %02x, err = %i)\n", - msg.buf[0], msg.buf[1], msg.buf[2], ret); - if (ret < 0) - return ret; - else - return -EREMOTEIO; - } - return 0; -} - -static int lgdt3305_read_reg(struct lgdt3305_state *state, u16 reg, u8 *val) -{ - int ret; - u8 reg_buf[] = { reg >> 8, reg & 0xff }; - struct i2c_msg msg[] = { - { .addr = state->cfg->i2c_addr, - .flags = 0, .buf = reg_buf, .len = 2 }, - { .addr = state->cfg->i2c_addr, - .flags = I2C_M_RD, .buf = val, .len = 1 }, - }; - - lg_reg("reg: 0x%04x\n", reg); - - ret = i2c_transfer(state->i2c_adap, msg, 2); - - if (ret != 2) { - lg_err("error (addr %02x reg %04x error (ret == %i)\n", - state->cfg->i2c_addr, reg, ret); - if (ret < 0) - return ret; - else - return -EREMOTEIO; - } - return 0; -} - -#define read_reg(state, reg) \ -({ \ - u8 __val; \ - int ret = lgdt3305_read_reg(state, reg, &__val); \ - if (lg_fail(ret)) \ - __val = 0; \ - __val; \ -}) - -static int lgdt3305_set_reg_bit(struct lgdt3305_state *state, - u16 reg, int bit, int onoff) -{ - u8 val; - int ret; - - lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff); - - ret = lgdt3305_read_reg(state, reg, &val); - if (lg_fail(ret)) - goto fail; - - val &= ~(1 << bit); - val |= (onoff & 1) << bit; - - ret = lgdt3305_write_reg(state, reg, val); -fail: - return ret; -} - -struct lgdt3305_reg { - u16 reg; - u8 val; -}; - -static int lgdt3305_write_regs(struct lgdt3305_state *state, - struct lgdt3305_reg *regs, int len) -{ - int i, ret; - - lg_reg("writing %d registers...\n", len); - - for (i = 0; i < len - 1; i++) { - ret = lgdt3305_write_reg(state, regs[i].reg, regs[i].val); - if (lg_fail(ret)) - return ret; - } - return 0; -} - -/* ------------------------------------------------------------------------ */ - -static int lgdt3305_soft_reset(struct lgdt3305_state *state) -{ - int ret; - - lg_dbg("\n"); - - ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 0); - if (lg_fail(ret)) - goto fail; - - msleep(20); - ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 1); -fail: - return ret; -} - -static inline int lgdt3305_mpeg_mode(struct lgdt3305_state *state, - enum lgdt3305_mpeg_mode mode) -{ - lg_dbg("(%d)\n", mode); - return lgdt3305_set_reg_bit(state, LGDT3305_TP_CTRL_1, 5, mode); -} - -static int lgdt3305_mpeg_mode_polarity(struct lgdt3305_state *state, - enum lgdt3305_tp_clock_edge edge, - enum lgdt3305_tp_valid_polarity valid) -{ - u8 val; - int ret; - - lg_dbg("edge = %d, valid = %d\n", edge, valid); - - ret = lgdt3305_read_reg(state, LGDT3305_TP_CTRL_1, &val); - if (lg_fail(ret)) - goto fail; - - val &= ~0x09; - - if (edge) - val |= 0x08; - if (valid) - val |= 0x01; - - ret = lgdt3305_write_reg(state, LGDT3305_TP_CTRL_1, val); - if (lg_fail(ret)) - goto fail; - - ret = lgdt3305_soft_reset(state); -fail: - return ret; -} - -static int lgdt3305_set_modulation(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param) -{ - u8 opermode; - int ret; - - lg_dbg("\n"); - - ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_1, &opermode); - if (lg_fail(ret)) - goto fail; - - opermode &= ~0x03; - - switch (param->u.vsb.modulation) { - case VSB_8: - opermode |= 0x03; - break; - case QAM_64: - opermode |= 0x00; - break; - case QAM_256: - opermode |= 0x01; - break; - default: - return -EINVAL; - } - ret = lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_1, opermode); -fail: - return ret; -} - -static int lgdt3305_set_filter_extension(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param) -{ - int val; - - switch (param->u.vsb.modulation) { - case VSB_8: - val = 0; - break; - case QAM_64: - case QAM_256: - val = 1; - break; - default: - return -EINVAL; - } - lg_dbg("val = %d\n", val); - - return lgdt3305_set_reg_bit(state, 0x043f, 2, val); -} - -/* ------------------------------------------------------------------------ */ - -static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param) -{ - u16 agc_ref; - - switch (param->u.vsb.modulation) { - case VSB_8: - agc_ref = 0x32c4; - break; - case QAM_64: - agc_ref = 0x2a00; - break; - case QAM_256: - agc_ref = 0x2a80; - break; - default: - return -EINVAL; - } - - lg_dbg("agc ref: 0x%04x\n", agc_ref); - - lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_1, agc_ref >> 8); - lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_2, agc_ref & 0xff); - - return 0; -} - -static int lgdt3305_rfagc_loop(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param) -{ - u16 ifbw, rfbw, agcdelay; - - switch (param->u.vsb.modulation) { - case VSB_8: - agcdelay = 0x04c0; - rfbw = 0x8000; - ifbw = 0x8000; - break; - case QAM_64: - case QAM_256: - agcdelay = 0x046b; - rfbw = 0x8889; - ifbw = 0x8888; - break; - default: - return -EINVAL; - } - - if (state->cfg->rf_agc_loop) { - lg_dbg("agcdelay: 0x%04x, rfbw: 0x%04x\n", agcdelay, rfbw); - - /* rf agc loop filter bandwidth */ - lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_1, - agcdelay >> 8); - lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_2, - agcdelay & 0xff); - - lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_1, - rfbw >> 8); - lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_2, - rfbw & 0xff); - } else { - lg_dbg("ifbw: 0x%04x\n", ifbw); - - /* if agc loop filter bandwidth */ - lgdt3305_write_reg(state, LGDT3305_IFBW_1, ifbw >> 8); - lgdt3305_write_reg(state, LGDT3305_IFBW_2, ifbw & 0xff); - } - - return 0; -} - -static int lgdt3305_agc_setup(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param) -{ - int lockdten, acqen; - - switch (param->u.vsb.modulation) { - case VSB_8: - lockdten = 0; - acqen = 0; - break; - case QAM_64: - case QAM_256: - lockdten = 1; - acqen = 1; - break; - default: - return -EINVAL; - } - - lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen); - - /* control agc function */ - lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1); - lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen); - - return lgdt3305_rfagc_loop(state, param); -} - -static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param) -{ - u16 usref = 0; - - switch (param->u.vsb.modulation) { - case VSB_8: - if (state->cfg->usref_8vsb) - usref = state->cfg->usref_8vsb; - break; - case QAM_64: - if (state->cfg->usref_qam64) - usref = state->cfg->usref_qam64; - break; - case QAM_256: - if (state->cfg->usref_qam256) - usref = state->cfg->usref_qam256; - break; - default: - return -EINVAL; - } - - if (usref) { - lg_dbg("set manual mode: 0x%04x\n", usref); - - lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 3, 1); - - lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_1, - 0xff & (usref >> 8)); - lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_2, - 0xff & (usref >> 0)); - } - return 0; -} - -/* ------------------------------------------------------------------------ */ - -static int lgdt3305_spectral_inversion(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param, - int inversion) -{ - int ret; - - lg_dbg("(%d)\n", inversion); - - switch (param->u.vsb.modulation) { - case VSB_8: - ret = lgdt3305_write_reg(state, LGDT3305_CR_CTRL_7, - inversion ? 0xf9 : 0x79); - break; - case QAM_64: - case QAM_256: - ret = lgdt3305_write_reg(state, LGDT3305_FEC_BLOCK_CTRL, - inversion ? 0xfd : 0xff); - break; - default: - ret = -EINVAL; - } - return ret; -} - -static int lgdt3305_set_if(struct lgdt3305_state *state, - struct dvb_frontend_parameters *param) -{ - u16 if_freq_khz; - u8 nco1, nco2, nco3, nco4; - u64 nco; - - switch (param->u.vsb.modulation) { - case VSB_8: - if_freq_khz = state->cfg->vsb_if_khz; - break; - case QAM_64: - case QAM_256: - if_freq_khz = state->cfg->qam_if_khz; - break; - default: - return -EINVAL; - } - - nco = if_freq_khz / 10; - -#define LGDT3305_64BIT_DIVISION_ENABLED 0 - /* FIXME: 64bit division disabled to avoid linking error: - * WARNING: "__udivdi3" [lgdt3305.ko] undefined! - */ - switch (param->u.vsb.modulation) { - case VSB_8: -#if LGDT3305_64BIT_DIVISION_ENABLED - nco <<= 24; - nco /= 625; -#else - nco *= ((1 << 24) / 625); -#endif - break; - case QAM_64: - case QAM_256: -#if LGDT3305_64BIT_DIVISION_ENABLED - nco <<= 28; - nco /= 625; -#else - nco *= ((1 << 28) / 625); -#endif - break; - default: - return -EINVAL; - } - - nco1 = (nco >> 24) & 0x3f; - nco1 |= 0x40; - nco2 = (nco >> 16) & 0xff; - nco3 = (nco >> 8) & 0xff; - nco4 = nco & 0xff; - - lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, nco1); - lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, nco2); - lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, nco3); - lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, nco4); - - lg_dbg("%d KHz -> [%02x%02x%02x%02x]\n", - if_freq_khz, nco1, nco2, nco3, nco4); - - return 0; -} - -/* ------------------------------------------------------------------------ */ - -static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct lgdt3305_state *state = fe->demodulator_priv; - - if (state->cfg->deny_i2c_rptr) - return 0; - - lg_dbg("(%d)\n", enable); - - return lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_2, 5, - enable ? 0 : 1); -} - -static int lgdt3305_sleep(struct dvb_frontend *fe) -{ - struct lgdt3305_state *state = fe->demodulator_priv; - u8 gen_ctrl_3, gen_ctrl_4; - - lg_dbg("\n"); - - gen_ctrl_3 = read_reg(state, LGDT3305_GEN_CTRL_3); - gen_ctrl_4 = read_reg(state, LGDT3305_GEN_CTRL_4); - - /* hold in software reset while sleeping */ - gen_ctrl_3 &= ~0x01; - /* tristate the IF-AGC pin */ - gen_ctrl_3 |= 0x02; - /* tristate the RF-AGC pin */ - gen_ctrl_3 |= 0x04; - - /* disable vsb/qam module */ - gen_ctrl_4 &= ~0x01; - /* disable adc module */ - gen_ctrl_4 &= ~0x02; - - lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_3, gen_ctrl_3); - lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_4, gen_ctrl_4); - - return 0; -} - -static int lgdt3305_init(struct dvb_frontend *fe) -{ - struct lgdt3305_state *state = fe->demodulator_priv; - int ret; - - static struct lgdt3305_reg lgdt3305_init_data[] = { - { .reg = LGDT3305_GEN_CTRL_1, - .val = 0x03, }, - { .reg = LGDT3305_GEN_CTRL_2, - .val = 0xb0, }, - { .reg = LGDT3305_GEN_CTRL_3, - .val = 0x01, }, - { .reg = LGDT3305_GEN_CONTROL, - .val = 0x6f, }, - { .reg = LGDT3305_GEN_CTRL_4, - .val = 0x03, }, - { .reg = LGDT3305_DGTL_AGC_REF_1, - .val = 0x32, }, - { .reg = LGDT3305_DGTL_AGC_REF_2, - .val = 0xc4, }, - { .reg = LGDT3305_CR_CTR_FREQ_1, - .val = 0x00, }, - { .reg = LGDT3305_CR_CTR_FREQ_2, - .val = 0x00, }, - { .reg = LGDT3305_CR_CTR_FREQ_3, - .val = 0x00, }, - { .reg = LGDT3305_CR_CTR_FREQ_4, - .val = 0x00, }, - { .reg = LGDT3305_CR_CTRL_7, - .val = 0x79, }, - { .reg = LGDT3305_AGC_POWER_REF_1, - .val = 0x32, }, - { .reg = LGDT3305_AGC_POWER_REF_2, - .val = 0xc4, }, - { .reg = LGDT3305_AGC_DELAY_PT_1, - .val = 0x0d, }, - { .reg = LGDT3305_AGC_DELAY_PT_2, - .val = 0x30, }, - { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1, - .val = 0x80, }, - { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2, - .val = 0x00, }, - { .reg = LGDT3305_IFBW_1, - .val = 0x80, }, - { .reg = LGDT3305_IFBW_2, - .val = 0x00, }, - { .reg = LGDT3305_AGC_CTRL_1, - .val = 0x30, }, - { .reg = LGDT3305_AGC_CTRL_4, - .val = 0x61, }, - { .reg = LGDT3305_FEC_BLOCK_CTRL, - .val = 0xff, }, - { .reg = LGDT3305_TP_CTRL_1, - .val = 0x1b, }, - }; - - lg_dbg("\n"); - - ret = lgdt3305_write_regs(state, lgdt3305_init_data, - ARRAY_SIZE(lgdt3305_init_data)); - if (lg_fail(ret)) - goto fail; - - ret = lgdt3305_soft_reset(state); -fail: - return ret; -} - -static int lgdt3305_set_parameters(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) -{ - struct lgdt3305_state *state = fe->demodulator_priv; - int ret; - - lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation); - - if (fe->ops.tuner_ops.set_params) { - ret = fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - if (lg_fail(ret)) - goto fail; - state->current_frequency = param->frequency; - } - - ret = lgdt3305_set_modulation(state, param); - if (lg_fail(ret)) - goto fail; - - ret = lgdt3305_passband_digital_agc(state, param); - if (lg_fail(ret)) - goto fail; - ret = lgdt3305_set_agc_power_ref(state, param); - if (lg_fail(ret)) - goto fail; - ret = lgdt3305_agc_setup(state, param); - if (lg_fail(ret)) - goto fail; - - /* low if */ - ret = lgdt3305_write_reg(state, LGDT3305_GEN_CONTROL, 0x2f); - if (lg_fail(ret)) - goto fail; - ret = lgdt3305_set_reg_bit(state, LGDT3305_CR_CTR_FREQ_1, 6, 1); - if (lg_fail(ret)) - goto fail; - - ret = lgdt3305_set_if(state, param); - if (lg_fail(ret)) - goto fail; - ret = lgdt3305_spectral_inversion(state, param, - state->cfg->spectral_inversion - ? 1 : 0); - if (lg_fail(ret)) - goto fail; - - ret = lgdt3305_set_filter_extension(state, param); - if (lg_fail(ret)) - goto fail; - - state->current_modulation = param->u.vsb.modulation; - - ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode); - if (lg_fail(ret)) - goto fail; - - /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */ - ret = lgdt3305_mpeg_mode_polarity(state, - state->cfg->tpclk_edge, - state->cfg->tpvalid_polarity); -fail: - return ret; -} - -static int lgdt3305_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) -{ - struct lgdt3305_state *state = fe->demodulator_priv; - - lg_dbg("\n"); - - param->u.vsb.modulation = state->current_modulation; - param->frequency = state->current_frequency; - return 0; -} - -/* ------------------------------------------------------------------------ */ - -static int lgdt3305_read_cr_lock_status(struct lgdt3305_state *state, - int *locked) -{ - u8 val; - int ret; - char *cr_lock_state = ""; - - *locked = 0; - - ret = lgdt3305_read_reg(state, LGDT3305_CR_LOCK_STATUS, &val); - if (lg_fail(ret)) - goto fail; - - switch (state->current_modulation) { - case QAM_256: - case QAM_64: - if (val & (1 << 1)) - *locked = 1; - - switch (val & 0x07) { - case 0: - cr_lock_state = "QAM UNLOCK"; - break; - case 4: - cr_lock_state = "QAM 1stLock"; - break; - case 6: - cr_lock_state = "QAM 2ndLock"; - break; - case 7: - cr_lock_state = "QAM FinalLock"; - break; - default: - cr_lock_state = "CLOCKQAM-INVALID!"; - break; - } - break; - case VSB_8: - if (val & (1 << 7)) { - *locked = 1; - cr_lock_state = "CLOCKVSB"; - } - break; - default: - ret = -EINVAL; - } - lg_dbg("(%d) %s\n", *locked, cr_lock_state); -fail: - return ret; -} - -static int lgdt3305_read_fec_lock_status(struct lgdt3305_state *state, - int *locked) -{ - u8 val; - int ret, mpeg_lock, fec_lock, viterbi_lock; - - *locked = 0; - - switch (state->current_modulation) { - case QAM_256: - case QAM_64: - ret = lgdt3305_read_reg(state, - LGDT3305_FEC_LOCK_STATUS, &val); - if (lg_fail(ret)) - goto fail; - - mpeg_lock = (val & (1 << 0)) ? 1 : 0; - fec_lock = (val & (1 << 2)) ? 1 : 0; - viterbi_lock = (val & (1 << 3)) ? 1 : 0; - - *locked = mpeg_lock && fec_lock && viterbi_lock; - - lg_dbg("(%d) %s%s%s\n", *locked, - mpeg_lock ? "mpeg lock " : "", - fec_lock ? "fec lock " : "", - viterbi_lock ? "viterbi lock" : ""); - break; - case VSB_8: - default: - ret = -EINVAL; - } -fail: - return ret; -} - -static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct lgdt3305_state *state = fe->demodulator_priv; - u8 val; - int ret, signal, inlock, nofecerr, snrgood, - cr_lock, fec_lock, sync_lock; - - *status = 0; - - ret = lgdt3305_read_reg(state, LGDT3305_GEN_STATUS, &val); - if (lg_fail(ret)) - goto fail; - - signal = (val & (1 << 4)) ? 1 : 0; - inlock = (val & (1 << 3)) ? 0 : 1; - sync_lock = (val & (1 << 2)) ? 1 : 0; - nofecerr = (val & (1 << 1)) ? 1 : 0; - snrgood = (val & (1 << 0)) ? 1 : 0; - - lg_dbg("%s%s%s%s%s\n", - signal ? "SIGNALEXIST " : "", - inlock ? "INLOCK " : "", - sync_lock ? "SYNCLOCK " : "", - nofecerr ? "NOFECERR " : "", - snrgood ? "SNRGOOD " : ""); - - ret = lgdt3305_read_cr_lock_status(state, &cr_lock); - if (lg_fail(ret)) - goto fail; - - if (signal) - *status |= FE_HAS_SIGNAL; - if (cr_lock) - *status |= FE_HAS_CARRIER; - if (nofecerr) - *status |= FE_HAS_VITERBI; - if (sync_lock) - *status |= FE_HAS_SYNC; - - switch (state->current_modulation) { - case QAM_256: - case QAM_64: - ret = lgdt3305_read_fec_lock_status(state, &fec_lock); - if (lg_fail(ret)) - goto fail; - - if (fec_lock) - *status |= FE_HAS_LOCK; - break; - case VSB_8: - if (inlock) - *status |= FE_HAS_LOCK; - break; - default: - ret = -EINVAL; - } -fail: - return ret; -} - -/* ------------------------------------------------------------------------ */ - -/* borrowed from lgdt330x.c */ -static u32 calculate_snr(u32 mse, u32 c) -{ - if (mse == 0) /* no signal */ - return 0; - - mse = intlog10(mse); - if (mse > c) { - /* Negative SNR, which is possible, but realisticly the - demod will lose lock before the signal gets this bad. The - API only allows for unsigned values, so just return 0 */ - return 0; - } - return 10*(c - mse); -} - -static int lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct lgdt3305_state *state = fe->demodulator_priv; - u32 noise; /* noise value */ - u32 c; /* per-modulation SNR calculation constant */ - - switch (state->current_modulation) { - case VSB_8: -#ifdef USE_PTMSE - /* Use Phase Tracker Mean-Square Error Register */ - /* SNR for ranges from -13.11 to +44.08 */ - noise = ((read_reg(state, LGDT3305_PT_MSE_1) & 0x07) << 16) | - (read_reg(state, LGDT3305_PT_MSE_2) << 8) | - (read_reg(state, LGDT3305_PT_MSE_3) & 0xff); - c = 73957994; /* log10(25*32^2)*2^24 */ -#else - /* Use Equalizer Mean-Square Error Register */ - /* SNR for ranges from -16.12 to +44.08 */ - noise = ((read_reg(state, LGDT3305_EQ_MSE_1) & 0x0f) << 16) | - (read_reg(state, LGDT3305_EQ_MSE_2) << 8) | - (read_reg(state, LGDT3305_EQ_MSE_3) & 0xff); - c = 73957994; /* log10(25*32^2)*2^24 */ -#endif - break; - case QAM_64: - case QAM_256: - noise = (read_reg(state, LGDT3305_CR_MSE_1) << 8) | - (read_reg(state, LGDT3305_CR_MSE_2) & 0xff); - - c = (state->current_modulation == QAM_64) ? - 97939837 : 98026066; - /* log10(688128)*2^24 and log10(696320)*2^24 */ - break; - default: - return -EINVAL; - } - state->snr = calculate_snr(noise, c); - /* report SNR in dB * 10 */ - *snr = (state->snr / ((1 << 24) / 10)); - lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise, - state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16); - - return 0; -} - -static int lgdt3305_read_signal_strength(struct dvb_frontend *fe, - u16 *strength) -{ - /* borrowed from lgdt330x.c - * - * Calculate strength from SNR up to 35dB - * Even though the SNR can go higher than 35dB, - * there is some comfort factor in having a range of - * strong signals that can show at 100% - */ - struct lgdt3305_state *state = fe->demodulator_priv; - u16 snr; - int ret; - - *strength = 0; - - ret = fe->ops.read_snr(fe, &snr); - if (lg_fail(ret)) - goto fail; - /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */ - /* scale the range 0 - 35*2^24 into 0 - 65535 */ - if (state->snr >= 8960 * 0x10000) - *strength = 0xffff; - else - *strength = state->snr / 8960; -fail: - return ret; -} - -/* ------------------------------------------------------------------------ */ - -static int lgdt3305_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - *ber = 0; - return 0; -} - -static int lgdt3305_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct lgdt3305_state *state = fe->demodulator_priv; - - *ucblocks = - (read_reg(state, LGDT3305_FEC_PKT_ERR_1) << 8) | - (read_reg(state, LGDT3305_FEC_PKT_ERR_2) & 0xff); - - return 0; -} - -static int lgdt3305_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings - *fe_tune_settings) -{ - fe_tune_settings->min_delay_ms = 500; - lg_dbg("\n"); - return 0; -} - -static void lgdt3305_release(struct dvb_frontend *fe) -{ - struct lgdt3305_state *state = fe->demodulator_priv; - lg_dbg("\n"); - kfree(state); -} - -static struct dvb_frontend_ops lgdt3305_ops; - -struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, - struct i2c_adapter *i2c_adap) -{ - struct lgdt3305_state *state = NULL; - int ret; - u8 val; - - lg_dbg("(%d-%04x)\n", - i2c_adap ? i2c_adapter_id(i2c_adap) : 0, - config ? config->i2c_addr : 0); - - state = kzalloc(sizeof(struct lgdt3305_state), GFP_KERNEL); - if (state == NULL) - goto fail; - - state->cfg = config; - state->i2c_adap = i2c_adap; - - memcpy(&state->frontend.ops, &lgdt3305_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - /* verify that we're talking to a lg dt3305 */ - ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val); - if ((lg_fail(ret)) | (val == 0)) - goto fail; - ret = lgdt3305_write_reg(state, 0x0808, 0x80); - if (lg_fail(ret)) - goto fail; - ret = lgdt3305_read_reg(state, 0x0808, &val); - if ((lg_fail(ret)) | (val != 0x80)) - goto fail; - ret = lgdt3305_write_reg(state, 0x0808, 0x00); - if (lg_fail(ret)) - goto fail; - - state->current_frequency = -1; - state->current_modulation = -1; - - return &state->frontend; -fail: - lg_warn("unable to detect LGDT3305 hardware\n"); - kfree(state); - return NULL; -} -EXPORT_SYMBOL(lgdt3305_attach); - -static struct dvb_frontend_ops lgdt3305_ops = { - .info = { - .name = "LG Electronics LGDT3305 VSB/QAM Frontend", - .type = FE_ATSC, - .frequency_min = 54000000, - .frequency_max = 858000000, - .frequency_stepsize = 62500, - .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - .i2c_gate_ctrl = lgdt3305_i2c_gate_ctrl, - .init = lgdt3305_init, - .sleep = lgdt3305_sleep, - .set_frontend = lgdt3305_set_parameters, - .get_frontend = lgdt3305_get_frontend, - .get_tune_settings = lgdt3305_get_tune_settings, - .read_status = lgdt3305_read_status, - .read_ber = lgdt3305_read_ber, - .read_signal_strength = lgdt3305_read_signal_strength, - .read_snr = lgdt3305_read_snr, - .read_ucblocks = lgdt3305_read_ucblocks, - .release = lgdt3305_release, -}; - -MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver"); -MODULE_AUTHOR("Michael Krufky "); -MODULE_LICENSE("GPL"); -MODULE_VERSION("0.1"); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/trunk/drivers/media/dvb/frontends/lgdt3305.h b/trunk/drivers/media/dvb/frontends/lgdt3305.h deleted file mode 100644 index 4fa6e52d1fe8..000000000000 --- a/trunk/drivers/media/dvb/frontends/lgdt3305.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Support for LGDT3305 - VSB/QAM - * - * Copyright (C) 2008, 2009 Michael Krufky - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _LGDT3305_H_ -#define _LGDT3305_H_ - -#include -#include "dvb_frontend.h" - - -enum lgdt3305_mpeg_mode { - LGDT3305_MPEG_PARALLEL = 0, - LGDT3305_MPEG_SERIAL = 1, -}; - -enum lgdt3305_tp_clock_edge { - LGDT3305_TPCLK_RISING_EDGE = 0, - LGDT3305_TPCLK_FALLING_EDGE = 1, -}; - -enum lgdt3305_tp_valid_polarity { - LGDT3305_TP_VALID_LOW = 0, - LGDT3305_TP_VALID_HIGH = 1, -}; - -struct lgdt3305_config { - u8 i2c_addr; - - /* user defined IF frequency in KHz */ - u16 qam_if_khz; - u16 vsb_if_khz; - - /* AGC Power reference - defaults are used if left unset */ - u16 usref_8vsb; /* default: 0x32c4 */ - u16 usref_qam64; /* default: 0x5400 */ - u16 usref_qam256; /* default: 0x2a80 */ - - /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */ - int deny_i2c_rptr:1; - - /* spectral inversion - 0:disabled 1:enabled */ - int spectral_inversion:1; - - /* use RF AGC loop - 0:disabled 1:enabled */ - int rf_agc_loop:1; - - enum lgdt3305_mpeg_mode mpeg_mode; - enum lgdt3305_tp_clock_edge tpclk_edge; - enum lgdt3305_tp_valid_polarity tpvalid_polarity; -}; - -#if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \ - defined(MODULE)) -extern -struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, - struct i2c_adapter *i2c_adap); -#else -static inline -struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, - struct i2c_adapter *i2c_adap) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_LGDT3305 */ - -#endif /* _LGDT3305_H_ */ diff --git a/trunk/drivers/media/dvb/frontends/lnbh24.h b/trunk/drivers/media/dvb/frontends/lnbh24.h deleted file mode 100644 index c059b165318f..000000000000 --- a/trunk/drivers/media/dvb/frontends/lnbh24.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * lnbh24.h - driver for lnb supply and control ic lnbh24 - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _LNBH24_H -#define _LNBH24_H - -/* system register bits */ -#define LNBH24_OLF 0x01 -#define LNBH24_OTF 0x02 -#define LNBH24_EN 0x04 -#define LNBH24_VSEL 0x08 -#define LNBH24_LLC 0x10 -#define LNBH24_TEN 0x20 -#define LNBH24_TTX 0x40 -#define LNBH24_PCL 0x80 - -#include - -#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \ - && defined(MODULE)) -/* override_set and override_clear control which - system register bits (above) to always set & clear */ -extern struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, u8 override_set, - u8 override_clear, u8 i2c_addr); -#else -static inline struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, u8 override_set, - u8 override_clear, u8 i2c_addr) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif diff --git a/trunk/drivers/media/dvb/frontends/lnbp21.c b/trunk/drivers/media/dvb/frontends/lnbp21.c index 1dcc56f32bff..76f935d9755a 100644 --- a/trunk/drivers/media/dvb/frontends/lnbp21.c +++ b/trunk/drivers/media/dvb/frontends/lnbp21.c @@ -1,8 +1,7 @@ /* - * lnbp21.c - driver for lnb supply and control ic lnbp21 + * lnbp21.h - driver for lnb supply and control ic lnbp21 * * Copyright (C) 2006 Oliver Endriss - * Copyright (C) 2009 Igor M. Liplianin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -34,21 +33,18 @@ #include "dvb_frontend.h" #include "lnbp21.h" -#include "lnbh24.h" struct lnbp21 { u8 config; u8 override_or; u8 override_and; struct i2c_adapter *i2c; - u8 i2c_addr; }; -static int lnbp21_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) +static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) { struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv; - struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0, + struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &lnbp21->config, .len = sizeof(lnbp21->config) }; @@ -76,7 +72,7 @@ static int lnbp21_set_voltage(struct dvb_frontend *fe, static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) { struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv; - struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0, + struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &lnbp21->config, .len = sizeof(lnbp21->config) }; @@ -101,18 +97,15 @@ static void lnbp21_release(struct dvb_frontend *fe) fe->sec_priv = NULL; } -static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, u8 override_set, - u8 override_clear, u8 i2c_addr, u8 config) +struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) { struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); if (!lnbp21) return NULL; /* default configuration */ - lnbp21->config = config; + lnbp21->config = LNBP21_ISEL; lnbp21->i2c = i2c; - lnbp21->i2c_addr = i2c_addr; fe->sec_priv = lnbp21; /* bits which should be forced to '1' */ @@ -133,29 +126,11 @@ static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe, /* override frontend ops */ fe->ops.set_voltage = lnbp21_set_voltage; fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; - printk(KERN_INFO "LNBx2x attached on addr=%x", lnbp21->i2c_addr); return fe; } - -struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, u8 override_set, - u8 override_clear, u8 i2c_addr) -{ - return lnbx2x_attach(fe, i2c, override_set, override_clear, - i2c_addr, LNBH24_TTX); -} -EXPORT_SYMBOL(lnbh24_attach); - -struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, u8 override_set, - u8 override_clear) -{ - return lnbx2x_attach(fe, i2c, override_set, override_clear, - 0x08, LNBP21_ISEL); -} EXPORT_SYMBOL(lnbp21_attach); -MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24"); -MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin"); +MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21"); +MODULE_AUTHOR("Oliver Endriss"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/frontends/lnbp21.h b/trunk/drivers/media/dvb/frontends/lnbp21.h index fcdf1c650dde..8fe094bd9689 100644 --- a/trunk/drivers/media/dvb/frontends/lnbp21.h +++ b/trunk/drivers/media/dvb/frontends/lnbp21.h @@ -28,48 +28,26 @@ #define _LNBP21_H /* system register bits */ -/* [RO] 0=OK; 1=over current limit flag */ #define LNBP21_OLF 0x01 -/* [RO] 0=OK; 1=over temperature flag (150 C) */ #define LNBP21_OTF 0x02 -/* [RW] 0=disable LNB power, enable loopthrough - 1=enable LNB power, disable loopthrough */ #define LNBP21_EN 0x04 -/* [RW] 0=low voltage (13/14V, vert pol) - 1=high voltage (18/19V,horiz pol) */ #define LNBP21_VSEL 0x08 -/* [RW] increase LNB voltage by 1V: - 0=13/18V; 1=14/19V */ #define LNBP21_LLC 0x10 -/* [RW] 0=tone controlled by DSQIN pin - 1=tone enable, disable DSQIN */ #define LNBP21_TEN 0x20 -/* [RW] current limit select: - 0:Iout=500-650mA Isc=300mA - 1:Iout=400-550mA Isc=200mA */ #define LNBP21_ISEL 0x40 -/* [RW] short-circuit protect: - 0=pulsed (dynamic) curr limiting - 1=static curr limiting */ #define LNBP21_PCL 0x80 #include -#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \ - && defined(MODULE)) -/* override_set and override_clear control which - system register bits (above) to always set & clear */ -extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, u8 override_set, - u8 override_clear); +#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) && defined(MODULE)) +/* override_set and override_clear control which system register bits (above) to always set & clear */ +extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear); #else -static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, u8 override_set, - u8 override_clear) +static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } -#endif +#endif // CONFIG_DVB_LNBP21 -#endif +#endif // _LNBP21_H diff --git a/trunk/drivers/media/dvb/frontends/s921_module.c b/trunk/drivers/media/dvb/frontends/s921_module.c index 3f5a0e1dfdf5..892af8c9ed57 100644 --- a/trunk/drivers/media/dvb/frontends/s921_module.c +++ b/trunk/drivers/media/dvb/frontends/s921_module.c @@ -169,6 +169,7 @@ struct dvb_frontend* s921_attach(const struct s921_config *config, struct s921_state *state; state = kzalloc(sizeof(struct s921_state), GFP_KERNEL); + memset(state, 0x0, sizeof(struct s921_state)); state->addr = config->i2c_address; state->i2c = i2c; diff --git a/trunk/drivers/media/dvb/frontends/stb6100_cfg.h b/trunk/drivers/media/dvb/frontends/stb6100_cfg.h index 6314d18c797a..d3133405dc03 100644 --- a/trunk/drivers/media/dvb/frontends/stb6100_cfg.h +++ b/trunk/drivers/media/dvb/frontends/stb6100_cfg.h @@ -36,6 +36,7 @@ static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency) return err; } *frequency = t_state.frequency; + printk("%s: Frequency=%d\n", __func__, t_state.frequency); } return 0; } @@ -58,6 +59,7 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency) return err; } } + printk("%s: Frequency=%d\n", __func__, t_state.frequency); return 0; } @@ -79,6 +81,7 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) } *bandwidth = t_state.bandwidth; } + printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth); return 0; } @@ -100,5 +103,6 @@ static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) return err; } } + printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth); return 0; } diff --git a/trunk/drivers/media/dvb/frontends/stv0900.h b/trunk/drivers/media/dvb/frontends/stv0900.h deleted file mode 100644 index 8a1332c2031d..000000000000 --- a/trunk/drivers/media/dvb/frontends/stv0900.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * stv0900.h - * - * Driver for ST STV0900 satellite demodulator IC. - * - * Copyright (C) ST Microelectronics. - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef STV0900_H -#define STV0900_H - -#include -#include "dvb_frontend.h" - -struct stv0900_config { - u8 demod_address; - u32 xtal; - u8 clkmode;/* 0 for CLKI, 2 for XTALI */ - - u8 diseqc_mode; - - u8 path1_mode; - u8 path2_mode; - - u8 tun1_maddress;/* 0, 1, 2, 3 for 0xc0, 0xc2, 0xc4, 0xc6 */ - u8 tun2_maddress; - u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */ - u8 tun2_adc; -}; - -#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \ - && defined(MODULE)) -extern struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, - struct i2c_adapter *i2c, int demod); -#else -static inline struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, - struct i2c_adapter *i2c, int demod) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif - diff --git a/trunk/drivers/media/dvb/frontends/stv0900_core.c b/trunk/drivers/media/dvb/frontends/stv0900_core.c deleted file mode 100644 index 8499bcf7f251..000000000000 --- a/trunk/drivers/media/dvb/frontends/stv0900_core.c +++ /dev/null @@ -1,1949 +0,0 @@ -/* - * stv0900_core.c - * - * Driver for ST STV0900 satellite demodulator IC. - * - * Copyright (C) ST Microelectronics. - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include - -#include "stv0900.h" -#include "stv0900_reg.h" -#include "stv0900_priv.h" -#include "stv0900_init.h" - -static int stvdebug = 1; -module_param_named(debug, stvdebug, int, 0644); - -/* internal params node */ -struct stv0900_inode { - /* pointer for internal params, one for each pair of demods */ - struct stv0900_internal *internal; - struct stv0900_inode *next_inode; -}; - -/* first internal params */ -static struct stv0900_inode *stv0900_first_inode; - -/* find chip by i2c adapter and i2c address */ -static struct stv0900_inode *find_inode(struct i2c_adapter *i2c_adap, - u8 i2c_addr) -{ - struct stv0900_inode *temp_chip = stv0900_first_inode; - - if (temp_chip != NULL) { - /* - Search of the last stv0900 chip or - find it by i2c adapter and i2c address */ - while ((temp_chip != NULL) && - ((temp_chip->internal->i2c_adap != i2c_adap) || - (temp_chip->internal->i2c_addr != i2c_addr))) - - temp_chip = temp_chip->next_inode; - - } - - return temp_chip; -} - -/* deallocating chip */ -static void remove_inode(struct stv0900_internal *internal) -{ - struct stv0900_inode *prev_node = stv0900_first_inode; - struct stv0900_inode *del_node = find_inode(internal->i2c_adap, - internal->i2c_addr); - - if (del_node != NULL) { - if (del_node == stv0900_first_inode) { - stv0900_first_inode = del_node->next_inode; - } else { - while (prev_node->next_inode != del_node) - prev_node = prev_node->next_inode; - - if (del_node->next_inode == NULL) - prev_node->next_inode = NULL; - else - prev_node->next_inode = - prev_node->next_inode->next_inode; - } - - kfree(del_node); - } -} - -/* allocating new chip */ -static struct stv0900_inode *append_internal(struct stv0900_internal *internal) -{ - struct stv0900_inode *new_node = stv0900_first_inode; - - if (new_node == NULL) { - new_node = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL); - stv0900_first_inode = new_node; - } else { - while (new_node->next_inode != NULL) - new_node = new_node->next_inode; - - new_node->next_inode = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL); - if (new_node->next_inode != NULL) - new_node = new_node->next_inode; - else - new_node = NULL; - } - - if (new_node != NULL) { - new_node->internal = internal; - new_node->next_inode = NULL; - } - - return new_node; -} - -s32 ge2comp(s32 a, s32 width) -{ - if (width == 32) - return a; - else - return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a; -} - -void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr, - u8 reg_data) -{ - u8 data[3]; - int ret; - struct i2c_msg i2cmsg = { - .addr = i_params->i2c_addr, - .flags = 0, - .len = 3, - .buf = data, - }; - - data[0] = MSB(reg_addr); - data[1] = LSB(reg_addr); - data[2] = reg_data; - - ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1); - if (ret != 1) - dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret); -} - -u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg_addr) -{ - u8 data[2]; - int ret; - struct i2c_msg i2cmsg = { - .addr = i_params->i2c_addr, - .flags = 0, - .len = 2, - .buf = data, - }; - - data[0] = MSB(reg_addr); - data[1] = LSB(reg_addr); - - ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1); - if (ret != 1) - dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret); - - i2cmsg.flags = I2C_M_RD; - i2cmsg.len = 1; - ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1); - if (ret != 1) - dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret); - - return data[0]; -} - -void extract_mask_pos(u32 label, u8 *mask, u8 *pos) -{ - u8 position = 0, i = 0; - - (*mask) = label & 0xff; - - while ((position == 0) && (i < 8)) { - position = ((*mask) >> i) & 0x01; - i++; - } - - (*pos) = (i - 1); -} - -void stv0900_write_bits(struct stv0900_internal *i_params, u32 label, u8 val) -{ - u8 reg, mask, pos; - - reg = stv0900_read_reg(i_params, (label >> 16) & 0xffff); - extract_mask_pos(label, &mask, &pos); - - val = mask & (val << pos); - - reg = (reg & (~mask)) | val; - stv0900_write_reg(i_params, (label >> 16) & 0xffff, reg); - -} - -u8 stv0900_get_bits(struct stv0900_internal *i_params, u32 label) -{ - u8 val = 0xff; - u8 mask, pos; - - extract_mask_pos(label, &mask, &pos); - - val = stv0900_read_reg(i_params, label >> 16); - val = (val & mask) >> pos; - - return val; -} - -enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *i_params) -{ - s32 i; - enum fe_stv0900_error error; - - if (i_params != NULL) { - i_params->chip_id = stv0900_read_reg(i_params, R0900_MID); - if (i_params->errs == STV0900_NO_ERROR) { - /*Startup sequence*/ - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5c); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5c); - stv0900_write_reg(i_params, R0900_P1_TNRCFG, 0x6c); - stv0900_write_reg(i_params, R0900_P2_TNRCFG, 0x6f); - stv0900_write_reg(i_params, R0900_P1_I2CRPT, 0x24); - stv0900_write_reg(i_params, R0900_P2_I2CRPT, 0x24); - stv0900_write_reg(i_params, R0900_NCOARSE, 0x13); - msleep(3); - stv0900_write_reg(i_params, R0900_I2CCFG, 0x08); - - switch (i_params->clkmode) { - case 0: - case 2: - stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20 - | i_params->clkmode); - break; - default: - /* preserve SELOSCI bit */ - i = 0x02 & stv0900_read_reg(i_params, R0900_SYNTCTRL); - stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20 | i); - break; - } - - msleep(3); - for (i = 0; i < 182; i++) - stv0900_write_reg(i_params, STV0900_InitVal[i][0], STV0900_InitVal[i][1]); - - if (stv0900_read_reg(i_params, R0900_MID) >= 0x20) { - stv0900_write_reg(i_params, R0900_TSGENERAL, 0x0c); - for (i = 0; i < 32; i++) - stv0900_write_reg(i_params, STV0900_Cut20_AddOnVal[i][0], STV0900_Cut20_AddOnVal[i][1]); - } - - stv0900_write_reg(i_params, R0900_P1_FSPYCFG, 0x6c); - stv0900_write_reg(i_params, R0900_P2_FSPYCFG, 0x6c); - stv0900_write_reg(i_params, R0900_TSTRES0, 0x80); - stv0900_write_reg(i_params, R0900_TSTRES0, 0x00); - } - error = i_params->errs; - } else - error = STV0900_INVALID_HANDLE; - - return error; - -} - -u32 stv0900_get_mclk_freq(struct stv0900_internal *i_params, u32 ext_clk) -{ - u32 mclk = 90000000, div = 0, ad_div = 0; - - div = stv0900_get_bits(i_params, F0900_M_DIV); - ad_div = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6); - - mclk = (div + 1) * ext_clk / ad_div; - - dprintk(KERN_INFO "%s: Calculated Mclk = %d\n", __func__, mclk); - - return mclk; -} - -enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *i_params, u32 mclk) -{ - enum fe_stv0900_error error = STV0900_NO_ERROR; - u32 m_div, clk_sel; - - dprintk(KERN_INFO "%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, - i_params->quartz); - - if (i_params == NULL) - error = STV0900_INVALID_HANDLE; - else { - if (i_params->errs) - error = STV0900_I2C_ERROR; - else { - clk_sel = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6); - m_div = ((clk_sel * mclk) / i_params->quartz) - 1; - stv0900_write_bits(i_params, F0900_M_DIV, m_div); - i_params->mclk = stv0900_get_mclk_freq(i_params, - i_params->quartz); - - /*Set the DiseqC frequency to 22KHz */ - /* - Formula: - DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg) - DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg) - */ - m_div = i_params->mclk / 704000; - stv0900_write_reg(i_params, R0900_P1_F22TX, m_div); - stv0900_write_reg(i_params, R0900_P1_F22RX, m_div); - - stv0900_write_reg(i_params, R0900_P2_F22TX, m_div); - stv0900_write_reg(i_params, R0900_P2_F22RX, m_div); - - if ((i_params->errs)) - error = STV0900_I2C_ERROR; - } - } - - return error; -} - -u32 stv0900_get_err_count(struct stv0900_internal *i_params, int cntr, - enum fe_stv0900_demod_num demod) -{ - u32 lsb, msb, hsb, err_val; - s32 err1field_hsb, err1field_msb, err1field_lsb; - s32 err2field_hsb, err2field_msb, err2field_lsb; - - dmd_reg(err1field_hsb, F0900_P1_ERR_CNT12, F0900_P2_ERR_CNT12); - dmd_reg(err1field_msb, F0900_P1_ERR_CNT11, F0900_P2_ERR_CNT11); - dmd_reg(err1field_lsb, F0900_P1_ERR_CNT10, F0900_P2_ERR_CNT10); - - dmd_reg(err2field_hsb, F0900_P1_ERR_CNT22, F0900_P2_ERR_CNT22); - dmd_reg(err2field_msb, F0900_P1_ERR_CNT21, F0900_P2_ERR_CNT21); - dmd_reg(err2field_lsb, F0900_P1_ERR_CNT20, F0900_P2_ERR_CNT20); - - switch (cntr) { - case 0: - default: - hsb = stv0900_get_bits(i_params, err1field_hsb); - msb = stv0900_get_bits(i_params, err1field_msb); - lsb = stv0900_get_bits(i_params, err1field_lsb); - break; - case 1: - hsb = stv0900_get_bits(i_params, err2field_hsb); - msb = stv0900_get_bits(i_params, err2field_msb); - lsb = stv0900_get_bits(i_params, err2field_lsb); - break; - } - - err_val = (hsb << 16) + (msb << 8) + (lsb); - - return err_val; -} - -static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - - u32 fi2c; - - dmd_reg(fi2c, F0900_P1_I2CT_ON, F0900_P2_I2CT_ON); - if (enable) - stv0900_write_bits(i_params, fi2c, 1); - - return 0; -} - -static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params, - enum fe_stv0900_clock_type path1_ts, - enum fe_stv0900_clock_type path2_ts) -{ - - dprintk(KERN_INFO "%s\n", __func__); - - if (i_params->chip_id >= 0x20) { - switch (path1_ts) { - case STV0900_PARALLEL_PUNCT_CLOCK: - case STV0900_DVBCI_CLOCK: - switch (path2_ts) { - case STV0900_SERIAL_PUNCT_CLOCK: - case STV0900_SERIAL_CONT_CLOCK: - default: - stv0900_write_reg(i_params, R0900_TSGENERAL, - 0x00); - break; - case STV0900_PARALLEL_PUNCT_CLOCK: - case STV0900_DVBCI_CLOCK: - stv0900_write_reg(i_params, R0900_TSGENERAL, - 0x06); - stv0900_write_bits(i_params, - F0900_P1_TSFIFO_MANSPEED, 3); - stv0900_write_bits(i_params, - F0900_P2_TSFIFO_MANSPEED, 0); - stv0900_write_reg(i_params, - R0900_P1_TSSPEED, 0x14); - stv0900_write_reg(i_params, - R0900_P2_TSSPEED, 0x28); - break; - } - break; - case STV0900_SERIAL_PUNCT_CLOCK: - case STV0900_SERIAL_CONT_CLOCK: - default: - switch (path2_ts) { - case STV0900_SERIAL_PUNCT_CLOCK: - case STV0900_SERIAL_CONT_CLOCK: - default: - stv0900_write_reg(i_params, - R0900_TSGENERAL, 0x0C); - break; - case STV0900_PARALLEL_PUNCT_CLOCK: - case STV0900_DVBCI_CLOCK: - stv0900_write_reg(i_params, - R0900_TSGENERAL, 0x0A); - dprintk(KERN_INFO "%s: 0x0a\n", __func__); - break; - } - break; - } - } else { - switch (path1_ts) { - case STV0900_PARALLEL_PUNCT_CLOCK: - case STV0900_DVBCI_CLOCK: - switch (path2_ts) { - case STV0900_SERIAL_PUNCT_CLOCK: - case STV0900_SERIAL_CONT_CLOCK: - default: - stv0900_write_reg(i_params, R0900_TSGENERAL1X, - 0x10); - break; - case STV0900_PARALLEL_PUNCT_CLOCK: - case STV0900_DVBCI_CLOCK: - stv0900_write_reg(i_params, R0900_TSGENERAL1X, - 0x16); - stv0900_write_bits(i_params, - F0900_P1_TSFIFO_MANSPEED, 3); - stv0900_write_bits(i_params, - F0900_P2_TSFIFO_MANSPEED, 0); - stv0900_write_reg(i_params, R0900_P1_TSSPEED, - 0x14); - stv0900_write_reg(i_params, R0900_P2_TSSPEED, - 0x28); - break; - } - - break; - case STV0900_SERIAL_PUNCT_CLOCK: - case STV0900_SERIAL_CONT_CLOCK: - default: - switch (path2_ts) { - case STV0900_SERIAL_PUNCT_CLOCK: - case STV0900_SERIAL_CONT_CLOCK: - default: - stv0900_write_reg(i_params, R0900_TSGENERAL1X, - 0x14); - break; - case STV0900_PARALLEL_PUNCT_CLOCK: - case STV0900_DVBCI_CLOCK: - stv0900_write_reg(i_params, R0900_TSGENERAL1X, - 0x12); - dprintk(KERN_INFO "%s: 0x12\n", __func__); - break; - } - - break; - } - } - - switch (path1_ts) { - case STV0900_PARALLEL_PUNCT_CLOCK: - stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00); - stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00); - break; - case STV0900_DVBCI_CLOCK: - stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00); - stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01); - break; - case STV0900_SERIAL_PUNCT_CLOCK: - stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01); - stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00); - break; - case STV0900_SERIAL_CONT_CLOCK: - stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01); - stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01); - break; - default: - break; - } - - switch (path2_ts) { - case STV0900_PARALLEL_PUNCT_CLOCK: - stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00); - stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00); - break; - case STV0900_DVBCI_CLOCK: - stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00); - stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01); - break; - case STV0900_SERIAL_PUNCT_CLOCK: - stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01); - stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00); - break; - case STV0900_SERIAL_CONT_CLOCK: - stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01); - stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01); - break; - default: - break; - } - - stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1); - stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 0); - stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1); - stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 0); -} - -void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency, - u32 bandwidth) -{ - struct dvb_frontend_ops *frontend_ops = NULL; - struct dvb_tuner_ops *tuner_ops = NULL; - - if (&fe->ops) - frontend_ops = &fe->ops; - - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - - if (tuner_ops->set_frequency) { - if ((tuner_ops->set_frequency(fe, frequency)) < 0) - dprintk("%s: Invalid parameter\n", __func__); - else - dprintk("%s: Frequency=%d\n", __func__, frequency); - - } - - if (tuner_ops->set_bandwidth) { - if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0) - dprintk("%s: Invalid parameter\n", __func__); - else - dprintk("%s: Bandwidth=%d\n", __func__, bandwidth); - - } -} - -void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) -{ - struct dvb_frontend_ops *frontend_ops = NULL; - struct dvb_tuner_ops *tuner_ops = NULL; - - if (&fe->ops) - frontend_ops = &fe->ops; - - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - - if (tuner_ops->set_bandwidth) { - if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0) - dprintk("%s: Invalid parameter\n", __func__); - else - dprintk("%s: Bandwidth=%d\n", __func__, bandwidth); - - } -} - -static s32 stv0900_get_rf_level(struct stv0900_internal *i_params, - const struct stv0900_table *lookup, - enum fe_stv0900_demod_num demod) -{ - s32 agc_gain = 0, - imin, - imax, - i, - rf_lvl = 0; - - dprintk(KERN_INFO "%s\n", __func__); - - if ((lookup != NULL) && lookup->size) { - switch (demod) { - case STV0900_DEMOD_1: - default: - agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE1), - stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE0)); - break; - case STV0900_DEMOD_2: - agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE1), - stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE0)); - break; - } - - imin = 0; - imax = lookup->size - 1; - if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[imax].regval)) { - while ((imax - imin) > 1) { - i = (imax + imin) >> 1; - - if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[i].regval)) - imax = i; - else - imin = i; - } - - rf_lvl = (((s32)agc_gain - lookup->table[imin].regval) - * (lookup->table[imax].realval - lookup->table[imin].realval) - / (lookup->table[imax].regval - lookup->table[imin].regval)) - + lookup->table[imin].realval; - } else if (agc_gain > lookup->table[0].regval) - rf_lvl = 5; - else if (agc_gain < lookup->table[lookup->size-1].regval) - rf_lvl = -100; - - } - - dprintk(KERN_INFO "%s: RFLevel = %d\n", __func__, rf_lvl); - - return rf_lvl; -} - -static int stv0900_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *internal = state->internal; - s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf, - state->demod); - - *strength = (rflevel + 100) * (16383 / 105); - - return 0; -} - - -static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, - const struct stv0900_table *lookup) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - - s32 c_n = -100, - regval, imin, imax, - i, - lock_flag_field, - noise_field1, - noise_field0; - - dprintk(KERN_INFO "%s\n", __func__); - - dmd_reg(lock_flag_field, F0900_P1_LOCK_DEFINITIF, - F0900_P2_LOCK_DEFINITIF); - if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) { - dmd_reg(noise_field1, F0900_P1_NOSPLHT_NORMED1, - F0900_P2_NOSPLHT_NORMED1); - dmd_reg(noise_field0, F0900_P1_NOSPLHT_NORMED0, - F0900_P2_NOSPLHT_NORMED0); - } else { - dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1, - F0900_P2_NOSDATAT_NORMED1); - dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0, - F0900_P2_NOSDATAT_NORMED0); - } - - if (stv0900_get_bits(i_params, lock_flag_field)) { - if ((lookup != NULL) && lookup->size) { - regval = 0; - msleep(5); - for (i = 0; i < 16; i++) { - regval += MAKEWORD(stv0900_get_bits(i_params, - noise_field1), - stv0900_get_bits(i_params, - noise_field0)); - msleep(1); - } - - regval /= 16; - imin = 0; - imax = lookup->size - 1; - if (INRANGE(lookup->table[imin].regval, - regval, - lookup->table[imax].regval)) { - while ((imax - imin) > 1) { - i = (imax + imin) >> 1; - if (INRANGE(lookup->table[imin].regval, - regval, - lookup->table[i].regval)) - imax = i; - else - imin = i; - } - - c_n = ((regval - lookup->table[imin].regval) - * (lookup->table[imax].realval - - lookup->table[imin].realval) - / (lookup->table[imax].regval - - lookup->table[imin].regval)) - + lookup->table[imin].realval; - } else if (regval < lookup->table[imin].regval) - c_n = 1000; - } - } - - return c_n; -} - -static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - *snr = stv0900_carr_get_quality(fe, - (const struct stv0900_table *)&stv0900_s2_cn); - *snr += 30; - *snr *= (16383 / 1030); - - return 0; -} - -static u32 stv0900_get_ber(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - u32 ber = 10000000, i; - s32 dmd_state_reg; - s32 demod_state; - s32 vstatus_reg; - s32 prvit_field; - s32 pdel_status_reg; - s32 pdel_lock_field; - - dmd_reg(dmd_state_reg, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); - dmd_reg(vstatus_reg, R0900_P1_VSTATUSVIT, R0900_P2_VSTATUSVIT); - dmd_reg(prvit_field, F0900_P1_PRFVIT, F0900_P2_PRFVIT); - dmd_reg(pdel_status_reg, R0900_P1_PDELSTATUS1, R0900_P2_PDELSTATUS1); - dmd_reg(pdel_lock_field, F0900_P1_PKTDELIN_LOCK, - F0900_P2_PKTDELIN_LOCK); - - demod_state = stv0900_get_bits(i_params, dmd_state_reg); - - switch (demod_state) { - case STV0900_SEARCH: - case STV0900_PLH_DETECTED: - default: - ber = 10000000; - break; - case STV0900_DVBS_FOUND: - ber = 0; - for (i = 0; i < 5; i++) { - msleep(5); - ber += stv0900_get_err_count(i_params, 0, demod); - } - - ber /= 5; - if (stv0900_get_bits(i_params, prvit_field)) { - ber *= 9766; - ber = ber >> 13; - } - - break; - case STV0900_DVBS2_FOUND: - ber = 0; - for (i = 0; i < 5; i++) { - msleep(5); - ber += stv0900_get_err_count(i_params, 0, demod); - } - - ber /= 5; - if (stv0900_get_bits(i_params, pdel_lock_field)) { - ber *= 9766; - ber = ber >> 13; - } - - break; - } - - return ber; -} - -static int stv0900_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *internal = state->internal; - - *ber = stv0900_get_ber(internal, state->demod); - - return 0; -} - -int stv0900_get_demod_lock(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod, s32 time_out) -{ - s32 timer = 0, - lock = 0, - header_field, - lock_field; - - enum fe_stv0900_search_state dmd_state; - - dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); - dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF); - while ((timer < time_out) && (lock == 0)) { - dmd_state = stv0900_get_bits(i_params, header_field); - dprintk("Demod State = %d\n", dmd_state); - switch (dmd_state) { - case STV0900_SEARCH: - case STV0900_PLH_DETECTED: - default: - lock = 0; - break; - case STV0900_DVBS2_FOUND: - case STV0900_DVBS_FOUND: - lock = stv0900_get_bits(i_params, lock_field); - break; - } - - if (lock == 0) - msleep(10); - - timer += 10; - } - - if (lock) - dprintk("DEMOD LOCK OK\n"); - else - dprintk("DEMOD LOCK FAIL\n"); - - return lock; -} - -void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - s32 regflist, - i; - - dprintk(KERN_INFO "%s\n", __func__); - - dmd_reg(regflist, R0900_P1_MODCODLST0, R0900_P2_MODCODLST0); - - for (i = 0; i < 16; i++) - stv0900_write_reg(i_params, regflist + i, 0xff); -} - -void stv0900_activate_s2_modcode(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - u32 matype, - mod_code, - fmod, - reg_index, - field_index; - - dprintk(KERN_INFO "%s\n", __func__); - - if (i_params->chip_id <= 0x11) { - msleep(5); - - switch (demod) { - case STV0900_DEMOD_1: - default: - mod_code = stv0900_read_reg(i_params, - R0900_P1_PLHMODCOD); - matype = mod_code & 0x3; - mod_code = (mod_code & 0x7f) >> 2; - - reg_index = R0900_P1_MODCODLSTF - mod_code / 2; - field_index = mod_code % 2; - break; - case STV0900_DEMOD_2: - mod_code = stv0900_read_reg(i_params, - R0900_P2_PLHMODCOD); - matype = mod_code & 0x3; - mod_code = (mod_code & 0x7f) >> 2; - - reg_index = R0900_P2_MODCODLSTF - mod_code / 2; - field_index = mod_code % 2; - break; - } - - - switch (matype) { - case 0: - default: - fmod = 14; - break; - case 1: - fmod = 13; - break; - case 2: - fmod = 11; - break; - case 3: - fmod = 7; - break; - } - - if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910)) - && (matype <= 1)) { - if (field_index == 0) - stv0900_write_reg(i_params, reg_index, - 0xf0 | fmod); - else - stv0900_write_reg(i_params, reg_index, - (fmod << 4) | 0xf); - } - } else if (i_params->chip_id >= 0x12) { - switch (demod) { - case STV0900_DEMOD_1: - default: - for (reg_index = 0; reg_index < 7; reg_index++) - stv0900_write_reg(i_params, R0900_P1_MODCODLST0 + reg_index, 0xff); - - stv0900_write_reg(i_params, R0900_P1_MODCODLSTE, 0xff); - stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0xcf); - for (reg_index = 0; reg_index < 8; reg_index++) - stv0900_write_reg(i_params, R0900_P1_MODCODLST7 + reg_index, 0xcc); - - break; - case STV0900_DEMOD_2: - for (reg_index = 0; reg_index < 7; reg_index++) - stv0900_write_reg(i_params, R0900_P2_MODCODLST0 + reg_index, 0xff); - - stv0900_write_reg(i_params, R0900_P2_MODCODLSTE, 0xff); - stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0xcf); - for (reg_index = 0; reg_index < 8; reg_index++) - stv0900_write_reg(i_params, R0900_P2_MODCODLST7 + reg_index, 0xcc); - - break; - } - - } -} - -void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - u32 reg_index; - - dprintk(KERN_INFO "%s\n", __func__); - - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_reg(i_params, R0900_P1_MODCODLST0, 0xff); - stv0900_write_reg(i_params, R0900_P1_MODCODLST1, 0xf0); - stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0x0f); - for (reg_index = 0; reg_index < 13; reg_index++) - stv0900_write_reg(i_params, - R0900_P1_MODCODLST2 + reg_index, 0); - - break; - case STV0900_DEMOD_2: - stv0900_write_reg(i_params, R0900_P2_MODCODLST0, 0xff); - stv0900_write_reg(i_params, R0900_P2_MODCODLST1, 0xf0); - stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0x0f); - for (reg_index = 0; reg_index < 13; reg_index++) - stv0900_write_reg(i_params, - R0900_P2_MODCODLST2 + reg_index, 0); - - break; - } -} - -static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe) -{ - return DVBFE_ALGO_CUSTOM; -} - -static int stb0900_set_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - dprintk(KERN_INFO "%s(..)\n", __func__); - - return 0; -} - -static int stb0900_get_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - dprintk(KERN_INFO "%s(..)\n", __func__); - - return 0; -} - -void stv0900_start_search(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1f); - - if (i_params->chip_id == 0x10) - stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xaa); - - if (i_params->chip_id < 0x20) - stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55); - - if (i_params->dmd1_symbol_rate <= 5000000) { - stv0900_write_reg(i_params, R0900_P1_CARCFG, 0x44); - stv0900_write_reg(i_params, R0900_P1_CFRUP1, 0x0f); - stv0900_write_reg(i_params, R0900_P1_CFRUP0, 0xff); - stv0900_write_reg(i_params, R0900_P1_CFRLOW1, 0xf0); - stv0900_write_reg(i_params, R0900_P1_CFRLOW0, 0x00); - stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68); - } else { - stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xc4); - stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44); - } - - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0); - - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41); - stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41); - - if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) { - stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82); - stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0); - } - } - - stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00); - stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xe0); - stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xc0); - stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); - stv0900_write_bits(i_params, F0900_P1_S1S2_SEQUENTIAL, 0); - stv0900_write_reg(i_params, R0900_P1_RTC, 0x88); - if (i_params->chip_id >= 0x20) { - if (i_params->dmd1_symbol_rate < 2000000) { - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x39); - stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x40); - } - - if (i_params->dmd1_symbol_rate < 10000000) { - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4c); - stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20); - } else { - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4b); - stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20); - } - - } else { - if (i_params->dmd1_symbol_rate < 10000000) - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xef); - else - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed); - } - - switch (i_params->dmd1_srch_algo) { - case STV0900_WARM_START: - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); - break; - case STV0900_COLD_START: - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); - break; - default: - break; - } - - break; - case STV0900_DEMOD_2: - stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1f); - if (i_params->chip_id == 0x10) - stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xaa); - - if (i_params->chip_id < 0x20) - stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55); - - if (i_params->dmd2_symbol_rate <= 5000000) { - stv0900_write_reg(i_params, R0900_P2_CARCFG, 0x44); - stv0900_write_reg(i_params, R0900_P2_CFRUP1, 0x0f); - stv0900_write_reg(i_params, R0900_P2_CFRUP0, 0xff); - stv0900_write_reg(i_params, R0900_P2_CFRLOW1, 0xf0); - stv0900_write_reg(i_params, R0900_P2_CFRLOW0, 0x00); - stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68); - } else { - stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xc4); - stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44); - } - - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0); - - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41); - stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41); - if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) { - stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82); - stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0); - } - } - - stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00); - stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xe0); - stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xc0); - stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); - stv0900_write_bits(i_params, F0900_P2_S1S2_SEQUENTIAL, 0); - stv0900_write_reg(i_params, R0900_P2_RTC, 0x88); - if (i_params->chip_id >= 0x20) { - if (i_params->dmd2_symbol_rate < 2000000) { - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x39); - stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x40); - } - - if (i_params->dmd2_symbol_rate < 10000000) { - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4c); - stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20); - } else { - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4b); - stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20); - } - - } else { - if (i_params->dmd2_symbol_rate < 10000000) - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xef); - else - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed); - } - - switch (i_params->dmd2_srch_algo) { - case STV0900_WARM_START: - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); - break; - case STV0900_COLD_START: - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); - break; - default: - break; - } - - break; - } -} - -u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode, - s32 pilot, u8 chip_id) -{ - u8 aclc_value = 0x29; - s32 i; - const struct stv0900_car_loop_optim *car_loop_s2; - - dprintk(KERN_INFO "%s\n", __func__); - - if (chip_id <= 0x12) - car_loop_s2 = FE_STV0900_S2CarLoop; - else if (chip_id == 0x20) - car_loop_s2 = FE_STV0900_S2CarLoopCut20; - else - car_loop_s2 = FE_STV0900_S2CarLoop; - - if (modcode < STV0900_QPSK_12) { - i = 0; - while ((i < 3) && (modcode != FE_STV0900_S2LowQPCarLoopCut20[i].modcode)) - i++; - - if (i >= 3) - i = 2; - } else { - i = 0; - while ((i < 14) && (modcode != car_loop_s2[i].modcode)) - i++; - - if (i >= 14) { - i = 0; - while ((i < 11) && (modcode != FE_STV0900_S2APSKCarLoopCut20[i].modcode)) - i++; - - if (i >= 11) - i = 10; - } - } - - if (modcode <= STV0900_QPSK_25) { - if (pilot) { - if (srate <= 3000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_2; - else if (srate <= 7000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_5; - else if (srate <= 15000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_10; - else if (srate <= 25000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_20; - else - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_30; - } else { - if (srate <= 3000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_2; - else if (srate <= 7000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_5; - else if (srate <= 15000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_10; - else if (srate <= 25000000) - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_20; - else - aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_30; - } - - } else if (modcode <= STV0900_8PSK_910) { - if (pilot) { - if (srate <= 3000000) - aclc_value = car_loop_s2[i].car_loop_pilots_on_2; - else if (srate <= 7000000) - aclc_value = car_loop_s2[i].car_loop_pilots_on_5; - else if (srate <= 15000000) - aclc_value = car_loop_s2[i].car_loop_pilots_on_10; - else if (srate <= 25000000) - aclc_value = car_loop_s2[i].car_loop_pilots_on_20; - else - aclc_value = car_loop_s2[i].car_loop_pilots_on_30; - } else { - if (srate <= 3000000) - aclc_value = car_loop_s2[i].car_loop_pilots_off_2; - else if (srate <= 7000000) - aclc_value = car_loop_s2[i].car_loop_pilots_off_5; - else if (srate <= 15000000) - aclc_value = car_loop_s2[i].car_loop_pilots_off_10; - else if (srate <= 25000000) - aclc_value = car_loop_s2[i].car_loop_pilots_off_20; - else - aclc_value = car_loop_s2[i].car_loop_pilots_off_30; - } - - } else { - if (srate <= 3000000) - aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_2; - else if (srate <= 7000000) - aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_5; - else if (srate <= 15000000) - aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_10; - else if (srate <= 25000000) - aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_20; - else - aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_30; - } - - return aclc_value; -} - -u8 stv0900_get_optim_short_carr_loop(s32 srate, enum fe_stv0900_modulation modulation, u8 chip_id) -{ - s32 mod_index = 0; - - u8 aclc_value = 0x0b; - - dprintk(KERN_INFO "%s\n", __func__); - - switch (modulation) { - case STV0900_QPSK: - default: - mod_index = 0; - break; - case STV0900_8PSK: - mod_index = 1; - break; - case STV0900_16APSK: - mod_index = 2; - break; - case STV0900_32APSK: - mod_index = 3; - break; - } - - switch (chip_id) { - case 0x20: - if (srate <= 3000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_2; - else if (srate <= 7000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_5; - else if (srate <= 15000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_10; - else if (srate <= 25000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_20; - else - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_30; - - break; - case 0x12: - default: - if (srate <= 3000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_2; - else if (srate <= 7000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_5; - else if (srate <= 15000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_10; - else if (srate <= 25000000) - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_20; - else - aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_30; - - break; - } - - return aclc_value; -} - -static enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *i_params, - enum fe_stv0900_demod_mode LDPC_Mode, - enum fe_stv0900_demod_num demod) -{ - enum fe_stv0900_error error = STV0900_NO_ERROR; - - dprintk(KERN_INFO "%s\n", __func__); - - switch (LDPC_Mode) { - case STV0900_DUAL: - default: - if ((i_params->demod_mode != STV0900_DUAL) - || (stv0900_get_bits(i_params, F0900_DDEMOD) != 1)) { - stv0900_write_reg(i_params, R0900_GENCFG, 0x1d); - - i_params->demod_mode = STV0900_DUAL; - - stv0900_write_bits(i_params, F0900_FRESFEC, 1); - stv0900_write_bits(i_params, F0900_FRESFEC, 0); - } - - break; - case STV0900_SINGLE: - if (demod == STV0900_DEMOD_2) - stv0900_write_reg(i_params, R0900_GENCFG, 0x06); - else - stv0900_write_reg(i_params, R0900_GENCFG, 0x04); - - i_params->demod_mode = STV0900_SINGLE; - - stv0900_write_bits(i_params, F0900_FRESFEC, 1); - stv0900_write_bits(i_params, F0900_FRESFEC, 0); - stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1); - stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0); - stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1); - stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0); - break; - } - - return error; -} - -static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, - struct stv0900_init_params *p_init) -{ - struct stv0900_state *state = fe->demodulator_priv; - enum fe_stv0900_error error = STV0900_NO_ERROR; - enum fe_stv0900_error demodError = STV0900_NO_ERROR; - int selosci; - - struct stv0900_inode *temp_int = find_inode(state->i2c_adap, - state->config->demod_address); - - dprintk(KERN_INFO "%s\n", __func__); - - if (temp_int != NULL) { - state->internal = temp_int->internal; - (state->internal->dmds_used)++; - dprintk(KERN_INFO "%s: Find Internal Structure!\n", __func__); - return STV0900_NO_ERROR; - } else { - state->internal = kmalloc(sizeof(struct stv0900_internal), GFP_KERNEL); - temp_int = append_internal(state->internal); - state->internal->dmds_used = 1; - state->internal->i2c_adap = state->i2c_adap; - state->internal->i2c_addr = state->config->demod_address; - state->internal->clkmode = state->config->clkmode; - state->internal->errs = STV0900_NO_ERROR; - dprintk(KERN_INFO "%s: Create New Internal Structure!\n", __func__); - } - - if (state->internal != NULL) { - demodError = stv0900_initialize(state->internal); - if (demodError == STV0900_NO_ERROR) { - error = STV0900_NO_ERROR; - } else { - if (demodError == STV0900_INVALID_HANDLE) - error = STV0900_INVALID_HANDLE; - else - error = STV0900_I2C_ERROR; - } - - if (state->internal != NULL) { - if (error == STV0900_NO_ERROR) { - state->internal->demod_mode = p_init->demod_mode; - - stv0900_st_dvbs2_single(state->internal, state->internal->demod_mode, STV0900_DEMOD_1); - - state->internal->chip_id = stv0900_read_reg(state->internal, R0900_MID); - state->internal->rolloff = p_init->rolloff; - state->internal->quartz = p_init->dmd_ref_clk; - - stv0900_write_bits(state->internal, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff); - stv0900_write_bits(state->internal, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff); - - stv0900_set_ts_parallel_serial(state->internal, p_init->path1_ts_clock, p_init->path2_ts_clock); - stv0900_write_bits(state->internal, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress); - switch (p_init->tuner1_adc) { - case 1: - stv0900_write_reg(state->internal, R0900_TSTTNR1, 0x26); - break; - default: - break; - } - - stv0900_write_bits(state->internal, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress); - switch (p_init->tuner2_adc) { - case 1: - stv0900_write_reg(state->internal, R0900_TSTTNR3, 0x26); - break; - default: - break; - } - - stv0900_write_bits(state->internal, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inversion); - stv0900_write_bits(state->internal, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inversion); - stv0900_set_mclk(state->internal, 135000000); - msleep(3); - - switch (state->internal->clkmode) { - case 0: - case 2: - stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | state->internal->clkmode); - break; - default: - selosci = 0x02 & stv0900_read_reg(state->internal, R0900_SYNTCTRL); - stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | selosci); - break; - } - msleep(3); - - state->internal->mclk = stv0900_get_mclk_freq(state->internal, state->internal->quartz); - if (state->internal->errs) - error = STV0900_I2C_ERROR; - } - } else { - error = STV0900_INVALID_HANDLE; - } - } - - return error; -} - -static int stv0900_status(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - enum fe_stv0900_search_state demod_state; - s32 mode_field, delin_field, lock_field, fifo_field, lockedvit_field; - int locked = FALSE; - - dmd_reg(mode_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); - dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF); - dmd_reg(delin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK); - dmd_reg(fifo_field, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK); - dmd_reg(lockedvit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT); - - demod_state = stv0900_get_bits(i_params, mode_field); - switch (demod_state) { - case STV0900_SEARCH: - case STV0900_PLH_DETECTED: - default: - locked = FALSE; - break; - case STV0900_DVBS2_FOUND: - locked = stv0900_get_bits(i_params, lock_field) && - stv0900_get_bits(i_params, delin_field) && - stv0900_get_bits(i_params, fifo_field); - break; - case STV0900_DVBS_FOUND: - locked = stv0900_get_bits(i_params, lock_field) && - stv0900_get_bits(i_params, lockedvit_field) && - stv0900_get_bits(i_params, fifo_field); - break; - } - - return locked; -} - -static enum dvbfe_search stv0900_search(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - struct stv0900_search_params p_search; - struct stv0900_signal_info p_result; - - enum fe_stv0900_error error = STV0900_NO_ERROR; - - dprintk(KERN_INFO "%s: ", __func__); - - p_result.locked = FALSE; - p_search.path = state->demod; - p_search.frequency = c->frequency; - p_search.symbol_rate = c->symbol_rate; - p_search.search_range = 10000000; - p_search.fec = STV0900_FEC_UNKNOWN; - p_search.standard = STV0900_AUTO_SEARCH; - p_search.iq_inversion = STV0900_IQ_AUTO; - p_search.search_algo = STV0900_BLIND_SEARCH; - - if ((INRANGE(100000, p_search.symbol_rate, 70000000)) && - (INRANGE(100000, p_search.search_range, 50000000))) { - switch (p_search.path) { - case STV0900_DEMOD_1: - default: - i_params->dmd1_srch_standard = p_search.standard; - i_params->dmd1_symbol_rate = p_search.symbol_rate; - i_params->dmd1_srch_range = p_search.search_range; - i_params->tuner1_freq = p_search.frequency; - i_params->dmd1_srch_algo = p_search.search_algo; - i_params->dmd1_srch_iq_inv = p_search.iq_inversion; - i_params->dmd1_fec = p_search.fec; - break; - - case STV0900_DEMOD_2: - i_params->dmd2_srch_stndrd = p_search.standard; - i_params->dmd2_symbol_rate = p_search.symbol_rate; - i_params->dmd2_srch_range = p_search.search_range; - i_params->tuner2_freq = p_search.frequency; - i_params->dmd2_srch_algo = p_search.search_algo; - i_params->dmd2_srch_iq_inv = p_search.iq_inversion; - i_params->dmd2_fec = p_search.fec; - break; - } - - if ((stv0900_algo(fe) == STV0900_RANGEOK) && - (i_params->errs == STV0900_NO_ERROR)) { - switch (p_search.path) { - case STV0900_DEMOD_1: - default: - p_result.locked = i_params->dmd1_rslts.locked; - p_result.standard = i_params->dmd1_rslts.standard; - p_result.frequency = i_params->dmd1_rslts.frequency; - p_result.symbol_rate = i_params->dmd1_rslts.symbol_rate; - p_result.fec = i_params->dmd1_rslts.fec; - p_result.modcode = i_params->dmd1_rslts.modcode; - p_result.pilot = i_params->dmd1_rslts.pilot; - p_result.frame_length = i_params->dmd1_rslts.frame_length; - p_result.spectrum = i_params->dmd1_rslts.spectrum; - p_result.rolloff = i_params->dmd1_rslts.rolloff; - p_result.modulation = i_params->dmd1_rslts.modulation; - break; - case STV0900_DEMOD_2: - p_result.locked = i_params->dmd2_rslts.locked; - p_result.standard = i_params->dmd2_rslts.standard; - p_result.frequency = i_params->dmd2_rslts.frequency; - p_result.symbol_rate = i_params->dmd2_rslts.symbol_rate; - p_result.fec = i_params->dmd2_rslts.fec; - p_result.modcode = i_params->dmd2_rslts.modcode; - p_result.pilot = i_params->dmd2_rslts.pilot; - p_result.frame_length = i_params->dmd2_rslts.frame_length; - p_result.spectrum = i_params->dmd2_rslts.spectrum; - p_result.rolloff = i_params->dmd2_rslts.rolloff; - p_result.modulation = i_params->dmd2_rslts.modulation; - break; - } - - } else { - p_result.locked = FALSE; - switch (p_search.path) { - case STV0900_DEMOD_1: - switch (i_params->dmd1_err) { - case STV0900_I2C_ERROR: - error = STV0900_I2C_ERROR; - break; - case STV0900_NO_ERROR: - default: - error = STV0900_SEARCH_FAILED; - break; - } - break; - case STV0900_DEMOD_2: - switch (i_params->dmd2_err) { - case STV0900_I2C_ERROR: - error = STV0900_I2C_ERROR; - break; - case STV0900_NO_ERROR: - default: - error = STV0900_SEARCH_FAILED; - break; - } - break; - } - } - - } else - error = STV0900_BAD_PARAMETER; - - if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) { - dprintk(KERN_INFO "Search Success\n"); - return DVBFE_ALGO_SEARCH_SUCCESS; - } else { - dprintk(KERN_INFO "Search Fail\n"); - return DVBFE_ALGO_SEARCH_FAILED; - } - - return DVBFE_ALGO_SEARCH_ERROR; -} - -static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status) -{ - struct stv0900_state *state = fe->demodulator_priv; - - dprintk("%s: ", __func__); - - if ((stv0900_status(state->internal, state->demod)) == TRUE) { - dprintk("DEMOD LOCK OK\n"); - *status = FE_HAS_CARRIER - | FE_HAS_VITERBI - | FE_HAS_SYNC - | FE_HAS_LOCK; - } else - dprintk("DEMOD LOCK FAIL\n"); - - return 0; -} - -static int stv0900_track(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - return 0; -} - -static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts) -{ - - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - s32 rst_field; - - dmd_reg(rst_field, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE); - - if (stop_ts == TRUE) - stv0900_write_bits(i_params, rst_field, 1); - else - stv0900_write_bits(i_params, rst_field, 0); - - return 0; -} - -static int stv0900_diseqc_init(struct dvb_frontend *fe) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - s32 mode_field, reset_field; - - dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE); - dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET); - - stv0900_write_bits(i_params, mode_field, state->config->diseqc_mode); - stv0900_write_bits(i_params, reset_field, 1); - stv0900_write_bits(i_params, reset_field, 0); - - return 0; -} - -static int stv0900_init(struct dvb_frontend *fe) -{ - dprintk(KERN_INFO "%s\n", __func__); - - stv0900_stop_ts(fe, 1); - stv0900_diseqc_init(fe); - - return 0; -} - -static int stv0900_diseqc_send(struct stv0900_internal *i_params , u8 *Data, - u32 NbData, enum fe_stv0900_demod_num demod) -{ - s32 i = 0; - - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 1); - while (i < NbData) { - while (stv0900_get_bits(i_params, F0900_P1_FIFO_FULL)) - ;/* checkpatch complains */ - stv0900_write_reg(i_params, R0900_P1_DISTXDATA, Data[i]); - i++; - } - - stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 0); - i = 0; - while ((stv0900_get_bits(i_params, F0900_P1_TX_IDLE) != 1) && (i < 10)) { - msleep(10); - i++; - } - - break; - case STV0900_DEMOD_2: - stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 1); - - while (i < NbData) { - while (stv0900_get_bits(i_params, F0900_P2_FIFO_FULL)) - ;/* checkpatch complains */ - stv0900_write_reg(i_params, R0900_P2_DISTXDATA, Data[i]); - i++; - } - - stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 0); - i = 0; - while ((stv0900_get_bits(i_params, F0900_P2_TX_IDLE) != 1) && (i < 10)) { - msleep(10); - i++; - } - - break; - } - - return 0; -} - -static int stv0900_send_master_cmd(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *cmd) -{ - struct stv0900_state *state = fe->demodulator_priv; - - return stv0900_diseqc_send(state->internal, - cmd->msg, - cmd->msg_len, - state->demod); -} - -static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - s32 mode_field; - u32 diseqc_fifo; - - dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE); - dmd_reg(diseqc_fifo, R0900_P1_DISTXDATA, R0900_P2_DISTXDATA); - - switch (burst) { - case SEC_MINI_A: - stv0900_write_bits(i_params, mode_field, 3);/* Unmodulated */ - stv0900_write_reg(i_params, diseqc_fifo, 0x00); - break; - case SEC_MINI_B: - stv0900_write_bits(i_params, mode_field, 2);/* Modulated */ - stv0900_write_reg(i_params, diseqc_fifo, 0xff); - break; - } - - return 0; -} - -static int stv0900_recv_slave_reply(struct dvb_frontend *fe, - struct dvb_diseqc_slave_reply *reply) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - s32 i = 0; - - switch (state->demod) { - case STV0900_DEMOD_1: - default: - reply->msg_len = 0; - - while ((stv0900_get_bits(i_params, F0900_P1_RX_END) != 1) && (i < 10)) { - msleep(10); - i++; - } - - if (stv0900_get_bits(i_params, F0900_P1_RX_END)) { - reply->msg_len = stv0900_get_bits(i_params, F0900_P1_FIFO_BYTENBR); - - for (i = 0; i < reply->msg_len; i++) - reply->msg[i] = stv0900_read_reg(i_params, R0900_P1_DISRXDATA); - } - break; - case STV0900_DEMOD_2: - reply->msg_len = 0; - - while ((stv0900_get_bits(i_params, F0900_P2_RX_END) != 1) && (i < 10)) { - msleep(10); - i++; - } - - if (stv0900_get_bits(i_params, F0900_P2_RX_END)) { - reply->msg_len = stv0900_get_bits(i_params, F0900_P2_FIFO_BYTENBR); - - for (i = 0; i < reply->msg_len; i++) - reply->msg[i] = stv0900_read_reg(i_params, R0900_P2_DISRXDATA); - } - break; - } - - return 0; -} - -static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - s32 mode_field, reset_field; - - dprintk(KERN_INFO "%s: %s\n", __func__, ((tone == 0) ? "Off" : "On")); - - dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE); - dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET); - - if (tone) { - /*Set the DiseqC mode to 22Khz continues tone*/ - stv0900_write_bits(i_params, mode_field, 0); - stv0900_write_bits(i_params, reset_field, 1); - /*release DiseqC reset to enable the 22KHz tone*/ - stv0900_write_bits(i_params, reset_field, 0); - } else { - stv0900_write_bits(i_params, mode_field, 0); - /*maintain the DiseqC reset to disable the 22KHz tone*/ - stv0900_write_bits(i_params, reset_field, 1); - } - - return 0; -} - -static void stv0900_release(struct dvb_frontend *fe) -{ - struct stv0900_state *state = fe->demodulator_priv; - - dprintk(KERN_INFO "%s\n", __func__); - - if ((--(state->internal->dmds_used)) <= 0) { - - dprintk(KERN_INFO "%s: Actually removing\n", __func__); - - remove_inode(state->internal); - kfree(state->internal); - } - - kfree(state); -} - -static struct dvb_frontend_ops stv0900_ops = { - - .info = { - .name = "STV0900 frontend", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, - .frequency_tolerance = 0, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 500, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | - FE_CAN_FEC_7_8 | FE_CAN_QPSK | - FE_CAN_2G_MODULATION | - FE_CAN_FEC_AUTO - }, - .release = stv0900_release, - .init = stv0900_init, - .get_frontend_algo = stv0900_frontend_algo, - .i2c_gate_ctrl = stv0900_i2c_gate_ctrl, - .diseqc_send_master_cmd = stv0900_send_master_cmd, - .diseqc_send_burst = stv0900_send_burst, - .diseqc_recv_slave_reply = stv0900_recv_slave_reply, - .set_tone = stv0900_set_tone, - .set_property = stb0900_set_property, - .get_property = stb0900_get_property, - .search = stv0900_search, - .track = stv0900_track, - .read_status = stv0900_read_status, - .read_ber = stv0900_read_ber, - .read_signal_strength = stv0900_read_signal_strength, - .read_snr = stv0900_read_snr, -}; - -struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, - struct i2c_adapter *i2c, - int demod) -{ - struct stv0900_state *state = NULL; - struct stv0900_init_params init_params; - enum fe_stv0900_error err_stv0900; - - state = kzalloc(sizeof(struct stv0900_state), GFP_KERNEL); - if (state == NULL) - goto error; - - state->demod = demod; - state->config = config; - state->i2c_adap = i2c; - - memcpy(&state->frontend.ops, &stv0900_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - switch (demod) { - case 0: - case 1: - init_params.dmd_ref_clk = config->xtal; - init_params.demod_mode = STV0900_DUAL; - init_params.rolloff = STV0900_35; - init_params.path1_ts_clock = config->path1_mode; - init_params.tun1_maddress = config->tun1_maddress; - init_params.tun1_iq_inversion = STV0900_IQ_NORMAL; - init_params.tuner1_adc = config->tun1_adc; - init_params.path2_ts_clock = config->path2_mode; - init_params.tun2_maddress = config->tun2_maddress; - init_params.tuner2_adc = config->tun2_adc; - init_params.tun2_iq_inversion = STV0900_IQ_SWAPPED; - - err_stv0900 = stv0900_init_internal(&state->frontend, - &init_params); - - if (err_stv0900) - goto error; - - break; - default: - goto error; - break; - } - - dprintk("%s: Attaching STV0900 demodulator(%d) \n", __func__, demod); - return &state->frontend; - -error: - dprintk("%s: Failed to attach STV0900 demodulator(%d) \n", - __func__, demod); - kfree(state); - return NULL; -} -EXPORT_SYMBOL(stv0900_attach); - -MODULE_PARM_DESC(debug, "Set debug"); - -MODULE_AUTHOR("Igor M. Liplianin"); -MODULE_DESCRIPTION("ST STV0900 frontend"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/frontends/stv0900_init.h b/trunk/drivers/media/dvb/frontends/stv0900_init.h deleted file mode 100644 index ff388b47a4e3..000000000000 --- a/trunk/drivers/media/dvb/frontends/stv0900_init.h +++ /dev/null @@ -1,441 +0,0 @@ -/* - * stv0900_init.h - * - * Driver for ST STV0900 satellite demodulator IC. - * - * Copyright (C) ST Microelectronics. - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef STV0900_INIT_H -#define STV0900_INIT_H - -#include "stv0900_priv.h" - -/* DVBS2 C/N Look-Up table */ -static const struct stv0900_table stv0900_s2_cn = { - 55, - { - { -30, 13348 }, /*C/N=-3dB*/ - { -20, 12640 }, /*C/N=-2dB*/ - { -10, 11883 }, /*C/N=-1dB*/ - { 0, 11101 }, /*C/N=-0dB*/ - { 5, 10718 }, /*C/N=0.5dB*/ - { 10, 10339 }, /*C/N=1.0dB*/ - { 15, 9947 }, /*C/N=1.5dB*/ - { 20, 9552 }, /*C/N=2.0dB*/ - { 25, 9183 }, /*C/N=2.5dB*/ - { 30, 8799 }, /*C/N=3.0dB*/ - { 35, 8422 }, /*C/N=3.5dB*/ - { 40, 8062 }, /*C/N=4.0dB*/ - { 45, 7707 }, /*C/N=4.5dB*/ - { 50, 7353 }, /*C/N=5.0dB*/ - { 55, 7025 }, /*C/N=5.5dB*/ - { 60, 6684 }, /*C/N=6.0dB*/ - { 65, 6331 }, /*C/N=6.5dB*/ - { 70, 6036 }, /*C/N=7.0dB*/ - { 75, 5727 }, /*C/N=7.5dB*/ - { 80, 5437 }, /*C/N=8.0dB*/ - { 85, 5164 }, /*C/N=8.5dB*/ - { 90, 4902 }, /*C/N=9.0dB*/ - { 95, 4653 }, /*C/N=9.5dB*/ - { 100, 4408 }, /*C/N=10.0dB*/ - { 105, 4187 }, /*C/N=10.5dB*/ - { 110, 3961 }, /*C/N=11.0dB*/ - { 115, 3751 }, /*C/N=11.5dB*/ - { 120, 3558 }, /*C/N=12.0dB*/ - { 125, 3368 }, /*C/N=12.5dB*/ - { 130, 3191 }, /*C/N=13.0dB*/ - { 135, 3017 }, /*C/N=13.5dB*/ - { 140, 2862 }, /*C/N=14.0dB*/ - { 145, 2710 }, /*C/N=14.5dB*/ - { 150, 2565 }, /*C/N=15.0dB*/ - { 160, 2300 }, /*C/N=16.0dB*/ - { 170, 2058 }, /*C/N=17.0dB*/ - { 180, 1849 }, /*C/N=18.0dB*/ - { 190, 1663 }, /*C/N=19.0dB*/ - { 200, 1495 }, /*C/N=20.0dB*/ - { 210, 1349 }, /*C/N=21.0dB*/ - { 220, 1222 }, /*C/N=22.0dB*/ - { 230, 1110 }, /*C/N=23.0dB*/ - { 240, 1011 }, /*C/N=24.0dB*/ - { 250, 925 }, /*C/N=25.0dB*/ - { 260, 853 }, /*C/N=26.0dB*/ - { 270, 789 }, /*C/N=27.0dB*/ - { 280, 734 }, /*C/N=28.0dB*/ - { 290, 690 }, /*C/N=29.0dB*/ - { 300, 650 }, /*C/N=30.0dB*/ - { 310, 619 }, /*C/N=31.0dB*/ - { 320, 593 }, /*C/N=32.0dB*/ - { 330, 571 }, /*C/N=33.0dB*/ - { 400, 498 }, /*C/N=40.0dB*/ - { 450, 484 }, /*C/N=45.0dB*/ - { 500, 481 } /*C/N=50.0dB*/ - } -}; - -/* RF level C/N Look-Up table */ -static const struct stv0900_table stv0900_rf = { - 14, - { - { -5, 0xCAA1 }, /*-5dBm*/ - { -10, 0xC229 }, /*-10dBm*/ - { -15, 0xBB08 }, /*-15dBm*/ - { -20, 0xB4BC }, /*-20dBm*/ - { -25, 0xAD5A }, /*-25dBm*/ - { -30, 0xA298 }, /*-30dBm*/ - { -35, 0x98A8 }, /*-35dBm*/ - { -40, 0x8389 }, /*-40dBm*/ - { -45, 0x59BE }, /*-45dBm*/ - { -50, 0x3A14 }, /*-50dBm*/ - { -55, 0x2D11 }, /*-55dBm*/ - { -60, 0x210D }, /*-60dBm*/ - { -65, 0xA14F }, /*-65dBm*/ - { -70, 0x7AA } /*-70dBm*/ - } -}; - -struct stv0900_car_loop_optim { - enum fe_stv0900_modcode modcode; - u8 car_loop_pilots_on_2; - u8 car_loop_pilots_off_2; - u8 car_loop_pilots_on_5; - u8 car_loop_pilots_off_5; - u8 car_loop_pilots_on_10; - u8 car_loop_pilots_off_10; - u8 car_loop_pilots_on_20; - u8 car_loop_pilots_off_20; - u8 car_loop_pilots_on_30; - u8 car_loop_pilots_off_30; - -}; - -struct stv0900_short_frames_car_loop_optim { - enum fe_stv0900_modulation modulation; - u8 car_loop_cut12_2; /* Cut 1.2, SR<=3msps */ - u8 car_loop_cut20_2; /* Cut 2.0, SR<3msps */ - u8 car_loop_cut12_5; /* Cut 1.2, 3 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef STV0900_PRIV_H -#define STV0900_PRIV_H - -#include - -#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X)) -#define INRANGE(X, Y, Z) ((((X) <= (Y)) && ((Y) <= (Z))) \ - || (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0) - -#ifndef MAKEWORD -#define MAKEWORD(X, Y) (((X) << 8) + (Y)) -#endif - -#define LSB(X) (((X) & 0xFF)) -#define MSB(Y) (((Y) >> 8) & 0xFF) - -#ifndef TRUE -#define TRUE (1 == 1) -#endif -#ifndef FALSE -#define FALSE (!TRUE) -#endif - -#define dmd_reg(a, b, c) \ - do { \ - a = 0; \ - switch (demod) { \ - case STV0900_DEMOD_1: \ - default: \ - a = b; \ - break; \ - case STV0900_DEMOD_2: \ - a = c; \ - break; \ - } \ - } while (0) - -#define dmd_choose(a, b) (demod = STV0900_DEMOD_2 ? b : a)) - -static int stvdebug; - -#define dprintk(args...) \ - do { \ - if (stvdebug) \ - printk(KERN_DEBUG args); \ - } while (0) - -#define STV0900_MAXLOOKUPSIZE 500 -#define STV0900_BLIND_SEARCH_AGC2_TH 700 - -/* One point of the lookup table */ -struct stv000_lookpoint { - s32 realval;/* real value */ - s32 regval;/* binary value */ -}; - -/* Lookup table definition */ -struct stv0900_table{ - s32 size;/* Size of the lookup table */ - struct stv000_lookpoint table[STV0900_MAXLOOKUPSIZE];/* Lookup table */ -}; - -enum fe_stv0900_error { - STV0900_NO_ERROR = 0, - STV0900_INVALID_HANDLE, - STV0900_BAD_PARAMETER, - STV0900_I2C_ERROR, - STV0900_SEARCH_FAILED, -}; - -enum fe_stv0900_clock_type { - STV0900_USE_REGISTERS_DEFAULT, - STV0900_SERIAL_PUNCT_CLOCK,/*Serial punctured clock */ - STV0900_SERIAL_CONT_CLOCK,/*Serial continues clock */ - STV0900_PARALLEL_PUNCT_CLOCK,/*Parallel punctured clock */ - STV0900_DVBCI_CLOCK/*Parallel continues clock : DVBCI */ -}; - -enum fe_stv0900_search_state { - STV0900_SEARCH = 0, - STV0900_PLH_DETECTED, - STV0900_DVBS2_FOUND, - STV0900_DVBS_FOUND - -}; - -enum fe_stv0900_ldpc_state { - STV0900_PATH1_OFF_PATH2_OFF = 0, - STV0900_PATH1_ON_PATH2_OFF = 1, - STV0900_PATH1_OFF_PATH2_ON = 2, - STV0900_PATH1_ON_PATH2_ON = 3 -}; - -enum fe_stv0900_signal_type { - STV0900_NOAGC1 = 0, - STV0900_AGC1OK, - STV0900_NOTIMING, - STV0900_ANALOGCARRIER, - STV0900_TIMINGOK, - STV0900_NOAGC2, - STV0900_AGC2OK, - STV0900_NOCARRIER, - STV0900_CARRIEROK, - STV0900_NODATA, - STV0900_DATAOK, - STV0900_OUTOFRANGE, - STV0900_RANGEOK -}; - -enum fe_stv0900_demod_num { - STV0900_DEMOD_1, - STV0900_DEMOD_2 -}; - -enum fe_stv0900_tracking_standard { - STV0900_DVBS1_STANDARD,/* Found Standard*/ - STV0900_DVBS2_STANDARD, - STV0900_DSS_STANDARD, - STV0900_TURBOCODE_STANDARD, - STV0900_UNKNOWN_STANDARD -}; - -enum fe_stv0900_search_standard { - STV0900_AUTO_SEARCH, - STV0900_SEARCH_DVBS1,/* Search Standard*/ - STV0900_SEARCH_DVBS2, - STV0900_SEARCH_DSS, - STV0900_SEARCH_TURBOCODE -}; - -enum fe_stv0900_search_algo { - STV0900_BLIND_SEARCH,/* offset freq and SR are Unknown */ - STV0900_COLD_START,/* only the SR is known */ - STV0900_WARM_START/* offset freq and SR are known */ -}; - -enum fe_stv0900_modulation { - STV0900_QPSK, - STV0900_8PSK, - STV0900_16APSK, - STV0900_32APSK, - STV0900_UNKNOWN -}; - -enum fe_stv0900_modcode { - STV0900_DUMMY_PLF, - STV0900_QPSK_14, - STV0900_QPSK_13, - STV0900_QPSK_25, - STV0900_QPSK_12, - STV0900_QPSK_35, - STV0900_QPSK_23, - STV0900_QPSK_34, - STV0900_QPSK_45, - STV0900_QPSK_56, - STV0900_QPSK_89, - STV0900_QPSK_910, - STV0900_8PSK_35, - STV0900_8PSK_23, - STV0900_8PSK_34, - STV0900_8PSK_56, - STV0900_8PSK_89, - STV0900_8PSK_910, - STV0900_16APSK_23, - STV0900_16APSK_34, - STV0900_16APSK_45, - STV0900_16APSK_56, - STV0900_16APSK_89, - STV0900_16APSK_910, - STV0900_32APSK_34, - STV0900_32APSK_45, - STV0900_32APSK_56, - STV0900_32APSK_89, - STV0900_32APSK_910, - STV0900_MODCODE_UNKNOWN -}; - -enum fe_stv0900_fec {/*DVBS1, DSS and turbo code puncture rate*/ - STV0900_FEC_1_2 = 0, - STV0900_FEC_2_3, - STV0900_FEC_3_4, - STV0900_FEC_4_5,/*for turbo code only*/ - STV0900_FEC_5_6, - STV0900_FEC_6_7,/*for DSS only */ - STV0900_FEC_7_8, - STV0900_FEC_8_9,/*for turbo code only*/ - STV0900_FEC_UNKNOWN -}; - -enum fe_stv0900_frame_length { - STV0900_LONG_FRAME, - STV0900_SHORT_FRAME -}; - -enum fe_stv0900_pilot { - STV0900_PILOTS_OFF, - STV0900_PILOTS_ON -}; - -enum fe_stv0900_rolloff { - STV0900_35, - STV0900_25, - STV0900_20 -}; - -enum fe_stv0900_search_iq { - STV0900_IQ_AUTO, - STV0900_IQ_AUTO_NORMAL_FIRST, - STV0900_IQ_FORCE_NORMAL, - STV0900_IQ_FORCE_SWAPPED -}; - -enum stv0900_iq_inversion { - STV0900_IQ_NORMAL, - STV0900_IQ_SWAPPED -}; - -enum fe_stv0900_diseqc_mode { - STV0900_22KHZ_Continues = 0, - STV0900_DISEQC_2_3_PWM = 2, - STV0900_DISEQC_3_3_PWM = 3, - STV0900_DISEQC_2_3_ENVELOP = 4, - STV0900_DISEQC_3_3_ENVELOP = 5 -}; - -enum fe_stv0900_demod_mode { - STV0900_SINGLE = 0, - STV0900_DUAL -}; - -struct stv0900_init_params{ - u32 dmd_ref_clk;/* Refrence,Input clock for the demod in Hz */ - - /* Demodulator Type (single demod or dual demod) */ - enum fe_stv0900_demod_mode demod_mode; - enum fe_stv0900_rolloff rolloff; - enum fe_stv0900_clock_type path1_ts_clock; - - u8 tun1_maddress; - int tuner1_adc; - - /* IQ from the tuner1 to the demod */ - enum stv0900_iq_inversion tun1_iq_inversion; - enum fe_stv0900_clock_type path2_ts_clock; - - u8 tun2_maddress; - int tuner2_adc; - - /* IQ from the tuner2 to the demod */ - enum stv0900_iq_inversion tun2_iq_inversion; -}; - -struct stv0900_search_params { - enum fe_stv0900_demod_num path;/* Path Used demod1 or 2 */ - - u32 frequency;/* Transponder frequency (in KHz) */ - u32 symbol_rate;/* Transponder symbol rate (in bds)*/ - u32 search_range;/* Range of the search (in Hz) */ - - enum fe_stv0900_search_standard standard; - enum fe_stv0900_modulation modulation; - enum fe_stv0900_fec fec; - enum fe_stv0900_modcode modcode; - enum fe_stv0900_search_iq iq_inversion; - enum fe_stv0900_search_algo search_algo; - -}; - -struct stv0900_signal_info { - int locked;/* Transponder locked */ - u32 frequency;/* Transponder frequency (in KHz) */ - u32 symbol_rate;/* Transponder symbol rate (in Mbds) */ - - enum fe_stv0900_tracking_standard standard; - enum fe_stv0900_fec fec; - enum fe_stv0900_modcode modcode; - enum fe_stv0900_modulation modulation; - enum fe_stv0900_pilot pilot; - enum fe_stv0900_frame_length frame_length; - enum stv0900_iq_inversion spectrum; - enum fe_stv0900_rolloff rolloff; - - s32 Power;/* Power of the RF signal (dBm) */ - s32 C_N;/* Carrier to noise ratio (dB x10)*/ - u32 BER;/* Bit error rate (x10^7) */ - -}; - -struct stv0900_internal{ - s32 quartz; - s32 mclk; - /* manual RollOff for DVBS1/DSS only */ - enum fe_stv0900_rolloff rolloff; - /* Demodulator use for single demod or for dual demod) */ - enum fe_stv0900_demod_mode demod_mode; - - /*Demod 1*/ - s32 tuner1_freq; - s32 tuner1_bw; - s32 dmd1_symbol_rate; - s32 dmd1_srch_range; - - /* algorithm for search Blind, Cold or Warm*/ - enum fe_stv0900_search_algo dmd1_srch_algo; - /* search standard: Auto, DVBS1/DSS only or DVBS2 only*/ - enum fe_stv0900_search_standard dmd1_srch_standard; - /* inversion search : auto, auto norma first, normal or inverted */ - enum fe_stv0900_search_iq dmd1_srch_iq_inv; - enum fe_stv0900_modcode dmd1_modcode; - enum fe_stv0900_modulation dmd1_modulation; - enum fe_stv0900_fec dmd1_fec; - - struct stv0900_signal_info dmd1_rslts; - enum fe_stv0900_signal_type dmd1_state; - - enum fe_stv0900_error dmd1_err; - - /*Demod 2*/ - s32 tuner2_freq; - s32 tuner2_bw; - s32 dmd2_symbol_rate; - s32 dmd2_srch_range; - - enum fe_stv0900_search_algo dmd2_srch_algo; - enum fe_stv0900_search_standard dmd2_srch_stndrd; - /* inversion search : auto, auto normal first, normal or inverted */ - enum fe_stv0900_search_iq dmd2_srch_iq_inv; - enum fe_stv0900_modcode dmd2_modcode; - enum fe_stv0900_modulation dmd2_modulation; - enum fe_stv0900_fec dmd2_fec; - - /* results of the search*/ - struct stv0900_signal_info dmd2_rslts; - /* current state of the search algorithm */ - enum fe_stv0900_signal_type dmd2_state; - - enum fe_stv0900_error dmd2_err; - - struct i2c_adapter *i2c_adap; - u8 i2c_addr; - u8 clkmode;/* 0 for CLKI, 2 for XTALI */ - u8 chip_id; - enum fe_stv0900_error errs; - int dmds_used; -}; - -/* state for each demod */ -struct stv0900_state { - /* pointer for internal params, one for each pair of demods */ - struct stv0900_internal *internal; - struct i2c_adapter *i2c_adap; - const struct stv0900_config *config; - struct dvb_frontend frontend; - int demod; -}; - -extern s32 ge2comp(s32 a, s32 width); - -extern void stv0900_write_reg(struct stv0900_internal *i_params, - u16 reg_addr, u8 reg_data); - -extern u8 stv0900_read_reg(struct stv0900_internal *i_params, - u16 reg_addr); - -extern void stv0900_write_bits(struct stv0900_internal *i_params, - u32 label, u8 val); - -extern u8 stv0900_get_bits(struct stv0900_internal *i_params, - u32 label); - -extern int stv0900_get_demod_lock(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod, s32 time_out); -extern int stv0900_check_signal_presence(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod); - -extern enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe); - -extern void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency, - u32 bandwidth); -extern void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth); - -extern void stv0900_start_search(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod); - -extern u8 stv0900_get_optim_carr_loop(s32 srate, - enum fe_stv0900_modcode modcode, - s32 pilot, u8 chip_id); - -extern u8 stv0900_get_optim_short_carr_loop(s32 srate, - enum fe_stv0900_modulation modulation, - u8 chip_id); - -extern void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod); - -extern void stv0900_activate_s2_modcode(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod); - -extern void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod); - -extern enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe, - enum fe_stv0900_demod_num demod); - -#endif diff --git a/trunk/drivers/media/dvb/frontends/stv0900_reg.h b/trunk/drivers/media/dvb/frontends/stv0900_reg.h deleted file mode 100644 index 264f9cf9a17e..000000000000 --- a/trunk/drivers/media/dvb/frontends/stv0900_reg.h +++ /dev/null @@ -1,3787 +0,0 @@ -/* - * stv0900_reg.h - * - * Driver for ST STV0900 satellite demodulator IC. - * - * Copyright (C) ST Microelectronics. - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef STV0900_REG_H -#define STV0900_REG_H - -/*MID*/ -#define R0900_MID 0xf100 -#define F0900_MCHIP_IDENT 0xf10000f0 -#define F0900_MRELEASE 0xf100000f - -/*DACR1*/ -#define R0900_DACR1 0xf113 -#define F0900_DAC_MODE 0xf11300e0 -#define F0900_DAC_VALUE1 0xf113000f - -/*DACR2*/ -#define R0900_DACR2 0xf114 -#define F0900_DAC_VALUE0 0xf11400ff - -/*OUTCFG*/ -#define R0900_OUTCFG 0xf11c -#define F0900_INV_DATA6 0xf11c0080 -#define F0900_OUTSERRS1_HZ 0xf11c0040 -#define F0900_OUTSERRS2_HZ 0xf11c0020 -#define F0900_OUTSERRS3_HZ 0xf11c0010 -#define F0900_OUTPARRS3_HZ 0xf11c0008 -#define F0900_OUTHZ3_CONTROL 0xf11c0007 - -/*MODECFG*/ -#define R0900_MODECFG 0xf11d -#define F0900_FECSPY_SEL_2 0xf11d0020 -#define F0900_HWARE_SEL_2 0xf11d0010 -#define F0900_PKTDEL_SEL_2 0xf11d0008 -#define F0900_DISEQC_SEL_2 0xf11d0004 -#define F0900_VIT_SEL_2 0xf11d0002 -#define F0900_DEMOD_SEL_2 0xf11d0001 - -/*IRQSTATUS3*/ -#define R0900_IRQSTATUS3 0xf120 -#define F0900_SPLL_LOCK 0xf1200020 -#define F0900_SSTREAM_LCK_3 0xf1200010 -#define F0900_SSTREAM_LCK_2 0xf1200008 -#define F0900_SSTREAM_LCK_1 0xf1200004 -#define F0900_SDVBS1_PRF_2 0xf1200002 -#define F0900_SDVBS1_PRF_1 0xf1200001 - -/*IRQSTATUS2*/ -#define R0900_IRQSTATUS2 0xf121 -#define F0900_SSPY_ENDSIM_3 0xf1210080 -#define F0900_SSPY_ENDSIM_2 0xf1210040 -#define F0900_SSPY_ENDSIM_1 0xf1210020 -#define F0900_SPKTDEL_ERROR_2 0xf1210010 -#define F0900_SPKTDEL_LOCKB_2 0xf1210008 -#define F0900_SPKTDEL_LOCK_2 0xf1210004 -#define F0900_SPKTDEL_ERROR_1 0xf1210002 -#define F0900_SPKTDEL_LOCKB_1 0xf1210001 - -/*IRQSTATUS1*/ -#define R0900_IRQSTATUS1 0xf122 -#define F0900_SPKTDEL_LOCK_1 0xf1220080 -#define F0900_SEXTPINB2 0xf1220040 -#define F0900_SEXTPIN2 0xf1220020 -#define F0900_SEXTPINB1 0xf1220010 -#define F0900_SEXTPIN1 0xf1220008 -#define F0900_SDEMOD_LOCKB_2 0xf1220004 -#define F0900_SDEMOD_LOCK_2 0xf1220002 -#define F0900_SDEMOD_IRQ_2 0xf1220001 - -/*IRQSTATUS0*/ -#define R0900_IRQSTATUS0 0xf123 -#define F0900_SDEMOD_LOCKB_1 0xf1230080 -#define F0900_SDEMOD_LOCK_1 0xf1230040 -#define F0900_SDEMOD_IRQ_1 0xf1230020 -#define F0900_SBCH_ERRFLAG 0xf1230010 -#define F0900_SDISEQC2RX_IRQ 0xf1230008 -#define F0900_SDISEQC2TX_IRQ 0xf1230004 -#define F0900_SDISEQC1RX_IRQ 0xf1230002 -#define F0900_SDISEQC1TX_IRQ 0xf1230001 - -/*IRQMASK3*/ -#define R0900_IRQMASK3 0xf124 -#define F0900_MPLL_LOCK 0xf1240020 -#define F0900_MSTREAM_LCK_3 0xf1240010 -#define F0900_MSTREAM_LCK_2 0xf1240008 -#define F0900_MSTREAM_LCK_1 0xf1240004 -#define F0900_MDVBS1_PRF_2 0xf1240002 -#define F0900_MDVBS1_PRF_1 0xf1240001 - -/*IRQMASK2*/ -#define R0900_IRQMASK2 0xf125 -#define F0900_MSPY_ENDSIM_3 0xf1250080 -#define F0900_MSPY_ENDSIM_2 0xf1250040 -#define F0900_MSPY_ENDSIM_1 0xf1250020 -#define F0900_MPKTDEL_ERROR_2 0xf1250010 -#define F0900_MPKTDEL_LOCKB_2 0xf1250008 -#define F0900_MPKTDEL_LOCK_2 0xf1250004 -#define F0900_MPKTDEL_ERROR_1 0xf1250002 -#define F0900_MPKTDEL_LOCKB_1 0xf1250001 - -/*IRQMASK1*/ -#define R0900_IRQMASK1 0xf126 -#define F0900_MPKTDEL_LOCK_1 0xf1260080 -#define F0900_MEXTPINB2 0xf1260040 -#define F0900_MEXTPIN2 0xf1260020 -#define F0900_MEXTPINB1 0xf1260010 -#define F0900_MEXTPIN1 0xf1260008 -#define F0900_MDEMOD_LOCKB_2 0xf1260004 -#define F0900_MDEMOD_LOCK_2 0xf1260002 -#define F0900_MDEMOD_IRQ_2 0xf1260001 - -/*IRQMASK0*/ -#define R0900_IRQMASK0 0xf127 -#define F0900_MDEMOD_LOCKB_1 0xf1270080 -#define F0900_MDEMOD_LOCK_1 0xf1270040 -#define F0900_MDEMOD_IRQ_1 0xf1270020 -#define F0900_MBCH_ERRFLAG 0xf1270010 -#define F0900_MDISEQC2RX_IRQ 0xf1270008 -#define F0900_MDISEQC2TX_IRQ 0xf1270004 -#define F0900_MDISEQC1RX_IRQ 0xf1270002 -#define F0900_MDISEQC1TX_IRQ 0xf1270001 - -/*I2CCFG*/ -#define R0900_I2CCFG 0xf129 -#define F0900_I2C2_FASTMODE 0xf1290080 -#define F0900_STATUS_WR2 0xf1290040 -#define F0900_I2C2ADDR_INC 0xf1290030 -#define F0900_I2C_FASTMODE 0xf1290008 -#define F0900_STATUS_WR 0xf1290004 -#define F0900_I2CADDR_INC 0xf1290003 - -/*P1_I2CRPT*/ -#define R0900_P1_I2CRPT 0xf12a -#define F0900_P1_I2CT_ON 0xf12a0080 -#define F0900_P1_ENARPT_LEVEL 0xf12a0070 -#define F0900_P1_SCLT_DELAY 0xf12a0008 -#define F0900_P1_STOP_ENABLE 0xf12a0004 -#define F0900_P1_STOP_SDAT2SDA 0xf12a0002 - -/*P2_I2CRPT*/ -#define R0900_P2_I2CRPT 0xf12b -#define F0900_P2_I2CT_ON 0xf12b0080 -#define F0900_P2_ENARPT_LEVEL 0xf12b0070 -#define F0900_P2_SCLT_DELAY 0xf12b0008 -#define F0900_P2_STOP_ENABLE 0xf12b0004 -#define F0900_P2_STOP_SDAT2SDA 0xf12b0002 - -/*CLKI2CFG*/ -#define R0900_CLKI2CFG 0xf140 -#define F0900_CLKI2_OPD 0xf1400080 -#define F0900_CLKI2_CONFIG 0xf140007e -#define F0900_CLKI2_XOR 0xf1400001 - -/*GPIO1CFG*/ -#define R0900_GPIO1CFG 0xf141 -#define F0900_GPIO1_OPD 0xf1410080 -#define F0900_GPIO1_CONFIG 0xf141007e -#define F0900_GPIO1_XOR 0xf1410001 - -/*GPIO2CFG*/ -#define R0900_GPIO2CFG 0xf142 -#define F0900_GPIO2_OPD 0xf1420080 -#define F0900_GPIO2_CONFIG 0xf142007e -#define F0900_GPIO2_XOR 0xf1420001 - -/*GPIO3CFG*/ -#define R0900_GPIO3CFG 0xf143 -#define F0900_GPIO3_OPD 0xf1430080 -#define F0900_GPIO3_CONFIG 0xf143007e -#define F0900_GPIO3_XOR 0xf1430001 - -/*GPIO4CFG*/ -#define R0900_GPIO4CFG 0xf144 -#define F0900_GPIO4_OPD 0xf1440080 -#define F0900_GPIO4_CONFIG 0xf144007e -#define F0900_GPIO4_XOR 0xf1440001 - -/*GPIO5CFG*/ -#define R0900_GPIO5CFG 0xf145 -#define F0900_GPIO5_OPD 0xf1450080 -#define F0900_GPIO5_CONFIG 0xf145007e -#define F0900_GPIO5_XOR 0xf1450001 - -/*GPIO6CFG*/ -#define R0900_GPIO6CFG 0xf146 -#define F0900_GPIO6_OPD 0xf1460080 -#define F0900_GPIO6_CONFIG 0xf146007e -#define F0900_GPIO6_XOR 0xf1460001 - -/*GPIO7CFG*/ -#define R0900_GPIO7CFG 0xf147 -#define F0900_GPIO7_OPD 0xf1470080 -#define F0900_GPIO7_CONFIG 0xf147007e -#define F0900_GPIO7_XOR 0xf1470001 - -/*GPIO8CFG*/ -#define R0900_GPIO8CFG 0xf148 -#define F0900_GPIO8_OPD 0xf1480080 -#define F0900_GPIO8_CONFIG 0xf148007e -#define F0900_GPIO8_XOR 0xf1480001 - -/*GPIO9CFG*/ -#define R0900_GPIO9CFG 0xf149 -#define F0900_GPIO9_OPD 0xf1490080 -#define F0900_GPIO9_CONFIG 0xf149007e -#define F0900_GPIO9_XOR 0xf1490001 - -/*GPIO10CFG*/ -#define R0900_GPIO10CFG 0xf14a -#define F0900_GPIO10_OPD 0xf14a0080 -#define F0900_GPIO10_CONFIG 0xf14a007e -#define F0900_GPIO10_XOR 0xf14a0001 - -/*GPIO11CFG*/ -#define R0900_GPIO11CFG 0xf14b -#define F0900_GPIO11_OPD 0xf14b0080 -#define F0900_GPIO11_CONFIG 0xf14b007e -#define F0900_GPIO11_XOR 0xf14b0001 - -/*GPIO12CFG*/ -#define R0900_GPIO12CFG 0xf14c -#define F0900_GPIO12_OPD 0xf14c0080 -#define F0900_GPIO12_CONFIG 0xf14c007e -#define F0900_GPIO12_XOR 0xf14c0001 - -/*GPIO13CFG*/ -#define R0900_GPIO13CFG 0xf14d -#define F0900_GPIO13_OPD 0xf14d0080 -#define F0900_GPIO13_CONFIG 0xf14d007e -#define F0900_GPIO13_XOR 0xf14d0001 - -/*CS0CFG*/ -#define R0900_CS0CFG 0xf14e -#define F0900_CS0_OPD 0xf14e0080 -#define F0900_CS0_CONFIG 0xf14e007e -#define F0900_CS0_XOR 0xf14e0001 - -/*CS1CFG*/ -#define R0900_CS1CFG 0xf14f -#define F0900_CS1_OPD 0xf14f0080 -#define F0900_CS1_CONFIG 0xf14f007e -#define F0900_CS1_XOR 0xf14f0001 - -/*STDBYCFG*/ -#define R0900_STDBYCFG 0xf150 -#define F0900_STDBY_OPD 0xf1500080 -#define F0900_STDBY_CONFIG 0xf150007e -#define F0900_STBDY_XOR 0xf1500001 - -/*DIRCLKCFG*/ -#define R0900_DIRCLKCFG 0xf151 -#define F0900_DIRCLK_OPD 0xf1510080 -#define F0900_DIRCLK_CONFIG 0xf151007e -#define F0900_DIRCLK_XOR 0xf1510001 - -/*AGCRF1CFG*/ -#define R0900_AGCRF1CFG 0xf152 -#define F0900_AGCRF1_OPD 0xf1520080 -#define F0900_AGCRF1_CONFIG 0xf152007e -#define F0900_AGCRF1_XOR 0xf1520001 - -/*SDAT1CFG*/ -#define R0900_SDAT1CFG 0xf153 -#define F0900_SDAT1_OPD 0xf1530080 -#define F0900_SDAT1_CONFIG 0xf153007e -#define F0900_SDAT1_XOR 0xf1530001 - -/*SCLT1CFG*/ -#define R0900_SCLT1CFG 0xf154 -#define F0900_SCLT1_OPD 0xf1540080 -#define F0900_SCLT1_CONFIG 0xf154007e -#define F0900_SCLT1_XOR 0xf1540001 - -/*DISEQCO1CFG*/ -#define R0900_DISEQCO1CFG 0xf155 -#define F0900_DISEQCO1_OPD 0xf1550080 -#define F0900_DISEQCO1_CONFIG 0xf155007e -#define F0900_DISEQC1_XOR 0xf1550001 - -/*AGCRF2CFG*/ -#define R0900_AGCRF2CFG 0xf156 -#define F0900_AGCRF2_OPD 0xf1560080 -#define F0900_AGCRF2_CONFIG 0xf156007e -#define F0900_AGCRF2_XOR 0xf1560001 - -/*SDAT2CFG*/ -#define R0900_SDAT2CFG 0xf157 -#define F0900_SDAT2_OPD 0xf1570080 -#define F0900_SDAT2_CONFIG 0xf157007e -#define F0900_SDAT2_XOR 0xf1570001 - -/*SCLT2CFG*/ -#define R0900_SCLT2CFG 0xf158 -#define F0900_SCLT2_OPD 0xf1580080 -#define F0900_SCLT2_CONFIG 0xf158007e -#define F0900_SCLT2_XOR 0xf1580001 - -/*DISEQCO2CFG*/ -#define R0900_DISEQCO2CFG 0xf159 -#define F0900_DISEQCO2_OPD 0xf1590080 -#define F0900_DISEQCO2_CONFIG 0xf159007e -#define F0900_DISEQC2_XOR 0xf1590001 - -/*CLKOUT27CFG*/ -#define R0900_CLKOUT27CFG 0xf15a -#define F0900_CLKOUT27_OPD 0xf15a0080 -#define F0900_CLKOUT27_CONFIG 0xf15a007e -#define F0900_CLKOUT27_XOR 0xf15a0001 - -/*ERROR1CFG*/ -#define R0900_ERROR1CFG 0xf15b -#define F0900_ERROR1_OPD 0xf15b0080 -#define F0900_ERROR1_CONFIG 0xf15b007e -#define F0900_ERROR1_XOR 0xf15b0001 - -/*DPN1CFG*/ -#define R0900_DPN1CFG 0xf15c -#define F0900_DPN1_OPD 0xf15c0080 -#define F0900_DPN1_CONFIG 0xf15c007e -#define F0900_DPN1_XOR 0xf15c0001 - -/*STROUT1CFG*/ -#define R0900_STROUT1CFG 0xf15d -#define F0900_STROUT1_OPD 0xf15d0080 -#define F0900_STROUT1_CONFIG 0xf15d007e -#define F0900_STROUT1_XOR 0xf15d0001 - -/*CLKOUT1CFG*/ -#define R0900_CLKOUT1CFG 0xf15e -#define F0900_CLKOUT1_OPD 0xf15e0080 -#define F0900_CLKOUT1_CONFIG 0xf15e007e -#define F0900_CLKOUT1_XOR 0xf15e0001 - -/*DATA71CFG*/ -#define R0900_DATA71CFG 0xf15f -#define F0900_DATA71_OPD 0xf15f0080 -#define F0900_DATA71_CONFIG 0xf15f007e -#define F0900_DATA71_XOR 0xf15f0001 - -/*ERROR2CFG*/ -#define R0900_ERROR2CFG 0xf160 -#define F0900_ERROR2_OPD 0xf1600080 -#define F0900_ERROR2_CONFIG 0xf160007e -#define F0900_ERROR2_XOR 0xf1600001 - -/*DPN2CFG*/ -#define R0900_DPN2CFG 0xf161 -#define F0900_DPN2_OPD 0xf1610080 -#define F0900_DPN2_CONFIG 0xf161007e -#define F0900_DPN2_XOR 0xf1610001 - -/*STROUT2CFG*/ -#define R0900_STROUT2CFG 0xf162 -#define F0900_STROUT2_OPD 0xf1620080 -#define F0900_STROUT2_CONFIG 0xf162007e -#define F0900_STROUT2_XOR 0xf1620001 - -/*CLKOUT2CFG*/ -#define R0900_CLKOUT2CFG 0xf163 -#define F0900_CLKOUT2_OPD 0xf1630080 -#define F0900_CLKOUT2_CONFIG 0xf163007e -#define F0900_CLKOUT2_XOR 0xf1630001 - -/*DATA72CFG*/ -#define R0900_DATA72CFG 0xf164 -#define F0900_DATA72_OPD 0xf1640080 -#define F0900_DATA72_CONFIG 0xf164007e -#define F0900_DATA72_XOR 0xf1640001 - -/*ERROR3CFG*/ -#define R0900_ERROR3CFG 0xf165 -#define F0900_ERROR3_OPD 0xf1650080 -#define F0900_ERROR3_CONFIG 0xf165007e -#define F0900_ERROR3_XOR 0xf1650001 - -/*DPN3CFG*/ -#define R0900_DPN3CFG 0xf166 -#define F0900_DPN3_OPD 0xf1660080 -#define F0900_DPN3_CONFIG 0xf166007e -#define F0900_DPN3_XOR 0xf1660001 - -/*STROUT3CFG*/ -#define R0900_STROUT3CFG 0xf167 -#define F0900_STROUT3_OPD 0xf1670080 -#define F0900_STROUT3_CONFIG 0xf167007e -#define F0900_STROUT3_XOR 0xf1670001 - -/*CLKOUT3CFG*/ -#define R0900_CLKOUT3CFG 0xf168 -#define F0900_CLKOUT3_OPD 0xf1680080 -#define F0900_CLKOUT3_CONFIG 0xf168007e -#define F0900_CLKOUT3_XOR 0xf1680001 - -/*DATA73CFG*/ -#define R0900_DATA73CFG 0xf169 -#define F0900_DATA73_OPD 0xf1690080 -#define F0900_DATA73_CONFIG 0xf169007e -#define F0900_DATA73_XOR 0xf1690001 - -/*FSKTFC2*/ -#define R0900_FSKTFC2 0xf170 -#define F0900_FSKT_KMOD 0xf17000fc -#define F0900_FSKT_CAR2 0xf1700003 - -/*FSKTFC1*/ -#define R0900_FSKTFC1 0xf171 -#define F0900_FSKT_CAR1 0xf17100ff - -/*FSKTFC0*/ -#define R0900_FSKTFC0 0xf172 -#define F0900_FSKT_CAR0 0xf17200ff - -/*FSKTDELTAF1*/ -#define R0900_FSKTDELTAF1 0xf173 -#define F0900_FSKT_DELTAF1 0xf173000f - -/*FSKTDELTAF0*/ -#define R0900_FSKTDELTAF0 0xf174 -#define F0900_FSKT_DELTAF0 0xf17400ff - -/*FSKTCTRL*/ -#define R0900_FSKTCTRL 0xf175 -#define F0900_FSKT_EN_SGN 0xf1750040 -#define F0900_FSKT_MOD_SGN 0xf1750020 -#define F0900_FSKT_MOD_EN 0xf175001c -#define F0900_FSKT_DACMODE 0xf1750003 - -/*FSKRFC2*/ -#define R0900_FSKRFC2 0xf176 -#define F0900_FSKR_DETSGN 0xf1760040 -#define F0900_FSKR_OUTSGN 0xf1760020 -#define F0900_FSKR_KAGC 0xf176001c -#define F0900_FSKR_CAR2 0xf1760003 - -/*FSKRFC1*/ -#define R0900_FSKRFC1 0xf177 -#define F0900_FSKR_CAR1 0xf17700ff - -/*FSKRFC0*/ -#define R0900_FSKRFC0 0xf178 -#define F0900_FSKR_CAR0 0xf17800ff - -/*FSKRK1*/ -#define R0900_FSKRK1 0xf179 -#define F0900_FSKR_K1_EXP 0xf17900e0 -#define F0900_FSKR_K1_MANT 0xf179001f - -/*FSKRK2*/ -#define R0900_FSKRK2 0xf17a -#define F0900_FSKR_K2_EXP 0xf17a00e0 -#define F0900_FSKR_K2_MANT 0xf17a001f - -/*FSKRAGCR*/ -#define R0900_FSKRAGCR 0xf17b -#define F0900_FSKR_OUTCTL 0xf17b00c0 -#define F0900_FSKR_AGC_REF 0xf17b003f - -/*FSKRAGC*/ -#define R0900_FSKRAGC 0xf17c -#define F0900_FSKR_AGC_ACCU 0xf17c00ff - -/*FSKRALPHA*/ -#define R0900_FSKRALPHA 0xf17d -#define F0900_FSKR_ALPHA_EXP 0xf17d001c -#define F0900_FSKR_ALPHA_M 0xf17d0003 - -/*FSKRPLTH1*/ -#define R0900_FSKRPLTH1 0xf17e -#define F0900_FSKR_BETA 0xf17e00f0 -#define F0900_FSKR_PLL_TRESH1 0xf17e000f - -/*FSKRPLTH0*/ -#define R0900_FSKRPLTH0 0xf17f -#define F0900_FSKR_PLL_TRESH0 0xf17f00ff - -/*FSKRDF1*/ -#define R0900_FSKRDF1 0xf180 -#define F0900_FSKR_OUT 0xf1800080 -#define F0900_FSKR_DELTAF1 0xf180001f - -/*FSKRDF0*/ -#define R0900_FSKRDF0 0xf181 -#define F0900_FSKR_DELTAF0 0xf18100ff - -/*FSKRSTEPP*/ -#define R0900_FSKRSTEPP 0xf182 -#define F0900_FSKR_STEP_PLUS 0xf18200ff - -/*FSKRSTEPM*/ -#define R0900_FSKRSTEPM 0xf183 -#define F0900_FSKR_STEP_MINUS 0xf18300ff - -/*FSKRDET1*/ -#define R0900_FSKRDET1 0xf184 -#define F0900_FSKR_DETECT 0xf1840080 -#define F0900_FSKR_CARDET_ACCU1 0xf184000f - -/*FSKRDET0*/ -#define R0900_FSKRDET0 0xf185 -#define F0900_FSKR_CARDET_ACCU0 0xf18500ff - -/*FSKRDTH1*/ -#define R0900_FSKRDTH1 0xf186 -#define F0900_FSKR_CARLOSS_THRESH1 0xf18600f0 -#define F0900_FSKR_CARDET_THRESH1 0xf186000f - -/*FSKRDTH0*/ -#define R0900_FSKRDTH0 0xf187 -#define F0900_FSKR_CARDET_THRESH0 0xf18700ff - -/*FSKRLOSS*/ -#define R0900_FSKRLOSS 0xf188 -#define F0900_FSKR_CARLOSS_THRESH0 0xf18800ff - -/*P2_DISTXCTL*/ -#define R0900_P2_DISTXCTL 0xf190 -#define F0900_P2_TIM_OFF 0xf1900080 -#define F0900_P2_DISEQC_RESET 0xf1900040 -#define F0900_P2_TIM_CMD 0xf1900030 -#define F0900_P2_DIS_PRECHARGE 0xf1900008 -#define F0900_P2_DISTX_MODE 0xf1900007 - -/*P2_DISRXCTL*/ -#define R0900_P2_DISRXCTL 0xf191 -#define F0900_P2_RECEIVER_ON 0xf1910080 -#define F0900_P2_IGNO_SHORT22K 0xf1910040 -#define F0900_P2_ONECHIP_TRX 0xf1910020 -#define F0900_P2_EXT_ENVELOP 0xf1910010 -#define F0900_P2_PIN_SELECT 0xf191000c -#define F0900_P2_IRQ_RXEND 0xf1910002 -#define F0900_P2_IRQ_4NBYTES 0xf1910001 - -/*P2_DISRX_ST0*/ -#define R0900_P2_DISRX_ST0 0xf194 -#define F0900_P2_RX_END 0xf1940080 -#define F0900_P2_RX_ACTIVE 0xf1940040 -#define F0900_P2_SHORT_22KHZ 0xf1940020 -#define F0900_P2_CONT_TONE 0xf1940010 -#define F0900_P2_FIFO_4BREADY 0xf1940008 -#define F0900_P2_FIFO_EMPTY 0xf1940004 -#define F0900_P2_ABORT_DISRX 0xf1940001 - -/*P2_DISRX_ST1*/ -#define R0900_P2_DISRX_ST1 0xf195 -#define F0900_P2_RX_FAIL 0xf1950080 -#define F0900_P2_FIFO_PARITYFAIL 0xf1950040 -#define F0900_P2_RX_NONBYTE 0xf1950020 -#define F0900_P2_FIFO_OVERFLOW 0xf1950010 -#define F0900_P2_FIFO_BYTENBR 0xf195000f - -/*P2_DISRXDATA*/ -#define R0900_P2_DISRXDATA 0xf196 -#define F0900_P2_DISRX_DATA 0xf19600ff - -/*P2_DISTXDATA*/ -#define R0900_P2_DISTXDATA 0xf197 -#define F0900_P2_DISEQC_FIFO 0xf19700ff - -/*P2_DISTXSTATUS*/ -#define R0900_P2_DISTXSTATUS 0xf198 -#define F0900_P2_TX_FAIL 0xf1980080 -#define F0900_P2_FIFO_FULL 0xf1980040 -#define F0900_P2_TX_IDLE 0xf1980020 -#define F0900_P2_GAP_BURST 0xf1980010 -#define F0900_P2_TXFIFO_BYTES 0xf198000f - -/*P2_F22TX*/ -#define R0900_P2_F22TX 0xf199 -#define F0900_P2_F22_REG 0xf19900ff - -/*P2_F22RX*/ -#define R0900_P2_F22RX 0xf19a -#define F0900_P2_F22RX_REG 0xf19a00ff - -/*P2_ACRPRESC*/ -#define R0900_P2_ACRPRESC 0xf19c -#define F0900_P2_ACR_CODFRDY 0xf19c0008 -#define F0900_P2_ACR_PRESC 0xf19c0007 - -/*P2_ACRDIV*/ -#define R0900_P2_ACRDIV 0xf19d -#define F0900_P2_ACR_DIV 0xf19d00ff - -/*P1_DISTXCTL*/ -#define R0900_P1_DISTXCTL 0xf1a0 -#define F0900_P1_TIM_OFF 0xf1a00080 -#define F0900_P1_DISEQC_RESET 0xf1a00040 -#define F0900_P1_TIM_CMD 0xf1a00030 -#define F0900_P1_DIS_PRECHARGE 0xf1a00008 -#define F0900_P1_DISTX_MODE 0xf1a00007 - -/*P1_DISRXCTL*/ -#define R0900_P1_DISRXCTL 0xf1a1 -#define F0900_P1_RECEIVER_ON 0xf1a10080 -#define F0900_P1_IGNO_SHORT22K 0xf1a10040 -#define F0900_P1_ONECHIP_TRX 0xf1a10020 -#define F0900_P1_EXT_ENVELOP 0xf1a10010 -#define F0900_P1_PIN_SELECT 0xf1a1000c -#define F0900_P1_IRQ_RXEND 0xf1a10002 -#define F0900_P1_IRQ_4NBYTES 0xf1a10001 - -/*P1_DISRX_ST0*/ -#define R0900_P1_DISRX_ST0 0xf1a4 -#define F0900_P1_RX_END 0xf1a40080 -#define F0900_P1_RX_ACTIVE 0xf1a40040 -#define F0900_P1_SHORT_22KHZ 0xf1a40020 -#define F0900_P1_CONT_TONE 0xf1a40010 -#define F0900_P1_FIFO_4BREADY 0xf1a40008 -#define F0900_P1_FIFO_EMPTY 0xf1a40004 -#define F0900_P1_ABORT_DISRX 0xf1a40001 - -/*P1_DISRX_ST1*/ -#define R0900_P1_DISRX_ST1 0xf1a5 -#define F0900_P1_RX_FAIL 0xf1a50080 -#define F0900_P1_FIFO_PARITYFAIL 0xf1a50040 -#define F0900_P1_RX_NONBYTE 0xf1a50020 -#define F0900_P1_FIFO_OVERFLOW 0xf1a50010 -#define F0900_P1_FIFO_BYTENBR 0xf1a5000f - -/*P1_DISRXDATA*/ -#define R0900_P1_DISRXDATA 0xf1a6 -#define F0900_P1_DISRX_DATA 0xf1a600ff - -/*P1_DISTXDATA*/ -#define R0900_P1_DISTXDATA 0xf1a7 -#define F0900_P1_DISEQC_FIFO 0xf1a700ff - -/*P1_DISTXSTATUS*/ -#define R0900_P1_DISTXSTATUS 0xf1a8 -#define F0900_P1_TX_FAIL 0xf1a80080 -#define F0900_P1_FIFO_FULL 0xf1a80040 -#define F0900_P1_TX_IDLE 0xf1a80020 -#define F0900_P1_GAP_BURST 0xf1a80010 -#define F0900_P1_TXFIFO_BYTES 0xf1a8000f - -/*P1_F22TX*/ -#define R0900_P1_F22TX 0xf1a9 -#define F0900_P1_F22_REG 0xf1a900ff - -/*P1_F22RX*/ -#define R0900_P1_F22RX 0xf1aa -#define F0900_P1_F22RX_REG 0xf1aa00ff - -/*P1_ACRPRESC*/ -#define R0900_P1_ACRPRESC 0xf1ac -#define F0900_P1_ACR_CODFRDY 0xf1ac0008 -#define F0900_P1_ACR_PRESC 0xf1ac0007 - -/*P1_ACRDIV*/ -#define R0900_P1_ACRDIV 0xf1ad -#define F0900_P1_ACR_DIV 0xf1ad00ff - -/*NCOARSE*/ -#define R0900_NCOARSE 0xf1b3 -#define F0900_M_DIV 0xf1b300ff - -/*SYNTCTRL*/ -#define R0900_SYNTCTRL 0xf1b6 -#define F0900_STANDBY 0xf1b60080 -#define F0900_BYPASSPLLCORE 0xf1b60040 -#define F0900_SELX1RATIO 0xf1b60020 -#define F0900_I2C_TUD 0xf1b60010 -#define F0900_STOP_PLL 0xf1b60008 -#define F0900_BYPASSPLLFSK 0xf1b60004 -#define F0900_SELOSCI 0xf1b60002 -#define F0900_BYPASSPLLADC 0xf1b60001 - -/*FILTCTRL*/ -#define R0900_FILTCTRL 0xf1b7 -#define F0900_INV_CLK135 0xf1b70080 -#define F0900_PERM_BYPDIS 0xf1b70040 -#define F0900_SEL_FSKCKDIV 0xf1b70004 -#define F0900_INV_CLKFSK 0xf1b70002 -#define F0900_BYPASS_APPLI 0xf1b70001 - -/*PLLSTAT*/ -#define R0900_PLLSTAT 0xf1b8 -#define F0900_ACM_SEL 0xf1b80080 -#define F0900_DTV_SEL 0xf1b80040 -#define F0900_PLLLOCK 0xf1b80001 - -/*STOPCLK1*/ -#define R0900_STOPCLK1 0xf1c2 -#define F0900_STOP_CLKPKDT2 0xf1c20040 -#define F0900_STOP_CLKPKDT1 0xf1c20020 -#define F0900_STOP_CLKFEC 0xf1c20010 -#define F0900_STOP_CLKADCI2 0xf1c20008 -#define F0900_INV_CLKADCI2 0xf1c20004 -#define F0900_STOP_CLKADCI1 0xf1c20002 -#define F0900_INV_CLKADCI1 0xf1c20001 - -/*STOPCLK2*/ -#define R0900_STOPCLK2 0xf1c3 -#define F0900_STOP_CLKSAMP2 0xf1c30010 -#define F0900_STOP_CLKSAMP1 0xf1c30008 -#define F0900_STOP_CLKVIT2 0xf1c30004 -#define F0900_STOP_CLKVIT1 0xf1c30002 -#define F0900_STOP_CLKTS 0xf1c30001 - -/*TSTTNR0*/ -#define R0900_TSTTNR0 0xf1df -#define F0900_SEL_FSK 0xf1df0080 -#define F0900_FSK_PON 0xf1df0004 -#define F0900_FSK_OPENLOOP 0xf1df0002 - -/*TSTTNR1*/ -#define R0900_TSTTNR1 0xf1e0 -#define F0900_BYPASS_ADC1 0xf1e00080 -#define F0900_INVADC1_CKOUT 0xf1e00040 -#define F0900_SELIQSRC1 0xf1e00030 -#define F0900_ADC1_PON 0xf1e00002 -#define F0900_ADC1_INMODE 0xf1e00001 - -/*TSTTNR2*/ -#define R0900_TSTTNR2 0xf1e1 -#define F0900_DISEQC1_PON 0xf1e10020 -#define F0900_DISEQC1_TEST 0xf1e1001f - -/*TSTTNR3*/ -#define R0900_TSTTNR3 0xf1e2 -#define F0900_BYPASS_ADC2 0xf1e20080 -#define F0900_INVADC2_CKOUT 0xf1e20040 -#define F0900_SELIQSRC2 0xf1e20030 -#define F0900_ADC2_PON 0xf1e20002 -#define F0900_ADC2_INMODE 0xf1e20001 - -/*TSTTNR4*/ -#define R0900_TSTTNR4 0xf1e3 -#define F0900_DISEQC2_PON 0xf1e30020 -#define F0900_DISEQC2_TEST 0xf1e3001f - -/*P2_IQCONST*/ -#define R0900_P2_IQCONST 0xf200 -#define F0900_P2_CONSTEL_SELECT 0xf2000060 -#define F0900_P2_IQSYMB_SEL 0xf200001f - -/*P2_NOSCFG*/ -#define R0900_P2_NOSCFG 0xf201 -#define F0900_P2_DUMMYPL_NOSDATA 0xf2010020 -#define F0900_P2_NOSPLH_BETA 0xf2010018 -#define F0900_P2_NOSDATA_BETA 0xf2010007 - -/*P2_ISYMB*/ -#define R0900_P2_ISYMB 0xf202 -#define F0900_P2_I_SYMBOL 0xf20201ff - -/*P2_QSYMB*/ -#define R0900_P2_QSYMB 0xf203 -#define F0900_P2_Q_SYMBOL 0xf20301ff - -/*P2_AGC1CFG*/ -#define R0900_P2_AGC1CFG 0xf204 -#define F0900_P2_DC_FROZEN 0xf2040080 -#define F0900_P2_DC_CORRECT 0xf2040040 -#define F0900_P2_AMM_FROZEN 0xf2040020 -#define F0900_P2_AMM_CORRECT 0xf2040010 -#define F0900_P2_QUAD_FROZEN 0xf2040008 -#define F0900_P2_QUAD_CORRECT 0xf2040004 -#define F0900_P2_DCCOMP_SLOW 0xf2040002 -#define F0900_P2_IQMISM_SLOW 0xf2040001 - -/*P2_AGC1CN*/ -#define R0900_P2_AGC1CN 0xf206 -#define F0900_P2_AGC1_LOCKED 0xf2060080 -#define F0900_P2_AGC1_OVERFLOW 0xf2060040 -#define F0900_P2_AGC1_NOSLOWLK 0xf2060020 -#define F0900_P2_AGC1_MINPOWER 0xf2060010 -#define F0900_P2_AGCOUT_FAST 0xf2060008 -#define F0900_P2_AGCIQ_BETA 0xf2060007 - -/*P2_AGC1REF*/ -#define R0900_P2_AGC1REF 0xf207 -#define F0900_P2_AGCIQ_REF 0xf20700ff - -/*P2_IDCCOMP*/ -#define R0900_P2_IDCCOMP 0xf208 -#define F0900_P2_IAVERAGE_ADJ 0xf20801ff - -/*P2_QDCCOMP*/ -#define R0900_P2_QDCCOMP 0xf209 -#define F0900_P2_QAVERAGE_ADJ 0xf20901ff - -/*P2_POWERI*/ -#define R0900_P2_POWERI 0xf20a -#define F0900_P2_POWER_I 0xf20a00ff - -/*P2_POWERQ*/ -#define R0900_P2_POWERQ 0xf20b -#define F0900_P2_POWER_Q 0xf20b00ff - -/*P2_AGC1AMM*/ -#define R0900_P2_AGC1AMM 0xf20c -#define F0900_P2_AMM_VALUE 0xf20c00ff - -/*P2_AGC1QUAD*/ -#define R0900_P2_AGC1QUAD 0xf20d -#define F0900_P2_QUAD_VALUE 0xf20d01ff - -/*P2_AGCIQIN1*/ -#define R0900_P2_AGCIQIN1 0xf20e -#define F0900_P2_AGCIQ_VALUE1 0xf20e00ff - -/*P2_AGCIQIN0*/ -#define R0900_P2_AGCIQIN0 0xf20f -#define F0900_P2_AGCIQ_VALUE0 0xf20f00ff - -/*P2_DEMOD*/ -#define R0900_P2_DEMOD 0xf210 -#define F0900_P2_DEMOD_STOP 0xf2100040 -#define F0900_P2_SPECINV_CONTROL 0xf2100030 -#define F0900_P2_FORCE_ENASAMP 0xf2100008 -#define F0900_P2_MANUAL_ROLLOFF 0xf2100004 -#define F0900_P2_ROLLOFF_CONTROL 0xf2100003 - -/*P2_DMDMODCOD*/ -#define R0900_P2_DMDMODCOD 0xf211 -#define F0900_P2_MANUAL_MODCOD 0xf2110080 -#define F0900_P2_DEMOD_MODCOD 0xf211007c -#define F0900_P2_DEMOD_TYPE 0xf2110003 - -/*P2_DSTATUS*/ -#define R0900_P2_DSTATUS 0xf212 -#define F0900_P2_CAR_LOCK 0xf2120080 -#define F0900_P2_TMGLOCK_QUALITY 0xf2120060 -#define F0900_P2_SDVBS1_ENABLE 0xf2120010 -#define F0900_P2_LOCK_DEFINITIF 0xf2120008 -#define F0900_P2_TIMING_IS_LOCKED 0xf2120004 -#define F0900_P2_COARSE_TMGLOCK 0xf2120002 -#define F0900_P2_COARSE_CARLOCK 0xf2120001 - -/*P2_DSTATUS2*/ -#define R0900_P2_DSTATUS2 0xf213 -#define F0900_P2_DEMOD_DELOCK 0xf2130080 -#define F0900_P2_DEMOD_TIMEOUT 0xf2130040 -#define F0900_P2_MODCODRQ_SYNCTAG 0xf2130020 -#define F0900_P2_POLYPH_SATEVENT 0xf2130010 -#define F0900_P2_AGC1_NOSIGNALACK 0xf2130008 -#define F0900_P2_AGC2_OVERFLOW 0xf2130004 -#define F0900_P2_CFR_OVERFLOW 0xf2130002 -#define F0900_P2_GAMMA_OVERUNDER 0xf2130001 - -/*P2_DMDCFGMD*/ -#define R0900_P2_DMDCFGMD 0xf214 -#define F0900_P2_DVBS2_ENABLE 0xf2140080 -#define F0900_P2_DVBS1_ENABLE 0xf2140040 -#define F0900_P2_CFR_AUTOSCAN 0xf2140020 -#define F0900_P2_SCAN_ENABLE 0xf2140010 -#define F0900_P2_TUN_AUTOSCAN 0xf2140008 -#define F0900_P2_NOFORCE_RELOCK 0xf2140004 -#define F0900_P2_TUN_RNG 0xf2140003 - -/*P2_DMDCFG2*/ -#define R0900_P2_DMDCFG2 0xf215 -#define F0900_P2_AGC1_WAITLOCK 0xf2150080 -#define F0900_P2_S1S2_SEQUENTIAL 0xf2150040 -#define F0900_P2_OVERFLOW_TIMEOUT 0xf2150020 -#define F0900_P2_SCANFAIL_TIMEOUT 0xf2150010 -#define F0900_P2_DMDTOUT_BACK 0xf2150008 -#define F0900_P2_CARLOCK_S1ENABLE 0xf2150004 -#define F0900_P2_COARSE_LK3MODE 0xf2150002 -#define F0900_P2_COARSE_LK2MODE 0xf2150001 - -/*P2_DMDISTATE*/ -#define R0900_P2_DMDISTATE 0xf216 -#define F0900_P2_I2C_NORESETDMODE 0xf2160080 -#define F0900_P2_FORCE_ETAPED 0xf2160040 -#define F0900_P2_SDMDRST_DIRCLK 0xf2160020 -#define F0900_P2_I2C_DEMOD_MODE 0xf216001f - -/*P2_DMDT0M*/ -#define R0900_P2_DMDT0M 0xf217 -#define F0900_P2_DMDT0_MIN 0xf21700ff - -/*P2_DMDSTATE*/ -#define R0900_P2_DMDSTATE 0xf21b -#define F0900_P2_DEMOD_LOCKED 0xf21b0080 -#define F0900_P2_HEADER_MODE 0xf21b0060 -#define F0900_P2_DEMOD_MODE 0xf21b001f - -/*P2_DMDFLYW*/ -#define R0900_P2_DMDFLYW 0xf21c -#define F0900_P2_I2C_IRQVAL 0xf21c00f0 -#define F0900_P2_FLYWHEEL_CPT 0xf21c000f - -/*P2_DSTATUS3*/ -#define R0900_P2_DSTATUS3 0xf21d -#define F0900_P2_CFR_ZIGZAG 0xf21d0080 -#define F0900_P2_DEMOD_CFGMODE 0xf21d0060 -#define F0900_P2_GAMMA_LOWBAUDRATE 0xf21d0010 -#define F0900_P2_RELOCK_MODE 0xf21d0008 -#define F0900_P2_DEMOD_FAIL 0xf21d0004 -#define F0900_P2_ETAPE1A_DVBXMEM 0xf21d0003 - -/*P2_DMDCFG3*/ -#define R0900_P2_DMDCFG3 0xf21e -#define F0900_P2_DVBS1_TMGWAIT 0xf21e0080 -#define F0900_P2_NO_BWCENTERING 0xf21e0040 -#define F0900_P2_INV_SEQSRCH 0xf21e0020 -#define F0900_P2_DIS_SFRUPLOW_TRK 0xf21e0010 -#define F0900_P2_NOSTOP_FIFOFULL 0xf21e0008 -#define F0900_P2_LOCKTIME_MODE 0xf21e0007 - -/*P2_DMDCFG4*/ -#define R0900_P2_DMDCFG4 0xf21f -#define F0900_P2_TUNER_NRELAUNCH 0xf21f0008 -#define F0900_P2_DIS_CLKENABLE 0xf21f0004 -#define F0900_P2_DIS_HDRDIVLOCK 0xf21f0002 -#define F0900_P2_NO_TNRWBINIT 0xf21f0001 - -/*P2_CORRELMANT*/ -#define R0900_P2_CORRELMANT 0xf220 -#define F0900_P2_CORREL_MANT 0xf22000ff - -/*P2_CORRELABS*/ -#define R0900_P2_CORRELABS 0xf221 -#define F0900_P2_CORREL_ABS 0xf22100ff - -/*P2_CORRELEXP*/ -#define R0900_P2_CORRELEXP 0xf222 -#define F0900_P2_CORREL_ABSEXP 0xf22200f0 -#define F0900_P2_CORREL_EXP 0xf222000f - -/*P2_PLHMODCOD*/ -#define R0900_P2_PLHMODCOD 0xf224 -#define F0900_P2_SPECINV_DEMOD 0xf2240080 -#define F0900_P2_PLH_MODCOD 0xf224007c -#define F0900_P2_PLH_TYPE 0xf2240003 - -/*P2_AGCK32*/ -#define R0900_P2_AGCK32 0xf22b -#define F0900_P2_R3ADJOFF_32APSK 0xf22b0080 -#define F0900_P2_R2ADJOFF_32APSK 0xf22b0040 -#define F0900_P2_R1ADJOFF_32APSK 0xf22b0020 -#define F0900_P2_RADJ_32APSK 0xf22b001f - -/*P2_AGC2O*/ -#define R0900_P2_AGC2O 0xf22c -#define F0900_P2_AGC2REF_ADJUSTING 0xf22c0080 -#define F0900_P2_AGC2_COARSEFAST 0xf22c0040 -#define F0900_P2_AGC2_LKSQRT 0xf22c0020 -#define F0900_P2_AGC2_LKMODE 0xf22c0010 -#define F0900_P2_AGC2_LKEQUA 0xf22c0008 -#define F0900_P2_AGC2_COEF 0xf22c0007 - -/*P2_AGC2REF*/ -#define R0900_P2_AGC2REF 0xf22d -#define F0900_P2_AGC2_REF 0xf22d00ff - -/*P2_AGC1ADJ*/ -#define R0900_P2_AGC1ADJ 0xf22e -#define F0900_P2_AGC1ADJ_MANUAL 0xf22e0080 -#define F0900_P2_AGC1_ADJUSTED 0xf22e017f - -/*P2_AGC2I1*/ -#define R0900_P2_AGC2I1 0xf236 -#define F0900_P2_AGC2_INTEGRATOR1 0xf23600ff - -/*P2_AGC2I0*/ -#define R0900_P2_AGC2I0 0xf237 -#define F0900_P2_AGC2_INTEGRATOR0 0xf23700ff - -/*P2_CARCFG*/ -#define R0900_P2_CARCFG 0xf238 -#define F0900_P2_CFRUPLOW_AUTO 0xf2380080 -#define F0900_P2_CFRUPLOW_TEST 0xf2380040 -#define F0900_P2_EN_CAR2CENTER 0xf2380020 -#define F0900_P2_CARHDR_NODIV8 0xf2380010 -#define F0900_P2_I2C_ROTA 0xf2380008 -#define F0900_P2_ROTAON 0xf2380004 -#define F0900_P2_PH_DET_ALGO 0xf2380003 - -/*P2_ACLC*/ -#define R0900_P2_ACLC 0xf239 -#define F0900_P2_STOP_S2ALPHA 0xf23900c0 -#define F0900_P2_CAR_ALPHA_MANT 0xf2390030 -#define F0900_P2_CAR_ALPHA_EXP 0xf239000f - -/*P2_BCLC*/ -#define R0900_P2_BCLC 0xf23a -#define F0900_P2_STOP_S2BETA 0xf23a00c0 -#define F0900_P2_CAR_BETA_MANT 0xf23a0030 -#define F0900_P2_CAR_BETA_EXP 0xf23a000f - -/*P2_CARFREQ*/ -#define R0900_P2_CARFREQ 0xf23d -#define F0900_P2_KC_COARSE_EXP 0xf23d00f0 -#define F0900_P2_BETA_FREQ 0xf23d000f - -/*P2_CARHDR*/ -#define R0900_P2_CARHDR 0xf23e -#define F0900_P2_K_FREQ_HDR 0xf23e00ff - -/*P2_LDT*/ -#define R0900_P2_LDT 0xf23f -#define F0900_P2_CARLOCK_THRES 0xf23f01ff - -/*P2_LDT2*/ -#define R0900_P2_LDT2 0xf240 -#define F0900_P2_CARLOCK_THRES2 0xf24001ff - -/*P2_CFRICFG*/ -#define R0900_P2_CFRICFG 0xf241 -#define F0900_P2_CFRINIT_UNVALRNG 0xf2410080 -#define F0900_P2_CFRINIT_LUNVALCPT 0xf2410040 -#define F0900_P2_CFRINIT_ABORTDBL 0xf2410020 -#define F0900_P2_CFRINIT_ABORTPRED 0xf2410010 -#define F0900_P2_CFRINIT_UNVALSKIP 0xf2410008 -#define F0900_P2_CFRINIT_CSTINC 0xf2410004 -#define F0900_P2_NEG_CFRSTEP 0xf2410001 - -/*P2_CFRUP1*/ -#define R0900_P2_CFRUP1 0xf242 -#define F0900_P2_CFR_UP1 0xf24201ff - -/*P2_CFRUP0*/ -#define R0900_P2_CFRUP0 0xf243 -#define F0900_P2_CFR_UP0 0xf24300ff - -/*P2_CFRLOW1*/ -#define R0900_P2_CFRLOW1 0xf246 -#define F0900_P2_CFR_LOW1 0xf24601ff - -/*P2_CFRLOW0*/ -#define R0900_P2_CFRLOW0 0xf247 -#define F0900_P2_CFR_LOW0 0xf24700ff - -/*P2_CFRINIT1*/ -#define R0900_P2_CFRINIT1 0xf248 -#define F0900_P2_CFR_INIT1 0xf24801ff - -/*P2_CFRINIT0*/ -#define R0900_P2_CFRINIT0 0xf249 -#define F0900_P2_CFR_INIT0 0xf24900ff - -/*P2_CFRINC1*/ -#define R0900_P2_CFRINC1 0xf24a -#define F0900_P2_MANUAL_CFRINC 0xf24a0080 -#define F0900_P2_CFR_INC1 0xf24a017f - -/*P2_CFRINC0*/ -#define R0900_P2_CFRINC0 0xf24b -#define F0900_P2_CFR_INC0 0xf24b00f0 - -/*P2_CFR2*/ -#define R0900_P2_CFR2 0xf24c -#define F0900_P2_CAR_FREQ2 0xf24c01ff - -/*P2_CFR1*/ -#define R0900_P2_CFR1 0xf24d -#define F0900_P2_CAR_FREQ1 0xf24d00ff - -/*P2_CFR0*/ -#define R0900_P2_CFR0 0xf24e -#define F0900_P2_CAR_FREQ0 0xf24e00ff - -/*P2_LDI*/ -#define R0900_P2_LDI 0xf24f -#define F0900_P2_LOCK_DET_INTEGR 0xf24f01ff - -/*P2_TMGCFG*/ -#define R0900_P2_TMGCFG 0xf250 -#define F0900_P2_TMGLOCK_BETA 0xf25000c0 -#define F0900_P2_NOTMG_GROUPDELAY 0xf2500020 -#define F0900_P2_DO_TIMING_CORR 0xf2500010 -#define F0900_P2_MANUAL_SCAN 0xf250000c -#define F0900_P2_TMG_MINFREQ 0xf2500003 - -/*P2_RTC*/ -#define R0900_P2_RTC 0xf251 -#define F0900_P2_TMGALPHA_EXP 0xf25100f0 -#define F0900_P2_TMGBETA_EXP 0xf251000f - -/*P2_RTCS2*/ -#define R0900_P2_RTCS2 0xf252 -#define F0900_P2_TMGALPHAS2_EXP 0xf25200f0 -#define F0900_P2_TMGBETAS2_EXP 0xf252000f - -/*P2_TMGTHRISE*/ -#define R0900_P2_TMGTHRISE 0xf253 -#define F0900_P2_TMGLOCK_THRISE 0xf25300ff - -/*P2_TMGTHFALL*/ -#define R0900_P2_TMGTHFALL 0xf254 -#define F0900_P2_TMGLOCK_THFALL 0xf25400ff - -/*P2_SFRUPRATIO*/ -#define R0900_P2_SFRUPRATIO 0xf255 -#define F0900_P2_SFR_UPRATIO 0xf25500ff - -/*P2_SFRLOWRATIO*/ -#define R0900_P2_SFRLOWRATIO 0xf256 -#define F0900_P2_SFR_LOWRATIO 0xf25600ff - -/*P2_KREFTMG*/ -#define R0900_P2_KREFTMG 0xf258 -#define F0900_P2_KREF_TMG 0xf25800ff - -/*P2_SFRSTEP*/ -#define R0900_P2_SFRSTEP 0xf259 -#define F0900_P2_SFR_SCANSTEP 0xf25900f0 -#define F0900_P2_SFR_CENTERSTEP 0xf259000f - -/*P2_TMGCFG2*/ -#define R0900_P2_TMGCFG2 0xf25a -#define F0900_P2_DIS_AUTOSAMP 0xf25a0008 -#define F0900_P2_SCANINIT_QUART 0xf25a0004 -#define F0900_P2_NOTMG_DVBS1DERAT 0xf25a0002 -#define F0900_P2_SFRRATIO_FINE 0xf25a0001 - -/*P2_SFRINIT1*/ -#define R0900_P2_SFRINIT1 0xf25e -#define F0900_P2_SFR_INIT1 0xf25e00ff - -/*P2_SFRINIT0*/ -#define R0900_P2_SFRINIT0 0xf25f -#define F0900_P2_SFR_INIT0 0xf25f00ff - -/*P2_SFRUP1*/ -#define R0900_P2_SFRUP1 0xf260 -#define F0900_P2_AUTO_GUP 0xf2600080 -#define F0900_P2_SYMB_FREQ_UP1 0xf260007f - -/*P2_SFRUP0*/ -#define R0900_P2_SFRUP0 0xf261 -#define F0900_P2_SYMB_FREQ_UP0 0xf26100ff - -/*P2_SFRLOW1*/ -#define R0900_P2_SFRLOW1 0xf262 -#define F0900_P2_AUTO_GLOW 0xf2620080 -#define F0900_P2_SYMB_FREQ_LOW1 0xf262007f - -/*P2_SFRLOW0*/ -#define R0900_P2_SFRLOW0 0xf263 -#define F0900_P2_SYMB_FREQ_LOW0 0xf26300ff - -/*P2_SFR3*/ -#define R0900_P2_SFR3 0xf264 -#define F0900_P2_SYMB_FREQ3 0xf26400ff - -/*P2_SFR2*/ -#define R0900_P2_SFR2 0xf265 -#define F0900_P2_SYMB_FREQ2 0xf26500ff - -/*P2_SFR1*/ -#define R0900_P2_SFR1 0xf266 -#define F0900_P2_SYMB_FREQ1 0xf26600ff - -/*P2_SFR0*/ -#define R0900_P2_SFR0 0xf267 -#define F0900_P2_SYMB_FREQ0 0xf26700ff - -/*P2_TMGREG2*/ -#define R0900_P2_TMGREG2 0xf268 -#define F0900_P2_TMGREG2 0xf26800ff - -/*P2_TMGREG1*/ -#define R0900_P2_TMGREG1 0xf269 -#define F0900_P2_TMGREG1 0xf26900ff - -/*P2_TMGREG0*/ -#define R0900_P2_TMGREG0 0xf26a -#define F0900_P2_TMGREG0 0xf26a00ff - -/*P2_TMGLOCK1*/ -#define R0900_P2_TMGLOCK1 0xf26b -#define F0900_P2_TMGLOCK_LEVEL1 0xf26b01ff - -/*P2_TMGLOCK0*/ -#define R0900_P2_TMGLOCK0 0xf26c -#define F0900_P2_TMGLOCK_LEVEL0 0xf26c00ff - -/*P2_TMGOBS*/ -#define R0900_P2_TMGOBS 0xf26d -#define F0900_P2_ROLLOFF_STATUS 0xf26d00c0 -#define F0900_P2_SCAN_SIGN 0xf26d0030 -#define F0900_P2_TMG_SCANNING 0xf26d0008 -#define F0900_P2_CHCENTERING_MODE 0xf26d0004 -#define F0900_P2_TMG_SCANFAIL 0xf26d0002 - -/*P2_EQUALCFG*/ -#define R0900_P2_EQUALCFG 0xf26f -#define F0900_P2_NOTMG_NEGALWAIT 0xf26f0080 -#define F0900_P2_EQUAL_ON 0xf26f0040 -#define F0900_P2_SEL_EQUALCOR 0xf26f0038 -#define F0900_P2_MU_EQUALDFE 0xf26f0007 - -/*P2_EQUAI1*/ -#define R0900_P2_EQUAI1 0xf270 -#define F0900_P2_EQUA_ACCI1 0xf27001ff - -/*P2_EQUAQ1*/ -#define R0900_P2_EQUAQ1 0xf271 -#define F0900_P2_EQUA_ACCQ1 0xf27101ff - -/*P2_EQUAI2*/ -#define R0900_P2_EQUAI2 0xf272 -#define F0900_P2_EQUA_ACCI2 0xf27201ff - -/*P2_EQUAQ2*/ -#define R0900_P2_EQUAQ2 0xf273 -#define F0900_P2_EQUA_ACCQ2 0xf27301ff - -/*P2_EQUAI3*/ -#define R0900_P2_EQUAI3 0xf274 -#define F0900_P2_EQUA_ACCI3 0xf27401ff - -/*P2_EQUAQ3*/ -#define R0900_P2_EQUAQ3 0xf275 -#define F0900_P2_EQUA_ACCQ3 0xf27501ff - -/*P2_EQUAI4*/ -#define R0900_P2_EQUAI4 0xf276 -#define F0900_P2_EQUA_ACCI4 0xf27601ff - -/*P2_EQUAQ4*/ -#define R0900_P2_EQUAQ4 0xf277 -#define F0900_P2_EQUA_ACCQ4 0xf27701ff - -/*P2_EQUAI5*/ -#define R0900_P2_EQUAI5 0xf278 -#define F0900_P2_EQUA_ACCI5 0xf27801ff - -/*P2_EQUAQ5*/ -#define R0900_P2_EQUAQ5 0xf279 -#define F0900_P2_EQUA_ACCQ5 0xf27901ff - -/*P2_EQUAI6*/ -#define R0900_P2_EQUAI6 0xf27a -#define F0900_P2_EQUA_ACCI6 0xf27a01ff - -/*P2_EQUAQ6*/ -#define R0900_P2_EQUAQ6 0xf27b -#define F0900_P2_EQUA_ACCQ6 0xf27b01ff - -/*P2_EQUAI7*/ -#define R0900_P2_EQUAI7 0xf27c -#define F0900_P2_EQUA_ACCI7 0xf27c01ff - -/*P2_EQUAQ7*/ -#define R0900_P2_EQUAQ7 0xf27d -#define F0900_P2_EQUA_ACCQ7 0xf27d01ff - -/*P2_EQUAI8*/ -#define R0900_P2_EQUAI8 0xf27e -#define F0900_P2_EQUA_ACCI8 0xf27e01ff - -/*P2_EQUAQ8*/ -#define R0900_P2_EQUAQ8 0xf27f -#define F0900_P2_EQUA_ACCQ8 0xf27f01ff - -/*P2_NNOSDATAT1*/ -#define R0900_P2_NNOSDATAT1 0xf280 -#define F0900_P2_NOSDATAT_NORMED1 0xf28000ff - -/*P2_NNOSDATAT0*/ -#define R0900_P2_NNOSDATAT0 0xf281 -#define F0900_P2_NOSDATAT_NORMED0 0xf28100ff - -/*P2_NNOSDATA1*/ -#define R0900_P2_NNOSDATA1 0xf282 -#define F0900_P2_NOSDATA_NORMED1 0xf28200ff - -/*P2_NNOSDATA0*/ -#define R0900_P2_NNOSDATA0 0xf283 -#define F0900_P2_NOSDATA_NORMED0 0xf28300ff - -/*P2_NNOSPLHT1*/ -#define R0900_P2_NNOSPLHT1 0xf284 -#define F0900_P2_NOSPLHT_NORMED1 0xf28400ff - -/*P2_NNOSPLHT0*/ -#define R0900_P2_NNOSPLHT0 0xf285 -#define F0900_P2_NOSPLHT_NORMED0 0xf28500ff - -/*P2_NNOSPLH1*/ -#define R0900_P2_NNOSPLH1 0xf286 -#define F0900_P2_NOSPLH_NORMED1 0xf28600ff - -/*P2_NNOSPLH0*/ -#define R0900_P2_NNOSPLH0 0xf287 -#define F0900_P2_NOSPLH_NORMED0 0xf28700ff - -/*P2_NOSDATAT1*/ -#define R0900_P2_NOSDATAT1 0xf288 -#define F0900_P2_NOSDATAT_UNNORMED1 0xf28800ff - -/*P2_NOSDATAT0*/ -#define R0900_P2_NOSDATAT0 0xf289 -#define F0900_P2_NOSDATAT_UNNORMED0 0xf28900ff - -/*P2_NOSDATA1*/ -#define R0900_P2_NOSDATA1 0xf28a -#define F0900_P2_NOSDATA_UNNORMED1 0xf28a00ff - -/*P2_NOSDATA0*/ -#define R0900_P2_NOSDATA0 0xf28b -#define F0900_P2_NOSDATA_UNNORMED0 0xf28b00ff - -/*P2_NOSPLHT1*/ -#define R0900_P2_NOSPLHT1 0xf28c -#define F0900_P2_NOSPLHT_UNNORMED1 0xf28c00ff - -/*P2_NOSPLHT0*/ -#define R0900_P2_NOSPLHT0 0xf28d -#define F0900_P2_NOSPLHT_UNNORMED0 0xf28d00ff - -/*P2_NOSPLH1*/ -#define R0900_P2_NOSPLH1 0xf28e -#define F0900_P2_NOSPLH_UNNORMED1 0xf28e00ff - -/*P2_NOSPLH0*/ -#define R0900_P2_NOSPLH0 0xf28f -#define F0900_P2_NOSPLH_UNNORMED0 0xf28f00ff - -/*P2_CAR2CFG*/ -#define R0900_P2_CAR2CFG 0xf290 -#define F0900_P2_DESCRAMB_OFF 0xf2900080 -#define F0900_P2_PN4_SELECT 0xf2900040 -#define F0900_P2_CFR2_STOPDVBS1 0xf2900020 -#define F0900_P2_STOP_CFR2UPDATE 0xf2900010 -#define F0900_P2_STOP_NCO2UPDATE 0xf2900008 -#define F0900_P2_ROTA2ON 0xf2900004 -#define F0900_P2_PH_DET_ALGO2 0xf2900003 - -/*P2_ACLC2*/ -#define R0900_P2_ACLC2 0xf291 -#define F0900_P2_CAR2_PUNCT_ADERAT 0xf2910040 -#define F0900_P2_CAR2_ALPHA_MANT 0xf2910030 -#define F0900_P2_CAR2_ALPHA_EXP 0xf291000f - -/*P2_BCLC2*/ -#define R0900_P2_BCLC2 0xf292 -#define F0900_P2_DVBS2_NIP 0xf2920080 -#define F0900_P2_CAR2_PUNCT_BDERAT 0xf2920040 -#define F0900_P2_CAR2_BETA_MANT 0xf2920030 -#define F0900_P2_CAR2_BETA_EXP 0xf292000f - -/*P2_CFR22*/ -#define R0900_P2_CFR22 0xf293 -#define F0900_P2_CAR2_FREQ2 0xf29301ff - -/*P2_CFR21*/ -#define R0900_P2_CFR21 0xf294 -#define F0900_P2_CAR2_FREQ1 0xf29400ff - -/*P2_CFR20*/ -#define R0900_P2_CFR20 0xf295 -#define F0900_P2_CAR2_FREQ0 0xf29500ff - -/*P2_ACLC2S2Q*/ -#define R0900_P2_ACLC2S2Q 0xf297 -#define F0900_P2_ENAB_SPSKSYMB 0xf2970080 -#define F0900_P2_CAR2S2_QADERAT 0xf2970040 -#define F0900_P2_CAR2S2_Q_ALPH_M 0xf2970030 -#define F0900_P2_CAR2S2_Q_ALPH_E 0xf297000f - -/*P2_ACLC2S28*/ -#define R0900_P2_ACLC2S28 0xf298 -#define F0900_P2_OLDI3Q_MODE 0xf2980080 -#define F0900_P2_CAR2S2_8ADERAT 0xf2980040 -#define F0900_P2_CAR2S2_8_ALPH_M 0xf2980030 -#define F0900_P2_CAR2S2_8_ALPH_E 0xf298000f - -/*P2_ACLC2S216A*/ -#define R0900_P2_ACLC2S216A 0xf299 -#define F0900_P2_CAR2S2_16ADERAT 0xf2990040 -#define F0900_P2_CAR2S2_16A_ALPH_M 0xf2990030 -#define F0900_P2_CAR2S2_16A_ALPH_E 0xf299000f - -/*P2_ACLC2S232A*/ -#define R0900_P2_ACLC2S232A 0xf29a -#define F0900_P2_CAR2S2_32ADERAT 0xf29a0040 -#define F0900_P2_CAR2S2_32A_ALPH_M 0xf29a0030 -#define F0900_P2_CAR2S2_32A_ALPH_E 0xf29a000f - -/*P2_BCLC2S2Q*/ -#define R0900_P2_BCLC2S2Q 0xf29c -#define F0900_P2_DVBS2S2Q_NIP 0xf29c0080 -#define F0900_P2_CAR2S2_QBDERAT 0xf29c0040 -#define F0900_P2_CAR2S2_Q_BETA_M 0xf29c0030 -#define F0900_P2_CAR2S2_Q_BETA_E 0xf29c000f - -/*P2_BCLC2S28*/ -#define R0900_P2_BCLC2S28 0xf29d -#define F0900_P2_DVBS2S28_NIP 0xf29d0080 -#define F0900_P2_CAR2S2_8BDERAT 0xf29d0040 -#define F0900_P2_CAR2S2_8_BETA_M 0xf29d0030 -#define F0900_P2_CAR2S2_8_BETA_E 0xf29d000f - -/*P2_BCLC2S216A*/ -#define R0900_P2_BCLC2S216A 0xf29e -#define F0900_P2_DVBS2S216A_NIP 0xf29e0080 -#define F0900_P2_CAR2S2_16BDERAT 0xf29e0040 -#define F0900_P2_CAR2S2_16A_BETA_M 0xf29e0030 -#define F0900_P2_CAR2S2_16A_BETA_E 0xf29e000f - -/*P2_BCLC2S232A*/ -#define R0900_P2_BCLC2S232A 0xf29f -#define F0900_P2_DVBS2S232A_NIP 0xf29f0080 -#define F0900_P2_CAR2S2_32BDERAT 0xf29f0040 -#define F0900_P2_CAR2S2_32A_BETA_M 0xf29f0030 -#define F0900_P2_CAR2S2_32A_BETA_E 0xf29f000f - -/*P2_PLROOT2*/ -#define R0900_P2_PLROOT2 0xf2ac -#define F0900_P2_SHORTFR_DISABLE 0xf2ac0080 -#define F0900_P2_LONGFR_DISABLE 0xf2ac0040 -#define F0900_P2_DUMMYPL_DISABLE 0xf2ac0020 -#define F0900_P2_SHORTFR_AVOID 0xf2ac0010 -#define F0900_P2_PLSCRAMB_MODE 0xf2ac000c -#define F0900_P2_PLSCRAMB_ROOT2 0xf2ac0003 - -/*P2_PLROOT1*/ -#define R0900_P2_PLROOT1 0xf2ad -#define F0900_P2_PLSCRAMB_ROOT1 0xf2ad00ff - -/*P2_PLROOT0*/ -#define R0900_P2_PLROOT0 0xf2ae -#define F0900_P2_PLSCRAMB_ROOT0 0xf2ae00ff - -/*P2_MODCODLST0*/ -#define R0900_P2_MODCODLST0 0xf2b0 -#define F0900_P2_EN_TOKEN31 0xf2b00080 -#define F0900_P2_SYNCTAG_SELECT 0xf2b00040 -#define F0900_P2_MODCODRQ_MODE 0xf2b00030 - -/*P2_MODCODLST1*/ -#define R0900_P2_MODCODLST1 0xf2b1 -#define F0900_P2_DIS_MODCOD29 0xf2b100f0 -#define F0900_P2_DIS_32PSK_9_10 0xf2b1000f - -/*P2_MODCODLST2*/ -#define R0900_P2_MODCODLST2 0xf2b2 -#define F0900_P2_DIS_32PSK_8_9 0xf2b200f0 -#define F0900_P2_DIS_32PSK_5_6 0xf2b2000f - -/*P2_MODCODLST3*/ -#define R0900_P2_MODCODLST3 0xf2b3 -#define F0900_P2_DIS_32PSK_4_5 0xf2b300f0 -#define F0900_P2_DIS_32PSK_3_4 0xf2b3000f - -/*P2_MODCODLST4*/ -#define R0900_P2_MODCODLST4 0xf2b4 -#define F0900_P2_DIS_16PSK_9_10 0xf2b400f0 -#define F0900_P2_DIS_16PSK_8_9 0xf2b4000f - -/*P2_MODCODLST5*/ -#define R0900_P2_MODCODLST5 0xf2b5 -#define F0900_P2_DIS_16PSK_5_6 0xf2b500f0 -#define F0900_P2_DIS_16PSK_4_5 0xf2b5000f - -/*P2_MODCODLST6*/ -#define R0900_P2_MODCODLST6 0xf2b6 -#define F0900_P2_DIS_16PSK_3_4 0xf2b600f0 -#define F0900_P2_DIS_16PSK_2_3 0xf2b6000f - -/*P2_MODCODLST7*/ -#define R0900_P2_MODCODLST7 0xf2b7 -#define F0900_P2_DIS_8P_9_10 0xf2b700f0 -#define F0900_P2_DIS_8P_8_9 0xf2b7000f - -/*P2_MODCODLST8*/ -#define R0900_P2_MODCODLST8 0xf2b8 -#define F0900_P2_DIS_8P_5_6 0xf2b800f0 -#define F0900_P2_DIS_8P_3_4 0xf2b8000f - -/*P2_MODCODLST9*/ -#define R0900_P2_MODCODLST9 0xf2b9 -#define F0900_P2_DIS_8P_2_3 0xf2b900f0 -#define F0900_P2_DIS_8P_3_5 0xf2b9000f - -/*P2_MODCODLSTA*/ -#define R0900_P2_MODCODLSTA 0xf2ba -#define F0900_P2_DIS_QP_9_10 0xf2ba00f0 -#define F0900_P2_DIS_QP_8_9 0xf2ba000f - -/*P2_MODCODLSTB*/ -#define R0900_P2_MODCODLSTB 0xf2bb -#define F0900_P2_DIS_QP_5_6 0xf2bb00f0 -#define F0900_P2_DIS_QP_4_5 0xf2bb000f - -/*P2_MODCODLSTC*/ -#define R0900_P2_MODCODLSTC 0xf2bc -#define F0900_P2_DIS_QP_3_4 0xf2bc00f0 -#define F0900_P2_DIS_QP_2_3 0xf2bc000f - -/*P2_MODCODLSTD*/ -#define R0900_P2_MODCODLSTD 0xf2bd -#define F0900_P2_DIS_QP_3_5 0xf2bd00f0 -#define F0900_P2_DIS_QP_1_2 0xf2bd000f - -/*P2_MODCODLSTE*/ -#define R0900_P2_MODCODLSTE 0xf2be -#define F0900_P2_DIS_QP_2_5 0xf2be00f0 -#define F0900_P2_DIS_QP_1_3 0xf2be000f - -/*P2_MODCODLSTF*/ -#define R0900_P2_MODCODLSTF 0xf2bf -#define F0900_P2_DIS_QP_1_4 0xf2bf00f0 -#define F0900_P2_DDEMOD_SET 0xf2bf0002 -#define F0900_P2_DDEMOD_MASK 0xf2bf0001 - -/*P2_DMDRESCFG*/ -#define R0900_P2_DMDRESCFG 0xf2c6 -#define F0900_P2_DMDRES_RESET 0xf2c60080 -#define F0900_P2_DMDRES_NOISESQR 0xf2c60010 -#define F0900_P2_DMDRES_STRALL 0xf2c60008 -#define F0900_P2_DMDRES_NEWONLY 0xf2c60004 -#define F0900_P2_DMDRES_NOSTORE 0xf2c60002 -#define F0900_P2_DMDRES_AGC2MEM 0xf2c60001 - -/*P2_DMDRESADR*/ -#define R0900_P2_DMDRESADR 0xf2c7 -#define F0900_P2_SUSP_PREDCANAL 0xf2c70080 -#define F0900_P2_DMDRES_VALIDCFR 0xf2c70040 -#define F0900_P2_DMDRES_MEMFULL 0xf2c70030 -#define F0900_P2_DMDRES_RESNBR 0xf2c7000f - -/*P2_DMDRESDATA7*/ -#define R0900_P2_DMDRESDATA7 0xf2c8 -#define F0900_P2_DMDRES_DATA7 0xf2c800ff - -/*P2_DMDRESDATA6*/ -#define R0900_P2_DMDRESDATA6 0xf2c9 -#define F0900_P2_DMDRES_DATA6 0xf2c900ff - -/*P2_DMDRESDATA5*/ -#define R0900_P2_DMDRESDATA5 0xf2ca -#define F0900_P2_DMDRES_DATA5 0xf2ca00ff - -/*P2_DMDRESDATA4*/ -#define R0900_P2_DMDRESDATA4 0xf2cb -#define F0900_P2_DMDRES_DATA4 0xf2cb00ff - -/*P2_DMDRESDATA3*/ -#define R0900_P2_DMDRESDATA3 0xf2cc -#define F0900_P2_DMDRES_DATA3 0xf2cc00ff - -/*P2_DMDRESDATA2*/ -#define R0900_P2_DMDRESDATA2 0xf2cd -#define F0900_P2_DMDRES_DATA2 0xf2cd00ff - -/*P2_DMDRESDATA1*/ -#define R0900_P2_DMDRESDATA1 0xf2ce -#define F0900_P2_DMDRES_DATA1 0xf2ce00ff - -/*P2_DMDRESDATA0*/ -#define R0900_P2_DMDRESDATA0 0xf2cf -#define F0900_P2_DMDRES_DATA0 0xf2cf00ff - -/*P2_FFEI1*/ -#define R0900_P2_FFEI1 0xf2d0 -#define F0900_P2_FFE_ACCI1 0xf2d001ff - -/*P2_FFEQ1*/ -#define R0900_P2_FFEQ1 0xf2d1 -#define F0900_P2_FFE_ACCQ1 0xf2d101ff - -/*P2_FFEI2*/ -#define R0900_P2_FFEI2 0xf2d2 -#define F0900_P2_FFE_ACCI2 0xf2d201ff - -/*P2_FFEQ2*/ -#define R0900_P2_FFEQ2 0xf2d3 -#define F0900_P2_FFE_ACCQ2 0xf2d301ff - -/*P2_FFEI3*/ -#define R0900_P2_FFEI3 0xf2d4 -#define F0900_P2_FFE_ACCI3 0xf2d401ff - -/*P2_FFEQ3*/ -#define R0900_P2_FFEQ3 0xf2d5 -#define F0900_P2_FFE_ACCQ3 0xf2d501ff - -/*P2_FFEI4*/ -#define R0900_P2_FFEI4 0xf2d6 -#define F0900_P2_FFE_ACCI4 0xf2d601ff - -/*P2_FFEQ4*/ -#define R0900_P2_FFEQ4 0xf2d7 -#define F0900_P2_FFE_ACCQ4 0xf2d701ff - -/*P2_FFECFG*/ -#define R0900_P2_FFECFG 0xf2d8 -#define F0900_P2_EQUALFFE_ON 0xf2d80040 -#define F0900_P2_EQUAL_USEDSYMB 0xf2d80030 -#define F0900_P2_MU_EQUALFFE 0xf2d80007 - -/*P2_TNRCFG*/ -#define R0900_P2_TNRCFG 0xf2e0 -#define F0900_P2_TUN_ACKFAIL 0xf2e00080 -#define F0900_P2_TUN_TYPE 0xf2e00070 -#define F0900_P2_TUN_SECSTOP 0xf2e00008 -#define F0900_P2_TUN_VCOSRCH 0xf2e00004 -#define F0900_P2_TUN_MADDRESS 0xf2e00003 - -/*P2_TNRCFG2*/ -#define R0900_P2_TNRCFG2 0xf2e1 -#define F0900_P2_TUN_IQSWAP 0xf2e10080 -#define F0900_P2_STB6110_STEP2MHZ 0xf2e10040 -#define F0900_P2_STB6120_DBLI2C 0xf2e10020 -#define F0900_P2_DIS_FCCK 0xf2e10010 -#define F0900_P2_DIS_LPEN 0xf2e10008 -#define F0900_P2_DIS_BWCALC 0xf2e10004 -#define F0900_P2_SHORT_WAITSTATES 0xf2e10002 -#define F0900_P2_DIS_2BWAGC1 0xf2e10001 - -/*P2_TNRXTAL*/ -#define R0900_P2_TNRXTAL 0xf2e4 -#define F0900_P2_TUN_MCLKDECIMAL 0xf2e400e0 -#define F0900_P2_TUN_XTALFREQ 0xf2e4001f - -/*P2_TNRSTEPS*/ -#define R0900_P2_TNRSTEPS 0xf2e7 -#define F0900_P2_TUNER_BW1P6 0xf2e70080 -#define F0900_P2_BWINC_OFFSET 0xf2e70070 -#define F0900_P2_SOFTSTEP_RNG 0xf2e70008 -#define F0900_P2_TUN_BWOFFSET 0xf2e70107 - -/*P2_TNRGAIN*/ -#define R0900_P2_TNRGAIN 0xf2e8 -#define F0900_P2_TUN_KDIVEN 0xf2e800c0 -#define F0900_P2_STB6X00_OCK 0xf2e80030 -#define F0900_P2_TUN_GAIN 0xf2e8000f - -/*P2_TNRRF1*/ -#define R0900_P2_TNRRF1 0xf2e9 -#define F0900_P2_TUN_RFFREQ2 0xf2e900ff - -/*P2_TNRRF0*/ -#define R0900_P2_TNRRF0 0xf2ea -#define F0900_P2_TUN_RFFREQ1 0xf2ea00ff - -/*P2_TNRBW*/ -#define R0900_P2_TNRBW 0xf2eb -#define F0900_P2_TUN_RFFREQ0 0xf2eb00c0 -#define F0900_P2_TUN_BW 0xf2eb003f - -/*P2_TNRADJ*/ -#define R0900_P2_TNRADJ 0xf2ec -#define F0900_P2_STB61X0_RCLK 0xf2ec0080 -#define F0900_P2_STB61X0_CALTIME 0xf2ec0040 -#define F0900_P2_STB6X00_DLB 0xf2ec0038 -#define F0900_P2_STB6000_FCL 0xf2ec0007 - -/*P2_TNRCTL2*/ -#define R0900_P2_TNRCTL2 0xf2ed -#define F0900_P2_STB61X0_LCP1_RCCKOFF 0xf2ed0080 -#define F0900_P2_STB61X0_LCP0 0xf2ed0040 -#define F0900_P2_STB61X0_XTOUT_RFOUTS 0xf2ed0020 -#define F0900_P2_STB61X0_XTON_MCKDV 0xf2ed0010 -#define F0900_P2_STB61X0_CALOFF_DCOFF 0xf2ed0008 -#define F0900_P2_STB6110_LPT 0xf2ed0004 -#define F0900_P2_STB6110_RX 0xf2ed0002 -#define F0900_P2_STB6110_SYN 0xf2ed0001 - -/*P2_TNRCFG3*/ -#define R0900_P2_TNRCFG3 0xf2ee -#define F0900_P2_STB6120_DISCTRL1 0xf2ee0080 -#define F0900_P2_STB6120_INVORDER 0xf2ee0040 -#define F0900_P2_STB6120_ENCTRL6 0xf2ee0020 -#define F0900_P2_TUN_PLLFREQ 0xf2ee001c -#define F0900_P2_TUN_I2CFREQ_MODE 0xf2ee0003 - -/*P2_TNRLAUNCH*/ -#define R0900_P2_TNRLAUNCH 0xf2f0 - -/*P2_TNRLD*/ -#define R0900_P2_TNRLD 0xf2f0 -#define F0900_P2_TUNLD_VCOING 0xf2f00080 -#define F0900_P2_TUN_REG1FAIL 0xf2f00040 -#define F0900_P2_TUN_REG2FAIL 0xf2f00020 -#define F0900_P2_TUN_REG3FAIL 0xf2f00010 -#define F0900_P2_TUN_REG4FAIL 0xf2f00008 -#define F0900_P2_TUN_REG5FAIL 0xf2f00004 -#define F0900_P2_TUN_BWING 0xf2f00002 -#define F0900_P2_TUN_LOCKED 0xf2f00001 - -/*P2_TNROBSL*/ -#define R0900_P2_TNROBSL 0xf2f6 -#define F0900_P2_TUN_I2CABORTED 0xf2f60080 -#define F0900_P2_TUN_LPEN 0xf2f60040 -#define F0900_P2_TUN_FCCK 0xf2f60020 -#define F0900_P2_TUN_I2CLOCKED 0xf2f60010 -#define F0900_P2_TUN_PROGDONE 0xf2f6000c -#define F0900_P2_TUN_RFRESTE1 0xf2f60003 - -/*P2_TNRRESTE*/ -#define R0900_P2_TNRRESTE 0xf2f7 -#define F0900_P2_TUN_RFRESTE0 0xf2f700ff - -/*P2_SMAPCOEF7*/ -#define R0900_P2_SMAPCOEF7 0xf300 -#define F0900_P2_DIS_QSCALE 0xf3000080 -#define F0900_P2_SMAPCOEF_Q_LLR12 0xf300017f - -/*P2_SMAPCOEF6*/ -#define R0900_P2_SMAPCOEF6 0xf301 -#define F0900_P2_DIS_NEWSCALE 0xf3010008 -#define F0900_P2_ADJ_8PSKLLR1 0xf3010004 -#define F0900_P2_OLD_8PSKLLR1 0xf3010002 -#define F0900_P2_DIS_AB8PSK 0xf3010001 - -/*P2_SMAPCOEF5*/ -#define R0900_P2_SMAPCOEF5 0xf302 -#define F0900_P2_DIS_8SCALE 0xf3020080 -#define F0900_P2_SMAPCOEF_8P_LLR23 0xf302017f - -/*P2_DMDPLHSTAT*/ -#define R0900_P2_DMDPLHSTAT 0xf320 -#define F0900_P2_PLH_STATISTIC 0xf32000ff - -/*P2_LOCKTIME3*/ -#define R0900_P2_LOCKTIME3 0xf322 -#define F0900_P2_DEMOD_LOCKTIME3 0xf32200ff - -/*P2_LOCKTIME2*/ -#define R0900_P2_LOCKTIME2 0xf323 -#define F0900_P2_DEMOD_LOCKTIME2 0xf32300ff - -/*P2_LOCKTIME1*/ -#define R0900_P2_LOCKTIME1 0xf324 -#define F0900_P2_DEMOD_LOCKTIME1 0xf32400ff - -/*P2_LOCKTIME0*/ -#define R0900_P2_LOCKTIME0 0xf325 -#define F0900_P2_DEMOD_LOCKTIME0 0xf32500ff - -/*P2_VITSCALE*/ -#define R0900_P2_VITSCALE 0xf332 -#define F0900_P2_NVTH_NOSRANGE 0xf3320080 -#define F0900_P2_VERROR_MAXMODE 0xf3320040 -#define F0900_P2_KDIV_MODE 0xf3320030 -#define F0900_P2_NSLOWSN_LOCKED 0xf3320008 -#define F0900_P2_DELOCK_PRFLOSS 0xf3320004 -#define F0900_P2_DIS_RSFLOCK 0xf3320002 - -/*P2_FECM*/ -#define R0900_P2_FECM 0xf333 -#define F0900_P2_DSS_DVB 0xf3330080 -#define F0900_P2_DEMOD_BYPASS 0xf3330040 -#define F0900_P2_CMP_SLOWMODE 0xf3330020 -#define F0900_P2_DSS_SRCH 0xf3330010 -#define F0900_P2_DIFF_MODEVIT 0xf3330004 -#define F0900_P2_SYNCVIT 0xf3330002 -#define F0900_P2_IQINV 0xf3330001 - -/*P2_VTH12*/ -#define R0900_P2_VTH12 0xf334 -#define F0900_P2_VTH12 0xf33400ff - -/*P2_VTH23*/ -#define R0900_P2_VTH23 0xf335 -#define F0900_P2_VTH23 0xf33500ff - -/*P2_VTH34*/ -#define R0900_P2_VTH34 0xf336 -#define F0900_P2_VTH34 0xf33600ff - -/*P2_VTH56*/ -#define R0900_P2_VTH56 0xf337 -#define F0900_P2_VTH56 0xf33700ff - -/*P2_VTH67*/ -#define R0900_P2_VTH67 0xf338 -#define F0900_P2_VTH67 0xf33800ff - -/*P2_VTH78*/ -#define R0900_P2_VTH78 0xf339 -#define F0900_P2_VTH78 0xf33900ff - -/*P2_VITCURPUN*/ -#define R0900_P2_VITCURPUN 0xf33a -#define F0900_P2_VIT_MAPPING 0xf33a00e0 -#define F0900_P2_VIT_CURPUN 0xf33a001f - -/*P2_VERROR*/ -#define R0900_P2_VERROR 0xf33b -#define F0900_P2_REGERR_VIT 0xf33b00ff - -/*P2_PRVIT*/ -#define R0900_P2_PRVIT 0xf33c -#define F0900_P2_DIS_VTHLOCK 0xf33c0040 -#define F0900_P2_E7_8VIT 0xf33c0020 -#define F0900_P2_E6_7VIT 0xf33c0010 -#define F0900_P2_E5_6VIT 0xf33c0008 -#define F0900_P2_E3_4VIT 0xf33c0004 -#define F0900_P2_E2_3VIT 0xf33c0002 -#define F0900_P2_E1_2VIT 0xf33c0001 - -/*P2_VAVSRVIT*/ -#define R0900_P2_VAVSRVIT 0xf33d -#define F0900_P2_AMVIT 0xf33d0080 -#define F0900_P2_FROZENVIT 0xf33d0040 -#define F0900_P2_SNVIT 0xf33d0030 -#define F0900_P2_TOVVIT 0xf33d000c -#define F0900_P2_HYPVIT 0xf33d0003 - -/*P2_VSTATUSVIT*/ -#define R0900_P2_VSTATUSVIT 0xf33e -#define F0900_P2_VITERBI_ON 0xf33e0080 -#define F0900_P2_END_LOOPVIT 0xf33e0040 -#define F0900_P2_VITERBI_DEPRF 0xf33e0020 -#define F0900_P2_PRFVIT 0xf33e0010 -#define F0900_P2_LOCKEDVIT 0xf33e0008 -#define F0900_P2_VITERBI_DELOCK 0xf33e0004 -#define F0900_P2_VIT_DEMODSEL 0xf33e0002 -#define F0900_P2_VITERBI_COMPOUT 0xf33e0001 - -/*P2_VTHINUSE*/ -#define R0900_P2_VTHINUSE 0xf33f -#define F0900_P2_VIT_INUSE 0xf33f00ff - -/*P2_KDIV12*/ -#define R0900_P2_KDIV12 0xf340 -#define F0900_P2_KDIV12_MANUAL 0xf3400080 -#define F0900_P2_K_DIVIDER_12 0xf340007f - -/*P2_KDIV23*/ -#define R0900_P2_KDIV23 0xf341 -#define F0900_P2_KDIV23_MANUAL 0xf3410080 -#define F0900_P2_K_DIVIDER_23 0xf341007f - -/*P2_KDIV34*/ -#define R0900_P2_KDIV34 0xf342 -#define F0900_P2_KDIV34_MANUAL 0xf3420080 -#define F0900_P2_K_DIVIDER_34 0xf342007f - -/*P2_KDIV56*/ -#define R0900_P2_KDIV56 0xf343 -#define F0900_P2_KDIV56_MANUAL 0xf3430080 -#define F0900_P2_K_DIVIDER_56 0xf343007f - -/*P2_KDIV67*/ -#define R0900_P2_KDIV67 0xf344 -#define F0900_P2_KDIV67_MANUAL 0xf3440080 -#define F0900_P2_K_DIVIDER_67 0xf344007f - -/*P2_KDIV78*/ -#define R0900_P2_KDIV78 0xf345 -#define F0900_P2_KDIV78_MANUAL 0xf3450080 -#define F0900_P2_K_DIVIDER_78 0xf345007f - -/*P2_PDELCTRL1*/ -#define R0900_P2_PDELCTRL1 0xf350 -#define F0900_P2_INV_MISMASK 0xf3500080 -#define F0900_P2_FORCE_ACCEPTED 0xf3500040 -#define F0900_P2_FILTER_EN 0xf3500020 -#define F0900_P2_FORCE_PKTDELINUSE 0xf3500010 -#define F0900_P2_HYSTEN 0xf3500008 -#define F0900_P2_HYSTSWRST 0xf3500004 -#define F0900_P2_EN_MIS00 0xf3500002 -#define F0900_P2_ALGOSWRST 0xf3500001 - -/*P2_PDELCTRL2*/ -#define R0900_P2_PDELCTRL2 0xf351 -#define F0900_P2_FORCE_CONTINUOUS 0xf3510080 -#define F0900_P2_RESET_UPKO_COUNT 0xf3510040 -#define F0900_P2_USER_PKTDELIN_NB 0xf3510020 -#define F0900_P2_FORCE_LOCKED 0xf3510010 -#define F0900_P2_DATA_UNBBSCRAM 0xf3510008 -#define F0900_P2_FORCE_LONGPKT 0xf3510004 -#define F0900_P2_FRAME_MODE 0xf3510002 - -/*P2_HYSTTHRESH*/ -#define R0900_P2_HYSTTHRESH 0xf354 -#define F0900_P2_UNLCK_THRESH 0xf35400f0 -#define F0900_P2_DELIN_LCK_THRESH 0xf354000f - -/*P2_ISIENTRY*/ -#define R0900_P2_ISIENTRY 0xf35e -#define F0900_P2_ISI_ENTRY 0xf35e00ff - -/*P2_ISIBITENA*/ -#define R0900_P2_ISIBITENA 0xf35f -#define F0900_P2_ISI_BIT_EN 0xf35f00ff - -/*P2_MATSTR1*/ -#define R0900_P2_MATSTR1 0xf360 -#define F0900_P2_MATYPE_CURRENT1 0xf36000ff - -/*P2_MATSTR0*/ -#define R0900_P2_MATSTR0 0xf361 -#define F0900_P2_MATYPE_CURRENT0 0xf36100ff - -/*P2_UPLSTR1*/ -#define R0900_P2_UPLSTR1 0xf362 -#define F0900_P2_UPL_CURRENT1 0xf36200ff - -/*P2_UPLSTR0*/ -#define R0900_P2_UPLSTR0 0xf363 -#define F0900_P2_UPL_CURRENT0 0xf36300ff - -/*P2_DFLSTR1*/ -#define R0900_P2_DFLSTR1 0xf364 -#define F0900_P2_DFL_CURRENT1 0xf36400ff - -/*P2_DFLSTR0*/ -#define R0900_P2_DFLSTR0 0xf365 -#define F0900_P2_DFL_CURRENT0 0xf36500ff - -/*P2_SYNCSTR*/ -#define R0900_P2_SYNCSTR 0xf366 -#define F0900_P2_SYNC_CURRENT 0xf36600ff - -/*P2_SYNCDSTR1*/ -#define R0900_P2_SYNCDSTR1 0xf367 -#define F0900_P2_SYNCD_CURRENT1 0xf36700ff - -/*P2_SYNCDSTR0*/ -#define R0900_P2_SYNCDSTR0 0xf368 -#define F0900_P2_SYNCD_CURRENT0 0xf36800ff - -/*P2_PDELSTATUS1*/ -#define R0900_P2_PDELSTATUS1 0xf369 -#define F0900_P2_PKTDELIN_DELOCK 0xf3690080 -#define F0900_P2_SYNCDUPDFL_BADDFL 0xf3690040 -#define F0900_P2_CONTINUOUS_STREAM 0xf3690020 -#define F0900_P2_UNACCEPTED_STREAM 0xf3690010 -#define F0900_P2_BCH_ERROR_FLAG 0xf3690008 -#define F0900_P2_BBHCRCKO 0xf3690004 -#define F0900_P2_PKTDELIN_LOCK 0xf3690002 -#define F0900_P2_FIRST_LOCK 0xf3690001 - -/*P2_PDELSTATUS2*/ -#define R0900_P2_PDELSTATUS2 0xf36a -#define F0900_P2_PKTDEL_DEMODSEL 0xf36a0080 -#define F0900_P2_FRAME_MODCOD 0xf36a007c -#define F0900_P2_FRAME_TYPE 0xf36a0003 - -/*P2_BBFCRCKO1*/ -#define R0900_P2_BBFCRCKO1 0xf36b -#define F0900_P2_BBHCRC_KOCNT1 0xf36b00ff - -/*P2_BBFCRCKO0*/ -#define R0900_P2_BBFCRCKO0 0xf36c -#define F0900_P2_BBHCRC_KOCNT0 0xf36c00ff - -/*P2_UPCRCKO1*/ -#define R0900_P2_UPCRCKO1 0xf36d -#define F0900_P2_PKTCRC_KOCNT1 0xf36d00ff - -/*P2_UPCRCKO0*/ -#define R0900_P2_UPCRCKO0 0xf36e -#define F0900_P2_PKTCRC_KOCNT0 0xf36e00ff - -/*P2_TSSTATEM*/ -#define R0900_P2_TSSTATEM 0xf370 -#define F0900_P2_TSDIL_ON 0xf3700080 -#define F0900_P2_TSSKIPRS_ON 0xf3700040 -#define F0900_P2_TSRS_ON 0xf3700020 -#define F0900_P2_TSDESCRAMB_ON 0xf3700010 -#define F0900_P2_TSFRAME_MODE 0xf3700008 -#define F0900_P2_TS_DISABLE 0xf3700004 -#define F0900_P2_TSACM_MODE 0xf3700002 -#define F0900_P2_TSOUT_NOSYNC 0xf3700001 - -/*P2_TSCFGH*/ -#define R0900_P2_TSCFGH 0xf372 -#define F0900_P2_TSFIFO_DVBCI 0xf3720080 -#define F0900_P2_TSFIFO_SERIAL 0xf3720040 -#define F0900_P2_TSFIFO_TEIUPDATE 0xf3720020 -#define F0900_P2_TSFIFO_DUTY50 0xf3720010 -#define F0900_P2_TSFIFO_HSGNLOUT 0xf3720008 -#define F0900_P2_TSFIFO_ERRMODE 0xf3720006 -#define F0900_P2_RST_HWARE 0xf3720001 - -/*P2_TSCFGM*/ -#define R0900_P2_TSCFGM 0xf373 -#define F0900_P2_TSFIFO_MANSPEED 0xf37300c0 -#define F0900_P2_TSFIFO_PERMDATA 0xf3730020 -#define F0900_P2_TSFIFO_NONEWSGNL 0xf3730010 -#define F0900_P2_TSFIFO_BITSPEED 0xf3730008 -#define F0900_P2_NPD_SPECDVBS2 0xf3730004 -#define F0900_P2_TSFIFO_STOPCKDIS 0xf3730002 -#define F0900_P2_TSFIFO_INVDATA 0xf3730001 - -/*P2_TSCFGL*/ -#define R0900_P2_TSCFGL 0xf374 -#define F0900_P2_TSFIFO_BCLKDEL1CK 0xf37400c0 -#define F0900_P2_BCHERROR_MODE 0xf3740030 -#define F0900_P2_TSFIFO_NSGNL2DATA 0xf3740008 -#define F0900_P2_TSFIFO_EMBINDVB 0xf3740004 -#define F0900_P2_TSFIFO_DPUNACT 0xf3740002 -#define F0900_P2_TSFIFO_NPDOFF 0xf3740001 - -/*P2_TSINSDELH*/ -#define R0900_P2_TSINSDELH 0xf376 -#define F0900_P2_TSDEL_SYNCBYTE 0xf3760080 -#define F0900_P2_TSDEL_XXHEADER 0xf3760040 -#define F0900_P2_TSDEL_BBHEADER 0xf3760020 -#define F0900_P2_TSDEL_DATAFIELD 0xf3760010 -#define F0900_P2_TSINSDEL_ISCR 0xf3760008 -#define F0900_P2_TSINSDEL_NPD 0xf3760004 -#define F0900_P2_TSINSDEL_RSPARITY 0xf3760002 -#define F0900_P2_TSINSDEL_CRC8 0xf3760001 - -/*P2_TSSPEED*/ -#define R0900_P2_TSSPEED 0xf380 -#define F0900_P2_TSFIFO_OUTSPEED 0xf38000ff - -/*P2_TSSTATUS*/ -#define R0900_P2_TSSTATUS 0xf381 -#define F0900_P2_TSFIFO_LINEOK 0xf3810080 -#define F0900_P2_TSFIFO_ERROR 0xf3810040 -#define F0900_P2_TSFIFO_DATA7 0xf3810020 -#define F0900_P2_TSFIFO_NOSYNC 0xf3810010 -#define F0900_P2_ISCR_INITIALIZED 0xf3810008 -#define F0900_P2_ISCR_UPDATED 0xf3810004 -#define F0900_P2_SOFFIFO_UNREGUL 0xf3810002 -#define F0900_P2_DIL_READY 0xf3810001 - -/*P2_TSSTATUS2*/ -#define R0900_P2_TSSTATUS2 0xf382 -#define F0900_P2_TSFIFO_DEMODSEL 0xf3820080 -#define F0900_P2_TSFIFOSPEED_STORE 0xf3820040 -#define F0900_P2_DILXX_RESET 0xf3820020 -#define F0900_P2_TSSERIAL_IMPOS 0xf3820010 -#define F0900_P2_TSFIFO_LINENOK 0xf3820008 -#define F0900_P2_BITSPEED_EVENT 0xf3820004 -#define F0900_P2_SCRAMBDETECT 0xf3820002 -#define F0900_P2_ULDTV67_FALSELOCK 0xf3820001 - -/*P2_TSBITRATE1*/ -#define R0900_P2_TSBITRATE1 0xf383 -#define F0900_P2_TSFIFO_BITRATE1 0xf38300ff - -/*P2_TSBITRATE0*/ -#define R0900_P2_TSBITRATE0 0xf384 -#define F0900_P2_TSFIFO_BITRATE0 0xf38400ff - -/*P2_ERRCTRL1*/ -#define R0900_P2_ERRCTRL1 0xf398 -#define F0900_P2_ERR_SOURCE1 0xf39800f0 -#define F0900_P2_NUM_EVENT1 0xf3980007 - -/*P2_ERRCNT12*/ -#define R0900_P2_ERRCNT12 0xf399 -#define F0900_P2_ERRCNT1_OLDVALUE 0xf3990080 -#define F0900_P2_ERR_CNT12 0xf399007f - -/*P2_ERRCNT11*/ -#define R0900_P2_ERRCNT11 0xf39a -#define F0900_P2_ERR_CNT11 0xf39a00ff - -/*P2_ERRCNT10*/ -#define R0900_P2_ERRCNT10 0xf39b -#define F0900_P2_ERR_CNT10 0xf39b00ff - -/*P2_ERRCTRL2*/ -#define R0900_P2_ERRCTRL2 0xf39c -#define F0900_P2_ERR_SOURCE2 0xf39c00f0 -#define F0900_P2_NUM_EVENT2 0xf39c0007 - -/*P2_ERRCNT22*/ -#define R0900_P2_ERRCNT22 0xf39d -#define F0900_P2_ERRCNT2_OLDVALUE 0xf39d0080 -#define F0900_P2_ERR_CNT22 0xf39d007f - -/*P2_ERRCNT21*/ -#define R0900_P2_ERRCNT21 0xf39e -#define F0900_P2_ERR_CNT21 0xf39e00ff - -/*P2_ERRCNT20*/ -#define R0900_P2_ERRCNT20 0xf39f -#define F0900_P2_ERR_CNT20 0xf39f00ff - -/*P2_FECSPY*/ -#define R0900_P2_FECSPY 0xf3a0 -#define F0900_P2_SPY_ENABLE 0xf3a00080 -#define F0900_P2_NO_SYNCBYTE 0xf3a00040 -#define F0900_P2_SERIAL_MODE 0xf3a00020 -#define F0900_P2_UNUSUAL_PACKET 0xf3a00010 -#define F0900_P2_BER_PACKMODE 0xf3a00008 -#define F0900_P2_BERMETER_LMODE 0xf3a00002 -#define F0900_P2_BERMETER_RESET 0xf3a00001 - -/*P2_FSPYCFG*/ -#define R0900_P2_FSPYCFG 0xf3a1 -#define F0900_P2_FECSPY_INPUT 0xf3a100c0 -#define F0900_P2_RST_ON_ERROR 0xf3a10020 -#define F0900_P2_ONE_SHOT 0xf3a10010 -#define F0900_P2_I2C_MODE 0xf3a1000c -#define F0900_P2_SPY_HYSTERESIS 0xf3a10003 - -/*P2_FSPYDATA*/ -#define R0900_P2_FSPYDATA 0xf3a2 -#define F0900_P2_SPY_STUFFING 0xf3a20080 -#define F0900_P2_NOERROR_PKTJITTER 0xf3a20040 -#define F0900_P2_SPY_CNULLPKT 0xf3a20020 -#define F0900_P2_SPY_OUTDATA_MODE 0xf3a2001f - -/*P2_FSPYOUT*/ -#define R0900_P2_FSPYOUT 0xf3a3 -#define F0900_P2_FSPY_DIRECT 0xf3a30080 -#define F0900_P2_SPY_OUTDATA_BUS 0xf3a30038 -#define F0900_P2_STUFF_MODE 0xf3a30007 - -/*P2_FSTATUS*/ -#define R0900_P2_FSTATUS 0xf3a4 -#define F0900_P2_SPY_ENDSIM 0xf3a40080 -#define F0900_P2_VALID_SIM 0xf3a40040 -#define F0900_P2_FOUND_SIGNAL 0xf3a40020 -#define F0900_P2_DSS_SYNCBYTE 0xf3a40010 -#define F0900_P2_RESULT_STATE 0xf3a4000f - -/*P2_FBERCPT4*/ -#define R0900_P2_FBERCPT4 0xf3a8 -#define F0900_P2_FBERMETER_CPT4 0xf3a800ff - -/*P2_FBERCPT3*/ -#define R0900_P2_FBERCPT3 0xf3a9 -#define F0900_P2_FBERMETER_CPT3 0xf3a900ff - -/*P2_FBERCPT2*/ -#define R0900_P2_FBERCPT2 0xf3aa -#define F0900_P2_FBERMETER_CPT2 0xf3aa00ff - -/*P2_FBERCPT1*/ -#define R0900_P2_FBERCPT1 0xf3ab -#define F0900_P2_FBERMETER_CPT1 0xf3ab00ff - -/*P2_FBERCPT0*/ -#define R0900_P2_FBERCPT0 0xf3ac -#define F0900_P2_FBERMETER_CPT0 0xf3ac00ff - -/*P2_FBERERR2*/ -#define R0900_P2_FBERERR2 0xf3ad -#define F0900_P2_FBERMETER_ERR2 0xf3ad00ff - -/*P2_FBERERR1*/ -#define R0900_P2_FBERERR1 0xf3ae -#define F0900_P2_FBERMETER_ERR1 0xf3ae00ff - -/*P2_FBERERR0*/ -#define R0900_P2_FBERERR0 0xf3af -#define F0900_P2_FBERMETER_ERR0 0xf3af00ff - -/*P2_FSPYBER*/ -#define R0900_P2_FSPYBER 0xf3b2 -#define F0900_P2_FSPYOBS_XORREAD 0xf3b20040 -#define F0900_P2_FSPYBER_OBSMODE 0xf3b20020 -#define F0900_P2_FSPYBER_SYNCBYTE 0xf3b20010 -#define F0900_P2_FSPYBER_UNSYNC 0xf3b20008 -#define F0900_P2_FSPYBER_CTIME 0xf3b20007 - -/*P1_IQCONST*/ -#define R0900_P1_IQCONST 0xf400 -#define F0900_P1_CONSTEL_SELECT 0xf4000060 -#define F0900_P1_IQSYMB_SEL 0xf400001f - -/*P1_NOSCFG*/ -#define R0900_P1_NOSCFG 0xf401 -#define F0900_P1_DUMMYPL_NOSDATA 0xf4010020 -#define F0900_P1_NOSPLH_BETA 0xf4010018 -#define F0900_P1_NOSDATA_BETA 0xf4010007 - -/*P1_ISYMB*/ -#define R0900_P1_ISYMB 0xf402 -#define F0900_P1_I_SYMBOL 0xf40201ff - -/*P1_QSYMB*/ -#define R0900_P1_QSYMB 0xf403 -#define F0900_P1_Q_SYMBOL 0xf40301ff - -/*P1_AGC1CFG*/ -#define R0900_P1_AGC1CFG 0xf404 -#define F0900_P1_DC_FROZEN 0xf4040080 -#define F0900_P1_DC_CORRECT 0xf4040040 -#define F0900_P1_AMM_FROZEN 0xf4040020 -#define F0900_P1_AMM_CORRECT 0xf4040010 -#define F0900_P1_QUAD_FROZEN 0xf4040008 -#define F0900_P1_QUAD_CORRECT 0xf4040004 -#define F0900_P1_DCCOMP_SLOW 0xf4040002 -#define F0900_P1_IQMISM_SLOW 0xf4040001 - -/*P1_AGC1CN*/ -#define R0900_P1_AGC1CN 0xf406 -#define F0900_P1_AGC1_LOCKED 0xf4060080 -#define F0900_P1_AGC1_OVERFLOW 0xf4060040 -#define F0900_P1_AGC1_NOSLOWLK 0xf4060020 -#define F0900_P1_AGC1_MINPOWER 0xf4060010 -#define F0900_P1_AGCOUT_FAST 0xf4060008 -#define F0900_P1_AGCIQ_BETA 0xf4060007 - -/*P1_AGC1REF*/ -#define R0900_P1_AGC1REF 0xf407 -#define F0900_P1_AGCIQ_REF 0xf40700ff - -/*P1_IDCCOMP*/ -#define R0900_P1_IDCCOMP 0xf408 -#define F0900_P1_IAVERAGE_ADJ 0xf40801ff - -/*P1_QDCCOMP*/ -#define R0900_P1_QDCCOMP 0xf409 -#define F0900_P1_QAVERAGE_ADJ 0xf40901ff - -/*P1_POWERI*/ -#define R0900_P1_POWERI 0xf40a -#define F0900_P1_POWER_I 0xf40a00ff - -/*P1_POWERQ*/ -#define R0900_P1_POWERQ 0xf40b -#define F0900_P1_POWER_Q 0xf40b00ff - -/*P1_AGC1AMM*/ -#define R0900_P1_AGC1AMM 0xf40c -#define F0900_P1_AMM_VALUE 0xf40c00ff - -/*P1_AGC1QUAD*/ -#define R0900_P1_AGC1QUAD 0xf40d -#define F0900_P1_QUAD_VALUE 0xf40d01ff - -/*P1_AGCIQIN1*/ -#define R0900_P1_AGCIQIN1 0xf40e -#define F0900_P1_AGCIQ_VALUE1 0xf40e00ff - -/*P1_AGCIQIN0*/ -#define R0900_P1_AGCIQIN0 0xf40f -#define F0900_P1_AGCIQ_VALUE0 0xf40f00ff - -/*P1_DEMOD*/ -#define R0900_P1_DEMOD 0xf410 -#define F0900_P1_DEMOD_STOP 0xf4100040 -#define F0900_P1_SPECINV_CONTROL 0xf4100030 -#define F0900_P1_FORCE_ENASAMP 0xf4100008 -#define F0900_P1_MANUAL_ROLLOFF 0xf4100004 -#define F0900_P1_ROLLOFF_CONTROL 0xf4100003 - -/*P1_DMDMODCOD*/ -#define R0900_P1_DMDMODCOD 0xf411 -#define F0900_P1_MANUAL_MODCOD 0xf4110080 -#define F0900_P1_DEMOD_MODCOD 0xf411007c -#define F0900_P1_DEMOD_TYPE 0xf4110003 - -/*P1_DSTATUS*/ -#define R0900_P1_DSTATUS 0xf412 -#define F0900_P1_CAR_LOCK 0xf4120080 -#define F0900_P1_TMGLOCK_QUALITY 0xf4120060 -#define F0900_P1_SDVBS1_ENABLE 0xf4120010 -#define F0900_P1_LOCK_DEFINITIF 0xf4120008 -#define F0900_P1_TIMING_IS_LOCKED 0xf4120004 -#define F0900_P1_COARSE_TMGLOCK 0xf4120002 -#define F0900_P1_COARSE_CARLOCK 0xf4120001 - -/*P1_DSTATUS2*/ -#define R0900_P1_DSTATUS2 0xf413 -#define F0900_P1_DEMOD_DELOCK 0xf4130080 -#define F0900_P1_DEMOD_TIMEOUT 0xf4130040 -#define F0900_P1_MODCODRQ_SYNCTAG 0xf4130020 -#define F0900_P1_POLYPH_SATEVENT 0xf4130010 -#define F0900_P1_AGC1_NOSIGNALACK 0xf4130008 -#define F0900_P1_AGC2_OVERFLOW 0xf4130004 -#define F0900_P1_CFR_OVERFLOW 0xf4130002 -#define F0900_P1_GAMMA_OVERUNDER 0xf4130001 - -/*P1_DMDCFGMD*/ -#define R0900_P1_DMDCFGMD 0xf414 -#define F0900_P1_DVBS2_ENABLE 0xf4140080 -#define F0900_P1_DVBS1_ENABLE 0xf4140040 -#define F0900_P1_CFR_AUTOSCAN 0xf4140020 -#define F0900_P1_SCAN_ENABLE 0xf4140010 -#define F0900_P1_TUN_AUTOSCAN 0xf4140008 -#define F0900_P1_NOFORCE_RELOCK 0xf4140004 -#define F0900_P1_TUN_RNG 0xf4140003 - -/*P1_DMDCFG2*/ -#define R0900_P1_DMDCFG2 0xf415 -#define F0900_P1_AGC1_WAITLOCK 0xf4150080 -#define F0900_P1_S1S2_SEQUENTIAL 0xf4150040 -#define F0900_P1_OVERFLOW_TIMEOUT 0xf4150020 -#define F0900_P1_SCANFAIL_TIMEOUT 0xf4150010 -#define F0900_P1_DMDTOUT_BACK 0xf4150008 -#define F0900_P1_CARLOCK_S1ENABLE 0xf4150004 -#define F0900_P1_COARSE_LK3MODE 0xf4150002 -#define F0900_P1_COARSE_LK2MODE 0xf4150001 - -/*P1_DMDISTATE*/ -#define R0900_P1_DMDISTATE 0xf416 -#define F0900_P1_I2C_NORESETDMODE 0xf4160080 -#define F0900_P1_FORCE_ETAPED 0xf4160040 -#define F0900_P1_SDMDRST_DIRCLK 0xf4160020 -#define F0900_P1_I2C_DEMOD_MODE 0xf416001f - -/*P1_DMDT0M*/ -#define R0900_P1_DMDT0M 0xf417 -#define F0900_P1_DMDT0_MIN 0xf41700ff - -/*P1_DMDSTATE*/ -#define R0900_P1_DMDSTATE 0xf41b -#define F0900_P1_DEMOD_LOCKED 0xf41b0080 -#define F0900_P1_HEADER_MODE 0xf41b0060 -#define F0900_P1_DEMOD_MODE 0xf41b001f - -/*P1_DMDFLYW*/ -#define R0900_P1_DMDFLYW 0xf41c -#define F0900_P1_I2C_IRQVAL 0xf41c00f0 -#define F0900_P1_FLYWHEEL_CPT 0xf41c000f - -/*P1_DSTATUS3*/ -#define R0900_P1_DSTATUS3 0xf41d -#define F0900_P1_CFR_ZIGZAG 0xf41d0080 -#define F0900_P1_DEMOD_CFGMODE 0xf41d0060 -#define F0900_P1_GAMMA_LOWBAUDRATE 0xf41d0010 -#define F0900_P1_RELOCK_MODE 0xf41d0008 -#define F0900_P1_DEMOD_FAIL 0xf41d0004 -#define F0900_P1_ETAPE1A_DVBXMEM 0xf41d0003 - -/*P1_DMDCFG3*/ -#define R0900_P1_DMDCFG3 0xf41e -#define F0900_P1_DVBS1_TMGWAIT 0xf41e0080 -#define F0900_P1_NO_BWCENTERING 0xf41e0040 -#define F0900_P1_INV_SEQSRCH 0xf41e0020 -#define F0900_P1_DIS_SFRUPLOW_TRK 0xf41e0010 -#define F0900_P1_NOSTOP_FIFOFULL 0xf41e0008 -#define F0900_P1_LOCKTIME_MODE 0xf41e0007 - -/*P1_DMDCFG4*/ -#define R0900_P1_DMDCFG4 0xf41f -#define F0900_P1_TUNER_NRELAUNCH 0xf41f0008 -#define F0900_P1_DIS_CLKENABLE 0xf41f0004 -#define F0900_P1_DIS_HDRDIVLOCK 0xf41f0002 -#define F0900_P1_NO_TNRWBINIT 0xf41f0001 - -/*P1_CORRELMANT*/ -#define R0900_P1_CORRELMANT 0xf420 -#define F0900_P1_CORREL_MANT 0xf42000ff - -/*P1_CORRELABS*/ -#define R0900_P1_CORRELABS 0xf421 -#define F0900_P1_CORREL_ABS 0xf42100ff - -/*P1_CORRELEXP*/ -#define R0900_P1_CORRELEXP 0xf422 -#define F0900_P1_CORREL_ABSEXP 0xf42200f0 -#define F0900_P1_CORREL_EXP 0xf422000f - -/*P1_PLHMODCOD*/ -#define R0900_P1_PLHMODCOD 0xf424 -#define F0900_P1_SPECINV_DEMOD 0xf4240080 -#define F0900_P1_PLH_MODCOD 0xf424007c -#define F0900_P1_PLH_TYPE 0xf4240003 - -/*P1_AGCK32*/ -#define R0900_P1_AGCK32 0xf42b -#define F0900_P1_R3ADJOFF_32APSK 0xf42b0080 -#define F0900_P1_R2ADJOFF_32APSK 0xf42b0040 -#define F0900_P1_R1ADJOFF_32APSK 0xf42b0020 -#define F0900_P1_RADJ_32APSK 0xf42b001f - -/*P1_AGC2O*/ -#define R0900_P1_AGC2O 0xf42c -#define F0900_P1_AGC2REF_ADJUSTING 0xf42c0080 -#define F0900_P1_AGC2_COARSEFAST 0xf42c0040 -#define F0900_P1_AGC2_LKSQRT 0xf42c0020 -#define F0900_P1_AGC2_LKMODE 0xf42c0010 -#define F0900_P1_AGC2_LKEQUA 0xf42c0008 -#define F0900_P1_AGC2_COEF 0xf42c0007 - -/*P1_AGC2REF*/ -#define R0900_P1_AGC2REF 0xf42d -#define F0900_P1_AGC2_REF 0xf42d00ff - -/*P1_AGC1ADJ*/ -#define R0900_P1_AGC1ADJ 0xf42e -#define F0900_P1_AGC1ADJ_MANUAL 0xf42e0080 -#define F0900_P1_AGC1_ADJUSTED 0xf42e017f - -/*P1_AGC2I1*/ -#define R0900_P1_AGC2I1 0xf436 -#define F0900_P1_AGC2_INTEGRATOR1 0xf43600ff - -/*P1_AGC2I0*/ -#define R0900_P1_AGC2I0 0xf437 -#define F0900_P1_AGC2_INTEGRATOR0 0xf43700ff - -/*P1_CARCFG*/ -#define R0900_P1_CARCFG 0xf438 -#define F0900_P1_CFRUPLOW_AUTO 0xf4380080 -#define F0900_P1_CFRUPLOW_TEST 0xf4380040 -#define F0900_P1_EN_CAR2CENTER 0xf4380020 -#define F0900_P1_CARHDR_NODIV8 0xf4380010 -#define F0900_P1_I2C_ROTA 0xf4380008 -#define F0900_P1_ROTAON 0xf4380004 -#define F0900_P1_PH_DET_ALGO 0xf4380003 - -/*P1_ACLC*/ -#define R0900_P1_ACLC 0xf439 -#define F0900_P1_STOP_S2ALPHA 0xf43900c0 -#define F0900_P1_CAR_ALPHA_MANT 0xf4390030 -#define F0900_P1_CAR_ALPHA_EXP 0xf439000f - -/*P1_BCLC*/ -#define R0900_P1_BCLC 0xf43a -#define F0900_P1_STOP_S2BETA 0xf43a00c0 -#define F0900_P1_CAR_BETA_MANT 0xf43a0030 -#define F0900_P1_CAR_BETA_EXP 0xf43a000f - -/*P1_CARFREQ*/ -#define R0900_P1_CARFREQ 0xf43d -#define F0900_P1_KC_COARSE_EXP 0xf43d00f0 -#define F0900_P1_BETA_FREQ 0xf43d000f - -/*P1_CARHDR*/ -#define R0900_P1_CARHDR 0xf43e -#define F0900_P1_K_FREQ_HDR 0xf43e00ff - -/*P1_LDT*/ -#define R0900_P1_LDT 0xf43f -#define F0900_P1_CARLOCK_THRES 0xf43f01ff - -/*P1_LDT2*/ -#define R0900_P1_LDT2 0xf440 -#define F0900_P1_CARLOCK_THRES2 0xf44001ff - -/*P1_CFRICFG*/ -#define R0900_P1_CFRICFG 0xf441 -#define F0900_P1_CFRINIT_UNVALRNG 0xf4410080 -#define F0900_P1_CFRINIT_LUNVALCPT 0xf4410040 -#define F0900_P1_CFRINIT_ABORTDBL 0xf4410020 -#define F0900_P1_CFRINIT_ABORTPRED 0xf4410010 -#define F0900_P1_CFRINIT_UNVALSKIP 0xf4410008 -#define F0900_P1_CFRINIT_CSTINC 0xf4410004 -#define F0900_P1_NEG_CFRSTEP 0xf4410001 - -/*P1_CFRUP1*/ -#define R0900_P1_CFRUP1 0xf442 -#define F0900_P1_CFR_UP1 0xf44201ff - -/*P1_CFRUP0*/ -#define R0900_P1_CFRUP0 0xf443 -#define F0900_P1_CFR_UP0 0xf44300ff - -/*P1_CFRLOW1*/ -#define R0900_P1_CFRLOW1 0xf446 -#define F0900_P1_CFR_LOW1 0xf44601ff - -/*P1_CFRLOW0*/ -#define R0900_P1_CFRLOW0 0xf447 -#define F0900_P1_CFR_LOW0 0xf44700ff - -/*P1_CFRINIT1*/ -#define R0900_P1_CFRINIT1 0xf448 -#define F0900_P1_CFR_INIT1 0xf44801ff - -/*P1_CFRINIT0*/ -#define R0900_P1_CFRINIT0 0xf449 -#define F0900_P1_CFR_INIT0 0xf44900ff - -/*P1_CFRINC1*/ -#define R0900_P1_CFRINC1 0xf44a -#define F0900_P1_MANUAL_CFRINC 0xf44a0080 -#define F0900_P1_CFR_INC1 0xf44a017f - -/*P1_CFRINC0*/ -#define R0900_P1_CFRINC0 0xf44b -#define F0900_P1_CFR_INC0 0xf44b00f0 - -/*P1_CFR2*/ -#define R0900_P1_CFR2 0xf44c -#define F0900_P1_CAR_FREQ2 0xf44c01ff - -/*P1_CFR1*/ -#define R0900_P1_CFR1 0xf44d -#define F0900_P1_CAR_FREQ1 0xf44d00ff - -/*P1_CFR0*/ -#define R0900_P1_CFR0 0xf44e -#define F0900_P1_CAR_FREQ0 0xf44e00ff - -/*P1_LDI*/ -#define R0900_P1_LDI 0xf44f -#define F0900_P1_LOCK_DET_INTEGR 0xf44f01ff - -/*P1_TMGCFG*/ -#define R0900_P1_TMGCFG 0xf450 -#define F0900_P1_TMGLOCK_BETA 0xf45000c0 -#define F0900_P1_NOTMG_GROUPDELAY 0xf4500020 -#define F0900_P1_DO_TIMING_CORR 0xf4500010 -#define F0900_P1_MANUAL_SCAN 0xf450000c -#define F0900_P1_TMG_MINFREQ 0xf4500003 - -/*P1_RTC*/ -#define R0900_P1_RTC 0xf451 -#define F0900_P1_TMGALPHA_EXP 0xf45100f0 -#define F0900_P1_TMGBETA_EXP 0xf451000f - -/*P1_RTCS2*/ -#define R0900_P1_RTCS2 0xf452 -#define F0900_P1_TMGALPHAS2_EXP 0xf45200f0 -#define F0900_P1_TMGBETAS2_EXP 0xf452000f - -/*P1_TMGTHRISE*/ -#define R0900_P1_TMGTHRISE 0xf453 -#define F0900_P1_TMGLOCK_THRISE 0xf45300ff - -/*P1_TMGTHFALL*/ -#define R0900_P1_TMGTHFALL 0xf454 -#define F0900_P1_TMGLOCK_THFALL 0xf45400ff - -/*P1_SFRUPRATIO*/ -#define R0900_P1_SFRUPRATIO 0xf455 -#define F0900_P1_SFR_UPRATIO 0xf45500ff - -/*P1_SFRLOWRATIO*/ -#define R0900_P1_SFRLOWRATIO 0xf456 -#define F0900_P1_SFR_LOWRATIO 0xf45600ff - -/*P1_KREFTMG*/ -#define R0900_P1_KREFTMG 0xf458 -#define F0900_P1_KREF_TMG 0xf45800ff - -/*P1_SFRSTEP*/ -#define R0900_P1_SFRSTEP 0xf459 -#define F0900_P1_SFR_SCANSTEP 0xf45900f0 -#define F0900_P1_SFR_CENTERSTEP 0xf459000f - -/*P1_TMGCFG2*/ -#define R0900_P1_TMGCFG2 0xf45a -#define F0900_P1_DIS_AUTOSAMP 0xf45a0008 -#define F0900_P1_SCANINIT_QUART 0xf45a0004 -#define F0900_P1_NOTMG_DVBS1DERAT 0xf45a0002 -#define F0900_P1_SFRRATIO_FINE 0xf45a0001 - -/*P1_SFRINIT1*/ -#define R0900_P1_SFRINIT1 0xf45e -#define F0900_P1_SFR_INIT1 0xf45e00ff - -/*P1_SFRINIT0*/ -#define R0900_P1_SFRINIT0 0xf45f -#define F0900_P1_SFR_INIT0 0xf45f00ff - -/*P1_SFRUP1*/ -#define R0900_P1_SFRUP1 0xf460 -#define F0900_P1_AUTO_GUP 0xf4600080 -#define F0900_P1_SYMB_FREQ_UP1 0xf460007f - -/*P1_SFRUP0*/ -#define R0900_P1_SFRUP0 0xf461 -#define F0900_P1_SYMB_FREQ_UP0 0xf46100ff - -/*P1_SFRLOW1*/ -#define R0900_P1_SFRLOW1 0xf462 -#define F0900_P1_AUTO_GLOW 0xf4620080 -#define F0900_P1_SYMB_FREQ_LOW1 0xf462007f - -/*P1_SFRLOW0*/ -#define R0900_P1_SFRLOW0 0xf463 -#define F0900_P1_SYMB_FREQ_LOW0 0xf46300ff - -/*P1_SFR3*/ -#define R0900_P1_SFR3 0xf464 -#define F0900_P1_SYMB_FREQ3 0xf46400ff - -/*P1_SFR2*/ -#define R0900_P1_SFR2 0xf465 -#define F0900_P1_SYMB_FREQ2 0xf46500ff - -/*P1_SFR1*/ -#define R0900_P1_SFR1 0xf466 -#define F0900_P1_SYMB_FREQ1 0xf46600ff - -/*P1_SFR0*/ -#define R0900_P1_SFR0 0xf467 -#define F0900_P1_SYMB_FREQ0 0xf46700ff - -/*P1_TMGREG2*/ -#define R0900_P1_TMGREG2 0xf468 -#define F0900_P1_TMGREG2 0xf46800ff - -/*P1_TMGREG1*/ -#define R0900_P1_TMGREG1 0xf469 -#define F0900_P1_TMGREG1 0xf46900ff - -/*P1_TMGREG0*/ -#define R0900_P1_TMGREG0 0xf46a -#define F0900_P1_TMGREG0 0xf46a00ff - -/*P1_TMGLOCK1*/ -#define R0900_P1_TMGLOCK1 0xf46b -#define F0900_P1_TMGLOCK_LEVEL1 0xf46b01ff - -/*P1_TMGLOCK0*/ -#define R0900_P1_TMGLOCK0 0xf46c -#define F0900_P1_TMGLOCK_LEVEL0 0xf46c00ff - -/*P1_TMGOBS*/ -#define R0900_P1_TMGOBS 0xf46d -#define F0900_P1_ROLLOFF_STATUS 0xf46d00c0 -#define F0900_P1_SCAN_SIGN 0xf46d0030 -#define F0900_P1_TMG_SCANNING 0xf46d0008 -#define F0900_P1_CHCENTERING_MODE 0xf46d0004 -#define F0900_P1_TMG_SCANFAIL 0xf46d0002 - -/*P1_EQUALCFG*/ -#define R0900_P1_EQUALCFG 0xf46f -#define F0900_P1_NOTMG_NEGALWAIT 0xf46f0080 -#define F0900_P1_EQUAL_ON 0xf46f0040 -#define F0900_P1_SEL_EQUALCOR 0xf46f0038 -#define F0900_P1_MU_EQUALDFE 0xf46f0007 - -/*P1_EQUAI1*/ -#define R0900_P1_EQUAI1 0xf470 -#define F0900_P1_EQUA_ACCI1 0xf47001ff - -/*P1_EQUAQ1*/ -#define R0900_P1_EQUAQ1 0xf471 -#define F0900_P1_EQUA_ACCQ1 0xf47101ff - -/*P1_EQUAI2*/ -#define R0900_P1_EQUAI2 0xf472 -#define F0900_P1_EQUA_ACCI2 0xf47201ff - -/*P1_EQUAQ2*/ -#define R0900_P1_EQUAQ2 0xf473 -#define F0900_P1_EQUA_ACCQ2 0xf47301ff - -/*P1_EQUAI3*/ -#define R0900_P1_EQUAI3 0xf474 -#define F0900_P1_EQUA_ACCI3 0xf47401ff - -/*P1_EQUAQ3*/ -#define R0900_P1_EQUAQ3 0xf475 -#define F0900_P1_EQUA_ACCQ3 0xf47501ff - -/*P1_EQUAI4*/ -#define R0900_P1_EQUAI4 0xf476 -#define F0900_P1_EQUA_ACCI4 0xf47601ff - -/*P1_EQUAQ4*/ -#define R0900_P1_EQUAQ4 0xf477 -#define F0900_P1_EQUA_ACCQ4 0xf47701ff - -/*P1_EQUAI5*/ -#define R0900_P1_EQUAI5 0xf478 -#define F0900_P1_EQUA_ACCI5 0xf47801ff - -/*P1_EQUAQ5*/ -#define R0900_P1_EQUAQ5 0xf479 -#define F0900_P1_EQUA_ACCQ5 0xf47901ff - -/*P1_EQUAI6*/ -#define R0900_P1_EQUAI6 0xf47a -#define F0900_P1_EQUA_ACCI6 0xf47a01ff - -/*P1_EQUAQ6*/ -#define R0900_P1_EQUAQ6 0xf47b -#define F0900_P1_EQUA_ACCQ6 0xf47b01ff - -/*P1_EQUAI7*/ -#define R0900_P1_EQUAI7 0xf47c -#define F0900_P1_EQUA_ACCI7 0xf47c01ff - -/*P1_EQUAQ7*/ -#define R0900_P1_EQUAQ7 0xf47d -#define F0900_P1_EQUA_ACCQ7 0xf47d01ff - -/*P1_EQUAI8*/ -#define R0900_P1_EQUAI8 0xf47e -#define F0900_P1_EQUA_ACCI8 0xf47e01ff - -/*P1_EQUAQ8*/ -#define R0900_P1_EQUAQ8 0xf47f -#define F0900_P1_EQUA_ACCQ8 0xf47f01ff - -/*P1_NNOSDATAT1*/ -#define R0900_P1_NNOSDATAT1 0xf480 -#define F0900_P1_NOSDATAT_NORMED1 0xf48000ff - -/*P1_NNOSDATAT0*/ -#define R0900_P1_NNOSDATAT0 0xf481 -#define F0900_P1_NOSDATAT_NORMED0 0xf48100ff - -/*P1_NNOSDATA1*/ -#define R0900_P1_NNOSDATA1 0xf482 -#define F0900_P1_NOSDATA_NORMED1 0xf48200ff - -/*P1_NNOSDATA0*/ -#define R0900_P1_NNOSDATA0 0xf483 -#define F0900_P1_NOSDATA_NORMED0 0xf48300ff - -/*P1_NNOSPLHT1*/ -#define R0900_P1_NNOSPLHT1 0xf484 -#define F0900_P1_NOSPLHT_NORMED1 0xf48400ff - -/*P1_NNOSPLHT0*/ -#define R0900_P1_NNOSPLHT0 0xf485 -#define F0900_P1_NOSPLHT_NORMED0 0xf48500ff - -/*P1_NNOSPLH1*/ -#define R0900_P1_NNOSPLH1 0xf486 -#define F0900_P1_NOSPLH_NORMED1 0xf48600ff - -/*P1_NNOSPLH0*/ -#define R0900_P1_NNOSPLH0 0xf487 -#define F0900_P1_NOSPLH_NORMED0 0xf48700ff - -/*P1_NOSDATAT1*/ -#define R0900_P1_NOSDATAT1 0xf488 -#define F0900_P1_NOSDATAT_UNNORMED1 0xf48800ff - -/*P1_NOSDATAT0*/ -#define R0900_P1_NOSDATAT0 0xf489 -#define F0900_P1_NOSDATAT_UNNORMED0 0xf48900ff - -/*P1_NOSDATA1*/ -#define R0900_P1_NOSDATA1 0xf48a -#define F0900_P1_NOSDATA_UNNORMED1 0xf48a00ff - -/*P1_NOSDATA0*/ -#define R0900_P1_NOSDATA0 0xf48b -#define F0900_P1_NOSDATA_UNNORMED0 0xf48b00ff - -/*P1_NOSPLHT1*/ -#define R0900_P1_NOSPLHT1 0xf48c -#define F0900_P1_NOSPLHT_UNNORMED1 0xf48c00ff - -/*P1_NOSPLHT0*/ -#define R0900_P1_NOSPLHT0 0xf48d -#define F0900_P1_NOSPLHT_UNNORMED0 0xf48d00ff - -/*P1_NOSPLH1*/ -#define R0900_P1_NOSPLH1 0xf48e -#define F0900_P1_NOSPLH_UNNORMED1 0xf48e00ff - -/*P1_NOSPLH0*/ -#define R0900_P1_NOSPLH0 0xf48f -#define F0900_P1_NOSPLH_UNNORMED0 0xf48f00ff - -/*P1_CAR2CFG*/ -#define R0900_P1_CAR2CFG 0xf490 -#define F0900_P1_DESCRAMB_OFF 0xf4900080 -#define F0900_P1_PN4_SELECT 0xf4900040 -#define F0900_P1_CFR2_STOPDVBS1 0xf4900020 -#define F0900_P1_STOP_CFR2UPDATE 0xf4900010 -#define F0900_P1_STOP_NCO2UPDATE 0xf4900008 -#define F0900_P1_ROTA2ON 0xf4900004 -#define F0900_P1_PH_DET_ALGO2 0xf4900003 - -/*P1_ACLC2*/ -#define R0900_P1_ACLC2 0xf491 -#define F0900_P1_CAR2_PUNCT_ADERAT 0xf4910040 -#define F0900_P1_CAR2_ALPHA_MANT 0xf4910030 -#define F0900_P1_CAR2_ALPHA_EXP 0xf491000f - -/*P1_BCLC2*/ -#define R0900_P1_BCLC2 0xf492 -#define F0900_P1_DVBS2_NIP 0xf4920080 -#define F0900_P1_CAR2_PUNCT_BDERAT 0xf4920040 -#define F0900_P1_CAR2_BETA_MANT 0xf4920030 -#define F0900_P1_CAR2_BETA_EXP 0xf492000f - -/*P1_CFR22*/ -#define R0900_P1_CFR22 0xf493 -#define F0900_P1_CAR2_FREQ2 0xf49301ff - -/*P1_CFR21*/ -#define R0900_P1_CFR21 0xf494 -#define F0900_P1_CAR2_FREQ1 0xf49400ff - -/*P1_CFR20*/ -#define R0900_P1_CFR20 0xf495 -#define F0900_P1_CAR2_FREQ0 0xf49500ff - -/*P1_ACLC2S2Q*/ -#define R0900_P1_ACLC2S2Q 0xf497 -#define F0900_P1_ENAB_SPSKSYMB 0xf4970080 -#define F0900_P1_CAR2S2_QADERAT 0xf4970040 -#define F0900_P1_CAR2S2_Q_ALPH_M 0xf4970030 -#define F0900_P1_CAR2S2_Q_ALPH_E 0xf497000f - -/*P1_ACLC2S28*/ -#define R0900_P1_ACLC2S28 0xf498 -#define F0900_P1_OLDI3Q_MODE 0xf4980080 -#define F0900_P1_CAR2S2_8ADERAT 0xf4980040 -#define F0900_P1_CAR2S2_8_ALPH_M 0xf4980030 -#define F0900_P1_CAR2S2_8_ALPH_E 0xf498000f - -/*P1_ACLC2S216A*/ -#define R0900_P1_ACLC2S216A 0xf499 -#define F0900_P1_CAR2S2_16ADERAT 0xf4990040 -#define F0900_P1_CAR2S2_16A_ALPH_M 0xf4990030 -#define F0900_P1_CAR2S2_16A_ALPH_E 0xf499000f - -/*P1_ACLC2S232A*/ -#define R0900_P1_ACLC2S232A 0xf49a -#define F0900_P1_CAR2S2_32ADERAT 0xf49a0040 -#define F0900_P1_CAR2S2_32A_ALPH_M 0xf49a0030 -#define F0900_P1_CAR2S2_32A_ALPH_E 0xf49a000f - -/*P1_BCLC2S2Q*/ -#define R0900_P1_BCLC2S2Q 0xf49c -#define F0900_P1_DVBS2S2Q_NIP 0xf49c0080 -#define F0900_P1_CAR2S2_QBDERAT 0xf49c0040 -#define F0900_P1_CAR2S2_Q_BETA_M 0xf49c0030 -#define F0900_P1_CAR2S2_Q_BETA_E 0xf49c000f - -/*P1_BCLC2S28*/ -#define R0900_P1_BCLC2S28 0xf49d -#define F0900_P1_DVBS2S28_NIP 0xf49d0080 -#define F0900_P1_CAR2S2_8BDERAT 0xf49d0040 -#define F0900_P1_CAR2S2_8_BETA_M 0xf49d0030 -#define F0900_P1_CAR2S2_8_BETA_E 0xf49d000f - -/*P1_BCLC2S216A*/ -#define R0900_P1_BCLC2S216A 0xf49e -#define F0900_P1_DVBS2S216A_NIP 0xf49e0080 -#define F0900_P1_CAR2S2_16BDERAT 0xf49e0040 -#define F0900_P1_CAR2S2_16A_BETA_M 0xf49e0030 -#define F0900_P1_CAR2S2_16A_BETA_E 0xf49e000f - -/*P1_BCLC2S232A*/ -#define R0900_P1_BCLC2S232A 0xf49f -#define F0900_P1_DVBS2S232A_NIP 0xf49f0080 -#define F0900_P1_CAR2S2_32BDERAT 0xf49f0040 -#define F0900_P1_CAR2S2_32A_BETA_M 0xf49f0030 -#define F0900_P1_CAR2S2_32A_BETA_E 0xf49f000f - -/*P1_PLROOT2*/ -#define R0900_P1_PLROOT2 0xf4ac -#define F0900_P1_SHORTFR_DISABLE 0xf4ac0080 -#define F0900_P1_LONGFR_DISABLE 0xf4ac0040 -#define F0900_P1_DUMMYPL_DISABLE 0xf4ac0020 -#define F0900_P1_SHORTFR_AVOID 0xf4ac0010 -#define F0900_P1_PLSCRAMB_MODE 0xf4ac000c -#define F0900_P1_PLSCRAMB_ROOT2 0xf4ac0003 - -/*P1_PLROOT1*/ -#define R0900_P1_PLROOT1 0xf4ad -#define F0900_P1_PLSCRAMB_ROOT1 0xf4ad00ff - -/*P1_PLROOT0*/ -#define R0900_P1_PLROOT0 0xf4ae -#define F0900_P1_PLSCRAMB_ROOT0 0xf4ae00ff - -/*P1_MODCODLST0*/ -#define R0900_P1_MODCODLST0 0xf4b0 -#define F0900_P1_EN_TOKEN31 0xf4b00080 -#define F0900_P1_SYNCTAG_SELECT 0xf4b00040 -#define F0900_P1_MODCODRQ_MODE 0xf4b00030 - -/*P1_MODCODLST1*/ -#define R0900_P1_MODCODLST1 0xf4b1 -#define F0900_P1_DIS_MODCOD29 0xf4b100f0 -#define F0900_P1_DIS_32PSK_9_10 0xf4b1000f - -/*P1_MODCODLST2*/ -#define R0900_P1_MODCODLST2 0xf4b2 -#define F0900_P1_DIS_32PSK_8_9 0xf4b200f0 -#define F0900_P1_DIS_32PSK_5_6 0xf4b2000f - -/*P1_MODCODLST3*/ -#define R0900_P1_MODCODLST3 0xf4b3 -#define F0900_P1_DIS_32PSK_4_5 0xf4b300f0 -#define F0900_P1_DIS_32PSK_3_4 0xf4b3000f - -/*P1_MODCODLST4*/ -#define R0900_P1_MODCODLST4 0xf4b4 -#define F0900_P1_DIS_16PSK_9_10 0xf4b400f0 -#define F0900_P1_DIS_16PSK_8_9 0xf4b4000f - -/*P1_MODCODLST5*/ -#define R0900_P1_MODCODLST5 0xf4b5 -#define F0900_P1_DIS_16PSK_5_6 0xf4b500f0 -#define F0900_P1_DIS_16PSK_4_5 0xf4b5000f - -/*P1_MODCODLST6*/ -#define R0900_P1_MODCODLST6 0xf4b6 -#define F0900_P1_DIS_16PSK_3_4 0xf4b600f0 -#define F0900_P1_DIS_16PSK_2_3 0xf4b6000f - -/*P1_MODCODLST7*/ -#define R0900_P1_MODCODLST7 0xf4b7 -#define F0900_P1_DIS_8P_9_10 0xf4b700f0 -#define F0900_P1_DIS_8P_8_9 0xf4b7000f - -/*P1_MODCODLST8*/ -#define R0900_P1_MODCODLST8 0xf4b8 -#define F0900_P1_DIS_8P_5_6 0xf4b800f0 -#define F0900_P1_DIS_8P_3_4 0xf4b8000f - -/*P1_MODCODLST9*/ -#define R0900_P1_MODCODLST9 0xf4b9 -#define F0900_P1_DIS_8P_2_3 0xf4b900f0 -#define F0900_P1_DIS_8P_3_5 0xf4b9000f - -/*P1_MODCODLSTA*/ -#define R0900_P1_MODCODLSTA 0xf4ba -#define F0900_P1_DIS_QP_9_10 0xf4ba00f0 -#define F0900_P1_DIS_QP_8_9 0xf4ba000f - -/*P1_MODCODLSTB*/ -#define R0900_P1_MODCODLSTB 0xf4bb -#define F0900_P1_DIS_QP_5_6 0xf4bb00f0 -#define F0900_P1_DIS_QP_4_5 0xf4bb000f - -/*P1_MODCODLSTC*/ -#define R0900_P1_MODCODLSTC 0xf4bc -#define F0900_P1_DIS_QP_3_4 0xf4bc00f0 -#define F0900_P1_DIS_QP_2_3 0xf4bc000f - -/*P1_MODCODLSTD*/ -#define R0900_P1_MODCODLSTD 0xf4bd -#define F0900_P1_DIS_QP_3_5 0xf4bd00f0 -#define F0900_P1_DIS_QP_1_2 0xf4bd000f - -/*P1_MODCODLSTE*/ -#define R0900_P1_MODCODLSTE 0xf4be -#define F0900_P1_DIS_QP_2_5 0xf4be00f0 -#define F0900_P1_DIS_QP_1_3 0xf4be000f - -/*P1_MODCODLSTF*/ -#define R0900_P1_MODCODLSTF 0xf4bf -#define F0900_P1_DIS_QP_1_4 0xf4bf00f0 -#define F0900_P1_DDEMOD_SET 0xf4bf0002 -#define F0900_P1_DDEMOD_MASK 0xf4bf0001 - -/*P1_DMDRESCFG*/ -#define R0900_P1_DMDRESCFG 0xf4c6 -#define F0900_P1_DMDRES_RESET 0xf4c60080 -#define F0900_P1_DMDRES_NOISESQR 0xf4c60010 -#define F0900_P1_DMDRES_STRALL 0xf4c60008 -#define F0900_P1_DMDRES_NEWONLY 0xf4c60004 -#define F0900_P1_DMDRES_NOSTORE 0xf4c60002 -#define F0900_P1_DMDRES_AGC2MEM 0xf4c60001 - -/*P1_DMDRESADR*/ -#define R0900_P1_DMDRESADR 0xf4c7 -#define F0900_P1_SUSP_PREDCANAL 0xf4c70080 -#define F0900_P1_DMDRES_VALIDCFR 0xf4c70040 -#define F0900_P1_DMDRES_MEMFULL 0xf4c70030 -#define F0900_P1_DMDRES_RESNBR 0xf4c7000f - -/*P1_DMDRESDATA7*/ -#define R0900_P1_DMDRESDATA7 0xf4c8 -#define F0900_P1_DMDRES_DATA7 0xf4c800ff - -/*P1_DMDRESDATA6*/ -#define R0900_P1_DMDRESDATA6 0xf4c9 -#define F0900_P1_DMDRES_DATA6 0xf4c900ff - -/*P1_DMDRESDATA5*/ -#define R0900_P1_DMDRESDATA5 0xf4ca -#define F0900_P1_DMDRES_DATA5 0xf4ca00ff - -/*P1_DMDRESDATA4*/ -#define R0900_P1_DMDRESDATA4 0xf4cb -#define F0900_P1_DMDRES_DATA4 0xf4cb00ff - -/*P1_DMDRESDATA3*/ -#define R0900_P1_DMDRESDATA3 0xf4cc -#define F0900_P1_DMDRES_DATA3 0xf4cc00ff - -/*P1_DMDRESDATA2*/ -#define R0900_P1_DMDRESDATA2 0xf4cd -#define F0900_P1_DMDRES_DATA2 0xf4cd00ff - -/*P1_DMDRESDATA1*/ -#define R0900_P1_DMDRESDATA1 0xf4ce -#define F0900_P1_DMDRES_DATA1 0xf4ce00ff - -/*P1_DMDRESDATA0*/ -#define R0900_P1_DMDRESDATA0 0xf4cf -#define F0900_P1_DMDRES_DATA0 0xf4cf00ff - -/*P1_FFEI1*/ -#define R0900_P1_FFEI1 0xf4d0 -#define F0900_P1_FFE_ACCI1 0xf4d001ff - -/*P1_FFEQ1*/ -#define R0900_P1_FFEQ1 0xf4d1 -#define F0900_P1_FFE_ACCQ1 0xf4d101ff - -/*P1_FFEI2*/ -#define R0900_P1_FFEI2 0xf4d2 -#define F0900_P1_FFE_ACCI2 0xf4d201ff - -/*P1_FFEQ2*/ -#define R0900_P1_FFEQ2 0xf4d3 -#define F0900_P1_FFE_ACCQ2 0xf4d301ff - -/*P1_FFEI3*/ -#define R0900_P1_FFEI3 0xf4d4 -#define F0900_P1_FFE_ACCI3 0xf4d401ff - -/*P1_FFEQ3*/ -#define R0900_P1_FFEQ3 0xf4d5 -#define F0900_P1_FFE_ACCQ3 0xf4d501ff - -/*P1_FFEI4*/ -#define R0900_P1_FFEI4 0xf4d6 -#define F0900_P1_FFE_ACCI4 0xf4d601ff - -/*P1_FFEQ4*/ -#define R0900_P1_FFEQ4 0xf4d7 -#define F0900_P1_FFE_ACCQ4 0xf4d701ff - -/*P1_FFECFG*/ -#define R0900_P1_FFECFG 0xf4d8 -#define F0900_P1_EQUALFFE_ON 0xf4d80040 -#define F0900_P1_EQUAL_USEDSYMB 0xf4d80030 -#define F0900_P1_MU_EQUALFFE 0xf4d80007 - -/*P1_TNRCFG*/ -#define R0900_P1_TNRCFG 0xf4e0 -#define F0900_P1_TUN_ACKFAIL 0xf4e00080 -#define F0900_P1_TUN_TYPE 0xf4e00070 -#define F0900_P1_TUN_SECSTOP 0xf4e00008 -#define F0900_P1_TUN_VCOSRCH 0xf4e00004 -#define F0900_P1_TUN_MADDRESS 0xf4e00003 - -/*P1_TNRCFG2*/ -#define R0900_P1_TNRCFG2 0xf4e1 -#define F0900_P1_TUN_IQSWAP 0xf4e10080 -#define F0900_P1_STB6110_STEP2MHZ 0xf4e10040 -#define F0900_P1_STB6120_DBLI2C 0xf4e10020 -#define F0900_P1_DIS_FCCK 0xf4e10010 -#define F0900_P1_DIS_LPEN 0xf4e10008 -#define F0900_P1_DIS_BWCALC 0xf4e10004 -#define F0900_P1_SHORT_WAITSTATES 0xf4e10002 -#define F0900_P1_DIS_2BWAGC1 0xf4e10001 - -/*P1_TNRXTAL*/ -#define R0900_P1_TNRXTAL 0xf4e4 -#define F0900_P1_TUN_MCLKDECIMAL 0xf4e400e0 -#define F0900_P1_TUN_XTALFREQ 0xf4e4001f - -/*P1_TNRSTEPS*/ -#define R0900_P1_TNRSTEPS 0xf4e7 -#define F0900_P1_TUNER_BW1P6 0xf4e70080 -#define F0900_P1_BWINC_OFFSET 0xf4e70070 -#define F0900_P1_SOFTSTEP_RNG 0xf4e70008 -#define F0900_P1_TUN_BWOFFSET 0xf4e70107 - -/*P1_TNRGAIN*/ -#define R0900_P1_TNRGAIN 0xf4e8 -#define F0900_P1_TUN_KDIVEN 0xf4e800c0 -#define F0900_P1_STB6X00_OCK 0xf4e80030 -#define F0900_P1_TUN_GAIN 0xf4e8000f - -/*P1_TNRRF1*/ -#define R0900_P1_TNRRF1 0xf4e9 -#define F0900_P1_TUN_RFFREQ2 0xf4e900ff - -/*P1_TNRRF0*/ -#define R0900_P1_TNRRF0 0xf4ea -#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff - -/*P1_TNRBW*/ -#define R0900_P1_TNRBW 0xf4eb -#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0 -#define F0900_P1_TUN_BW 0xf4eb003f - -/*P1_TNRADJ*/ -#define R0900_P1_TNRADJ 0xf4ec -#define F0900_P1_STB61X0_RCLK 0xf4ec0080 -#define F0900_P1_STB61X0_CALTIME 0xf4ec0040 -#define F0900_P1_STB6X00_DLB 0xf4ec0038 -#define F0900_P1_STB6000_FCL 0xf4ec0007 - -/*P1_TNRCTL2*/ -#define R0900_P1_TNRCTL2 0xf4ed -#define F0900_P1_STB61X0_LCP1_RCCKOFF 0xf4ed0080 -#define F0900_P1_STB61X0_LCP0 0xf4ed0040 -#define F0900_P1_STB61X0_XTOUT_RFOUTS 0xf4ed0020 -#define F0900_P1_STB61X0_XTON_MCKDV 0xf4ed0010 -#define F0900_P1_STB61X0_CALOFF_DCOFF 0xf4ed0008 -#define F0900_P1_STB6110_LPT 0xf4ed0004 -#define F0900_P1_STB6110_RX 0xf4ed0002 -#define F0900_P1_STB6110_SYN 0xf4ed0001 - -/*P1_TNRCFG3*/ -#define R0900_P1_TNRCFG3 0xf4ee -#define F0900_P1_STB6120_DISCTRL1 0xf4ee0080 -#define F0900_P1_STB6120_INVORDER 0xf4ee0040 -#define F0900_P1_STB6120_ENCTRL6 0xf4ee0020 -#define F0900_P1_TUN_PLLFREQ 0xf4ee001c -#define F0900_P1_TUN_I2CFREQ_MODE 0xf4ee0003 - -/*P1_TNRLAUNCH*/ -#define R0900_P1_TNRLAUNCH 0xf4f0 - -/*P1_TNRLD*/ -#define R0900_P1_TNRLD 0xf4f0 -#define F0900_P1_TUNLD_VCOING 0xf4f00080 -#define F0900_P1_TUN_REG1FAIL 0xf4f00040 -#define F0900_P1_TUN_REG2FAIL 0xf4f00020 -#define F0900_P1_TUN_REG3FAIL 0xf4f00010 -#define F0900_P1_TUN_REG4FAIL 0xf4f00008 -#define F0900_P1_TUN_REG5FAIL 0xf4f00004 -#define F0900_P1_TUN_BWING 0xf4f00002 -#define F0900_P1_TUN_LOCKED 0xf4f00001 - -/*P1_TNROBSL*/ -#define R0900_P1_TNROBSL 0xf4f6 -#define F0900_P1_TUN_I2CABORTED 0xf4f60080 -#define F0900_P1_TUN_LPEN 0xf4f60040 -#define F0900_P1_TUN_FCCK 0xf4f60020 -#define F0900_P1_TUN_I2CLOCKED 0xf4f60010 -#define F0900_P1_TUN_PROGDONE 0xf4f6000c -#define F0900_P1_TUN_RFRESTE1 0xf4f60003 - -/*P1_TNRRESTE*/ -#define R0900_P1_TNRRESTE 0xf4f7 -#define F0900_P1_TUN_RFRESTE0 0xf4f700ff - -/*P1_SMAPCOEF7*/ -#define R0900_P1_SMAPCOEF7 0xf500 -#define F0900_P1_DIS_QSCALE 0xf5000080 -#define F0900_P1_SMAPCOEF_Q_LLR12 0xf500017f - -/*P1_SMAPCOEF6*/ -#define R0900_P1_SMAPCOEF6 0xf501 -#define F0900_P1_DIS_NEWSCALE 0xf5010008 -#define F0900_P1_ADJ_8PSKLLR1 0xf5010004 -#define F0900_P1_OLD_8PSKLLR1 0xf5010002 -#define F0900_P1_DIS_AB8PSK 0xf5010001 - -/*P1_SMAPCOEF5*/ -#define R0900_P1_SMAPCOEF5 0xf502 -#define F0900_P1_DIS_8SCALE 0xf5020080 -#define F0900_P1_SMAPCOEF_8P_LLR23 0xf502017f - -/*P1_DMDPLHSTAT*/ -#define R0900_P1_DMDPLHSTAT 0xf520 -#define F0900_P1_PLH_STATISTIC 0xf52000ff - -/*P1_LOCKTIME3*/ -#define R0900_P1_LOCKTIME3 0xf522 -#define F0900_P1_DEMOD_LOCKTIME3 0xf52200ff - -/*P1_LOCKTIME2*/ -#define R0900_P1_LOCKTIME2 0xf523 -#define F0900_P1_DEMOD_LOCKTIME2 0xf52300ff - -/*P1_LOCKTIME1*/ -#define R0900_P1_LOCKTIME1 0xf524 -#define F0900_P1_DEMOD_LOCKTIME1 0xf52400ff - -/*P1_LOCKTIME0*/ -#define R0900_P1_LOCKTIME0 0xf525 -#define F0900_P1_DEMOD_LOCKTIME0 0xf52500ff - -/*P1_VITSCALE*/ -#define R0900_P1_VITSCALE 0xf532 -#define F0900_P1_NVTH_NOSRANGE 0xf5320080 -#define F0900_P1_VERROR_MAXMODE 0xf5320040 -#define F0900_P1_KDIV_MODE 0xf5320030 -#define F0900_P1_NSLOWSN_LOCKED 0xf5320008 -#define F0900_P1_DELOCK_PRFLOSS 0xf5320004 -#define F0900_P1_DIS_RSFLOCK 0xf5320002 - -/*P1_FECM*/ -#define R0900_P1_FECM 0xf533 -#define F0900_P1_DSS_DVB 0xf5330080 -#define F0900_P1_DEMOD_BYPASS 0xf5330040 -#define F0900_P1_CMP_SLOWMODE 0xf5330020 -#define F0900_P1_DSS_SRCH 0xf5330010 -#define F0900_P1_DIFF_MODEVIT 0xf5330004 -#define F0900_P1_SYNCVIT 0xf5330002 -#define F0900_P1_IQINV 0xf5330001 - -/*P1_VTH12*/ -#define R0900_P1_VTH12 0xf534 -#define F0900_P1_VTH12 0xf53400ff - -/*P1_VTH23*/ -#define R0900_P1_VTH23 0xf535 -#define F0900_P1_VTH23 0xf53500ff - -/*P1_VTH34*/ -#define R0900_P1_VTH34 0xf536 -#define F0900_P1_VTH34 0xf53600ff - -/*P1_VTH56*/ -#define R0900_P1_VTH56 0xf537 -#define F0900_P1_VTH56 0xf53700ff - -/*P1_VTH67*/ -#define R0900_P1_VTH67 0xf538 -#define F0900_P1_VTH67 0xf53800ff - -/*P1_VTH78*/ -#define R0900_P1_VTH78 0xf539 -#define F0900_P1_VTH78 0xf53900ff - -/*P1_VITCURPUN*/ -#define R0900_P1_VITCURPUN 0xf53a -#define F0900_P1_VIT_MAPPING 0xf53a00e0 -#define F0900_P1_VIT_CURPUN 0xf53a001f - -/*P1_VERROR*/ -#define R0900_P1_VERROR 0xf53b -#define F0900_P1_REGERR_VIT 0xf53b00ff - -/*P1_PRVIT*/ -#define R0900_P1_PRVIT 0xf53c -#define F0900_P1_DIS_VTHLOCK 0xf53c0040 -#define F0900_P1_E7_8VIT 0xf53c0020 -#define F0900_P1_E6_7VIT 0xf53c0010 -#define F0900_P1_E5_6VIT 0xf53c0008 -#define F0900_P1_E3_4VIT 0xf53c0004 -#define F0900_P1_E2_3VIT 0xf53c0002 -#define F0900_P1_E1_2VIT 0xf53c0001 - -/*P1_VAVSRVIT*/ -#define R0900_P1_VAVSRVIT 0xf53d -#define F0900_P1_AMVIT 0xf53d0080 -#define F0900_P1_FROZENVIT 0xf53d0040 -#define F0900_P1_SNVIT 0xf53d0030 -#define F0900_P1_TOVVIT 0xf53d000c -#define F0900_P1_HYPVIT 0xf53d0003 - -/*P1_VSTATUSVIT*/ -#define R0900_P1_VSTATUSVIT 0xf53e -#define F0900_P1_VITERBI_ON 0xf53e0080 -#define F0900_P1_END_LOOPVIT 0xf53e0040 -#define F0900_P1_VITERBI_DEPRF 0xf53e0020 -#define F0900_P1_PRFVIT 0xf53e0010 -#define F0900_P1_LOCKEDVIT 0xf53e0008 -#define F0900_P1_VITERBI_DELOCK 0xf53e0004 -#define F0900_P1_VIT_DEMODSEL 0xf53e0002 -#define F0900_P1_VITERBI_COMPOUT 0xf53e0001 - -/*P1_VTHINUSE*/ -#define R0900_P1_VTHINUSE 0xf53f -#define F0900_P1_VIT_INUSE 0xf53f00ff - -/*P1_KDIV12*/ -#define R0900_P1_KDIV12 0xf540 -#define F0900_P1_KDIV12_MANUAL 0xf5400080 -#define F0900_P1_K_DIVIDER_12 0xf540007f - -/*P1_KDIV23*/ -#define R0900_P1_KDIV23 0xf541 -#define F0900_P1_KDIV23_MANUAL 0xf5410080 -#define F0900_P1_K_DIVIDER_23 0xf541007f - -/*P1_KDIV34*/ -#define R0900_P1_KDIV34 0xf542 -#define F0900_P1_KDIV34_MANUAL 0xf5420080 -#define F0900_P1_K_DIVIDER_34 0xf542007f - -/*P1_KDIV56*/ -#define R0900_P1_KDIV56 0xf543 -#define F0900_P1_KDIV56_MANUAL 0xf5430080 -#define F0900_P1_K_DIVIDER_56 0xf543007f - -/*P1_KDIV67*/ -#define R0900_P1_KDIV67 0xf544 -#define F0900_P1_KDIV67_MANUAL 0xf5440080 -#define F0900_P1_K_DIVIDER_67 0xf544007f - -/*P1_KDIV78*/ -#define R0900_P1_KDIV78 0xf545 -#define F0900_P1_KDIV78_MANUAL 0xf5450080 -#define F0900_P1_K_DIVIDER_78 0xf545007f - -/*P1_PDELCTRL1*/ -#define R0900_P1_PDELCTRL1 0xf550 -#define F0900_P1_INV_MISMASK 0xf5500080 -#define F0900_P1_FORCE_ACCEPTED 0xf5500040 -#define F0900_P1_FILTER_EN 0xf5500020 -#define F0900_P1_FORCE_PKTDELINUSE 0xf5500010 -#define F0900_P1_HYSTEN 0xf5500008 -#define F0900_P1_HYSTSWRST 0xf5500004 -#define F0900_P1_EN_MIS00 0xf5500002 -#define F0900_P1_ALGOSWRST 0xf5500001 - -/*P1_PDELCTRL2*/ -#define R0900_P1_PDELCTRL2 0xf551 -#define F0900_P1_FORCE_CONTINUOUS 0xf5510080 -#define F0900_P1_RESET_UPKO_COUNT 0xf5510040 -#define F0900_P1_USER_PKTDELIN_NB 0xf5510020 -#define F0900_P1_FORCE_LOCKED 0xf5510010 -#define F0900_P1_DATA_UNBBSCRAM 0xf5510008 -#define F0900_P1_FORCE_LONGPKT 0xf5510004 -#define F0900_P1_FRAME_MODE 0xf5510002 - -/*P1_HYSTTHRESH*/ -#define R0900_P1_HYSTTHRESH 0xf554 -#define F0900_P1_UNLCK_THRESH 0xf55400f0 -#define F0900_P1_DELIN_LCK_THRESH 0xf554000f - -/*P1_ISIENTRY*/ -#define R0900_P1_ISIENTRY 0xf55e -#define F0900_P1_ISI_ENTRY 0xf55e00ff - -/*P1_ISIBITENA*/ -#define R0900_P1_ISIBITENA 0xf55f -#define F0900_P1_ISI_BIT_EN 0xf55f00ff - -/*P1_MATSTR1*/ -#define R0900_P1_MATSTR1 0xf560 -#define F0900_P1_MATYPE_CURRENT1 0xf56000ff - -/*P1_MATSTR0*/ -#define R0900_P1_MATSTR0 0xf561 -#define F0900_P1_MATYPE_CURRENT0 0xf56100ff - -/*P1_UPLSTR1*/ -#define R0900_P1_UPLSTR1 0xf562 -#define F0900_P1_UPL_CURRENT1 0xf56200ff - -/*P1_UPLSTR0*/ -#define R0900_P1_UPLSTR0 0xf563 -#define F0900_P1_UPL_CURRENT0 0xf56300ff - -/*P1_DFLSTR1*/ -#define R0900_P1_DFLSTR1 0xf564 -#define F0900_P1_DFL_CURRENT1 0xf56400ff - -/*P1_DFLSTR0*/ -#define R0900_P1_DFLSTR0 0xf565 -#define F0900_P1_DFL_CURRENT0 0xf56500ff - -/*P1_SYNCSTR*/ -#define R0900_P1_SYNCSTR 0xf566 -#define F0900_P1_SYNC_CURRENT 0xf56600ff - -/*P1_SYNCDSTR1*/ -#define R0900_P1_SYNCDSTR1 0xf567 -#define F0900_P1_SYNCD_CURRENT1 0xf56700ff - -/*P1_SYNCDSTR0*/ -#define R0900_P1_SYNCDSTR0 0xf568 -#define F0900_P1_SYNCD_CURRENT0 0xf56800ff - -/*P1_PDELSTATUS1*/ -#define R0900_P1_PDELSTATUS1 0xf569 -#define F0900_P1_PKTDELIN_DELOCK 0xf5690080 -#define F0900_P1_SYNCDUPDFL_BADDFL 0xf5690040 -#define F0900_P1_CONTINUOUS_STREAM 0xf5690020 -#define F0900_P1_UNACCEPTED_STREAM 0xf5690010 -#define F0900_P1_BCH_ERROR_FLAG 0xf5690008 -#define F0900_P1_BBHCRCKO 0xf5690004 -#define F0900_P1_PKTDELIN_LOCK 0xf5690002 -#define F0900_P1_FIRST_LOCK 0xf5690001 - -/*P1_PDELSTATUS2*/ -#define R0900_P1_PDELSTATUS2 0xf56a -#define F0900_P1_PKTDEL_DEMODSEL 0xf56a0080 -#define F0900_P1_FRAME_MODCOD 0xf56a007c -#define F0900_P1_FRAME_TYPE 0xf56a0003 - -/*P1_BBFCRCKO1*/ -#define R0900_P1_BBFCRCKO1 0xf56b -#define F0900_P1_BBHCRC_KOCNT1 0xf56b00ff - -/*P1_BBFCRCKO0*/ -#define R0900_P1_BBFCRCKO0 0xf56c -#define F0900_P1_BBHCRC_KOCNT0 0xf56c00ff - -/*P1_UPCRCKO1*/ -#define R0900_P1_UPCRCKO1 0xf56d -#define F0900_P1_PKTCRC_KOCNT1 0xf56d00ff - -/*P1_UPCRCKO0*/ -#define R0900_P1_UPCRCKO0 0xf56e -#define F0900_P1_PKTCRC_KOCNT0 0xf56e00ff - -/*P1_TSSTATEM*/ -#define R0900_P1_TSSTATEM 0xf570 -#define F0900_P1_TSDIL_ON 0xf5700080 -#define F0900_P1_TSSKIPRS_ON 0xf5700040 -#define F0900_P1_TSRS_ON 0xf5700020 -#define F0900_P1_TSDESCRAMB_ON 0xf5700010 -#define F0900_P1_TSFRAME_MODE 0xf5700008 -#define F0900_P1_TS_DISABLE 0xf5700004 -#define F0900_P1_TSACM_MODE 0xf5700002 -#define F0900_P1_TSOUT_NOSYNC 0xf5700001 - -/*P1_TSCFGH*/ -#define R0900_P1_TSCFGH 0xf572 -#define F0900_P1_TSFIFO_DVBCI 0xf5720080 -#define F0900_P1_TSFIFO_SERIAL 0xf5720040 -#define F0900_P1_TSFIFO_TEIUPDATE 0xf5720020 -#define F0900_P1_TSFIFO_DUTY50 0xf5720010 -#define F0900_P1_TSFIFO_HSGNLOUT 0xf5720008 -#define F0900_P1_TSFIFO_ERRMODE 0xf5720006 -#define F0900_P1_RST_HWARE 0xf5720001 - -/*P1_TSCFGM*/ -#define R0900_P1_TSCFGM 0xf573 -#define F0900_P1_TSFIFO_MANSPEED 0xf57300c0 -#define F0900_P1_TSFIFO_PERMDATA 0xf5730020 -#define F0900_P1_TSFIFO_NONEWSGNL 0xf5730010 -#define F0900_P1_TSFIFO_BITSPEED 0xf5730008 -#define F0900_P1_NPD_SPECDVBS2 0xf5730004 -#define F0900_P1_TSFIFO_STOPCKDIS 0xf5730002 -#define F0900_P1_TSFIFO_INVDATA 0xf5730001 - -/*P1_TSCFGL*/ -#define R0900_P1_TSCFGL 0xf574 -#define F0900_P1_TSFIFO_BCLKDEL1CK 0xf57400c0 -#define F0900_P1_BCHERROR_MODE 0xf5740030 -#define F0900_P1_TSFIFO_NSGNL2DATA 0xf5740008 -#define F0900_P1_TSFIFO_EMBINDVB 0xf5740004 -#define F0900_P1_TSFIFO_DPUNACT 0xf5740002 -#define F0900_P1_TSFIFO_NPDOFF 0xf5740001 - -/*P1_TSINSDELH*/ -#define R0900_P1_TSINSDELH 0xf576 -#define F0900_P1_TSDEL_SYNCBYTE 0xf5760080 -#define F0900_P1_TSDEL_XXHEADER 0xf5760040 -#define F0900_P1_TSDEL_BBHEADER 0xf5760020 -#define F0900_P1_TSDEL_DATAFIELD 0xf5760010 -#define F0900_P1_TSINSDEL_ISCR 0xf5760008 -#define F0900_P1_TSINSDEL_NPD 0xf5760004 -#define F0900_P1_TSINSDEL_RSPARITY 0xf5760002 -#define F0900_P1_TSINSDEL_CRC8 0xf5760001 - -/*P1_TSSPEED*/ -#define R0900_P1_TSSPEED 0xf580 -#define F0900_P1_TSFIFO_OUTSPEED 0xf58000ff - -/*P1_TSSTATUS*/ -#define R0900_P1_TSSTATUS 0xf581 -#define F0900_P1_TSFIFO_LINEOK 0xf5810080 -#define F0900_P1_TSFIFO_ERROR 0xf5810040 -#define F0900_P1_TSFIFO_DATA7 0xf5810020 -#define F0900_P1_TSFIFO_NOSYNC 0xf5810010 -#define F0900_P1_ISCR_INITIALIZED 0xf5810008 -#define F0900_P1_ISCR_UPDATED 0xf5810004 -#define F0900_P1_SOFFIFO_UNREGUL 0xf5810002 -#define F0900_P1_DIL_READY 0xf5810001 - -/*P1_TSSTATUS2*/ -#define R0900_P1_TSSTATUS2 0xf582 -#define F0900_P1_TSFIFO_DEMODSEL 0xf5820080 -#define F0900_P1_TSFIFOSPEED_STORE 0xf5820040 -#define F0900_P1_DILXX_RESET 0xf5820020 -#define F0900_P1_TSSERIAL_IMPOS 0xf5820010 -#define F0900_P1_TSFIFO_LINENOK 0xf5820008 -#define F0900_P1_BITSPEED_EVENT 0xf5820004 -#define F0900_P1_SCRAMBDETECT 0xf5820002 -#define F0900_P1_ULDTV67_FALSELOCK 0xf5820001 - -/*P1_TSBITRATE1*/ -#define R0900_P1_TSBITRATE1 0xf583 -#define F0900_P1_TSFIFO_BITRATE1 0xf58300ff - -/*P1_TSBITRATE0*/ -#define R0900_P1_TSBITRATE0 0xf584 -#define F0900_P1_TSFIFO_BITRATE0 0xf58400ff - -/*P1_ERRCTRL1*/ -#define R0900_P1_ERRCTRL1 0xf598 -#define F0900_P1_ERR_SOURCE1 0xf59800f0 -#define F0900_P1_NUM_EVENT1 0xf5980007 - -/*P1_ERRCNT12*/ -#define R0900_P1_ERRCNT12 0xf599 -#define F0900_P1_ERRCNT1_OLDVALUE 0xf5990080 -#define F0900_P1_ERR_CNT12 0xf599007f - -/*P1_ERRCNT11*/ -#define R0900_P1_ERRCNT11 0xf59a -#define F0900_P1_ERR_CNT11 0xf59a00ff - -/*P1_ERRCNT10*/ -#define R0900_P1_ERRCNT10 0xf59b -#define F0900_P1_ERR_CNT10 0xf59b00ff - -/*P1_ERRCTRL2*/ -#define R0900_P1_ERRCTRL2 0xf59c -#define F0900_P1_ERR_SOURCE2 0xf59c00f0 -#define F0900_P1_NUM_EVENT2 0xf59c0007 - -/*P1_ERRCNT22*/ -#define R0900_P1_ERRCNT22 0xf59d -#define F0900_P1_ERRCNT2_OLDVALUE 0xf59d0080 -#define F0900_P1_ERR_CNT22 0xf59d007f - -/*P1_ERRCNT21*/ -#define R0900_P1_ERRCNT21 0xf59e -#define F0900_P1_ERR_CNT21 0xf59e00ff - -/*P1_ERRCNT20*/ -#define R0900_P1_ERRCNT20 0xf59f -#define F0900_P1_ERR_CNT20 0xf59f00ff - -/*P1_FECSPY*/ -#define R0900_P1_FECSPY 0xf5a0 -#define F0900_P1_SPY_ENABLE 0xf5a00080 -#define F0900_P1_NO_SYNCBYTE 0xf5a00040 -#define F0900_P1_SERIAL_MODE 0xf5a00020 -#define F0900_P1_UNUSUAL_PACKET 0xf5a00010 -#define F0900_P1_BER_PACKMODE 0xf5a00008 -#define F0900_P1_BERMETER_LMODE 0xf5a00002 -#define F0900_P1_BERMETER_RESET 0xf5a00001 - -/*P1_FSPYCFG*/ -#define R0900_P1_FSPYCFG 0xf5a1 -#define F0900_P1_FECSPY_INPUT 0xf5a100c0 -#define F0900_P1_RST_ON_ERROR 0xf5a10020 -#define F0900_P1_ONE_SHOT 0xf5a10010 -#define F0900_P1_I2C_MODE 0xf5a1000c -#define F0900_P1_SPY_HYSTERESIS 0xf5a10003 - -/*P1_FSPYDATA*/ -#define R0900_P1_FSPYDATA 0xf5a2 -#define F0900_P1_SPY_STUFFING 0xf5a20080 -#define F0900_P1_NOERROR_PKTJITTER 0xf5a20040 -#define F0900_P1_SPY_CNULLPKT 0xf5a20020 -#define F0900_P1_SPY_OUTDATA_MODE 0xf5a2001f - -/*P1_FSPYOUT*/ -#define R0900_P1_FSPYOUT 0xf5a3 -#define F0900_P1_FSPY_DIRECT 0xf5a30080 -#define F0900_P1_SPY_OUTDATA_BUS 0xf5a30038 -#define F0900_P1_STUFF_MODE 0xf5a30007 - -/*P1_FSTATUS*/ -#define R0900_P1_FSTATUS 0xf5a4 -#define F0900_P1_SPY_ENDSIM 0xf5a40080 -#define F0900_P1_VALID_SIM 0xf5a40040 -#define F0900_P1_FOUND_SIGNAL 0xf5a40020 -#define F0900_P1_DSS_SYNCBYTE 0xf5a40010 -#define F0900_P1_RESULT_STATE 0xf5a4000f - -/*P1_FBERCPT4*/ -#define R0900_P1_FBERCPT4 0xf5a8 -#define F0900_P1_FBERMETER_CPT4 0xf5a800ff - -/*P1_FBERCPT3*/ -#define R0900_P1_FBERCPT3 0xf5a9 -#define F0900_P1_FBERMETER_CPT3 0xf5a900ff - -/*P1_FBERCPT2*/ -#define R0900_P1_FBERCPT2 0xf5aa -#define F0900_P1_FBERMETER_CPT2 0xf5aa00ff - -/*P1_FBERCPT1*/ -#define R0900_P1_FBERCPT1 0xf5ab -#define F0900_P1_FBERMETER_CPT1 0xf5ab00ff - -/*P1_FBERCPT0*/ -#define R0900_P1_FBERCPT0 0xf5ac -#define F0900_P1_FBERMETER_CPT0 0xf5ac00ff - -/*P1_FBERERR2*/ -#define R0900_P1_FBERERR2 0xf5ad -#define F0900_P1_FBERMETER_ERR2 0xf5ad00ff - -/*P1_FBERERR1*/ -#define R0900_P1_FBERERR1 0xf5ae -#define F0900_P1_FBERMETER_ERR1 0xf5ae00ff - -/*P1_FBERERR0*/ -#define R0900_P1_FBERERR0 0xf5af -#define F0900_P1_FBERMETER_ERR0 0xf5af00ff - -/*P1_FSPYBER*/ -#define R0900_P1_FSPYBER 0xf5b2 -#define F0900_P1_FSPYOBS_XORREAD 0xf5b20040 -#define F0900_P1_FSPYBER_OBSMODE 0xf5b20020 -#define F0900_P1_FSPYBER_SYNCBYTE 0xf5b20010 -#define F0900_P1_FSPYBER_UNSYNC 0xf5b20008 -#define F0900_P1_FSPYBER_CTIME 0xf5b20007 - -/*RCCFGH*/ -#define R0900_RCCFGH 0xf600 -#define F0900_TSRCFIFO_DVBCI 0xf6000080 -#define F0900_TSRCFIFO_SERIAL 0xf6000040 -#define F0900_TSRCFIFO_DISABLE 0xf6000020 -#define F0900_TSFIFO_2TORC 0xf6000010 -#define F0900_TSRCFIFO_HSGNLOUT 0xf6000008 -#define F0900_TSRCFIFO_ERRMODE 0xf6000006 - -/*TSGENERAL*/ -#define R0900_TSGENERAL 0xf630 -#define F0900_TSFIFO_BCLK1ALL 0xf6300020 -#define F0900_MUXSTREAM_OUTMODE 0xf6300008 -#define F0900_TSFIFO_PERMPARAL 0xf6300006 -#define F0900_RST_REEDSOLO 0xf6300001 - -/*TSGENERAL1X*/ -#define R0900_TSGENERAL1X 0xf670 -#define F0900_TSFIFO1X_BCLK1ALL 0xf6700020 -#define F0900_MUXSTREAM1X_OUTMODE 0xf6700008 -#define F0900_TSFIFO1X_PERMPARAL 0xf6700006 -#define F0900_RST1X_REEDSOLO 0xf6700001 - -/*NBITER_NF4*/ -#define R0900_NBITER_NF4 0xfa03 -#define F0900_NBITER_NF_QP_1_2 0xfa0300ff - -/*NBITER_NF5*/ -#define R0900_NBITER_NF5 0xfa04 -#define F0900_NBITER_NF_QP_3_5 0xfa0400ff - -/*NBITER_NF6*/ -#define R0900_NBITER_NF6 0xfa05 -#define F0900_NBITER_NF_QP_2_3 0xfa0500ff - -/*NBITER_NF7*/ -#define R0900_NBITER_NF7 0xfa06 -#define F0900_NBITER_NF_QP_3_4 0xfa0600ff - -/*NBITER_NF8*/ -#define R0900_NBITER_NF8 0xfa07 -#define F0900_NBITER_NF_QP_4_5 0xfa0700ff - -/*NBITER_NF9*/ -#define R0900_NBITER_NF9 0xfa08 -#define F0900_NBITER_NF_QP_5_6 0xfa0800ff - -/*NBITER_NF10*/ -#define R0900_NBITER_NF10 0xfa09 -#define F0900_NBITER_NF_QP_8_9 0xfa0900ff - -/*NBITER_NF11*/ -#define R0900_NBITER_NF11 0xfa0a -#define F0900_NBITER_NF_QP_9_10 0xfa0a00ff - -/*NBITER_NF12*/ -#define R0900_NBITER_NF12 0xfa0b -#define F0900_NBITER_NF_8P_3_5 0xfa0b00ff - -/*NBITER_NF13*/ -#define R0900_NBITER_NF13 0xfa0c -#define F0900_NBITER_NF_8P_2_3 0xfa0c00ff - -/*NBITER_NF14*/ -#define R0900_NBITER_NF14 0xfa0d -#define F0900_NBITER_NF_8P_3_4 0xfa0d00ff - -/*NBITER_NF15*/ -#define R0900_NBITER_NF15 0xfa0e -#define F0900_NBITER_NF_8P_5_6 0xfa0e00ff - -/*NBITER_NF16*/ -#define R0900_NBITER_NF16 0xfa0f -#define F0900_NBITER_NF_8P_8_9 0xfa0f00ff - -/*NBITER_NF17*/ -#define R0900_NBITER_NF17 0xfa10 -#define F0900_NBITER_NF_8P_9_10 0xfa1000ff - -/*NBITERNOERR*/ -#define R0900_NBITERNOERR 0xfa3f -#define F0900_NBITER_STOP_CRIT 0xfa3f000f - -/*GAINLLR_NF4*/ -#define R0900_GAINLLR_NF4 0xfa43 -#define F0900_GAINLLR_NF_QP_1_2 0xfa43007f - -/*GAINLLR_NF5*/ -#define R0900_GAINLLR_NF5 0xfa44 -#define F0900_GAINLLR_NF_QP_3_5 0xfa44007f - -/*GAINLLR_NF6*/ -#define R0900_GAINLLR_NF6 0xfa45 -#define F0900_GAINLLR_NF_QP_2_3 0xfa45007f - -/*GAINLLR_NF7*/ -#define R0900_GAINLLR_NF7 0xfa46 -#define F0900_GAINLLR_NF_QP_3_4 0xfa46007f - -/*GAINLLR_NF8*/ -#define R0900_GAINLLR_NF8 0xfa47 -#define F0900_GAINLLR_NF_QP_4_5 0xfa47007f - -/*GAINLLR_NF9*/ -#define R0900_GAINLLR_NF9 0xfa48 -#define F0900_GAINLLR_NF_QP_5_6 0xfa48007f - -/*GAINLLR_NF10*/ -#define R0900_GAINLLR_NF10 0xfa49 -#define F0900_GAINLLR_NF_QP_8_9 0xfa49007f - -/*GAINLLR_NF11*/ -#define R0900_GAINLLR_NF11 0xfa4a -#define F0900_GAINLLR_NF_QP_9_10 0xfa4a007f - -/*GAINLLR_NF12*/ -#define R0900_GAINLLR_NF12 0xfa4b -#define F0900_GAINLLR_NF_8P_3_5 0xfa4b007f - -/*GAINLLR_NF13*/ -#define R0900_GAINLLR_NF13 0xfa4c -#define F0900_GAINLLR_NF_8P_2_3 0xfa4c007f - -/*GAINLLR_NF14*/ -#define R0900_GAINLLR_NF14 0xfa4d -#define F0900_GAINLLR_NF_8P_3_4 0xfa4d007f - -/*GAINLLR_NF15*/ -#define R0900_GAINLLR_NF15 0xfa4e -#define F0900_GAINLLR_NF_8P_5_6 0xfa4e007f - -/*GAINLLR_NF16*/ -#define R0900_GAINLLR_NF16 0xfa4f -#define F0900_GAINLLR_NF_8P_8_9 0xfa4f007f - -/*GAINLLR_NF17*/ -#define R0900_GAINLLR_NF17 0xfa50 -#define F0900_GAINLLR_NF_8P_9_10 0xfa50007f - -/*CFGEXT*/ -#define R0900_CFGEXT 0xfa80 -#define F0900_STAGMODE 0xfa800080 -#define F0900_BYPBCH 0xfa800040 -#define F0900_BYPLDPC 0xfa800020 -#define F0900_LDPCMODE 0xfa800010 -#define F0900_INVLLRSIGN 0xfa800008 -#define F0900_SHORTMULT 0xfa800004 -#define F0900_EXTERNTX 0xfa800001 - -/*GENCFG*/ -#define R0900_GENCFG 0xfa86 -#define F0900_BROADCAST 0xfa860010 -#define F0900_NOSHFRD2 0xfa860008 -#define F0900_BCHERRFLAG 0xfa860004 -#define F0900_PRIORITY 0xfa860002 -#define F0900_DDEMOD 0xfa860001 - -/*LDPCERR1*/ -#define R0900_LDPCERR1 0xfa96 -#define F0900_LDPC_ERRORS_COUNTER1 0xfa9600ff - -/*LDPCERR0*/ -#define R0900_LDPCERR0 0xfa97 -#define F0900_LDPC_ERRORS_COUNTER0 0xfa9700ff - -/*BCHERR*/ -#define R0900_BCHERR 0xfa98 -#define F0900_ERRORFLAG 0xfa980010 -#define F0900_BCH_ERRORS_COUNTER 0xfa98000f - -/*TSTRES0*/ -#define R0900_TSTRES0 0xff11 -#define F0900_FRESFEC 0xff110080 -#define F0900_FRESTS 0xff110040 -#define F0900_FRESVIT1 0xff110020 -#define F0900_FRESVIT2 0xff110010 -#define F0900_FRESSYM1 0xff110008 -#define F0900_FRESSYM2 0xff110004 -#define F0900_FRESMAS 0xff110002 -#define F0900_FRESINT 0xff110001 - -/*P2_TSTDISRX*/ -#define R0900_P2_TSTDISRX 0xff65 -#define F0900_P2_EN_DISRX 0xff650080 -#define F0900_P2_TST_CURRSRC 0xff650040 -#define F0900_P2_IN_DIGSIGNAL 0xff650020 -#define F0900_P2_HIZ_CURRENTSRC 0xff650010 -#define F0900_TST_P2_PIN_SELECT 0xff650008 -#define F0900_P2_TST_DISRX 0xff650007 - -/*P1_TSTDISRX*/ -#define R0900_P1_TSTDISRX 0xff67 -#define F0900_P1_EN_DISRX 0xff670080 -#define F0900_P1_TST_CURRSRC 0xff670040 -#define F0900_P1_IN_DIGSIGNAL 0xff670020 -#define F0900_P1_HIZ_CURRENTSRC 0xff670010 -#define F0900_TST_P1_PIN_SELECT 0xff670008 -#define F0900_P1_TST_DISRX 0xff670007 - -#define STV0900_NBREGS 684 -#define STV0900_NBFIELDS 1702 - -#endif - diff --git a/trunk/drivers/media/dvb/frontends/stv0900_sw.c b/trunk/drivers/media/dvb/frontends/stv0900_sw.c deleted file mode 100644 index a5a31536cbcb..000000000000 --- a/trunk/drivers/media/dvb/frontends/stv0900_sw.c +++ /dev/null @@ -1,2847 +0,0 @@ -/* - * stv0900_sw.c - * - * Driver for ST STV0900 satellite demodulator IC. - * - * Copyright (C) ST Microelectronics. - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "stv0900.h" -#include "stv0900_reg.h" -#include "stv0900_priv.h" - -int stv0900_check_signal_presence(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - s32 carr_offset, - agc2_integr, - max_carrier; - - int no_signal; - - switch (demod) { - case STV0900_DEMOD_1: - default: - carr_offset = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8) - | stv0900_read_reg(i_params, - R0900_P1_CFR1); - carr_offset = ge2comp(carr_offset, 16); - agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) - | stv0900_read_reg(i_params, - R0900_P1_AGC2I0); - max_carrier = i_params->dmd1_srch_range / 1000; - break; - case STV0900_DEMOD_2: - carr_offset = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8) - | stv0900_read_reg(i_params, - R0900_P2_CFR1); - carr_offset = ge2comp(carr_offset, 16); - agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) - | stv0900_read_reg(i_params, - R0900_P2_AGC2I0); - max_carrier = i_params->dmd2_srch_range / 1000; - break; - } - - max_carrier += (max_carrier / 10); - max_carrier = 65536 * (max_carrier / 2); - max_carrier /= i_params->mclk / 1000; - if (max_carrier > 0x4000) - max_carrier = 0x4000; - - if ((agc2_integr > 0x2000) - || (carr_offset > + 2*max_carrier) - || (carr_offset < -2*max_carrier)) - no_signal = TRUE; - else - no_signal = FALSE; - - return no_signal; -} - -static void stv0900_get_sw_loop_params(struct stv0900_internal *i_params, - s32 *frequency_inc, s32 *sw_timeout, - s32 *steps, - enum fe_stv0900_demod_num demod) -{ - s32 timeout, freq_inc, max_steps, srate, max_carrier; - - enum fe_stv0900_search_standard standard; - - switch (demod) { - case STV0900_DEMOD_1: - default: - srate = i_params->dmd1_symbol_rate; - max_carrier = i_params->dmd1_srch_range / 1000; - max_carrier += max_carrier / 10; - standard = i_params->dmd1_srch_standard; - break; - case STV0900_DEMOD_2: - srate = i_params->dmd2_symbol_rate; - max_carrier = i_params->dmd2_srch_range / 1000; - max_carrier += max_carrier / 10; - standard = i_params->dmd2_srch_stndrd; - break; - } - - max_carrier = 65536 * (max_carrier / 2); - max_carrier /= i_params->mclk / 1000; - - if (max_carrier > 0x4000) - max_carrier = 0x4000; - - freq_inc = srate; - freq_inc /= i_params->mclk >> 10; - freq_inc = freq_inc << 6; - - switch (standard) { - case STV0900_SEARCH_DVBS1: - case STV0900_SEARCH_DSS: - freq_inc *= 3; - timeout = 20; - break; - case STV0900_SEARCH_DVBS2: - freq_inc *= 4; - timeout = 25; - break; - case STV0900_AUTO_SEARCH: - default: - freq_inc *= 3; - timeout = 25; - break; - } - - freq_inc /= 100; - - if ((freq_inc > max_carrier) || (freq_inc < 0)) - freq_inc = max_carrier / 2; - - timeout *= 27500; - - if (srate > 0) - timeout /= srate / 1000; - - if ((timeout > 100) || (timeout < 0)) - timeout = 100; - - max_steps = (max_carrier / freq_inc) + 1; - - if ((max_steps > 100) || (max_steps < 0)) { - max_steps = 100; - freq_inc = max_carrier / max_steps; - } - - *frequency_inc = freq_inc; - *sw_timeout = timeout; - *steps = max_steps; - -} - -static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params, - s32 FreqIncr, s32 Timeout, int zigzag, - s32 MaxStep, enum fe_stv0900_demod_num demod) -{ - int no_signal, - lock = FALSE; - s32 stepCpt, - freqOffset, - max_carrier; - - switch (demod) { - case STV0900_DEMOD_1: - default: - max_carrier = i_params->dmd1_srch_range / 1000; - max_carrier += (max_carrier / 10); - break; - case STV0900_DEMOD_2: - max_carrier = i_params->dmd2_srch_range / 1000; - max_carrier += (max_carrier / 10); - break; - } - - max_carrier = 65536 * (max_carrier / 2); - max_carrier /= i_params->mclk / 1000; - - if (max_carrier > 0x4000) - max_carrier = 0x4000; - - if (zigzag == TRUE) - freqOffset = 0; - else - freqOffset = -max_carrier + FreqIncr; - - stepCpt = 0; - - do { - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, - (freqOffset / 256) & 0xFF); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, - freqOffset & 0xFF); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); - stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1); - - if (i_params->chip_id == 0x12) { - stv0900_write_bits(i_params, - F0900_P1_RST_HWARE, 1); - stv0900_write_bits(i_params, - F0900_P1_RST_HWARE, 0); - } - break; - case STV0900_DEMOD_2: - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, - (freqOffset / 256) & 0xFF); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, - freqOffset & 0xFF); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); - stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1); - - if (i_params->chip_id == 0x12) { - stv0900_write_bits(i_params, - F0900_P2_RST_HWARE, 1); - stv0900_write_bits(i_params, - F0900_P2_RST_HWARE, 0); - } - break; - } - - if (zigzag == TRUE) { - if (freqOffset >= 0) - freqOffset = -freqOffset - 2 * FreqIncr; - else - freqOffset = -freqOffset; - } else - freqOffset += + 2 * FreqIncr; - - stepCpt++; - lock = stv0900_get_demod_lock(i_params, demod, Timeout); - no_signal = stv0900_check_signal_presence(i_params, demod); - - } while ((lock == FALSE) - && (no_signal == FALSE) - && ((freqOffset - FreqIncr) < max_carrier) - && ((freqOffset + FreqIncr) > -max_carrier) - && (stepCpt < MaxStep)); - - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0); - break; - case STV0900_DEMOD_2: - stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0); - break; - } - - return lock; -} - -int stv0900_sw_algo(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - int lock = FALSE; - - int no_signal, - zigzag; - s32 dvbs2_fly_wheel; - - s32 freqIncrement, softStepTimeout, trialCounter, max_steps; - - stv0900_get_sw_loop_params(i_params, &freqIncrement, &softStepTimeout, - &max_steps, demod); - switch (demod) { - case STV0900_DEMOD_1: - default: - switch (i_params->dmd1_srch_standard) { - case STV0900_SEARCH_DVBS1: - case STV0900_SEARCH_DSS: - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P1_CARFREQ, - 0x3B); - else - stv0900_write_reg(i_params, R0900_P1_CARFREQ, - 0xef); - - stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x49); - zigzag = FALSE; - break; - case STV0900_SEARCH_DVBS2: - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P1_CORRELABS, - 0x79); - else - stv0900_write_reg(i_params, R0900_P1_CORRELABS, - 0x68); - - stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, - 0x89); - - zigzag = TRUE; - break; - case STV0900_AUTO_SEARCH: - default: - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P1_CARFREQ, - 0x3B); - stv0900_write_reg(i_params, R0900_P1_CORRELABS, - 0x79); - } else { - stv0900_write_reg(i_params, R0900_P1_CARFREQ, - 0xef); - stv0900_write_reg(i_params, R0900_P1_CORRELABS, - 0x68); - } - - stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, - 0xc9); - zigzag = FALSE; - break; - } - - trialCounter = 0; - do { - lock = stv0900_search_carr_sw_loop(i_params, - freqIncrement, - softStepTimeout, - zigzag, - max_steps, - demod); - no_signal = stv0900_check_signal_presence(i_params, - demod); - trialCounter++; - if ((lock == TRUE) - || (no_signal == TRUE) - || (trialCounter == 2)) { - - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, - R0900_P1_CARFREQ, - 0x49); - stv0900_write_reg(i_params, - R0900_P1_CORRELABS, - 0x9e); - } else { - stv0900_write_reg(i_params, - R0900_P1_CARFREQ, - 0xed); - stv0900_write_reg(i_params, - R0900_P1_CORRELABS, - 0x88); - } - - if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS2_FOUND)) { - msleep(softStepTimeout); - dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT); - - if (dvbs2_fly_wheel < 0xd) { - msleep(softStepTimeout); - dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT); - } - - if (dvbs2_fly_wheel < 0xd) { - lock = FALSE; - - if (trialCounter < 2) { - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x79); - else - stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x68); - - stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x89); - } - } - } - } - - } while ((lock == FALSE) - && (trialCounter < 2) - && (no_signal == FALSE)); - - break; - case STV0900_DEMOD_2: - switch (i_params->dmd2_srch_stndrd) { - case STV0900_SEARCH_DVBS1: - case STV0900_SEARCH_DSS: - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P2_CARFREQ, - 0x3b); - else - stv0900_write_reg(i_params, R0900_P2_CARFREQ, - 0xef); - - stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, - 0x49); - zigzag = FALSE; - break; - case STV0900_SEARCH_DVBS2: - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P2_CORRELABS, - 0x79); - else - stv0900_write_reg(i_params, R0900_P2_CORRELABS, - 0x68); - - stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89); - zigzag = TRUE; - break; - case STV0900_AUTO_SEARCH: - default: - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P2_CARFREQ, - 0x3b); - stv0900_write_reg(i_params, R0900_P2_CORRELABS, - 0x79); - } else { - stv0900_write_reg(i_params, R0900_P2_CARFREQ, - 0xef); - stv0900_write_reg(i_params, R0900_P2_CORRELABS, - 0x68); - } - - stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0xc9); - - zigzag = FALSE; - break; - } - - trialCounter = 0; - - do { - lock = stv0900_search_carr_sw_loop(i_params, - freqIncrement, - softStepTimeout, - zigzag, - max_steps, - demod); - no_signal = stv0900_check_signal_presence(i_params, - demod); - trialCounter++; - if ((lock == TRUE) - || (no_signal == TRUE) - || (trialCounter == 2)) { - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, - R0900_P2_CARFREQ, - 0x49); - stv0900_write_reg(i_params, - R0900_P2_CORRELABS, - 0x9e); - } else { - stv0900_write_reg(i_params, - R0900_P2_CARFREQ, - 0xed); - stv0900_write_reg(i_params, - R0900_P2_CORRELABS, - 0x88); - } - - if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS2_FOUND)) { - msleep(softStepTimeout); - dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT); - if (dvbs2_fly_wheel < 0xd) { - msleep(softStepTimeout); - dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT); - } - - if (dvbs2_fly_wheel < 0xd) { - lock = FALSE; - if (trialCounter < 2) { - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x79); - else - stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x68); - - stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89); - } - } - } - } - - } while ((lock == FALSE) && (trialCounter < 2) && (no_signal == FALSE)); - - break; - } - - return lock; -} - -static u32 stv0900_get_symbol_rate(struct stv0900_internal *i_params, - u32 mclk, - enum fe_stv0900_demod_num demod) -{ - s32 sfr_field3, sfr_field2, sfr_field1, sfr_field0, - rem1, rem2, intval1, intval2, srate; - - dmd_reg(sfr_field3, F0900_P1_SYMB_FREQ3, F0900_P2_SYMB_FREQ3); - dmd_reg(sfr_field2, F0900_P1_SYMB_FREQ2, F0900_P2_SYMB_FREQ2); - dmd_reg(sfr_field1, F0900_P1_SYMB_FREQ1, F0900_P2_SYMB_FREQ1); - dmd_reg(sfr_field0, F0900_P1_SYMB_FREQ0, F0900_P2_SYMB_FREQ0); - - srate = (stv0900_get_bits(i_params, sfr_field3) << 24) + - (stv0900_get_bits(i_params, sfr_field2) << 16) + - (stv0900_get_bits(i_params, sfr_field1) << 8) + - (stv0900_get_bits(i_params, sfr_field0)); - dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n", - srate, stv0900_get_bits(i_params, sfr_field0), - stv0900_get_bits(i_params, sfr_field1), - stv0900_get_bits(i_params, sfr_field2), - stv0900_get_bits(i_params, sfr_field3)); - - intval1 = (mclk) >> 16; - intval2 = (srate) >> 16; - - rem1 = (mclk) % 0x10000; - rem2 = (srate) % 0x10000; - srate = (intval1 * intval2) + - ((intval1 * rem2) >> 16) + - ((intval2 * rem1) >> 16); - - return srate; -} - -static void stv0900_set_symbol_rate(struct stv0900_internal *i_params, - u32 mclk, u32 srate, - enum fe_stv0900_demod_num demod) -{ - s32 sfr_init_reg; - u32 symb; - - dprintk(KERN_INFO "%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk, - srate, demod); - - dmd_reg(sfr_init_reg, R0900_P1_SFRINIT1, R0900_P2_SFRINIT1); - - if (srate > 60000000) { - symb = srate << 4; - symb /= (mclk >> 12); - } else if (srate > 6000000) { - symb = srate << 6; - symb /= (mclk >> 10); - } else { - symb = srate << 9; - symb /= (mclk >> 7); - } - - stv0900_write_reg(i_params, sfr_init_reg, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, sfr_init_reg + 1, (symb & 0xFF)); -} - -static void stv0900_set_max_symbol_rate(struct stv0900_internal *i_params, - u32 mclk, u32 srate, - enum fe_stv0900_demod_num demod) -{ - s32 sfr_max_reg; - u32 symb; - - dmd_reg(sfr_max_reg, R0900_P1_SFRUP1, R0900_P2_SFRUP1); - - srate = 105 * (srate / 100); - - if (srate > 60000000) { - symb = srate << 4; - symb /= (mclk >> 12); - } else if (srate > 6000000) { - symb = srate << 6; - symb /= (mclk >> 10); - } else { - symb = srate << 9; - symb /= (mclk >> 7); - } - - if (symb < 0x7fff) { - stv0900_write_reg(i_params, sfr_max_reg, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, sfr_max_reg + 1, (symb & 0xFF)); - } else { - stv0900_write_reg(i_params, sfr_max_reg, 0x7F); - stv0900_write_reg(i_params, sfr_max_reg + 1, 0xFF); - } -} - -static void stv0900_set_min_symbol_rate(struct stv0900_internal *i_params, - u32 mclk, u32 srate, - enum fe_stv0900_demod_num demod) -{ - s32 sfr_min_reg; - u32 symb; - - dmd_reg(sfr_min_reg, R0900_P1_SFRLOW1, R0900_P2_SFRLOW1); - - srate = 95 * (srate / 100); - if (srate > 60000000) { - symb = srate << 4; - symb /= (mclk >> 12); - - } else if (srate > 6000000) { - symb = srate << 6; - symb /= (mclk >> 10); - - } else { - symb = srate << 9; - symb /= (mclk >> 7); - } - - stv0900_write_reg(i_params, sfr_min_reg, (symb >> 8) & 0xFF); - stv0900_write_reg(i_params, sfr_min_reg + 1, (symb & 0xFF)); -} - -static s32 stv0900_get_timing_offst(struct stv0900_internal *i_params, - u32 srate, - enum fe_stv0900_demod_num demod) -{ - s32 tmgreg, - timingoffset; - - dmd_reg(tmgreg, R0900_P1_TMGREG2, R0900_P2_TMGREG2); - - timingoffset = (stv0900_read_reg(i_params, tmgreg) << 16) + - (stv0900_read_reg(i_params, tmgreg + 1) << 8) + - (stv0900_read_reg(i_params, tmgreg + 2)); - - timingoffset = ge2comp(timingoffset, 24); - - - if (timingoffset == 0) - timingoffset = 1; - - timingoffset = ((s32)srate * 10) / ((s32)0x1000000 / timingoffset); - timingoffset /= 320; - - return timingoffset; -} - -static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - s32 rolloff, man_fld, matstr_reg, rolloff_ctl_fld; - - dmd_reg(man_fld, F0900_P1_MANUAL_ROLLOFF, F0900_P2_MANUAL_ROLLOFF); - dmd_reg(matstr_reg, R0900_P1_MATSTR1, R0900_P2_MATSTR1); - dmd_reg(rolloff_ctl_fld, F0900_P1_ROLLOFF_CONTROL, - F0900_P2_ROLLOFF_CONTROL); - - if (i_params->chip_id == 0x10) { - stv0900_write_bits(i_params, man_fld, 1); - rolloff = stv0900_read_reg(i_params, matstr_reg) & 0x03; - stv0900_write_bits(i_params, rolloff_ctl_fld, rolloff); - } else - stv0900_write_bits(i_params, man_fld, 0); -} - -static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro) -{ - u32 rolloff; - - switch (ro) { - case STV0900_20: - rolloff = 20; - break; - case STV0900_25: - rolloff = 25; - break; - case STV0900_35: - default: - rolloff = 35; - break; - } - - return srate + (srate * rolloff) / 100; -} - -static int stv0900_check_timing_lock(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - int timingLock = FALSE; - s32 i, - timingcpt = 0; - u8 carFreq, - tmgTHhigh, - tmgTHLow; - - switch (demod) { - case STV0900_DEMOD_1: - default: - carFreq = stv0900_read_reg(i_params, R0900_P1_CARFREQ); - tmgTHhigh = stv0900_read_reg(i_params, R0900_P1_TMGTHRISE); - tmgTHLow = stv0900_read_reg(i_params, R0900_P1_TMGTHFALL); - stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20); - stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x0); - stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); - stv0900_write_reg(i_params, R0900_P1_RTC, 0x80); - stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x40); - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x0); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0x0); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0x0); - stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x65); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); - msleep(7); - - for (i = 0; i < 10; i++) { - if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2) - timingcpt++; - - msleep(1); - } - - if (timingcpt >= 3) - timingLock = TRUE; - - stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); - stv0900_write_reg(i_params, R0900_P1_RTC, 0x88); - stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68); - stv0900_write_reg(i_params, R0900_P1_CARFREQ, carFreq); - stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, tmgTHhigh); - stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, tmgTHLow); - break; - case STV0900_DEMOD_2: - carFreq = stv0900_read_reg(i_params, R0900_P2_CARFREQ); - tmgTHhigh = stv0900_read_reg(i_params, R0900_P2_TMGTHRISE); - tmgTHLow = stv0900_read_reg(i_params, R0900_P2_TMGTHFALL); - stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20); - stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0); - stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); - stv0900_write_reg(i_params, R0900_P2_RTC, 0x80); - stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x40); - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x0); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0x0); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0x0); - stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x65); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); - msleep(5); - for (i = 0; i < 10; i++) { - if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2) - timingcpt++; - - msleep(1); - } - - if (timingcpt >= 3) - timingLock = TRUE; - - stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); - stv0900_write_reg(i_params, R0900_P2_RTC, 0x88); - stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68); - stv0900_write_reg(i_params, R0900_P2_CARFREQ, carFreq); - stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, tmgTHhigh); - stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, tmgTHLow); - break; - } - - return timingLock; -} - -static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe, - s32 demod_timeout) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - - int lock = FALSE; - s32 srate, search_range, locktimeout, - currier_step, nb_steps, current_step, - direction, tuner_freq, timeout; - - switch (demod) { - case STV0900_DEMOD_1: - default: - srate = i_params->dmd1_symbol_rate; - search_range = i_params->dmd1_srch_range; - break; - - case STV0900_DEMOD_2: - srate = i_params->dmd2_symbol_rate; - search_range = i_params->dmd2_srch_range; - break; - } - - if (srate >= 10000000) - locktimeout = demod_timeout / 3; - else - locktimeout = demod_timeout / 2; - - lock = stv0900_get_demod_lock(i_params, demod, locktimeout); - - if (lock == FALSE) { - if (srate >= 10000000) { - if (stv0900_check_timing_lock(i_params, demod) == TRUE) { - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); - break; - case STV0900_DEMOD_2: - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); - break; - } - - lock = stv0900_get_demod_lock(i_params, demod, demod_timeout); - } else - lock = FALSE; - } else { - if (srate <= 4000000) - currier_step = 1000; - else if (srate <= 7000000) - currier_step = 2000; - else if (srate <= 10000000) - currier_step = 3000; - else - currier_step = 5000; - - nb_steps = ((search_range / 1000) / currier_step); - nb_steps /= 2; - nb_steps = (2 * (nb_steps + 1)); - if (nb_steps < 0) - nb_steps = 2; - else if (nb_steps > 12) - nb_steps = 12; - - current_step = 1; - direction = 1; - timeout = (demod_timeout / 3); - if (timeout > 1000) - timeout = 1000; - - switch (demod) { - case STV0900_DEMOD_1: - default: - if (lock == FALSE) { - tuner_freq = i_params->tuner1_freq; - i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + i_params->dmd1_symbol_rate; - - while ((current_step <= nb_steps) && (lock == FALSE)) { - - if (direction > 0) - tuner_freq += (current_step * currier_step); - else - tuner_freq -= (current_step * currier_step); - - stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C); - if (i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS2) { - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); - } - - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); - lock = stv0900_get_demod_lock(i_params, demod, timeout); - direction *= -1; - current_step++; - } - } - break; - case STV0900_DEMOD_2: - if (lock == FALSE) { - tuner_freq = i_params->tuner2_freq; - i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + srate; - - while ((current_step <= nb_steps) && (lock == FALSE)) { - - if (direction > 0) - tuner_freq += (current_step * currier_step); - else - tuner_freq -= (current_step * currier_step); - - stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C); - if (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS2) { - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); - } - - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); - lock = stv0900_get_demod_lock(i_params, demod, timeout); - direction *= -1; - current_step++; - } - } - break; - } - } - } - - return lock; -} - -static void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout, - s32 srate, - enum fe_stv0900_search_algo algo) -{ - switch (algo) { - case STV0900_BLIND_SEARCH: - if (srate <= 1500000) { - (*demod_timeout) = 1500; - (*fec_timeout) = 400; - } else if (srate <= 5000000) { - (*demod_timeout) = 1000; - (*fec_timeout) = 300; - } else { - (*demod_timeout) = 700; - (*fec_timeout) = 100; - } - - break; - case STV0900_COLD_START: - case STV0900_WARM_START: - default: - if (srate <= 1000000) { - (*demod_timeout) = 3000; - (*fec_timeout) = 1700; - } else if (srate <= 2000000) { - (*demod_timeout) = 2500; - (*fec_timeout) = 1100; - } else if (srate <= 5000000) { - (*demod_timeout) = 1000; - (*fec_timeout) = 550; - } else if (srate <= 10000000) { - (*demod_timeout) = 700; - (*fec_timeout) = 250; - } else if (srate <= 20000000) { - (*demod_timeout) = 400; - (*fec_timeout) = 130; - } - - else { - (*demod_timeout) = 300; - (*fec_timeout) = 100; - } - - break; - - } - - if (algo == STV0900_WARM_START) - (*demod_timeout) /= 2; -} - -static void stv0900_set_viterbi_tracq(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - - s32 vth_reg; - - dprintk(KERN_INFO "%s\n", __func__); - - dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12); - - stv0900_write_reg(i_params, vth_reg++, 0xd0); - stv0900_write_reg(i_params, vth_reg++, 0x7d); - stv0900_write_reg(i_params, vth_reg++, 0x53); - stv0900_write_reg(i_params, vth_reg++, 0x2F); - stv0900_write_reg(i_params, vth_reg++, 0x24); - stv0900_write_reg(i_params, vth_reg++, 0x1F); -} - -static void stv0900_set_viterbi_standard(struct stv0900_internal *i_params, - enum fe_stv0900_search_standard Standard, - enum fe_stv0900_fec PunctureRate, - enum fe_stv0900_demod_num demod) -{ - - s32 fecmReg, - prvitReg; - - dprintk(KERN_INFO "%s: ViterbiStandard = ", __func__); - - switch (demod) { - case STV0900_DEMOD_1: - default: - fecmReg = R0900_P1_FECM; - prvitReg = R0900_P1_PRVIT; - break; - case STV0900_DEMOD_2: - fecmReg = R0900_P2_FECM; - prvitReg = R0900_P2_PRVIT; - break; - } - - switch (Standard) { - case STV0900_AUTO_SEARCH: - dprintk("Auto\n"); - stv0900_write_reg(i_params, fecmReg, 0x10); - stv0900_write_reg(i_params, prvitReg, 0x3F); - break; - case STV0900_SEARCH_DVBS1: - dprintk("DVBS1\n"); - stv0900_write_reg(i_params, fecmReg, 0x00); - switch (PunctureRate) { - case STV0900_FEC_UNKNOWN: - default: - stv0900_write_reg(i_params, prvitReg, 0x2F); - break; - case STV0900_FEC_1_2: - stv0900_write_reg(i_params, prvitReg, 0x01); - break; - case STV0900_FEC_2_3: - stv0900_write_reg(i_params, prvitReg, 0x02); - break; - case STV0900_FEC_3_4: - stv0900_write_reg(i_params, prvitReg, 0x04); - break; - case STV0900_FEC_5_6: - stv0900_write_reg(i_params, prvitReg, 0x08); - break; - case STV0900_FEC_7_8: - stv0900_write_reg(i_params, prvitReg, 0x20); - break; - } - - break; - case STV0900_SEARCH_DSS: - dprintk("DSS\n"); - stv0900_write_reg(i_params, fecmReg, 0x80); - switch (PunctureRate) { - case STV0900_FEC_UNKNOWN: - default: - stv0900_write_reg(i_params, prvitReg, 0x13); - break; - case STV0900_FEC_1_2: - stv0900_write_reg(i_params, prvitReg, 0x01); - break; - case STV0900_FEC_2_3: - stv0900_write_reg(i_params, prvitReg, 0x02); - break; - case STV0900_FEC_6_7: - stv0900_write_reg(i_params, prvitReg, 0x10); - break; - } - break; - default: - break; - } -} - -static void stv0900_track_optimization(struct dvb_frontend *fe) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - - s32 srate, pilots, aclc, freq1, freq0, - i = 0, timed, timef, blindTunSw = 0; - - enum fe_stv0900_rolloff rolloff; - enum fe_stv0900_modcode foundModcod; - - dprintk(KERN_INFO "%s\n", __func__); - - srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - srate += stv0900_get_timing_offst(i_params, srate, demod); - - switch (demod) { - case STV0900_DEMOD_1: - default: - switch (i_params->dmd1_rslts.standard) { - case STV0900_DVBS1_STANDARD: - if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) { - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); - } - - stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff); - stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1); - stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75); - break; - case STV0900_DSS_STANDARD: - if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) { - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); - } - - stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff); - stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1); - stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75); - break; - case STV0900_DVBS2_STANDARD: - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); - stv0900_write_reg(i_params, R0900_P1_ACLC, 0); - stv0900_write_reg(i_params, R0900_P1_BCLC, 0); - if (i_params->dmd1_rslts.frame_length == STV0900_LONG_FRAME) { - foundModcod = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD); - pilots = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01; - aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id); - if (foundModcod <= STV0900_QPSK_910) - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc); - else if (foundModcod <= STV0900_8PSK_910) { - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc); - } - - if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) { - if (foundModcod <= STV0900_16APSK_910) { - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc); - } else if (foundModcod <= STV0900_32APSK_910) { - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc); - } - } - - } else { - aclc = stv0900_get_optim_short_carr_loop(srate, i_params->dmd1_rslts.modulation, i_params->chip_id); - if (i_params->dmd1_rslts.modulation == STV0900_QPSK) - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc); - - else if (i_params->dmd1_rslts.modulation == STV0900_8PSK) { - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc); - } else if (i_params->dmd1_rslts.modulation == STV0900_16APSK) { - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc); - } else if (i_params->dmd1_rslts.modulation == STV0900_32APSK) { - stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc); - } - - } - - if (i_params->chip_id <= 0x11) { - if (i_params->demod_mode != STV0900_SINGLE) - stv0900_activate_s2_modcode(i_params, demod); - - } - - stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67); - break; - case STV0900_UNKNOWN_STANDARD: - default: - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); - break; - } - - freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2); - freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1); - rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS); - if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) { - stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00); - stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); - stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01); - stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); - stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod); - stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod); - blindTunSw = 1; - } - - if (i_params->chip_id >= 0x20) { - if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) { - stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0a); - stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x0); - } - } - - if (i_params->chip_id < 0x20) - stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x08); - - if (i_params->chip_id == 0x10) - stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0x0A); - - stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); - - if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd1_symbol_rate < 10000000)) { - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); - i_params->tuner1_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000; - - if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) { - if (i_params->dmd1_srch_algo != STV0900_WARM_START) - stv0900_set_bandwidth(fe, i_params->tuner1_bw); - } - - if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) - msleep(50); - else - msleep(5); - - stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START); - - if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) { - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); - i = 0; - while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) { - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); - i++; - } - } - - } - - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49); - - if ((i_params->dmd1_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd1_rslts.standard == STV0900_DSS_STANDARD)) - stv0900_set_viterbi_tracq(i_params, demod); - - break; - - case STV0900_DEMOD_2: - switch (i_params->dmd2_rslts.standard) { - case STV0900_DVBS1_STANDARD: - - if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) { - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); - } - - stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff); - stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1); - stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75); - break; - case STV0900_DSS_STANDARD: - if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) { - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); - } - - stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff); - stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1); - stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75); - break; - case STV0900_DVBS2_STANDARD: - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); - stv0900_write_reg(i_params, R0900_P2_ACLC, 0); - stv0900_write_reg(i_params, R0900_P2_BCLC, 0); - if (i_params->dmd2_rslts.frame_length == STV0900_LONG_FRAME) { - foundModcod = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD); - pilots = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01; - aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id); - if (foundModcod <= STV0900_QPSK_910) - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc); - else if (foundModcod <= STV0900_8PSK_910) { - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc); - } - - if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) { - if (foundModcod <= STV0900_16APSK_910) { - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc); - } else if (foundModcod <= STV0900_32APSK_910) { - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc); - } - - } - - } else { - aclc = stv0900_get_optim_short_carr_loop(srate, - i_params->dmd2_rslts.modulation, - i_params->chip_id); - - if (i_params->dmd2_rslts.modulation == STV0900_QPSK) - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc); - - else if (i_params->dmd2_rslts.modulation == STV0900_8PSK) { - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc); - } else if (i_params->dmd2_rslts.modulation == STV0900_16APSK) { - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc); - } else if (i_params->dmd2_rslts.modulation == STV0900_32APSK) { - stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); - stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc); - } - } - - stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67); - - break; - case STV0900_UNKNOWN_STANDARD: - default: - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); - break; - } - - freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2); - freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1); - rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS); - if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { - stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00); - stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); - stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01); - stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); - stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod); - stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod); - blindTunSw = 1; - } - - if (i_params->chip_id >= 0x20) { - if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) { - stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0a); - stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x0); - } - } - - if (i_params->chip_id < 0x20) - stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x08); - - if (i_params->chip_id == 0x10) - stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0x0a); - - stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); - if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd2_symbol_rate < 10000000)) { - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); - i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000; - - if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) { - if (i_params->dmd2_srch_algo != STV0900_WARM_START) - stv0900_set_bandwidth(fe, i_params->tuner2_bw); - } - - if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) - msleep(50); - else - msleep(5); - - stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START); - if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) { - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); - i = 0; - while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) { - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); - i++; - } - } - } - - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49); - - if ((i_params->dmd2_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd2_rslts.standard == STV0900_DSS_STANDARD)) - stv0900_set_viterbi_tracq(i_params, demod); - - break; - } -} - -static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv0900_demod_num demod, s32 time_out) -{ - s32 timer = 0, lock = 0, header_field, pktdelin_field, lock_vit_field; - - enum fe_stv0900_search_state dmd_state; - - dprintk(KERN_INFO "%s\n", __func__); - - dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); - dmd_reg(pktdelin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK); - dmd_reg(lock_vit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT); - - dmd_state = stv0900_get_bits(i_params, header_field); - - while ((timer < time_out) && (lock == 0)) { - switch (dmd_state) { - case STV0900_SEARCH: - case STV0900_PLH_DETECTED: - default: - lock = 0; - break; - case STV0900_DVBS2_FOUND: - lock = stv0900_get_bits(i_params, pktdelin_field); - break; - case STV0900_DVBS_FOUND: - lock = stv0900_get_bits(i_params, lock_vit_field); - break; - } - - if (lock == 0) { - msleep(10); - timer += 10; - } - } - - if (lock) - dprintk("DEMOD FEC LOCK OK\n"); - else - dprintk("DEMOD FEC LOCK FAIL\n"); - - return lock; -} - -static int stv0900_wait_for_lock(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod, - s32 dmd_timeout, s32 fec_timeout) -{ - - s32 timer = 0, lock = 0, str_merg_rst_fld, str_merg_lock_fld; - - dprintk(KERN_INFO "%s\n", __func__); - - dmd_reg(str_merg_rst_fld, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE); - dmd_reg(str_merg_lock_fld, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK); - - lock = stv0900_get_demod_lock(i_params, demod, dmd_timeout); - - if (lock) - lock = lock && stv0900_get_fec_lock(i_params, demod, fec_timeout); - - if (lock) { - lock = 0; - - dprintk(KERN_INFO "%s: Timer = %d, time_out = %d\n", __func__, timer, fec_timeout); - - while ((timer < fec_timeout) && (lock == 0)) { - lock = stv0900_get_bits(i_params, str_merg_lock_fld); - msleep(1); - timer++; - } - } - - if (lock) - dprintk(KERN_INFO "%s: DEMOD LOCK OK\n", __func__); - else - dprintk(KERN_INFO "%s: DEMOD LOCK FAIL\n", __func__); - - if (lock) - return TRUE; - else - return FALSE; -} - -enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe, - enum fe_stv0900_demod_num demod) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_tracking_standard fnd_standard; - s32 state_field, - dss_dvb_field; - - dprintk(KERN_INFO "%s\n", __func__); - - dmd_reg(state_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); - dmd_reg(dss_dvb_field, F0900_P1_DSS_DVB, F0900_P2_DSS_DVB); - - if (stv0900_get_bits(i_params, state_field) == 2) - fnd_standard = STV0900_DVBS2_STANDARD; - - else if (stv0900_get_bits(i_params, state_field) == 3) { - if (stv0900_get_bits(i_params, dss_dvb_field) == 1) - fnd_standard = STV0900_DSS_STANDARD; - else - fnd_standard = STV0900_DVBS1_STANDARD; - } else - fnd_standard = STV0900_UNKNOWN_STANDARD; - - return fnd_standard; -} - -static s32 stv0900_get_carr_freq(struct stv0900_internal *i_params, u32 mclk, - enum fe_stv0900_demod_num demod) -{ - s32 cfr_field2, cfr_field1, cfr_field0, - derot, rem1, rem2, intval1, intval2; - - dmd_reg(cfr_field2, F0900_P1_CAR_FREQ2, F0900_P2_CAR_FREQ2); - dmd_reg(cfr_field1, F0900_P1_CAR_FREQ1, F0900_P2_CAR_FREQ1); - dmd_reg(cfr_field0, F0900_P1_CAR_FREQ0, F0900_P2_CAR_FREQ0); - - derot = (stv0900_get_bits(i_params, cfr_field2) << 16) + - (stv0900_get_bits(i_params, cfr_field1) << 8) + - (stv0900_get_bits(i_params, cfr_field0)); - - derot = ge2comp(derot, 24); - intval1 = mclk >> 12; - intval2 = derot >> 12; - rem1 = mclk % 0x1000; - rem2 = derot % 0x1000; - derot = (intval1 * intval2) + - ((intval1 * rem2) >> 12) + - ((intval2 * rem1) >> 12); - - return derot; -} - -static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe) -{ - struct dvb_frontend_ops *frontend_ops = NULL; - struct dvb_tuner_ops *tuner_ops = NULL; - u32 frequency = 0; - - if (&fe->ops) - frontend_ops = &fe->ops; - - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - - if (tuner_ops->get_frequency) { - if ((tuner_ops->get_frequency(fe, &frequency)) < 0) - dprintk("%s: Invalid parameter\n", __func__); - else - dprintk("%s: Frequency=%d\n", __func__, frequency); - - } - - return frequency; -} - -static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - s32 rate_fld, vit_curpun_fld; - enum fe_stv0900_fec prate; - - dmd_reg(vit_curpun_fld, F0900_P1_VIT_CURPUN, F0900_P2_VIT_CURPUN); - rate_fld = stv0900_get_bits(i_params, vit_curpun_fld); - - switch (rate_fld) { - case 13: - prate = STV0900_FEC_1_2; - break; - case 18: - prate = STV0900_FEC_2_3; - break; - case 21: - prate = STV0900_FEC_3_4; - break; - case 24: - prate = STV0900_FEC_5_6; - break; - case 25: - prate = STV0900_FEC_6_7; - break; - case 26: - prate = STV0900_FEC_7_8; - break; - default: - prate = STV0900_FEC_UNKNOWN; - break; - } - - return prate; -} - -static enum fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE; - s32 offsetFreq, - srate_offset, - i = 0; - - u8 timing; - - msleep(5); - switch (demod) { - case STV0900_DEMOD_1: - default: - if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) { - timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2); - i = 0; - stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x5c); - - while ((i <= 50) && (timing != 0) && (timing != 0xFF)) { - timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2); - msleep(5); - i += 5; - } - } - - i_params->dmd1_rslts.standard = stv0900_get_standard(fe, demod); - i_params->dmd1_rslts.frequency = stv0900_get_tuner_freq(fe); - offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000; - i_params->dmd1_rslts.frequency += offsetFreq; - i_params->dmd1_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd1_rslts.symbol_rate, demod); - i_params->dmd1_rslts.symbol_rate += srate_offset; - i_params->dmd1_rslts.fec = stv0900_get_vit_fec(i_params, demod); - i_params->dmd1_rslts.modcode = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD); - i_params->dmd1_rslts.pilot = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01; - i_params->dmd1_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE)) >> 1; - i_params->dmd1_rslts.rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS); - switch (i_params->dmd1_rslts.standard) { - case STV0900_DVBS2_STANDARD: - i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_SPECINV_DEMOD); - if (i_params->dmd1_rslts.modcode <= STV0900_QPSK_910) - i_params->dmd1_rslts.modulation = STV0900_QPSK; - else if (i_params->dmd1_rslts.modcode <= STV0900_8PSK_910) - i_params->dmd1_rslts.modulation = STV0900_8PSK; - else if (i_params->dmd1_rslts.modcode <= STV0900_16APSK_910) - i_params->dmd1_rslts.modulation = STV0900_16APSK; - else if (i_params->dmd1_rslts.modcode <= STV0900_32APSK_910) - i_params->dmd1_rslts.modulation = STV0900_32APSK; - else - i_params->dmd1_rslts.modulation = STV0900_UNKNOWN; - break; - case STV0900_DVBS1_STANDARD: - case STV0900_DSS_STANDARD: - i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_IQINV); - i_params->dmd1_rslts.modulation = STV0900_QPSK; - break; - default: - break; - } - - if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) { - offsetFreq = i_params->dmd1_rslts.frequency - i_params->tuner1_freq; - i_params->tuner1_freq = stv0900_get_tuner_freq(fe); - if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500)) - range = STV0900_RANGEOK; - else - if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd1_rslts.symbol_rate, i_params->dmd1_rslts.rolloff) / 2000)) - range = STV0900_RANGEOK; - else - range = STV0900_OUTOFRANGE; - - } else { - if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500)) - range = STV0900_RANGEOK; - else - range = STV0900_OUTOFRANGE; - } - break; - case STV0900_DEMOD_2: - if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { - timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2); - i = 0; - stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x5c); - - while ((i <= 50) && (timing != 0) && (timing != 0xff)) { - timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2); - msleep(5); - i += 5; - } - } - - i_params->dmd2_rslts.standard = stv0900_get_standard(fe, demod); - i_params->dmd2_rslts.frequency = stv0900_get_tuner_freq(fe); - offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000; - i_params->dmd2_rslts.frequency += offsetFreq; - i_params->dmd2_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd2_rslts.symbol_rate, demod); - i_params->dmd2_rslts.symbol_rate += srate_offset; - i_params->dmd2_rslts.fec = stv0900_get_vit_fec(i_params, demod); - i_params->dmd2_rslts.modcode = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD); - i_params->dmd2_rslts.pilot = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01; - i_params->dmd2_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE)) >> 1; - i_params->dmd2_rslts.rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS); - switch (i_params->dmd2_rslts.standard) { - case STV0900_DVBS2_STANDARD: - i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_SPECINV_DEMOD); - if (i_params->dmd2_rslts.modcode <= STV0900_QPSK_910) - i_params->dmd2_rslts.modulation = STV0900_QPSK; - else if (i_params->dmd2_rslts.modcode <= STV0900_8PSK_910) - i_params->dmd2_rslts.modulation = STV0900_8PSK; - else if (i_params->dmd2_rslts.modcode <= STV0900_16APSK_910) - i_params->dmd2_rslts.modulation = STV0900_16APSK; - else if (i_params->dmd2_rslts.modcode <= STV0900_32APSK_910) - i_params->dmd2_rslts.modulation = STV0900_32APSK; - else - i_params->dmd2_rslts.modulation = STV0900_UNKNOWN; - break; - case STV0900_DVBS1_STANDARD: - case STV0900_DSS_STANDARD: - i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_IQINV); - i_params->dmd2_rslts.modulation = STV0900_QPSK; - break; - default: - break; - } - - if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) { - offsetFreq = i_params->dmd2_rslts.frequency - i_params->tuner2_freq; - i_params->tuner2_freq = stv0900_get_tuner_freq(fe); - - if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500)) - range = STV0900_RANGEOK; - else - if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd2_rslts.symbol_rate, i_params->dmd2_rslts.rolloff) / 2000)) - range = STV0900_RANGEOK; - else - range = STV0900_OUTOFRANGE; - } else { - if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500)) - range = STV0900_RANGEOK; - else - range = STV0900_OUTOFRANGE; - } - - break; - } - - return range; -} - -static enum fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - - s32 srate, demod_timeout, - fec_timeout, freq1, freq0; - enum fe_stv0900_signal_type signal_type = STV0900_NODATA;; - - switch (demod) { - case STV0900_DEMOD_1: - default: - i_params->dmd1_rslts.locked = FALSE; - if (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) { - srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - srate += stv0900_get_timing_offst(i_params, srate, demod); - if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) - stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); - - stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START); - freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2); - freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1); - stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); - stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); - if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { - i_params->dmd1_rslts.locked = TRUE; - signal_type = stv0900_get_signal_params(fe); - stv0900_track_optimization(fe); - } else { - stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1c); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); - if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { - i_params->dmd1_rslts.locked = TRUE; - signal_type = stv0900_get_signal_params(fe); - stv0900_track_optimization(fe); - } - - } - - } else - i_params->dmd1_rslts.locked = FALSE; - - break; - case STV0900_DEMOD_2: - i_params->dmd2_rslts.locked = FALSE; - if (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) { - srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - srate += stv0900_get_timing_offst(i_params, srate, demod); - - if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) - stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); - - stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START); - freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2); - freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1); - stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); - stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); - - if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { - i_params->dmd2_rslts.locked = TRUE; - signal_type = stv0900_get_signal_params(fe); - stv0900_track_optimization(fe); - } else { - stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1c); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); - - if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { - i_params->dmd2_rslts.locked = TRUE; - signal_type = stv0900_get_signal_params(fe); - stv0900_track_optimization(fe); - } - - } - - } else - i_params->dmd1_rslts.locked = FALSE; - - break; - } - - return signal_type; -} - -static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - u32 minagc2level = 0xffff, - agc2level, - init_freq, freq_step; - - s32 i, j, nb_steps, direction; - - dprintk(KERN_INFO "%s\n", __func__); - - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); - stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1); - - stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83); - stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0); - - stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82); - stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0); - stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0); - - stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); - nb_steps = -1 + (i_params->dmd1_srch_range / 1000000); - nb_steps /= 2; - nb_steps = (2 * nb_steps) + 1; - - if (nb_steps < 0) - nb_steps = 1; - - direction = 1; - - freq_step = (1000000 << 8) / (i_params->mclk >> 8); - - init_freq = 0; - - for (i = 0; i < nb_steps; i++) { - if (direction > 0) - init_freq = init_freq + (freq_step * i); - else - init_freq = init_freq - (freq_step * i); - - direction *= -1; - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (init_freq >> 8) & 0xff); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, init_freq & 0xff); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x58); - msleep(10); - agc2level = 0; - - for (j = 0; j < 10; j++) - agc2level += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) - | stv0900_read_reg(i_params, R0900_P1_AGC2I0); - - agc2level /= 10; - - if (agc2level < minagc2level) - minagc2level = agc2level; - } - break; - case STV0900_DEMOD_2: - stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); - stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1); - stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83); - stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0); - stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82); - stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0); - stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0); - stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); - nb_steps = -1 + (i_params->dmd2_srch_range / 1000000); - nb_steps /= 2; - nb_steps = (2 * nb_steps) + 1; - - if (nb_steps < 0) - nb_steps = 1; - - direction = 1; - freq_step = (1000000 << 8) / (i_params->mclk >> 8); - init_freq = 0; - for (i = 0; i < nb_steps; i++) { - if (direction > 0) - init_freq = init_freq + (freq_step * i); - else - init_freq = init_freq - (freq_step * i); - - direction *= -1; - - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (init_freq >> 8) & 0xff); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, init_freq & 0xff); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x58); - - msleep(10); - agc2level = 0; - for (j = 0; j < 10; j++) - agc2level += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) - | stv0900_read_reg(i_params, R0900_P2_AGC2I0); - - agc2level /= 10; - - if (agc2level < minagc2level) - minagc2level = agc2level; - } - break; - } - - return (u16)minagc2level; -} - -static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - int timingLock = FALSE; - s32 i, timingcpt = 0, - direction = 1, - nb_steps, - current_step = 0, - tuner_freq; - - u32 coarse_srate = 0, agc2_integr = 0, currier_step = 1200; - - switch (demod) { - case STV0900_DEMOD_1: - default: - stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1F); - stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0x12); - stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xf0); - stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xe0); - stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1); - stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83); - stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0); - stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82); - stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0); - stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0); - stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x50); - - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x6a); - stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x95); - } else { - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed); - stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x73); - } - - if (i_params->dmd1_symbol_rate <= 2000000) - currier_step = 1000; - else if (i_params->dmd1_symbol_rate <= 5000000) - currier_step = 2000; - else if (i_params->dmd1_symbol_rate <= 12000000) - currier_step = 3000; - else - currier_step = 5000; - - nb_steps = -1 + ((i_params->dmd1_srch_range / 1000) / currier_step); - nb_steps /= 2; - nb_steps = (2 * nb_steps) + 1; - - if (nb_steps < 0) - nb_steps = 1; - - else if (nb_steps > 10) { - nb_steps = 11; - currier_step = (i_params->dmd1_srch_range / 1000) / 10; - } - - current_step = 0; - - direction = 1; - tuner_freq = i_params->tuner1_freq; - - while ((timingLock == FALSE) && (current_step < nb_steps)) { - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5F); - stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x0); - - msleep(50); - - for (i = 0; i < 10; i++) { - if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2) - timingcpt++; - - agc2_integr += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) | stv0900_read_reg(i_params, R0900_P1_AGC2I0); - - } - - agc2_integr /= 10; - coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - current_step++; - direction *= -1; - - dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started. tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n", tuner_freq, agc2_integr, coarse_srate, timingcpt); - - if ((timingcpt >= 5) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000)) { - timingLock = TRUE; - } - - else if (current_step < nb_steps) { - if (direction > 0) - tuner_freq += (current_step * currier_step); - else - tuner_freq -= (current_step * currier_step); - - stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw); - } - } - - if (timingLock == FALSE) - coarse_srate = 0; - else - coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - break; - case STV0900_DEMOD_2: - stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1F); - stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0x12); - stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xf0); - stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xe0); - stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1); - stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83); - stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0); - stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82); - stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0); - stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0); - stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x50); - - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x6a); - stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x95); - } else { - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed); - stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x73); - } - - if (i_params->dmd2_symbol_rate <= 2000000) - currier_step = 1000; - else if (i_params->dmd2_symbol_rate <= 5000000) - currier_step = 2000; - else if (i_params->dmd2_symbol_rate <= 12000000) - currier_step = 3000; - else - currier_step = 5000; - - - nb_steps = -1 + ((i_params->dmd2_srch_range / 1000) / currier_step); - nb_steps /= 2; - nb_steps = (2 * nb_steps) + 1; - - if (nb_steps < 0) - nb_steps = 1; - else if (nb_steps > 10) { - nb_steps = 11; - currier_step = (i_params->dmd2_srch_range / 1000) / 10; - } - - current_step = 0; - direction = 1; - tuner_freq = i_params->tuner2_freq; - - while ((timingLock == FALSE) && (current_step < nb_steps)) { - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5F); - stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x0); - - msleep(50); - timingcpt = 0; - - for (i = 0; i < 20; i++) { - if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2) - timingcpt++; - agc2_integr += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) - | stv0900_read_reg(i_params, R0900_P2_AGC2I0); - } - - agc2_integr /= 20; - coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - if ((timingcpt >= 10) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000)) - timingLock = TRUE; - else { - current_step++; - direction *= -1; - - if (direction > 0) - tuner_freq += (current_step * currier_step); - else - tuner_freq -= (current_step * currier_step); - - stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw); - } - } - - if (timingLock == FALSE) - coarse_srate = 0; - else - coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - break; - } - - return coarse_srate; -} - -static u32 stv0900_search_srate_fine(struct dvb_frontend *fe) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - u32 coarse_srate, - coarse_freq, - symb; - - coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); - - switch (demod) { - case STV0900_DEMOD_1: - default: - coarse_freq = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8) - | stv0900_read_reg(i_params, R0900_P1_CFR1); - symb = 13 * (coarse_srate / 10); - - if (symb < i_params->dmd1_symbol_rate) - coarse_srate = 0; - else { - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01); - stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20); - stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x00); - stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2); - stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); - - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49); - else - stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed); - - if (coarse_srate > 3000000) { - symb = 13 * (coarse_srate / 10); - symb = (symb / 1000) * 65536; - symb /= (i_params->mclk / 1000); - stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF)); - - symb = 10 * (coarse_srate / 13); - symb = (symb / 1000) * 65536; - symb /= (i_params->mclk / 1000); - - stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF)); - - symb = (coarse_srate / 1000) * 65536; - symb /= (i_params->mclk / 1000); - stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF); - stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF)); - } else { - symb = 13 * (coarse_srate / 10); - symb = (symb / 100) * 65536; - symb /= (i_params->mclk / 100); - stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF)); - - symb = 10 * (coarse_srate / 14); - symb = (symb / 100) * 65536; - symb /= (i_params->mclk / 100); - stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF)); - - symb = (coarse_srate / 100) * 65536; - symb /= (i_params->mclk / 100); - stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF); - stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF)); - } - - stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20); - stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (coarse_freq >> 8) & 0xff); - stv0900_write_reg(i_params, R0900_P1_CFRINIT0, coarse_freq & 0xff); - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); - } - break; - case STV0900_DEMOD_2: - coarse_freq = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8) - | stv0900_read_reg(i_params, R0900_P2_CFR1); - - symb = 13 * (coarse_srate / 10); - - if (symb < i_params->dmd2_symbol_rate) - coarse_srate = 0; - else { - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); - stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01); - stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20); - stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0x00); - stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2); - stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); - - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49); - else - stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed); - - if (coarse_srate > 3000000) { - symb = 13 * (coarse_srate / 10); - symb = (symb / 1000) * 65536; - symb /= (i_params->mclk / 1000); - stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF)); - - symb = 10 * (coarse_srate / 13); - symb = (symb / 1000) * 65536; - symb /= (i_params->mclk / 1000); - - stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF)); - - symb = (coarse_srate / 1000) * 65536; - symb /= (i_params->mclk / 1000); - stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF); - stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF)); - } else { - symb = 13 * (coarse_srate / 10); - symb = (symb / 100) * 65536; - symb /= (i_params->mclk / 100); - stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF)); - - symb = 10 * (coarse_srate / 14); - symb = (symb / 100) * 65536; - symb /= (i_params->mclk / 100); - stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F); - stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF)); - - symb = (coarse_srate / 100) * 65536; - symb /= (i_params->mclk / 100); - stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF); - stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF)); - } - - stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20); - stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (coarse_freq >> 8) & 0xff); - stv0900_write_reg(i_params, R0900_P2_CFRINIT0, coarse_freq & 0xff); - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); - } - - break; - } - - return coarse_srate; -} - -static int stv0900_blind_search_algo(struct dvb_frontend *fe) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - u8 k_ref_tmg, k_ref_tmg_max, k_ref_tmg_min; - u32 coarse_srate; - int lock = FALSE, coarse_fail = FALSE; - s32 demod_timeout = 500, fec_timeout = 50, kref_tmg_reg, fail_cpt, i, agc2_overflow; - u16 agc2_integr; - u8 dstatus2; - - dprintk(KERN_INFO "%s\n", __func__); - - if (i_params->chip_id < 0x20) { - k_ref_tmg_max = 233; - k_ref_tmg_min = 143; - } else { - k_ref_tmg_max = 120; - k_ref_tmg_min = 30; - } - - agc2_integr = stv0900_blind_check_agc2_min_level(i_params, demod); - - if (agc2_integr > STV0900_BLIND_SEARCH_AGC2_TH) { - lock = FALSE; - - } else { - switch (demod) { - case STV0900_DEMOD_1: - default: - if (i_params->chip_id == 0x10) - stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xAA); - - if (i_params->chip_id < 0x20) - stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55); - - stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xC4); - stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44); - - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41); - stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41); - stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82); - stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0); - } - - kref_tmg_reg = R0900_P1_KREFTMG; - break; - case STV0900_DEMOD_2: - if (i_params->chip_id == 0x10) - stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xAA); - - if (i_params->chip_id < 0x20) - stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55); - - stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xC4); - stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44); - - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41); - stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41); - stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82); - stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0); - } - - kref_tmg_reg = R0900_P2_KREFTMG; - break; - } - - k_ref_tmg = k_ref_tmg_max; - - do { - stv0900_write_reg(i_params, kref_tmg_reg, k_ref_tmg); - if (stv0900_search_srate_coarse(fe) != 0) { - coarse_srate = stv0900_search_srate_fine(fe); - - if (coarse_srate != 0) { - stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, coarse_srate, STV0900_BLIND_SEARCH); - lock = stv0900_get_demod_lock(i_params, demod, demod_timeout); - } else - lock = FALSE; - } else { - fail_cpt = 0; - agc2_overflow = 0; - - switch (demod) { - case STV0900_DEMOD_1: - default: - for (i = 0; i < 10; i++) { - agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) - | stv0900_read_reg(i_params, R0900_P1_AGC2I0); - - if (agc2_integr >= 0xff00) - agc2_overflow++; - - dstatus2 = stv0900_read_reg(i_params, R0900_P1_DSTATUS2); - - if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1)) - fail_cpt++; - } - break; - case STV0900_DEMOD_2: - for (i = 0; i < 10; i++) { - agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) - | stv0900_read_reg(i_params, R0900_P2_AGC2I0); - - if (agc2_integr >= 0xff00) - agc2_overflow++; - - dstatus2 = stv0900_read_reg(i_params, R0900_P2_DSTATUS2); - - if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1)) - fail_cpt++; - } - break; - } - - if ((fail_cpt > 7) || (agc2_overflow > 7)) - coarse_fail = TRUE; - - lock = FALSE; - } - k_ref_tmg -= 30; - } while ((k_ref_tmg >= k_ref_tmg_min) && (lock == FALSE) && (coarse_fail == FALSE)); - } - - return lock; -} - -static void stv0900_set_viterbi_acq(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - s32 vth_reg; - - dprintk(KERN_INFO "%s\n", __func__); - - dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12); - - stv0900_write_reg(i_params, vth_reg++, 0x96); - stv0900_write_reg(i_params, vth_reg++, 0x64); - stv0900_write_reg(i_params, vth_reg++, 0x36); - stv0900_write_reg(i_params, vth_reg++, 0x23); - stv0900_write_reg(i_params, vth_reg++, 0x1E); - stv0900_write_reg(i_params, vth_reg++, 0x19); -} - -static void stv0900_set_search_standard(struct stv0900_internal *i_params, - enum fe_stv0900_demod_num demod) -{ - - int sstndrd; - - dprintk(KERN_INFO "%s\n", __func__); - - sstndrd = i_params->dmd1_srch_standard; - if (demod == 1) - sstndrd = i_params->dmd2_srch_stndrd; - - switch (sstndrd) { - case STV0900_SEARCH_DVBS1: - dprintk("Search Standard = DVBS1\n"); - break; - case STV0900_SEARCH_DSS: - dprintk("Search Standard = DSS\n"); - case STV0900_SEARCH_DVBS2: - break; - dprintk("Search Standard = DVBS2\n"); - case STV0900_AUTO_SEARCH: - default: - dprintk("Search Standard = AUTO\n"); - break; - } - - switch (demod) { - case STV0900_DEMOD_1: - default: - switch (i_params->dmd1_srch_standard) { - case STV0900_SEARCH_DVBS1: - case STV0900_SEARCH_DSS: - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); - - stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0); - stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a); - stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09); - stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x22); - - stv0900_set_viterbi_acq(i_params, demod); - stv0900_set_viterbi_standard(i_params, - i_params->dmd1_srch_standard, - i_params->dmd1_fec, demod); - - break; - case STV0900_SEARCH_DVBS2: - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); - stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 1); - stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a); - stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09); - stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26); - if (i_params->demod_mode != STV0900_SINGLE) { - if (i_params->chip_id <= 0x11) - stv0900_stop_all_s2_modcod(i_params, demod); - else - stv0900_activate_s2_modcode(i_params, demod); - - } else - stv0900_activate_s2_modcode_single(i_params, demod); - - stv0900_set_viterbi_tracq(i_params, demod); - - break; - case STV0900_AUTO_SEARCH: - default: - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); - stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0); - stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a); - stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09); - stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26); - if (i_params->demod_mode != STV0900_SINGLE) { - if (i_params->chip_id <= 0x11) - stv0900_stop_all_s2_modcod(i_params, demod); - else - stv0900_activate_s2_modcode(i_params, demod); - - } else - stv0900_activate_s2_modcode_single(i_params, demod); - - if (i_params->dmd1_symbol_rate >= 2000000) - stv0900_set_viterbi_acq(i_params, demod); - else - stv0900_set_viterbi_tracq(i_params, demod); - - stv0900_set_viterbi_standard(i_params, i_params->dmd1_srch_standard, i_params->dmd1_fec, demod); - - break; - } - break; - case STV0900_DEMOD_2: - switch (i_params->dmd2_srch_stndrd) { - case STV0900_SEARCH_DVBS1: - case STV0900_SEARCH_DSS: - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); - stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0); - stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a); - stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09); - stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x22); - stv0900_set_viterbi_acq(i_params, demod); - stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod); - break; - case STV0900_SEARCH_DVBS2: - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); - stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 1); - stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a); - stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09); - stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26); - if (i_params->demod_mode != STV0900_SINGLE) - stv0900_activate_s2_modcode(i_params, demod); - else - stv0900_activate_s2_modcode_single(i_params, demod); - - stv0900_set_viterbi_tracq(i_params, demod); - break; - case STV0900_AUTO_SEARCH: - default: - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); - stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); - stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); - stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0); - stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a); - stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09); - stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26); - if (i_params->demod_mode != STV0900_SINGLE) - stv0900_activate_s2_modcode(i_params, demod); - else - stv0900_activate_s2_modcode_single(i_params, demod); - - if (i_params->dmd2_symbol_rate >= 2000000) - stv0900_set_viterbi_acq(i_params, demod); - else - stv0900_set_viterbi_tracq(i_params, demod); - - stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod); - - break; - } - - break; - } -} - -enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - - s32 demod_timeout = 500, fec_timeout = 50, stream_merger_field; - - int lock = FALSE, low_sr = FALSE; - - enum fe_stv0900_signal_type signal_type = STV0900_NOCARRIER; - enum fe_stv0900_search_algo algo; - int no_signal = FALSE; - - dprintk(KERN_INFO "%s\n", __func__); - - switch (demod) { - case STV0900_DEMOD_1: - default: - algo = i_params->dmd1_srch_algo; - - stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1); - stream_merger_field = F0900_P1_RST_HWARE; - - stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C); - - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x9e); - else - stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x88); - - stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd1_symbol_rate, i_params->dmd1_srch_algo); - - if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) { - i_params->tuner1_bw = 2 * 36000000; - - stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x00); - stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70); - - stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); - } else { - stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20); - stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2); - - if (i_params->dmd1_symbol_rate < 2000000) - stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x63); - else - stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70); - - stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0x5a); - - if (i_params->dmd1_srch_algo == STV0900_COLD_START) - i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10; - else if (i_params->dmd1_srch_algo == STV0900_WARM_START) - i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000; - } else { - stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0xc1); - i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10; - } - - stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01); - - stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod); - stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod); - stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod); - if (i_params->dmd1_symbol_rate >= 10000000) - low_sr = FALSE; - else - low_sr = TRUE; - - } - - stv0900_set_tuner(fe, i_params->tuner1_freq, i_params->tuner1_bw); - - stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, i_params->dmd1_srch_iq_inv); - stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1); - - stv0900_set_search_standard(i_params, demod); - - if (i_params->dmd1_srch_algo != STV0900_BLIND_SEARCH) - stv0900_start_search(i_params, demod); - break; - case STV0900_DEMOD_2: - algo = i_params->dmd2_srch_algo; - - stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1); - - stream_merger_field = F0900_P2_RST_HWARE; - - stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C); - - if (i_params->chip_id >= 0x20) - stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x9e); - else - stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x88); - - stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd2_symbol_rate, i_params->dmd2_srch_algo); - - if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { - i_params->tuner2_bw = 2 * 36000000; - - stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x00); - stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70); - - stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); - } else { - stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20); - stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2); - - if (i_params->dmd2_symbol_rate < 2000000) - stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x63); - else - stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70); - - if (i_params->dmd2_symbol_rate >= 10000000) - stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); - else - stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x60); - - if (i_params->chip_id >= 0x20) { - stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0x5a); - - if (i_params->dmd2_srch_algo == STV0900_COLD_START) - i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate, - i_params->rolloff) + 10000000)) / 10; - else if (i_params->dmd2_srch_algo == STV0900_WARM_START) - i_params->tuner2_bw = stv0900_carrier_width(i_params->dmd2_symbol_rate, - i_params->rolloff) + 10000000; - } else { - stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0xc1); - i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate, - i_params->rolloff) + 10000000)) / 10; - } - - stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01); - - stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod); - stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod); - stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod); - if (i_params->dmd2_symbol_rate >= 10000000) - low_sr = FALSE; - else - low_sr = TRUE; - - } - - stv0900_set_tuner(fe, i_params->tuner2_freq, i_params->tuner2_bw); - - stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, i_params->dmd2_srch_iq_inv); - stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1); - - stv0900_set_search_standard(i_params, demod); - - if (i_params->dmd2_srch_algo != STV0900_BLIND_SEARCH) - stv0900_start_search(i_params, demod); - break; - } - - if (i_params->chip_id == 0x12) { - stv0900_write_bits(i_params, stream_merger_field, 0); - msleep(3); - stv0900_write_bits(i_params, stream_merger_field, 1); - stv0900_write_bits(i_params, stream_merger_field, 0); - } - - if (algo == STV0900_BLIND_SEARCH) - lock = stv0900_blind_search_algo(fe); - else if (algo == STV0900_COLD_START) - lock = stv0900_get_demod_cold_lock(fe, demod_timeout); - else if (algo == STV0900_WARM_START) - lock = stv0900_get_demod_lock(i_params, demod, demod_timeout); - - if ((lock == FALSE) && (algo == STV0900_COLD_START)) { - if (low_sr == FALSE) { - if (stv0900_check_timing_lock(i_params, demod) == TRUE) - lock = stv0900_sw_algo(i_params, demod); - } - } - - if (lock == TRUE) - signal_type = stv0900_get_signal_params(fe); - - if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) { - stv0900_track_optimization(fe); - if (i_params->chip_id <= 0x11) { - if ((stv0900_get_standard(fe, STV0900_DEMOD_1) == STV0900_DVBS1_STANDARD) && (stv0900_get_standard(fe, STV0900_DEMOD_2) == STV0900_DVBS1_STANDARD)) { - msleep(20); - stv0900_write_bits(i_params, stream_merger_field, 0); - } else { - stv0900_write_bits(i_params, stream_merger_field, 0); - msleep(3); - stv0900_write_bits(i_params, stream_merger_field, 1); - stv0900_write_bits(i_params, stream_merger_field, 0); - } - } else if (i_params->chip_id == 0x20) { - stv0900_write_bits(i_params, stream_merger_field, 0); - msleep(3); - stv0900_write_bits(i_params, stream_merger_field, 1); - stv0900_write_bits(i_params, stream_merger_field, 0); - } - - if (stv0900_wait_for_lock(i_params, demod, fec_timeout, fec_timeout) == TRUE) { - lock = TRUE; - switch (demod) { - case STV0900_DEMOD_1: - default: - i_params->dmd1_rslts.locked = TRUE; - if (i_params->dmd1_rslts.standard == STV0900_DVBS2_STANDARD) { - stv0900_set_dvbs2_rolloff(i_params, demod); - stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0x40); - stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0); - stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67); - } else { - stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75); - } - - stv0900_write_reg(i_params, R0900_P1_FBERCPT4, 0); - stv0900_write_reg(i_params, R0900_P1_ERRCTRL2, 0xc1); - break; - case STV0900_DEMOD_2: - i_params->dmd2_rslts.locked = TRUE; - - if (i_params->dmd2_rslts.standard == STV0900_DVBS2_STANDARD) { - stv0900_set_dvbs2_rolloff(i_params, demod); - stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x60); - stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x20); - stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67); - } else { - stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75); - } - - stv0900_write_reg(i_params, R0900_P2_FBERCPT4, 0); - - stv0900_write_reg(i_params, R0900_P2_ERRCTRL2, 0xc1); - break; - } - } else { - lock = FALSE; - signal_type = STV0900_NODATA; - no_signal = stv0900_check_signal_presence(i_params, demod); - - switch (demod) { - case STV0900_DEMOD_1: - default: - i_params->dmd1_rslts.locked = FALSE; - break; - case STV0900_DEMOD_2: - i_params->dmd2_rslts.locked = FALSE; - break; - } - } - } - - if ((signal_type == STV0900_NODATA) && (no_signal == FALSE)) { - switch (demod) { - case STV0900_DEMOD_1: - default: - if (i_params->chip_id <= 0x11) { - if ((stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) && - (i_params->dmd1_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST)) - signal_type = stv0900_dvbs1_acq_workaround(fe); - } else - i_params->dmd1_rslts.locked = FALSE; - - break; - case STV0900_DEMOD_2: - if (i_params->chip_id <= 0x11) { - if ((stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) && - (i_params->dmd2_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST)) - signal_type = stv0900_dvbs1_acq_workaround(fe); - } else - i_params->dmd2_rslts.locked = FALSE; - break; - } - } - - return signal_type; -} - diff --git a/trunk/drivers/media/dvb/frontends/stv6110.c b/trunk/drivers/media/dvb/frontends/stv6110.c deleted file mode 100644 index 70efac869d28..000000000000 --- a/trunk/drivers/media/dvb/frontends/stv6110.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * stv6110.c - * - * Driver for ST STV6110 satellite tuner IC. - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include - -#include - -#include "stv6110.h" - -static int debug; - -struct stv6110_priv { - int i2c_address; - struct i2c_adapter *i2c; - - u32 mclk; - u8 regs[8]; -}; - -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG args); \ - } while (0) - -static s32 abssub(s32 a, s32 b) -{ - if (a > b) - return a - b; - else - return b - a; -}; - -static int stv6110_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static int stv6110_write_regs(struct dvb_frontend *fe, u8 buf[], - int start, int len) -{ - struct stv6110_priv *priv = fe->tuner_priv; - int rc; - u8 cmdbuf[len + 1]; - struct i2c_msg msg = { - .addr = priv->i2c_address, - .flags = 0, - .buf = cmdbuf, - .len = len + 1 - }; - - dprintk("%s\n", __func__); - - if (start + len > 8) - return -EINVAL; - - memcpy(&cmdbuf[1], buf, len); - cmdbuf[0] = start; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - rc = i2c_transfer(priv->i2c, &msg, 1); - if (rc != 1) - dprintk("%s: i2c error\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return 0; -} - -static int stv6110_read_regs(struct dvb_frontend *fe, u8 regs[], - int start, int len) -{ - struct stv6110_priv *priv = fe->tuner_priv; - int rc; - u8 reg[] = { start }; - struct i2c_msg msg_wr = { - .addr = priv->i2c_address, - .flags = 0, - .buf = reg, - .len = 1, - }; - - struct i2c_msg msg_rd = { - .addr = priv->i2c_address, - .flags = I2C_M_RD, - .buf = regs, - .len = len, - }; - /* write subaddr */ - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - rc = i2c_transfer(priv->i2c, &msg_wr, 1); - if (rc != 1) - dprintk("%s: i2c error\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - /* read registers */ - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - rc = i2c_transfer(priv->i2c, &msg_rd, 1); - if (rc != 1) - dprintk("%s: i2c error\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - memcpy(&priv->regs[start], regs, len); - - return 0; -} - -static int stv6110_read_reg(struct dvb_frontend *fe, int start) -{ - u8 buf[] = { 0 }; - stv6110_read_regs(fe, buf, start, 1); - - return buf[0]; -} - -static int stv6110_sleep(struct dvb_frontend *fe) -{ - u8 reg[] = { 0 }; - stv6110_write_regs(fe, reg, 0, 1); - - return 0; -} - -static u32 carrier_width(u32 symbol_rate, fe_rolloff_t rolloff) -{ - u32 rlf; - - switch (rolloff) { - case ROLLOFF_20: - rlf = 20; - break; - case ROLLOFF_25: - rlf = 25; - break; - default: - rlf = 35; - break; - } - - return symbol_rate + ((symbol_rate * rlf) / 100); -} - -static int stv6110_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) -{ - struct stv6110_priv *priv = fe->tuner_priv; - u8 r8, ret = 0x04; - int i; - - if ((bandwidth / 2) > 36000000) /*BW/2 max=31+5=36 mhz for r8=31*/ - r8 = 31; - else if ((bandwidth / 2) < 5000000) /* BW/2 min=5Mhz for F=0 */ - r8 = 0; - else /*if 5 < BW/2 < 36*/ - r8 = (bandwidth / 2) / 1000000 - 5; - - /* ctrl3, RCCLKOFF = 0 Activate the calibration Clock */ - /* ctrl3, CF = r8 Set the LPF value */ - priv->regs[RSTV6110_CTRL3] &= ~((1 << 6) | 0x1f); - priv->regs[RSTV6110_CTRL3] |= (r8 & 0x1f); - stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1); - /* stat1, CALRCSTRT = 1 Start LPF auto calibration*/ - priv->regs[RSTV6110_STAT1] |= 0x02; - stv6110_write_regs(fe, &priv->regs[RSTV6110_STAT1], RSTV6110_STAT1, 1); - - i = 0; - /* Wait for CALRCSTRT == 0 */ - while ((i < 10) && (ret != 0)) { - ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x02); - mdelay(1); /* wait for LPF auto calibration */ - i++; - } - - /* RCCLKOFF = 1 calibration done, desactivate the calibration Clock */ - priv->regs[RSTV6110_CTRL3] |= (1 << 6); - stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1); - return 0; -} - -static int stv6110_init(struct dvb_frontend *fe) -{ - struct stv6110_priv *priv = fe->tuner_priv; - u8 buf0[] = { 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e }; - - memcpy(priv->regs, buf0, 8); - /* K = (Reference / 1000000) - 16 */ - priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3); - priv->regs[RSTV6110_CTRL1] |= - ((((priv->mclk / 1000000) - 16) & 0x1f) << 3); - - stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], RSTV6110_CTRL1, 8); - msleep(1); - stv6110_set_bandwidth(fe, 72000000); - - return 0; -} - -static int stv6110_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct stv6110_priv *priv = fe->tuner_priv; - u32 nbsteps, divider, psd2, freq; - u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - - stv6110_read_regs(fe, regs, 0, 8); - /*N*/ - divider = (priv->regs[RSTV6110_TUNING2] & 0x0f) << 8; - divider += priv->regs[RSTV6110_TUNING1]; - - /*R*/ - nbsteps = (priv->regs[RSTV6110_TUNING2] >> 6) & 3; - /*p*/ - psd2 = (priv->regs[RSTV6110_TUNING2] >> 4) & 1; - - freq = divider * (priv->mclk / 1000); - freq /= (1 << (nbsteps + psd2)); - freq /= 4; - - *frequency = freq; - - return 0; -} - -static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency) -{ - struct stv6110_priv *priv = fe->tuner_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - u8 ret = 0x04; - u32 divider, ref, p, presc, i, result_freq, vco_freq; - s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val; - s32 srate; u8 gain; - - dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__, - frequency, priv->mclk); - - /* K = (Reference / 1000000) - 16 */ - priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3); - priv->regs[RSTV6110_CTRL1] |= - ((((priv->mclk / 1000000) - 16) & 0x1f) << 3); - - /* BB_GAIN = db/2 */ - if (fe->ops.set_property && fe->ops.get_property) { - srate = c->symbol_rate; - dprintk("%s: Get Frontend parameters: srate=%d\n", - __func__, srate); - } else - srate = 15000000; - - if (srate >= 15000000) - gain = 3; /* +6 dB */ - else if (srate >= 5000000) - gain = 3; /* +6 dB */ - else - gain = 3; /* +6 dB */ - - priv->regs[RSTV6110_CTRL2] &= ~0x0f; - priv->regs[RSTV6110_CTRL2] |= (gain & 0x0f); - - if (frequency <= 1023000) { - p = 1; - presc = 0; - } else if (frequency <= 1300000) { - p = 1; - presc = 1; - } else if (frequency <= 2046000) { - p = 0; - presc = 0; - } else { - p = 0; - presc = 1; - } - /* DIV4SEL = p*/ - priv->regs[RSTV6110_TUNING2] &= ~(1 << 4); - priv->regs[RSTV6110_TUNING2] |= (p << 4); - - /* PRESC32ON = presc */ - priv->regs[RSTV6110_TUNING2] &= ~(1 << 5); - priv->regs[RSTV6110_TUNING2] |= (presc << 5); - - p_val = (int)(1 << (p + 1)) * 10;/* P = 2 or P = 4 */ - for (r_div = 0; r_div <= 3; r_div++) { - p_calc = (priv->mclk / 100000); - p_calc /= (1 << (r_div + 1)); - if ((abssub(p_calc, p_val)) < (abssub(p_calc_opt, p_val))) - r_div_opt = r_div; - - p_calc_opt = (priv->mclk / 100000); - p_calc_opt /= (1 << (r_div_opt + 1)); - } - - ref = priv->mclk / ((1 << (r_div_opt + 1)) * (1 << (p + 1))); - divider = (((frequency * 1000) + (ref >> 1)) / ref); - - /* RDIV = r_div_opt */ - priv->regs[RSTV6110_TUNING2] &= ~(3 << 6); - priv->regs[RSTV6110_TUNING2] |= (((r_div_opt) & 3) << 6); - - /* NDIV_MSB = MSB(divider) */ - priv->regs[RSTV6110_TUNING2] &= ~0x0f; - priv->regs[RSTV6110_TUNING2] |= (((divider) >> 8) & 0x0f); - - /* NDIV_LSB, LSB(divider) */ - priv->regs[RSTV6110_TUNING1] = (divider & 0xff); - - /* CALVCOSTRT = 1 VCO Auto Calibration */ - priv->regs[RSTV6110_STAT1] |= 0x04; - stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], - RSTV6110_CTRL1, 8); - - i = 0; - /* Wait for CALVCOSTRT == 0 */ - while ((i < 10) && (ret != 0)) { - ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x04); - msleep(1); /* wait for VCO auto calibration */ - i++; - } - - ret = stv6110_read_reg(fe, RSTV6110_STAT1); - stv6110_get_frequency(fe, &result_freq); - - vco_freq = divider * ((priv->mclk / 1000) / ((1 << (r_div_opt + 1)))); - dprintk("%s, stat1=%x, lo_freq=%d kHz, vco_frec=%d kHz\n", __func__, - ret, result_freq, vco_freq); - - return 0; -} - -static int stv6110_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - u32 bandwidth = carrier_width(c->symbol_rate, c->rolloff); - - stv6110_set_frequency(fe, c->frequency); - stv6110_set_bandwidth(fe, bandwidth); - - return 0; -} - -static int stv6110_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -{ - struct stv6110_priv *priv = fe->tuner_priv; - u8 r8 = 0; - u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - stv6110_read_regs(fe, regs, 0, 8); - - /* CF */ - r8 = priv->regs[RSTV6110_CTRL3] & 0x1f; - *bandwidth = (r8 + 5) * 2000000;/* x2 for ZIF tuner BW/2 = F+5 Mhz */ - - return 0; -} - -static struct dvb_tuner_ops stv6110_tuner_ops = { - .info = { - .name = "ST STV6110", - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 1000, - }, - .init = stv6110_init, - .release = stv6110_release, - .sleep = stv6110_sleep, - .set_params = stv6110_set_params, - .get_frequency = stv6110_get_frequency, - .set_frequency = stv6110_set_frequency, - .get_bandwidth = stv6110_get_bandwidth, - .set_bandwidth = stv6110_set_bandwidth, - -}; - -struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe, - const struct stv6110_config *config, - struct i2c_adapter *i2c) -{ - struct stv6110_priv *priv = NULL; - u8 reg0[] = { 0x00, 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e }; - - struct i2c_msg msg[] = { - { - .addr = config->i2c_address, - .flags = 0, - .buf = reg0, - .len = 9 - } - }; - int ret; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - ret = i2c_transfer(i2c, msg, 1); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - if (ret != 1) - return NULL; - - priv = kzalloc(sizeof(struct stv6110_priv), GFP_KERNEL); - if (priv == NULL) - return NULL; - - priv->i2c_address = config->i2c_address; - priv->i2c = i2c; - priv->mclk = config->mclk; - - memcpy(&priv->regs, ®0[1], 8); - - memcpy(&fe->ops.tuner_ops, &stv6110_tuner_ops, - sizeof(struct dvb_tuner_ops)); - fe->tuner_priv = priv; - printk(KERN_INFO "STV6110 attached on addr=%x!\n", priv->i2c_address); - - return fe; -} -EXPORT_SYMBOL(stv6110_attach); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("ST STV6110 driver"); -MODULE_AUTHOR("Igor M. Liplianin"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/frontends/stv6110.h b/trunk/drivers/media/dvb/frontends/stv6110.h deleted file mode 100644 index 1c0314d6aa55..000000000000 --- a/trunk/drivers/media/dvb/frontends/stv6110.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * stv6110.h - * - * Driver for ST STV6110 satellite tuner IC. - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __DVB_STV6110_H__ -#define __DVB_STV6110_H__ - -#include -#include "dvb_frontend.h" - -/* registers */ -#define RSTV6110_CTRL1 0 -#define RSTV6110_CTRL2 1 -#define RSTV6110_TUNING1 2 -#define RSTV6110_TUNING2 3 -#define RSTV6110_CTRL3 4 -#define RSTV6110_STAT1 5 -#define RSTV6110_STAT2 6 -#define RSTV6110_STAT3 7 - -struct stv6110_config { - u8 i2c_address; - u32 mclk; - int iq_wiring; -}; - -#if defined(CONFIG_DVB_STV6110) || (defined(CONFIG_DVB_STV6110_MODULE) \ - && defined(MODULE)) -extern struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe, - const struct stv6110_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe, - const struct stv6110_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif diff --git a/trunk/drivers/media/dvb/frontends/tda1004x.c b/trunk/drivers/media/dvb/frontends/tda1004x.c index 4981cef8b444..1465ff77b0cb 100644 --- a/trunk/drivers/media/dvb/frontends/tda1004x.c +++ b/trunk/drivers/media/dvb/frontends/tda1004x.c @@ -162,7 +162,7 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg) if (ret != 2) { dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret); - return -EINVAL; + return -1; } dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__, @@ -481,18 +481,16 @@ static void tda10046_init_plls(struct dvb_frontend* fe) static int tda10046_fwupload(struct dvb_frontend* fe) { struct tda1004x_state* state = fe->demodulator_priv; - int ret, confc4; + int ret; const struct firmware *fw; /* reset + wake up chip */ if (state->config->xtal_freq == TDA10046_XTAL_4M) { - confc4 = 0; + tda1004x_write_byteI(state, TDA1004X_CONFC4, 0); } else { dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__); - confc4 = 0x80; + tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); } - tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4); - tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); /* set GPIO 1 and 3 */ if (state->config->gpio_config != TDA10046_GPTRI) { @@ -510,29 +508,13 @@ static int tda10046_fwupload(struct dvb_frontend* fe) if (tda1004x_check_upload_ok(state) == 0) return 0; - /* - For i2c normal work, we need to slow down the bus speed. - However, the slow down breaks the eeprom firmware load. - So, use normal speed for eeprom booting and then restore the - i2c speed after that. Tested with MSI TV @nyware A/D board, - that comes with firmware version 29 inside their eeprom. - - It should also be noticed that no other I2C transfer should - be in course while booting from eeprom, otherwise, tda10046 - goes into an instable state. So, proper locking are needed - at the i2c bus master. - */ printk(KERN_INFO "tda1004x: trying to boot from eeprom\n"); - tda1004x_write_byteI(state, TDA1004X_CONFC4, 4); + tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); msleep(300); - tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4); - - /* Checks if eeprom firmware went without troubles */ + /* don't re-upload unless necessary */ if (tda1004x_check_upload_ok(state) == 0) return 0; - /* eeprom firmware didn't work. Load one manually. */ - if (state->config->request_firmware != NULL) { /* request the firmware, this will block until someone uploads it */ printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); diff --git a/trunk/drivers/media/dvb/frontends/zl10036.c b/trunk/drivers/media/dvb/frontends/zl10036.c deleted file mode 100644 index e22a0b381dc4..000000000000 --- a/trunk/drivers/media/dvb/frontends/zl10036.c +++ /dev/null @@ -1,519 +0,0 @@ -/** - * Driver for Zarlink zl10036 DVB-S silicon tuner - * - * Copyright (C) 2006 Tino Reichardt - * Copyright (C) 2007-2009 Matthias Schwarzott - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - ** - * The data sheet for this tuner can be found at: - * http://www.mcmilk.de/projects/dvb-card/datasheets/ZL10036.pdf - * - * This one is working: (at my Avermedia DVB-S Pro) - * - zl10036 (40pin, FTA) - * - * A driver for zl10038 should be very similar. - */ - -#include -#include -#include - -#include "zl10036.h" - -static int zl10036_debug; -#define dprintk(level, args...) \ - do { if (zl10036_debug & level) printk(KERN_DEBUG "zl10036: " args); \ - } while (0) - -#define deb_info(args...) dprintk(0x01, args) -#define deb_i2c(args...) dprintk(0x02, args) - -struct zl10036_state { - struct i2c_adapter *i2c; - const struct zl10036_config *config; - u32 frequency; - u8 br, bf; -}; - - -/* This driver assumes the tuner is driven by a 10.111MHz Cristal */ -#define _XTAL 10111 - -/* Some of the possible dividers: - * 64, (write 0x05 to reg), freq step size 158kHz - * 10, (write 0x0a to reg), freq step size 1.011kHz (used here) - * 5, (write 0x09 to reg), freq step size 2.022kHz - */ - -#define _RDIV 10 -#define _RDIV_REG 0x0a -#define _FR (_XTAL/_RDIV) - -#define STATUS_POR 0x80 /* Power on Reset */ -#define STATUS_FL 0x40 /* Frequency & Phase Lock */ - -/* read/write for zl10036 and zl10038 */ - -static int zl10036_read_status_reg(struct zl10036_state *state) -{ - u8 status; - struct i2c_msg msg[1] = { - { .addr = state->config->tuner_address, .flags = I2C_M_RD, - .buf = &status, .len = sizeof(status) }, - }; - - if (i2c_transfer(state->i2c, msg, 1) != 1) { - printk(KERN_ERR "%s: i2c read failed at addr=%02x\n", - __func__, state->config->tuner_address); - return -EIO; - } - - deb_i2c("R(status): %02x [FL=%d]\n", status, - (status & STATUS_FL) ? 1 : 0); - if (status & STATUS_POR) - deb_info("%s: Power-On-Reset bit enabled - " - "need to initialize the tuner\n", __func__); - - return status; -} - -static int zl10036_write(struct zl10036_state *state, u8 buf[], u8 count) -{ - struct i2c_msg msg[1] = { - { .addr = state->config->tuner_address, .flags = 0, - .buf = buf, .len = count }, - }; - u8 reg = 0; - int ret; - - if (zl10036_debug & 0x02) { - /* every 8bit-value satisifes this! - * so only check for debug log */ - if ((buf[0] & 0x80) == 0x00) - reg = 2; - else if ((buf[0] & 0xc0) == 0x80) - reg = 4; - else if ((buf[0] & 0xf0) == 0xc0) - reg = 6; - else if ((buf[0] & 0xf0) == 0xd0) - reg = 8; - else if ((buf[0] & 0xf0) == 0xe0) - reg = 10; - else if ((buf[0] & 0xf0) == 0xf0) - reg = 12; - - deb_i2c("W(%d):", reg); - { - int i; - for (i = 0; i < count; i++) - printk(KERN_CONT " %02x", buf[i]); - printk(KERN_CONT "\n"); - } - } - - ret = i2c_transfer(state->i2c, msg, 1); - if (ret != 1) { - printk(KERN_ERR "%s: i2c error, ret=%d\n", __func__, ret); - return -EIO; - } - - return 0; -} - -static int zl10036_release(struct dvb_frontend *fe) -{ - struct zl10036_state *state = fe->tuner_priv; - - fe->tuner_priv = NULL; - kfree(state); - - return 0; -} - -static int zl10036_sleep(struct dvb_frontend *fe) -{ - struct zl10036_state *state = fe->tuner_priv; - u8 buf[] = { 0xf0, 0x80 }; /* regs 12/13 */ - int ret; - - deb_info("%s\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ - - ret = zl10036_write(state, buf, sizeof(buf)); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ - - return ret; -} - -/** - * register map of the ZL10036/ZL10038 - * - * reg[default] content - * 2[0x00]: 0 | N14 | N13 | N12 | N11 | N10 | N9 | N8 - * 3[0x00]: N7 | N6 | N5 | N4 | N3 | N2 | N1 | N0 - * 4[0x80]: 1 | 0 | RFG | BA1 | BA0 | BG1 | BG0 | LEN - * 5[0x00]: P0 | C1 | C0 | R4 | R3 | R2 | R1 | R0 - * 6[0xc0]: 1 | 1 | 0 | 0 | RSD | 0 | 0 | 0 - * 7[0x20]: P1 | BF6 | BF5 | BF4 | BF3 | BF2 | BF1 | 0 - * 8[0xdb]: 1 | 1 | 0 | 1 | 0 | CC | 1 | 1 - * 9[0x30]: VSD | V2 | V1 | V0 | S3 | S2 | S1 | S0 - * 10[0xe1]: 1 | 1 | 1 | 0 | 0 | LS2 | LS1 | LS0 - * 11[0xf5]: WS | WH2 | WH1 | WH0 | WL2 | WL1 | WL0 | WRE - * 12[0xf0]: 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 - * 13[0x28]: PD | BR4 | BR3 | BR2 | BR1 | BR0 | CLR | TL - */ - -static int zl10036_set_frequency(struct zl10036_state *state, u32 frequency) -{ - u8 buf[2]; - u32 div, foffset; - - div = (frequency + _FR/2) / _FR; - state->frequency = div * _FR; - - foffset = frequency - state->frequency; - - buf[0] = (div >> 8) & 0x7f; - buf[1] = (div >> 0) & 0xff; - - deb_info("%s: ftodo=%u fpriv=%u ferr=%d div=%u\n", __func__, - frequency, state->frequency, foffset, div); - - return zl10036_write(state, buf, sizeof(buf)); -} - -static int zl10036_set_bandwidth(struct zl10036_state *state, u32 fbw) -{ - /* fbw is measured in kHz */ - u8 br, bf; - int ret; - u8 buf_bf[] = { - 0xc0, 0x00, /* 6/7: rsd=0 bf=0 */ - }; - u8 buf_br[] = { - 0xf0, 0x00, /* 12/13: br=0xa clr=0 tl=0*/ - }; - u8 zl10036_rsd_off[] = { 0xc8 }; /* set RSD=1 */ - - /* ensure correct values */ - if (fbw > 35000) - fbw = 35000; - if (fbw < 8000) - fbw = 8000; - -#define _BR_MAXIMUM (_XTAL/575) /* _XTAL / 575kHz = 17 */ - - /* <= 28,82 MHz */ - if (fbw <= 28820) { - br = _BR_MAXIMUM; - } else { - /** - * f(bw)=34,6MHz f(xtal)=10.111MHz - * br = (10111/34600) * 63 * 1/K = 14; - */ - br = ((_XTAL * 21 * 1000) / (fbw * 419)); - } - - /* ensure correct values */ - if (br < 4) - br = 4; - if (br > _BR_MAXIMUM) - br = _BR_MAXIMUM; - - /* - * k = 1.257 - * bf = fbw/_XTAL * br * k - 1 */ - - bf = (fbw * br * 1257) / (_XTAL * 1000) - 1; - - /* ensure correct values */ - if (bf > 62) - bf = 62; - - buf_bf[1] = (bf << 1) & 0x7e; - buf_br[1] = (br << 2) & 0x7c; - deb_info("%s: BW=%d br=%u bf=%u\n", __func__, fbw, br, bf); - - if (br != state->br) { - ret = zl10036_write(state, buf_br, sizeof(buf_br)); - if (ret < 0) - return ret; - } - - if (bf != state->bf) { - ret = zl10036_write(state, buf_bf, sizeof(buf_bf)); - if (ret < 0) - return ret; - - /* time = br/(32* fxtal) */ - /* minimal sleep time to be calculated - * maximum br is 63 -> max time = 2 /10 MHz = 2e-7 */ - msleep(1); - - ret = zl10036_write(state, zl10036_rsd_off, - sizeof(zl10036_rsd_off)); - if (ret < 0) - return ret; - } - - state->br = br; - state->bf = bf; - - return 0; -} - -static int zl10036_set_gain_params(struct zl10036_state *state, - int c) -{ - u8 buf[2]; - u8 rfg, ba, bg; - - /* default values */ - rfg = 0; /* enable when using an lna */ - ba = 1; - bg = 1; - - /* reg 4 */ - buf[0] = 0x80 | ((rfg << 5) & 0x20) - | ((ba << 3) & 0x18) | ((bg << 1) & 0x06); - - if (!state->config->rf_loop_enable) - buf[0] |= 0x01; - - /* P0=0 */ - buf[1] = _RDIV_REG | ((c << 5) & 0x60); - - deb_info("%s: c=%u rfg=%u ba=%u bg=%u\n", __func__, c, rfg, ba, bg); - return zl10036_write(state, buf, sizeof(buf)); -} - -static int zl10036_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct zl10036_state *state = fe->tuner_priv; - int ret = 0; - u32 frequency = params->frequency; - u32 fbw; - int i; - u8 c; - - /* ensure correct values - * maybe redundant as core already checks this */ - if ((frequency < fe->ops.info.frequency_min) - || (frequency > fe->ops.info.frequency_max)) - return -EINVAL; - - /** - * alpha = 1.35 for dvb-s - * fBW = (alpha*symbolrate)/(2*0.8) - * 1.35 / (2*0.8) = 27 / 32 - */ - fbw = (27 * params->u.qpsk.symbol_rate) / 32; - - /* scale to kHz */ - fbw /= 1000; - - /* Add safe margin of 3MHz */ - fbw += 3000; - - /* setting the charge pump - guessed values */ - if (frequency < 950000) - return -EINVAL; - else if (frequency < 1250000) - c = 0; - else if (frequency < 1750000) - c = 1; - else if (frequency < 2175000) - c = 2; - else - return -EINVAL; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ - - ret = zl10036_set_gain_params(state, c); - if (ret < 0) - goto error; - - ret = zl10036_set_frequency(state, params->frequency); - if (ret < 0) - goto error; - - ret = zl10036_set_bandwidth(state, fbw); - if (ret < 0) - goto error; - - /* wait for tuner lock - no idea if this is really needed */ - for (i = 0; i < 20; i++) { - ret = zl10036_read_status_reg(state); - if (ret < 0) - goto error; - - /* check Frequency & Phase Lock Bit */ - if (ret & STATUS_FL) - break; - - msleep(10); - } - -error: - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ - - return ret; -} - -static int zl10036_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct zl10036_state *state = fe->tuner_priv; - - *frequency = state->frequency; - - return 0; -} - -static int zl10036_init_regs(struct zl10036_state *state) -{ - int ret; - int i; - - /* could also be one block from reg 2 to 13 and additional 10/11 */ - u8 zl10036_init_tab[][2] = { - { 0x04, 0x00 }, /* 2/3: div=0x400 - arbitrary value */ - { 0x8b, _RDIV_REG }, /* 4/5: rfg=0 ba=1 bg=1 len=? */ - /* p0=0 c=0 r=_RDIV_REG */ - { 0xc0, 0x20 }, /* 6/7: rsd=0 bf=0x10 */ - { 0xd3, 0x40 }, /* 8/9: from datasheet */ - { 0xe3, 0x5b }, /* 10/11: lock window level */ - { 0xf0, 0x28 }, /* 12/13: br=0xa clr=0 tl=0*/ - { 0xe3, 0xf9 }, /* 10/11: unlock window level */ - }; - - /* invalid values to trigger writing */ - state->br = 0xff; - state->bf = 0xff; - - if (!state->config->rf_loop_enable) - zl10036_init_tab[1][2] |= 0x01; - - deb_info("%s\n", __func__); - - for (i = 0; i < ARRAY_SIZE(zl10036_init_tab); i++) { - ret = zl10036_write(state, zl10036_init_tab[i], 2); - if (ret < 0) - return ret; - } - - return 0; -} - -static int zl10036_init(struct dvb_frontend *fe) -{ - struct zl10036_state *state = fe->tuner_priv; - int ret = 0; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ - - ret = zl10036_read_status_reg(state); - if (ret < 0) - return ret; - - /* Only init if Power-on-Reset bit is set? */ - ret = zl10036_init_regs(state); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ - - return ret; -} - -static struct dvb_tuner_ops zl10036_tuner_ops = { - .info = { - .name = "Zarlink ZL10036", - .frequency_min = 950000, - .frequency_max = 2175000 - }, - .init = zl10036_init, - .release = zl10036_release, - .sleep = zl10036_sleep, - .set_params = zl10036_set_params, - .get_frequency = zl10036_get_frequency, -}; - -struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe, - const struct zl10036_config *config, - struct i2c_adapter *i2c) -{ - struct zl10036_state *state = NULL; - int ret; - - if (NULL == config) { - printk(KERN_ERR "%s: no config specified", __func__); - goto error; - } - - state = kzalloc(sizeof(struct zl10036_state), GFP_KERNEL); - if (NULL == state) - return NULL; - - state->config = config; - state->i2c = i2c; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ - - ret = zl10036_read_status_reg(state); - if (ret < 0) { - printk(KERN_ERR "%s: No zl10036 found\n", __func__); - goto error; - } - - ret = zl10036_init_regs(state); - if (ret < 0) { - printk(KERN_ERR "%s: tuner initialization failed\n", - __func__); - goto error; - } - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ - - fe->tuner_priv = state; - - memcpy(&fe->ops.tuner_ops, &zl10036_tuner_ops, - sizeof(struct dvb_tuner_ops)); - printk(KERN_INFO "%s: tuner initialization (%s addr=0x%02x) ok\n", - __func__, fe->ops.tuner_ops.info.name, config->tuner_address); - - return fe; - -error: - zl10036_release(fe); - return NULL; -} -EXPORT_SYMBOL(zl10036_attach); - -module_param_named(debug, zl10036_debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); -MODULE_DESCRIPTION("DVB ZL10036 driver"); -MODULE_AUTHOR("Tino Reichardt"); -MODULE_AUTHOR("Matthias Schwarzott"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/frontends/zl10036.h b/trunk/drivers/media/dvb/frontends/zl10036.h deleted file mode 100644 index d84b8f8215e9..000000000000 --- a/trunk/drivers/media/dvb/frontends/zl10036.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Driver for Zarlink ZL10036 DVB-S silicon tuner - * - * Copyright (C) 2006 Tino Reichardt - * Copyright (C) 2007-2009 Matthias Schwarzott - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef DVB_ZL10036_H -#define DVB_ZL10036_H - -#include -#include "dvb_frontend.h" - -/** - * Attach a zl10036 tuner to the supplied frontend structure. - * - * @param fe Frontend to attach to. - * @param config zl10036_config structure - * @return FE pointer on success, NULL on failure. - */ - -struct zl10036_config { - u8 tuner_address; - int rf_loop_enable; -}; - -#if defined(CONFIG_DVB_ZL10036) || \ - (defined(CONFIG_DVB_ZL10036_MODULE) && defined(MODULE)) -extern struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe, - const struct zl10036_config *config, struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe, - const struct zl10036_config *config, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif /* DVB_ZL10036_H */ diff --git a/trunk/drivers/media/dvb/frontends/zl10353.c b/trunk/drivers/media/dvb/frontends/zl10353.c index 148b6f7f6cb2..b150ed306696 100644 --- a/trunk/drivers/media/dvb/frontends/zl10353.c +++ b/trunk/drivers/media/dvb/frontends/zl10353.c @@ -572,10 +572,6 @@ static int zl10353_init(struct dvb_frontend *fe) zl10353_dump_regs(fe); if (state->config.parallel_ts) zl10353_reset_attach[2] &= ~0x20; - if (state->config.clock_ctl_1) - zl10353_reset_attach[3] = state->config.clock_ctl_1; - if (state->config.pll_0) - zl10353_reset_attach[4] = state->config.pll_0; /* Do a "hard" reset if not already done */ if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] || @@ -618,7 +614,6 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config, struct i2c_adapter *i2c) { struct zl10353_state *state = NULL; - int id; /* allocate memory for the internal state */ state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL); @@ -630,8 +625,7 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config, memcpy(&state->config, config, sizeof(struct zl10353_config)); /* check if the demod is there */ - id = zl10353_read_register(state, CHIP_ID); - if ((id != ID_ZL10353) && (id != ID_CE6230) && (id != ID_CE6231)) + if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353) goto error; /* create dvb_frontend */ diff --git a/trunk/drivers/media/dvb/frontends/zl10353.h b/trunk/drivers/media/dvb/frontends/zl10353.h index 6e3ca9eed048..2287bac46243 100644 --- a/trunk/drivers/media/dvb/frontends/zl10353.h +++ b/trunk/drivers/media/dvb/frontends/zl10353.h @@ -41,10 +41,6 @@ struct zl10353_config /* set if i2c_gate_ctrl disable is required */ u8 disable_i2c_gate_ctrl:1; - - /* clock control registers (0x51-0x54) */ - u8 clock_ctl_1; /* default: 0x46 */ - u8 pll_0; /* default: 0x15 */ }; #if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE)) diff --git a/trunk/drivers/media/dvb/frontends/zl10353_priv.h b/trunk/drivers/media/dvb/frontends/zl10353_priv.h index e0dd1d3e09dd..055ff1f7e349 100644 --- a/trunk/drivers/media/dvb/frontends/zl10353_priv.h +++ b/trunk/drivers/media/dvb/frontends/zl10353_priv.h @@ -22,9 +22,7 @@ #ifndef _ZL10353_PRIV_ #define _ZL10353_PRIV_ -#define ID_ZL10353 0x14 /* Zarlink ZL10353 */ -#define ID_CE6230 0x18 /* Intel CE6230 */ -#define ID_CE6231 0x19 /* Intel CE6231 */ +#define ID_ZL10353 0x14 #define msb(x) (((x) >> 8) & 0xff) #define lsb(x) ((x) & 0xff) @@ -52,10 +50,6 @@ enum zl10353_reg_addr { TPS_RECEIVED_0 = 0x1E, TPS_CURRENT_1 = 0x1F, TPS_CURRENT_0 = 0x20, - CLOCK_CTL_0 = 0x51, - CLOCK_CTL_1 = 0x52, - PLL_0 = 0x53, - PLL_1 = 0x54, RESET = 0x55, AGC_TARGET = 0x56, MCLK_RATIO = 0x5C, diff --git a/trunk/drivers/media/dvb/pluto2/pluto2.c b/trunk/drivers/media/dvb/pluto2/pluto2.c index ee89623be85a..d101b304e9b0 100644 --- a/trunk/drivers/media/dvb/pluto2/pluto2.c +++ b/trunk/drivers/media/dvb/pluto2/pluto2.c @@ -116,7 +116,6 @@ struct pluto { /* irq */ unsigned int overflow; - unsigned int dead; /* dma */ dma_addr_t dma_addr; @@ -337,10 +336,8 @@ static irqreturn_t pluto_irq(int irq, void *dev_id) return IRQ_NONE; if (tscr == 0xffffffff) { - if (pluto->dead == 0) - dev_err(&pluto->pdev->dev, "card has hung or been ejected.\n"); - /* It's dead Jim */ - pluto->dead = 1; + // FIXME: maybe recover somehow + dev_err(&pluto->pdev->dev, "card hung up :(\n"); return IRQ_HANDLED; } diff --git a/trunk/drivers/media/dvb/siano/Makefile b/trunk/drivers/media/dvb/siano/Makefile index bcf93f4828b2..ee0737af98c0 100644 --- a/trunk/drivers/media/dvb/siano/Makefile +++ b/trunk/drivers/media/dvb/siano/Makefile @@ -1,8 +1,6 @@ -sms1xxx-objs := smscoreapi.o sms-cards.o +sms1xxx-objs := smscoreapi.o smsusb.o smsdvb.o sms-cards.o obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o -obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o -obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsdvb.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core diff --git a/trunk/drivers/media/dvb/siano/sms-cards.c b/trunk/drivers/media/dvb/siano/sms-cards.c index 63e4d0ec6583..4307e4e8aa34 100644 --- a/trunk/drivers/media/dvb/siano/sms-cards.c +++ b/trunk/drivers/media/dvb/siano/sms-cards.c @@ -19,9 +19,50 @@ #include "sms-cards.h" -static int sms_dbg; -module_param_named(cards_dbg, sms_dbg, int, 0644); -MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))"); +struct usb_device_id smsusb_id_table[] = { +#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS + { USB_DEVICE(0x187f, 0x0010), + .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, + { USB_DEVICE(0x187f, 0x0100), + .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, + { USB_DEVICE(0x187f, 0x0200), + .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A }, + { USB_DEVICE(0x187f, 0x0201), + .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, + { USB_DEVICE(0x187f, 0x0300), + .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, +#endif + { USB_DEVICE(0x2040, 0x1700), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, + { USB_DEVICE(0x2040, 0x1800), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A }, + { USB_DEVICE(0x2040, 0x1801), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B }, + { USB_DEVICE(0x2040, 0x2000), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x2009), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 }, + { USB_DEVICE(0x2040, 0x200a), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x2010), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x2019), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x5500), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5510), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5520), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5530), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5580), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5590), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, smsusb_id_table); static struct sms_board sms_boards[] = { [SMS_BOARD_UNKNOWN] = { @@ -74,7 +115,6 @@ static struct sms_board sms_boards[] = { .type = SMS_NOVA_B0, .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", .lna_ctrl = 29, - .rf_switch = 17, }, [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = { .name = "Hauppauge WinTV MiniCard", @@ -90,7 +130,6 @@ struct sms_board *sms_get_board(int id) return &sms_boards[id]; } -EXPORT_SYMBOL_GPL(sms_get_board); static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) { @@ -143,7 +182,6 @@ int sms_board_setup(struct smscore_device_t *coredev) } return 0; } -EXPORT_SYMBOL_GPL(sms_board_setup); int sms_board_power(struct smscore_device_t *coredev, int onoff) { @@ -159,13 +197,12 @@ int sms_board_power(struct smscore_device_t *coredev, int onoff) case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: /* LNA */ - if (!onoff) - sms_set_gpio(coredev, board->lna_ctrl, 0); + sms_set_gpio(coredev, + board->lna_ctrl, onoff ? 1 : 0); break; } return 0; } -EXPORT_SYMBOL_GPL(sms_board_power); int sms_board_led_feedback(struct smscore_device_t *coredev, int led) { @@ -188,40 +225,3 @@ int sms_board_led_feedback(struct smscore_device_t *coredev, int led) } return 0; } -EXPORT_SYMBOL_GPL(sms_board_led_feedback); - -int sms_board_lna_control(struct smscore_device_t *coredev, int onoff) -{ - int board_id = smscore_get_board_id(coredev); - struct sms_board *board = sms_get_board(board_id); - - sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled"); - - switch (board_id) { - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: - sms_set_gpio(coredev, - board->rf_switch, onoff ? 1 : 0); - return sms_set_gpio(coredev, - board->lna_ctrl, onoff ? 1 : 0); - } - return -EINVAL; -} -EXPORT_SYMBOL_GPL(sms_board_lna_control); - -int sms_board_load_modules(int id) -{ - switch (id) { - case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT: - case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A: - case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B: - case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: - request_module("smsdvb"); - break; - default: - /* do nothing */ - break; - } - return 0; -} -EXPORT_SYMBOL_GPL(sms_board_load_modules); diff --git a/trunk/drivers/media/dvb/siano/sms-cards.h b/trunk/drivers/media/dvb/siano/sms-cards.h index 64d74c59c33f..8e0fe9fd2610 100644 --- a/trunk/drivers/media/dvb/siano/sms-cards.h +++ b/trunk/drivers/media/dvb/siano/sms-cards.h @@ -40,7 +40,7 @@ struct sms_board { char *name, *fw[DEVICE_MODE_MAX]; /* gpios */ - int led_power, led_hi, led_lo, lna_ctrl, rf_switch; + int led_power, led_hi, led_lo, lna_ctrl; }; struct sms_board *sms_get_board(int id); @@ -52,8 +52,7 @@ int sms_board_setup(struct smscore_device_t *coredev); #define SMS_LED_HI 2 int sms_board_led_feedback(struct smscore_device_t *coredev, int led); int sms_board_power(struct smscore_device_t *coredev, int onoff); -int sms_board_lna_control(struct smscore_device_t *coredev, int onoff); -extern int sms_board_load_modules(int id); +extern struct usb_device_id smsusb_id_table[]; #endif /* __SMS_CARDS_H__ */ diff --git a/trunk/drivers/media/dvb/siano/smscoreapi.c b/trunk/drivers/media/dvb/siano/smscoreapi.c index 7bd4d1dee2b3..cf613f22fb8d 100644 --- a/trunk/drivers/media/dvb/siano/smscoreapi.c +++ b/trunk/drivers/media/dvb/siano/smscoreapi.c @@ -3,7 +3,7 @@ * * This file contains implementation for the interface to sms core component * - * author: Uri Shkolnik + * author: Anatoly Greenblat * * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. * @@ -34,8 +34,8 @@ #include "smscoreapi.h" #include "sms-cards.h" -static int sms_dbg; -module_param_named(debug, sms_dbg, int, 0644); +int sms_debug; +module_param_named(debug, sms_debug, int, 0644); MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); struct smscore_device_notifyee_t { @@ -105,13 +105,11 @@ int smscore_led_state(struct smscore_device_t *core, int led) core->led_state = led; return core->led_state; } -EXPORT_SYMBOL_GPL(smscore_set_board_id); int smscore_get_board_id(struct smscore_device_t *core) { return core->board_id; } -EXPORT_SYMBOL_GPL(smscore_get_board_id); struct smscore_registry_entry_t { struct list_head entry; @@ -172,7 +170,6 @@ int smscore_registry_getmode(char *devpath) return default_mode; } -EXPORT_SYMBOL_GPL(smscore_registry_getmode); static enum sms_device_type_st smscore_registry_gettype(char *devpath) { @@ -264,7 +261,6 @@ int smscore_register_hotplug(hotplug_t hotplug) return rc; } -EXPORT_SYMBOL_GPL(smscore_register_hotplug); /** * unregister a client callback that called when device plugged in/unplugged @@ -293,7 +289,6 @@ void smscore_unregister_hotplug(hotplug_t hotplug) kmutex_unlock(&g_smscore_deviceslock); } -EXPORT_SYMBOL_GPL(smscore_unregister_hotplug); static void smscore_notify_clients(struct smscore_device_t *coredev) { @@ -437,7 +432,6 @@ int smscore_register_device(struct smsdevice_params_t *params, return 0; } -EXPORT_SYMBOL_GPL(smscore_register_device); /** * sets initial device mode and notifies client hotplugs that device is ready @@ -466,7 +460,6 @@ int smscore_start_device(struct smscore_device_t *coredev) return rc; } -EXPORT_SYMBOL_GPL(smscore_start_device); static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, void *buffer, size_t size, @@ -695,7 +688,6 @@ void smscore_unregister_device(struct smscore_device_t *coredev) sms_info("device %p destroyed", coredev); } -EXPORT_SYMBOL_GPL(smscore_unregister_device); static int smscore_detect_mode(struct smscore_device_t *coredev) { @@ -740,7 +732,7 @@ static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { /*DVBH*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, /*TDMB*/ - {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"}, + {"none", "tdmb_nova_12mhz.inp", "none", "none"}, /*DABIP*/ {"none", "none", "none", "none"}, /*BDA*/ @@ -887,7 +879,6 @@ int smscore_get_device_mode(struct smscore_device_t *coredev) { return coredev->mode; } -EXPORT_SYMBOL_GPL(smscore_get_device_mode); /** * find client by response id & type within the clients list. @@ -1015,7 +1006,6 @@ void smscore_onresponse(struct smscore_device_t *coredev, smscore_putbuffer(coredev, cb); } } -EXPORT_SYMBOL_GPL(smscore_onresponse); /** * return pointer to next free buffer descriptor from core pool @@ -1041,7 +1031,6 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) return cb; } -EXPORT_SYMBOL_GPL(smscore_getbuffer); /** * return buffer descriptor to a pool @@ -1056,7 +1045,6 @@ void smscore_putbuffer(struct smscore_device_t *coredev, { list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); } -EXPORT_SYMBOL_GPL(smscore_putbuffer); static int smscore_validate_client(struct smscore_device_t *coredev, struct smscore_client_t *client, @@ -1136,7 +1124,6 @@ int smscore_register_client(struct smscore_device_t *coredev, return 0; } -EXPORT_SYMBOL_GPL(smscore_register_client); /** * frees smsclient object and all subclients associated with it @@ -1167,7 +1154,6 @@ void smscore_unregister_client(struct smscore_client_t *client) spin_unlock_irqrestore(&coredev->clientslock, flags); } -EXPORT_SYMBOL_GPL(smscore_unregister_client); /** * verifies that source id is not taken by another client, @@ -1207,7 +1193,6 @@ int smsclient_sendrequest(struct smscore_client_t *client, return coredev->sendrequest_handler(coredev->context, buffer, size); } -EXPORT_SYMBOL_GPL(smsclient_sendrequest); int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, @@ -1291,12 +1276,12 @@ static int __init smscore_module_init(void) INIT_LIST_HEAD(&g_smscore_registry); kmutex_init(&g_smscore_registrylock); + /* USB Register */ + rc = smsusb_register(); + /* DVB Register */ + rc = smsdvb_register(); - - - - return rc; sms_debug("rc %d", rc); return rc; @@ -1305,10 +1290,6 @@ static int __init smscore_module_init(void) static void __exit smscore_module_exit(void) { - - - - kmutex_lock(&g_smscore_deviceslock); while (!list_empty(&g_smscore_notifyees)) { struct smscore_device_notifyee_t *notifyee = @@ -1331,12 +1312,18 @@ static void __exit smscore_module_exit(void) } kmutex_unlock(&g_smscore_registrylock); + /* DVB UnRegister */ + smsdvb_unregister(); + + /* Unregister USB */ + smsusb_unregister(); + sms_debug(""); } module_init(smscore_module_init); module_exit(smscore_module_exit); -MODULE_DESCRIPTION("Siano MDTV Core module"); -MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)"); +MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle"); +MODULE_AUTHOR("Siano Mobile Silicon,,, (doronc@siano-ms.com)"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/siano/smscoreapi.h b/trunk/drivers/media/dvb/siano/smscoreapi.h index 548de9056e8b..760e233fcbc5 100644 --- a/trunk/drivers/media/dvb/siano/smscoreapi.h +++ b/trunk/drivers/media/dvb/siano/smscoreapi.h @@ -29,13 +29,13 @@ #include #include #include -#include #include "dmxdev.h" #include "dvbdev.h" #include "dvb_demux.h" #include "dvb_frontend.h" +#include #define kmutex_init(_p_) mutex_init(_p_) #define kmutex_lock(_p_) mutex_lock(_p_) @@ -369,6 +369,27 @@ struct smscore_gpio_config { u8 outputdriving; }; +struct smsdvb_client_t { + struct list_head entry; + + struct smscore_device_t *coredev; + struct smscore_client_t *smsclient; + + struct dvb_adapter adapter; + struct dvb_demux demux; + struct dmxdev dmxdev; + struct dvb_frontend frontend; + + fe_status_t fe_status; + int fe_ber, fe_snr, fe_unc, fe_signal_strength; + + struct completion tune_done, stat_done; + + /* todo: save freq/band instead whole struct */ + struct dvb_frontend_parameters fe_params; + +}; + extern void smscore_registry_setmode(char *devpath, int mode); extern int smscore_registry_getmode(char *devpath); @@ -397,13 +418,6 @@ extern int smsclient_sendrequest(struct smscore_client_t *client, extern void smscore_onresponse(struct smscore_device_t *coredev, struct smscore_buffer_t *cb); -extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); -extern int smscore_map_common_buffer(struct smscore_device_t *coredev, - struct vm_area_struct *vma); -extern int smscore_get_fw_filename(struct smscore_device_t *coredev, - int mode, char *filename); -extern int smscore_send_fw_file(struct smscore_device_t *coredev, - u8 *ufwbuf, int size); extern struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev); @@ -419,9 +433,18 @@ int smscore_get_board_id(struct smscore_device_t *core); int smscore_led_state(struct smscore_device_t *core, int led); +/* smsdvb.c */ +int smsdvb_register(void); +void smsdvb_unregister(void); + +/* smsusb.c */ +int smsusb_register(void); +void smsusb_unregister(void); /* ------------------------------------------------------------------------ */ +extern int sms_debug; + #define DBG_INFO 1 #define DBG_ADV 2 @@ -429,7 +452,7 @@ int smscore_led_state(struct smscore_device_t *core, int led); printk(kern "%s: " fmt "\n", __func__, ##arg) #define dprintk(kern, lvl, fmt, arg...) do {\ - if (sms_dbg & lvl) \ + if (sms_debug & lvl) \ sms_printk(kern, fmt, ##arg); } while (0) #define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg) diff --git a/trunk/drivers/media/dvb/siano/smsdvb.c b/trunk/drivers/media/dvb/siano/smsdvb.c index ba080b95befb..2da953a4f4f5 100644 --- a/trunk/drivers/media/dvb/siano/smsdvb.c +++ b/trunk/drivers/media/dvb/siano/smsdvb.c @@ -1,7 +1,7 @@ /* * Driver for the Siano SMS1xxx USB dongle * - * Author: Uri Shkolni + * author: Anatoly Greenblat * * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. * @@ -27,33 +27,9 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -struct smsdvb_client_t { - struct list_head entry; - - struct smscore_device_t *coredev; - struct smscore_client_t *smsclient; - - struct dvb_adapter adapter; - struct dvb_demux demux; - struct dmxdev dmxdev; - struct dvb_frontend frontend; - - fe_status_t fe_status; - int fe_ber, fe_snr, fe_unc, fe_signal_strength; - - struct completion tune_done, stat_done; - - /* todo: save freq/band instead whole struct */ - struct dvb_frontend_parameters fe_params; -}; - static struct list_head g_smsdvb_clients; static struct mutex g_smsdvb_clientslock; -static int sms_dbg; -module_param_named(debug, sms_dbg, int, 0644); -MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); - static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) { struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; @@ -286,7 +262,6 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, struct SmsMsgHdr_ST Msg; u32 Data[3]; } Msg; - int ret; Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; Msg.Msg.msgDstId = HIF_TASK; @@ -307,24 +282,6 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, default: return -EINVAL; } - /* Disable LNA, if any. An error is returned if no LNA is present */ - ret = sms_board_lna_control(client->coredev, 0); - if (ret == 0) { - fe_status_t status; - - /* tune with LNA off at first */ - ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->tune_done); - - smsdvb_read_status(fe, &status); - - if (status & FE_HAS_LOCK) - return ret; - - /* previous tune didnt lock - enable LNA and tune again */ - sms_board_lna_control(client->coredev, 1); - } - return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->tune_done); } @@ -372,7 +329,7 @@ static void smsdvb_release(struct dvb_frontend *fe) static struct dvb_frontend_ops smsdvb_fe_ops = { .info = { - .name = "Siano Mobile Digital MDTV Receiver", + .name = "Siano Mobile Digital SMS1xxx", .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, @@ -414,7 +371,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, if (!arrival) return 0; - if (smscore_get_device_mode(coredev) != DEVICE_MODE_DVBT_BDA) { + if (smscore_get_device_mode(coredev) != 4) { sms_err("SMS Device mode is not set for " "DVB operation."); return 0; @@ -516,7 +473,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, return rc; } -int smsdvb_module_init(void) +int smsdvb_register(void) { int rc; @@ -530,7 +487,7 @@ int smsdvb_module_init(void) return rc; } -void smsdvb_module_exit(void) +void smsdvb_unregister(void) { smscore_unregister_hotplug(smsdvb_hotplug); @@ -542,10 +499,3 @@ void smsdvb_module_exit(void) kmutex_unlock(&g_smsdvb_clientslock); } - -module_init(smsdvb_module_init); -module_exit(smsdvb_module_exit); - -MODULE_DESCRIPTION("SMS DVB subsystem adaptation module"); -MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/siano/smsusb.c b/trunk/drivers/media/dvb/siano/smsusb.c index 71c65f544c07..5d7ca3417719 100644 --- a/trunk/drivers/media/dvb/siano/smsusb.c +++ b/trunk/drivers/media/dvb/siano/smsusb.c @@ -27,10 +27,6 @@ #include "smscoreapi.h" #include "sms-cards.h" -static int sms_dbg; -module_param_named(debug, sms_dbg, int, 0644); -MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); - #define USB1_BUFFER_SIZE 0x1000 #define USB2_BUFFER_SIZE 0x4000 @@ -428,7 +424,6 @@ static int smsusb_probe(struct usb_interface *intf, rc = smsusb_init_device(intf, id->driver_info); sms_info("rc %d", rc); - sms_board_load_modules(id->driver_info); return rc; } @@ -441,7 +436,7 @@ static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg) { struct smsusb_device_t *dev = (struct smsusb_device_t *)usb_get_intfdata(intf); - printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event); + printk(KERN_INFO "%s Entering status %d.\n", __func__, msg.event); smsusb_stop_streaming(dev); return 0; } @@ -453,7 +448,7 @@ static int smsusb_resume(struct usb_interface *intf) (struct smsusb_device_t *)usb_get_intfdata(intf); struct usb_device *udev = interface_to_usbdev(intf); - printk(KERN_INFO "%s: Entering.\n", __func__); + printk(KERN_INFO "%s Entering.\n", __func__); usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); @@ -468,8 +463,9 @@ static int smsusb_resume(struct usb_interface *intf) intf->cur_altsetting->desc. bInterfaceNumber, 0); if (rc < 0) { - printk(KERN_INFO "%s usb_set_interface failed, " - "rc %d\n", __func__, rc); + printk(KERN_INFO + "%s usb_set_interface failed, rc %d\n", + __func__, rc); return rc; } } @@ -478,55 +474,8 @@ static int smsusb_resume(struct usb_interface *intf) return 0; } -struct usb_device_id smsusb_id_table[] = { -#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS - { USB_DEVICE(0x187f, 0x0010), - .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, - { USB_DEVICE(0x187f, 0x0100), - .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, - { USB_DEVICE(0x187f, 0x0200), - .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A }, - { USB_DEVICE(0x187f, 0x0201), - .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, - { USB_DEVICE(0x187f, 0x0300), - .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, -#endif - { USB_DEVICE(0x2040, 0x1700), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, - { USB_DEVICE(0x2040, 0x1800), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A }, - { USB_DEVICE(0x2040, 0x1801), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B }, - { USB_DEVICE(0x2040, 0x2000), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2009), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 }, - { USB_DEVICE(0x2040, 0x200a), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2010), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2011), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2019), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x5500), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5510), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5520), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5530), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5580), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5590), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, smsusb_id_table); - static struct usb_driver smsusb_driver = { - .name = "smsusb", + .name = "sms1xxx", .probe = smsusb_probe, .disconnect = smsusb_disconnect, .id_table = smsusb_id_table, @@ -535,7 +484,7 @@ static struct usb_driver smsusb_driver = { .resume = smsusb_resume, }; -int smsusb_module_init(void) +int smsusb_register(void) { int rc = usb_register(&smsusb_driver); if (rc) @@ -546,16 +495,10 @@ int smsusb_module_init(void) return rc; } -void smsusb_module_exit(void) +void smsusb_unregister(void) { sms_debug(""); /* Regular USB Cleanup */ usb_deregister(&smsusb_driver); } -module_init(smsusb_module_init); -module_exit(smsusb_module_exit); - -MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle"); -MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/ttpci/Kconfig b/trunk/drivers/media/dvb/ttpci/Kconfig index 772990415f99..ab0bcd208c78 100644 --- a/trunk/drivers/media/dvb/ttpci/Kconfig +++ b/trunk/drivers/media/dvb/ttpci/Kconfig @@ -108,7 +108,7 @@ config DVB_BUDGET_CI select DVB_STB6100 if !DVB_FE_CUSTOMISE select DVB_LNBP21 if !DVB_FE_CUSTOMISE select DVB_TDA10023 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE select VIDEO_IR help Support for simple SAA7146 based DVB cards diff --git a/trunk/drivers/media/dvb/ttpci/av7110.c b/trunk/drivers/media/dvb/ttpci/av7110.c index 4624cee93e74..aa1ff524256e 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110.c +++ b/trunk/drivers/media/dvb/ttpci/av7110.c @@ -725,7 +725,7 @@ static int dvb_osd_ioctl(struct inode *inode, struct file *file, } -static const struct file_operations dvb_osd_fops = { +static struct file_operations dvb_osd_fops = { .owner = THIS_MODULE, .ioctl = dvb_generic_ioctl, .open = dvb_generic_open, diff --git a/trunk/drivers/media/dvb/ttpci/av7110_av.c b/trunk/drivers/media/dvb/ttpci/av7110_av.c index e4d0900d5121..bdc62acf2099 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_av.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_av.c @@ -1456,7 +1456,7 @@ static int dvb_audio_release(struct inode *inode, struct file *file) * driver registration ******************************************************************************/ -static const struct file_operations dvb_video_fops = { +static struct file_operations dvb_video_fops = { .owner = THIS_MODULE, .write = dvb_video_write, .ioctl = dvb_generic_ioctl, @@ -1474,7 +1474,7 @@ static struct dvb_device dvbdev_video = { .kernel_ioctl = dvb_video_ioctl, }; -static const struct file_operations dvb_audio_fops = { +static struct file_operations dvb_audio_fops = { .owner = THIS_MODULE, .write = dvb_audio_write, .ioctl = dvb_generic_ioctl, diff --git a/trunk/drivers/media/dvb/ttpci/av7110_ca.c b/trunk/drivers/media/dvb/ttpci/av7110_ca.c index c7a65b1544a3..261135ded481 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_ca.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_ca.c @@ -345,7 +345,7 @@ static ssize_t dvb_ca_read(struct file *file, char __user *buf, return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos); } -static const struct file_operations dvb_ca_fops = { +static struct file_operations dvb_ca_fops = { .owner = THIS_MODULE, .read = dvb_ca_read, .write = dvb_ca_write, diff --git a/trunk/drivers/media/dvb/ttpci/av7110_v4l.c b/trunk/drivers/media/dvb/ttpci/av7110_v4l.c index 2210cff738e6..c5b9c70563dc 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_v4l.c @@ -316,261 +316,253 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh) return 0; } -static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t) +static long av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; - u16 stereo_det; - s8 stereo; - - dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index); - - if (!av7110->analog_tuner_flags || t->index != 0) - return -EINVAL; + struct saa7146_dev *dev = fh->dev; + struct av7110 *av7110 = (struct av7110*) dev->ext_priv; + dprintk(4, "saa7146_dev: %p\n", dev); - memset(t, 0, sizeof(*t)); - strcpy((char *)t->name, "Television"); - - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; - t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */ - t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */ - /* FIXME: add the real signal strength here */ - t->signal = 0xffff; - t->afc = 0; - - /* FIXME: standard / stereo detection is still broken */ - msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det); - dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det); - msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det); - dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det); - stereo = (s8)(stereo_det >> 8); - if (stereo > 0x10) { - /* stereo */ - t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; - t->audmode = V4L2_TUNER_MODE_STEREO; - } else if (stereo < -0x10) { - /* bilingual */ - t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; - t->audmode = V4L2_TUNER_MODE_LANG1; - } else /* mono */ - t->rxsubchans = V4L2_TUNER_SUB_MONO; + switch (cmd) { + case VIDIOC_G_TUNER: + { + struct v4l2_tuner *t = arg; + u16 stereo_det; + s8 stereo; - return 0; -} + dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index); -static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; - u16 fm_matrix, src; - dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index); + if (!av7110->analog_tuner_flags || t->index != 0) + return -EINVAL; - if (!av7110->analog_tuner_flags || av7110->current_input != 1) - return -EINVAL; + memset(t, 0, sizeof(*t)); + strcpy((char *)t->name, "Television"); + + t->type = V4L2_TUNER_ANALOG_TV; + t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | + V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; + t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */ + t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */ + /* FIXME: add the real signal strength here */ + t->signal = 0xffff; + t->afc = 0; + + // FIXME: standard / stereo detection is still broken + msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det); + dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det); + msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det); + dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det); + stereo = (s8)(stereo_det >> 8); + if (stereo > 0x10) { + /* stereo */ + t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; + t->audmode = V4L2_TUNER_MODE_STEREO; + } + else if (stereo < -0x10) { + /* bilingual */ + t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + t->audmode = V4L2_TUNER_MODE_LANG1; + } + else /* mono */ + t->rxsubchans = V4L2_TUNER_SUB_MONO; - switch (t->audmode) { - case V4L2_TUNER_MODE_STEREO: - dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"); - fm_matrix = 0x3001; /* stereo */ - src = 0x0020; - break; - case V4L2_TUNER_MODE_LANG1_LANG2: - dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n"); - fm_matrix = 0x3000; /* bilingual */ - src = 0x0020; - break; - case V4L2_TUNER_MODE_LANG1: - dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"); - fm_matrix = 0x3000; /* mono */ - src = 0x0000; - break; - case V4L2_TUNER_MODE_LANG2: - dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"); - fm_matrix = 0x3000; /* mono */ - src = 0x0010; - break; - default: /* case V4L2_TUNER_MODE_MONO: */ - dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n"); - fm_matrix = 0x3000; /* mono */ - src = 0x0030; - break; + return 0; } - msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix); - msp_writereg(av7110, MSP_WR_DSP, 0x0008, src); - msp_writereg(av7110, MSP_WR_DSP, 0x0009, src); - msp_writereg(av7110, MSP_WR_DSP, 0x000a, src); - return 0; -} - -static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; - - dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency); - - if (!av7110->analog_tuner_flags || av7110->current_input != 1) - return -EINVAL; - - memset(f, 0, sizeof(*f)); - f->type = V4L2_TUNER_ANALOG_TV; - f->frequency = av7110->current_freq; - return 0; -} - -static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; - - dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency); - - if (!av7110->analog_tuner_flags || av7110->current_input != 1) - return -EINVAL; + case VIDIOC_S_TUNER: + { + struct v4l2_tuner *t = arg; + u16 fm_matrix, src; + dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index); - if (V4L2_TUNER_ANALOG_TV != f->type) - return -EINVAL; + if (!av7110->analog_tuner_flags || av7110->current_input != 1) + return -EINVAL; - msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); /* fast mute */ - msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0); + switch (t->audmode) { + case V4L2_TUNER_MODE_STEREO: + dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"); + fm_matrix = 0x3001; // stereo + src = 0x0020; + break; + case V4L2_TUNER_MODE_LANG1_LANG2: + dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n"); + fm_matrix = 0x3000; // bilingual + src = 0x0020; + break; + case V4L2_TUNER_MODE_LANG1: + dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"); + fm_matrix = 0x3000; // mono + src = 0x0000; + break; + case V4L2_TUNER_MODE_LANG2: + dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"); + fm_matrix = 0x3000; // mono + src = 0x0010; + break; + default: /* case V4L2_TUNER_MODE_MONO: */ + dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n"); + fm_matrix = 0x3000; // mono + src = 0x0030; + break; + } + msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix); + msp_writereg(av7110, MSP_WR_DSP, 0x0008, src); + msp_writereg(av7110, MSP_WR_DSP, 0x0009, src); + msp_writereg(av7110, MSP_WR_DSP, 0x000a, src); + return 0; + } + case VIDIOC_G_FREQUENCY: + { + struct v4l2_frequency *f = arg; - /* tune in desired frequency */ - if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) - ves1820_set_tv_freq(dev, f->frequency); - else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) - stv0297_set_tv_freq(dev, f->frequency); - av7110->current_freq = f->frequency; + dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency); - msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); /* start stereo detection */ - msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000); - msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); /* loudspeaker + headphone */ - msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); /* SCART 1 volume */ - return 0; -} + if (!av7110->analog_tuner_flags || av7110->current_input != 1) + return -EINVAL; -static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; + memset(f, 0, sizeof(*f)); + f->type = V4L2_TUNER_ANALOG_TV; + f->frequency = av7110->current_freq; + return 0; + } + case VIDIOC_S_FREQUENCY: + { + struct v4l2_frequency *f = arg; - dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index); + dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency); - if (av7110->analog_tuner_flags) { - if (i->index < 0 || i->index >= 4) + if (!av7110->analog_tuner_flags || av7110->current_input != 1) return -EINVAL; - } else { - if (i->index != 0) + + if (V4L2_TUNER_ANALOG_TV != f->type) return -EINVAL; - } - memcpy(i, &inputs[i->index], sizeof(struct v4l2_input)); + msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute + msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0); - return 0; -} + /* tune in desired frequency */ + if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) { + ves1820_set_tv_freq(dev, f->frequency); + } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { + stv0297_set_tv_freq(dev, f->frequency); + } + av7110->current_freq = f->frequency; -static int vidioc_g_input(struct file *file, void *fh, unsigned int *input) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; + msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection + msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000); + msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone + msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume + return 0; + } + case VIDIOC_ENUMINPUT: + { + struct v4l2_input *i = arg; - *input = av7110->current_input; - dprintk(2, "VIDIOC_G_INPUT: %d\n", *input); - return 0; -} + dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index); -static int vidioc_s_input(struct file *file, void *fh, unsigned int input) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; + if (av7110->analog_tuner_flags) { + if (i->index < 0 || i->index >= 4) + return -EINVAL; + } else { + if (i->index != 0) + return -EINVAL; + } - dprintk(2, "VIDIOC_S_INPUT: %d\n", input); + memcpy(i, &inputs[i->index], sizeof(struct v4l2_input)); - if (!av7110->analog_tuner_flags) return 0; + } + case VIDIOC_G_INPUT: + { + int *input = (int *)arg; + *input = av7110->current_input; + dprintk(2, "VIDIOC_G_INPUT: %d\n", *input); + return 0; + } + case VIDIOC_S_INPUT: + { + int input = *(int *)arg; - if (input < 0 || input >= 4) - return -EINVAL; + dprintk(2, "VIDIOC_S_INPUT: %d\n", input); - av7110->current_input = input; - return av7110_dvb_c_switch(fh); -} + if (!av7110->analog_tuner_flags) + return 0; -static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) -{ - dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index); - if (a->index != 0) - return -EINVAL; - memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio)); - return 0; -} - -static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a) -{ - dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); - return 0; -} - -static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, - struct v4l2_sliced_vbi_cap *cap) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; + if (input < 0 || input >= 4) + return -EINVAL; - dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n"); - if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) - return -EINVAL; - if (FW_VERSION(av7110->arm_app) >= 0x2623) { - cap->service_set = V4L2_SLICED_WSS_625; - cap->service_lines[0][23] = V4L2_SLICED_WSS_625; + av7110->current_input = input; + return av7110_dvb_c_switch(fh); } - return 0; -} - -static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh, - struct v4l2_format *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; + case VIDIOC_G_AUDIO: + { + struct v4l2_audio *a = arg; - dprintk(2, "VIDIOC_G_FMT:\n"); - if (FW_VERSION(av7110->arm_app) < 0x2623) - return -EINVAL; - memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); - if (av7110->wssMode) { - f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; - f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; - f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data); + dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index); + if (a->index != 0) + return -EINVAL; + memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio)); + break; } - return 0; -} - -static int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh, - struct v4l2_format *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; - - dprintk(2, "VIDIOC_S_FMT\n"); - if (FW_VERSION(av7110->arm_app) < 0x2623) - return -EINVAL; - if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 && - f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) { - memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced)); - /* WSS controlled by firmware */ - av7110->wssMode = 0; - av7110->wssData = 0; - return av7110_fw_cmd(av7110, COMTYPE_ENCODER, - SetWSSConfig, 1, 0); - } else { - memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced)); - f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; - f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; - f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data); - /* WSS controlled by userspace */ - av7110->wssMode = 1; - av7110->wssData = 0; + case VIDIOC_S_AUDIO: + { + struct v4l2_audio *a = arg; + dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); + break; + } + case VIDIOC_G_SLICED_VBI_CAP: + { + struct v4l2_sliced_vbi_cap *cap = arg; + dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n"); + memset(cap, 0, sizeof *cap); + if (FW_VERSION(av7110->arm_app) >= 0x2623) { + cap->service_set = V4L2_SLICED_WSS_625; + cap->service_lines[0][23] = V4L2_SLICED_WSS_625; + } + break; + } + case VIDIOC_G_FMT: + { + struct v4l2_format *f = arg; + dprintk(2, "VIDIOC_G_FMT:\n"); + if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT || + FW_VERSION(av7110->arm_app) < 0x2623) + return -EAGAIN; /* handled by core driver */ + memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); + if (av7110->wssMode) { + f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; + f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; + f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data); + } + break; + } + case VIDIOC_S_FMT: + { + struct v4l2_format *f = arg; + dprintk(2, "VIDIOC_S_FMT\n"); + if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT || + FW_VERSION(av7110->arm_app) < 0x2623) + return -EAGAIN; /* handled by core driver */ + if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 && + f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) { + memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); + /* WSS controlled by firmware */ + av7110->wssMode = 0; + av7110->wssData = 0; + return av7110_fw_cmd(av7110, COMTYPE_ENCODER, + SetWSSConfig, 1, 0); + } else { + memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); + f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; + f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; + f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data); + /* WSS controlled by userspace */ + av7110->wssMode = 1; + av7110->wssData = 0; + } + break; + } + default: + printk("no such ioctl\n"); + return -ENOIOCTLCMD; } return 0; } @@ -617,6 +609,22 @@ static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size * INITIALIZATION ****************************************************************************/ +static struct saa7146_extension_ioctls ioctls[] = { + { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE }, + { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE }, + { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE }, + { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE }, + { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, + { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, + { VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE }, + { VIDIOC_G_FMT, SAA7146_BEFORE }, + { VIDIOC_S_FMT, SAA7146_BEFORE }, + { 0, 0 } +}; + static u8 saa7113_init_regs[] = { 0x02, 0xd0, 0x03, 0x23, @@ -780,34 +788,20 @@ int av7110_init_analog_module(struct av7110 *av7110) int av7110_init_v4l(struct av7110 *av7110) { struct saa7146_dev* dev = av7110->dev; - struct saa7146_ext_vv *vv_data; int ret; /* special case DVB-C: these cards have an analog tuner plus need some special handling, so we have separate saa7146_ext_vv data for these... */ if (av7110->analog_tuner_flags) - vv_data = &av7110_vv_data_c; + ret = saa7146_vv_init(dev, &av7110_vv_data_c); else - vv_data = &av7110_vv_data_st; - ret = saa7146_vv_init(dev, vv_data); + ret = saa7146_vv_init(dev, &av7110_vv_data_st); if (ret) { ERR(("cannot init capture device. skipping.\n")); return -ENODEV; } - vv_data->ops.vidioc_enum_input = vidioc_enum_input; - vv_data->ops.vidioc_g_input = vidioc_g_input; - vv_data->ops.vidioc_s_input = vidioc_s_input; - vv_data->ops.vidioc_g_tuner = vidioc_g_tuner; - vv_data->ops.vidioc_s_tuner = vidioc_s_tuner; - vv_data->ops.vidioc_g_frequency = vidioc_g_frequency; - vv_data->ops.vidioc_s_frequency = vidioc_s_frequency; - vv_data->ops.vidioc_g_audio = vidioc_g_audio; - vv_data->ops.vidioc_s_audio = vidioc_s_audio; - vv_data->ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap; - vv_data->ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out; - vv_data->ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out; if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) { ERR(("cannot register capture device. skipping.\n")); @@ -906,6 +900,9 @@ static struct saa7146_ext_vv av7110_vv_data_st = { .num_stds = ARRAY_SIZE(standard), .std_callback = &std_callback, + .ioctls = &ioctls[0], + .ioctl = av7110_ioctl, + .vbi_fops.open = av7110_vbi_reset, .vbi_fops.release = av7110_vbi_reset, .vbi_fops.write = av7110_vbi_write, @@ -921,6 +918,9 @@ static struct saa7146_ext_vv av7110_vv_data_c = { .num_stds = ARRAY_SIZE(standard), .std_callback = &std_callback, + .ioctls = &ioctls[0], + .ioctl = av7110_ioctl, + .vbi_fops.open = av7110_vbi_reset, .vbi_fops.release = av7110_vbi_reset, .vbi_fops.write = av7110_vbi_write, diff --git a/trunk/drivers/media/dvb/ttpci/budget-av.c b/trunk/drivers/media/dvb/ttpci/budget-av.c index 855fe74b640b..4182121d7e5d 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-av.c +++ b/trunk/drivers/media/dvb/ttpci/budget-av.c @@ -1404,41 +1404,6 @@ static int budget_av_detach(struct saa7146_dev *dev) return err; } -#define KNC1_INPUTS 2 -static struct v4l2_input knc1_inputs[KNC1_INPUTS] = { - {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0}, - {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0}, -}; - -static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) -{ - dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index); - if (i->index < 0 || i->index >= KNC1_INPUTS) - return -EINVAL; - memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input)); - return 0; -} - -static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct budget_av *budget_av = (struct budget_av *)dev->ext_priv; - - *i = budget_av->cur_input; - - dprintk(1, "VIDIOC_G_INPUT %d.\n", *i); - return 0; -} - -static int vidioc_s_input(struct file *file, void *fh, unsigned int input) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct budget_av *budget_av = (struct budget_av *)dev->ext_priv; - - dprintk(1, "VIDIOC_S_INPUT %d.\n", input); - return saa7113_setinput(budget_av, input); -} - static struct saa7146_ext_vv vv_data; static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) @@ -1477,9 +1442,6 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio ERR(("cannot init vv subsystem.\n")); return err; } - vv_data.ops.vidioc_enum_input = vidioc_enum_input; - vv_data.ops.vidioc_g_input = vidioc_g_input; - vv_data.ops.vidioc_s_input = vidioc_s_input; if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) { /* fixme: proper cleanup here */ @@ -1518,6 +1480,54 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio return 0; } +#define KNC1_INPUTS 2 +static struct v4l2_input knc1_inputs[KNC1_INPUTS] = { + {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0}, + {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0}, +}; + +static struct saa7146_extension_ioctls ioctls[] = { + {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE}, + {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE}, + {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE}, + {0, 0} +}; + +static long av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) +{ + struct saa7146_dev *dev = fh->dev; + struct budget_av *budget_av = (struct budget_av *) dev->ext_priv; + + switch (cmd) { + case VIDIOC_ENUMINPUT:{ + struct v4l2_input *i = arg; + + dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index); + if (i->index < 0 || i->index >= KNC1_INPUTS) { + return -EINVAL; + } + memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input)); + return 0; + } + case VIDIOC_G_INPUT:{ + int *input = (int *) arg; + + *input = budget_av->cur_input; + + dprintk(1, "VIDIOC_G_INPUT %d.\n", *input); + return 0; + } + case VIDIOC_S_INPUT:{ + int input = *(int *) arg; + dprintk(1, "VIDIOC_S_INPUT %d.\n", input); + return saa7113_setinput(budget_av, input); + } + default: + return -ENOIOCTLCMD; + } + return 0; +} + static struct saa7146_standard standard[] = { {.name = "PAL",.id = V4L2_STD_PAL, .v_offset = 0x17,.v_field = 288, @@ -1536,6 +1546,8 @@ static struct saa7146_ext_vv vv_data = { .flags = 0, .stds = &standard[0], .num_stds = ARRAY_SIZE(standard), + .ioctls = &ioctls[0], + .ioctl = av_ioctl, }; static struct saa7146_extension budget_extension; diff --git a/trunk/drivers/media/dvb/ttpci/budget-ci.c b/trunk/drivers/media/dvb/ttpci/budget-ci.c index 371a71616810..bcbc5d41a0fe 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-ci.c +++ b/trunk/drivers/media/dvb/ttpci/budget-ci.c @@ -1076,10 +1076,6 @@ static struct tda10023_config tda10023_config = { .deltaf = 0xa511, }; -static struct tda827x_config tda827x_config = { - .config = 0, -}; - /* TT S2-3200 DVB-S (STB0899) Inittab */ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = { @@ -1418,7 +1414,7 @@ static void frontend_init(struct budget_ci *budget_ci) case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */ budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48); if (budget_ci->budget.dvb_frontend) { - if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) { + if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, NULL) == NULL) { printk(KERN_ERR "%s: No tda827x found!\n", __func__); dvb_frontend_detach(budget_ci->budget.dvb_frontend); budget_ci->budget.dvb_frontend = NULL; diff --git a/trunk/drivers/media/radio/dsbr100.c b/trunk/drivers/media/radio/dsbr100.c index cc54ed4efc48..2014ebc4e984 100644 --- a/trunk/drivers/media/radio/dsbr100.c +++ b/trunk/drivers/media/radio/dsbr100.c @@ -390,11 +390,9 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf) static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *v) { - struct dsbr100_device *radio = video_drvdata(file); - strlcpy(v->driver, "dsbr100", sizeof(v->driver)); strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card)); - usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info)); + sprintf(v->bus_info, "USB"); v->version = RADIO_VERSION; v->capabilities = V4L2_CAP_TUNER; return 0; @@ -452,10 +450,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, if (radio->removed) return -EIO; - mutex_lock(&radio->lock); radio->curfreq = f->frequency; - mutex_unlock(&radio->lock); - retval = dsbr100_setfreq(radio, radio->curfreq); if (retval < 0) dev_warn(&radio->usbdev->dev, "Set frequency failed\n"); @@ -606,10 +601,7 @@ static int usb_dsbr100_close(struct file *file) if (!radio) return -ENODEV; - mutex_lock(&radio->lock); radio->users = 0; - mutex_unlock(&radio->lock); - if (!radio->removed) { retval = dsbr100_stop(radio); if (retval < 0) { diff --git a/trunk/drivers/media/radio/radio-aimslab.c b/trunk/drivers/media/radio/radio-aimslab.c index ac82e33cb6fc..bfa13b8b3043 100644 --- a/trunk/drivers/media/radio/radio-aimslab.c +++ b/trunk/drivers/media/radio/radio-aimslab.c @@ -32,15 +32,14 @@ #include /* Initdata */ #include /* request_region */ #include /* udelay */ +#include /* outb, outb_p */ +#include /* copy to/from user */ #include /* kernel radio structs */ -#include /* for KERNEL_VERSION MACRO */ -#include /* outb, outb_p */ -#include +#include #include -MODULE_AUTHOR("M.Kirkwood"); -MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card."); -MODULE_LICENSE("GPL"); +#include /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,0,2) #ifndef CONFIG_RADIO_RTRACK_PORT #define CONFIG_RADIO_RTRACK_PORT -1 @@ -48,95 +47,86 @@ MODULE_LICENSE("GPL"); static int io = CONFIG_RADIO_RTRACK_PORT; static int radio_nr = -1; +static struct mutex lock; -module_param(io, int, 0); -MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)"); -module_param(radio_nr, int, 0); - -#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) - -struct rtrack +struct rt_device { - struct v4l2_device v4l2_dev; - struct video_device vdev; + unsigned long in_use; int port; int curvol; unsigned long curfreq; int muted; - int io; - struct mutex lock; }; -static struct rtrack rtrack_card; /* local things */ static void sleep_delay(long n) { /* Sleep nicely for 'n' uS */ - int d = n / msecs_to_jiffies(1000); - if (!d) + int d=n/msecs_to_jiffies(1000); + if(!d) udelay(n); else msleep(jiffies_to_msecs(d)); } -static void rt_decvol(struct rtrack *rt) +static void rt_decvol(void) { - outb(0x58, rt->io); /* volume down + sigstr + on */ + outb(0x58, io); /* volume down + sigstr + on */ sleep_delay(100000); - outb(0xd8, rt->io); /* volume steady + sigstr + on */ + outb(0xd8, io); /* volume steady + sigstr + on */ } -static void rt_incvol(struct rtrack *rt) +static void rt_incvol(void) { - outb(0x98, rt->io); /* volume up + sigstr + on */ + outb(0x98, io); /* volume up + sigstr + on */ sleep_delay(100000); - outb(0xd8, rt->io); /* volume steady + sigstr + on */ + outb(0xd8, io); /* volume steady + sigstr + on */ } -static void rt_mute(struct rtrack *rt) +static void rt_mute(struct rt_device *dev) { - rt->muted = 1; - mutex_lock(&rt->lock); - outb(0xd0, rt->io); /* volume steady, off */ - mutex_unlock(&rt->lock); + dev->muted = 1; + mutex_lock(&lock); + outb(0xd0, io); /* volume steady, off */ + mutex_unlock(&lock); } -static int rt_setvol(struct rtrack *rt, int vol) +static int rt_setvol(struct rt_device *dev, int vol) { int i; - mutex_lock(&rt->lock); + mutex_lock(&lock); - if (vol == rt->curvol) { /* requested volume = current */ - if (rt->muted) { /* user is unmuting the card */ - rt->muted = 0; - outb(0xd8, rt->io); /* enable card */ + if(vol == dev->curvol) { /* requested volume = current */ + if (dev->muted) { /* user is unmuting the card */ + dev->muted = 0; + outb (0xd8, io); /* enable card */ } - mutex_unlock(&rt->lock); + mutex_unlock(&lock); return 0; } - if (vol == 0) { /* volume = 0 means mute the card */ - outb(0x48, rt->io); /* volume down but still "on" */ + if(vol == 0) { /* volume = 0 means mute the card */ + outb(0x48, io); /* volume down but still "on" */ sleep_delay(2000000); /* make sure it's totally down */ - outb(0xd0, rt->io); /* volume steady, off */ - rt->curvol = 0; /* track the volume state! */ - mutex_unlock(&rt->lock); + outb(0xd0, io); /* volume steady, off */ + dev->curvol = 0; /* track the volume state! */ + mutex_unlock(&lock); return 0; } - rt->muted = 0; - if (vol > rt->curvol) - for (i = rt->curvol; i < vol; i++) - rt_incvol(rt); + dev->muted = 0; + if(vol > dev->curvol) + for(i = dev->curvol; i < vol; i++) + rt_incvol(); else - for (i = rt->curvol; i > vol; i--) - rt_decvol(rt); + for(i = dev->curvol; i > vol; i--) + rt_decvol(); - rt->curvol = vol; - mutex_unlock(&rt->lock); + dev->curvol = vol; + mutex_unlock(&lock); return 0; } @@ -145,137 +135,155 @@ static int rt_setvol(struct rtrack *rt, int vol) * and bit 4 (+16) is to keep the signal strength meter enabled */ -static void send_0_byte(struct rtrack *rt) +static void send_0_byte(int port, struct rt_device *dev) { - if (rt->curvol == 0 || rt->muted) { - outb_p(128+64+16+ 1, rt->io); /* wr-enable + data low */ - outb_p(128+64+16+2+1, rt->io); /* clock */ + if ((dev->curvol == 0) || (dev->muted)) { + outb_p(128+64+16+ 1, port); /* wr-enable + data low */ + outb_p(128+64+16+2+1, port); /* clock */ } else { - outb_p(128+64+16+8+ 1, rt->io); /* on + wr-enable + data low */ - outb_p(128+64+16+8+2+1, rt->io); /* clock */ + outb_p(128+64+16+8+ 1, port); /* on + wr-enable + data low */ + outb_p(128+64+16+8+2+1, port); /* clock */ } sleep_delay(1000); } -static void send_1_byte(struct rtrack *rt) +static void send_1_byte(int port, struct rt_device *dev) { - if (rt->curvol == 0 || rt->muted) { - outb_p(128+64+16+4 +1, rt->io); /* wr-enable+data high */ - outb_p(128+64+16+4+2+1, rt->io); /* clock */ + if ((dev->curvol == 0) || (dev->muted)) { + outb_p(128+64+16+4 +1, port); /* wr-enable+data high */ + outb_p(128+64+16+4+2+1, port); /* clock */ } else { - outb_p(128+64+16+8+4 +1, rt->io); /* on+wr-enable+data high */ - outb_p(128+64+16+8+4+2+1, rt->io); /* clock */ + outb_p(128+64+16+8+4 +1, port); /* on+wr-enable+data high */ + outb_p(128+64+16+8+4+2+1, port); /* clock */ } sleep_delay(1000); } -static int rt_setfreq(struct rtrack *rt, unsigned long freq) +static int rt_setfreq(struct rt_device *dev, unsigned long freq) { int i; - mutex_lock(&rt->lock); /* Stop other ops interfering */ - - rt->curfreq = freq; + /* adapted from radio-aztech.c */ /* now uses VIDEO_TUNER_LOW for fine tuning */ freq += 171200; /* Add 10.7 MHz IF */ freq /= 800; /* Convert to 50 kHz units */ - send_0_byte(rt); /* 0: LSB of frequency */ + mutex_lock(&lock); /* Stop other ops interfering */ + + send_0_byte (io, dev); /* 0: LSB of frequency */ for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ if (freq & (1 << i)) - send_1_byte(rt); + send_1_byte (io, dev); else - send_0_byte(rt); + send_0_byte (io, dev); - send_0_byte(rt); /* 14: test bit - always 0 */ - send_0_byte(rt); /* 15: test bit - always 0 */ + send_0_byte (io, dev); /* 14: test bit - always 0 */ + send_0_byte (io, dev); /* 15: test bit - always 0 */ - send_0_byte(rt); /* 16: band data 0 - always 0 */ - send_0_byte(rt); /* 17: band data 1 - always 0 */ - send_0_byte(rt); /* 18: band data 2 - always 0 */ - send_0_byte(rt); /* 19: time base - always 0 */ + send_0_byte (io, dev); /* 16: band data 0 - always 0 */ + send_0_byte (io, dev); /* 17: band data 1 - always 0 */ + send_0_byte (io, dev); /* 18: band data 2 - always 0 */ + send_0_byte (io, dev); /* 19: time base - always 0 */ - send_0_byte(rt); /* 20: spacing (0 = 25 kHz) */ - send_1_byte(rt); /* 21: spacing (1 = 25 kHz) */ - send_0_byte(rt); /* 22: spacing (0 = 25 kHz) */ - send_1_byte(rt); /* 23: AM/FM (FM = 1, always) */ + send_0_byte (io, dev); /* 20: spacing (0 = 25 kHz) */ + send_1_byte (io, dev); /* 21: spacing (1 = 25 kHz) */ + send_0_byte (io, dev); /* 22: spacing (0 = 25 kHz) */ + send_1_byte (io, dev); /* 23: AM/FM (FM = 1, always) */ - if (rt->curvol == 0 || rt->muted) - outb(0xd0, rt->io); /* volume steady + sigstr */ + if ((dev->curvol == 0) || (dev->muted)) + outb (0xd0, io); /* volume steady + sigstr */ else - outb(0xd8, rt->io); /* volume steady + sigstr + on */ + outb (0xd8, io); /* volume steady + sigstr + on */ - mutex_unlock(&rt->lock); + mutex_unlock(&lock); return 0; } -static int rt_getsigstr(struct rtrack *rt) +static int rt_getsigstr(struct rt_device *dev) { - int sig = 1; - - mutex_lock(&rt->lock); - if (inb(rt->io) & 2) /* bit set = no signal present */ - sig = 0; - mutex_unlock(&rt->lock); - return sig; + if (inb(io) & 2) /* bit set = no signal present */ + return 0; + return 1; /* signal present */ } +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + },{ + .id = V4L2_CID_AUDIO_VOLUME, + .name = "Volume", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; + static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *v) { strlcpy(v->driver, "radio-aimslab", sizeof(v->driver)); strlcpy(v->card, "RadioTrack", sizeof(v->card)); - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); + sprintf(v->bus_info, "ISA"); v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->capabilities = V4L2_CAP_TUNER; return 0; } static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct rtrack *rt = video_drvdata(file); + struct rt_device *rt = video_drvdata(file); if (v->index > 0) return -EINVAL; - strlcpy(v->name, "FM", sizeof(v->name)); + strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; - v->rangelow = 87 * 16000; - v->rangehigh = 108 * 16000; + v->rangelow = (87*16000); + v->rangehigh = (108*16000); v->rxsubchans = V4L2_TUNER_SUB_MONO; v->capability = V4L2_TUNER_CAP_LOW; v->audmode = V4L2_TUNER_MODE_MONO; - v->signal = 0xffff * rt_getsigstr(rt); + v->signal = 0xffff*rt_getsigstr(rt); return 0; } static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - return v->index ? -EINVAL : 0; + if (v->index > 0) + return -EINVAL; + return 0; } static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct rtrack *rt = video_drvdata(file); + struct rt_device *rt = video_drvdata(file); - rt_setfreq(rt, f->frequency); + rt->curfreq = f->frequency; + rt_setfreq(rt, rt->curfreq); return 0; } static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct rtrack *rt = video_drvdata(file); + struct rt_device *rt = video_drvdata(file); f->type = V4L2_TUNER_RADIO; f->frequency = rt->curfreq; @@ -285,11 +293,14 @@ static int vidioc_g_frequency(struct file *file, void *priv, static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff); + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); + return 0; + } } return -EINVAL; } @@ -297,14 +308,14 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct rtrack *rt = video_drvdata(file); + struct rt_device *rt = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: ctrl->value = rt->muted; return 0; case V4L2_CID_AUDIO_VOLUME: - ctrl->value = rt->curvol; + ctrl->value = rt->curvol * 6554; return 0; } return -EINVAL; @@ -313,62 +324,71 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct rtrack *rt = video_drvdata(file); + struct rt_device *rt = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: if (ctrl->value) rt_mute(rt); else - rt_setvol(rt, rt->curvol); + rt_setvol(rt,rt->curvol); return 0; case V4L2_CID_AUDIO_VOLUME: - rt_setvol(rt, ctrl->value); + rt_setvol(rt,ctrl->value); return 0; } return -EINVAL; } -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +static int vidioc_g_audio (struct file *file, void *priv, + struct v4l2_audio *a) { - *i = 0; + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; return 0; } -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { - return i ? -EINVAL : 0; + *i = 0; + return 0; } -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; + if (i != 0) + return -EINVAL; return 0; } static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) { - return a->index ? -EINVAL : 0; + if (a->index != 0) + return -EINVAL; + return 0; } -static int rtrack_open(struct file *file) +static struct rt_device rtrack_unit; + +static int rtrack_exclusive_open(struct file *file) { - return 0; + return test_and_set_bit(0, &rtrack_unit.in_use) ? -EBUSY : 0; } -static int rtrack_release(struct file *file) +static int rtrack_exclusive_release(struct file *file) { + clear_bit(0, &rtrack_unit.in_use); return 0; } static const struct v4l2_file_operations rtrack_fops = { .owner = THIS_MODULE, - .open = rtrack_open, - .release = rtrack_release, + .open = rtrack_exclusive_open, + .release = rtrack_exclusive_release, .ioctl = video_ioctl2, }; @@ -387,69 +407,64 @@ static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device rtrack_radio = { + .name = "RadioTrack radio", + .fops = &rtrack_fops, + .ioctl_ops = &rtrack_ioctl_ops, + .release = video_device_release_empty, +}; + static int __init rtrack_init(void) { - struct rtrack *rt = &rtrack_card; - struct v4l2_device *v4l2_dev = &rt->v4l2_dev; - int res; - - strlcpy(v4l2_dev->name, "rtrack", sizeof(v4l2_dev->name)); - rt->io = io; - - if (rt->io == -1) { - v4l2_err(v4l2_dev, "you must set an I/O address with io=0x20f or 0x30f\n"); + if(io==-1) + { + printk(KERN_ERR "You must set an I/O address with io=0x???\n"); return -EINVAL; } - if (!request_region(rt->io, 2, "rtrack")) { - v4l2_err(v4l2_dev, "port 0x%x already in use\n", rt->io); + if (!request_region(io, 2, "rtrack")) + { + printk(KERN_ERR "rtrack: port 0x%x already in use\n", io); return -EBUSY; } - res = v4l2_device_register(NULL, v4l2_dev); - if (res < 0) { - release_region(rt->io, 2); - v4l2_err(v4l2_dev, "could not register v4l2_device\n"); - return res; - } + video_set_drvdata(&rtrack_radio, &rtrack_unit); - strlcpy(rt->vdev.name, v4l2_dev->name, sizeof(rt->vdev.name)); - rt->vdev.v4l2_dev = v4l2_dev; - rt->vdev.fops = &rtrack_fops; - rt->vdev.ioctl_ops = &rtrack_ioctl_ops; - rt->vdev.release = video_device_release_empty; - video_set_drvdata(&rt->vdev, rt); - - if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { - v4l2_device_unregister(&rt->v4l2_dev); - release_region(rt->io, 2); + if (video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr) < 0) { + release_region(io, 2); return -EINVAL; } - v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); + printk(KERN_INFO "AIMSlab RadioTrack/RadioReveal card driver.\n"); /* Set up the I/O locking */ - mutex_init(&rt->lock); + mutex_init(&lock); /* mute card - prevents noisy bootups */ /* this ensures that the volume is all the way down */ - outb(0x48, rt->io); /* volume down but still "on" */ + outb(0x48, io); /* volume down but still "on" */ sleep_delay(2000000); /* make sure it's totally down */ - outb(0xc0, rt->io); /* steady volume, mute card */ + outb(0xc0, io); /* steady volume, mute card */ + rtrack_unit.curvol = 0; return 0; } -static void __exit rtrack_exit(void) -{ - struct rtrack *rt = &rtrack_card; +MODULE_AUTHOR("M.Kirkwood"); +MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card."); +MODULE_LICENSE("GPL"); - video_unregister_device(&rt->vdev); - v4l2_device_unregister(&rt->v4l2_dev); - release_region(rt->io, 2); +module_param(io, int, 0); +MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)"); +module_param(radio_nr, int, 0); + +static void __exit cleanup_rtrack_module(void) +{ + video_unregister_device(&rtrack_radio); + release_region(io,2); } module_init(rtrack_init); -module_exit(rtrack_exit); +module_exit(cleanup_rtrack_module); diff --git a/trunk/drivers/media/radio/radio-aztech.c b/trunk/drivers/media/radio/radio-aztech.c index 49299f7fd834..5604e881e96c 100644 --- a/trunk/drivers/media/radio/radio-aztech.c +++ b/trunk/drivers/media/radio/radio-aztech.c @@ -29,15 +29,33 @@ #include /* Initdata */ #include /* request_region */ #include /* udelay */ +#include /* outb, outb_p */ +#include /* copy to/from user */ #include /* kernel radio structs */ -#include /* for KERNEL_VERSION MACRO */ -#include /* outb, outb_p */ -#include +#include #include -MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); -MODULE_DESCRIPTION("A driver for the Aztech radio card."); -MODULE_LICENSE("GPL"); +#include /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,0,2) + +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + },{ + .id = V4L2_CID_AUDIO_VOLUME, + .name = "Volume", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ @@ -48,64 +66,55 @@ MODULE_LICENSE("GPL"); static int io = CONFIG_RADIO_AZTECH_PORT; static int radio_nr = -1; static int radio_wait_time = 1000; +static struct mutex lock; -module_param(io, int, 0); -module_param(radio_nr, int, 0); -MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)"); - -#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) - -struct aztech +struct az_device { - struct v4l2_device v4l2_dev; - struct video_device vdev; - int io; + unsigned long in_use; int curvol; unsigned long curfreq; int stereo; - struct mutex lock; }; -static struct aztech aztech_card; - static int volconvert(int level) { - level >>= 14; /* Map 16bits down to 2 bit */ - level &= 3; + level>>=14; /* Map 16bits down to 2 bit */ + level&=3; /* convert to card-friendly values */ - switch (level) { - case 0: - return 0; - case 1: - return 1; - case 2: - return 4; - case 3: - return 5; + switch (level) + { + case 0: + return 0; + case 1: + return 1; + case 2: + return 4; + case 3: + return 5; } return 0; /* Quieten gcc */ } -static void send_0_byte(struct aztech *az) +static void send_0_byte (struct az_device *dev) { udelay(radio_wait_time); - outb_p(2 + volconvert(az->curvol), az->io); - outb_p(64 + 2 + volconvert(az->curvol), az->io); + outb_p(2+volconvert(dev->curvol), io); + outb_p(64+2+volconvert(dev->curvol), io); } -static void send_1_byte(struct aztech *az) +static void send_1_byte (struct az_device *dev) { udelay (radio_wait_time); - outb_p(128 + 2 + volconvert(az->curvol), az->io); - outb_p(128 + 64 + 2 + volconvert(az->curvol), az->io); + outb_p(128+2+volconvert(dev->curvol), io); + outb_p(128+64+2+volconvert(dev->curvol), io); } -static int az_setvol(struct aztech *az, int vol) +static int az_setvol(struct az_device *dev, int vol) { - mutex_lock(&az->lock); - outb(volconvert(vol), az->io); - mutex_unlock(&az->lock); + mutex_lock(&lock); + outb (volconvert(vol), io); + mutex_unlock(&lock); return 0; } @@ -117,221 +126,233 @@ static int az_setvol(struct aztech *az, int vol) * */ -static int az_getsigstr(struct aztech *az) +static int az_getsigstr(struct az_device *dev) { - int sig = 1; - - mutex_lock(&az->lock); - if (inb(az->io) & 2) /* bit set = no signal present */ - sig = 0; - mutex_unlock(&az->lock); - return sig; + if (inb(io) & 2) /* bit set = no signal present */ + return 0; + return 1; /* signal present */ } -static int az_getstereo(struct aztech *az) +static int az_getstereo(struct az_device *dev) { - int stereo = 1; - - mutex_lock(&az->lock); - if (inb(az->io) & 1) /* bit set = mono */ - stereo = 0; - mutex_unlock(&az->lock); - return stereo; + if (inb(io) & 1) /* bit set = mono */ + return 0; + return 1; /* stereo */ } -static int az_setfreq(struct aztech *az, unsigned long frequency) +static int az_setfreq(struct az_device *dev, unsigned long frequency) { int i; - mutex_lock(&az->lock); - - az->curfreq = frequency; frequency += 171200; /* Add 10.7 MHz IF */ frequency /= 800; /* Convert to 50 kHz units */ - send_0_byte(az); /* 0: LSB of frequency */ + mutex_lock(&lock); + + send_0_byte (dev); /* 0: LSB of frequency */ for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ if (frequency & (1 << i)) - send_1_byte(az); + send_1_byte (dev); else - send_0_byte(az); + send_0_byte (dev); - send_0_byte(az); /* 14: test bit - always 0 */ - send_0_byte(az); /* 15: test bit - always 0 */ - send_0_byte(az); /* 16: band data 0 - always 0 */ - if (az->stereo) /* 17: stereo (1 to enable) */ - send_1_byte(az); + send_0_byte (dev); /* 14: test bit - always 0 */ + send_0_byte (dev); /* 15: test bit - always 0 */ + send_0_byte (dev); /* 16: band data 0 - always 0 */ + if (dev->stereo) /* 17: stereo (1 to enable) */ + send_1_byte (dev); else - send_0_byte(az); + send_0_byte (dev); - send_1_byte(az); /* 18: band data 1 - unknown */ - send_0_byte(az); /* 19: time base - always 0 */ - send_0_byte(az); /* 20: spacing (0 = 25 kHz) */ - send_1_byte(az); /* 21: spacing (1 = 25 kHz) */ - send_0_byte(az); /* 22: spacing (0 = 25 kHz) */ - send_1_byte(az); /* 23: AM/FM (FM = 1, always) */ + send_1_byte (dev); /* 18: band data 1 - unknown */ + send_0_byte (dev); /* 19: time base - always 0 */ + send_0_byte (dev); /* 20: spacing (0 = 25 kHz) */ + send_1_byte (dev); /* 21: spacing (1 = 25 kHz) */ + send_0_byte (dev); /* 22: spacing (0 = 25 kHz) */ + send_1_byte (dev); /* 23: AM/FM (FM = 1, always) */ /* latch frequency */ - udelay(radio_wait_time); - outb_p(128 + 64 + volconvert(az->curvol), az->io); + udelay (radio_wait_time); + outb_p(128+64+volconvert(dev->curvol), io); - mutex_unlock(&az->lock); + mutex_unlock(&lock); return 0; } -static int vidioc_querycap(struct file *file, void *priv, +static int vidioc_querycap (struct file *file, void *priv, struct v4l2_capability *v) { - strlcpy(v->driver, "radio-aztech", sizeof(v->driver)); - strlcpy(v->card, "Aztech Radio", sizeof(v->card)); - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); + strlcpy(v->driver, "radio-aztech", sizeof (v->driver)); + strlcpy(v->card, "Aztech Radio", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->capabilities = V4L2_CAP_TUNER; return 0; } -static int vidioc_g_tuner(struct file *file, void *priv, +static int vidioc_g_tuner (struct file *file, void *priv, struct v4l2_tuner *v) { - struct aztech *az = video_drvdata(file); + struct az_device *az = video_drvdata(file); if (v->index > 0) return -EINVAL; - strlcpy(v->name, "FM", sizeof(v->name)); + strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; - v->rangelow = 87 * 16000; - v->rangehigh = 108 * 16000; - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; - v->capability = V4L2_TUNER_CAP_LOW; - if (az_getstereo(az)) + v->rangelow=(87*16000); + v->rangehigh=(108*16000); + v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; + v->capability=V4L2_TUNER_CAP_LOW; + if(az_getstereo(az)) v->audmode = V4L2_TUNER_MODE_STEREO; else v->audmode = V4L2_TUNER_MODE_MONO; - v->signal = 0xFFFF * az_getsigstr(az); + v->signal=0xFFFF*az_getsigstr(az); return 0; } -static int vidioc_s_tuner(struct file *file, void *priv, + +static int vidioc_s_tuner (struct file *file, void *priv, struct v4l2_tuner *v) { - return v->index ? -EINVAL : 0; + if (v->index > 0) + return -EINVAL; + + return 0; } -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +static int vidioc_g_audio (struct file *file, void *priv, + struct v4l2_audio *a) { - *i = 0; + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; return 0; } -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { - return i ? -EINVAL : 0; + *i = 0; + return 0; } -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; + if (i != 0) + return -EINVAL; return 0; } -static int vidioc_s_audio(struct file *file, void *priv, + +static int vidioc_s_audio (struct file *file, void *priv, struct v4l2_audio *a) { - return a->index ? -EINVAL : 0; + if (a->index != 0) + return -EINVAL; + + return 0; } -static int vidioc_s_frequency(struct file *file, void *priv, +static int vidioc_s_frequency (struct file *file, void *priv, struct v4l2_frequency *f) { - struct aztech *az = video_drvdata(file); + struct az_device *az = video_drvdata(file); - az_setfreq(az, f->frequency); + az->curfreq = f->frequency; + az_setfreq(az, az->curfreq); return 0; } -static int vidioc_g_frequency(struct file *file, void *priv, +static int vidioc_g_frequency (struct file *file, void *priv, struct v4l2_frequency *f) { - struct aztech *az = video_drvdata(file); + struct az_device *az = video_drvdata(file); f->type = V4L2_TUNER_RADIO; f->frequency = az->curfreq; + return 0; } -static int vidioc_queryctrl(struct file *file, void *priv, +static int vidioc_queryctrl (struct file *file, void *priv, struct v4l2_queryctrl *qc) { - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff); + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); + return (0); + } } return -EINVAL; } -static int vidioc_g_ctrl(struct file *file, void *priv, +static int vidioc_g_ctrl (struct file *file, void *priv, struct v4l2_control *ctrl) { - struct aztech *az = video_drvdata(file); + struct az_device *az = video_drvdata(file); switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - if (az->curvol == 0) - ctrl->value = 1; - else - ctrl->value = 0; - return 0; - case V4L2_CID_AUDIO_VOLUME: - ctrl->value = az->curvol * 6554; - return 0; + case V4L2_CID_AUDIO_MUTE: + if (az->curvol==0) + ctrl->value=1; + else + ctrl->value=0; + return (0); + case V4L2_CID_AUDIO_VOLUME: + ctrl->value=az->curvol * 6554; + return (0); } return -EINVAL; } -static int vidioc_s_ctrl(struct file *file, void *priv, +static int vidioc_s_ctrl (struct file *file, void *priv, struct v4l2_control *ctrl) { - struct aztech *az = video_drvdata(file); + struct az_device *az = video_drvdata(file); switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - if (ctrl->value) - az_setvol(az, 0); - else - az_setvol(az, az->curvol); - return 0; - case V4L2_CID_AUDIO_VOLUME: - az_setvol(az, ctrl->value); - return 0; + case V4L2_CID_AUDIO_MUTE: + if (ctrl->value) { + az_setvol(az,0); + } else { + az_setvol(az,az->curvol); + } + return (0); + case V4L2_CID_AUDIO_VOLUME: + az_setvol(az,ctrl->value); + return (0); } return -EINVAL; } -static int aztech_open(struct file *file) +static struct az_device aztech_unit; + +static int aztech_exclusive_open(struct file *file) { - return 0; + return test_and_set_bit(0, &aztech_unit.in_use) ? -EBUSY : 0; } -static int aztech_release(struct file *file) +static int aztech_exclusive_release(struct file *file) { + clear_bit(0, &aztech_unit.in_use); return 0; } static const struct v4l2_file_operations aztech_fops = { .owner = THIS_MODULE, - .open = aztech_open, - .release = aztech_release, + .open = aztech_exclusive_open, + .release = aztech_exclusive_release, .ioctl = video_ioctl2, }; @@ -350,60 +371,57 @@ static const struct v4l2_ioctl_ops aztech_ioctl_ops = { .vidioc_s_ctrl = vidioc_s_ctrl, }; -static int __init aztech_init(void) -{ - struct aztech *az = &aztech_card; - struct v4l2_device *v4l2_dev = &az->v4l2_dev; - int res; +static struct video_device aztech_radio = { + .name = "Aztech radio", + .fops = &aztech_fops, + .ioctl_ops = &aztech_ioctl_ops, + .release = video_device_release_empty, +}; - strlcpy(v4l2_dev->name, "aztech", sizeof(v4l2_dev->name)); - az->io = io; +module_param_named(debug,aztech_radio.debug, int, 0644); +MODULE_PARM_DESC(debug,"activates debug info"); - if (az->io == -1) { - v4l2_err(v4l2_dev, "you must set an I/O address with io=0x350 or 0x358\n"); +static int __init aztech_init(void) +{ + if(io==-1) + { + printk(KERN_ERR "You must set an I/O address with io=0x???\n"); return -EINVAL; } - if (!request_region(az->io, 2, "aztech")) { - v4l2_err(v4l2_dev, "port 0x%x already in use\n", az->io); + if (!request_region(io, 2, "aztech")) + { + printk(KERN_ERR "aztech: port 0x%x already in use\n", io); return -EBUSY; } - res = v4l2_device_register(NULL, v4l2_dev); - if (res < 0) { - release_region(az->io, 2); - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); - return res; - } + mutex_init(&lock); + video_set_drvdata(&aztech_radio, &aztech_unit); - mutex_init(&az->lock); - strlcpy(az->vdev.name, v4l2_dev->name, sizeof(az->vdev.name)); - az->vdev.v4l2_dev = v4l2_dev; - az->vdev.fops = &aztech_fops; - az->vdev.ioctl_ops = &aztech_ioctl_ops; - az->vdev.release = video_device_release_empty; - video_set_drvdata(&az->vdev, az); - - if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { - v4l2_device_unregister(v4l2_dev); - release_region(az->io, 2); + if (video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr) < 0) { + release_region(io,2); return -EINVAL; } - v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); + printk(KERN_INFO "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); /* mute card - prevents noisy bootups */ - outb(0, az->io); + outb (0, io); return 0; } -static void __exit aztech_exit(void) -{ - struct aztech *az = &aztech_card; +MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); +MODULE_DESCRIPTION("A driver for the Aztech radio card."); +MODULE_LICENSE("GPL"); + +module_param(io, int, 0); +module_param(radio_nr, int, 0); +MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)"); - video_unregister_device(&az->vdev); - v4l2_device_unregister(&az->v4l2_dev); - release_region(az->io, 2); +static void __exit aztech_cleanup(void) +{ + video_unregister_device(&aztech_radio); + release_region(io,2); } module_init(aztech_init); -module_exit(aztech_exit); +module_exit(aztech_cleanup); diff --git a/trunk/drivers/media/radio/radio-cadet.c b/trunk/drivers/media/radio/radio-cadet.c index d30fc0ce82c0..cb3075ac104c 100644 --- a/trunk/drivers/media/radio/radio-cadet.c +++ b/trunk/drivers/media/radio/radio-cadet.c @@ -35,318 +35,333 @@ #include /* Initdata */ #include /* request_region */ #include /* udelay */ +#include /* outb, outb_p */ +#include /* copy to/from user */ #include /* V4L2 API defs */ +#include +#include #include #include -#include /* outb, outb_p */ -#include -#include - -MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); -MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card."); -MODULE_LICENSE("GPL"); - -static int io = -1; /* default to isapnp activation */ -static int radio_nr = -1; - -module_param(io, int, 0); -MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)"); -module_param(radio_nr, int, 0); - -#define CADET_VERSION KERNEL_VERSION(0, 3, 3) #define RDS_BUFFER 256 #define RDS_RX_FLAG 1 #define MBS_RX_FLAG 2 -struct cadet { - struct v4l2_device v4l2_dev; - struct video_device vdev; - int io; - int users; - int curtuner; - int tunestat; - int sigstrength; - wait_queue_head_t read_queue; - struct timer_list readtimer; - __u8 rdsin, rdsout, rdsstat; - unsigned char rdsbuf[RDS_BUFFER]; - struct mutex lock; - int reading; +#define CADET_VERSION KERNEL_VERSION(0,3,3) + +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + },{ + .id = V4L2_CID_AUDIO_VOLUME, + .name = "Volume", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } }; -static struct cadet cadet_card; +static int io=-1; /* default to isapnp activation */ +static int radio_nr = -1; +static int users; +static int curtuner; +static int tunestat; +static int sigstrength; +static wait_queue_head_t read_queue; +static struct timer_list readtimer; +static __u8 rdsin, rdsout, rdsstat; +static unsigned char rdsbuf[RDS_BUFFER]; +static spinlock_t cadet_io_lock; + +static int cadet_probe(void); /* * Signal Strength Threshold Values * The V4L API spec does not define any particular unit for the signal * strength value. These values are in microvolts of RF at the tuner's input. */ -static __u16 sigtable[2][4] = { - { 5, 10, 30, 150 }, - { 28, 40, 63, 1000 } -}; +static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}}; -static int cadet_getstereo(struct cadet *dev) +static int +cadet_getstereo(void) { int ret = V4L2_TUNER_SUB_MONO; - - if (dev->curtuner != 0) /* Only FM has stereo capability! */ + if(curtuner != 0) /* Only FM has stereo capability! */ return V4L2_TUNER_SUB_MONO; - mutex_lock(&dev->lock); - outb(7, dev->io); /* Select tuner control */ - if ((inb(dev->io + 1) & 0x40) == 0) + spin_lock(&cadet_io_lock); + outb(7,io); /* Select tuner control */ + if( (inb(io+1) & 0x40) == 0) ret = V4L2_TUNER_SUB_STEREO; - mutex_unlock(&dev->lock); + spin_unlock(&cadet_io_lock); return ret; } -static unsigned cadet_gettune(struct cadet *dev) +static unsigned +cadet_gettune(void) { - int curvol, i; - unsigned fifo = 0; + int curvol,i; + unsigned fifo=0; /* * Prepare for read */ - mutex_lock(&dev->lock); + spin_lock(&cadet_io_lock); - outb(7, dev->io); /* Select tuner control */ - curvol = inb(dev->io + 1); /* Save current volume/mute setting */ - outb(0x00, dev->io + 1); /* Ensure WRITE-ENABLE is LOW */ - dev->tunestat = 0xffff; + outb(7,io); /* Select tuner control */ + curvol=inb(io+1); /* Save current volume/mute setting */ + outb(0x00,io+1); /* Ensure WRITE-ENABLE is LOW */ + tunestat=0xffff; /* * Read the shift register */ - for (i = 0; i < 25; i++) { - fifo = (fifo << 1) | ((inb(dev->io + 1) >> 7) & 0x01); - if (i < 24) { - outb(0x01, dev->io + 1); - dev->tunestat &= inb(dev->io + 1); - outb(0x00, dev->io + 1); + for(i=0;i<25;i++) { + fifo=(fifo<<1)|((inb(io+1)>>7)&0x01); + if(i<24) { + outb(0x01,io+1); + tunestat&=inb(io+1); + outb(0x00,io+1); } } /* * Restore volume/mute setting */ - outb(curvol, dev->io + 1); - mutex_unlock(&dev->lock); + outb(curvol,io+1); + spin_unlock(&cadet_io_lock); return fifo; } -static unsigned cadet_getfreq(struct cadet *dev) +static unsigned +cadet_getfreq(void) { int i; - unsigned freq = 0, test, fifo = 0; + unsigned freq=0,test,fifo=0; /* * Read current tuning */ - fifo = cadet_gettune(dev); + fifo=cadet_gettune(); /* * Convert to actual frequency */ - if (dev->curtuner == 0) { /* FM */ - test = 12500; - for (i = 0; i < 14; i++) { - if ((fifo & 0x01) != 0) - freq += test; - test = test << 1; - fifo = fifo >> 1; + if(curtuner==0) { /* FM */ + test=12500; + for(i=0;i<14;i++) { + if((fifo&0x01)!=0) { + freq+=test; + } + test=test<<1; + fifo=fifo>>1; } - freq -= 10700000; /* IF frequency is 10.7 MHz */ - freq = (freq * 16) / 1000000; /* Make it 1/16 MHz */ + freq-=10700000; /* IF frequency is 10.7 MHz */ + freq=(freq*16)/1000000; /* Make it 1/16 MHz */ + } + if(curtuner==1) { /* AM */ + freq=((fifo&0x7fff)-2010)*16; } - if (dev->curtuner == 1) /* AM */ - freq = ((fifo & 0x7fff) - 2010) * 16; return freq; } -static void cadet_settune(struct cadet *dev, unsigned fifo) +static void +cadet_settune(unsigned fifo) { int i; unsigned test; - mutex_lock(&dev->lock); + spin_lock(&cadet_io_lock); - outb(7, dev->io); /* Select tuner control */ + outb(7,io); /* Select tuner control */ /* * Write the shift register */ - test = 0; - test = (fifo >> 23) & 0x02; /* Align data for SDO */ - test |= 0x1c; /* SDM=1, SWE=1, SEN=1, SCK=0 */ - outb(7, dev->io); /* Select tuner control */ - outb(test, dev->io + 1); /* Initialize for write */ - for (i = 0; i < 25; i++) { - test |= 0x01; /* Toggle SCK High */ - outb(test, dev->io + 1); - test &= 0xfe; /* Toggle SCK Low */ - outb(test, dev->io + 1); - fifo = fifo << 1; /* Prepare the next bit */ - test = 0x1c | ((fifo >> 23) & 0x02); - outb(test, dev->io + 1); + test=0; + test=(fifo>>23)&0x02; /* Align data for SDO */ + test|=0x1c; /* SDM=1, SWE=1, SEN=1, SCK=0 */ + outb(7,io); /* Select tuner control */ + outb(test,io+1); /* Initialize for write */ + for(i=0;i<25;i++) { + test|=0x01; /* Toggle SCK High */ + outb(test,io+1); + test&=0xfe; /* Toggle SCK Low */ + outb(test,io+1); + fifo=fifo<<1; /* Prepare the next bit */ + test=0x1c|((fifo>>23)&0x02); + outb(test,io+1); } - mutex_unlock(&dev->lock); + spin_unlock(&cadet_io_lock); } -static void cadet_setfreq(struct cadet *dev, unsigned freq) +static void +cadet_setfreq(unsigned freq) { unsigned fifo; - int i, j, test; + int i,j,test; int curvol; /* * Formulate a fifo command */ - fifo = 0; - if (dev->curtuner == 0) { /* FM */ - test = 102400; - freq = (freq * 1000) / 16; /* Make it kHz */ - freq += 10700; /* IF is 10700 kHz */ - for (i = 0; i < 14; i++) { - fifo = fifo << 1; - if (freq >= test) { - fifo |= 0x01; - freq -= test; + fifo=0; + if(curtuner==0) { /* FM */ + test=102400; + freq=(freq*1000)/16; /* Make it kHz */ + freq+=10700; /* IF is 10700 kHz */ + for(i=0;i<14;i++) { + fifo=fifo<<1; + if(freq>=test) { + fifo|=0x01; + freq-=test; } - test = test >> 1; + test=test>>1; } } - if (dev->curtuner == 1) { /* AM */ - fifo = (freq / 16) + 2010; /* Make it kHz */ - fifo |= 0x100000; /* Select AM Band */ + if(curtuner==1) { /* AM */ + fifo=(freq/16)+2010; /* Make it kHz */ + fifo|=0x100000; /* Select AM Band */ } /* * Save current volume/mute setting */ - mutex_lock(&dev->lock); - outb(7, dev->io); /* Select tuner control */ - curvol = inb(dev->io + 1); - mutex_unlock(&dev->lock); + spin_lock(&cadet_io_lock); + outb(7,io); /* Select tuner control */ + curvol=inb(io+1); + spin_unlock(&cadet_io_lock); /* * Tune the card */ - for (j = 3; j > -1; j--) { - cadet_settune(dev, fifo | (j << 16)); + for(j=3;j>-1;j--) { + cadet_settune(fifo|(j<<16)); - mutex_lock(&dev->lock); - outb(7, dev->io); /* Select tuner control */ - outb(curvol, dev->io + 1); - mutex_unlock(&dev->lock); + spin_lock(&cadet_io_lock); + outb(7,io); /* Select tuner control */ + outb(curvol,io+1); + spin_unlock(&cadet_io_lock); msleep(100); - cadet_gettune(dev); - if ((dev->tunestat & 0x40) == 0) { /* Tuned */ - dev->sigstrength = sigtable[dev->curtuner][j]; + cadet_gettune(); + if((tunestat & 0x40) == 0) { /* Tuned */ + sigstrength=sigtable[curtuner][j]; return; } } - dev->sigstrength = 0; + sigstrength=0; } -static int cadet_getvol(struct cadet *dev) +static int +cadet_getvol(void) { int ret = 0; - mutex_lock(&dev->lock); + spin_lock(&cadet_io_lock); - outb(7, dev->io); /* Select tuner control */ - if ((inb(dev->io + 1) & 0x20) != 0) + outb(7,io); /* Select tuner control */ + if((inb(io + 1) & 0x20) != 0) ret = 0xffff; - mutex_unlock(&dev->lock); + spin_unlock(&cadet_io_lock); return ret; } -static void cadet_setvol(struct cadet *dev, int vol) +static void +cadet_setvol(int vol) { - mutex_lock(&dev->lock); - outb(7, dev->io); /* Select tuner control */ - if (vol > 0) - outb(0x20, dev->io + 1); + spin_lock(&cadet_io_lock); + outb(7,io); /* Select tuner control */ + if(vol>0) + outb(0x20,io+1); else - outb(0x00, dev->io + 1); - mutex_unlock(&dev->lock); + outb(0x00,io+1); + spin_unlock(&cadet_io_lock); } -static void cadet_handler(unsigned long data) +static void +cadet_handler(unsigned long data) { - struct cadet *dev = (void *)data; + /* + * Service the RDS fifo + */ - /* Service the RDS fifo */ - if (mutex_trylock(&dev->lock)) { - outb(0x3, dev->io); /* Select RDS Decoder Control */ - if ((inb(dev->io + 1) & 0x20) != 0) + if(spin_trylock(&cadet_io_lock)) + { + outb(0x3,io); /* Select RDS Decoder Control */ + if((inb(io+1)&0x20)!=0) { printk(KERN_CRIT "cadet: RDS fifo overflow\n"); - outb(0x80, dev->io); /* Select RDS fifo */ - while ((inb(dev->io) & 0x80) != 0) { - dev->rdsbuf[dev->rdsin] = inb(dev->io + 1); - if (dev->rdsin == dev->rdsout) + } + outb(0x80,io); /* Select RDS fifo */ + while((inb(io)&0x80)!=0) { + rdsbuf[rdsin]=inb(io+1); + if(rdsin==rdsout) printk(KERN_WARNING "cadet: RDS buffer overflow\n"); else - dev->rdsin++; + rdsin++; } - mutex_unlock(&dev->lock); + spin_unlock(&cadet_io_lock); } /* * Service pending read */ - if (dev->rdsin != dev->rdsout) - wake_up_interruptible(&dev->read_queue); + if( rdsin!=rdsout) + wake_up_interruptible(&read_queue); /* * Clean up and exit */ - init_timer(&dev->readtimer); - dev->readtimer.function = cadet_handler; - dev->readtimer.data = (unsigned long)0; - dev->readtimer.expires = jiffies + msecs_to_jiffies(50); - add_timer(&dev->readtimer); + init_timer(&readtimer); + readtimer.function=cadet_handler; + readtimer.data=(unsigned long)0; + readtimer.expires=jiffies+msecs_to_jiffies(50); + add_timer(&readtimer); } -static ssize_t cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos) + +static ssize_t +cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { - struct cadet *dev = video_drvdata(file); + int i=0; unsigned char readbuf[RDS_BUFFER]; - int i = 0; - - if (dev->rdsstat == 0) { - mutex_lock(&dev->lock); - dev->rdsstat = 1; - outb(0x80, dev->io); /* Select RDS fifo */ - mutex_unlock(&dev->lock); - init_timer(&dev->readtimer); - dev->readtimer.function = cadet_handler; - dev->readtimer.data = (unsigned long)dev; - dev->readtimer.expires = jiffies + msecs_to_jiffies(50); - add_timer(&dev->readtimer); + + if(rdsstat==0) { + spin_lock(&cadet_io_lock); + rdsstat=1; + outb(0x80,io); /* Select RDS fifo */ + spin_unlock(&cadet_io_lock); + init_timer(&readtimer); + readtimer.function=cadet_handler; + readtimer.data=(unsigned long)0; + readtimer.expires=jiffies+msecs_to_jiffies(50); + add_timer(&readtimer); } - if (dev->rdsin == dev->rdsout) { + if(rdsin==rdsout) { if (file->f_flags & O_NONBLOCK) return -EWOULDBLOCK; - interruptible_sleep_on(&dev->read_queue); + interruptible_sleep_on(&read_queue); } - while (i < count && dev->rdsin != dev->rdsout) - readbuf[i++] = dev->rdsbuf[dev->rdsout++]; + while( idriver, "ADS Cadet", sizeof(v->driver)); - strlcpy(v->card, "ADS Cadet", sizeof(v->card)); - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); + v->capabilities = + V4L2_CAP_TUNER | + V4L2_CAP_READWRITE; v->version = CADET_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_READWRITE; + strcpy(v->driver, "ADS Cadet"); + strcpy(v->card, "ADS Cadet"); return 0; } static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct cadet *dev = video_drvdata(file); - v->type = V4L2_TUNER_RADIO; switch (v->index) { case 0: - strlcpy(v->name, "FM", sizeof(v->name)); + strcpy(v->name, "FM"); v->capability = V4L2_TUNER_CAP_STEREO; v->rangelow = 1400; /* 87.5 MHz */ v->rangehigh = 1728; /* 108.0 MHz */ - v->rxsubchans = cadet_getstereo(dev); - switch (v->rxsubchans) { + v->rxsubchans=cadet_getstereo(); + switch (v->rxsubchans){ case V4L2_TUNER_SUB_MONO: v->audmode = V4L2_TUNER_MODE_MONO; break; case V4L2_TUNER_SUB_STEREO: v->audmode = V4L2_TUNER_MODE_STEREO; break; - default: - break; + default: ; } break; case 1: - strlcpy(v->name, "AM", sizeof(v->name)); + strcpy(v->name, "AM"); v->capability = V4L2_TUNER_CAP_LOW; v->rangelow = 8320; /* 520 kHz */ v->rangehigh = 26400; /* 1650 kHz */ @@ -398,29 +411,25 @@ static int vidioc_g_tuner(struct file *file, void *priv, default: return -EINVAL; } - v->signal = dev->sigstrength; /* We might need to modify scaling of this */ + v->signal = sigstrength; /* We might need to modify scaling of this */ return 0; } static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct cadet *dev = video_drvdata(file); - - if (v->index != 0 && v->index != 1) + if((v->index != 0)&&(v->index != 1)) return -EINVAL; - dev->curtuner = v->index; + curtuner = v->index; return 0; } static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct cadet *dev = video_drvdata(file); - - f->tuner = dev->curtuner; + f->tuner = curtuner; f->type = V4L2_TUNER_RADIO; - f->frequency = cadet_getfreq(dev); + f->frequency = cadet_getfreq(); return 0; } @@ -428,26 +437,27 @@ static int vidioc_g_frequency(struct file *file, void *priv, static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct cadet *dev = video_drvdata(file); - if (f->type != V4L2_TUNER_RADIO) return -EINVAL; - if (dev->curtuner == 0 && (f->frequency < 1400 || f->frequency > 1728)) + if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728))) return -EINVAL; - if (dev->curtuner == 1 && (f->frequency < 8320 || f->frequency > 26400)) + if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400))) return -EINVAL; - cadet_setfreq(dev, f->frequency); + cadet_setfreq(f->frequency); return 0; } static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff); + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); + return 0; + } } return -EINVAL; } @@ -455,14 +465,12 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct cadet *dev = video_drvdata(file); - - switch (ctrl->id) { + switch (ctrl->id){ case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */ - ctrl->value = (cadet_getvol(dev) == 0); + ctrl->value = (cadet_getvol() == 0); break; case V4L2_CID_AUDIO_VOLUME: - ctrl->value = cadet_getvol(dev); + ctrl->value = cadet_getvol(); break; default: return -EINVAL; @@ -473,17 +481,15 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct cadet *dev = video_drvdata(file); - switch (ctrl->id){ case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */ if (ctrl->value) - cadet_setvol(dev, 0); + cadet_setvol(0); else - cadet_setvol(dev, 0xffff); + cadet_setvol(0xffff); break; case V4L2_CID_AUDIO_VOLUME: - cadet_setvol(dev, ctrl->value); + cadet_setvol(ctrl->value); break; default: return -EINVAL; @@ -491,60 +497,61 @@ static int vidioc_s_ctrl(struct file *file, void *priv, return 0; } -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +static int vidioc_g_audio(struct file *file, void *priv, + struct v4l2_audio *a) { - *i = 0; + if (a->index > 1) + return -EINVAL; + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; return 0; } -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { - return i ? -EINVAL : 0; + *i = 0; + return 0; } -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; + if (i != 0) + return -EINVAL; return 0; } static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) { - return a->index ? -EINVAL : 0; + if (a->index != 0) + return -EINVAL; + return 0; } -static int cadet_open(struct file *file) +static int +cadet_open(struct file *file) { - struct cadet *dev = video_drvdata(file); - - dev->users++; - if (1 == dev->users) - init_waitqueue_head(&dev->read_queue); + users++; + if (1 == users) init_waitqueue_head(&read_queue); return 0; } -static int cadet_release(struct file *file) +static int +cadet_release(struct file *file) { - struct cadet *dev = video_drvdata(file); - - dev->users--; - if (0 == dev->users) { - del_timer_sync(&dev->readtimer); - dev->rdsstat = 0; + users--; + if (0 == users){ + del_timer_sync(&readtimer); + rdsstat=0; } return 0; } -static unsigned int cadet_poll(struct file *file, struct poll_table_struct *wait) +static unsigned int +cadet_poll(struct file *file, struct poll_table_struct *wait) { - struct cadet *dev = video_drvdata(file); - - poll_wait(file, &dev->read_queue, wait); - if (dev->rdsin != dev->rdsout) + poll_wait(file,&read_queue,wait); + if(rdsin != rdsout) return POLLIN | POLLRDNORM; return 0; } @@ -574,6 +581,13 @@ static const struct v4l2_ioctl_ops cadet_ioctl_ops = { .vidioc_s_input = vidioc_s_input, }; +static struct video_device cadet_radio = { + .name = "Cadet radio", + .fops = &cadet_fops, + .ioctl_ops = &cadet_ioctl_ops, + .release = video_device_release_empty, +}; + #ifdef CONFIG_PNP static struct pnp_device_id cadet_pnp_devices[] = { @@ -584,7 +598,7 @@ static struct pnp_device_id cadet_pnp_devices[] = { MODULE_DEVICE_TABLE(pnp, cadet_pnp_devices); -static int cadet_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) +static int cadet_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) { if (!dev) return -ENODEV; @@ -592,12 +606,13 @@ static int cadet_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_ if (io > 0) return -EBUSY; - if (!pnp_port_valid(dev, 0)) + if (!pnp_port_valid(dev, 0)) { return -ENODEV; + } io = pnp_port_start(dev, 0); - printk(KERN_INFO "radio-cadet: PnP reports device at %#x\n", io); + printk ("radio-cadet: PnP reports device at %#x\n", io); return io; } @@ -613,23 +628,23 @@ static struct pnp_driver cadet_pnp_driver = { static struct pnp_driver cadet_pnp_driver; #endif -static void cadet_probe(struct cadet *dev) +static int cadet_probe(void) { - static int iovals[8] = { 0x330, 0x332, 0x334, 0x336, 0x338, 0x33a, 0x33c, 0x33e }; + static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e}; int i; - for (i = 0; i < 8; i++) { - dev->io = iovals[i]; - if (request_region(dev->io, 2, "cadet-probe")) { - cadet_setfreq(dev, 1410); - if (cadet_getfreq(dev) == 1410) { - release_region(dev->io, 2); - return; + for(i=0;i<8;i++) { + io=iovals[i]; + if (request_region(io, 2, "cadet-probe")) { + cadet_setfreq(1410); + if(cadet_getfreq()==1410) { + release_region(io, 2); + return io; } - release_region(dev->io, 2); + release_region(io, 2); } } - dev->io = -1; + return -1; } /* @@ -639,69 +654,59 @@ static void cadet_probe(struct cadet *dev) static int __init cadet_init(void) { - struct cadet *dev = &cadet_card; - struct v4l2_device *v4l2_dev = &dev->v4l2_dev; - int res; - - strlcpy(v4l2_dev->name, "cadet", sizeof(v4l2_dev->name)); - mutex_init(&dev->lock); + spin_lock_init(&cadet_io_lock); - /* If a probe was requested then probe ISAPnP first (safest) */ + /* + * If a probe was requested then probe ISAPnP first (safest) + */ if (io < 0) pnp_register_driver(&cadet_pnp_driver); - dev->io = io; + /* + * If that fails then probe unsafely if probe is requested + */ + if(io < 0) + io = cadet_probe (); - /* If that fails then probe unsafely if probe is requested */ - if (dev->io < 0) - cadet_probe(dev); + /* + * Else we bail out + */ - /* Else we bail out */ - if (dev->io < 0) { + if(io < 0) { #ifdef MODULE - v4l2_err(v4l2_dev, "you must set an I/O address with io=0x330, 0x332, 0x334,\n"); - v4l2_err(v4l2_dev, "0x336, 0x338, 0x33a, 0x33c or 0x33e\n"); + printk(KERN_ERR "You must set an I/O address with io=0x???\n"); #endif goto fail; } - if (!request_region(dev->io, 2, "cadet")) - goto fail; - - res = v4l2_device_register(NULL, v4l2_dev); - if (res < 0) { - release_region(dev->io, 2); - v4l2_err(v4l2_dev, "could not register v4l2_device\n"); + if (!request_region(io,2,"cadet")) goto fail; - } - - strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); - dev->vdev.v4l2_dev = v4l2_dev; - dev->vdev.fops = &cadet_fops; - dev->vdev.ioctl_ops = &cadet_ioctl_ops; - dev->vdev.release = video_device_release_empty; - video_set_drvdata(&dev->vdev, dev); - - if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { - v4l2_device_unregister(v4l2_dev); - release_region(dev->io, 2); + if (video_register_device(&cadet_radio, VFL_TYPE_RADIO, radio_nr) < 0) { + release_region(io,2); goto fail; } - v4l2_info(v4l2_dev, "ADS Cadet Radio Card at 0x%x\n", dev->io); + printk(KERN_INFO "ADS Cadet Radio Card at 0x%x\n",io); return 0; fail: pnp_unregister_driver(&cadet_pnp_driver); - return -ENODEV; + return -1; } -static void __exit cadet_exit(void) -{ - struct cadet *dev = &cadet_card; - video_unregister_device(&dev->vdev); - v4l2_device_unregister(&dev->v4l2_dev); - release_region(dev->io, 2); + +MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); +MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card."); +MODULE_LICENSE("GPL"); + +module_param(io, int, 0); +MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)"); +module_param(radio_nr, int, 0); + +static void __exit cadet_cleanup_module(void) +{ + video_unregister_device(&cadet_radio); + release_region(io,2); pnp_unregister_driver(&cadet_pnp_driver); } module_init(cadet_init); -module_exit(cadet_exit); +module_exit(cadet_cleanup_module); diff --git a/trunk/drivers/media/radio/radio-gemtek-pci.c b/trunk/drivers/media/radio/radio-gemtek-pci.c index 09265d25725e..0c96bf8525b0 100644 --- a/trunk/drivers/media/radio/radio-gemtek-pci.c +++ b/trunk/drivers/media/radio/radio-gemtek-pci.c @@ -45,25 +45,34 @@ #include #include #include -#include -#include /* for KERNEL_VERSION MACRO */ -#include -#include +#include #include +#include -MODULE_AUTHOR("Vladimir Shebordaev "); -MODULE_DESCRIPTION("The video4linux driver for the Gemtek PCI Radio Card"); -MODULE_LICENSE("GPL"); - -static int nr_radio = -1; -static int mx = 1; - -module_param(mx, bool, 0); -MODULE_PARM_DESC(mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not"); -module_param(nr_radio, int, 0); -MODULE_PARM_DESC(nr_radio, "video4linux device number to use"); +#include /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,0,2) + +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + },{ + .id = V4L2_CID_AUDIO_VOLUME, + .name = "Volume", + .minimum = 0, + .maximum = 65535, + .step = 65535, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; -#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) +#include +#include #ifndef PCI_VENDOR_ID_GEMTEK #define PCI_VENDOR_ID_GEMTEK 0x5046 @@ -81,11 +90,8 @@ MODULE_PARM_DESC(nr_radio, "video4linux device number to use"); #define GEMTEK_PCI_RANGE_HIGH (108*16000) #endif -struct gemtek_pci { - struct v4l2_device v4l2_dev; - struct video_device vdev; - struct mutex lock; - struct pci_dev *pdev; +struct gemtek_pci_card { + struct video_device *videodev; u32 iobase; u32 length; @@ -94,133 +100,116 @@ struct gemtek_pci { u8 mute; }; -static inline struct gemtek_pci *to_gemtek_pci(struct v4l2_device *v4l2_dev) -{ - return container_of(v4l2_dev, struct gemtek_pci, v4l2_dev); -} +static int nr_radio = -1; +static unsigned long in_use; -static inline u8 gemtek_pci_out(u16 value, u32 port) +static inline u8 gemtek_pci_out( u16 value, u32 port ) { - outw(value, port); + outw( value, port ); return (u8)value; } -#define _b0(v) (*((u8 *)&v)) - -static void __gemtek_pci_cmd(u16 value, u32 port, u8 *last_byte, int keep) +#define _b0( v ) *((u8 *)&v) +static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep ) { - u8 byte = *last_byte; + register u8 byte = *last_byte; - if (!value) { - if (!keep) + if ( !value ) { + if ( !keep ) value = (u16)port; byte &= 0xfd; } else byte |= 2; - _b0(value) = byte; - outw(value, port); + _b0( value ) = byte; + outw( value, port ); byte |= 1; - _b0(value) = byte; - outw(value, port); + _b0( value ) = byte; + outw( value, port ); byte &= 0xfe; - _b0(value) = byte; - outw(value, port); + _b0( value ) = byte; + outw( value, port ); *last_byte = byte; } -static inline void gemtek_pci_nil(u32 port, u8 *last_byte) +static inline void gemtek_pci_nil( u32 port, u8 *last_byte ) { - __gemtek_pci_cmd(0x00, port, last_byte, false); + __gemtek_pci_cmd( 0x00, port, last_byte, false ); } -static inline void gemtek_pci_cmd(u16 cmd, u32 port, u8 *last_byte) +static inline void gemtek_pci_cmd( u16 cmd, u32 port, u8 *last_byte ) { - __gemtek_pci_cmd(cmd, port, last_byte, true); + __gemtek_pci_cmd( cmd, port, last_byte, true ); } -static void gemtek_pci_setfrequency(struct gemtek_pci *card, unsigned long frequency) +static void gemtek_pci_setfrequency( struct gemtek_pci_card *card, unsigned long frequency ) { - int i; - u32 value = frequency / 200 + 856; - u16 mask = 0x8000; + register int i; + register u32 value = frequency / 200 + 856; + register u16 mask = 0x8000; u8 last_byte; u32 port = card->iobase; - mutex_lock(&card->lock); - card->current_frequency = frequency; - last_byte = gemtek_pci_out(0x06, port); + last_byte = gemtek_pci_out( 0x06, port ); i = 0; do { - gemtek_pci_nil(port, &last_byte); + gemtek_pci_nil( port, &last_byte ); i++; - } while (i < 9); + } while ( i < 9 ); i = 0; do { - gemtek_pci_cmd(value & mask, port, &last_byte); + gemtek_pci_cmd( value & mask, port, &last_byte ); mask >>= 1; i++; - } while (i < 16); + } while ( i < 16 ); - outw(0x10, port); - mutex_unlock(&card->lock); + outw( 0x10, port ); } -static void gemtek_pci_mute(struct gemtek_pci *card) +static inline void gemtek_pci_mute( struct gemtek_pci_card *card ) { - mutex_lock(&card->lock); - outb(0x1f, card->iobase); + outb( 0x1f, card->iobase ); card->mute = true; - mutex_unlock(&card->lock); } -static void gemtek_pci_unmute(struct gemtek_pci *card) +static inline void gemtek_pci_unmute( struct gemtek_pci_card *card ) { - mutex_lock(&card->lock); - if (card->mute) { - gemtek_pci_setfrequency(card, card->current_frequency); + if ( card->mute ) { + gemtek_pci_setfrequency( card, card->current_frequency ); card->mute = false; } - mutex_unlock(&card->lock); } -static int gemtek_pci_getsignal(struct gemtek_pci *card) +static inline unsigned int gemtek_pci_getsignal( struct gemtek_pci_card *card ) { - int sig; - - mutex_lock(&card->lock); - sig = (inb(card->iobase) & 0x08) ? 0 : 1; - mutex_unlock(&card->lock); - return sig; + return ( inb( card->iobase ) & 0x08 ) ? 0 : 1; } static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *v) { - struct gemtek_pci *card = video_drvdata(file); - strlcpy(v->driver, "radio-gemtek-pci", sizeof(v->driver)); strlcpy(v->card, "GemTek PCI Radio", sizeof(v->card)); - snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(card->pdev)); + sprintf(v->bus_info, "ISA"); v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->capabilities = V4L2_CAP_TUNER; return 0; } static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct gemtek_pci *card = video_drvdata(file); + struct gemtek_pci_card *card = video_drvdata(file); if (v->index > 0) return -EINVAL; - strlcpy(v->name, "FM", sizeof(v->name)); + strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; v->rangelow = GEMTEK_PCI_RANGE_LOW; v->rangehigh = GEMTEK_PCI_RANGE_HIGH; @@ -234,18 +223,21 @@ static int vidioc_g_tuner(struct file *file, void *priv, static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - return v->index ? -EINVAL : 0; + if (v->index > 0) + return -EINVAL; + return 0; } static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct gemtek_pci *card = video_drvdata(file); + struct gemtek_pci_card *card = video_drvdata(file); - if (f->frequency < GEMTEK_PCI_RANGE_LOW || - f->frequency > GEMTEK_PCI_RANGE_HIGH) + if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) || + (f->frequency > GEMTEK_PCI_RANGE_HIGH) ) return -EINVAL; gemtek_pci_setfrequency(card, f->frequency); + card->current_frequency = f->frequency; card->mute = false; return 0; } @@ -253,7 +245,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct gemtek_pci *card = video_drvdata(file); + struct gemtek_pci_card *card = video_drvdata(file); f->type = V4L2_TUNER_RADIO; f->frequency = card->current_frequency; @@ -263,11 +255,13 @@ static int vidioc_g_frequency(struct file *file, void *priv, static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535); + int i; + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); + return 0; + } } return -EINVAL; } @@ -275,7 +269,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct gemtek_pci *card = video_drvdata(file); + struct gemtek_pci_card *card = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -294,7 +288,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct gemtek_pci *card = video_drvdata(file); + struct gemtek_pci_card *card = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -313,30 +307,36 @@ static int vidioc_s_ctrl(struct file *file, void *priv, return -EINVAL; } -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +static int vidioc_g_audio(struct file *file, void *priv, + struct v4l2_audio *a) { - *i = 0; + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; return 0; } -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { - return i ? -EINVAL : 0; + *i = 0; + return 0; } -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; + if (i != 0) + return -EINVAL; return 0; } static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) { - return a->index ? -EINVAL : 0; + if (a->index != 0) + return -EINVAL; + return 0; } enum { @@ -354,22 +354,25 @@ static struct pci_device_id gemtek_pci_id[] = { 0 } }; -MODULE_DEVICE_TABLE(pci, gemtek_pci_id); +MODULE_DEVICE_TABLE( pci, gemtek_pci_id ); + +static int mx = 1; -static int gemtek_pci_open(struct file *file) +static int gemtek_pci_exclusive_open(struct file *file) { - return 0; + return test_and_set_bit(0, &in_use) ? -EBUSY : 0; } -static int gemtek_pci_release(struct file *file) +static int gemtek_pci_exclusive_release(struct file *file) { + clear_bit(0, &in_use); return 0; } static const struct v4l2_file_operations gemtek_pci_fops = { .owner = THIS_MODULE, - .open = gemtek_pci_open, - .release = gemtek_pci_release, + .open = gemtek_pci_exclusive_open, + .release = gemtek_pci_exclusive_release, .ioctl = video_ioctl2, }; @@ -388,100 +391,108 @@ static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { .vidioc_s_ctrl = vidioc_s_ctrl, }; -static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) +static struct video_device vdev_template = { + .name = "Gemtek PCI Radio", + .fops = &gemtek_pci_fops, + .ioctl_ops = &gemtek_pci_ioctl_ops, + .release = video_device_release_empty, +}; + +static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id ) { - struct gemtek_pci *card; - struct v4l2_device *v4l2_dev; - int res; + struct gemtek_pci_card *card; + struct video_device *devradio; - card = kzalloc(sizeof(struct gemtek_pci), GFP_KERNEL); - if (card == NULL) { - dev_err(&pdev->dev, "out of memory\n"); + if ( (card = kzalloc( sizeof( struct gemtek_pci_card ), GFP_KERNEL )) == NULL ) { + printk( KERN_ERR "gemtek_pci: out of memory\n" ); return -ENOMEM; } - v4l2_dev = &card->v4l2_dev; - mutex_init(&card->lock); - card->pdev = pdev; - - strlcpy(v4l2_dev->name, "gemtek_pci", sizeof(v4l2_dev->name)); - - res = v4l2_device_register(&pdev->dev, v4l2_dev); - if (res < 0) { - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); - kfree(card); - return res; - } - - if (pci_enable_device(pdev)) + if ( pci_enable_device( pci_dev ) ) goto err_pci; - card->iobase = pci_resource_start(pdev, 0); - card->length = pci_resource_len(pdev, 0); + card->iobase = pci_resource_start( pci_dev, 0 ); + card->length = pci_resource_len( pci_dev, 0 ); - if (request_region(card->iobase, card->length, card_names[pci_id->driver_data]) == NULL) { - v4l2_err(v4l2_dev, "i/o port already in use\n"); + if ( request_region( card->iobase, card->length, card_names[pci_id->driver_data] ) == NULL ) { + printk( KERN_ERR "gemtek_pci: i/o port already in use\n" ); goto err_pci; } - strlcpy(card->vdev.name, v4l2_dev->name, sizeof(card->vdev.name)); - card->vdev.v4l2_dev = v4l2_dev; - card->vdev.fops = &gemtek_pci_fops; - card->vdev.ioctl_ops = &gemtek_pci_ioctl_ops; - card->vdev.release = video_device_release_empty; - video_set_drvdata(&card->vdev, card); + pci_set_drvdata( pci_dev, card ); - if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0) + if ( (devradio = kmalloc( sizeof( struct video_device ), GFP_KERNEL )) == NULL ) { + printk( KERN_ERR "gemtek_pci: out of memory\n" ); goto err_video; + } + *devradio = vdev_template; + + if (video_register_device(devradio, VFL_TYPE_RADIO, nr_radio) < 0) { + kfree( devradio ); + goto err_video; + } - gemtek_pci_mute(card); + card->videodev = devradio; + video_set_drvdata(devradio, card); + gemtek_pci_mute( card ); - v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", - pdev->revision, card->iobase, card->iobase + card->length - 1); + printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", + pci_dev->revision, card->iobase, card->iobase + card->length - 1 ); return 0; err_video: - release_region(card->iobase, card->length); + release_region( card->iobase, card->length ); err_pci: - v4l2_device_unregister(v4l2_dev); - kfree(card); + kfree( card ); return -ENODEV; } -static void __devexit gemtek_pci_remove(struct pci_dev *pdev) +static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev ) { - struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); - struct gemtek_pci *card = to_gemtek_pci(v4l2_dev); + struct gemtek_pci_card *card = pci_get_drvdata( pci_dev ); - video_unregister_device(&card->vdev); - v4l2_device_unregister(v4l2_dev); + video_unregister_device( card->videodev ); + kfree( card->videodev ); - release_region(card->iobase, card->length); + release_region( card->iobase, card->length ); - if (mx) - gemtek_pci_mute(card); + if ( mx ) + gemtek_pci_mute( card ); - kfree(card); + kfree( card ); + + pci_set_drvdata( pci_dev, NULL ); } -static struct pci_driver gemtek_pci_driver = { +static struct pci_driver gemtek_pci_driver = +{ .name = "gemtek_pci", .id_table = gemtek_pci_id, .probe = gemtek_pci_probe, .remove = __devexit_p(gemtek_pci_remove), }; -static int __init gemtek_pci_init(void) +static int __init gemtek_pci_init_module( void ) { - return pci_register_driver(&gemtek_pci_driver); + return pci_register_driver( &gemtek_pci_driver ); } -static void __exit gemtek_pci_exit(void) +static void __exit gemtek_pci_cleanup_module( void ) { pci_unregister_driver(&gemtek_pci_driver); } -module_init(gemtek_pci_init); -module_exit(gemtek_pci_exit); +MODULE_AUTHOR( "Vladimir Shebordaev " ); +MODULE_DESCRIPTION( "The video4linux driver for the Gemtek PCI Radio Card" ); +MODULE_LICENSE("GPL"); + +module_param(mx, bool, 0); +MODULE_PARM_DESC( mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not" ); +module_param(nr_radio, int, 0); +MODULE_PARM_DESC( nr_radio, "video4linux device number to use"); + +module_init( gemtek_pci_init_module ); +module_exit( gemtek_pci_cleanup_module ); + diff --git a/trunk/drivers/media/radio/radio-gemtek.c b/trunk/drivers/media/radio/radio-gemtek.c index 150464426d1d..2b68be773f13 100644 --- a/trunk/drivers/media/radio/radio-gemtek.c +++ b/trunk/drivers/media/radio/radio-gemtek.c @@ -20,14 +20,16 @@ #include /* Initdata */ #include /* request_region */ #include /* udelay */ +#include /* outb, outb_p */ +#include /* copy to/from user */ #include /* kernel radio structs */ -#include /* for KERNEL_VERSION MACRO */ -#include -#include /* outb, outb_p */ #include -#include +#include +#include -#define RADIO_VERSION KERNEL_VERSION(0, 0, 3) +#include /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,0,3) +#define RADIO_BANNER "GemTek Radio card driver: v0.0.3" /* * Module info. @@ -55,6 +57,7 @@ static int shutdown = 1; static int keepmuted = 1; static int initmute = 1; static int radio_nr = -1; +static unsigned long in_use; module_param(io, int, 0444); MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic " @@ -109,19 +112,12 @@ module_param(radio_nr, int, 0444); #define SHORT_DELAY 5 /* usec */ #define LONG_DELAY 75 /* usec */ -struct gemtek { - struct v4l2_device v4l2_dev; - struct video_device vdev; - struct mutex lock; +struct gemtek_device { unsigned long lastfreq; int muted; - int verified; - int io; u32 bu2614data; }; -static struct gemtek gemtek_card; - #define BU2614_FREQ_BITS 16 /* D0..D15, Frequency data */ #define BU2614_PORT_BITS 3 /* P0..P2, Output port control data */ #define BU2614_VOID_BITS 4 /* unused */ @@ -157,6 +153,10 @@ static struct gemtek gemtek_card; #define BU2614_FMUN_MASK MKMASK(FMUN) #define BU2614_TEST_MASK MKMASK(TEST) +static struct gemtek_device gemtek_unit; + +static spinlock_t lock; + /* * Set data which will be sent to BU2614FS. */ @@ -166,33 +166,33 @@ static struct gemtek gemtek_card; /* * Transmit settings to BU2614FS over GemTek IC. */ -static void gemtek_bu2614_transmit(struct gemtek *gt) +static void gemtek_bu2614_transmit(struct gemtek_device *dev) { int i, bit, q, mute; - mutex_lock(>->lock); + spin_lock(&lock); - mute = gt->muted ? GEMTEK_MT : 0x00; + mute = dev->muted ? GEMTEK_MT : 0x00; - outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io); + outb_p(mute | GEMTEK_DA | GEMTEK_CK, io); udelay(SHORT_DELAY); - outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io); + outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, io); udelay(LONG_DELAY); - for (i = 0, q = gt->bu2614data; i < 32; i++, q >>= 1) { - bit = (q & 1) ? GEMTEK_DA : 0; - outb_p(mute | GEMTEK_CE | bit, gt->io); - udelay(SHORT_DELAY); - outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, gt->io); - udelay(SHORT_DELAY); + for (i = 0, q = dev->bu2614data; i < 32; i++, q >>= 1) { + bit = (q & 1) ? GEMTEK_DA : 0; + outb_p(mute | GEMTEK_CE | bit, io); + udelay(SHORT_DELAY); + outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, io); + udelay(SHORT_DELAY); } - outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io); + outb_p(mute | GEMTEK_DA | GEMTEK_CK, io); udelay(SHORT_DELAY); - outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io); + outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, io); udelay(LONG_DELAY); - mutex_unlock(>->lock); + spin_unlock(&lock); } /* @@ -206,109 +206,107 @@ static unsigned long gemtek_convfreq(unsigned long freq) /* * Set FM-frequency. */ -static void gemtek_setfreq(struct gemtek *gt, unsigned long freq) +static void gemtek_setfreq(struct gemtek_device *dev, unsigned long freq) { - if (keepmuted && hardmute && gt->muted) + + if (keepmuted && hardmute && dev->muted) return; - freq = clamp_val(freq, GEMTEK_LOWFREQ, GEMTEK_HIGHFREQ); + if (freq < GEMTEK_LOWFREQ) + freq = GEMTEK_LOWFREQ; + else if (freq > GEMTEK_HIGHFREQ) + freq = GEMTEK_HIGHFREQ; - gt->lastfreq = freq; - gt->muted = 0; + dev->lastfreq = freq; + dev->muted = 0; - gemtek_bu2614_set(gt, BU2614_PORT, 0); - gemtek_bu2614_set(gt, BU2614_FMES, 0); - gemtek_bu2614_set(gt, BU2614_SWIN, 0); /* FM-mode */ - gemtek_bu2614_set(gt, BU2614_SWAL, 0); - gemtek_bu2614_set(gt, BU2614_FMUN, 1); /* GT bit set */ - gemtek_bu2614_set(gt, BU2614_TEST, 0); + gemtek_bu2614_set(dev, BU2614_PORT, 0); + gemtek_bu2614_set(dev, BU2614_FMES, 0); + gemtek_bu2614_set(dev, BU2614_SWIN, 0); /* FM-mode */ + gemtek_bu2614_set(dev, BU2614_SWAL, 0); + gemtek_bu2614_set(dev, BU2614_FMUN, 1); /* GT bit set */ + gemtek_bu2614_set(dev, BU2614_TEST, 0); - gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_STDF_3_125_KHZ); - gemtek_bu2614_set(gt, BU2614_FREQ, gemtek_convfreq(freq)); + gemtek_bu2614_set(dev, BU2614_STDF, GEMTEK_STDF_3_125_KHZ); + gemtek_bu2614_set(dev, BU2614_FREQ, gemtek_convfreq(freq)); - gemtek_bu2614_transmit(gt); + gemtek_bu2614_transmit(dev); } /* * Set mute flag. */ -static void gemtek_mute(struct gemtek *gt) +static void gemtek_mute(struct gemtek_device *dev) { int i; - - gt->muted = 1; + dev->muted = 1; if (hardmute) { /* Turn off PLL, disable data output */ - gemtek_bu2614_set(gt, BU2614_PORT, 0); - gemtek_bu2614_set(gt, BU2614_FMES, 0); /* CT bit off */ - gemtek_bu2614_set(gt, BU2614_SWIN, 0); /* FM-mode */ - gemtek_bu2614_set(gt, BU2614_SWAL, 0); - gemtek_bu2614_set(gt, BU2614_FMUN, 0); /* GT bit off */ - gemtek_bu2614_set(gt, BU2614_TEST, 0); - gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_PLL_OFF); - gemtek_bu2614_set(gt, BU2614_FREQ, 0); - gemtek_bu2614_transmit(gt); - return; - } - - mutex_lock(>->lock); + gemtek_bu2614_set(dev, BU2614_PORT, 0); + gemtek_bu2614_set(dev, BU2614_FMES, 0); /* CT bit off */ + gemtek_bu2614_set(dev, BU2614_SWIN, 0); /* FM-mode */ + gemtek_bu2614_set(dev, BU2614_SWAL, 0); + gemtek_bu2614_set(dev, BU2614_FMUN, 0); /* GT bit off */ + gemtek_bu2614_set(dev, BU2614_TEST, 0); + gemtek_bu2614_set(dev, BU2614_STDF, GEMTEK_PLL_OFF); + gemtek_bu2614_set(dev, BU2614_FREQ, 0); + gemtek_bu2614_transmit(dev); + } else { + spin_lock(&lock); - /* Read bus contents (CE, CK and DA). */ - i = inb_p(gt->io); - /* Write it back with mute flag set. */ - outb_p((i >> 5) | GEMTEK_MT, gt->io); - udelay(SHORT_DELAY); + /* Read bus contents (CE, CK and DA). */ + i = inb_p(io); + /* Write it back with mute flag set. */ + outb_p((i >> 5) | GEMTEK_MT, io); + udelay(SHORT_DELAY); - mutex_unlock(>->lock); + spin_unlock(&lock); + } } /* * Unset mute flag. */ -static void gemtek_unmute(struct gemtek *gt) +static void gemtek_unmute(struct gemtek_device *dev) { int i; + dev->muted = 0; - gt->muted = 0; if (hardmute) { /* Turn PLL back on. */ - gemtek_setfreq(gt, gt->lastfreq); - return; - } - mutex_lock(>->lock); + gemtek_setfreq(dev, dev->lastfreq); + } else { + spin_lock(&lock); - i = inb_p(gt->io); - outb_p(i >> 5, gt->io); - udelay(SHORT_DELAY); + i = inb_p(io); + outb_p(i >> 5, io); + udelay(SHORT_DELAY); - mutex_unlock(>->lock); + spin_unlock(&lock); + } } /* * Get signal strength (= stereo status). */ -static inline int gemtek_getsigstr(struct gemtek *gt) +static inline int gemtek_getsigstr(void) { - int sig; - - mutex_lock(>->lock); - sig = inb_p(gt->io) & GEMTEK_NS ? 0 : 1; - mutex_unlock(>->lock); - return sig; + return inb_p(io) & GEMTEK_NS ? 0 : 1; } /* * Check if requested card acts like GemTek Radio card. */ -static int gemtek_verify(struct gemtek *gt, int port) +static int gemtek_verify(int port) { + static int verified = -1; int i, q; - if (gt->verified == port) + if (verified == port) return 1; - mutex_lock(>->lock); + spin_lock(&lock); q = inb_p(port); /* Read bus contents before probing. */ /* Try to turn on CE, CK and DA respectively and check if card responds @@ -318,15 +316,15 @@ static int gemtek_verify(struct gemtek *gt, int port) udelay(SHORT_DELAY); if ((inb_p(port) & (~GEMTEK_NS)) != (0x17 | (1 << (i + 5)))) { - mutex_unlock(>->lock); + spin_unlock(&lock); return 0; } } outb_p(q >> 5, port); /* Write bus contents back. */ udelay(SHORT_DELAY); - mutex_unlock(>->lock); - gt->verified = port; + spin_unlock(&lock); + verified = port; return 1; } @@ -334,61 +332,83 @@ static int gemtek_verify(struct gemtek *gt, int port) /* * Automatic probing for card. */ -static int gemtek_probe(struct gemtek *gt) +static int gemtek_probe(void) { - struct v4l2_device *v4l2_dev = >->v4l2_dev; int ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c }; int i; if (!probe) { - v4l2_info(v4l2_dev, "Automatic device probing disabled.\n"); + printk(KERN_INFO "Automatic device probing disabled.\n"); return -1; } - v4l2_info(v4l2_dev, "Automatic device probing enabled.\n"); + printk(KERN_INFO "Automatic device probing enabled.\n"); for (i = 0; i < ARRAY_SIZE(ioports); ++i) { - v4l2_info(v4l2_dev, "Trying I/O port 0x%x...\n", ioports[i]); + printk(KERN_INFO "Trying I/O port 0x%x...\n", ioports[i]); if (!request_region(ioports[i], 1, "gemtek-probe")) { - v4l2_warn(v4l2_dev, "I/O port 0x%x busy!\n", + printk(KERN_WARNING "I/O port 0x%x busy!\n", ioports[i]); continue; } - if (gemtek_verify(gt, ioports[i])) { - v4l2_info(v4l2_dev, "Card found from I/O port " + if (gemtek_verify(ioports[i])) { + printk(KERN_INFO "Card found from I/O port " "0x%x!\n", ioports[i]); release_region(ioports[i], 1); - gt->io = ioports[i]; - return gt->io; + + io = ioports[i]; + return io; } release_region(ioports[i], 1); } - v4l2_err(v4l2_dev, "Automatic probing failed!\n"); + printk(KERN_ERR "Automatic probing failed!\n"); + return -1; } /* * Video 4 Linux stuff. */ -static int gemtek_open(struct file *file) + +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + }, { + .id = V4L2_CID_AUDIO_VOLUME, + .name = "Volume", + .minimum = 0, + .maximum = 65535, + .step = 65535, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; + +static int gemtek_exclusive_open(struct file *file) { - return 0; + return test_and_set_bit(0, &in_use) ? -EBUSY : 0; } -static int gemtek_release(struct file *file) +static int gemtek_exclusive_release(struct file *file) { + clear_bit(0, &in_use); return 0; } static const struct v4l2_file_operations gemtek_fops = { .owner = THIS_MODULE, - .open = gemtek_open, - .release = gemtek_release, + .open = gemtek_exclusive_open, + .release = gemtek_exclusive_release, .ioctl = video_ioctl2, }; @@ -397,25 +417,23 @@ static int vidioc_querycap(struct file *file, void *priv, { strlcpy(v->driver, "radio-gemtek", sizeof(v->driver)); strlcpy(v->card, "GemTek", sizeof(v->card)); - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); + sprintf(v->bus_info, "ISA"); v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->capabilities = V4L2_CAP_TUNER; return 0; } static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct gemtek *gt = video_drvdata(file); - if (v->index > 0) return -EINVAL; - strlcpy(v->name, "FM", sizeof(v->name)); + strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; v->rangelow = GEMTEK_LOWFREQ; v->rangehigh = GEMTEK_HIGHFREQ; v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; - v->signal = 0xffff * gemtek_getsigstr(gt); + v->signal = 0xffff * gemtek_getsigstr(); if (v->signal) { v->audmode = V4L2_TUNER_MODE_STEREO; v->rxsubchans = V4L2_TUNER_SUB_STEREO; @@ -423,56 +441,65 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) v->audmode = V4L2_TUNER_MODE_MONO; v->rxsubchans = V4L2_TUNER_SUB_MONO; } + return 0; } static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - return (v->index != 0) ? -EINVAL : 0; + if (v->index > 0) + return -EINVAL; + return 0; } -static int vidioc_g_frequency(struct file *file, void *priv, +static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct gemtek *gt = video_drvdata(file); + struct gemtek_device *rt = video_drvdata(file); + + gemtek_setfreq(rt, f->frequency); - if (f->tuner != 0) - return -EINVAL; - f->type = V4L2_TUNER_RADIO; - f->frequency = gt->lastfreq; return 0; } -static int vidioc_s_frequency(struct file *file, void *priv, +static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct gemtek *gt = video_drvdata(file); + struct gemtek_device *rt = video_drvdata(file); - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) - return -EINVAL; - gemtek_setfreq(gt, f->frequency); + f->type = V4L2_TUNER_RADIO; + f->frequency = rt->lastfreq; return 0; } static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); - default: - return -EINVAL; + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); ++i) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), sizeof(*qc)); + return 0; + } } + return -EINVAL; } static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct gemtek *gt = video_drvdata(file); + struct gemtek_device *rt = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: - ctrl->value = gt->muted; + ctrl->value = rt->muted; + return 0; + case V4L2_CID_AUDIO_VOLUME: + if (rt->muted) + ctrl->value = 0; + else + ctrl->value = 65535; return 0; } return -EINVAL; @@ -481,41 +508,53 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct gemtek *gt = video_drvdata(file); + struct gemtek_device *rt = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: if (ctrl->value) - gemtek_mute(gt); + gemtek_mute(rt); + else + gemtek_unmute(rt); + return 0; + case V4L2_CID_AUDIO_VOLUME: + if (ctrl->value) + gemtek_unmute(rt); else - gemtek_unmute(gt); + gemtek_mute(rt); return 0; } return -EINVAL; } -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) { - *i = 0; + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; return 0; } -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { - return (i != 0) ? -EINVAL : 0; + *i = 0; + return 0; } -static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; + if (i != 0) + return -EINVAL; return 0; } static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) { - return (a->index != 0) ? -EINVAL : 0; + if (a->index != 0) + return -EINVAL; + return 0; } static const struct v4l2_ioctl_ops gemtek_ioctl_ops = { @@ -533,73 +572,62 @@ static const struct v4l2_ioctl_ops gemtek_ioctl_ops = { .vidioc_s_ctrl = vidioc_s_ctrl }; +static struct video_device gemtek_radio = { + .name = "GemTek Radio card", + .fops = &gemtek_fops, + .ioctl_ops = &gemtek_ioctl_ops, + .release = video_device_release_empty, +}; + /* * Initialization / cleanup related stuff. */ +/* + * Initilize card. + */ static int __init gemtek_init(void) { - struct gemtek *gt = &gemtek_card; - struct v4l2_device *v4l2_dev = >->v4l2_dev; - int res; + printk(KERN_INFO RADIO_BANNER "\n"); - strlcpy(v4l2_dev->name, "gemtek", sizeof(v4l2_dev->name)); + spin_lock_init(&lock); - v4l2_info(v4l2_dev, "GemTek Radio card driver: v0.0.3\n"); - - mutex_init(>->lock); - - gt->verified = -1; - gt->io = io; - gemtek_probe(gt); - if (gt->io) { - if (!request_region(gt->io, 1, "gemtek")) { - v4l2_err(v4l2_dev, "I/O port 0x%x already in use.\n", gt->io); + gemtek_probe(); + if (io) { + if (!request_region(io, 1, "gemtek")) { + printk(KERN_ERR "I/O port 0x%x already in use.\n", io); return -EBUSY; } - if (!gemtek_verify(gt, gt->io)) - v4l2_warn(v4l2_dev, "Card at I/O port 0x%x does not " + if (!gemtek_verify(io)) + printk(KERN_WARNING "Card at I/O port 0x%x does not " "respond properly, check your " - "configuration.\n", gt->io); + "configuration.\n", io); else - v4l2_info(v4l2_dev, "Using I/O port 0x%x.\n", gt->io); + printk(KERN_INFO "Using I/O port 0x%x.\n", io); } else if (probe) { - v4l2_err(v4l2_dev, "Automatic probing failed and no " + printk(KERN_ERR "Automatic probing failed and no " "fixed I/O port defined.\n"); return -ENODEV; } else { - v4l2_err(v4l2_dev, "Automatic probing disabled but no fixed " + printk(KERN_ERR "Automatic probing disabled but no fixed " "I/O port defined."); return -EINVAL; } - res = v4l2_device_register(NULL, v4l2_dev); - if (res < 0) { - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); - release_region(gt->io, 1); - return res; - } + video_set_drvdata(&gemtek_radio, &gemtek_unit); - strlcpy(gt->vdev.name, v4l2_dev->name, sizeof(gt->vdev.name)); - gt->vdev.v4l2_dev = v4l2_dev; - gt->vdev.fops = &gemtek_fops; - gt->vdev.ioctl_ops = &gemtek_ioctl_ops; - gt->vdev.release = video_device_release_empty; - video_set_drvdata(>->vdev, gt); - - if (video_register_device(>->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { - v4l2_device_unregister(v4l2_dev); - release_region(gt->io, 1); + if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr) < 0) { + release_region(io, 1); return -EBUSY; } /* Set defaults */ - gt->lastfreq = GEMTEK_LOWFREQ; - gt->bu2614data = 0; + gemtek_unit.lastfreq = GEMTEK_LOWFREQ; + gemtek_unit.bu2614data = 0; if (initmute) - gemtek_mute(gt); + gemtek_mute(&gemtek_unit); return 0; } @@ -609,19 +637,15 @@ static int __init gemtek_init(void) */ static void __exit gemtek_exit(void) { - struct gemtek *gt = &gemtek_card; - struct v4l2_device *v4l2_dev = >->v4l2_dev; - if (shutdown) { hardmute = 1; /* Turn off PLL */ - gemtek_mute(gt); + gemtek_mute(&gemtek_unit); } else { - v4l2_info(v4l2_dev, "Module unloaded but card not muted!\n"); + printk(KERN_INFO "Module unloaded but card not muted!\n"); } - video_unregister_device(>->vdev); - v4l2_device_unregister(>->v4l2_dev); - release_region(gt->io, 1); + video_unregister_device(&gemtek_radio); + release_region(io, 1); } module_init(gemtek_init); diff --git a/trunk/drivers/media/radio/radio-maestro.c b/trunk/drivers/media/radio/radio-maestro.c index 01a6d22950ad..ba3a13a90013 100644 --- a/trunk/drivers/media/radio/radio-maestro.c +++ b/trunk/drivers/media/radio/radio-maestro.c @@ -22,23 +22,28 @@ #include #include #include -#include /* for KERNEL_VERSION MACRO */ +#include +#include #include #include -#include -#include +#include #include -MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl"); -MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio."); -MODULE_LICENSE("GPL"); - -static int radio_nr = -1; -module_param(radio_nr, int, 0); - -#define RADIO_VERSION KERNEL_VERSION(0, 0, 6) +#include /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,0,6) #define DRIVER_VERSION "0.06" +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + } +}; + #define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */ #define IO_MASK 4 /* mask register offset from GPIO_DATA @@ -67,27 +72,62 @@ module_param(radio_nr, int, 0); #define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF) -struct maestro { - struct v4l2_device v4l2_dev; - struct video_device vdev; - struct pci_dev *pdev; - struct mutex lock; +static int radio_nr = -1; +module_param(radio_nr, int, 0); - u16 io; /* base of Maestro card radio io (GPIO_DATA)*/ - u16 muted; /* VIDEO_AUDIO_MUTE */ - u16 stereo; /* VIDEO_TUNER_STEREO_ON */ - u16 tuned; /* signal strength (0 or 0xffff) */ -}; +static unsigned long in_use; + +static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static inline struct maestro *to_maestro(struct v4l2_device *v4l2_dev) +static int maestro_exclusive_open(struct file *file) { - return container_of(v4l2_dev, struct maestro, v4l2_dev); + return test_and_set_bit(0, &in_use) ? -EBUSY : 0; } -static u32 radio_bits_get(struct maestro *dev) +static int maestro_exclusive_release(struct file *file) { - u16 io = dev->io, l, rdata; - u32 data = 0; + clear_bit(0, &in_use); + return 0; +} + +static void maestro_remove(struct pci_dev *pdev); + +static struct pci_device_id maestro_r_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968), + .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8, + .class_mask = 0xffff00 }, + { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978), + .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8, + .class_mask = 0xffff00 }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl); + +static struct pci_driver maestro_r_driver = { + .name = "maestro_radio", + .id_table = maestro_r_pci_tbl, + .probe = maestro_probe, + .remove = __devexit_p(maestro_remove), +}; + +static const struct v4l2_file_operations maestro_fops = { + .owner = THIS_MODULE, + .open = maestro_exclusive_open, + .release = maestro_exclusive_release, + .ioctl = video_ioctl2, +}; + +struct radio_device { + u16 io, /* base of Maestro card radio io (GPIO_DATA)*/ + muted, /* VIDEO_AUDIO_MUTE */ + stereo, /* VIDEO_TUNER_STEREO_ON */ + tuned; /* signal strength (0 or 0xffff) */ +}; + +static u32 radio_bits_get(struct radio_device *dev) +{ + register u16 io=dev->io, l, rdata; + register u32 data=0; u16 omask; omask = inw(io + IO_MASK); @@ -95,23 +135,25 @@ static u32 radio_bits_get(struct maestro *dev) outw(0, io); udelay(16); - for (l = 24; l--;) { + for (l=24;l--;) { outw(STR_CLK, io); /* HI state */ udelay(2); - if (!l) + if(!l) dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff; outw(0, io); /* LO state */ udelay(2); data <<= 1; /* shift data */ rdata = inw(io); - if (!l) - dev->stereo = (rdata & STR_MOST) ? 0 : 1; - else if (rdata & STR_DATA) - data++; + if(!l) + dev->stereo = rdata & STR_MOST ? + 0 : 1; + else + if(rdata & STR_DATA) + data++; udelay(2); } - if (dev->muted) + if(dev->muted) outw(STR_WREN, io); udelay(4); @@ -120,18 +162,18 @@ static u32 radio_bits_get(struct maestro *dev) return data & 0x3ffe; } -static void radio_bits_set(struct maestro *dev, u32 data) +static void radio_bits_set(struct radio_device *dev, u32 data) { - u16 io = dev->io, l, bits; + register u16 io=dev->io, l, bits; u16 omask, odir; omask = inw(io + IO_MASK); - odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN); + odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN); outw(odir | STR_DATA, io + IO_DIR); outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK); udelay(16); - for (l = 25; l; l--) { - bits = ((data >> 18) & STR_DATA) | STR_WREN; + for (l=25;l;l--) { + bits = ((data >> 18) & STR_DATA) | STR_WREN ; data <<= 1; /* shift data */ outw(bits, io); /* start strobe */ udelay(2); @@ -141,7 +183,7 @@ static void radio_bits_set(struct maestro *dev, u32 data) udelay(4); } - if (!dev->muted) + if(!dev->muted) outw(0, io); udelay(4); @@ -153,79 +195,78 @@ static void radio_bits_set(struct maestro *dev, u32 data) static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *v) { - struct maestro *dev = video_drvdata(file); - strlcpy(v->driver, "radio-maestro", sizeof(v->driver)); strlcpy(v->card, "Maestro Radio", sizeof(v->card)); - snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev)); + sprintf(v->bus_info, "PCI"); v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->capabilities = V4L2_CAP_TUNER; return 0; } static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct maestro *dev = video_drvdata(file); + struct radio_device *card = video_drvdata(file); if (v->index > 0) return -EINVAL; - mutex_lock(&dev->lock); - radio_bits_get(dev); + (void)radio_bits_get(card); - strlcpy(v->name, "FM", sizeof(v->name)); + strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; v->rangelow = FREQ_LO; v->rangehigh = FREQ_HI; - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; + v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; v->capability = V4L2_TUNER_CAP_LOW; - if (dev->stereo) + if(card->stereo) v->audmode = V4L2_TUNER_MODE_STEREO; else v->audmode = V4L2_TUNER_MODE_MONO; - v->signal = dev->tuned; - mutex_unlock(&dev->lock); + v->signal = card->tuned; return 0; } static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - return v->index ? -EINVAL : 0; + if (v->index > 0) + return -EINVAL; + return 0; } static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct maestro *dev = video_drvdata(file); + struct radio_device *card = video_drvdata(file); if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) return -EINVAL; - mutex_lock(&dev->lock); - radio_bits_set(dev, FREQ2BITS(f->frequency)); - mutex_unlock(&dev->lock); + radio_bits_set(card, FREQ2BITS(f->frequency)); return 0; } static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct maestro *dev = video_drvdata(file); + struct radio_device *card = video_drvdata(file); f->type = V4L2_TUNER_RADIO; - mutex_lock(&dev->lock); - f->frequency = BITS2FREQ(radio_bits_get(dev)); - mutex_unlock(&dev->lock); + f->frequency = BITS2FREQ(radio_bits_get(card)); return 0; } static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); + return 0; + } } return -EINVAL; } @@ -233,11 +274,11 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct maestro *dev = video_drvdata(file); + struct radio_device *card = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: - ctrl->value = dev->muted; + ctrl->value = card->muted; return 0; } return -EINVAL; @@ -246,85 +287,56 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct maestro *dev = video_drvdata(file); - u16 io = dev->io; - u16 omask; + struct radio_device *card = video_drvdata(file); + register u16 io = card->io; + register u16 omask = inw(io + IO_MASK); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: - mutex_lock(&dev->lock); - omask = inw(io + IO_MASK); outw(~STR_WREN, io + IO_MASK); - dev->muted = ctrl->value; - outw(dev->muted ? STR_WREN : 0, io); + outw((card->muted = ctrl->value ) ? + STR_WREN : 0, io); udelay(4); outw(omask, io + IO_MASK); msleep(125); - mutex_unlock(&dev->lock); return 0; } return -EINVAL; } -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) -{ - *i = 0; - return 0; -} - -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) -{ - return i ? -EINVAL : 0; -} - static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) { - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); a->capability = V4L2_AUDCAP_STEREO; return 0; } -static int vidioc_s_audio(struct file *file, void *priv, - struct v4l2_audio *a) +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { - return a->index ? -EINVAL : 0; + *i = 0; + return 0; } -static int maestro_open(struct file *file) +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { + if (i != 0) + return -EINVAL; return 0; } -static int maestro_release(struct file *file) +static int vidioc_s_audio(struct file *file, void *priv, + struct v4l2_audio *a) { + if (a->index != 0) + return -EINVAL; return 0; } -static const struct v4l2_file_operations maestro_fops = { - .owner = THIS_MODULE, - .open = maestro_open, - .release = maestro_release, - .ioctl = video_ioctl2, -}; - -static const struct v4l2_ioctl_ops maestro_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_audio = vidioc_g_audio, - .vidioc_s_audio = vidioc_s_audio, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, -}; - -static u16 __devinit radio_power_on(struct maestro *dev) +static u16 __devinit radio_power_on(struct radio_device *dev) { register u16 io = dev->io; register u32 ofreq; @@ -348,11 +360,33 @@ static u16 __devinit radio_power_on(struct maestro *dev) return (ofreq == radio_bits_get(dev)); } +static const struct v4l2_ioctl_ops maestro_ioctl_ops = { + .vidioc_querycap = vidioc_querycap, + .vidioc_g_tuner = vidioc_g_tuner, + .vidioc_s_tuner = vidioc_s_tuner, + .vidioc_g_audio = vidioc_g_audio, + .vidioc_s_audio = vidioc_s_audio, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, + .vidioc_g_frequency = vidioc_g_frequency, + .vidioc_s_frequency = vidioc_s_frequency, + .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, +}; + +static struct video_device maestro_radio = { + .name = "Maestro radio", + .fops = &maestro_fops, + .ioctl_ops = &maestro_ioctl_ops, + .release = video_device_release, +}; + static int __devinit maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - struct maestro *dev; - struct v4l2_device *v4l2_dev; + struct radio_device *radio_unit; + struct video_device *maestro_radio_inst; int retval; retval = pci_enable_device(pdev); @@ -363,53 +397,46 @@ static int __devinit maestro_probe(struct pci_dev *pdev, retval = -ENOMEM; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) { + radio_unit = kzalloc(sizeof(*radio_unit), GFP_KERNEL); + if (radio_unit == NULL) { dev_err(&pdev->dev, "not enough memory\n"); goto err; } - v4l2_dev = &dev->v4l2_dev; - mutex_init(&dev->lock); - dev->pdev = pdev; + radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA; - strlcpy(v4l2_dev->name, "maestro", sizeof(v4l2_dev->name)); - - retval = v4l2_device_register(&pdev->dev, v4l2_dev); - if (retval < 0) { - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); + maestro_radio_inst = video_device_alloc(); + if (maestro_radio_inst == NULL) { + dev_err(&pdev->dev, "not enough memory\n"); goto errfr; } - dev->io = pci_resource_start(pdev, 0) + GPIO_DATA; + memcpy(maestro_radio_inst, &maestro_radio, sizeof(maestro_radio)); + video_set_drvdata(maestro_radio_inst, radio_unit); + pci_set_drvdata(pdev, maestro_radio_inst); - strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); - dev->vdev.v4l2_dev = v4l2_dev; - dev->vdev.fops = &maestro_fops; - dev->vdev.ioctl_ops = &maestro_ioctl_ops; - dev->vdev.release = video_device_release_empty; - video_set_drvdata(&dev->vdev, dev); - - retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr); + retval = video_register_device(maestro_radio_inst, VFL_TYPE_RADIO, radio_nr); if (retval) { - v4l2_err(v4l2_dev, "can't register video device!\n"); + printk(KERN_ERR "can't register video device!\n"); goto errfr1; } - if (!radio_power_on(dev)) { + if (!radio_power_on(radio_unit)) { retval = -EIO; goto errunr; } - v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n"); + dev_info(&pdev->dev, "version " DRIVER_VERSION " time " __TIME__ " " + __DATE__ "\n"); + dev_info(&pdev->dev, "radio chip initialized\n"); return 0; errunr: - video_unregister_device(&dev->vdev); + video_unregister_device(maestro_radio_inst); errfr1: - v4l2_device_unregister(v4l2_dev); + video_device_release(maestro_radio_inst); errfr: - kfree(dev); + kfree(radio_unit); err: return retval; @@ -417,31 +444,11 @@ static int __devinit maestro_probe(struct pci_dev *pdev, static void __devexit maestro_remove(struct pci_dev *pdev) { - struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); - struct maestro *dev = to_maestro(v4l2_dev); + struct video_device *vdev = pci_get_drvdata(pdev); - video_unregister_device(&dev->vdev); - v4l2_device_unregister(&dev->v4l2_dev); + video_unregister_device(vdev); } -static struct pci_device_id maestro_r_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968), - .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8, - .class_mask = 0xffff00 }, - { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978), - .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8, - .class_mask = 0xffff00 }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl); - -static struct pci_driver maestro_r_driver = { - .name = "maestro_radio", - .id_table = maestro_r_pci_tbl, - .probe = maestro_probe, - .remove = __devexit_p(maestro_remove), -}; - static int __init maestro_radio_init(void) { int retval = pci_register_driver(&maestro_r_driver); @@ -459,3 +466,7 @@ static void __exit maestro_radio_exit(void) module_init(maestro_radio_init); module_exit(maestro_radio_exit); + +MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl"); +MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio."); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/radio/radio-maxiradio.c b/trunk/drivers/media/radio/radio-maxiradio.c index 2606f0b30355..c5dc00aa9c9f 100644 --- a/trunk/drivers/media/radio/radio-maxiradio.c +++ b/trunk/drivers/media/radio/radio-maxiradio.c @@ -37,32 +37,38 @@ #include #include #include +#include +#include #include + #include #include -#include /* for KERNEL_VERSION MACRO */ -#include -#include +#include #include -MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net"); -MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio."); -MODULE_LICENSE("GPL"); - -static int radio_nr = -1; -module_param(radio_nr, int, 0); - -static int debug; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "activates debug info"); - #define DRIVER_VERSION "0.77" -#define RADIO_VERSION KERNEL_VERSION(0, 7, 7) - -#define dprintk(dev, num, fmt, arg...) \ - v4l2_dbg(num, debug, &dev->v4l2_dev, fmt, ## arg) +#include /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,7,7) + +static struct video_device maxiradio_radio; + +#define dprintk(num, fmt, arg...) \ + do { \ + if (maxiradio_radio.debug >= num) \ + printk(KERN_DEBUG "%s: " fmt, \ + maxiradio_radio.name, ## arg); } while (0) + +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + } +}; #ifndef PCI_VENDOR_ID_GUILLEMOT #define PCI_VENDOR_ID_GUILLEMOT 0x5046 @@ -74,70 +80,90 @@ MODULE_PARM_DESC(debug, "activates debug info"); /* TEA5757 pin mappings */ -static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16; +static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16 ; + +static int radio_nr = -1; +module_param(radio_nr, int, 0); -#define FREQ_LO (50 * 16000) -#define FREQ_HI (150 * 16000) +static unsigned long in_use; + +#define FREQ_LO 50*16000 +#define FREQ_HI 150*16000 #define FREQ_IF 171200 /* 10.7*16000 */ #define FREQ_STEP 200 /* 12.5*16 */ /* (x==fmhz*16*1000) -> bits */ -#define FREQ2BITS(x) \ - ((((unsigned int)(x) + FREQ_IF + (FREQ_STEP << 1)) / (FREQ_STEP << 2)) << 2) +#define FREQ2BITS(x) ((( (unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1)) \ + /(FREQ_STEP<<2))<<2) #define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF) -struct maxiradio +static int maxiradio_exclusive_open(struct file *file) { - struct v4l2_device v4l2_dev; - struct video_device vdev; - struct pci_dev *pdev; + return test_and_set_bit(0, &in_use) ? -EBUSY : 0; +} + +static int maxiradio_exclusive_release(struct file *file) +{ + clear_bit(0, &in_use); + return 0; +} + +static const struct v4l2_file_operations maxiradio_fops = { + .owner = THIS_MODULE, + .open = maxiradio_exclusive_open, + .release = maxiradio_exclusive_release, + .ioctl = video_ioctl2, +}; - u16 io; /* base of radio io */ - u16 muted; /* VIDEO_AUDIO_MUTE */ - u16 stereo; /* VIDEO_TUNER_STEREO_ON */ - u16 tuned; /* signal strength (0 or 0xffff) */ +static struct radio_device +{ + __u16 io, /* base of radio io */ + muted, /* VIDEO_AUDIO_MUTE */ + stereo, /* VIDEO_TUNER_STEREO_ON */ + tuned; /* signal strength (0 or 0xffff) */ unsigned long freq; struct mutex lock; +} radio_unit = { + .muted =1, + .freq = FREQ_LO, }; -static inline struct maxiradio *to_maxiradio(struct v4l2_device *v4l2_dev) -{ - return container_of(v4l2_dev, struct maxiradio, v4l2_dev); -} - -static void outbit(unsigned long bit, u16 io) +static void outbit(unsigned long bit, __u16 io) { - int val = power | wren | (bit ? data : 0); - - outb(val, io); - udelay(4); - outb(val | clk, io); - udelay(4); - outb(val, io); - udelay(4); + if (bit != 0) + { + outb( power|wren|data ,io); udelay(4); + outb( power|wren|data|clk ,io); udelay(4); + outb( power|wren|data ,io); udelay(4); + } + else + { + outb( power|wren ,io); udelay(4); + outb( power|wren|clk ,io); udelay(4); + outb( power|wren ,io); udelay(4); + } } -static void turn_power(struct maxiradio *dev, int p) +static void turn_power(__u16 io, int p) { if (p != 0) { - dprintk(dev, 1, "Radio powered on\n"); - outb(power, dev->io); + dprintk(1, "Radio powered on\n"); + outb(power, io); } else { - dprintk(dev, 1, "Radio powered off\n"); - outb(0, dev->io); + dprintk(1, "Radio powered off\n"); + outb(0,io); } } -static void set_freq(struct maxiradio *dev, u32 freq) +static void set_freq(__u16 io, __u32 freq) { unsigned long int si; int bl; - int io = dev->io; int val = FREQ2BITS(freq); /* TEA5757 shift register bits (see pdf) */ @@ -162,14 +188,14 @@ static void set_freq(struct maxiradio *dev, u32 freq) si >>= 1; } - dprintk(dev, 1, "Radio freq set to %d.%02d MHz\n", + dprintk(1, "Radio freq set to %d.%02d MHz\n", freq / 16000, freq % 16000 * 100 / 16000); - turn_power(dev, 1); + turn_power(io, 1); } -static int get_stereo(u16 io) +static int get_stereo(__u16 io) { outb(power,io); udelay(4); @@ -177,7 +203,7 @@ static int get_stereo(u16 io) return !(inb(io) & mo_st); } -static int get_tune(u16 io) +static int get_tune(__u16 io) { outb(power+clk,io); udelay(4); @@ -186,84 +212,95 @@ static int get_tune(u16 io) } -static int vidioc_querycap(struct file *file, void *priv, +static int vidioc_querycap (struct file *file, void *priv, struct v4l2_capability *v) { - struct maxiradio *dev = video_drvdata(file); - - strlcpy(v->driver, "radio-maxiradio", sizeof(v->driver)); - strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof(v->card)); - snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev)); + strlcpy(v->driver, "radio-maxiradio", sizeof (v->driver)); + strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->capabilities = V4L2_CAP_TUNER; + return 0; } -static int vidioc_g_tuner(struct file *file, void *priv, +static int vidioc_g_tuner (struct file *file, void *priv, struct v4l2_tuner *v) { - struct maxiradio *dev = video_drvdata(file); + struct radio_device *card = video_drvdata(file); if (v->index > 0) return -EINVAL; - mutex_lock(&dev->lock); - strlcpy(v->name, "FM", sizeof(v->name)); + memset(v,0,sizeof(*v)); + strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; - v->rangelow = FREQ_LO; - v->rangehigh = FREQ_HI; - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; - v->capability = V4L2_TUNER_CAP_LOW; - if (get_stereo(dev->io)) + + v->rangelow=FREQ_LO; + v->rangehigh=FREQ_HI; + v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; + v->capability=V4L2_TUNER_CAP_LOW; + if(get_stereo(card->io)) v->audmode = V4L2_TUNER_MODE_STEREO; else v->audmode = V4L2_TUNER_MODE_MONO; - v->signal = 0xffff * get_tune(dev->io); - mutex_unlock(&dev->lock); + v->signal=0xffff*get_tune(card->io); return 0; } -static int vidioc_s_tuner(struct file *file, void *priv, +static int vidioc_s_tuner (struct file *file, void *priv, struct v4l2_tuner *v) { - return v->index ? -EINVAL : 0; + if (v->index > 0) + return -EINVAL; + + return 0; +} + +static int vidioc_g_audio (struct file *file, void *priv, + struct v4l2_audio *a) +{ + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "FM"); + a->capability = V4L2_AUDCAP_STEREO; + return 0; } static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { *i = 0; + return 0; } static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { - return i ? -EINVAL : 0; -} + if (i != 0) + return -EINVAL; -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; return 0; } -static int vidioc_s_audio(struct file *file, void *priv, +static int vidioc_s_audio (struct file *file, void *priv, struct v4l2_audio *a) { - return a->index ? -EINVAL : 0; + if (a->index != 0) + return -EINVAL; + + return 0; } -static int vidioc_s_frequency(struct file *file, void *priv, +static int vidioc_s_frequency (struct file *file, void *priv, struct v4l2_frequency *f) { - struct maxiradio *dev = video_drvdata(file); + struct radio_device *card = video_drvdata(file); if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) { - dprintk(dev, 1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n", + dprintk(1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n", f->frequency / 16000, f->frequency % 16000 * 100 / 16000, FREQ_LO / 16000, FREQ_HI / 16000); @@ -271,91 +308,75 @@ static int vidioc_s_frequency(struct file *file, void *priv, return -EINVAL; } - mutex_lock(&dev->lock); - dev->freq = f->frequency; - set_freq(dev, dev->freq); + card->freq = f->frequency; + set_freq(card->io, card->freq); msleep(125); - mutex_unlock(&dev->lock); return 0; } -static int vidioc_g_frequency(struct file *file, void *priv, +static int vidioc_g_frequency (struct file *file, void *priv, struct v4l2_frequency *f) { - struct maxiradio *dev = video_drvdata(file); + struct radio_device *card = video_drvdata(file); f->type = V4L2_TUNER_RADIO; - f->frequency = dev->freq; + f->frequency = card->freq; - dprintk(dev, 4, "radio freq is %d.%02d MHz", + dprintk(4, "radio freq is %d.%02d MHz", f->frequency / 16000, f->frequency % 16000 * 100 / 16000); return 0; } -static int vidioc_queryctrl(struct file *file, void *priv, +static int vidioc_queryctrl (struct file *file, void *priv, struct v4l2_queryctrl *qc) { - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), sizeof(*qc)); + return (0); + } } + return -EINVAL; } -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) +static int vidioc_g_ctrl (struct file *file, void *priv, + struct v4l2_control *ctrl) { - struct maxiradio *dev = video_drvdata(file); + struct radio_device *card = video_drvdata(file); switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - ctrl->value = dev->muted; - return 0; + case V4L2_CID_AUDIO_MUTE: + ctrl->value=card->muted; + return (0); } return -EINVAL; } -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) +static int vidioc_s_ctrl (struct file *file, void *priv, + struct v4l2_control *ctrl) { - struct maxiradio *dev = video_drvdata(file); + struct radio_device *card = video_drvdata(file); switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - mutex_lock(&dev->lock); - dev->muted = ctrl->value; - if (dev->muted) - turn_power(dev, 0); - else - set_freq(dev, dev->freq); - mutex_unlock(&dev->lock); - return 0; + case V4L2_CID_AUDIO_MUTE: + card->muted = ctrl->value; + if(card->muted) + turn_power(card->io, 0); + else + set_freq(card->io, card->freq); + return 0; } return -EINVAL; } -static int maxiradio_open(struct file *file) -{ - return 0; -} - -static int maxiradio_release(struct file *file) -{ - return 0; -} - -static const struct v4l2_file_operations maxiradio_fops = { - .owner = THIS_MODULE, - .open = maxiradio_open, - .release = maxiradio_release, - .ioctl = video_ioctl2, -}; - static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, @@ -371,84 +392,60 @@ static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device maxiradio_radio = { + .name = "Maxi Radio FM2000 radio", + .fops = &maxiradio_fops, + .ioctl_ops = &maxiradio_ioctl_ops, + .release = video_device_release_empty, +}; + static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - struct maxiradio *dev; - struct v4l2_device *v4l2_dev; - int retval = -ENOMEM; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) { - dev_err(&pdev->dev, "not enough memory\n"); - return -ENOMEM; - } - - v4l2_dev = &dev->v4l2_dev; - mutex_init(&dev->lock); - dev->pdev = pdev; - dev->muted = 1; - dev->freq = FREQ_LO; - - strlcpy(v4l2_dev->name, "maxiradio", sizeof(v4l2_dev->name)); - - retval = v4l2_device_register(&pdev->dev, v4l2_dev); - if (retval < 0) { - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); - goto errfr; - } - - if (!request_region(pci_resource_start(pdev, 0), + if(!request_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) { - v4l2_err(v4l2_dev, "can't reserve I/O ports\n"); + printk(KERN_ERR "radio-maxiradio: can't reserve I/O ports\n"); goto err_out; } if (pci_enable_device(pdev)) goto err_out_free_region; - dev->io = pci_resource_start(pdev, 0); - strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); - dev->vdev.v4l2_dev = v4l2_dev; - dev->vdev.fops = &maxiradio_fops; - dev->vdev.ioctl_ops = &maxiradio_ioctl_ops; - dev->vdev.release = video_device_release_empty; - video_set_drvdata(&dev->vdev, dev); + radio_unit.io = pci_resource_start(pdev, 0); + mutex_init(&radio_unit.lock); + video_set_drvdata(&maxiradio_radio, &radio_unit); - if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { - v4l2_err(v4l2_dev, "can't register device!"); + if (video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr) < 0) { + printk("radio-maxiradio: can't register device!"); goto err_out_free_region; } - v4l2_info(v4l2_dev, "version " DRIVER_VERSION - " time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "radio-maxiradio: version " + DRIVER_VERSION + " time " + __TIME__ " " + __DATE__ + "\n"); - v4l2_info(v4l2_dev, "found Guillemot MAXI Radio device (io = 0x%x)\n", - dev->io); + printk(KERN_INFO "radio-maxiradio: found Guillemot MAXI Radio device (io = 0x%x)\n", + radio_unit.io); return 0; err_out_free_region: release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); err_out: - v4l2_device_unregister(v4l2_dev); -errfr: - kfree(dev); return -ENODEV; } static void __devexit maxiradio_remove_one(struct pci_dev *pdev) { - struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); - struct maxiradio *dev = to_maxiradio(v4l2_dev); - - video_unregister_device(&dev->vdev); - v4l2_device_unregister(&dev->v4l2_dev); + video_unregister_device(&maxiradio_radio); release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); } static struct pci_device_id maxiradio_pci_tbl[] = { { PCI_VENDOR_ID_GUILLEMOT, PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO, PCI_ANY_ID, PCI_ANY_ID, }, - { 0 } + { 0,} }; MODULE_DEVICE_TABLE(pci, maxiradio_pci_tbl); @@ -472,3 +469,10 @@ static void __exit maxiradio_radio_exit(void) module_init(maxiradio_radio_init); module_exit(maxiradio_radio_exit); + +MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net"); +MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio."); +MODULE_LICENSE("GPL"); + +module_param_named(debug,maxiradio_radio.debug, int, 0644); +MODULE_PARM_DESC(debug,"activates debug info"); diff --git a/trunk/drivers/media/radio/radio-mr800.c b/trunk/drivers/media/radio/radio-mr800.c index ded25bfb366e..fdfc7bf86b9e 100644 --- a/trunk/drivers/media/radio/radio-mr800.c +++ b/trunk/drivers/media/radio/radio-mr800.c @@ -22,7 +22,7 @@ */ /* - * Big thanks to authors and contributors of dsbr100.c and radio-si470x.c + * Big thanks to authors of dsbr100.c and radio-si470x.c * * When work was looked pretty good, i discover this: * http://av-usbradio.sourceforge.net/index.php @@ -30,23 +30,18 @@ * Latest release of theirs project was in 2005. * Probably, this driver could be improved trough using their * achievements (specifications given). - * Also, Faidon Liambotis wrote nice driver for this radio - * in 2007. He allowed to use his driver to improve current mr800 radio driver. - * http://kerneltrap.org/mailarchive/linux-usb-devel/2007/10/11/342492 + * So, we have smth to begin with. * + * History: * Version 0.01: First working version. * It's required to blacklist AverMedia USB Radio * in usbhid/hid-quirks.c - * Version 0.10: A lot of cleanups and fixes: unpluging the device, - * few mutex locks were added, codinstyle issues, etc. - * Added stereo support. Thanks to - * Douglas Schilling Landgraf and - * David Ellingsworth - * for discussion, help and support. * * Many things to do: * - Correct power managment of device (suspend & resume) + * - Make x86 independance (little-endian and big-endian stuff) * - Add code for scanning and smooth tuning + * - Checked and add stereo&mono stuff * - Add code for sensitivity value * - Correct mistakes * - In Japan another FREQ_MIN and FREQ_MAX @@ -67,8 +62,8 @@ /* driver and module definitions */ #define DRIVER_AUTHOR "Alexey Klimov " #define DRIVER_DESC "AverMedia MR 800 USB FM radio driver" -#define DRIVER_VERSION "0.10" -#define RADIO_VERSION KERNEL_VERSION(0, 1, 0) +#define DRIVER_VERSION "0.01" +#define RADIO_VERSION KERNEL_VERSION(0, 0, 1) MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); @@ -92,22 +87,6 @@ devices, that would be 76 and 91. */ #define FREQ_MAX 108.0 #define FREQ_MUL 16000 -/* - * Commands that device should understand - * List isnt full and will be updated with implementation of new functions - */ -#define AMRADIO_SET_FREQ 0xa4 -#define AMRADIO_SET_MUTE 0xab -#define AMRADIO_SET_MONO 0xae - -/* Comfortable defines for amradio_set_mute */ -#define AMRADIO_START 0x00 -#define AMRADIO_STOP 0x01 - -/* Comfortable defines for amradio_set_stereo */ -#define WANT_STEREO 0x00 -#define WANT_MONO 0x01 - /* module parameter */ static int radio_nr = -1; module_param(radio_nr, int, 0); @@ -190,48 +169,43 @@ static struct usb_driver usb_amradio_driver = { .supports_autosuspend = 0, }; -/* switch on/off the radio. Send 8 bytes to device */ -static int amradio_set_mute(struct amradio_device *radio, char argument) +/* switch on radio. Send 8 bytes to device. */ +static int amradio_start(struct amradio_device *radio) { int retval; int size; - /* safety check */ - if (radio->removed) - return -EIO; - mutex_lock(&radio->lock); radio->buffer[0] = 0x00; radio->buffer[1] = 0x55; radio->buffer[2] = 0xaa; radio->buffer[3] = 0x00; - radio->buffer[4] = AMRADIO_SET_MUTE; - radio->buffer[5] = argument; + radio->buffer[4] = 0xab; + radio->buffer[5] = 0x00; radio->buffer[6] = 0x00; radio->buffer[7] = 0x00; retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) { + if (retval) { mutex_unlock(&radio->lock); return retval; } - radio->muted = argument; + radio->muted = 0; mutex_unlock(&radio->lock); return retval; } -/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ -static int amradio_setfreq(struct amradio_device *radio, int freq) +/* switch off radio */ +static int amradio_stop(struct amradio_device *radio) { int retval; int size; - unsigned short freq_send = 0x10 + (freq >> 3) / 25; /* safety check */ if (radio->removed) @@ -242,46 +216,33 @@ static int amradio_setfreq(struct amradio_device *radio, int freq) radio->buffer[0] = 0x00; radio->buffer[1] = 0x55; radio->buffer[2] = 0xaa; - radio->buffer[3] = 0x03; - radio->buffer[4] = AMRADIO_SET_FREQ; - radio->buffer[5] = 0x00; - radio->buffer[6] = 0x00; - radio->buffer[7] = 0x08; - - retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), - (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - - if (retval < 0 || size != BUFFER_LENGTH) { - mutex_unlock(&radio->lock); - return retval; - } - - /* frequency is calculated from freq_send and placed in first 2 bytes */ - radio->buffer[0] = (freq_send >> 8) & 0xff; - radio->buffer[1] = freq_send & 0xff; - radio->buffer[2] = 0x01; radio->buffer[3] = 0x00; - radio->buffer[4] = 0x00; - /* 5 and 6 bytes of buffer already = 0x00 */ + radio->buffer[4] = 0xab; + radio->buffer[5] = 0x01; + radio->buffer[6] = 0x00; radio->buffer[7] = 0x00; retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) { + if (retval) { mutex_unlock(&radio->lock); return retval; } + radio->muted = 1; + mutex_unlock(&radio->lock); return retval; } -static int amradio_set_stereo(struct amradio_device *radio, char argument) +/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ +static int amradio_setfreq(struct amradio_device *radio, int freq) { int retval; int size; + unsigned short freq_send = 0x13 + (freq >> 3) / 25; /* safety check */ if (radio->removed) @@ -292,33 +253,50 @@ static int amradio_set_stereo(struct amradio_device *radio, char argument) radio->buffer[0] = 0x00; radio->buffer[1] = 0x55; radio->buffer[2] = 0xaa; - radio->buffer[3] = 0x00; - radio->buffer[4] = AMRADIO_SET_MONO; - radio->buffer[5] = argument; + radio->buffer[3] = 0x03; + radio->buffer[4] = 0xa4; + radio->buffer[5] = 0x00; radio->buffer[6] = 0x00; + radio->buffer[7] = 0x08; + + retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), + (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); + + if (retval) { + mutex_unlock(&radio->lock); + return retval; + } + + /* frequency is calculated from freq_send and placed in first 2 bytes */ + radio->buffer[0] = (freq_send >> 8) & 0xff; + radio->buffer[1] = freq_send & 0xff; + radio->buffer[2] = 0x01; + radio->buffer[3] = 0x00; + radio->buffer[4] = 0x00; + /* 5 and 6 bytes of buffer already = 0x00 */ radio->buffer[7] = 0x00; retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); - if (retval < 0 || size != BUFFER_LENGTH) { - radio->stereo = -1; + if (retval) { mutex_unlock(&radio->lock); return retval; } - radio->stereo = 1; + radio->stereo = 0; mutex_unlock(&radio->lock); return retval; } -/* Handle unplugging the device. - * We call video_unregister_device in any case. - * The last function called in this procedure is - * usb_amradio_device_release. - */ +/* USB subsystem interface begins here */ + +/* handle unplugging of the device, release data structures +if nothing keeps us from doing it. If something is still +keeping us busy, the release callback of v4l will take care +of releasing it. */ static void usb_amradio_disconnect(struct usb_interface *intf) { struct amradio_device *radio = usb_get_intfdata(intf); @@ -335,11 +313,9 @@ static void usb_amradio_disconnect(struct usb_interface *intf) static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *v) { - struct amradio_device *radio = video_drvdata(file); - strlcpy(v->driver, "radio-mr800", sizeof(v->driver)); strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card)); - usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info)); + sprintf(v->bus_info, "USB"); v->version = RADIO_VERSION; v->capabilities = V4L2_CAP_TUNER; return 0; @@ -350,7 +326,6 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - int retval; /* safety check */ if (radio->removed) @@ -362,16 +337,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, /* TODO: Add function which look is signal stereo or not * amradio_getstat(radio); */ - -/* we call amradio_set_stereo to set radio->stereo - * Honestly, amradio_getstat should cover this in future and - * amradio_set_stereo shouldn't be here - */ - retval = amradio_set_stereo(radio, WANT_STEREO); - if (retval < 0) - amradio_dev_warn(&radio->videodev->dev, - "set stereo failed\n"); - + radio->stereo = -1; strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; v->rangelow = FREQ_MIN * FREQ_MUL; @@ -392,7 +358,6 @@ static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - int retval; /* safety check */ if (radio->removed) @@ -400,25 +365,6 @@ static int vidioc_s_tuner(struct file *file, void *priv, if (v->index > 0) return -EINVAL; - - /* mono/stereo selector */ - switch (v->audmode) { - case V4L2_TUNER_MODE_MONO: - retval = amradio_set_stereo(radio, WANT_MONO); - if (retval < 0) - amradio_dev_warn(&radio->videodev->dev, - "set mono failed\n"); - break; - case V4L2_TUNER_MODE_STEREO: - retval = amradio_set_stereo(radio, WANT_STEREO); - if (retval < 0) - amradio_dev_warn(&radio->videodev->dev, - "set stereo failed\n"); - break; - default: - return -EINVAL; - } - return 0; } @@ -427,18 +373,13 @@ static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - int retval; /* safety check */ if (radio->removed) return -EIO; - mutex_lock(&radio->lock); radio->curfreq = f->frequency; - mutex_unlock(&radio->lock); - - retval = amradio_setfreq(radio, radio->curfreq); - if (retval < 0) + if (amradio_setfreq(radio, radio->curfreq) < 0) amradio_dev_warn(&radio->videodev->dev, "set frequency failed\n"); return 0; @@ -497,7 +438,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - int retval; /* safety check */ if (radio->removed) @@ -506,15 +446,13 @@ static int vidioc_s_ctrl(struct file *file, void *priv, switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: if (ctrl->value) { - retval = amradio_set_mute(radio, AMRADIO_STOP); - if (retval < 0) { + if (amradio_stop(radio) < 0) { amradio_dev_warn(&radio->videodev->dev, "amradio_stop failed\n"); return -1; } } else { - retval = amradio_set_mute(radio, AMRADIO_START); - if (retval < 0) { + if (amradio_start(radio) < 0) { amradio_dev_warn(&radio->videodev->dev, "amradio_start failed\n"); return -1; @@ -565,29 +503,20 @@ static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) static int usb_amradio_open(struct file *file) { struct amradio_device *radio = video_get_drvdata(video_devdata(file)); - int retval; lock_kernel(); radio->users = 1; radio->muted = 1; - retval = amradio_set_mute(radio, AMRADIO_START); - if (retval < 0) { + if (amradio_start(radio) < 0) { amradio_dev_warn(&radio->videodev->dev, "radio did not start up properly\n"); radio->users = 0; unlock_kernel(); return -EIO; } - - retval = amradio_set_stereo(radio, WANT_STEREO); - if (retval < 0) - amradio_dev_warn(&radio->videodev->dev, - "set stereo failed\n"); - - retval = amradio_setfreq(radio, radio->curfreq); - if (retval < 0) + if (amradio_setfreq(radio, radio->curfreq) < 0) amradio_dev_warn(&radio->videodev->dev, "set frequency failed\n"); @@ -604,12 +533,10 @@ static int usb_amradio_close(struct file *file) if (!radio) return -ENODEV; - mutex_lock(&radio->lock); radio->users = 0; - mutex_unlock(&radio->lock); if (!radio->removed) { - retval = amradio_set_mute(radio, AMRADIO_STOP); + retval = amradio_stop(radio); if (retval < 0) amradio_dev_warn(&radio->videodev->dev, "amradio_stop failed\n"); @@ -622,10 +549,8 @@ static int usb_amradio_close(struct file *file) static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) { struct amradio_device *radio = usb_get_intfdata(intf); - int retval; - retval = amradio_set_mute(radio, AMRADIO_STOP); - if (retval < 0) + if (amradio_stop(radio) < 0) dev_warn(&intf->dev, "amradio_stop failed\n"); dev_info(&intf->dev, "going into suspend..\n"); @@ -637,10 +562,8 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) static int usb_amradio_resume(struct usb_interface *intf) { struct amradio_device *radio = usb_get_intfdata(intf); - int retval; - retval = amradio_set_mute(radio, AMRADIO_START); - if (retval < 0) + if (amradio_start(radio) < 0) dev_warn(&intf->dev, "amradio_start failed\n"); dev_info(&intf->dev, "coming out of suspend..\n"); @@ -691,32 +614,28 @@ static struct video_device amradio_videodev_template = { .release = usb_amradio_device_release, }; -/* check if the device is present and register with v4l and usb if it is */ +/* check if the device is present and register with v4l and +usb if it is */ static int usb_amradio_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct amradio_device *radio; - int retval; radio = kmalloc(sizeof(struct amradio_device), GFP_KERNEL); - if (!radio) { - dev_err(&intf->dev, "kmalloc for amradio_device failed\n"); + if (!(radio)) return -ENOMEM; - } radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL); - if (!radio->buffer) { - dev_err(&intf->dev, "kmalloc for radio->buffer failed\n"); + if (!(radio->buffer)) { kfree(radio); return -ENOMEM; } radio->videodev = video_device_alloc(); - if (!radio->videodev) { - dev_err(&intf->dev, "video_device_alloc failed\n"); + if (!(radio->videodev)) { kfree(radio->buffer); kfree(radio); return -ENOMEM; @@ -729,14 +648,12 @@ static int usb_amradio_probe(struct usb_interface *intf, radio->users = 0; radio->usbdev = interface_to_usbdev(intf); radio->curfreq = 95.16 * FREQ_MUL; - radio->stereo = -1; mutex_init(&radio->lock); video_set_drvdata(radio->videodev, radio); - retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); - if (retval < 0) { - dev_err(&intf->dev, "could not register video device\n"); + if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { + dev_warn(&intf->dev, "could not register video device\n"); video_device_release(radio->videodev); kfree(radio->buffer); kfree(radio); diff --git a/trunk/drivers/media/radio/radio-rtrack2.c b/trunk/drivers/media/radio/radio-rtrack2.c index d1e6b01d4eca..2587227214bf 100644 --- a/trunk/drivers/media/radio/radio-rtrack2.c +++ b/trunk/drivers/media/radio/radio-rtrack2.c @@ -13,16 +13,34 @@ #include /* Initdata */ #include /* request_region */ #include /* udelay */ +#include /* outb, outb_p */ +#include /* copy to/from user */ #include /* kernel radio structs */ -#include -#include /* for KERNEL_VERSION MACRO */ -#include /* outb, outb_p */ -#include +#include #include +#include -MODULE_AUTHOR("Ben Pfaff"); -MODULE_DESCRIPTION("A driver for the RadioTrack II radio card."); -MODULE_LICENSE("GPL"); +#include /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,0,2) + +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + },{ + .id = V4L2_CID_AUDIO_VOLUME, + .name = "Volume", + .minimum = 0, + .maximum = 65535, + .step = 65535, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; #ifndef CONFIG_RADIO_RTRACK2_PORT #define CONFIG_RADIO_RTRACK2_PORT -1 @@ -30,88 +48,79 @@ MODULE_LICENSE("GPL"); static int io = CONFIG_RADIO_RTRACK2_PORT; static int radio_nr = -1; +static spinlock_t lock; -module_param(io, int, 0); -MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)"); -module_param(radio_nr, int, 0); - -#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) - -struct rtrack2 +struct rt_device { - struct v4l2_device v4l2_dev; - struct video_device vdev; - int io; + unsigned long in_use; + int port; unsigned long curfreq; int muted; - struct mutex lock; }; -static struct rtrack2 rtrack2_card; - /* local things */ -static void rt_mute(struct rtrack2 *dev) +static void rt_mute(struct rt_device *dev) { - if (dev->muted) + if(dev->muted) return; - mutex_lock(&dev->lock); - outb(1, dev->io); - mutex_unlock(&dev->lock); + spin_lock(&lock); + outb(1, io); + spin_unlock(&lock); dev->muted = 1; } -static void rt_unmute(struct rtrack2 *dev) +static void rt_unmute(struct rt_device *dev) { if(dev->muted == 0) return; - mutex_lock(&dev->lock); - outb(0, dev->io); - mutex_unlock(&dev->lock); + spin_lock(&lock); + outb(0, io); + spin_unlock(&lock); dev->muted = 0; } -static void zero(struct rtrack2 *dev) +static void zero(void) { - outb_p(1, dev->io); - outb_p(3, dev->io); - outb_p(1, dev->io); + outb_p(1, io); + outb_p(3, io); + outb_p(1, io); } -static void one(struct rtrack2 *dev) +static void one(void) { - outb_p(5, dev->io); - outb_p(7, dev->io); - outb_p(5, dev->io); + outb_p(5, io); + outb_p(7, io); + outb_p(5, io); } -static int rt_setfreq(struct rtrack2 *dev, unsigned long freq) +static int rt_setfreq(struct rt_device *dev, unsigned long freq) { int i; - mutex_lock(&dev->lock); - dev->curfreq = freq; freq = freq / 200 + 856; - outb_p(0xc8, dev->io); - outb_p(0xc9, dev->io); - outb_p(0xc9, dev->io); + spin_lock(&lock); + + outb_p(0xc8, io); + outb_p(0xc9, io); + outb_p(0xc9, io); for (i = 0; i < 10; i++) - zero(dev); + zero (); for (i = 14; i >= 0; i--) if (freq & (1 << i)) - one(dev); + one (); else - zero(dev); + zero (); - outb_p(0xc8, dev->io); + outb_p(0xc8, io); if (!dev->muted) - outb_p(0, dev->io); + outb_p(0, io); - mutex_unlock(&dev->lock); + spin_unlock(&lock); return 0; } @@ -120,61 +129,61 @@ static int vidioc_querycap(struct file *file, void *priv, { strlcpy(v->driver, "radio-rtrack2", sizeof(v->driver)); strlcpy(v->card, "RadioTrack II", sizeof(v->card)); - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); + sprintf(v->bus_info, "ISA"); v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->capabilities = V4L2_CAP_TUNER; return 0; } static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - return v->index ? -EINVAL : 0; + if (v->index > 0) + return -EINVAL; + + return 0; } -static int rt_getsigstr(struct rtrack2 *dev) +static int rt_getsigstr(struct rt_device *dev) { - int sig = 1; - - mutex_lock(&dev->lock); - if (inb(dev->io) & 2) /* bit set = no signal present */ - sig = 0; - mutex_unlock(&dev->lock); - return sig; + if (inb(io) & 2) /* bit set = no signal present */ + return 0; + return 1; /* signal present */ } static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct rtrack2 *rt = video_drvdata(file); + struct rt_device *rt = video_drvdata(file); if (v->index > 0) return -EINVAL; - strlcpy(v->name, "FM", sizeof(v->name)); + strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; - v->rangelow = 88 * 16000; - v->rangehigh = 108 * 16000; + v->rangelow = (88*16000); + v->rangehigh = (108*16000); v->rxsubchans = V4L2_TUNER_SUB_MONO; v->capability = V4L2_TUNER_CAP_LOW; v->audmode = V4L2_TUNER_MODE_MONO; - v->signal = 0xFFFF * rt_getsigstr(rt); + v->signal = 0xFFFF*rt_getsigstr(rt); return 0; } static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct rtrack2 *rt = video_drvdata(file); + struct rt_device *rt = video_drvdata(file); - rt_setfreq(rt, f->frequency); + rt->curfreq = f->frequency; + rt_setfreq(rt, rt->curfreq); return 0; } static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct rtrack2 *rt = video_drvdata(file); + struct rt_device *rt = video_drvdata(file); f->type = V4L2_TUNER_RADIO; f->frequency = rt->curfreq; @@ -184,11 +193,14 @@ static int vidioc_g_frequency(struct file *file, void *priv, static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535); + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); + return 0; + } } return -EINVAL; } @@ -196,7 +208,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct rtrack2 *rt = video_drvdata(file); + struct rt_device *rt = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -215,7 +227,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct rtrack2 *rt = video_drvdata(file); + struct rt_device *rt = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -234,46 +246,55 @@ static int vidioc_s_ctrl(struct file *file, void *priv, return -EINVAL; } -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +static int vidioc_g_audio(struct file *file, void *priv, + struct v4l2_audio *a) { - *i = 0; + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; return 0; } -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { - return i ? -EINVAL : 0; + *i = 0; + return 0; } -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; + if (i != 0) + return -EINVAL; return 0; } static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) { - return a->index ? -EINVAL : 0; + if (a->index != 0) + return -EINVAL; + return 0; } -static int rtrack2_open(struct file *file) +static struct rt_device rtrack2_unit; + +static int rtrack2_exclusive_open(struct file *file) { - return 0; + return test_and_set_bit(0, &rtrack2_unit.in_use) ? -EBUSY : 0; } -static int rtrack2_release(struct file *file) +static int rtrack2_exclusive_release(struct file *file) { + clear_bit(0, &rtrack2_unit.in_use); return 0; } static const struct v4l2_file_operations rtrack2_fops = { .owner = THIS_MODULE, - .open = rtrack2_open, - .release = rtrack2_release, + .open = rtrack2_exclusive_open, + .release = rtrack2_exclusive_release, .ioctl = video_ioctl2, }; @@ -292,61 +313,62 @@ static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { .vidioc_s_input = vidioc_s_input, }; +static struct video_device rtrack2_radio = { + .name = "RadioTrack II radio", + .fops = &rtrack2_fops, + .ioctl_ops = &rtrack2_ioctl_ops, + .release = video_device_release_empty, +}; + static int __init rtrack2_init(void) { - struct rtrack2 *dev = &rtrack2_card; - struct v4l2_device *v4l2_dev = &dev->v4l2_dev; - int res; - - strlcpy(v4l2_dev->name, "rtrack2", sizeof(v4l2_dev->name)); - dev->io = io; - if (dev->io == -1) { - v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or io=0x30c\n"); + if(io==-1) + { + printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n"); return -EINVAL; } - if (!request_region(dev->io, 4, "rtrack2")) { - v4l2_err(v4l2_dev, "port 0x%x already in use\n", dev->io); + if (!request_region(io, 4, "rtrack2")) + { + printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io); return -EBUSY; } - res = v4l2_device_register(NULL, v4l2_dev); - if (res < 0) { - release_region(dev->io, 4); - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); - return res; - } + video_set_drvdata(&rtrack2_radio, &rtrack2_unit); - strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); - dev->vdev.v4l2_dev = v4l2_dev; - dev->vdev.fops = &rtrack2_fops; - dev->vdev.ioctl_ops = &rtrack2_ioctl_ops; - dev->vdev.release = video_device_release_empty; - video_set_drvdata(&dev->vdev, dev); - - mutex_init(&dev->lock); - if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { - v4l2_device_unregister(v4l2_dev); - release_region(dev->io, 4); + spin_lock_init(&lock); + if (video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr) < 0) { + release_region(io, 4); return -EINVAL; } - v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n"); + printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n"); /* mute card - prevents noisy bootups */ - outb(1, dev->io); - dev->muted = 1; + outb(1, io); + rtrack2_unit.muted = 1; return 0; } -static void __exit rtrack2_exit(void) -{ - struct rtrack2 *dev = &rtrack2_card; +MODULE_AUTHOR("Ben Pfaff"); +MODULE_DESCRIPTION("A driver for the RadioTrack II radio card."); +MODULE_LICENSE("GPL"); - video_unregister_device(&dev->vdev); - v4l2_device_unregister(&dev->v4l2_dev); - release_region(dev->io, 4); +module_param(io, int, 0); +MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)"); +module_param(radio_nr, int, 0); + +static void __exit rtrack2_cleanup_module(void) +{ + video_unregister_device(&rtrack2_radio); + release_region(io,4); } module_init(rtrack2_init); -module_exit(rtrack2_exit); +module_exit(rtrack2_cleanup_module); + +/* + Local variables: + compile-command: "mmake" + End: +*/ diff --git a/trunk/drivers/media/radio/radio-sf16fmi.c b/trunk/drivers/media/radio/radio-sf16fmi.c index f4784f0d1a88..d358e48c2422 100644 --- a/trunk/drivers/media/radio/radio-sf16fmi.c +++ b/trunk/drivers/media/radio/radio-sf16fmi.c @@ -22,109 +22,113 @@ #include /* Initdata */ #include /* request_region */ #include /* udelay */ -#include -#include #include /* kernel radio structs */ -#include /* outb, outb_p */ -#include +#include #include +#include +#include /* outb, outb_p */ +#include /* copy to/from user */ +#include -MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood"); -MODULE_DESCRIPTION("A driver for the SF16MI radio."); -MODULE_LICENSE("GPL"); - -static int io = -1; -static int radio_nr = -1; - -module_param(io, int, 0); -MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)"); -module_param(radio_nr, int, 0); +#define RADIO_VERSION KERNEL_VERSION(0,0,2) -#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + } +}; -struct fmi +struct fmi_device { - struct v4l2_device v4l2_dev; - struct video_device vdev; - int io; + unsigned long in_use; + int port; int curvol; /* 1 or 0 */ unsigned long curfreq; /* freq in kHz */ __u32 flags; - struct mutex lock; }; -static struct fmi fmi_card; -static struct pnp_dev *dev; +static int io = -1; +static int radio_nr = -1; +static struct pnp_dev *dev = NULL; +static struct mutex lock; /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ /* It is only useful to give freq in intervall of 800 (=0.05Mhz), * other bits will be truncated, e.g 92.7400016 -> 92.7, but * 92.7400017 -> 92.75 */ -#define RSF16_ENCODE(x) ((x) / 800 + 214) -#define RSF16_MINFREQ (87 * 16000) -#define RSF16_MAXFREQ (108 * 16000) +#define RSF16_ENCODE(x) ((x)/800+214) +#define RSF16_MINFREQ 87*16000 +#define RSF16_MAXFREQ 108*16000 -static void outbits(int bits, unsigned int data, int io) +static void outbits(int bits, unsigned int data, int port) { - while (bits--) { - if (data & 1) { - outb(5, io); + while(bits--) { + if(data & 1) { + outb(5, port); udelay(6); - outb(7, io); + outb(7, port); udelay(6); } else { - outb(1, io); + outb(1, port); udelay(6); - outb(3, io); + outb(3, port); udelay(6); } - data >>= 1; + data>>=1; } } -static inline void fmi_mute(struct fmi *fmi) +static inline void fmi_mute(int port) { - mutex_lock(&fmi->lock); - outb(0x00, fmi->io); - mutex_unlock(&fmi->lock); + mutex_lock(&lock); + outb(0x00, port); + mutex_unlock(&lock); } -static inline void fmi_unmute(struct fmi *fmi) +static inline void fmi_unmute(int port) { - mutex_lock(&fmi->lock); - outb(0x08, fmi->io); - mutex_unlock(&fmi->lock); + mutex_lock(&lock); + outb(0x08, port); + mutex_unlock(&lock); } -static inline int fmi_setfreq(struct fmi *fmi, unsigned long freq) +static inline int fmi_setfreq(struct fmi_device *dev) { - mutex_lock(&fmi->lock); - fmi->curfreq = freq; + int myport = dev->port; + unsigned long freq = dev->curfreq; - outbits(16, RSF16_ENCODE(freq), fmi->io); - outbits(8, 0xC0, fmi->io); + mutex_lock(&lock); + + outbits(16, RSF16_ENCODE(freq), myport); + outbits(8, 0xC0, myport); msleep(143); /* was schedule_timeout(HZ/7) */ - mutex_unlock(&fmi->lock); - if (fmi->curvol) - fmi_unmute(fmi); + mutex_unlock(&lock); + if (dev->curvol) fmi_unmute(myport); return 0; } -static inline int fmi_getsigstr(struct fmi *fmi) +static inline int fmi_getsigstr(struct fmi_device *dev) { int val; int res; + int myport = dev->port; + - mutex_lock(&fmi->lock); - val = fmi->curvol ? 0x08 : 0x00; /* unmute/mute */ - outb(val, fmi->io); - outb(val | 0x10, fmi->io); + mutex_lock(&lock); + val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */ + outb(val, myport); + outb(val | 0x10, myport); msleep(143); /* was schedule_timeout(HZ/7) */ - res = (int)inb(fmi->io + 1); - outb(val, fmi->io); + res = (int)inb(myport+1); + outb(val, myport); - mutex_unlock(&fmi->lock); + mutex_unlock(&lock); return (res & 2) ? 0 : 0xFFFF; } @@ -133,9 +137,9 @@ static int vidioc_querycap(struct file *file, void *priv, { strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver)); strlcpy(v->card, "SF16-FMx radio", sizeof(v->card)); - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); + sprintf(v->bus_info, "ISA"); v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->capabilities = V4L2_CAP_TUNER; return 0; } @@ -143,18 +147,18 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { int mult; - struct fmi *fmi = video_drvdata(file); + struct fmi_device *fmi = video_drvdata(file); if (v->index > 0) return -EINVAL; - strlcpy(v->name, "FM", sizeof(v->name)); + strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000; - v->rangelow = RSF16_MINFREQ / mult; - v->rangehigh = RSF16_MAXFREQ / mult; + v->rangelow = RSF16_MINFREQ/mult; + v->rangehigh = RSF16_MAXFREQ/mult; v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO; - v->capability = fmi->flags & V4L2_TUNER_CAP_LOW; + v->capability = fmi->flags&V4L2_TUNER_CAP_LOW; v->audmode = V4L2_TUNER_MODE_STEREO; v->signal = fmi_getsigstr(fmi); return 0; @@ -163,29 +167,32 @@ static int vidioc_g_tuner(struct file *file, void *priv, static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - return v->index ? -EINVAL : 0; + if (v->index > 0) + return -EINVAL; + return 0; } static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct fmi *fmi = video_drvdata(file); + struct fmi_device *fmi = video_drvdata(file); if (!(fmi->flags & V4L2_TUNER_CAP_LOW)) f->frequency *= 1000; if (f->frequency < RSF16_MINFREQ || - f->frequency > RSF16_MAXFREQ) + f->frequency > RSF16_MAXFREQ ) return -EINVAL; - /* rounding in steps of 800 to match the freq - that will be used */ - fmi_setfreq(fmi, (f->frequency / 800) * 800); + /*rounding in steps of 800 to match th freq + that will be used */ + fmi->curfreq = (f->frequency/800)*800; + fmi_setfreq(fmi); return 0; } static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct fmi *fmi = video_drvdata(file); + struct fmi_device *fmi = video_drvdata(file); f->type = V4L2_TUNER_RADIO; f->frequency = fmi->curfreq; @@ -197,9 +204,14 @@ static int vidioc_g_frequency(struct file *file, void *priv, static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); + return 0; + } } return -EINVAL; } @@ -207,7 +219,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct fmi *fmi = video_drvdata(file); + struct fmi_device *fmi = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -220,60 +232,69 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct fmi *fmi = video_drvdata(file); + struct fmi_device *fmi = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: if (ctrl->value) - fmi_mute(fmi); + fmi_mute(fmi->port); else - fmi_unmute(fmi); + fmi_unmute(fmi->port); fmi->curvol = ctrl->value; return 0; } return -EINVAL; } -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +static int vidioc_g_audio(struct file *file, void *priv, + struct v4l2_audio *a) { - *i = 0; + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; return 0; } -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { - return i ? -EINVAL : 0; + *i = 0; + return 0; } -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; + if (i != 0) + return -EINVAL; return 0; } static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) { - return a->index ? -EINVAL : 0; + if (a->index != 0) + return -EINVAL; + return 0; } -static int fmi_open(struct file *file) +static struct fmi_device fmi_unit; + +static int fmi_exclusive_open(struct file *file) { - return 0; + return test_and_set_bit(0, &fmi_unit.in_use) ? -EBUSY : 0; } -static int fmi_release(struct file *file) +static int fmi_exclusive_release(struct file *file) { + clear_bit(0, &fmi_unit.in_use); return 0; } static const struct v4l2_file_operations fmi_fops = { .owner = THIS_MODULE, - .open = fmi_open, - .release = fmi_release, + .open = fmi_exclusive_open, + .release = fmi_exclusive_release, .ioctl = video_ioctl2, }; @@ -292,6 +313,13 @@ static const struct v4l2_ioctl_ops fmi_ioctl_ops = { .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device fmi_radio = { + .name = "SF16FMx radio", + .fops = &fmi_fops, + .ioctl_ops = &fmi_ioctl_ops, + .release = video_device_release_empty, +}; + /* ladis: this is my card. does any other types exist? */ static struct isapnp_device_id id_table[] __devinitdata = { { ISAPNP_ANY_ID, ISAPNP_ANY_ID, @@ -316,7 +344,7 @@ static int __init isapnp_fmi_probe(void) if (pnp_device_attach(dev) < 0) return -EAGAIN; if (pnp_activate_dev(dev) < 0) { - printk(KERN_ERR "radio-sf16fmi: PnP configure failed (out of resources?)\n"); + printk ("radio-sf16fmi: PnP configure failed (out of resources?)\n"); pnp_device_detach(dev); return -ENOMEM; } @@ -326,72 +354,59 @@ static int __init isapnp_fmi_probe(void) } i = pnp_port_start(dev, 0); - printk(KERN_INFO "radio-sf16fmi: PnP reports card at %#x\n", i); + printk ("radio-sf16fmi: PnP reports card at %#x\n", i); return i; } static int __init fmi_init(void) { - struct fmi *fmi = &fmi_card; - struct v4l2_device *v4l2_dev = &fmi->v4l2_dev; - int res; - if (io < 0) io = isapnp_fmi_probe(); - strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name)); - fmi->io = io; - if (fmi->io < 0) { - v4l2_err(v4l2_dev, "No PnP card found.\n"); - return fmi->io; + if (io < 0) { + printk(KERN_ERR "radio-sf16fmi: No PnP card found.\n"); + return io; } if (!request_region(io, 2, "radio-sf16fmi")) { - v4l2_err(v4l2_dev, "port 0x%x already in use\n", fmi->io); + printk(KERN_ERR "radio-sf16fmi: port 0x%x already in use\n", io); pnp_device_detach(dev); return -EBUSY; } - res = v4l2_device_register(NULL, v4l2_dev); - if (res < 0) { - release_region(fmi->io, 2); - pnp_device_detach(dev); - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); - return res; - } - - fmi->flags = V4L2_TUNER_CAP_LOW; - strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name)); - fmi->vdev.v4l2_dev = v4l2_dev; - fmi->vdev.fops = &fmi_fops; - fmi->vdev.ioctl_ops = &fmi_ioctl_ops; - fmi->vdev.release = video_device_release_empty; - video_set_drvdata(&fmi->vdev, fmi); + fmi_unit.port = io; + fmi_unit.curvol = 0; + fmi_unit.curfreq = 0; + fmi_unit.flags = V4L2_TUNER_CAP_LOW; + video_set_drvdata(&fmi_radio, &fmi_unit); - mutex_init(&fmi->lock); + mutex_init(&lock); - if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { - v4l2_device_unregister(v4l2_dev); - release_region(fmi->io, 2); - pnp_device_detach(dev); + if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) < 0) { + release_region(io, 2); return -EINVAL; } - v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io); + printk(KERN_INFO "SF16FMx radio card driver at 0x%x\n", io); /* mute card - prevents noisy bootups */ - fmi_mute(fmi); + fmi_mute(io); return 0; } -static void __exit fmi_exit(void) -{ - struct fmi *fmi = &fmi_card; +MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood"); +MODULE_DESCRIPTION("A driver for the SF16MI radio."); +MODULE_LICENSE("GPL"); - video_unregister_device(&fmi->vdev); - v4l2_device_unregister(&fmi->v4l2_dev); - release_region(fmi->io, 2); +module_param(io, int, 0); +MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)"); +module_param(radio_nr, int, 0); + +static void __exit fmi_cleanup_module(void) +{ + video_unregister_device(&fmi_radio); + release_region(io, 2); if (dev) pnp_device_detach(dev); } module_init(fmi_init); -module_exit(fmi_exit); +module_exit(fmi_cleanup_module); diff --git a/trunk/drivers/media/radio/radio-sf16fmr2.c b/trunk/drivers/media/radio/radio-sf16fmr2.c index 0ba9d88a80fc..92f17a347fa7 100644 --- a/trunk/drivers/media/radio/radio-sf16fmr2.c +++ b/trunk/drivers/media/radio/radio-sf16fmr2.c @@ -18,28 +18,40 @@ #include /* Initdata */ #include /* request_region */ #include /* udelay */ +#include /* outb, outb_p */ +#include /* copy to/from user */ #include /* kernel radio structs */ -#include -#include /* for KERNEL_VERSION MACRO */ -#include /* outb, outb_p */ -#include +#include #include +#include -MODULE_AUTHOR("Ziglio Frediano, freddy77@angelfire.com"); -MODULE_DESCRIPTION("A driver for the SF16FMR2 radio."); -MODULE_LICENSE("GPL"); - -static int io = 0x384; -static int radio_nr = -1; - -module_param(io, int, 0); -MODULE_PARM_DESC(io, "I/O address of the SF16FMR2 card (should be 0x384, if do not work try 0x284)"); -module_param(radio_nr, int, 0); +static struct mutex lock; +#include /* for KERNEL_VERSION MACRO */ #define RADIO_VERSION KERNEL_VERSION(0,0,2) #define AUD_VOL_INDEX 1 +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + }, + [AUD_VOL_INDEX] = { + .id = V4L2_CID_AUDIO_VOLUME, + .name = "Volume", + .minimum = 0, + .maximum = 15, + .step = 1, + .default_value = 0, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; + #undef DEBUG //#define DEBUG 1 @@ -50,160 +62,156 @@ module_param(radio_nr, int, 0); #endif /* this should be static vars for module size */ -struct fmr2 +struct fmr2_device { - struct v4l2_device v4l2_dev; - struct video_device vdev; - struct mutex lock; - int io; + unsigned long in_use; + int port; int curvol; /* 0-15 */ int mute; int stereo; /* card is producing stereo audio */ unsigned long curfreq; /* freq in kHz */ int card_type; - u32 flags; + __u32 flags; }; -static struct fmr2 fmr2_card; +static int io = 0x384; +static int radio_nr = -1; /* hw precision is 12.5 kHz * It is only useful to give freq in intervall of 200 (=0.0125Mhz), * other bits will be truncated */ -#define RSF16_ENCODE(x) ((x) / 200 + 856) -#define RSF16_MINFREQ (87 * 16000) -#define RSF16_MAXFREQ (108 * 16000) +#define RSF16_ENCODE(x) ((x)/200+856) +#define RSF16_MINFREQ 87*16000 +#define RSF16_MAXFREQ 108*16000 -static inline void wait(int n, int io) +static inline void wait(int n,int port) { - for (; n; --n) - inb(io); + for (;n;--n) inb(port); } -static void outbits(int bits, unsigned int data, int nWait, int io) +static void outbits(int bits, unsigned int data, int nWait, int port) { int bit; - - for (; --bits >= 0;) { - bit = (data >> bits) & 1; - outb(bit, io); - wait(nWait, io); - outb(bit | 2, io); - wait(nWait, io); - outb(bit, io); - wait(nWait, io); + for(;--bits>=0;) { + bit = (data>>bits) & 1; + outb(bit,port); + wait(nWait,port); + outb(bit|2,port); + wait(nWait,port); + outb(bit,port); + wait(nWait,port); } } -static inline void fmr2_mute(int io) +static inline void fmr2_mute(int port) { - outb(0x00, io); - wait(4, io); + outb(0x00, port); + wait(4,port); } -static inline void fmr2_unmute(int io) +static inline void fmr2_unmute(int port) { - outb(0x04, io); - wait(4, io); + outb(0x04, port); + wait(4,port); } -static inline int fmr2_stereo_mode(int io) +static inline int fmr2_stereo_mode(int port) { - int n = inb(io); - - outb(6, io); - inb(io); - n = ((n >> 3) & 1) ^ 1; + int n = inb(port); + outb(6,port); + inb(port); + n = ((n>>3)&1)^1; debug_print((KERN_DEBUG "stereo: %d\n", n)); return n; } -static int fmr2_product_info(struct fmr2 *dev) +static int fmr2_product_info(struct fmr2_device *dev) { - int n = inb(dev->io); - + int n = inb(dev->port); n &= 0xC1; - if (n == 0) { + if (n == 0) + { /* this should support volume set */ dev->card_type = 12; return 0; } /* not volume (mine is 11) */ - dev->card_type = (n == 128) ? 11 : 0; + dev->card_type = (n==128)?11:0; return n; } -static inline int fmr2_getsigstr(struct fmr2 *dev) +static inline int fmr2_getsigstr(struct fmr2_device *dev) { - /* !!! works only if scanning freq */ - int res = 0xffff; - - outb(5, dev->io); - wait(4, dev->io); - if (!(inb(dev->io) & 1)) - res = 0; + /* !!! work only if scanning freq */ + int port = dev->port, res = 0xffff; + outb(5,port); + wait(4,port); + if (!(inb(port)&1)) res = 0; debug_print((KERN_DEBUG "signal: %d\n", res)); return res; } /* set frequency and unmute card */ -static int fmr2_setfreq(struct fmr2 *dev) +static int fmr2_setfreq(struct fmr2_device *dev) { + int port = dev->port; unsigned long freq = dev->curfreq; - fmr2_mute(dev->io); + fmr2_mute(port); /* 0x42 for mono output * 0x102 forward scanning * 0x182 scansione avanti */ - outbits(9, 0x2, 3, dev->io); - outbits(16, RSF16_ENCODE(freq), 2, dev->io); + outbits(9,0x2,3,port); + outbits(16,RSF16_ENCODE(freq),2,port); - fmr2_unmute(dev->io); + fmr2_unmute(port); /* wait 0.11 sec */ msleep(110); /* NOTE if mute this stop radio you must set freq on unmute */ - dev->stereo = fmr2_stereo_mode(dev->io); + dev->stereo = fmr2_stereo_mode(port); return 0; } /* !!! not tested, in my card this does't work !!! */ -static int fmr2_setvolume(struct fmr2 *dev) +static int fmr2_setvolume(struct fmr2_device *dev) { int vol[16] = { 0x021, 0x084, 0x090, 0x104, 0x110, 0x204, 0x210, 0x402, 0x404, 0x408, 0x410, 0x801, 0x802, 0x804, 0x808, 0x810 }; - int i, a; + int i, a, port = dev->port; int n = vol[dev->curvol & 0x0f]; if (dev->card_type != 11) return 1; for (i = 12; --i >= 0; ) { - a = ((n >> i) & 1) << 6; /* if (a==0) a = 0; else a = 0x40; */ - outb(a | 4, dev->io); - wait(4, dev->io); - outb(a | 0x24, dev->io); - wait(4, dev->io); - outb(a | 4, dev->io); - wait(4, dev->io); + a = ((n >> i) & 1) << 6; /* if (a=0) a= 0; else a= 0x40; */ + outb(a | 4, port); + wait(4, port); + outb(a | 0x24, port); + wait(4, port); + outb(a | 4, port); + wait(4, port); } for (i = 6; --i >= 0; ) { a = ((0x18 >> i) & 1) << 6; - outb(a | 4, dev->io); - wait(4, dev->io); - outb(a | 0x24, dev->io); - wait(4, dev->io); - outb(a | 4, dev->io); - wait(4, dev->io); + outb(a | 4, port); + wait(4,port); + outb(a | 0x24, port); + wait(4,port); + outb(a|4, port); + wait(4,port); } - wait(4, dev->io); - outb(0x14, dev->io); + wait(4, port); + outb(0x14, port); + return 0; } @@ -212,9 +220,9 @@ static int vidioc_querycap(struct file *file, void *priv, { strlcpy(v->driver, "radio-sf16fmr2", sizeof(v->driver)); strlcpy(v->card, "SF16-FMR2 radio", sizeof(v->card)); - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); + sprintf(v->bus_info, "ISA"); v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->capabilities = V4L2_CAP_TUNER; return 0; } @@ -222,52 +230,54 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { int mult; - struct fmr2 *fmr2 = video_drvdata(file); + struct fmr2_device *fmr2 = video_drvdata(file); if (v->index > 0) return -EINVAL; - strlcpy(v->name, "FM", sizeof(v->name)); + strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000; - v->rangelow = RSF16_MINFREQ / mult; - v->rangehigh = RSF16_MAXFREQ / mult; + v->rangelow = RSF16_MINFREQ/mult; + v->rangehigh = RSF16_MAXFREQ/mult; v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO; v->capability = fmr2->flags&V4L2_TUNER_CAP_LOW; v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO: V4L2_TUNER_MODE_MONO; - mutex_lock(&fmr2->lock); + mutex_lock(&lock); v->signal = fmr2_getsigstr(fmr2); - mutex_unlock(&fmr2->lock); + mutex_unlock(&lock); return 0; } static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - return v->index ? -EINVAL : 0; + if (v->index > 0) + return -EINVAL; + return 0; } static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct fmr2 *fmr2 = video_drvdata(file); + struct fmr2_device *fmr2 = video_drvdata(file); if (!(fmr2->flags & V4L2_TUNER_CAP_LOW)) f->frequency *= 1000; if (f->frequency < RSF16_MINFREQ || - f->frequency > RSF16_MAXFREQ) + f->frequency > RSF16_MAXFREQ ) return -EINVAL; - /* rounding in steps of 200 to match the freq - that will be used */ - fmr2->curfreq = (f->frequency / 200) * 200; + /*rounding in steps of 200 to match th freq + that will be used */ + fmr2->curfreq = (f->frequency/200)*200; /* set card freq (if not muted) */ if (fmr2->curvol && !fmr2->mute) { - mutex_lock(&fmr2->lock); + mutex_lock(&lock); fmr2_setfreq(fmr2); - mutex_unlock(&fmr2->lock); + mutex_unlock(&lock); } return 0; } @@ -275,7 +285,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct fmr2 *fmr2 = video_drvdata(file); + struct fmr2_device *fmr2 = video_drvdata(file); f->type = V4L2_TUNER_RADIO; f->frequency = fmr2->curfreq; @@ -287,16 +297,13 @@ static int vidioc_g_frequency(struct file *file, void *priv, static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - struct fmr2 *fmr2 = video_drvdata(file); + int i; - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); - case V4L2_CID_AUDIO_VOLUME: - /* Only card_type == 11 implements volume */ - if (fmr2->card_type == 11) - return v4l2_ctrl_query_fill(qc, 0, 15, 1, 0); - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &radio_qctrl[i], sizeof(*qc)); + return 0; + } } return -EINVAL; } @@ -304,7 +311,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct fmr2 *fmr2 = video_drvdata(file); + struct fmr2_device *fmr2 = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -320,14 +327,18 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct fmr2 *fmr2 = video_drvdata(file); + struct fmr2_device *fmr2 = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: fmr2->mute = ctrl->value; break; case V4L2_CID_AUDIO_VOLUME: - fmr2->curvol = ctrl->value; + if (ctrl->value > radio_qctrl[AUD_VOL_INDEX].maximum) + fmr2->curvol = radio_qctrl[AUD_VOL_INDEX].maximum; + else + fmr2->curvol = ctrl->value; + break; default: return -EINVAL; @@ -340,57 +351,66 @@ static int vidioc_s_ctrl(struct file *file, void *priv, printk(KERN_DEBUG "mute\n"); #endif - mutex_lock(&fmr2->lock); + mutex_lock(&lock); if (fmr2->curvol && !fmr2->mute) { fmr2_setvolume(fmr2); /* Set frequency and unmute card */ fmr2_setfreq(fmr2); } else - fmr2_mute(fmr2->io); - mutex_unlock(&fmr2->lock); + fmr2_mute(fmr2->port); + mutex_unlock(&lock); return 0; } -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +static int vidioc_g_audio(struct file *file, void *priv, + struct v4l2_audio *a) { - *i = 0; + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; return 0; } -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { - return i ? -EINVAL : 0; + *i = 0; + return 0; } -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; + if (i != 0) + return -EINVAL; return 0; } static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) { - return a->index ? -EINVAL : 0; + if (a->index != 0) + return -EINVAL; + return 0; } -static int fmr2_open(struct file *file) +static struct fmr2_device fmr2_unit; + +static int fmr2_exclusive_open(struct file *file) { - return 0; + return test_and_set_bit(0, &fmr2_unit.in_use) ? -EBUSY : 0; } -static int fmr2_release(struct file *file) +static int fmr2_exclusive_release(struct file *file) { + clear_bit(0, &fmr2_unit.in_use); return 0; } static const struct v4l2_file_operations fmr2_fops = { .owner = THIS_MODULE, - .open = fmr2_open, - .release = fmr2_release, + .open = fmr2_exclusive_open, + .release = fmr2_exclusive_release, .ioctl = video_ioctl2, }; @@ -409,64 +429,67 @@ static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device fmr2_radio = { + .name = "SF16FMR2 radio", + .fops = &fmr2_fops, + .ioctl_ops = &fmr2_ioctl_ops, + .release = video_device_release_empty, +}; + static int __init fmr2_init(void) { - struct fmr2 *fmr2 = &fmr2_card; - struct v4l2_device *v4l2_dev = &fmr2->v4l2_dev; - int res; - - strlcpy(v4l2_dev->name, "sf16fmr2", sizeof(v4l2_dev->name)); - fmr2->io = io; - fmr2->stereo = 1; - fmr2->flags = V4L2_TUNER_CAP_LOW; - mutex_init(&fmr2->lock); - - if (!request_region(fmr2->io, 2, "sf16fmr2")) { - v4l2_err(v4l2_dev, "request_region failed!\n"); + fmr2_unit.port = io; + fmr2_unit.curvol = 0; + fmr2_unit.mute = 0; + fmr2_unit.curfreq = 0; + fmr2_unit.stereo = 1; + fmr2_unit.flags = V4L2_TUNER_CAP_LOW; + fmr2_unit.card_type = 0; + video_set_drvdata(&fmr2_radio, &fmr2_unit); + + mutex_init(&lock); + + if (!request_region(io, 2, "sf16fmr2")) { + printk(KERN_ERR "radio-sf16fmr2: request_region failed!\n"); return -EBUSY; } - res = v4l2_device_register(NULL, v4l2_dev); - if (res < 0) { - release_region(fmr2->io, 2); - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); - return res; - } - - strlcpy(fmr2->vdev.name, v4l2_dev->name, sizeof(fmr2->vdev.name)); - fmr2->vdev.v4l2_dev = v4l2_dev; - fmr2->vdev.fops = &fmr2_fops; - fmr2->vdev.ioctl_ops = &fmr2_ioctl_ops; - fmr2->vdev.release = video_device_release_empty; - video_set_drvdata(&fmr2->vdev, fmr2); - - if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { - v4l2_device_unregister(v4l2_dev); - release_region(fmr2->io, 2); + if (video_register_device(&fmr2_radio, VFL_TYPE_RADIO, radio_nr) < 0) { + release_region(io, 2); return -EINVAL; } - v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io); + printk(KERN_INFO "SF16FMR2 radio card driver at 0x%x.\n", io); /* mute card - prevents noisy bootups */ - mutex_lock(&fmr2->lock); - fmr2_mute(fmr2->io); - fmr2_product_info(fmr2); - mutex_unlock(&fmr2->lock); - debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type)); + mutex_lock(&lock); + fmr2_mute(io); + fmr2_product_info(&fmr2_unit); + mutex_unlock(&lock); + debug_print((KERN_DEBUG "card_type %d\n", fmr2_unit.card_type)); + + /* Only card_type == 11 implements volume */ + if (fmr2_unit.card_type != 11) + radio_qctrl[AUD_VOL_INDEX].maximum = 1; + return 0; } -static void __exit fmr2_exit(void) -{ - struct fmr2 *fmr2 = &fmr2_card; +MODULE_AUTHOR("Ziglio Frediano, freddy77@angelfire.com"); +MODULE_DESCRIPTION("A driver for the SF16FMR2 radio."); +MODULE_LICENSE("GPL"); + +module_param(io, int, 0); +MODULE_PARM_DESC(io, "I/O address of the SF16FMR2 card (should be 0x384, if do not work try 0x284)"); +module_param(radio_nr, int, 0); - video_unregister_device(&fmr2->vdev); - v4l2_device_unregister(&fmr2->v4l2_dev); - release_region(fmr2->io, 2); +static void __exit fmr2_cleanup_module(void) +{ + video_unregister_device(&fmr2_radio); + release_region(io,2); } module_init(fmr2_init); -module_exit(fmr2_exit); +module_exit(fmr2_cleanup_module); #ifndef MODULE diff --git a/trunk/drivers/media/radio/radio-si470x.c b/trunk/drivers/media/radio/radio-si470x.c index 713e242ba8b2..4dfed6aa2dbc 100644 --- a/trunk/drivers/media/radio/radio-si470x.c +++ b/trunk/drivers/media/radio/radio-si470x.c @@ -5,9 +5,8 @@ * - Silicon Labs USB FM Radio Reference Design * - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF) * - KWorld USB FM Radio SnapMusic Mobile 700 (FM700) - * - Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) * - * Copyright (c) 2009 Tobias Lorenz + * Copyright (c) 2008 Tobias Lorenz * * 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 @@ -30,7 +29,7 @@ * 2008-01-12 Tobias Lorenz * Version 1.0.0 * - First working version - * 2008-01-13 Tobias Lorenz + * 2008-01-13 Tobias Lorenz * Version 1.0.1 * - Improved error handling, every function now returns errno * - Improved multi user access (start/mute/stop) @@ -105,7 +104,6 @@ * 2009-01-31 Rick Bronson * Tobias Lorenz * - add LED status output - * - get HW/SW version from scratchpad * * ToDo: * - add firmware download/update support @@ -116,10 +114,10 @@ /* driver definitions */ #define DRIVER_AUTHOR "Tobias Lorenz " #define DRIVER_NAME "radio-si470x" -#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 9) +#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 8) #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers" -#define DRIVER_VERSION "1.0.9" +#define DRIVER_VERSION "1.0.8" /* kernel includes */ @@ -147,7 +145,7 @@ static struct usb_device_id si470x_usb_driver_id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, /* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */ { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) }, - /* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */ + /* DealExtreme USB Radio */ { USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) }, /* Terminating entry */ { } @@ -347,7 +345,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); /* Report 19: stream */ #define STREAM_REPORT_SIZE 3 -#define STREAM_REPORT 19 +#define STREAM_REPORT 19 /* Report 20: scratch */ #define SCRATCH_PAGE_SIZE 63 @@ -355,13 +353,9 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); #define SCRATCH_REPORT 20 /* Reports 19-22: flash upgrade of the C8051F321 */ -#define WRITE_REPORT_SIZE 4 #define WRITE_REPORT 19 -#define FLASH_REPORT_SIZE 64 #define FLASH_REPORT 20 -#define CRC_REPORT_SIZE 3 #define CRC_REPORT 21 -#define RESPONSE_REPORT_SIZE 2 #define RESPONSE_REPORT 22 /* Report 23: currently unused, but can accept 60 byte reports on the HID */ @@ -420,7 +414,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); /* bootloader commands */ #define GET_SW_VERSION_COMMAND 0x00 -#define SET_PAGE_COMMAND 0x01 +#define SET_PAGE_COMMAND 0x01 #define ERASE_PAGE_COMMAND 0x02 #define WRITE_PAGE_COMMAND 0x03 #define CRC_ON_PAGE_COMMAND 0x04 @@ -434,6 +428,12 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); #define COMMAND_FAILED 0x02 #define COMMAND_PENDING 0x03 +/* buffer sizes */ +#define COMMAND_BUFFER_SIZE 4 +#define RESPONSE_BUFFER_SIZE 2 +#define FLASH_BUFFER_SIZE 64 +#define CRC_BUFFER_SIZE 3 + /************************************************************************** @@ -465,10 +465,6 @@ struct si470x_device { unsigned int buf_size; unsigned int rd_index; unsigned int wr_index; - - /* scratch page */ - unsigned char software_version; - unsigned char hardware_version; }; @@ -484,7 +480,7 @@ struct si470x_device { /************************************************************************** - * General Driver Functions - REGISTER_REPORTs + * General Driver Functions **************************************************************************/ /* @@ -569,6 +565,60 @@ static int si470x_set_register(struct si470x_device *radio, int regnr) } +/* + * si470x_get_all_registers - read entire registers + */ +static int si470x_get_all_registers(struct si470x_device *radio) +{ + unsigned char buf[ENTIRE_REPORT_SIZE]; + int retval; + unsigned char regnr; + + buf[0] = ENTIRE_REPORT; + + retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); + + if (retval >= 0) + for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) + radio->registers[regnr] = get_unaligned_be16( + &buf[regnr * RADIO_REGISTER_SIZE + 1]); + + return (retval < 0) ? -EINVAL : 0; +} + + +/* + * si470x_get_rds_registers - read rds registers + */ +static int si470x_get_rds_registers(struct si470x_device *radio) +{ + unsigned char buf[RDS_REPORT_SIZE]; + int retval; + int size; + unsigned char regnr; + + buf[0] = RDS_REPORT; + + retval = usb_interrupt_msg(radio->usbdev, + usb_rcvintpipe(radio->usbdev, 1), + (void *) &buf, sizeof(buf), &size, usb_timeout); + if (size != sizeof(buf)) + printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " + "return size differs: %d != %zu\n", size, sizeof(buf)); + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " + "usb_interrupt_msg returned %d\n", retval); + + if (retval >= 0) + for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) + radio->registers[STATUSRSSI + regnr] = + get_unaligned_be16( + &buf[regnr * RADIO_REGISTER_SIZE + 1]); + + return (retval < 0) ? -EINVAL : 0; +} + + /* * si470x_set_chan - set the channel */ @@ -836,70 +886,6 @@ static int si470x_rds_on(struct si470x_device *radio) -/************************************************************************** - * General Driver Functions - ENTIRE_REPORT - **************************************************************************/ - -/* - * si470x_get_all_registers - read entire registers - */ -static int si470x_get_all_registers(struct si470x_device *radio) -{ - unsigned char buf[ENTIRE_REPORT_SIZE]; - int retval; - unsigned char regnr; - - buf[0] = ENTIRE_REPORT; - - retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); - - if (retval >= 0) - for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) - radio->registers[regnr] = get_unaligned_be16( - &buf[regnr * RADIO_REGISTER_SIZE + 1]); - - return (retval < 0) ? -EINVAL : 0; -} - - - -/************************************************************************** - * General Driver Functions - RDS_REPORT - **************************************************************************/ - -/* - * si470x_get_rds_registers - read rds registers - */ -static int si470x_get_rds_registers(struct si470x_device *radio) -{ - unsigned char buf[RDS_REPORT_SIZE]; - int retval; - int size; - unsigned char regnr; - - buf[0] = RDS_REPORT; - - retval = usb_interrupt_msg(radio->usbdev, - usb_rcvintpipe(radio->usbdev, 1), - (void *) &buf, sizeof(buf), &size, usb_timeout); - if (size != sizeof(buf)) - printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " - "return size differs: %d != %zu\n", size, sizeof(buf)); - if (retval < 0) - printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " - "usb_interrupt_msg returned %d\n", retval); - - if (retval >= 0) - for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) - radio->registers[STATUSRSSI + regnr] = - get_unaligned_be16( - &buf[regnr * RADIO_REGISTER_SIZE + 1]); - - return (retval < 0) ? -EINVAL : 0; -} - - - /************************************************************************** * General Driver Functions - LED_REPORT **************************************************************************/ @@ -924,35 +910,6 @@ static int si470x_set_led_state(struct si470x_device *radio, -/************************************************************************** - * General Driver Functions - SCRATCH_REPORT - **************************************************************************/ - -/* - * si470x_get_scratch_versions - gets the scratch page and version infos - */ -static int si470x_get_scratch_page_versions(struct si470x_device *radio) -{ - unsigned char buf[SCRATCH_REPORT_SIZE]; - int retval; - - buf[0] = SCRATCH_REPORT; - - retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); - - if (retval < 0) - printk(KERN_WARNING DRIVER_NAME ": si470x_get_scratch: " - "si470x_get_report returned %d\n", retval); - else { - radio->software_version = buf[1]; - radio->hardware_version = buf[2]; - } - - return (retval < 0) ? -EINVAL : 0; -} - - - /************************************************************************** * RDS Driver Functions **************************************************************************/ @@ -1167,7 +1124,6 @@ static int si470x_fops_open(struct file *file) } if (radio->users == 1) { - /* start radio */ retval = si470x_start(radio); if (retval < 0) usb_autopm_put_interface(radio->intf); @@ -1209,7 +1165,6 @@ static int si470x_fops_release(struct file *file) /* cancel read processes */ wake_up_interruptible(&radio->read_queue); - /* stop radio */ retval = si470x_stop(radio); usb_autopm_put_interface(radio->intf); } @@ -1271,11 +1226,9 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = { static int si470x_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *capability) { - struct si470x_device *radio = video_drvdata(file); - strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver)); strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); - usb_make_path(radio->usbdev, capability->bus_info, sizeof(capability->bus_info)); + sprintf(capability->bus_info, "USB"); capability->version = DRIVER_KERNEL_VERSION; capability->capabilities = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_TUNER | V4L2_CAP_RADIO; @@ -1683,7 +1636,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, sizeof(si470x_viddev_template)); video_set_drvdata(radio->videodev, radio); - /* show some infos about the specific si470x device */ + /* show some infos about the specific device */ if (si470x_get_all_registers(radio) < 0) { retval = -EIO; goto err_all; @@ -1691,16 +1644,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", radio->registers[DEVICEID], radio->registers[CHIPID]); - /* get software and hardware versions */ - if (si470x_get_scratch_page_versions(radio) < 0) { - retval = -EIO; - goto err_all; - } - printk(KERN_INFO DRIVER_NAME - ": software version %d, hardware version %d\n", - radio->software_version, radio->hardware_version); - - /* check if device and firmware is current */ + /* check if firmware is current */ if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) < RADIO_SW_VERSION_CURRENT) { printk(KERN_WARNING DRIVER_NAME @@ -1713,7 +1657,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, ": If you have some trouble using this driver,\n"); printk(KERN_WARNING DRIVER_NAME ": please report to V4L ML at " - "linux-media@vger.kernel.org\n"); + "video4linux-list@redhat.com\n"); } /* set initial frequency */ diff --git a/trunk/drivers/media/radio/radio-terratec.c b/trunk/drivers/media/radio/radio-terratec.c index 5b007f5c74b2..0798d71abd00 100644 --- a/trunk/drivers/media/radio/radio-terratec.c +++ b/trunk/drivers/media/radio/radio-terratec.c @@ -27,29 +27,16 @@ #include /* Modules */ #include /* Initdata */ #include /* request_region */ +#include /* udelay */ +#include /* outb, outb_p */ +#include /* copy to/from user */ #include /* kernel radio structs */ -#include -#include /* for KERNEL_VERSION MACRO */ -#include /* outb, outb_p */ -#include +#include #include +#include -MODULE_AUTHOR("R.OFFERMANNS & others"); -MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card."); -MODULE_LICENSE("GPL"); - -#ifndef CONFIG_RADIO_TERRATEC_PORT -#define CONFIG_RADIO_TERRATEC_PORT 0x590 -#endif - -static int io = CONFIG_RADIO_TERRATEC_PORT; -static int radio_nr = -1; - -module_param(io, int, 0); -MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)"); -module_param(radio_nr, int, 0); - -#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) +#include /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,0,2) static struct v4l2_queryctrl radio_qctrl[] = { { @@ -70,6 +57,13 @@ static struct v4l2_queryctrl radio_qctrl[] = { } }; +#ifndef CONFIG_RADIO_TERRATEC_PORT +#define CONFIG_RADIO_TERRATEC_PORT 0x590 +#endif + +/**************** this ones are for the terratec *******************/ +#define BASEPORT 0x590 +#define VOLPORT 0x591 #define WRT_DIS 0x00 #define CLK_OFF 0x00 #define IIC_DATA 0x01 @@ -77,124 +71,138 @@ static struct v4l2_queryctrl radio_qctrl[] = { #define DATA 0x04 #define CLK_ON 0x08 #define WRT_EN 0x10 +/*******************************************************************/ -struct terratec +static int io = CONFIG_RADIO_TERRATEC_PORT; +static int radio_nr = -1; +static spinlock_t lock; + +struct tt_device { - struct v4l2_device v4l2_dev; - struct video_device vdev; - int io; + unsigned long in_use; + int port; int curvol; unsigned long curfreq; int muted; - struct mutex lock; }; -static struct terratec terratec_card; /* local things */ -static void tt_write_vol(struct terratec *tt, int volume) +static void cardWriteVol(int volume) { int i; - - volume = volume + (volume * 32); /* change both channels */ - mutex_lock(&tt->lock); - for (i = 0; i < 8; i++) { - if (volume & (0x80 >> i)) - outb(0x80, tt->io + 1); - else - outb(0x00, tt->io + 1); + volume = volume+(volume * 32); // change both channels + spin_lock(&lock); + for (i=0;i<8;i++) + { + if (volume & (0x80>>i)) + outb(0x80, VOLPORT); + else outb(0x00, VOLPORT); } - mutex_unlock(&tt->lock); + spin_unlock(&lock); } -static void tt_mute(struct terratec *tt) +static void tt_mute(struct tt_device *dev) { - tt->muted = 1; - tt_write_vol(tt, 0); + dev->muted = 1; + cardWriteVol(0); } -static int tt_setvol(struct terratec *tt, int vol) +static int tt_setvol(struct tt_device *dev, int vol) { - if (vol == tt->curvol) { /* requested volume = current */ - if (tt->muted) { /* user is unmuting the card */ - tt->muted = 0; - tt_write_vol(tt, vol); /* enable card */ + +// printk(KERN_ERR "setvol called, vol = %d\n", vol); + + if(vol == dev->curvol) { /* requested volume = current */ + if (dev->muted) { /* user is unmuting the card */ + dev->muted = 0; + cardWriteVol(vol); /* enable card */ } + return 0; } - if (vol == 0) { /* volume = 0 means mute the card */ - tt_write_vol(tt, 0); /* "turn off card" by setting vol to 0 */ - tt->curvol = vol; /* track the volume state! */ + if(vol == 0) { /* volume = 0 means mute the card */ + cardWriteVol(0); /* "turn off card" by setting vol to 0 */ + dev->curvol = vol; /* track the volume state! */ return 0; } - tt->muted = 0; - tt_write_vol(tt, vol); - tt->curvol = vol; + dev->muted = 0; + + cardWriteVol(vol); + + dev->curvol = vol; + return 0; + } /* this is the worst part in this driver */ /* many more or less strange things are going on here, but hey, it works :) */ -static int tt_setfreq(struct terratec *tt, unsigned long freq1) +static int tt_setfreq(struct tt_device *dev, unsigned long freq1) { int freq; int i; int p; int temp; long rest; - unsigned char buffer[25]; /* we have to bit shift 25 registers */ - - mutex_lock(&tt->lock); - - tt->curfreq = freq1; - freq = freq1 / 160; /* convert the freq. to a nice to handle value */ - memset(buffer, 0, sizeof(buffer)); + unsigned char buffer[25]; /* we have to bit shift 25 registers */ + freq = freq1/160; /* convert the freq. to a nice to handle value */ + for(i=24;i>-1;i--) + buffer[i]=0; - rest = freq * 10 + 10700; /* I once had understood what is going on here */ + rest = freq*10+10700; /* i once had understood what is going on here */ /* maybe some wise guy (friedhelm?) can comment this stuff */ - i = 13; - p = 10; - temp = 102400; - while (rest != 0) { - if (rest % temp == rest) + i=13; + p=10; + temp=102400; + while (rest!=0) + { + if (rest%temp == rest) buffer[i] = 0; - else { + else + { buffer[i] = 1; - rest = rest - temp; + rest = rest-temp; } i--; p--; - temp = temp / 2; + temp = temp/2; } - for (i = 24; i > -1; i--) { /* bit shift the values to the radiocard */ - if (buffer[i] == 1) { - outb(WRT_EN | DATA, tt->io); - outb(WRT_EN | DATA | CLK_ON, tt->io); - outb(WRT_EN | DATA, tt->io); - } else { - outb(WRT_EN | 0x00, tt->io); - outb(WRT_EN | 0x00 | CLK_ON, tt->io); + spin_lock(&lock); + + for (i=24;i>-1;i--) /* bit shift the values to the radiocard */ + { + if (buffer[i]==1) + { + outb(WRT_EN|DATA, BASEPORT); + outb(WRT_EN|DATA|CLK_ON , BASEPORT); + outb(WRT_EN|DATA, BASEPORT); + } + else + { + outb(WRT_EN|0x00, BASEPORT); + outb(WRT_EN|0x00|CLK_ON , BASEPORT); } } - outb(0x00, tt->io); + outb(0x00, BASEPORT); - mutex_unlock(&tt->lock); + spin_unlock(&lock); return 0; } -static int tt_getsigstr(struct terratec *tt) +static int tt_getsigstr(struct tt_device *dev) /* TODO */ { - if (inb(tt->io) & 2) /* bit set = no signal present */ + if (inb(io) & 2) /* bit set = no signal present */ return 0; return 1; /* signal present */ } @@ -204,50 +212,53 @@ static int vidioc_querycap(struct file *file, void *priv, { strlcpy(v->driver, "radio-terratec", sizeof(v->driver)); strlcpy(v->card, "ActiveRadio", sizeof(v->card)); - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); + sprintf(v->bus_info, "ISA"); v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->capabilities = V4L2_CAP_TUNER; return 0; } static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct terratec *tt = video_drvdata(file); + struct tt_device *tt = video_drvdata(file); if (v->index > 0) return -EINVAL; - strlcpy(v->name, "FM", sizeof(v->name)); + strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; - v->rangelow = 87 * 16000; - v->rangehigh = 108 * 16000; + v->rangelow = (87*16000); + v->rangehigh = (108*16000); v->rxsubchans = V4L2_TUNER_SUB_MONO; v->capability = V4L2_TUNER_CAP_LOW; v->audmode = V4L2_TUNER_MODE_MONO; - v->signal = 0xFFFF * tt_getsigstr(tt); + v->signal = 0xFFFF*tt_getsigstr(tt); return 0; } static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - return v->index ? -EINVAL : 0; + if (v->index > 0) + return -EINVAL; + return 0; } static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct terratec *tt = video_drvdata(file); + struct tt_device *tt = video_drvdata(file); - tt_setfreq(tt, f->frequency); + tt->curfreq = f->frequency; + tt_setfreq(tt, tt->curfreq); return 0; } static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct terratec *tt = video_drvdata(file); + struct tt_device *tt = video_drvdata(file); f->type = V4L2_TUNER_RADIO; f->frequency = tt->curfreq; @@ -261,7 +272,8 @@ static int vidioc_queryctrl(struct file *file, void *priv, for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { if (qc->id && qc->id == radio_qctrl[i].id) { - memcpy(qc, &(radio_qctrl[i]), sizeof(*qc)); + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); return 0; } } @@ -271,7 +283,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct terratec *tt = video_drvdata(file); + struct tt_device *tt = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -290,7 +302,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct terratec *tt = video_drvdata(file); + struct tt_device *tt = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -306,46 +318,55 @@ static int vidioc_s_ctrl(struct file *file, void *priv, return -EINVAL; } -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +static int vidioc_g_audio(struct file *file, void *priv, + struct v4l2_audio *a) { - *i = 0; + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; return 0; } -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { - return i ? -EINVAL : 0; + *i = 0; + return 0; } -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; + if (i != 0) + return -EINVAL; return 0; } static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) { - return a->index ? -EINVAL : 0; + if (a->index != 0) + return -EINVAL; + return 0; } -static int terratec_open(struct file *file) +static struct tt_device terratec_unit; + +static int terratec_exclusive_open(struct file *file) { - return 0; + return test_and_set_bit(0, &terratec_unit.in_use) ? -EBUSY : 0; } -static int terratec_release(struct file *file) +static int terratec_exclusive_release(struct file *file) { + clear_bit(0, &terratec_unit.in_use); return 0; } static const struct v4l2_file_operations terratec_fops = { .owner = THIS_MODULE, - .open = terratec_open, - .release = terratec_release, + .open = terratec_exclusive_open, + .release = terratec_exclusive_release, .ioctl = video_ioctl2, }; @@ -364,63 +385,60 @@ static const struct v4l2_ioctl_ops terratec_ioctl_ops = { .vidioc_s_input = vidioc_s_input, }; +static struct video_device terratec_radio = { + .name = "TerraTec ActiveRadio", + .fops = &terratec_fops, + .ioctl_ops = &terratec_ioctl_ops, + .release = video_device_release_empty, +}; + static int __init terratec_init(void) { - struct terratec *tt = &terratec_card; - struct v4l2_device *v4l2_dev = &tt->v4l2_dev; - int res; - - strlcpy(v4l2_dev->name, "terratec", sizeof(v4l2_dev->name)); - tt->io = io; - if (tt->io == -1) { - v4l2_err(v4l2_dev, "you must set an I/O address with io=0x590 or 0x591\n"); + if(io==-1) + { + printk(KERN_ERR "You must set an I/O address with io=0x???\n"); return -EINVAL; } - if (!request_region(tt->io, 2, "terratec")) { - v4l2_err(v4l2_dev, "port 0x%x already in use\n", io); + if (!request_region(io, 2, "terratec")) + { + printk(KERN_ERR "TerraTec: port 0x%x already in use\n", io); return -EBUSY; } - res = v4l2_device_register(NULL, v4l2_dev); - if (res < 0) { - release_region(tt->io, 2); - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); - return res; - } - - strlcpy(tt->vdev.name, v4l2_dev->name, sizeof(tt->vdev.name)); - tt->vdev.v4l2_dev = v4l2_dev; - tt->vdev.fops = &terratec_fops; - tt->vdev.ioctl_ops = &terratec_ioctl_ops; - tt->vdev.release = video_device_release_empty; - video_set_drvdata(&tt->vdev, tt); + video_set_drvdata(&terratec_radio, &terratec_unit); - mutex_init(&tt->lock); + spin_lock_init(&lock); - if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { - v4l2_device_unregister(&tt->v4l2_dev); - release_region(tt->io, 2); + if (video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr) < 0) { + release_region(io,2); return -EINVAL; } - v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n"); + printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver.\n"); /* mute card - prevents noisy bootups */ - tt_write_vol(tt, 0); + + /* this ensures that the volume is all the way down */ + cardWriteVol(0); + terratec_unit.curvol = 0; + return 0; } -static void __exit terratec_exit(void) -{ - struct terratec *tt = &terratec_card; - struct v4l2_device *v4l2_dev = &tt->v4l2_dev; +MODULE_AUTHOR("R.OFFERMANNS & others"); +MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card."); +MODULE_LICENSE("GPL"); +module_param(io, int, 0); +MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)"); +module_param(radio_nr, int, 0); - video_unregister_device(&tt->vdev); - v4l2_device_unregister(&tt->v4l2_dev); - release_region(tt->io, 2); - v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver unloaded.\n"); +static void __exit terratec_cleanup_module(void) +{ + video_unregister_device(&terratec_radio); + release_region(io,2); + printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver unloaded.\n"); } module_init(terratec_init); -module_exit(terratec_exit); +module_exit(terratec_cleanup_module); diff --git a/trunk/drivers/media/radio/radio-trust.c b/trunk/drivers/media/radio/radio-trust.c index d1be6492a07b..bdf9cb6a75f4 100644 --- a/trunk/drivers/media/radio/radio-trust.c +++ b/trunk/drivers/media/radio/radio-trust.c @@ -19,15 +19,49 @@ #include #include #include -#include /* for KERNEL_VERSION MACRO */ +#include +#include #include -#include -#include +#include #include -MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); -MODULE_DESCRIPTION("A driver for the Trust FM Radio card."); -MODULE_LICENSE("GPL"); +#include /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,0,2) + +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + },{ + .id = V4L2_CID_AUDIO_VOLUME, + .name = "Volume", + .minimum = 0, + .maximum = 65535, + .step = 2048, + .default_value = 65535, + .type = V4L2_CTRL_TYPE_INTEGER, + },{ + .id = V4L2_CID_AUDIO_BASS, + .name = "Bass", + .minimum = 0, + .maximum = 65535, + .step = 4370, + .default_value = 32768, + .type = V4L2_CTRL_TYPE_INTEGER, + },{ + .id = V4L2_CID_AUDIO_TREBLE, + .name = "Treble", + .minimum = 0, + .maximum = 65535, + .step = 4370, + .default_value = 32768, + .type = V4L2_CTRL_TYPE_INTEGER, + }, +}; /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ @@ -37,41 +71,26 @@ MODULE_LICENSE("GPL"); static int io = CONFIG_RADIO_TRUST_PORT; static int radio_nr = -1; - -module_param(io, int, 0); -MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)"); -module_param(radio_nr, int, 0); - -#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) - -struct trust { - struct v4l2_device v4l2_dev; - struct video_device vdev; - int io; - int ioval; - __u16 curvol; - __u16 curbass; - __u16 curtreble; - int muted; - unsigned long curfreq; - int curstereo; - int curmute; - struct mutex lock; -}; - -static struct trust trust_card; +static int ioval = 0xf; +static __u16 curvol; +static __u16 curbass; +static __u16 curtreble; +static unsigned long curfreq; +static int curstereo; +static int curmute; +static unsigned long in_use; /* i2c addresses */ #define TDA7318_ADDR 0x88 #define TSA6060T_ADDR 0xc4 -#define TR_DELAY do { inb(tr->io); inb(tr->io); inb(tr->io); } while (0) -#define TR_SET_SCL outb(tr->ioval |= 2, tr->io) -#define TR_CLR_SCL outb(tr->ioval &= 0xfd, tr->io) -#define TR_SET_SDA outb(tr->ioval |= 1, tr->io) -#define TR_CLR_SDA outb(tr->ioval &= 0xfe, tr->io) +#define TR_DELAY do { inb(io); inb(io); inb(io); } while(0) +#define TR_SET_SCL outb(ioval |= 2, io) +#define TR_CLR_SCL outb(ioval &= 0xfd, io) +#define TR_SET_SDA outb(ioval |= 1, io) +#define TR_CLR_SDA outb(ioval &= 0xfe, io) -static void write_i2c(struct trust *tr, int n, ...) +static void write_i2c(int n, ...) { unsigned char val, mask; va_list args; @@ -117,77 +136,62 @@ static void write_i2c(struct trust *tr, int n, ...) va_end(args); } -static void tr_setvol(struct trust *tr, __u16 vol) +static void tr_setvol(__u16 vol) { - mutex_lock(&tr->lock); - tr->curvol = vol / 2048; - write_i2c(tr, 2, TDA7318_ADDR, tr->curvol ^ 0x1f); - mutex_unlock(&tr->lock); + curvol = vol / 2048; + write_i2c(2, TDA7318_ADDR, curvol ^ 0x1f); } static int basstreble2chip[15] = { 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8 }; -static void tr_setbass(struct trust *tr, __u16 bass) +static void tr_setbass(__u16 bass) { - mutex_lock(&tr->lock); - tr->curbass = bass / 4370; - write_i2c(tr, 2, TDA7318_ADDR, 0x60 | basstreble2chip[tr->curbass]); - mutex_unlock(&tr->lock); + curbass = bass / 4370; + write_i2c(2, TDA7318_ADDR, 0x60 | basstreble2chip[curbass]); } -static void tr_settreble(struct trust *tr, __u16 treble) +static void tr_settreble(__u16 treble) { - mutex_lock(&tr->lock); - tr->curtreble = treble / 4370; - write_i2c(tr, 2, TDA7318_ADDR, 0x70 | basstreble2chip[tr->curtreble]); - mutex_unlock(&tr->lock); + curtreble = treble / 4370; + write_i2c(2, TDA7318_ADDR, 0x70 | basstreble2chip[curtreble]); } -static void tr_setstereo(struct trust *tr, int stereo) +static void tr_setstereo(int stereo) { - mutex_lock(&tr->lock); - tr->curstereo = !!stereo; - tr->ioval = (tr->ioval & 0xfb) | (!tr->curstereo << 2); - outb(tr->ioval, tr->io); - mutex_unlock(&tr->lock); + curstereo = !!stereo; + ioval = (ioval & 0xfb) | (!curstereo << 2); + outb(ioval, io); } -static void tr_setmute(struct trust *tr, int mute) +static void tr_setmute(int mute) { - mutex_lock(&tr->lock); - tr->curmute = !!mute; - tr->ioval = (tr->ioval & 0xf7) | (tr->curmute << 3); - outb(tr->ioval, tr->io); - mutex_unlock(&tr->lock); + curmute = !!mute; + ioval = (ioval & 0xf7) | (curmute << 3); + outb(ioval, io); } -static int tr_getsigstr(struct trust *tr) +static int tr_getsigstr(void) { int i, v; - mutex_lock(&tr->lock); - for (i = 0, v = 0; i < 100; i++) - v |= inb(tr->io); - mutex_unlock(&tr->lock); - return (v & 1) ? 0 : 0xffff; + for(i = 0, v = 0; i < 100; i++) v |= inb(io); + return (v & 1)? 0 : 0xffff; } -static int tr_getstereo(struct trust *tr) +static int tr_getstereo(void) { /* don't know how to determine it, just return the setting */ - return tr->curstereo; + return curstereo; } -static void tr_setfreq(struct trust *tr, unsigned long f) +static void tr_setfreq(unsigned long f) { - mutex_lock(&tr->lock); - tr->curfreq = f; f /= 160; /* Convert to 10 kHz units */ - f += 1070; /* Add 10.7 MHz IF */ - write_i2c(tr, 5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0); - mutex_unlock(&tr->lock); + f += 1070; /* Add 10.7 MHz IF */ + + write_i2c(5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0); } static int vidioc_querycap(struct file *file, void *priv, @@ -195,75 +199,68 @@ static int vidioc_querycap(struct file *file, void *priv, { strlcpy(v->driver, "radio-trust", sizeof(v->driver)); strlcpy(v->card, "Trust FM Radio", sizeof(v->card)); - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); + sprintf(v->bus_info, "ISA"); v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->capabilities = V4L2_CAP_TUNER; return 0; } static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct trust *tr = video_drvdata(file); - if (v->index > 0) return -EINVAL; - strlcpy(v->name, "FM", sizeof(v->name)); + strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; - v->rangelow = 87.5 * 16000; - v->rangehigh = 108 * 16000; - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; + v->rangelow = (87.5*16000); + v->rangehigh = (108*16000); + v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; v->capability = V4L2_TUNER_CAP_LOW; - if (tr_getstereo(tr)) + if (tr_getstereo()) v->audmode = V4L2_TUNER_MODE_STEREO; else v->audmode = V4L2_TUNER_MODE_MONO; - v->signal = tr_getsigstr(tr); + v->signal = tr_getsigstr(); return 0; } static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct trust *tr = video_drvdata(file); - - if (v->index) + if (v->index > 0) return -EINVAL; - tr_setstereo(tr, v->audmode == V4L2_TUNER_MODE_STEREO); + return 0; } static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct trust *tr = video_drvdata(file); - - tr_setfreq(tr, f->frequency); + curfreq = f->frequency; + tr_setfreq(curfreq); return 0; } static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct trust *tr = video_drvdata(file); - f->type = V4L2_TUNER_RADIO; - f->frequency = tr->curfreq; + f->frequency = curfreq; return 0; } static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 65535, 2048, 65535); - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - return v4l2_ctrl_query_fill(qc, 0, 65535, 4370, 32768); + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); + return 0; + } } return -EINVAL; } @@ -271,20 +268,18 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct trust *tr = video_drvdata(file); - switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: - ctrl->value = tr->curmute; + ctrl->value = curmute; return 0; case V4L2_CID_AUDIO_VOLUME: - ctrl->value = tr->curvol * 2048; + ctrl->value = curvol * 2048; return 0; case V4L2_CID_AUDIO_BASS: - ctrl->value = tr->curbass * 4370; + ctrl->value = curbass * 4370; return 0; case V4L2_CID_AUDIO_TREBLE: - ctrl->value = tr->curtreble * 4370; + ctrl->value = curtreble * 4370; return 0; } return -EINVAL; @@ -293,65 +288,70 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct trust *tr = video_drvdata(file); - switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: - tr_setmute(tr, ctrl->value); + tr_setmute(ctrl->value); return 0; case V4L2_CID_AUDIO_VOLUME: - tr_setvol(tr, ctrl->value); + tr_setvol(ctrl->value); return 0; case V4L2_CID_AUDIO_BASS: - tr_setbass(tr, ctrl->value); + tr_setbass(ctrl->value); return 0; case V4L2_CID_AUDIO_TREBLE: - tr_settreble(tr, ctrl->value); + tr_settreble(ctrl->value); return 0; } return -EINVAL; } -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +static int vidioc_g_audio(struct file *file, void *priv, + struct v4l2_audio *a) { - *i = 0; + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; return 0; } -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { - return i ? -EINVAL : 0; + *i = 0; + return 0; } -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; + if (i != 0) + return -EINVAL; return 0; } static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) { - return a->index ? -EINVAL : 0; + if (a->index != 0) + return -EINVAL; + return 0; } -static int trust_open(struct file *file) +static int trust_exclusive_open(struct file *file) { - return 0; + return test_and_set_bit(0, &in_use) ? -EBUSY : 0; } -static int trust_release(struct file *file) +static int trust_exclusive_release(struct file *file) { + clear_bit(0, &in_use); return 0; } static const struct v4l2_file_operations trust_fops = { .owner = THIS_MODULE, - .open = trust_open, - .release = trust_release, + .open = trust_exclusive_open, + .release = trust_exclusive_release, .ioctl = video_ioctl2, }; @@ -370,72 +370,59 @@ static const struct v4l2_ioctl_ops trust_ioctl_ops = { .vidioc_s_input = vidioc_s_input, }; +static struct video_device trust_radio = { + .name = "Trust FM Radio", + .fops = &trust_fops, + .ioctl_ops = &trust_ioctl_ops, + .release = video_device_release_empty, +}; + static int __init trust_init(void) { - struct trust *tr = &trust_card; - struct v4l2_device *v4l2_dev = &tr->v4l2_dev; - int res; - - strlcpy(v4l2_dev->name, "trust", sizeof(v4l2_dev->name)); - tr->io = io; - tr->ioval = 0xf; - mutex_init(&tr->lock); - - if (tr->io == -1) { - v4l2_err(v4l2_dev, "You must set an I/O address with io=0x0x350 or 0x358\n"); + if(io == -1) { + printk(KERN_ERR "You must set an I/O address with io=0x???\n"); return -EINVAL; } - if (!request_region(tr->io, 2, "Trust FM Radio")) { - v4l2_err(v4l2_dev, "port 0x%x already in use\n", tr->io); + if(!request_region(io, 2, "Trust FM Radio")) { + printk(KERN_ERR "trust: port 0x%x already in use\n", io); return -EBUSY; } - - res = v4l2_device_register(NULL, v4l2_dev); - if (res < 0) { - release_region(tr->io, 2); - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); - return res; - } - - strlcpy(tr->vdev.name, v4l2_dev->name, sizeof(tr->vdev.name)); - tr->vdev.v4l2_dev = v4l2_dev; - tr->vdev.fops = &trust_fops; - tr->vdev.ioctl_ops = &trust_ioctl_ops; - tr->vdev.release = video_device_release_empty; - video_set_drvdata(&tr->vdev, tr); - - if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { - v4l2_device_unregister(v4l2_dev); - release_region(tr->io, 2); + if (video_register_device(&trust_radio, VFL_TYPE_RADIO, radio_nr) < 0) { + release_region(io, 2); return -EINVAL; } - v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n"); + printk(KERN_INFO "Trust FM Radio card driver v1.0.\n"); - write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */ - write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */ - write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */ - write_i2c(tr, 2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */ - write_i2c(tr, 2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */ + write_i2c(2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */ + write_i2c(2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */ + write_i2c(2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */ + write_i2c(2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */ + write_i2c(2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */ - tr_setvol(tr, 0xffff); - tr_setbass(tr, 0x8000); - tr_settreble(tr, 0x8000); - tr_setstereo(tr, 1); + tr_setvol(0x8000); + tr_setbass(0x8000); + tr_settreble(0x8000); + tr_setstereo(1); /* mute card - prevents noisy bootups */ - tr_setmute(tr, 1); + tr_setmute(1); return 0; } +MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); +MODULE_DESCRIPTION("A driver for the Trust FM Radio card."); +MODULE_LICENSE("GPL"); + +module_param(io, int, 0); +MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)"); +module_param(radio_nr, int, 0); + static void __exit cleanup_trust_module(void) { - struct trust *tr = &trust_card; - - video_unregister_device(&tr->vdev); - v4l2_device_unregister(&tr->v4l2_dev); - release_region(tr->io, 2); + video_unregister_device(&trust_radio); + release_region(io, 2); } module_init(trust_init); diff --git a/trunk/drivers/media/radio/radio-typhoon.c b/trunk/drivers/media/radio/radio-typhoon.c index 92d923c7f360..5c3b319dab37 100644 --- a/trunk/drivers/media/radio/radio-typhoon.c +++ b/trunk/drivers/media/radio/radio-typhoon.c @@ -34,15 +34,37 @@ #include /* Modules */ #include /* Initdata */ #include /* request_region */ -#include /* for KERNEL_VERSION MACRO */ +#include /* radio card status report */ +#include +#include /* outb, outb_p */ +#include /* copy to/from user */ #include /* kernel radio structs */ -#include /* outb, outb_p */ -#include +#include #include -MODULE_AUTHOR("Dr. Henrik Seidel"); -MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio)."); -MODULE_LICENSE("GPL"); +#include /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,1,1) +#define BANNER "Typhoon Radio Card driver v0.1.1\n" + +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + },{ + .id = V4L2_CID_AUDIO_VOLUME, + .name = "Volume", + .minimum = 0, + .maximum = 65535, + .step = 1<<14, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; + #ifndef CONFIG_RADIO_TYPHOON_PORT #define CONFIG_RADIO_TYPHOON_PORT -1 @@ -52,26 +74,13 @@ MODULE_LICENSE("GPL"); #define CONFIG_RADIO_TYPHOON_MUTEFREQ 0 #endif -static int io = CONFIG_RADIO_TYPHOON_PORT; -static int radio_nr = -1; - -module_param(io, int, 0); -MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)"); - -module_param(radio_nr, int, 0); - -static unsigned long mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ; -module_param(mutefreq, ulong, 0); -MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)"); - -#define RADIO_VERSION KERNEL_VERSION(0, 1, 1) - -#define BANNER "Typhoon Radio Card driver v0.1.1\n" +#ifndef CONFIG_PROC_FS +#undef CONFIG_RADIO_TYPHOON_PROC_FS +#endif -struct typhoon { - struct v4l2_device v4l2_dev; - struct video_device vdev; - int io; +struct typhoon_device { + unsigned long in_use; + int iobase; int curvol; int muted; unsigned long curfreq; @@ -79,19 +88,25 @@ struct typhoon { struct mutex lock; }; -static struct typhoon typhoon_card; +static void typhoon_setvol_generic(struct typhoon_device *dev, int vol); +static int typhoon_setfreq_generic(struct typhoon_device *dev, + unsigned long frequency); +static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency); +static void typhoon_mute(struct typhoon_device *dev); +static void typhoon_unmute(struct typhoon_device *dev); +static int typhoon_setvol(struct typhoon_device *dev, int vol); -static void typhoon_setvol_generic(struct typhoon *dev, int vol) +static void typhoon_setvol_generic(struct typhoon_device *dev, int vol) { mutex_lock(&dev->lock); vol >>= 14; /* Map 16 bit to 2 bit */ vol &= 3; - outb_p(vol / 2, dev->io); /* Set the volume, high bit. */ - outb_p(vol % 2, dev->io + 2); /* Set the volume, low bit. */ + outb_p(vol / 2, dev->iobase); /* Set the volume, high bit. */ + outb_p(vol % 2, dev->iobase + 2); /* Set the volume, low bit. */ mutex_unlock(&dev->lock); } -static int typhoon_setfreq_generic(struct typhoon *dev, +static int typhoon_setfreq_generic(struct typhoon_device *dev, unsigned long frequency) { unsigned long outval; @@ -115,22 +130,22 @@ static int typhoon_setfreq_generic(struct typhoon *dev, outval -= (10 * x * x + 10433) / 20866; outval += 4 * x - 11505; - outb_p((outval >> 8) & 0x01, dev->io + 4); - outb_p(outval >> 9, dev->io + 6); - outb_p(outval & 0xff, dev->io + 8); + outb_p((outval >> 8) & 0x01, dev->iobase + 4); + outb_p(outval >> 9, dev->iobase + 6); + outb_p(outval & 0xff, dev->iobase + 8); mutex_unlock(&dev->lock); return 0; } -static int typhoon_setfreq(struct typhoon *dev, unsigned long frequency) +static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency) { typhoon_setfreq_generic(dev, frequency); dev->curfreq = frequency; return 0; } -static void typhoon_mute(struct typhoon *dev) +static void typhoon_mute(struct typhoon_device *dev) { if (dev->muted == 1) return; @@ -139,7 +154,7 @@ static void typhoon_mute(struct typhoon *dev) dev->muted = 1; } -static void typhoon_unmute(struct typhoon *dev) +static void typhoon_unmute(struct typhoon_device *dev) { if (dev->muted == 0) return; @@ -148,7 +163,7 @@ static void typhoon_unmute(struct typhoon *dev) dev->muted = 0; } -static int typhoon_setvol(struct typhoon *dev, int vol) +static int typhoon_setvol(struct typhoon_device *dev, int vol) { if (dev->muted && vol != 0) { /* user is unmuting the card */ dev->curvol = vol; @@ -173,9 +188,9 @@ static int vidioc_querycap(struct file *file, void *priv, { strlcpy(v->driver, "radio-typhoon", sizeof(v->driver)); strlcpy(v->card, "Typhoon Radio", sizeof(v->card)); - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); + sprintf(v->bus_info, "ISA"); v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->capabilities = V4L2_CAP_TUNER; return 0; } @@ -185,10 +200,10 @@ static int vidioc_g_tuner(struct file *file, void *priv, if (v->index > 0) return -EINVAL; - strlcpy(v->name, "FM", sizeof(v->name)); + strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; - v->rangelow = 87.5 * 16000; - v->rangehigh = 108 * 16000; + v->rangelow = (87.5*16000); + v->rangehigh = (108*16000); v->rxsubchans = V4L2_TUNER_SUB_MONO; v->capability = V4L2_TUNER_CAP_LOW; v->audmode = V4L2_TUNER_MODE_MONO; @@ -199,37 +214,44 @@ static int vidioc_g_tuner(struct file *file, void *priv, static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - return v->index ? -EINVAL : 0; + if (v->index > 0) + return -EINVAL; + + return 0; } -static int vidioc_g_frequency(struct file *file, void *priv, +static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct typhoon *dev = video_drvdata(file); + struct typhoon_device *typhoon = video_drvdata(file); - f->type = V4L2_TUNER_RADIO; - f->frequency = dev->curfreq; + typhoon->curfreq = f->frequency; + typhoon_setfreq(typhoon, typhoon->curfreq); return 0; } -static int vidioc_s_frequency(struct file *file, void *priv, +static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct typhoon *dev = video_drvdata(file); + struct typhoon_device *typhoon = video_drvdata(file); + + f->type = V4L2_TUNER_RADIO; + f->frequency = typhoon->curfreq; - dev->curfreq = f->frequency; - typhoon_setfreq(dev, dev->curfreq); return 0; } static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 65535, 16384, 65535); + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); + return 0; + } } return -EINVAL; } @@ -237,14 +259,14 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct typhoon *dev = video_drvdata(file); + struct typhoon_device *typhoon = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: - ctrl->value = dev->muted; + ctrl->value = typhoon->muted; return 0; case V4L2_CID_AUDIO_VOLUME: - ctrl->value = dev->curvol; + ctrl->value = typhoon->curvol; return 0; } return -EINVAL; @@ -253,86 +275,80 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl (struct file *file, void *priv, struct v4l2_control *ctrl) { - struct typhoon *dev = video_drvdata(file); + struct typhoon_device *typhoon = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: if (ctrl->value) - typhoon_mute(dev); + typhoon_mute(typhoon); else - typhoon_unmute(dev); + typhoon_unmute(typhoon); return 0; case V4L2_CID_AUDIO_VOLUME: - typhoon_setvol(dev, ctrl->value); + typhoon_setvol(typhoon, ctrl->value); return 0; } return -EINVAL; } -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +static int vidioc_g_audio(struct file *file, void *priv, + struct v4l2_audio *a) { - *i = 0; + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; return 0; } -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { - return i ? -EINVAL : 0; + *i = 0; + return 0; } -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; + if (i != 0) + return -EINVAL; return 0; } static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) { - return a->index ? -EINVAL : 0; + if (a->index != 0) + return -EINVAL; + return 0; } -static int vidioc_log_status(struct file *file, void *priv) +static struct typhoon_device typhoon_unit = { - struct typhoon *dev = video_drvdata(file); - struct v4l2_device *v4l2_dev = &dev->v4l2_dev; - - v4l2_info(v4l2_dev, BANNER); -#ifdef MODULE - v4l2_info(v4l2_dev, "Load type: Driver loaded as a module\n\n"); -#else - v4l2_info(v4l2_dev, "Load type: Driver compiled into kernel\n\n"); -#endif - v4l2_info(v4l2_dev, "frequency = %lu kHz\n", dev->curfreq >> 4); - v4l2_info(v4l2_dev, "volume = %d\n", dev->curvol); - v4l2_info(v4l2_dev, "mute = %s\n", dev->muted ? "on" : "off"); - v4l2_info(v4l2_dev, "io = 0x%x\n", dev->io); - v4l2_info(v4l2_dev, "mute frequency = %lu kHz\n", dev->mutefreq >> 4); - return 0; -} + .iobase = CONFIG_RADIO_TYPHOON_PORT, + .curfreq = CONFIG_RADIO_TYPHOON_MUTEFREQ, + .mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ, +}; -static int typhoon_open(struct file *file) +static int typhoon_exclusive_open(struct file *file) { - return 0; + return test_and_set_bit(0, &typhoon_unit.in_use) ? -EBUSY : 0; } -static int typhoon_release(struct file *file) +static int typhoon_exclusive_release(struct file *file) { + clear_bit(0, &typhoon_unit.in_use); return 0; } static const struct v4l2_file_operations typhoon_fops = { .owner = THIS_MODULE, - .open = typhoon_open, - .release = typhoon_release, + .open = typhoon_exclusive_open, + .release = typhoon_exclusive_release, .ioctl = video_ioctl2, }; static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { - .vidioc_log_status = vidioc_log_status, .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -347,72 +363,125 @@ static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { .vidioc_s_ctrl = vidioc_s_ctrl, }; -static int __init typhoon_init(void) +static struct video_device typhoon_radio = { + .name = "Typhoon Radio", + .fops = &typhoon_fops, + .ioctl_ops = &typhoon_ioctl_ops, + .release = video_device_release_empty, +}; + +#ifdef CONFIG_RADIO_TYPHOON_PROC_FS + +static int typhoon_proc_show(struct seq_file *m, void *v) +{ + #ifdef MODULE + #define MODULEPROCSTRING "Driver loaded as a module" + #else + #define MODULEPROCSTRING "Driver compiled into kernel" + #endif + + seq_puts(m, BANNER); + seq_puts(m, "Load type: " MODULEPROCSTRING "\n\n"); + seq_printf(m, "frequency = %lu kHz\n", + typhoon_unit.curfreq >> 4); + seq_printf(m, "volume = %d\n", typhoon_unit.curvol); + seq_printf(m, "mute = %s\n", typhoon_unit.muted ? + "on" : "off"); + seq_printf(m, "iobase = 0x%x\n", typhoon_unit.iobase); + seq_printf(m, "mute frequency = %lu kHz\n", + typhoon_unit.mutefreq >> 4); + return 0; +} + +static int typhoon_proc_open(struct inode *inode, struct file *file) { - struct typhoon *dev = &typhoon_card; - struct v4l2_device *v4l2_dev = &dev->v4l2_dev; - int res; + return single_open(file, typhoon_proc_show, NULL); +} + +static const struct file_operations typhoon_proc_fops = { + .owner = THIS_MODULE, + .open = typhoon_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif /* CONFIG_RADIO_TYPHOON_PROC_FS */ + +MODULE_AUTHOR("Dr. Henrik Seidel"); +MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio)."); +MODULE_LICENSE("GPL"); + +static int io = -1; +static int radio_nr = -1; + +module_param(io, int, 0); +MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)"); +module_param(radio_nr, int, 0); - strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name)); - dev->io = io; - dev->curfreq = dev->mutefreq = mutefreq; +#ifdef MODULE +static unsigned long mutefreq; +module_param(mutefreq, ulong, 0); +MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)"); +#endif - if (dev->io == -1) { - v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n"); +static int __init typhoon_init(void) +{ +#ifdef MODULE + if (io == -1) { + printk(KERN_ERR "radio-typhoon: You must set an I/O address with io=0x316 or io=0x336\n"); return -EINVAL; } + typhoon_unit.iobase = io; - if (dev->mutefreq < 87000 || dev->mutefreq > 108500) { - v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n"); - v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n"); + if (mutefreq < 87000 || mutefreq > 108500) { + printk(KERN_ERR "radio-typhoon: You must set a frequency (in kHz) used when muting the card,\n"); + printk(KERN_ERR "radio-typhoon: e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n"); return -EINVAL; } - - mutex_init(&dev->lock); - if (!request_region(dev->io, 8, "typhoon")) { - v4l2_err(v4l2_dev, "port 0x%x already in use\n", - dev->io); + typhoon_unit.mutefreq = mutefreq; +#endif /* MODULE */ + + printk(KERN_INFO BANNER); + mutex_init(&typhoon_unit.lock); + io = typhoon_unit.iobase; + if (!request_region(io, 8, "typhoon")) { + printk(KERN_ERR "radio-typhoon: port 0x%x already in use\n", + typhoon_unit.iobase); return -EBUSY; } - res = v4l2_device_register(NULL, v4l2_dev); - if (res < 0) { - release_region(dev->io, 8); - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); - return res; - } - v4l2_info(v4l2_dev, BANNER); - - strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); - dev->vdev.v4l2_dev = v4l2_dev; - dev->vdev.fops = &typhoon_fops; - dev->vdev.ioctl_ops = &typhoon_ioctl_ops; - dev->vdev.release = video_device_release_empty; - video_set_drvdata(&dev->vdev, dev); - if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { - v4l2_device_unregister(&dev->v4l2_dev); - release_region(dev->io, 8); + video_set_drvdata(&typhoon_radio, &typhoon_unit); + if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO, radio_nr) < 0) { + release_region(io, 8); return -EINVAL; } - v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io); - v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", dev->mutefreq); - dev->mutefreq <<= 4; + printk(KERN_INFO "radio-typhoon: port 0x%x.\n", typhoon_unit.iobase); + printk(KERN_INFO "radio-typhoon: mute frequency is %lu kHz.\n", + typhoon_unit.mutefreq); + typhoon_unit.mutefreq <<= 4; /* mute card - prevents noisy bootups */ - typhoon_mute(dev); + typhoon_mute(&typhoon_unit); + +#ifdef CONFIG_RADIO_TYPHOON_PROC_FS + if (!proc_create("driver/radio-typhoon", 0, NULL, &typhoon_proc_fops)) + printk(KERN_ERR "radio-typhoon: registering /proc/driver/radio-typhoon failed\n"); +#endif return 0; } -static void __exit typhoon_exit(void) +static void __exit typhoon_cleanup_module(void) { - struct typhoon *dev = &typhoon_card; - video_unregister_device(&dev->vdev); - v4l2_device_unregister(&dev->v4l2_dev); - release_region(dev->io, 8); +#ifdef CONFIG_RADIO_TYPHOON_PROC_FS + remove_proc_entry("driver/radio-typhoon", NULL); +#endif + + video_unregister_device(&typhoon_radio); + release_region(io, 8); } module_init(typhoon_init); -module_exit(typhoon_exit); +module_exit(typhoon_cleanup_module); diff --git a/trunk/drivers/media/radio/radio-zoltrix.c b/trunk/drivers/media/radio/radio-zoltrix.c index 1f85f2024dc0..d2ac17eeec5f 100644 --- a/trunk/drivers/media/radio/radio-zoltrix.c +++ b/trunk/drivers/media/radio/radio-zoltrix.c @@ -33,16 +33,33 @@ #include /* Initdata */ #include /* request_region */ #include /* udelay, msleep */ +#include /* outb, outb_p */ +#include /* copy to/from user */ #include /* kernel radio structs */ -#include -#include /* for KERNEL_VERSION MACRO */ -#include /* outb, outb_p */ -#include +#include #include -MODULE_AUTHOR("C.van Schaik"); -MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus."); -MODULE_LICENSE("GPL"); +#include /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,0,2) + +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + },{ + .id = V4L2_CID_AUDIO_VOLUME, + .name = "Volume", + .minimum = 0, + .maximum = 65535, + .step = 4096, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; #ifndef CONFIG_RADIO_ZOLTRIX_PORT #define CONFIG_RADIO_ZOLTRIX_PORT -1 @@ -51,16 +68,9 @@ MODULE_LICENSE("GPL"); static int io = CONFIG_RADIO_ZOLTRIX_PORT; static int radio_nr = -1; -module_param(io, int, 0); -MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)"); -module_param(radio_nr, int, 0); - -#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) - -struct zoltrix { - struct v4l2_device v4l2_dev; - struct video_device vdev; - int io; +struct zol_device { + unsigned long in_use; + int port; int curvol; unsigned long curfreq; int muted; @@ -68,158 +78,161 @@ struct zoltrix { struct mutex lock; }; -static struct zoltrix zoltrix_card; - -static int zol_setvol(struct zoltrix *zol, int vol) +static int zol_setvol(struct zol_device *dev, int vol) { - zol->curvol = vol; - if (zol->muted) + dev->curvol = vol; + if (dev->muted) return 0; - mutex_lock(&zol->lock); + mutex_lock(&dev->lock); if (vol == 0) { - outb(0, zol->io); - outb(0, zol->io); - inb(zol->io + 3); /* Zoltrix needs to be read to confirm */ - mutex_unlock(&zol->lock); + outb(0, io); + outb(0, io); + inb(io + 3); /* Zoltrix needs to be read to confirm */ + mutex_unlock(&dev->lock); return 0; } - outb(zol->curvol-1, zol->io); + outb(dev->curvol-1, io); msleep(10); - inb(zol->io + 2); - mutex_unlock(&zol->lock); + inb(io + 2); + mutex_unlock(&dev->lock); return 0; } -static void zol_mute(struct zoltrix *zol) +static void zol_mute(struct zol_device *dev) { - zol->muted = 1; - mutex_lock(&zol->lock); - outb(0, zol->io); - outb(0, zol->io); - inb(zol->io + 3); /* Zoltrix needs to be read to confirm */ - mutex_unlock(&zol->lock); + dev->muted = 1; + mutex_lock(&dev->lock); + outb(0, io); + outb(0, io); + inb(io + 3); /* Zoltrix needs to be read to confirm */ + mutex_unlock(&dev->lock); } -static void zol_unmute(struct zoltrix *zol) +static void zol_unmute(struct zol_device *dev) { - zol->muted = 0; - zol_setvol(zol, zol->curvol); + dev->muted = 0; + zol_setvol(dev, dev->curvol); } -static int zol_setfreq(struct zoltrix *zol, unsigned long freq) +static int zol_setfreq(struct zol_device *dev, unsigned long freq) { /* tunes the radio to the desired frequency */ - struct v4l2_device *v4l2_dev = &zol->v4l2_dev; unsigned long long bitmask, f, m; - unsigned int stereo = zol->stereo; + unsigned int stereo = dev->stereo; int i; if (freq == 0) { - v4l2_warn(v4l2_dev, "cannot set a frequency of 0.\n"); + printk(KERN_WARNING "zoltrix: received zero freq. Failed to set.\n"); return -EINVAL; } m = (freq / 160 - 8800) * 2; - f = (unsigned long long)m + 0x4d1c; + f = (unsigned long long) m + 0x4d1c; bitmask = 0xc480402c10080000ull; i = 45; - mutex_lock(&zol->lock); + mutex_lock(&dev->lock); - zol->curfreq = freq; + outb(0, io); + outb(0, io); + inb(io + 3); /* Zoltrix needs to be read to confirm */ - outb(0, zol->io); - outb(0, zol->io); - inb(zol->io + 3); /* Zoltrix needs to be read to confirm */ + outb(0x40, io); + outb(0xc0, io); - outb(0x40, zol->io); - outb(0xc0, zol->io); - - bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ (stereo << 31)); + bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ ( stereo << 31)); while (i--) { if ((bitmask & 0x8000000000000000ull) != 0) { - outb(0x80, zol->io); + outb(0x80, io); udelay(50); - outb(0x00, zol->io); + outb(0x00, io); udelay(50); - outb(0x80, zol->io); + outb(0x80, io); udelay(50); } else { - outb(0xc0, zol->io); + outb(0xc0, io); udelay(50); - outb(0x40, zol->io); + outb(0x40, io); udelay(50); - outb(0xc0, zol->io); + outb(0xc0, io); udelay(50); } bitmask *= 2; } /* termination sequence */ - outb(0x80, zol->io); - outb(0xc0, zol->io); - outb(0x40, zol->io); + outb(0x80, io); + outb(0xc0, io); + outb(0x40, io); udelay(1000); - inb(zol->io + 2); + inb(io+2); udelay(1000); - if (zol->muted) { - outb(0, zol->io); - outb(0, zol->io); - inb(zol->io + 3); + if (dev->muted) + { + outb(0, io); + outb(0, io); + inb(io + 3); udelay(1000); } - mutex_unlock(&zol->lock); + mutex_unlock(&dev->lock); - if (!zol->muted) - zol_setvol(zol, zol->curvol); + if(!dev->muted) + { + zol_setvol(dev, dev->curvol); + } return 0; } /* Get signal strength */ -static int zol_getsigstr(struct zoltrix *zol) + +static int zol_getsigstr(struct zol_device *dev) { int a, b; - mutex_lock(&zol->lock); - outb(0x00, zol->io); /* This stuff I found to do nothing */ - outb(zol->curvol, zol->io); + mutex_lock(&dev->lock); + outb(0x00, io); /* This stuff I found to do nothing */ + outb(dev->curvol, io); msleep(20); - a = inb(zol->io); + a = inb(io); msleep(10); - b = inb(zol->io); + b = inb(io); - mutex_unlock(&zol->lock); + mutex_unlock(&dev->lock); if (a != b) - return 0; + return (0); - /* I found this out by playing with a binary scanner on the card io */ - return a == 0xcf || a == 0xdf || a == 0xef; + if ((a == 0xcf) || (a == 0xdf) /* I found this out by playing */ + || (a == 0xef)) /* with a binary scanner on the card io */ + return (1); + return (0); } -static int zol_is_stereo(struct zoltrix *zol) +static int zol_is_stereo (struct zol_device *dev) { int x1, x2; - mutex_lock(&zol->lock); + mutex_lock(&dev->lock); - outb(0x00, zol->io); - outb(zol->curvol, zol->io); + outb(0x00, io); + outb(dev->curvol, io); msleep(20); - x1 = inb(zol->io); + x1 = inb(io); msleep(10); - x2 = inb(zol->io); + x2 = inb(io); - mutex_unlock(&zol->lock); + mutex_unlock(&dev->lock); - return x1 == x2 && x1 == 0xcf; + if ((x1 == x2) && (x1 == 0xcf)) + return 1; + return 0; } static int vidioc_querycap(struct file *file, void *priv, @@ -227,54 +240,59 @@ static int vidioc_querycap(struct file *file, void *priv, { strlcpy(v->driver, "radio-zoltrix", sizeof(v->driver)); strlcpy(v->card, "Zoltrix Radio", sizeof(v->card)); - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); + sprintf(v->bus_info, "ISA"); v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + v->capabilities = V4L2_CAP_TUNER; return 0; } static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - struct zoltrix *zol = video_drvdata(file); + struct zol_device *zol = video_drvdata(file); if (v->index > 0) return -EINVAL; - strlcpy(v->name, "FM", sizeof(v->name)); + strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; - v->rangelow = 88 * 16000; - v->rangehigh = 108 * 16000; - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; + v->rangelow = (88*16000); + v->rangehigh = (108*16000); + v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; v->capability = V4L2_TUNER_CAP_LOW; if (zol_is_stereo(zol)) v->audmode = V4L2_TUNER_MODE_STEREO; else v->audmode = V4L2_TUNER_MODE_MONO; - v->signal = 0xFFFF * zol_getsigstr(zol); + v->signal = 0xFFFF*zol_getsigstr(zol); return 0; } static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { - return v->index ? -EINVAL : 0; + if (v->index > 0) + return -EINVAL; + return 0; } static int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct zoltrix *zol = video_drvdata(file); + struct zol_device *zol = video_drvdata(file); - if (zol_setfreq(zol, f->frequency) != 0) + zol->curfreq = f->frequency; + if (zol_setfreq(zol, zol->curfreq) != 0) { + printk(KERN_WARNING "zoltrix: Set frequency failed.\n"); return -EINVAL; + } return 0; } static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct zoltrix *zol = video_drvdata(file); + struct zol_device *zol = video_drvdata(file); f->type = V4L2_TUNER_RADIO; f->frequency = zol->curfreq; @@ -284,11 +302,14 @@ static int vidioc_g_frequency(struct file *file, void *priv, static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 65535, 4096, 65535); + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); + return 0; + } } return -EINVAL; } @@ -296,7 +317,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct zoltrix *zol = video_drvdata(file); + struct zol_device *zol = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -312,7 +333,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct zoltrix *zol = video_drvdata(file); + struct zol_device *zol = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: @@ -320,71 +341,82 @@ static int vidioc_s_ctrl(struct file *file, void *priv, zol_mute(zol); else { zol_unmute(zol); - zol_setvol(zol, zol->curvol); + zol_setvol(zol,zol->curvol); } return 0; case V4L2_CID_AUDIO_VOLUME: - zol_setvol(zol, ctrl->value / 4096); + zol_setvol(zol,ctrl->value/4096); return 0; } zol->stereo = 1; - if (zol_setfreq(zol, zol->curfreq) != 0) + if (zol_setfreq(zol, zol->curfreq) != 0) { + printk(KERN_WARNING "zoltrix: Set frequency failed.\n"); return -EINVAL; + } #if 0 /* FIXME: Implement stereo/mono switch on V4L2 */ - if (v->mode & VIDEO_SOUND_STEREO) { - zol->stereo = 1; - zol_setfreq(zol, zol->curfreq); - } - if (v->mode & VIDEO_SOUND_MONO) { - zol->stereo = 0; - zol_setfreq(zol, zol->curfreq); - } + if (v->mode & VIDEO_SOUND_STEREO) { + zol->stereo = 1; + zol_setfreq(zol, zol->curfreq); + } + if (v->mode & VIDEO_SOUND_MONO) { + zol->stereo = 0; + zol_setfreq(zol, zol->curfreq); + } #endif return -EINVAL; } -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +static int vidioc_g_audio(struct file *file, void *priv, + struct v4l2_audio *a) { - *i = 0; + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; return 0; } -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { - return i ? -EINVAL : 0; + *i = 0; + return 0; } -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; + if (i != 0) + return -EINVAL; return 0; } static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) { - return a->index ? -EINVAL : 0; + if (a->index != 0) + return -EINVAL; + return 0; } -static int zoltrix_open(struct file *file) +static struct zol_device zoltrix_unit; + +static int zoltrix_exclusive_open(struct file *file) { - return 0; + return test_and_set_bit(0, &zoltrix_unit.in_use) ? -EBUSY : 0; } -static int zoltrix_release(struct file *file) +static int zoltrix_exclusive_release(struct file *file) { + clear_bit(0, &zoltrix_unit.in_use); return 0; } static const struct v4l2_file_operations zoltrix_fops = { .owner = THIS_MODULE, - .open = zoltrix_open, - .release = zoltrix_release, + .open = zoltrix_exclusive_open, + .release = zoltrix_exclusive_release, .ioctl = video_ioctl2, }; @@ -403,75 +435,67 @@ static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device zoltrix_radio = { + .name = "Zoltrix Radio Plus", + .fops = &zoltrix_fops, + .ioctl_ops = &zoltrix_ioctl_ops, + .release = video_device_release_empty, +}; + static int __init zoltrix_init(void) { - struct zoltrix *zol = &zoltrix_card; - struct v4l2_device *v4l2_dev = &zol->v4l2_dev; - int res; - - strlcpy(v4l2_dev->name, "zoltrix", sizeof(v4l2_dev->name)); - zol->io = io; - if (zol->io == -1) { - v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or 0x30c\n"); + if (io == -1) { + printk(KERN_ERR "You must set an I/O address with io=0x???\n"); return -EINVAL; } - if (zol->io != 0x20c && zol->io != 0x30c) { - v4l2_err(v4l2_dev, "invalid port, try 0x20c or 0x30c\n"); + if ((io != 0x20c) && (io != 0x30c)) { + printk(KERN_ERR "zoltrix: invalid port, try 0x20c or 0x30c\n"); return -ENXIO; } - if (!request_region(zol->io, 2, "zoltrix")) { - v4l2_err(v4l2_dev, "port 0x%x already in use\n", zol->io); + video_set_drvdata(&zoltrix_radio, &zoltrix_unit); + if (!request_region(io, 2, "zoltrix")) { + printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io); return -EBUSY; } - res = v4l2_device_register(NULL, v4l2_dev); - if (res < 0) { - release_region(zol->io, 2); - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); - return res; - } - - strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name)); - zol->vdev.v4l2_dev = v4l2_dev; - zol->vdev.fops = &zoltrix_fops; - zol->vdev.ioctl_ops = &zoltrix_ioctl_ops; - zol->vdev.release = video_device_release_empty; - video_set_drvdata(&zol->vdev, zol); - - if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { - v4l2_device_unregister(v4l2_dev); - release_region(zol->io, 2); + if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO, radio_nr) < 0) { + release_region(io, 2); return -EINVAL; } - v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n"); + printk(KERN_INFO "Zoltrix Radio Plus card driver.\n"); - mutex_init(&zol->lock); + mutex_init(&zoltrix_unit.lock); /* mute card - prevents noisy bootups */ /* this ensures that the volume is all the way down */ - outb(0, zol->io); - outb(0, zol->io); + outb(0, io); + outb(0, io); msleep(20); - inb(zol->io + 3); + inb(io + 3); - zol->curvol = 0; - zol->stereo = 1; + zoltrix_unit.curvol = 0; + zoltrix_unit.stereo = 1; return 0; } -static void __exit zoltrix_exit(void) -{ - struct zoltrix *zol = &zoltrix_card; +MODULE_AUTHOR("C.van Schaik"); +MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus."); +MODULE_LICENSE("GPL"); + +module_param(io, int, 0); +MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)"); +module_param(radio_nr, int, 0); - video_unregister_device(&zol->vdev); - v4l2_device_unregister(&zol->v4l2_dev); - release_region(zol->io, 2); +static void __exit zoltrix_cleanup_module(void) +{ + video_unregister_device(&zoltrix_radio); + release_region(io, 2); } module_init(zoltrix_init); -module_exit(zoltrix_exit); +module_exit(zoltrix_cleanup_module); diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index 76bad5819592..19cf3b8f67c4 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -249,25 +249,11 @@ config VIDEO_VP27SMPX To compile this driver as a module, choose M here: the module will be called vp27smpx. -comment "RDS decoders" - -config VIDEO_SAA6588 - tristate "SAA6588 Radio Chip RDS decoder support" - depends on VIDEO_V4L2 && I2C - - help - Support for this Radio Data System (RDS) decoder. This allows - seeing radio station identification transmitted using this - standard. - - To compile this driver as a module, choose M here: the - module will be called saa6588. - comment "Video decoders" config VIDEO_BT819 tristate "BT819A VideoStream decoder" - depends on VIDEO_V4L2 && I2C + depends on VIDEO_V4L1 && I2C ---help--- Support for BT819A video decoder. @@ -276,7 +262,7 @@ config VIDEO_BT819 config VIDEO_BT856 tristate "BT856 VideoStream decoder" - depends on VIDEO_V4L2 && I2C + depends on VIDEO_V4L1 && I2C ---help--- Support for BT856 video decoder. @@ -285,7 +271,7 @@ config VIDEO_BT856 config VIDEO_BT866 tristate "BT866 VideoStream decoder" - depends on VIDEO_V4L2 && I2C + depends on VIDEO_V4L1 && I2C ---help--- Support for BT866 video decoder. @@ -294,7 +280,7 @@ config VIDEO_BT866 config VIDEO_KS0127 tristate "KS0127 video decoder" - depends on VIDEO_V4L2 && I2C + depends on VIDEO_V4L1 && I2C ---help--- Support for KS0127 video decoder. @@ -321,18 +307,38 @@ config VIDEO_TCM825X config VIDEO_SAA7110 tristate "Philips SAA7110 video decoder" - depends on VIDEO_V4L2 && I2C + depends on VIDEO_V4L1 && I2C ---help--- Support for the Philips SAA7110 video decoders. To compile this driver as a module, choose M here: the module will be called saa7110. +config VIDEO_SAA7111 + tristate "Philips SAA7111 video decoder" + depends on VIDEO_V4L1 && I2C + ---help--- + Support for the Philips SAA711 video decoder. + + To compile this driver as a module, choose M here: the + module will be called saa7111. + +config VIDEO_SAA7114 + tristate "Philips SAA7114 video decoder" + depends on VIDEO_V4L1 && I2C + ---help--- + Support for the Philips SAA7114 video decoder. This driver + is used only on Zoran driver and should be moved soon to + SAA711x module. + + To compile this driver as a module, choose M here: the + module will be called saa7114. + config VIDEO_SAA711X - tristate "Philips SAA7111/3/4/5 video decoders" + tristate "Philips SAA7113/4/5 video decoders" depends on VIDEO_V4L2 && I2C ---help--- - Support for the Philips SAA7111/3/4/5 video decoders. + Support for the Philips SAA7113/4/5 video decoders. To compile this driver as a module, choose M here: the module will be called saa7115. @@ -377,7 +383,7 @@ config VIDEO_TVP5150 config VIDEO_VPX3220 tristate "vpx3220a, vpx3216b & vpx3214c video decoders" - depends on VIDEO_V4L2 && I2C + depends on VIDEO_V4L1 && I2C ---help--- Support for VPX322x video decoders. @@ -415,7 +421,7 @@ config VIDEO_SAA7127 config VIDEO_SAA7185 tristate "Philips SAA7185 video encoder" - depends on VIDEO_V4L2 && I2C + depends on VIDEO_V4L1 && I2C ---help--- Support for the Philips SAA7185 video encoder. @@ -424,7 +430,7 @@ config VIDEO_SAA7185 config VIDEO_ADV7170 tristate "Analog Devices ADV7170 video encoder" - depends on VIDEO_V4L2 && I2C + depends on VIDEO_V4L1 && I2C ---help--- Support for the Analog Devices ADV7170 video encoder driver @@ -433,7 +439,7 @@ config VIDEO_ADV7170 config VIDEO_ADV7175 tristate "Analog Devices ADV7175 video encoder" - depends on VIDEO_V4L2 && I2C + depends on VIDEO_V4L1 && I2C ---help--- Support for the Analog Devices ADV7175 video encoder driver @@ -481,6 +487,18 @@ config VIDEO_VIVI source "drivers/media/video/bt8xx/Kconfig" +config VIDEO_SAA6588 + tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards" + depends on I2C && VIDEO_BT848 + + help + Support for Radio Data System (RDS) decoder. This allows seeing + radio station identification transmitted using this standard. + Currently, it works only with bt8x8 chips. + + To compile this driver as a module, choose M here: the + module will be called saa6588. + config VIDEO_PMS tristate "Mediavision Pro Movie Studio Video For Linux" depends on ISA && VIDEO_V4L1 @@ -584,6 +602,7 @@ config VIDEO_SAA5249 config VIDEO_VINO tristate "SGI Vino Video For Linux (EXPERIMENTAL)" depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2 + select I2C_ALGO_SGI select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO help Say Y here to build in support for the Vino video input system found @@ -620,7 +639,7 @@ config VIDEO_MXB depends on PCI && VIDEO_V4L1 && I2C select VIDEO_SAA7146_VV select VIDEO_TUNER - select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_SAA7115 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TEA6420 if VIDEO_HELPER_CHIPS_AUTO @@ -709,6 +728,13 @@ config SOC_CAMERA_MT9M001 This driver supports MT9M001 cameras from Micron, monochrome and colour models. +config MT9M001_PCA9536_SWITCH + bool "pca9536 datawidth switch for mt9m001" + depends on SOC_CAMERA_MT9M001 && GENERIC_GPIO + help + Select this if your MT9M001 camera uses a PCA9536 I2C GPIO + extender to switch between 8 and 10 bit datawidth modes + config SOC_CAMERA_MT9M111 tristate "mt9m111 and mt9m112 support" depends on SOC_CAMERA && I2C @@ -728,6 +754,13 @@ config SOC_CAMERA_MT9V022 help This driver supports MT9V022 cameras from Micron +config MT9V022_PCA9536_SWITCH + bool "pca9536 datawidth switch for mt9v022" + depends on SOC_CAMERA_MT9V022 && GENERIC_GPIO + help + Select this if your MT9V022 camera uses a PCA9536 I2C GPIO + extender to switch between 8 and 10 bit datawidth modes + config SOC_CAMERA_TW9910 tristate "tw9910 support" depends on SOC_CAMERA && I2C @@ -746,13 +779,6 @@ config SOC_CAMERA_OV772X help This is a ov772x camera driver -config VIDEO_MX3 - tristate "i.MX3x Camera Sensor Interface driver" - depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA - select VIDEOBUF_DMA_CONTIG - ---help--- - This is a v4l2 driver for the i.MX3x Camera Sensor Interface - config VIDEO_PXA27x tristate "PXA27x Quick Capture Interface driver" depends on VIDEO_DEV && PXA27x && SOC_CAMERA @@ -791,8 +817,6 @@ source "drivers/media/video/gspca/Kconfig" source "drivers/media/video/pvrusb2/Kconfig" -source "drivers/media/video/hdpvr/Kconfig" - source "drivers/media/video/em28xx/Kconfig" source "drivers/media/video/usbvision/Kconfig" diff --git a/trunk/drivers/media/video/Makefile b/trunk/drivers/media/video/Makefile index b9046744463b..72f6d03d2d8f 100644 --- a/trunk/drivers/media/video/Makefile +++ b/trunk/drivers/media/video/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o +obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o @@ -42,6 +43,8 @@ obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o +obj-$(CONFIG_VIDEO_SAA7111) += saa7111.o +obj-$(CONFIG_VIDEO_SAA7114) += saa7114.o obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o @@ -119,8 +122,6 @@ obj-$(CONFIG_USB_PWC) += pwc/ obj-$(CONFIG_USB_ZC0301) += zc0301/ obj-$(CONFIG_USB_GSPCA) += gspca/ -obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/ - obj-$(CONFIG_USB_IBMCAM) += usbvideo/ obj-$(CONFIG_USB_KONICAWC) += usbvideo/ obj-$(CONFIG_USB_VICAM) += usbvideo/ @@ -133,11 +134,10 @@ obj-$(CONFIG_VIDEO_CX18) += cx18/ obj-$(CONFIG_VIDEO_VIVI) += vivi.o obj-$(CONFIG_VIDEO_CX23885) += cx23885/ -obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o -obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o +obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o -obj-$(CONFIG_SOC_CAMERA) += soc_camera.o +obj-$(CONFIG_SOC_CAMERA) += soc_camera.o obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o diff --git a/trunk/drivers/media/video/adv7170.c b/trunk/drivers/media/video/adv7170.c index 873c30a41bd7..e0eb4f321442 100644 --- a/trunk/drivers/media/video/adv7170.c +++ b/trunk/drivers/media/video/adv7170.c @@ -34,16 +34,15 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver"); MODULE_AUTHOR("Maxim Yevtyushkin"); MODULE_LICENSE("GPL"); - static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); @@ -51,43 +50,38 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); /* ----------------------------------------------------------------------- */ struct adv7170 { - struct v4l2_subdev sd; unsigned char reg[128]; - v4l2_std_id norm; + int norm; int input; + int enable; + int bright; + int contrast; + int hue; + int sat; }; -static inline struct adv7170 *to_adv7170(struct v4l2_subdev *sd) -{ - return container_of(sd, struct adv7170, sd); -} - static char *inputs[] = { "pass_through", "play_back" }; +static char *norms[] = { "PAL", "NTSC" }; /* ----------------------------------------------------------------------- */ -static inline int adv7170_write(struct v4l2_subdev *sd, u8 reg, u8 value) +static inline int adv7170_write(struct i2c_client *client, u8 reg, u8 value) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct adv7170 *encoder = to_adv7170(sd); + struct adv7170 *encoder = i2c_get_clientdata(client); encoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } -static inline int adv7170_read(struct v4l2_subdev *sd, u8 reg) +static inline int adv7170_read(struct i2c_client *client, u8 reg) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - return i2c_smbus_read_byte_data(client, reg); } -static int adv7170_write_block(struct v4l2_subdev *sd, +static int adv7170_write_block(struct i2c_client *client, const u8 *data, unsigned int len) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct adv7170 *encoder = to_adv7170(sd); int ret = -1; u8 reg; @@ -95,6 +89,7 @@ static int adv7170_write_block(struct v4l2_subdev *sd, * the adapter understands raw I2C */ if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { /* do raw I2C, not smbus compatible */ + struct adv7170 *encoder = i2c_get_clientdata(client); u8 block_data[32]; int block_len; @@ -115,7 +110,7 @@ static int adv7170_write_block(struct v4l2_subdev *sd, /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - ret = adv7170_write(sd, reg, *data++); + ret = adv7170_write(client, reg, *data++); if (ret < 0) break; len -= 2; @@ -133,161 +128,203 @@ static int adv7170_write_block(struct v4l2_subdev *sd, #define TR1PLAY 0x00 static const unsigned char init_NTSC[] = { - 0x00, 0x10, /* MR0 */ - 0x01, 0x20, /* MR1 */ - 0x02, 0x0e, /* MR2 RTC control: bits 2 and 1 */ - 0x03, 0x80, /* MR3 */ - 0x04, 0x30, /* MR4 */ - 0x05, 0x00, /* Reserved */ - 0x06, 0x00, /* Reserved */ - 0x07, TR0MODE, /* TM0 */ - 0x08, TR1CAPT, /* TM1 */ - 0x09, 0x16, /* Fsc0 */ - 0x0a, 0x7c, /* Fsc1 */ - 0x0b, 0xf0, /* Fsc2 */ - 0x0c, 0x21, /* Fsc3 */ - 0x0d, 0x00, /* Subcarrier Phase */ - 0x0e, 0x00, /* Closed Capt. Ext 0 */ - 0x0f, 0x00, /* Closed Capt. Ext 1 */ - 0x10, 0x00, /* Closed Capt. 0 */ - 0x11, 0x00, /* Closed Capt. 1 */ - 0x12, 0x00, /* Pedestal Ctl 0 */ - 0x13, 0x00, /* Pedestal Ctl 1 */ - 0x14, 0x00, /* Pedestal Ctl 2 */ - 0x15, 0x00, /* Pedestal Ctl 3 */ - 0x16, 0x00, /* CGMS_WSS_0 */ - 0x17, 0x00, /* CGMS_WSS_1 */ - 0x18, 0x00, /* CGMS_WSS_2 */ - 0x19, 0x00, /* Teletext Ctl */ + 0x00, 0x10, // MR0 + 0x01, 0x20, // MR1 + 0x02, 0x0e, // MR2 RTC control: bits 2 and 1 + 0x03, 0x80, // MR3 + 0x04, 0x30, // MR4 + 0x05, 0x00, // Reserved + 0x06, 0x00, // Reserved + 0x07, TR0MODE, // TM0 + 0x08, TR1CAPT, // TM1 + 0x09, 0x16, // Fsc0 + 0x0a, 0x7c, // Fsc1 + 0x0b, 0xf0, // Fsc2 + 0x0c, 0x21, // Fsc3 + 0x0d, 0x00, // Subcarrier Phase + 0x0e, 0x00, // Closed Capt. Ext 0 + 0x0f, 0x00, // Closed Capt. Ext 1 + 0x10, 0x00, // Closed Capt. 0 + 0x11, 0x00, // Closed Capt. 1 + 0x12, 0x00, // Pedestal Ctl 0 + 0x13, 0x00, // Pedestal Ctl 1 + 0x14, 0x00, // Pedestal Ctl 2 + 0x15, 0x00, // Pedestal Ctl 3 + 0x16, 0x00, // CGMS_WSS_0 + 0x17, 0x00, // CGMS_WSS_1 + 0x18, 0x00, // CGMS_WSS_2 + 0x19, 0x00, // Teletext Ctl }; static const unsigned char init_PAL[] = { - 0x00, 0x71, /* MR0 */ - 0x01, 0x20, /* MR1 */ - 0x02, 0x0e, /* MR2 RTC control: bits 2 and 1 */ - 0x03, 0x80, /* MR3 */ - 0x04, 0x30, /* MR4 */ - 0x05, 0x00, /* Reserved */ - 0x06, 0x00, /* Reserved */ - 0x07, TR0MODE, /* TM0 */ - 0x08, TR1CAPT, /* TM1 */ - 0x09, 0xcb, /* Fsc0 */ - 0x0a, 0x8a, /* Fsc1 */ - 0x0b, 0x09, /* Fsc2 */ - 0x0c, 0x2a, /* Fsc3 */ - 0x0d, 0x00, /* Subcarrier Phase */ - 0x0e, 0x00, /* Closed Capt. Ext 0 */ - 0x0f, 0x00, /* Closed Capt. Ext 1 */ - 0x10, 0x00, /* Closed Capt. 0 */ - 0x11, 0x00, /* Closed Capt. 1 */ - 0x12, 0x00, /* Pedestal Ctl 0 */ - 0x13, 0x00, /* Pedestal Ctl 1 */ - 0x14, 0x00, /* Pedestal Ctl 2 */ - 0x15, 0x00, /* Pedestal Ctl 3 */ - 0x16, 0x00, /* CGMS_WSS_0 */ - 0x17, 0x00, /* CGMS_WSS_1 */ - 0x18, 0x00, /* CGMS_WSS_2 */ - 0x19, 0x00, /* Teletext Ctl */ + 0x00, 0x71, // MR0 + 0x01, 0x20, // MR1 + 0x02, 0x0e, // MR2 RTC control: bits 2 and 1 + 0x03, 0x80, // MR3 + 0x04, 0x30, // MR4 + 0x05, 0x00, // Reserved + 0x06, 0x00, // Reserved + 0x07, TR0MODE, // TM0 + 0x08, TR1CAPT, // TM1 + 0x09, 0xcb, // Fsc0 + 0x0a, 0x8a, // Fsc1 + 0x0b, 0x09, // Fsc2 + 0x0c, 0x2a, // Fsc3 + 0x0d, 0x00, // Subcarrier Phase + 0x0e, 0x00, // Closed Capt. Ext 0 + 0x0f, 0x00, // Closed Capt. Ext 1 + 0x10, 0x00, // Closed Capt. 0 + 0x11, 0x00, // Closed Capt. 1 + 0x12, 0x00, // Pedestal Ctl 0 + 0x13, 0x00, // Pedestal Ctl 1 + 0x14, 0x00, // Pedestal Ctl 2 + 0x15, 0x00, // Pedestal Ctl 3 + 0x16, 0x00, // CGMS_WSS_0 + 0x17, 0x00, // CGMS_WSS_1 + 0x18, 0x00, // CGMS_WSS_2 + 0x19, 0x00, // Teletext Ctl }; -static int adv7170_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) +static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) { - struct adv7170 *encoder = to_adv7170(sd); - - v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std); - - if (std & V4L2_STD_NTSC) { - adv7170_write_block(sd, init_NTSC, sizeof(init_NTSC)); - if (encoder->input == 0) - adv7170_write(sd, 0x02, 0x0e); /* Enable genlock */ - adv7170_write(sd, 0x07, TR0MODE | TR0RST); - adv7170_write(sd, 0x07, TR0MODE); - } else if (std & V4L2_STD_PAL) { - adv7170_write_block(sd, init_PAL, sizeof(init_PAL)); - if (encoder->input == 0) - adv7170_write(sd, 0x02, 0x0e); /* Enable genlock */ - adv7170_write(sd, 0x07, TR0MODE | TR0RST); - adv7170_write(sd, 0x07, TR0MODE); - } else { - v4l2_dbg(1, debug, sd, "illegal norm: %llx\n", - (unsigned long long)std); - return -EINVAL; + struct adv7170 *encoder = i2c_get_clientdata(client); + + switch (cmd) { + case 0: +#if 0 + /* This is just for testing!!! */ + adv7170_write_block(client, init_common, + sizeof(init_common)); + adv7170_write(client, 0x07, TR0MODE | TR0RST); + adv7170_write(client, 0x07, TR0MODE); +#endif + break; + + case ENCODER_GET_CAPABILITIES: + { + struct video_encoder_capability *cap = arg; + + cap->flags = VIDEO_ENCODER_PAL | + VIDEO_ENCODER_NTSC; + cap->inputs = 2; + cap->outputs = 1; + break; } - v4l2_dbg(1, debug, sd, "switched to %llx\n", (unsigned long long)std); - encoder->norm = std; - return 0; -} -static int adv7170_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) -{ - struct adv7170 *encoder = to_adv7170(sd); + case ENCODER_SET_NORM: + { + int iarg = *(int *) arg; + + v4l_dbg(1, debug, client, "set norm %d\n", iarg); + + switch (iarg) { + case VIDEO_MODE_NTSC: + adv7170_write_block(client, init_NTSC, + sizeof(init_NTSC)); + if (encoder->input == 0) + adv7170_write(client, 0x02, 0x0e); // Enable genlock + adv7170_write(client, 0x07, TR0MODE | TR0RST); + adv7170_write(client, 0x07, TR0MODE); + break; + + case VIDEO_MODE_PAL: + adv7170_write_block(client, init_PAL, + sizeof(init_PAL)); + if (encoder->input == 0) + adv7170_write(client, 0x02, 0x0e); // Enable genlock + adv7170_write(client, 0x07, TR0MODE | TR0RST); + adv7170_write(client, 0x07, TR0MODE); + break; + + default: + v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg); + return -EINVAL; + } + v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]); + encoder->norm = iarg; + break; + } - /* RJ: route->input = 0: input is from decoder - route->input = 1: input is from ZR36060 - route->input = 2: color bar */ + case ENCODER_SET_INPUT: + { + int iarg = *(int *) arg; + + /* RJ: *iarg = 0: input is from decoder + *iarg = 1: input is from ZR36060 + *iarg = 2: color bar */ + + v4l_dbg(1, debug, client, "set input from %s\n", + iarg == 0 ? "decoder" : "ZR36060"); + + switch (iarg) { + case 0: + adv7170_write(client, 0x01, 0x20); + adv7170_write(client, 0x08, TR1CAPT); /* TR1 */ + adv7170_write(client, 0x02, 0x0e); // Enable genlock + adv7170_write(client, 0x07, TR0MODE | TR0RST); + adv7170_write(client, 0x07, TR0MODE); + /* udelay(10); */ + break; + + case 1: + adv7170_write(client, 0x01, 0x00); + adv7170_write(client, 0x08, TR1PLAY); /* TR1 */ + adv7170_write(client, 0x02, 0x08); + adv7170_write(client, 0x07, TR0MODE | TR0RST); + adv7170_write(client, 0x07, TR0MODE); + /* udelay(10); */ + break; + + default: + v4l_dbg(1, debug, client, "illegal input: %d\n", iarg); + return -EINVAL; + } + v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]); + encoder->input = iarg; + break; + } - v4l2_dbg(1, debug, sd, "set input from %s\n", - route->input == 0 ? "decoder" : "ZR36060"); + case ENCODER_SET_OUTPUT: + { + int *iarg = arg; - switch (route->input) { - case 0: - adv7170_write(sd, 0x01, 0x20); - adv7170_write(sd, 0x08, TR1CAPT); /* TR1 */ - adv7170_write(sd, 0x02, 0x0e); /* Enable genlock */ - adv7170_write(sd, 0x07, TR0MODE | TR0RST); - adv7170_write(sd, 0x07, TR0MODE); - /* udelay(10); */ + /* not much choice of outputs */ + if (*iarg != 0) { + return -EINVAL; + } break; + } + + case ENCODER_ENABLE_OUTPUT: + { + int *iarg = arg; - case 1: - adv7170_write(sd, 0x01, 0x00); - adv7170_write(sd, 0x08, TR1PLAY); /* TR1 */ - adv7170_write(sd, 0x02, 0x08); - adv7170_write(sd, 0x07, TR0MODE | TR0RST); - adv7170_write(sd, 0x07, TR0MODE); - /* udelay(10); */ + encoder->enable = !!*iarg; break; + } default: - v4l2_dbg(1, debug, sd, "illegal input: %d\n", route->input); return -EINVAL; } - v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[route->input]); - encoder->input = route->input; - return 0; -} -static int adv7170_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7170, 0); + return 0; } /* ----------------------------------------------------------------------- */ -static const struct v4l2_subdev_core_ops adv7170_core_ops = { - .g_chip_ident = adv7170_g_chip_ident, +static unsigned short normal_i2c[] = { + 0xd4 >> 1, 0xd6 >> 1, /* adv7170 IDs */ + 0x54 >> 1, 0x56 >> 1, /* adv7171 IDs */ + I2C_CLIENT_END }; -static const struct v4l2_subdev_video_ops adv7170_video_ops = { - .s_std_output = adv7170_s_std_output, - .s_routing = adv7170_s_routing, -}; - -static const struct v4l2_subdev_ops adv7170_ops = { - .core = &adv7170_core_ops, - .video = &adv7170_video_ops, -}; - -/* ----------------------------------------------------------------------- */ +I2C_CLIENT_INSMOD; static int adv7170_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct adv7170 *encoder; - struct v4l2_subdev *sd; int i; /* Check if the adapter supports the needed features */ @@ -300,29 +337,26 @@ static int adv7170_probe(struct i2c_client *client, encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - sd = &encoder->sd; - v4l2_i2c_subdev_init(sd, client, &adv7170_ops); - encoder->norm = V4L2_STD_NTSC; + encoder->norm = VIDEO_MODE_NTSC; encoder->input = 0; + encoder->enable = 1; + i2c_set_clientdata(client, encoder); - i = adv7170_write_block(sd, init_NTSC, sizeof(init_NTSC)); + i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC)); if (i >= 0) { - i = adv7170_write(sd, 0x07, TR0MODE | TR0RST); - i = adv7170_write(sd, 0x07, TR0MODE); - i = adv7170_read(sd, 0x12); - v4l2_dbg(1, debug, sd, "revision %d\n", i & 1); + i = adv7170_write(client, 0x07, TR0MODE | TR0RST); + i = adv7170_write(client, 0x07, TR0MODE); + i = adv7170_read(client, 0x12); + v4l_dbg(1, debug, client, "revision %d\n", i & 1); } if (i < 0) - v4l2_dbg(1, debug, sd, "init error 0x%x\n", i); + v4l_dbg(1, debug, client, "init error 0x%x\n", i); return 0; } static int adv7170_remove(struct i2c_client *client) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - - v4l2_device_unregister_subdev(sd); - kfree(to_adv7170(sd)); + kfree(i2c_get_clientdata(client)); return 0; } @@ -337,6 +371,8 @@ MODULE_DEVICE_TABLE(i2c, adv7170_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "adv7170", + .driverid = I2C_DRIVERID_ADV7170, + .command = adv7170_command, .probe = adv7170_probe, .remove = adv7170_remove, .id_table = adv7170_id, diff --git a/trunk/drivers/media/video/adv7175.c b/trunk/drivers/media/video/adv7175.c index ff1210303295..6008e84653f1 100644 --- a/trunk/drivers/media/video/adv7175.c +++ b/trunk/drivers/media/video/adv7175.c @@ -30,19 +30,15 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver"); MODULE_AUTHOR("Dave Perks"); MODULE_LICENSE("GPL"); -#define I2C_ADV7175 0xd4 -#define I2C_ADV7176 0x54 - - static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); @@ -50,38 +46,36 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); /* ----------------------------------------------------------------------- */ struct adv7175 { - struct v4l2_subdev sd; - v4l2_std_id norm; + int norm; int input; + int enable; + int bright; + int contrast; + int hue; + int sat; }; -static inline struct adv7175 *to_adv7175(struct v4l2_subdev *sd) -{ - return container_of(sd, struct adv7175, sd); -} +#define I2C_ADV7175 0xd4 +#define I2C_ADV7176 0x54 static char *inputs[] = { "pass_through", "play_back", "color_bar" }; +static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" }; /* ----------------------------------------------------------------------- */ -static inline int adv7175_write(struct v4l2_subdev *sd, u8 reg, u8 value) +static inline int adv7175_write(struct i2c_client *client, u8 reg, u8 value) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - return i2c_smbus_write_byte_data(client, reg, value); } -static inline int adv7175_read(struct v4l2_subdev *sd, u8 reg) +static inline int adv7175_read(struct i2c_client *client, u8 reg) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - return i2c_smbus_read_byte_data(client, reg); } -static int adv7175_write_block(struct v4l2_subdev *sd, +static int adv7175_write_block(struct i2c_client *client, const u8 *data, unsigned int len) { - struct i2c_client *client = v4l2_get_subdevdata(sd); int ret = -1; u8 reg; @@ -109,7 +103,7 @@ static int adv7175_write_block(struct v4l2_subdev *sd, /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - ret = adv7175_write(sd, reg, *data++); + ret = adv7175_write(client, reg, *data++); if (ret < 0) break; len -= 2; @@ -119,18 +113,18 @@ static int adv7175_write_block(struct v4l2_subdev *sd, return ret; } -static void set_subcarrier_freq(struct v4l2_subdev *sd, int pass_through) +static void set_subcarrier_freq(struct i2c_client *client, int pass_through) { /* for some reason pass_through NTSC needs * a different sub-carrier freq to remain stable. */ if (pass_through) - adv7175_write(sd, 0x02, 0x00); + adv7175_write(client, 0x02, 0x00); else - adv7175_write(sd, 0x02, 0x55); + adv7175_write(client, 0x02, 0x55); - adv7175_write(sd, 0x03, 0x55); - adv7175_write(sd, 0x04, 0x55); - adv7175_write(sd, 0x05, 0x25); + adv7175_write(client, 0x03, 0x55); + adv7175_write(client, 0x04, 0x55); + adv7175_write(client, 0x05, 0x25); } /* ----------------------------------------------------------------------- */ @@ -190,144 +184,180 @@ static const unsigned char init_ntsc[] = { 0x06, 0x1a, /* subc. phase */ }; -static int adv7175_init(struct v4l2_subdev *sd, u32 val) +static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) { - /* This is just for testing!!! */ - adv7175_write_block(sd, init_common, sizeof(init_common)); - adv7175_write(sd, 0x07, TR0MODE | TR0RST); - adv7175_write(sd, 0x07, TR0MODE); - return 0; -} + struct adv7175 *encoder = i2c_get_clientdata(client); -static int adv7175_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) -{ - struct adv7175 *encoder = to_adv7175(sd); - - if (std & V4L2_STD_NTSC) { - adv7175_write_block(sd, init_ntsc, sizeof(init_ntsc)); - if (encoder->input == 0) - adv7175_write(sd, 0x0d, 0x4f); /* Enable genlock */ - adv7175_write(sd, 0x07, TR0MODE | TR0RST); - adv7175_write(sd, 0x07, TR0MODE); - } else if (std & V4L2_STD_PAL) { - adv7175_write_block(sd, init_pal, sizeof(init_pal)); - if (encoder->input == 0) - adv7175_write(sd, 0x0d, 0x4f); /* Enable genlock */ - adv7175_write(sd, 0x07, TR0MODE | TR0RST); - adv7175_write(sd, 0x07, TR0MODE); - } else if (std & V4L2_STD_SECAM) { - /* This is an attempt to convert - * SECAM->PAL (typically it does not work - * due to genlock: when decoder is in SECAM - * and encoder in in PAL the subcarrier can - * not be syncronized with horizontal - * quency) */ - adv7175_write_block(sd, init_pal, sizeof(init_pal)); - if (encoder->input == 0) - adv7175_write(sd, 0x0d, 0x49); /* Disable genlock */ - adv7175_write(sd, 0x07, TR0MODE | TR0RST); - adv7175_write(sd, 0x07, TR0MODE); - } else { - v4l2_dbg(1, debug, sd, "illegal norm: %llx\n", - (unsigned long long)std); - return -EINVAL; - } - v4l2_dbg(1, debug, sd, "switched to %llx\n", (unsigned long long)std); - encoder->norm = std; - return 0; -} + switch (cmd) { + case 0: + /* This is just for testing!!! */ + adv7175_write_block(client, init_common, + sizeof(init_common)); + adv7175_write(client, 0x07, TR0MODE | TR0RST); + adv7175_write(client, 0x07, TR0MODE); + break; -static int adv7175_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) -{ - struct adv7175 *encoder = to_adv7175(sd); + case ENCODER_GET_CAPABILITIES: + { + struct video_encoder_capability *cap = arg; - /* RJ: route->input = 0: input is from decoder - route->input = 1: input is from ZR36060 - route->input = 2: color bar */ + cap->flags = VIDEO_ENCODER_PAL | + VIDEO_ENCODER_NTSC | + VIDEO_ENCODER_SECAM; /* well, hacky */ + cap->inputs = 2; + cap->outputs = 1; + break; + } - switch (route->input) { - case 0: - adv7175_write(sd, 0x01, 0x00); - - if (encoder->norm & V4L2_STD_NTSC) - set_subcarrier_freq(sd, 1); - - adv7175_write(sd, 0x0c, TR1CAPT); /* TR1 */ - if (encoder->norm & V4L2_STD_SECAM) - adv7175_write(sd, 0x0d, 0x49); /* Disable genlock */ - else - adv7175_write(sd, 0x0d, 0x4f); /* Enable genlock */ - adv7175_write(sd, 0x07, TR0MODE | TR0RST); - adv7175_write(sd, 0x07, TR0MODE); - /*udelay(10);*/ + case ENCODER_SET_NORM: + { + int iarg = *(int *) arg; + + switch (iarg) { + case VIDEO_MODE_NTSC: + adv7175_write_block(client, init_ntsc, + sizeof(init_ntsc)); + if (encoder->input == 0) + adv7175_write(client, 0x0d, 0x4f); // Enable genlock + adv7175_write(client, 0x07, TR0MODE | TR0RST); + adv7175_write(client, 0x07, TR0MODE); + break; + + case VIDEO_MODE_PAL: + adv7175_write_block(client, init_pal, + sizeof(init_pal)); + if (encoder->input == 0) + adv7175_write(client, 0x0d, 0x4f); // Enable genlock + adv7175_write(client, 0x07, TR0MODE | TR0RST); + adv7175_write(client, 0x07, TR0MODE); + break; + + case VIDEO_MODE_SECAM: // WARNING! ADV7176 does not support SECAM. + /* This is an attempt to convert + * SECAM->PAL (typically it does not work + * due to genlock: when decoder is in SECAM + * and encoder in in PAL the subcarrier can + * not be syncronized with horizontal + * quency) */ + adv7175_write_block(client, init_pal, + sizeof(init_pal)); + if (encoder->input == 0) + adv7175_write(client, 0x0d, 0x49); // Disable genlock + adv7175_write(client, 0x07, TR0MODE | TR0RST); + adv7175_write(client, 0x07, TR0MODE); + break; + default: + v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg); + return -EINVAL; + } + v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]); + encoder->norm = iarg; break; + } - case 1: - adv7175_write(sd, 0x01, 0x00); + case ENCODER_SET_INPUT: + { + int iarg = *(int *) arg; + + /* RJ: *iarg = 0: input is from SAA7110 + *iarg = 1: input is from ZR36060 + *iarg = 2: color bar */ + + switch (iarg) { + case 0: + adv7175_write(client, 0x01, 0x00); + + if (encoder->norm == VIDEO_MODE_NTSC) + set_subcarrier_freq(client, 1); + + adv7175_write(client, 0x0c, TR1CAPT); /* TR1 */ + if (encoder->norm == VIDEO_MODE_SECAM) + adv7175_write(client, 0x0d, 0x49); // Disable genlock + else + adv7175_write(client, 0x0d, 0x4f); // Enable genlock + adv7175_write(client, 0x07, TR0MODE | TR0RST); + adv7175_write(client, 0x07, TR0MODE); + //udelay(10); + break; + + case 1: + adv7175_write(client, 0x01, 0x00); + + if (encoder->norm == VIDEO_MODE_NTSC) + set_subcarrier_freq(client, 0); + + adv7175_write(client, 0x0c, TR1PLAY); /* TR1 */ + adv7175_write(client, 0x0d, 0x49); + adv7175_write(client, 0x07, TR0MODE | TR0RST); + adv7175_write(client, 0x07, TR0MODE); + /* udelay(10); */ + break; + + case 2: + adv7175_write(client, 0x01, 0x80); + + if (encoder->norm == VIDEO_MODE_NTSC) + set_subcarrier_freq(client, 0); + + adv7175_write(client, 0x0d, 0x49); + adv7175_write(client, 0x07, TR0MODE | TR0RST); + adv7175_write(client, 0x07, TR0MODE); + /* udelay(10); */ + break; + + default: + v4l_dbg(1, debug, client, "illegal input: %d\n", iarg); + return -EINVAL; + } + v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]); + encoder->input = iarg; + break; + } - if (encoder->norm & V4L2_STD_NTSC) - set_subcarrier_freq(sd, 0); + case ENCODER_SET_OUTPUT: + { + int *iarg = arg; - adv7175_write(sd, 0x0c, TR1PLAY); /* TR1 */ - adv7175_write(sd, 0x0d, 0x49); - adv7175_write(sd, 0x07, TR0MODE | TR0RST); - adv7175_write(sd, 0x07, TR0MODE); - /* udelay(10); */ + /* not much choice of outputs */ + if (*iarg != 0) + return -EINVAL; break; + } - case 2: - adv7175_write(sd, 0x01, 0x80); - - if (encoder->norm & V4L2_STD_NTSC) - set_subcarrier_freq(sd, 0); + case ENCODER_ENABLE_OUTPUT: + { + int *iarg = arg; - adv7175_write(sd, 0x0d, 0x49); - adv7175_write(sd, 0x07, TR0MODE | TR0RST); - adv7175_write(sd, 0x07, TR0MODE); - /* udelay(10); */ + encoder->enable = !!*iarg; break; + } default: - v4l2_dbg(1, debug, sd, "illegal input: %d\n", route->input); return -EINVAL; } - v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[route->input]); - encoder->input = route->input; - return 0; -} -static int adv7175_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7175, 0); + return 0; } /* ----------------------------------------------------------------------- */ -static const struct v4l2_subdev_core_ops adv7175_core_ops = { - .g_chip_ident = adv7175_g_chip_ident, - .init = adv7175_init, -}; - -static const struct v4l2_subdev_video_ops adv7175_video_ops = { - .s_std_output = adv7175_s_std_output, - .s_routing = adv7175_s_routing, -}; - -static const struct v4l2_subdev_ops adv7175_ops = { - .core = &adv7175_core_ops, - .video = &adv7175_video_ops, +/* + * Generic i2c probe + * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' + */ +static unsigned short normal_i2c[] = { + I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1, + I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1, + I2C_CLIENT_END }; -/* ----------------------------------------------------------------------- */ +I2C_CLIENT_INSMOD; static int adv7175_probe(struct i2c_client *client, const struct i2c_device_id *id) { int i; struct adv7175 *encoder; - struct v4l2_subdev *sd; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) @@ -339,29 +369,26 @@ static int adv7175_probe(struct i2c_client *client, encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - sd = &encoder->sd; - v4l2_i2c_subdev_init(sd, client, &adv7175_ops); - encoder->norm = V4L2_STD_NTSC; + encoder->norm = VIDEO_MODE_PAL; encoder->input = 0; + encoder->enable = 1; + i2c_set_clientdata(client, encoder); - i = adv7175_write_block(sd, init_common, sizeof(init_common)); + i = adv7175_write_block(client, init_common, sizeof(init_common)); if (i >= 0) { - i = adv7175_write(sd, 0x07, TR0MODE | TR0RST); - i = adv7175_write(sd, 0x07, TR0MODE); - i = adv7175_read(sd, 0x12); - v4l2_dbg(1, debug, sd, "revision %d\n", i & 1); + i = adv7175_write(client, 0x07, TR0MODE | TR0RST); + i = adv7175_write(client, 0x07, TR0MODE); + i = adv7175_read(client, 0x12); + v4l_dbg(1, debug, client, "revision %d\n", i & 1); } if (i < 0) - v4l2_dbg(1, debug, sd, "init error 0x%x\n", i); + v4l_dbg(1, debug, client, "init error 0x%x\n", i); return 0; } static int adv7175_remove(struct i2c_client *client) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - - v4l2_device_unregister_subdev(sd); - kfree(to_adv7175(sd)); + kfree(i2c_get_clientdata(client)); return 0; } @@ -376,6 +403,8 @@ MODULE_DEVICE_TABLE(i2c, adv7175_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "adv7175", + .driverid = I2C_DRIVERID_ADV7175, + .command = adv7175_command, .probe = adv7175_probe, .remove = adv7175_remove, .id_table = adv7175_id, diff --git a/trunk/drivers/media/video/au0828/Kconfig b/trunk/drivers/media/video/au0828/Kconfig index 05cdf494dfb0..018f72b8e3e2 100644 --- a/trunk/drivers/media/video/au0828/Kconfig +++ b/trunk/drivers/media/video/au0828/Kconfig @@ -1,13 +1,13 @@ config VIDEO_AU0828 tristate "Auvitek AU0828 support" - depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2 + depends on I2C && INPUT && DVB_CORE && USB select I2C_ALGOBIT select VIDEO_TVEEPROM - select DVB_AU8522 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE + select DVB_AU8522 if !DVB_FE_CUSTOMIZE + select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE + select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE + select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE ---help--- This is a video4linux driver for Auvitek's USB device. diff --git a/trunk/drivers/media/video/au0828/Makefile b/trunk/drivers/media/video/au0828/Makefile index 4d2623158188..cd2c58281b4e 100644 --- a/trunk/drivers/media/video/au0828/Makefile +++ b/trunk/drivers/media/video/au0828/Makefile @@ -1,4 +1,4 @@ -au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o au0828-video.o +au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o obj-$(CONFIG_VIDEO_AU0828) += au0828.o diff --git a/trunk/drivers/media/video/au0828/au0828-cards.c b/trunk/drivers/media/video/au0828/au0828-cards.c index 1aabaa7e55bb..d60123b413f5 100644 --- a/trunk/drivers/media/video/au0828/au0828-cards.c +++ b/trunk/drivers/media/video/au0828/au0828-cards.c @@ -21,89 +21,25 @@ #include "au0828.h" #include "au0828-cards.h" -#include "au8522.h" -#include "media/tuner.h" -#include "media/v4l2-common.h" - -void hvr950q_cs5340_audio(void *priv, int enable) -{ - /* Because the HVR-950q shares an i2s bus between the cs5340 and the - au8522, we need to hold cs5340 in reset when using the au8522 */ - struct au0828_dev *dev = priv; - if (enable == 1) - au0828_set(dev, REG_000, 0x10); - else - au0828_clear(dev, REG_000, 0x10); -} struct au0828_board au0828_boards[] = { [AU0828_BOARD_UNKNOWN] = { .name = "Unknown board", - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, }, [AU0828_BOARD_HAUPPAUGE_HVR850] = { .name = "Hauppauge HVR850", - .tuner_type = TUNER_XC5000, - .tuner_addr = 0x61, - .input = { - { - .type = AU0828_VMUX_TELEVISION, - .vmux = AU8522_COMPOSITE_CH4_SIF, - .amux = AU8522_AUDIO_SIF, - }, - { - .type = AU0828_VMUX_COMPOSITE, - .vmux = AU8522_COMPOSITE_CH1, - .amux = AU8522_AUDIO_NONE, - .audio_setup = hvr950q_cs5340_audio, - }, - { - .type = AU0828_VMUX_SVIDEO, - .vmux = AU8522_SVIDEO_CH13, - .amux = AU8522_AUDIO_NONE, - .audio_setup = hvr950q_cs5340_audio, - }, - }, }, [AU0828_BOARD_HAUPPAUGE_HVR950Q] = { .name = "Hauppauge HVR950Q", - .tuner_type = TUNER_XC5000, - .tuner_addr = 0x61, - .input = { - { - .type = AU0828_VMUX_TELEVISION, - .vmux = AU8522_COMPOSITE_CH4_SIF, - .amux = AU8522_AUDIO_SIF, - }, - { - .type = AU0828_VMUX_COMPOSITE, - .vmux = AU8522_COMPOSITE_CH1, - .amux = AU8522_AUDIO_NONE, - .audio_setup = hvr950q_cs5340_audio, - }, - { - .type = AU0828_VMUX_SVIDEO, - .vmux = AU8522_SVIDEO_CH13, - .amux = AU8522_AUDIO_NONE, - .audio_setup = hvr950q_cs5340_audio, - }, - }, }, [AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = { .name = "Hauppauge HVR950Q rev xxF8", - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, }, [AU0828_BOARD_DVICO_FUSIONHDTV7] = { .name = "DViCO FusionHDTV USB", - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, }, [AU0828_BOARD_HAUPPAUGE_WOODBURY] = { .name = "Hauppauge Woodbury", - .tuner_type = UNSET, - .tuner_addr = ADDR_UNSET, }, }; @@ -116,7 +52,7 @@ int au0828_tuner_callback(void *priv, int component, int command, int arg) dprintk(1, "%s()\n", __func__); - switch (dev->boardnr) { + switch (dev->board) { case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR950Q: case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: @@ -145,18 +81,17 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data) struct tveeprom tv; tveeprom_hauppauge_analog(&dev->i2c_client, &tv, eeprom_data); - dev->board.tuner_type = tv.tuner_type; /* Make sure we support the board model */ switch (tv.model) { case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */ - case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */ - case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ - case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ - case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ - case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and analog video */ - case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */ - case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and analog video */ + case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */ + case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ + case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ + case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ + case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */ + case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */ + case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */ case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */ break; default: @@ -172,21 +107,15 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data) void au0828_card_setup(struct au0828_dev *dev) { static u8 eeprom[256]; - struct tuner_setup tun_setup; - struct v4l2_subdev *sd; - unsigned int mode_mask = T_ANALOG_TV | - T_DIGITAL_TV; dprintk(1, "%s()\n", __func__); - memcpy(&dev->board, &au0828_boards[dev->boardnr], sizeof(dev->board)); - if (dev->i2c_rc == 0) { dev->i2c_client.addr = 0xa0 >> 1; tveeprom_read(&dev->i2c_client, eeprom, sizeof(eeprom)); } - switch (dev->boardnr) { + switch (dev->board) { case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR950Q: case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: @@ -195,32 +124,6 @@ void au0828_card_setup(struct au0828_dev *dev) hauppauge_eeprom(dev, eeprom+0xa0); break; } - - if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED) { - /* Load the analog demodulator driver (note this would need to - be abstracted out if we ever need to support a different - demod) */ - sd = v4l2_i2c_new_subdev(&dev->i2c_adap, "au8522", "au8522", - 0x8e >> 1); - if (sd == NULL) - printk(KERN_ERR "analog subdev registration failed\n"); - } - - /* Setup tuners */ - if (dev->board.tuner_type != TUNER_ABSENT) { - /* Load the tuner module, which does the attach */ - sd = v4l2_i2c_new_subdev(&dev->i2c_adap, "tuner", "tuner", - dev->board.tuner_addr); - if (sd == NULL) - printk(KERN_ERR "tuner subdev registration fail\n"); - - tun_setup.mode_mask = mode_mask; - tun_setup.type = dev->board.tuner_type; - tun_setup.addr = dev->board.tuner_addr; - tun_setup.tuner_callback = au0828_tuner_callback; - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, - &tun_setup); - } } /* @@ -232,7 +135,7 @@ void au0828_gpio_setup(struct au0828_dev *dev) { dprintk(1, "%s()\n", __func__); - switch (dev->boardnr) { + switch (dev->board) { case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR950Q: case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: @@ -241,23 +144,21 @@ void au0828_gpio_setup(struct au0828_dev *dev) * 4 - CS5340 * 5 - AU8522 Demodulator * 6 - eeprom W/P - * 7 - power supply * 9 - XC5000 Tuner */ /* Into reset */ au0828_write(dev, REG_003, 0x02); - au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10); + au0828_write(dev, REG_002, 0x88 | 0x20); au0828_write(dev, REG_001, 0x0); au0828_write(dev, REG_000, 0x0); msleep(100); - /* Out of reset (leave the cs5340 in reset until needed) */ + /* Out of reset */ au0828_write(dev, REG_003, 0x02); au0828_write(dev, REG_001, 0x02); - au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10); - au0828_write(dev, REG_000, 0x80 | 0x40 | 0x20); - + au0828_write(dev, REG_002, 0x88 | 0x20); + au0828_write(dev, REG_000, 0x88 | 0x20 | 0x40); msleep(250); break; case AU0828_BOARD_DVICO_FUSIONHDTV7: diff --git a/trunk/drivers/media/video/au0828/au0828-core.c b/trunk/drivers/media/video/au0828/au0828-core.c index 8c761d164442..5765e8656376 100644 --- a/trunk/drivers/media/video/au0828/au0828-core.c +++ b/trunk/drivers/media/video/au0828/au0828-core.c @@ -36,8 +36,6 @@ int au0828_debug; module_param_named(debug, au0828_debug, int, 0644); MODULE_PARM_DESC(debug, "enable debug messages"); -static atomic_t au0828_instance = ATOMIC_INIT(0); - #define _AU0828_BULKPIPE 0x03 #define _BULKPIPESIZE 0xffff @@ -53,13 +51,13 @@ static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value, u32 au0828_readreg(struct au0828_dev *dev, u16 reg) { recv_control_msg(dev, CMD_REQUEST_IN, 0, reg, dev->ctrlmsg, 1); - dprintk(8, "%s(0x%04x) = 0x%02x\n", __func__, reg, dev->ctrlmsg[0]); + dprintk(8, "%s(0x%x) = 0x%x\n", __func__, reg, dev->ctrlmsg[0]); return dev->ctrlmsg[0]; } u32 au0828_writereg(struct au0828_dev *dev, u16 reg, u32 val) { - dprintk(8, "%s(0x%04x, 0x%02x)\n", __func__, reg, val); + dprintk(8, "%s(0x%x, 0x%x)\n", __func__, reg, val); return send_control_msg(dev, CMD_REQUEST_OUT, val, reg, dev->ctrlmsg, 0); } @@ -148,14 +146,9 @@ static void au0828_usb_disconnect(struct usb_interface *interface) /* Digital TV */ au0828_dvb_unregister(dev); - if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED) - au0828_analog_unregister(dev); - /* I2C */ au0828_i2c_unregister(dev); - v4l2_device_unregister(&dev->v4l2_dev); - usb_set_intfdata(interface, NULL); mutex_lock(&dev->mutex); @@ -169,7 +162,7 @@ static void au0828_usb_disconnect(struct usb_interface *interface) static int au0828_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) { - int ifnum, retval, i; + int ifnum; struct au0828_dev *dev; struct usb_device *usbdev = interface_to_usbdev(interface); @@ -192,22 +185,10 @@ static int au0828_usb_probe(struct usb_interface *interface, mutex_init(&dev->mutex); mutex_init(&dev->dvb.lock); dev->usbdev = usbdev; - dev->boardnr = id->driver_info; + dev->board = id->driver_info; usb_set_intfdata(interface, dev); - /* Create the v4l2_device */ - i = atomic_inc_return(&au0828_instance) - 1; - snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s-%03d", - "au0828", i); - retval = v4l2_device_register(&dev->usbdev->dev, &dev->v4l2_dev); - if (retval) { - printk(KERN_ERR "%s() v4l2_device_register failed\n", - __func__); - kfree(dev); - return -EIO; - } - /* Power Up the bridge */ au0828_write(dev, REG_600, 1 << 4); @@ -220,15 +201,12 @@ static int au0828_usb_probe(struct usb_interface *interface, /* Setup */ au0828_card_setup(dev); - /* Analog TV */ - if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED) - au0828_analog_register(dev, interface); - /* Digital TV */ au0828_dvb_register(dev); printk(KERN_INFO "Registered device AU0828 [%s]\n", - dev->board.name == NULL ? "Unset" : dev->board.name); + au0828_boards[dev->board].name == NULL ? "Unset" : + au0828_boards[dev->board].name); return 0; } diff --git a/trunk/drivers/media/video/au0828/au0828-dvb.c b/trunk/drivers/media/video/au0828/au0828-dvb.c index 14baffc22192..a882cf546d0a 100644 --- a/trunk/drivers/media/video/au0828/au0828-dvb.c +++ b/trunk/drivers/media/video/au0828/au0828-dvb.c @@ -378,7 +378,7 @@ int au0828_dvb_register(struct au0828_dev *dev) dprintk(1, "%s()\n", __func__); /* init frontend */ - switch (dev->boardnr) { + switch (dev->board) { case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR950Q: dvb->frontend = dvb_attach(au8522_attach, diff --git a/trunk/drivers/media/video/au0828/au0828-i2c.c b/trunk/drivers/media/video/au0828/au0828-i2c.c index f9a958d0aef1..d618fbaade1b 100644 --- a/trunk/drivers/media/video/au0828/au0828-i2c.c +++ b/trunk/drivers/media/video/au0828/au0828-i2c.c @@ -140,39 +140,13 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, dprintk(4, "%s()\n", __func__); au0828_write(dev, REG_2FF, 0x01); - - /* FIXME: There is a problem with i2c communications with xc5000 that - requires us to slow down the i2c clock until we have a better - strategy (such as using the secondary i2c bus to do firmware - loading */ - if ((msg->addr << 1) == 0xc2) - au0828_write(dev, REG_202, 0x40); - else - au0828_write(dev, REG_202, 0x07); + au0828_write(dev, REG_202, 0x07); /* Hardware needs 8 bit addresses */ au0828_write(dev, REG_203, msg->addr << 1); dprintk(4, "SEND: %02x\n", msg->addr); - /* Deal with i2c_scan */ - if (msg->len == 0) { - /* The analog tuner detection code makes use of the SMBUS_QUICK - message (which involves a zero length i2c write). To avoid - checking the status register when we didn't strobe out any - actual bytes to the bus, just do a read check. This is - consistent with how I saw i2c device checking done in the - USB trace of the Windows driver */ - au0828_write(dev, REG_200, 0x20); - if (!i2c_wait_done(i2c_adap)) - return -EIO; - - if (i2c_wait_read_ack(i2c_adap)) - return -EIO; - - return 0; - } - for (i = 0; i < msg->len;) { dprintk(4, " %02x\n", msg->buf[i]); @@ -217,15 +191,7 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, dprintk(4, "%s()\n", __func__); au0828_write(dev, REG_2FF, 0x01); - - /* FIXME: There is a problem with i2c communications with xc5000 that - requires us to slow down the i2c clock until we have a better - strategy (such as using the secondary i2c bus to do firmware - loading */ - if ((msg->addr << 1) == 0xc2) - au0828_write(dev, REG_202, 0x40); - else - au0828_write(dev, REG_202, 0x07); + au0828_write(dev, REG_202, 0x07); /* Hardware needs 8 bit addresses */ au0828_write(dev, REG_203, msg->addr << 1); @@ -299,6 +265,33 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap, return retval; } +static int attach_inform(struct i2c_client *client) +{ + dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", + client->driver->driver.name, client->addr, client->name); + + if (!client->driver->command) + return 0; + + return 0; +} + +static int detach_inform(struct i2c_client *client) +{ + dprintk(1, "i2c detach [client=%s]\n", client->name); + + return 0; +} + +void au0828_call_i2c_clients(struct au0828_dev *dev, + unsigned int cmd, void *arg) +{ + if (dev->i2c_rc != 0) + return; + + i2c_clients_command(&dev->i2c_adap, cmd, arg); +} + static u32 au0828_functionality(struct i2c_adapter *adap) { return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; @@ -316,6 +309,9 @@ static struct i2c_adapter au0828_i2c_adap_template = { .owner = THIS_MODULE, .id = I2C_HW_B_AU0828, .algo = &au0828_i2c_algo_template, + .class = I2C_CLASS_TV_ANALOG, + .client_register = attach_inform, + .client_unregister = detach_inform, }; static struct i2c_client au0828_i2c_client_template = { @@ -360,9 +356,9 @@ int au0828_i2c_register(struct au0828_dev *dev) strlcpy(dev->i2c_adap.name, DRIVER_NAME, sizeof(dev->i2c_adap.name)); - dev->i2c_adap.algo = &dev->i2c_algo; + dev->i2c_algo.data = dev; dev->i2c_adap.algo_data = dev; - i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev); + i2c_set_adapdata(&dev->i2c_adap, dev); i2c_add_adapter(&dev->i2c_adap); dev->i2c_client.adapter = &dev->i2c_adap; diff --git a/trunk/drivers/media/video/au0828/au0828-reg.h b/trunk/drivers/media/video/au0828/au0828-reg.h index b15e4a3b6fc0..1e87fa0c6842 100644 --- a/trunk/drivers/media/video/au0828/au0828-reg.h +++ b/trunk/drivers/media/video/au0828/au0828-reg.h @@ -27,9 +27,6 @@ #define REG_002 0x002 #define REG_003 0x003 -#define AU0828_SENSORCTRL_100 0x100 -#define AU0828_SENSORCTRL_VBI_103 0x103 - #define REG_200 0x200 #define REG_201 0x201 #define REG_202 0x202 @@ -38,7 +35,4 @@ #define REG_209 0x209 #define REG_2FF 0x2ff -/* Audio registers */ -#define AU0828_AUDIOCTRL_50C 0x50C - #define REG_600 0x600 diff --git a/trunk/drivers/media/video/au0828/au0828-video.c b/trunk/drivers/media/video/au0828/au0828-video.c deleted file mode 100644 index f7ad4958b94e..000000000000 --- a/trunk/drivers/media/video/au0828/au0828-video.c +++ /dev/null @@ -1,1712 +0,0 @@ -/* - * Auvitek AU0828 USB Bridge (Analog video support) - * - * Copyright (C) 2009 Devin Heitmueller - * Copyright (C) 2005-2008 Auvitek International, Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * As published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/* Developer Notes: - * - * VBI support is not yet working - * The hardware scaler supported is unimplemented - * AC97 audio support is unimplemented (only i2s audio mode) - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "au0828.h" -#include "au0828-reg.h" - -static LIST_HEAD(au0828_devlist); -static DEFINE_MUTEX(au0828_sysfs_lock); - -#define AU0828_VERSION_CODE KERNEL_VERSION(0, 0, 1) - -/* ------------------------------------------------------------------ - Videobuf operations - ------------------------------------------------------------------*/ - -static unsigned int isoc_debug; -module_param(isoc_debug, int, 0644); -MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]"); - -#define au0828_isocdbg(fmt, arg...) \ -do {\ - if (isoc_debug) { \ - printk(KERN_INFO "au0828 %s :"fmt, \ - __func__ , ##arg); \ - } \ - } while (0) - -static inline void print_err_status(struct au0828_dev *dev, - int packet, int status) -{ - char *errmsg = "Unknown"; - - switch (status) { - case -ENOENT: - errmsg = "unlinked synchronuously"; - break; - case -ECONNRESET: - errmsg = "unlinked asynchronuously"; - break; - case -ENOSR: - errmsg = "Buffer error (overrun)"; - break; - case -EPIPE: - errmsg = "Stalled (device not responding)"; - break; - case -EOVERFLOW: - errmsg = "Babble (bad cable?)"; - break; - case -EPROTO: - errmsg = "Bit-stuff error (bad cable?)"; - break; - case -EILSEQ: - errmsg = "CRC/Timeout (could be anything)"; - break; - case -ETIME: - errmsg = "Device does not respond"; - break; - } - if (packet < 0) { - au0828_isocdbg("URB status %d [%s].\n", status, errmsg); - } else { - au0828_isocdbg("URB packet %d, status %d [%s].\n", - packet, status, errmsg); - } -} - -static int check_dev(struct au0828_dev *dev) -{ - if (dev->dev_state & DEV_DISCONNECTED) { - printk(KERN_INFO "v4l2 ioctl: device not present\n"); - return -ENODEV; - } - - if (dev->dev_state & DEV_MISCONFIGURED) { - printk(KERN_INFO "v4l2 ioctl: device is misconfigured; " - "close and open it again\n"); - return -EIO; - } - return 0; -} - -/* - * IRQ callback, called by URB callback - */ -static void au0828_irq_callback(struct urb *urb) -{ - struct au0828_dmaqueue *dma_q = urb->context; - struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq); - int rc, i; - - switch (urb->status) { - case 0: /* success */ - case -ETIMEDOUT: /* NAK */ - break; - case -ECONNRESET: /* kill */ - case -ENOENT: - case -ESHUTDOWN: - au0828_isocdbg("au0828_irq_callback called: status kill\n"); - return; - default: /* unknown error */ - au0828_isocdbg("urb completition error %d.\n", urb->status); - break; - } - - /* Copy data from URB */ - spin_lock(&dev->slock); - rc = dev->isoc_ctl.isoc_copy(dev, urb); - spin_unlock(&dev->slock); - - /* Reset urb buffers */ - for (i = 0; i < urb->number_of_packets; i++) { - urb->iso_frame_desc[i].status = 0; - urb->iso_frame_desc[i].actual_length = 0; - } - urb->status = 0; - - urb->status = usb_submit_urb(urb, GFP_ATOMIC); - if (urb->status) { - au0828_isocdbg("urb resubmit failed (error=%i)\n", - urb->status); - } -} - -/* - * Stop and Deallocate URBs - */ -void au0828_uninit_isoc(struct au0828_dev *dev) -{ - struct urb *urb; - int i; - - au0828_isocdbg("au0828: called au0828_uninit_isoc\n"); - - dev->isoc_ctl.nfields = -1; - for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { - urb = dev->isoc_ctl.urb[i]; - if (urb) { - if (!irqs_disabled()) - usb_kill_urb(urb); - else - usb_unlink_urb(urb); - - if (dev->isoc_ctl.transfer_buffer[i]) { - usb_buffer_free(dev->usbdev, - urb->transfer_buffer_length, - dev->isoc_ctl.transfer_buffer[i], - urb->transfer_dma); - } - usb_free_urb(urb); - dev->isoc_ctl.urb[i] = NULL; - } - dev->isoc_ctl.transfer_buffer[i] = NULL; - } - - kfree(dev->isoc_ctl.urb); - kfree(dev->isoc_ctl.transfer_buffer); - - dev->isoc_ctl.urb = NULL; - dev->isoc_ctl.transfer_buffer = NULL; - dev->isoc_ctl.num_bufs = 0; -} - -/* - * Allocate URBs and start IRQ - */ -int au0828_init_isoc(struct au0828_dev *dev, int max_packets, - int num_bufs, int max_pkt_size, - int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb)) -{ - struct au0828_dmaqueue *dma_q = &dev->vidq; - int i; - int sb_size, pipe; - struct urb *urb; - int j, k; - int rc; - - au0828_isocdbg("au0828: called au0828_prepare_isoc\n"); - - /* De-allocates all pending stuff */ - au0828_uninit_isoc(dev); - - dev->isoc_ctl.isoc_copy = isoc_copy; - dev->isoc_ctl.num_bufs = num_bufs; - - dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); - if (!dev->isoc_ctl.urb) { - au0828_isocdbg("cannot alloc memory for usb buffers\n"); - return -ENOMEM; - } - - dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, - GFP_KERNEL); - if (!dev->isoc_ctl.transfer_buffer) { - au0828_isocdbg("cannot allocate memory for usb transfer\n"); - kfree(dev->isoc_ctl.urb); - return -ENOMEM; - } - - dev->isoc_ctl.max_pkt_size = max_pkt_size; - dev->isoc_ctl.buf = NULL; - - sb_size = max_packets * dev->isoc_ctl.max_pkt_size; - - /* allocate urbs and transfer buffers */ - for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { - urb = usb_alloc_urb(max_packets, GFP_KERNEL); - if (!urb) { - au0828_isocdbg("cannot alloc isoc_ctl.urb %i\n", i); - au0828_uninit_isoc(dev); - return -ENOMEM; - } - dev->isoc_ctl.urb[i] = urb; - - dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->usbdev, - sb_size, GFP_KERNEL, &urb->transfer_dma); - if (!dev->isoc_ctl.transfer_buffer[i]) { - printk("unable to allocate %i bytes for transfer" - " buffer %i%s\n", - sb_size, i, - in_interrupt() ? " while in int" : ""); - au0828_uninit_isoc(dev); - return -ENOMEM; - } - memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size); - - pipe = usb_rcvisocpipe(dev->usbdev, - dev->isoc_in_endpointaddr), - - usb_fill_int_urb(urb, dev->usbdev, pipe, - dev->isoc_ctl.transfer_buffer[i], sb_size, - au0828_irq_callback, dma_q, 1); - - urb->number_of_packets = max_packets; - urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; - - k = 0; - for (j = 0; j < max_packets; j++) { - urb->iso_frame_desc[j].offset = k; - urb->iso_frame_desc[j].length = - dev->isoc_ctl.max_pkt_size; - k += dev->isoc_ctl.max_pkt_size; - } - } - - init_waitqueue_head(&dma_q->wq); - - /* submit urbs and enables IRQ */ - for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { - rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC); - if (rc) { - au0828_isocdbg("submit of urb %i failed (error=%i)\n", - i, rc); - au0828_uninit_isoc(dev); - return rc; - } - } - - return 0; -} - -/* - * Announces that a buffer were filled and request the next - */ -static inline void buffer_filled(struct au0828_dev *dev, - struct au0828_dmaqueue *dma_q, - struct au0828_buffer *buf) -{ - /* Advice that buffer was filled */ - au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i); - - buf->vb.state = VIDEOBUF_DONE; - buf->vb.field_count++; - do_gettimeofday(&buf->vb.ts); - - dev->isoc_ctl.buf = NULL; - - list_del(&buf->vb.queue); - wake_up(&buf->vb.done); -} - -/* - * Identify the buffer header type and properly handles - */ -static void au0828_copy_video(struct au0828_dev *dev, - struct au0828_dmaqueue *dma_q, - struct au0828_buffer *buf, - unsigned char *p, - unsigned char *outp, unsigned long len) -{ - void *fieldstart, *startwrite, *startread; - int linesdone, currlinedone, offset, lencopy, remain; - int bytesperline = dev->width << 1; /* Assumes 16-bit depth @@@@ */ - - if (dma_q->pos + len > buf->vb.size) - len = buf->vb.size - dma_q->pos; - - startread = p; - remain = len; - - /* Interlaces frame */ - if (buf->top_field) - fieldstart = outp; - else - fieldstart = outp + bytesperline; - - linesdone = dma_q->pos / bytesperline; - currlinedone = dma_q->pos % bytesperline; - offset = linesdone * bytesperline * 2 + currlinedone; - startwrite = fieldstart + offset; - lencopy = bytesperline - currlinedone; - lencopy = lencopy > remain ? remain : lencopy; - - if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) { - au0828_isocdbg("Overflow of %zi bytes past buffer end (1)\n", - ((char *)startwrite + lencopy) - - ((char *)outp + buf->vb.size)); - remain = (char *)outp + buf->vb.size - (char *)startwrite; - lencopy = remain; - } - if (lencopy <= 0) - return; - memcpy(startwrite, startread, lencopy); - - remain -= lencopy; - - while (remain > 0) { - startwrite += lencopy + bytesperline; - startread += lencopy; - if (bytesperline > remain) - lencopy = remain; - else - lencopy = bytesperline; - - if ((char *)startwrite + lencopy > (char *)outp + - buf->vb.size) { - au0828_isocdbg("Overflow %zi bytes past buf end (2)\n", - ((char *)startwrite + lencopy) - - ((char *)outp + buf->vb.size)); - lencopy = remain = (char *)outp + buf->vb.size - - (char *)startwrite; - } - if (lencopy <= 0) - break; - - memcpy(startwrite, startread, lencopy); - - remain -= lencopy; - } - - if (offset > 1440) { - /* We have enough data to check for greenscreen */ - if (outp[0] < 0x60 && outp[1440] < 0x60) - dev->greenscreen_detected = 1; - } - - dma_q->pos += len; -} - -/* - * video-buf generic routine to get the next available buffer - */ -static inline void get_next_buf(struct au0828_dmaqueue *dma_q, - struct au0828_buffer **buf) -{ - struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq); - - if (list_empty(&dma_q->active)) { - au0828_isocdbg("No active queue to serve\n"); - dev->isoc_ctl.buf = NULL; - *buf = NULL; - return; - } - - /* Get the next buffer */ - *buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue); - dev->isoc_ctl.buf = *buf; - - return; -} - -/* - * Controls the isoc copy of each urb packet - */ -static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb) -{ - struct au0828_buffer *buf; - struct au0828_dmaqueue *dma_q = urb->context; - unsigned char *outp = NULL; - int i, len = 0, rc = 1; - unsigned char *p; - unsigned char fbyte; - - if (!dev) - return 0; - - if ((dev->dev_state & DEV_DISCONNECTED) || - (dev->dev_state & DEV_MISCONFIGURED)) - return 0; - - if (urb->status < 0) { - print_err_status(dev, -1, urb->status); - if (urb->status == -ENOENT) - return 0; - } - - buf = dev->isoc_ctl.buf; - if (buf != NULL) - outp = videobuf_to_vmalloc(&buf->vb); - - for (i = 0; i < urb->number_of_packets; i++) { - int status = urb->iso_frame_desc[i].status; - - if (status < 0) { - print_err_status(dev, i, status); - if (urb->iso_frame_desc[i].status != -EPROTO) - continue; - } - - if (urb->iso_frame_desc[i].actual_length <= 0) - continue; - - if (urb->iso_frame_desc[i].actual_length > - dev->max_pkt_size) { - au0828_isocdbg("packet bigger than packet size"); - continue; - } - - p = urb->transfer_buffer + urb->iso_frame_desc[i].offset; - fbyte = p[0]; - len = urb->iso_frame_desc[i].actual_length - 4; - p += 4; - - if (fbyte & 0x80) { - len -= 4; - p += 4; - au0828_isocdbg("Video frame %s\n", - (fbyte & 0x40) ? "odd" : "even"); - if (!(fbyte & 0x40)) { - if (buf != NULL) - buffer_filled(dev, dma_q, buf); - get_next_buf(dma_q, &buf); - if (buf == NULL) - outp = NULL; - else - outp = videobuf_to_vmalloc(&buf->vb); - } - - if (buf != NULL) { - if (fbyte & 0x40) - buf->top_field = 1; - else - buf->top_field = 0; - } - - dma_q->pos = 0; - } - if (buf != NULL) - au0828_copy_video(dev, dma_q, buf, p, outp, len); - } - return rc; -} - -static int -buffer_setup(struct videobuf_queue *vq, unsigned int *count, - unsigned int *size) -{ - struct au0828_fh *fh = vq->priv_data; - *size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3; - - if (0 == *count) - *count = AU0828_DEF_BUF; - - if (*count < AU0828_MIN_BUF) - *count = AU0828_MIN_BUF; - return 0; -} - -/* This is called *without* dev->slock held; please keep it that way */ -static void free_buffer(struct videobuf_queue *vq, struct au0828_buffer *buf) -{ - struct au0828_fh *fh = vq->priv_data; - struct au0828_dev *dev = fh->dev; - unsigned long flags = 0; - if (in_interrupt()) - BUG(); - - /* We used to wait for the buffer to finish here, but this didn't work - because, as we were keeping the state as VIDEOBUF_QUEUED, - videobuf_queue_cancel marked it as finished for us. - (Also, it could wedge forever if the hardware was misconfigured.) - - This should be safe; by the time we get here, the buffer isn't - queued anymore. If we ever start marking the buffers as - VIDEOBUF_ACTIVE, it won't be, though. - */ - spin_lock_irqsave(&dev->slock, flags); - if (dev->isoc_ctl.buf == buf) - dev->isoc_ctl.buf = NULL; - spin_unlock_irqrestore(&dev->slock, flags); - - videobuf_vmalloc_free(&buf->vb); - buf->vb.state = VIDEOBUF_NEEDS_INIT; -} - -static int -buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, - enum v4l2_field field) -{ - struct au0828_fh *fh = vq->priv_data; - struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb); - struct au0828_dev *dev = fh->dev; - int rc = 0, urb_init = 0; - - buf->vb.size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3; - - if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) - return -EINVAL; - - buf->vb.width = dev->width; - buf->vb.height = dev->height; - buf->vb.field = field; - - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - rc = videobuf_iolock(vq, &buf->vb, NULL); - if (rc < 0) { - printk(KERN_INFO "videobuf_iolock failed\n"); - goto fail; - } - } - - if (!dev->isoc_ctl.num_bufs) - urb_init = 1; - - if (urb_init) { - rc = au0828_init_isoc(dev, AU0828_ISO_PACKETS_PER_URB, - AU0828_MAX_ISO_BUFS, dev->max_pkt_size, - au0828_isoc_copy); - if (rc < 0) { - printk(KERN_INFO "au0828_init_isoc failed\n"); - goto fail; - } - } - - buf->vb.state = VIDEOBUF_PREPARED; - return 0; - -fail: - free_buffer(vq, buf); - return rc; -} - -static void -buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) -{ - struct au0828_buffer *buf = container_of(vb, - struct au0828_buffer, - vb); - struct au0828_fh *fh = vq->priv_data; - struct au0828_dev *dev = fh->dev; - struct au0828_dmaqueue *vidq = &dev->vidq; - - buf->vb.state = VIDEOBUF_QUEUED; - list_add_tail(&buf->vb.queue, &vidq->active); -} - -static void buffer_release(struct videobuf_queue *vq, - struct videobuf_buffer *vb) -{ - struct au0828_buffer *buf = container_of(vb, - struct au0828_buffer, - vb); - - free_buffer(vq, buf); -} - -static struct videobuf_queue_ops au0828_video_qops = { - .buf_setup = buffer_setup, - .buf_prepare = buffer_prepare, - .buf_queue = buffer_queue, - .buf_release = buffer_release, -}; - -/* ------------------------------------------------------------------ - V4L2 interface - ------------------------------------------------------------------*/ - -static int au0828_i2s_init(struct au0828_dev *dev) -{ - /* Enable i2s mode */ - au0828_writereg(dev, AU0828_AUDIOCTRL_50C, 0x01); - return 0; -} - -/* - * Auvitek au0828 analog stream enable - * Please set interface0 to AS5 before enable the stream - */ -int au0828_analog_stream_enable(struct au0828_dev *d) -{ - dprintk(1, "au0828_analog_stream_enable called\n"); - au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00); - au0828_writereg(d, 0x106, 0x00); - /* set x position */ - au0828_writereg(d, 0x110, 0x00); - au0828_writereg(d, 0x111, 0x00); - au0828_writereg(d, 0x114, 0xa0); - au0828_writereg(d, 0x115, 0x05); - /* set y position */ - au0828_writereg(d, 0x112, 0x02); - au0828_writereg(d, 0x113, 0x00); - au0828_writereg(d, 0x116, 0xf2); - au0828_writereg(d, 0x117, 0x00); - au0828_writereg(d, AU0828_SENSORCTRL_100, 0xb3); - - return 0; -} - -int au0828_analog_stream_disable(struct au0828_dev *d) -{ - dprintk(1, "au0828_analog_stream_disable called\n"); - au0828_writereg(d, AU0828_SENSORCTRL_100, 0x0); - return 0; -} - -void au0828_analog_stream_reset(struct au0828_dev *dev) -{ - dprintk(1, "au0828_analog_stream_reset called\n"); - au0828_writereg(dev, AU0828_SENSORCTRL_100, 0x0); - mdelay(30); - au0828_writereg(dev, AU0828_SENSORCTRL_100, 0xb3); -} - -/* - * Some operations needs to stop current streaming - */ -static int au0828_stream_interrupt(struct au0828_dev *dev) -{ - int ret = 0; - - dev->stream_state = STREAM_INTERRUPT; - if (dev->dev_state == DEV_DISCONNECTED) - return -ENODEV; - else if (ret) { - dev->dev_state = DEV_MISCONFIGURED; - dprintk(1, "%s device is misconfigured!\n", __func__); - return ret; - } - return 0; -} - -/* - * au0828_release_resources - * unregister v4l2 devices - */ -void au0828_analog_unregister(struct au0828_dev *dev) -{ - dprintk(1, "au0828_release_resources called\n"); - mutex_lock(&au0828_sysfs_lock); - - if (dev->vdev) { - list_del(&dev->au0828list); - video_unregister_device(dev->vdev); - } - if (dev->vbi_dev) - video_unregister_device(dev->vbi_dev); - - mutex_unlock(&au0828_sysfs_lock); -} - - -/* Usage lock check functions */ -static int res_get(struct au0828_fh *fh) -{ - struct au0828_dev *dev = fh->dev; - int rc = 0; - - /* This instance already has stream_on */ - if (fh->stream_on) - return rc; - - if (dev->stream_on) - return -EBUSY; - - dev->stream_on = 1; - fh->stream_on = 1; - return rc; -} - -static int res_check(struct au0828_fh *fh) -{ - return fh->stream_on; -} - -static void res_free(struct au0828_fh *fh) -{ - struct au0828_dev *dev = fh->dev; - - fh->stream_on = 0; - dev->stream_on = 0; -} - -static int au0828_v4l2_open(struct file *filp) -{ - int minor = video_devdata(filp)->minor; - int ret = 0; - struct au0828_dev *h, *dev = NULL; - struct au0828_fh *fh; - int type = 0; - struct list_head *list; - - list_for_each(list, &au0828_devlist) { - h = list_entry(list, struct au0828_dev, au0828list); - if (h->vdev->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } -#ifdef VBI_IS_WORKING - if (h->vbi_dev->minor == minor) { - dev = h; - type = V4L2_BUF_TYPE_VBI_CAPTURE; - } -#endif - } - - if (NULL == dev) - return -ENODEV; - - fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL); - if (NULL == fh) { - dprintk(1, "Failed allocate au0828_fh struct!\n"); - return -ENOMEM; - } - - fh->type = type; - fh->dev = dev; - filp->private_data = fh; - - if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { - /* set au0828 interface0 to AS5 here again */ - ret = usb_set_interface(dev->usbdev, 0, 5); - if (ret < 0) { - printk(KERN_INFO "Au0828 can't set alternate to 5!\n"); - return -EBUSY; - } - dev->width = NTSC_STD_W; - dev->height = NTSC_STD_H; - dev->frame_size = dev->width * dev->height * 2; - dev->field_size = dev->width * dev->height; - dev->bytesperline = dev->width * 2; - - au0828_analog_stream_enable(dev); - au0828_analog_stream_reset(dev); - - /* If we were doing ac97 instead of i2s, it would go here...*/ - au0828_i2s_init(dev); - - dev->stream_state = STREAM_OFF; - dev->dev_state |= DEV_INITIALIZED; - } - - dev->users++; - - videobuf_queue_vmalloc_init(&fh->vb_vidq, &au0828_video_qops, - NULL, &dev->slock, fh->type, - V4L2_FIELD_INTERLACED, - sizeof(struct au0828_buffer), fh); - - return ret; -} - -static int au0828_v4l2_close(struct file *filp) -{ - int ret; - struct au0828_fh *fh = filp->private_data; - struct au0828_dev *dev = fh->dev; - - mutex_lock(&dev->lock); - if (res_check(fh)) - res_free(fh); - - if (dev->users == 1) { - videobuf_stop(&fh->vb_vidq); - videobuf_mmap_free(&fh->vb_vidq); - - if (dev->dev_state & DEV_DISCONNECTED) { - au0828_analog_unregister(dev); - mutex_unlock(&dev->lock); - kfree(dev); - return 0; - } - - au0828_analog_stream_disable(dev); - - au0828_uninit_isoc(dev); - - /* When close the device, set the usb intf0 into alt0 to free - USB bandwidth */ - ret = usb_set_interface(dev->usbdev, 0, 0); - if (ret < 0) - printk(KERN_INFO "Au0828 can't set alternate to 0!\n"); - } - - kfree(fh); - dev->users--; - wake_up_interruptible_nr(&dev->open, 1); - mutex_unlock(&dev->lock); - return 0; -} - -static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf, - size_t count, loff_t *pos) -{ - struct au0828_fh *fh = filp->private_data; - struct au0828_dev *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_lock(&dev->lock); - rc = res_get(fh); - mutex_unlock(&dev->lock); - - if (unlikely(rc < 0)) - return rc; - - return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, - filp->f_flags & O_NONBLOCK); - } - return 0; -} - -static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait) -{ - struct au0828_fh *fh = filp->private_data; - struct au0828_dev *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - mutex_lock(&dev->lock); - rc = res_get(fh); - mutex_unlock(&dev->lock); - - if (unlikely(rc < 0)) - return POLLERR; - - if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) - return POLLERR; - - return videobuf_poll_stream(filp, &fh->vb_vidq, wait); -} - -static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct au0828_fh *fh = filp->private_data; - struct au0828_dev *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - mutex_lock(&dev->lock); - rc = res_get(fh); - mutex_unlock(&dev->lock); - - if (unlikely(rc < 0)) - return rc; - - rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); - - dprintk(2, "vma start=0x%08lx, size=%ld, ret=%d\n", - (unsigned long)vma->vm_start, - (unsigned long)vma->vm_end-(unsigned long)vma->vm_start, - rc); - - return rc; -} - -static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd, - struct v4l2_format *format) -{ - int ret; - int width = format->fmt.pix.width; - int height = format->fmt.pix.height; - unsigned int maxwidth, maxheight; - - maxwidth = 720; - maxheight = 480; - -#ifdef VBI_IS_WORKING - if (format->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { - dprintk(1, "VBI format set: to be supported!\n"); - return 0; - } - if (format->type == V4L2_BUF_TYPE_VBI_CAPTURE) - return 0; -#endif - if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - /* If they are demanding a format other than the one we support, - bail out (tvtime asks for UYVY and then retries with YUYV) */ - if (format->fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY) - return -EINVAL; - - /* format->fmt.pix.width only support 720 and height 480 */ - if (width != 720) - width = 720; - if (height != 480) - height = 480; - - format->fmt.pix.width = width; - format->fmt.pix.height = height; - format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; - format->fmt.pix.bytesperline = width * 2; - format->fmt.pix.sizeimage = width * height * 2; - format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - format->fmt.pix.field = V4L2_FIELD_INTERLACED; - - if (cmd == VIDIOC_TRY_FMT) - return 0; - - /* maybe set new image format, driver current only support 720*480 */ - dev->width = width; - dev->height = height; - dev->frame_size = width * height * 2; - dev->field_size = width * height; - dev->bytesperline = width * 2; - - if (dev->stream_state == STREAM_ON) { - dprintk(1, "VIDIOC_SET_FMT: interrupting stream!\n"); - ret = au0828_stream_interrupt(dev); - if (ret != 0) { - dprintk(1, "error interrupting video stream!\n"); - return ret; - } - } - - /* set au0828 interface0 to AS5 here again */ - ret = usb_set_interface(dev->usbdev, 0, 5); - if (ret < 0) { - printk(KERN_INFO "Au0828 can't set alt setting to 5!\n"); - return -EBUSY; - } - - au0828_analog_stream_enable(dev); - - return 0; -} - - -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc); - if (qc->type) - return 0; - else - return -EINVAL; -} - -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - - strlcpy(cap->driver, "au0828", sizeof(cap->driver)); - strlcpy(cap->card, dev->board.name, sizeof(cap->card)); - strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); - - cap->version = AU0828_VERSION_CODE; - - /*set the device capabilities */ - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | -#ifdef VBI_IS_WORKING - V4L2_CAP_VBI_CAPTURE | -#endif - V4L2_CAP_AUDIO | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING | - V4L2_CAP_TUNER; - return 0; -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - if (f->index) - return -EINVAL; - - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - strcpy(f->description, "Packed YUV2"); - - f->flags = 0; - f->pixelformat = V4L2_PIX_FMT_UYVY; - - return 0; -} - -static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - - f->fmt.pix.width = dev->width; - f->fmt.pix.height = dev->height; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; - f->fmt.pix.bytesperline = dev->bytesperline; - f->fmt.pix.sizeimage = dev->frame_size; - f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */ - f->fmt.pix.field = V4L2_FIELD_INTERLACED; - return 0; -} - -static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - - return au0828_set_format(dev, VIDIOC_TRY_FMT, f); -} - -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - int rc; - - if (videobuf_queue_is_busy(&fh->vb_vidq)) { - printk(KERN_INFO "%s queue busy\n", __func__); - rc = -EBUSY; - goto out; - } - - if (dev->stream_on && !fh->stream_on) { - printk(KERN_INFO "%s device in use by another fh\n", __func__); - rc = -EBUSY; - goto out; - } - - return au0828_set_format(dev, VIDIOC_S_FMT, f); -out: - return rc; -} - -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - - /* FIXME: when we support something other than NTSC, we are going to - have to make the au0828 bridge adjust the size of its capture - buffer, which is currently hardcoded at 720x480 */ - - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_std, *norm); - return 0; -} - -static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *input) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - unsigned int tmp; - - static const char *inames[] = { - [AU0828_VMUX_UNDEFINED] = "Undefined", - [AU0828_VMUX_COMPOSITE] = "Composite", - [AU0828_VMUX_SVIDEO] = "S-Video", - [AU0828_VMUX_CABLE] = "Cable TV", - [AU0828_VMUX_TELEVISION] = "Television", - [AU0828_VMUX_DVB] = "DVB", - [AU0828_VMUX_DEBUG] = "tv debug" - }; - - tmp = input->index; - - if (tmp > AU0828_MAX_INPUT) - return -EINVAL; - if (AUVI_INPUT(tmp).type == 0) - return -EINVAL; - - input->index = tmp; - strcpy(input->name, inames[AUVI_INPUT(tmp).type]); - if ((AUVI_INPUT(tmp).type == AU0828_VMUX_TELEVISION) || - (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE)) - input->type |= V4L2_INPUT_TYPE_TUNER; - else - input->type |= V4L2_INPUT_TYPE_CAMERA; - - input->std = dev->vdev->tvnorms; - - return 0; -} - -static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - *i = dev->ctrl_input; - return 0; -} - -static int vidioc_s_input(struct file *file, void *priv, unsigned int index) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - int i; - struct v4l2_routing route; - - dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __func__, - index); - if (index >= AU0828_MAX_INPUT) - return -EINVAL; - if (AUVI_INPUT(index).type == 0) - return -EINVAL; - dev->ctrl_input = index; - - switch (AUVI_INPUT(index).type) { - case AU0828_VMUX_SVIDEO: - dev->input_type = AU0828_VMUX_SVIDEO; - break; - case AU0828_VMUX_COMPOSITE: - dev->input_type = AU0828_VMUX_COMPOSITE; - break; - case AU0828_VMUX_TELEVISION: - dev->input_type = AU0828_VMUX_TELEVISION; - break; - default: - dprintk(1, "VIDIOC_S_INPUT unknown input type set [%d]\n", - AUVI_INPUT(index).type); - break; - } - - route.input = AUVI_INPUT(index).vmux; - route.output = 0; - v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, &route); - - for (i = 0; i < AU0828_MAX_INPUT; i++) { - int enable = 0; - if (AUVI_INPUT(i).audio_setup == NULL) - continue; - - if (i == index) - enable = 1; - else - enable = 0; - if (enable) { - (AUVI_INPUT(i).audio_setup)(dev, enable); - } else { - /* Make sure we leave it turned on if some - other input is routed to this callback */ - if ((AUVI_INPUT(i).audio_setup) != - ((AUVI_INPUT(index).audio_setup))) { - (AUVI_INPUT(i).audio_setup)(dev, enable); - } - } - } - - route.input = AUVI_INPUT(index).amux; - v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing, &route); - return 0; -} - -static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - unsigned int index = a->index; - - if (a->index > 1) - return -EINVAL; - - index = dev->ctrl_ainput; - if (index == 0) - strcpy(a->name, "Television"); - else - strcpy(a->name, "Line in"); - - a->capability = V4L2_AUDCAP_STEREO; - a->index = index; - return 0; -} - -static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - if (a->index != dev->ctrl_ainput) - return -EINVAL; - return 0; -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - - v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl); - return 0; - -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl); - return 0; -} - -static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - - if (t->index != 0) - return -EINVAL; - - strcpy(t->name, "Auvitek tuner"); - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t); - return 0; -} - -static int vidioc_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - - if (t->index != 0) - return -EINVAL; - - t->type = V4L2_TUNER_ANALOG_TV; - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t); - dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal, - t->afc); - return 0; - -} - -static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *freq) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - - freq->type = V4L2_TUNER_ANALOG_TV; - freq->frequency = dev->ctrl_freq; - return 0; -} - -static int vidioc_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *freq) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - - if (freq->tuner != 0) - return -EINVAL; - if (freq->type != V4L2_TUNER_ANALOG_TV) - return -EINVAL; - - dev->ctrl_freq = freq->frequency; - - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, freq); - - au0828_analog_stream_reset(dev); - - return 0; -} - -static int vidioc_g_chip_ident(struct file *file, void *priv, - struct v4l2_dbg_chip_ident *chip) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - chip->ident = V4L2_IDENT_NONE; - chip->revision = 0; - - if (v4l2_chip_match_host(&chip->match)) { - chip->ident = V4L2_IDENT_AU0828; - return 0; - } - - v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip); - if (chip->ident == V4L2_IDENT_NONE) - return -EINVAL; - - return 0; -} - -static int vidioc_cropcap(struct file *file, void *priv, - struct v4l2_cropcap *cc) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - - if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - cc->bounds.left = 0; - cc->bounds.top = 0; - cc->bounds.width = dev->width; - cc->bounds.height = dev->height; - - cc->defrect = cc->bounds; - - cc->pixelaspect.numerator = 54; - cc->pixelaspect.denominator = 59; - - return 0; -} - -static int vidioc_streamon(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - au0828_analog_stream_enable(dev); - v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1); - } - - mutex_lock(&dev->lock); - rc = res_get(fh); - - if (likely(rc >= 0)) - rc = videobuf_streamon(&fh->vb_vidq); - mutex_unlock(&dev->lock); - - return rc; -} - -static int vidioc_streamoff(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - int i; - int ret; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (type != fh->type) - return -EINVAL; - - if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); - ret = au0828_stream_interrupt(dev); - if (ret != 0) - return ret; - } - - for (i = 0; i < AU0828_MAX_INPUT; i++) { - if (AUVI_INPUT(i).audio_setup == NULL) - continue; - (AUVI_INPUT(i).audio_setup)(dev, 0); - } - - mutex_lock(&dev->lock); - videobuf_streamoff(&fh->vb_vidq); - res_free(fh); - mutex_unlock(&dev->lock); - - return 0; -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int vidioc_g_register(struct file *file, void *priv, - struct v4l2_dbg_register *reg) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - - switch (reg->match.type) { - case V4L2_CHIP_MATCH_I2C_DRIVER: - v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg); - return 0; - default: - return -EINVAL; - } -} - -static int vidioc_s_register(struct file *file, void *priv, - struct v4l2_dbg_register *reg) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - - switch (reg->match.type) { - case V4L2_CHIP_MATCH_I2C_DRIVER: - v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg); - return 0; - default: - return -EINVAL; - } - return 0; -} -#endif - -static int vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *rb) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - return videobuf_reqbufs(&fh->vb_vidq, rb); -} - -static int vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *b) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - return videobuf_querybuf(&fh->vb_vidq, b); -} - -static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - return videobuf_qbuf(&fh->vb_vidq, b); -} - -static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ - struct au0828_fh *fh = priv; - struct au0828_dev *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - /* Workaround for a bug in the au0828 hardware design that sometimes - results in the colorspace being inverted */ - if (dev->greenscreen_detected == 1) { - dprintk(1, "Detected green frame. Resetting stream...\n"); - au0828_analog_stream_reset(dev); - dev->greenscreen_detected = 0; - } - - return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); -} - -#ifdef CONFIG_VIDEO_V4L1_COMPAT -static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) -{ - struct au0828_fh *fh = priv; - - return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); -} -#endif - -static struct v4l2_file_operations au0828_v4l_fops = { - .owner = THIS_MODULE, - .open = au0828_v4l2_open, - .release = au0828_v4l2_close, - .read = au0828_v4l2_read, - .poll = au0828_v4l2_poll, - .mmap = au0828_v4l2_mmap, - .ioctl = video_ioctl2, -}; - -static const struct v4l2_ioctl_ops video_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, -#ifdef VBI_IS_WORKING - .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, - .vidioc_try_fmt_vbi_cap = vidioc_s_fmt_vbi_cap, - .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap, -#endif - .vidioc_g_audio = vidioc_g_audio, - .vidioc_s_audio = vidioc_s_audio, - .vidioc_cropcap = vidioc_cropcap, -#ifdef VBI_IS_WORKING - .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap, - .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap, - .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap, -#endif - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_s_std = vidioc_s_std, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = vidioc_g_register, - .vidioc_s_register = vidioc_s_register, -#endif - .vidioc_g_chip_ident = vidioc_g_chip_ident, -#ifdef CONFIG_VIDEO_V4L1_COMPAT - .vidiocgmbuf = vidiocgmbuf, -#endif -}; - -static const struct video_device au0828_video_template = { - .fops = &au0828_v4l_fops, - .release = video_device_release, - .ioctl_ops = &video_ioctl_ops, - .minor = -1, - .tvnorms = V4L2_STD_NTSC_M, - .current_norm = V4L2_STD_NTSC_M, -}; - -/**************************************************************************/ - -int au0828_analog_register(struct au0828_dev *dev, - struct usb_interface *interface) -{ - int retval = -ENOMEM; - struct usb_host_interface *iface_desc; - struct usb_endpoint_descriptor *endpoint; - int i; - - dprintk(1, "au0828_analog_register called!\n"); - - /* set au0828 usb interface0 to as5 */ - retval = usb_set_interface(dev->usbdev, - interface->cur_altsetting->desc.bInterfaceNumber, 5); - if (retval != 0) { - printk(KERN_INFO "Failure setting usb interface0 to as5\n"); - return retval; - } - - /* Figure out which endpoint has the isoc interface */ - iface_desc = interface->cur_altsetting; - for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { - endpoint = &iface_desc->endpoint[i].desc; - if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) - == USB_DIR_IN) && - ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_ISOC)) { - - /* we find our isoc in endpoint */ - u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize); - dev->max_pkt_size = (tmp & 0x07ff) * - (((tmp & 0x1800) >> 11) + 1); - dev->isoc_in_endpointaddr = endpoint->bEndpointAddress; - } - } - if (!(dev->isoc_in_endpointaddr)) { - printk(KERN_INFO "Could not locate isoc endpoint\n"); - kfree(dev); - return -ENODEV; - } - - init_waitqueue_head(&dev->open); - spin_lock_init(&dev->slock); - mutex_init(&dev->lock); - - INIT_LIST_HEAD(&dev->vidq.active); - INIT_LIST_HEAD(&dev->vidq.queued); - - dev->width = NTSC_STD_W; - dev->height = NTSC_STD_H; - dev->field_size = dev->width * dev->height; - dev->frame_size = dev->field_size << 1; - dev->bytesperline = dev->width << 1; - dev->ctrl_ainput = 0; - - /* allocate and fill v4l2 video struct */ - dev->vdev = video_device_alloc(); - if (NULL == dev->vdev) { - dprintk(1, "Can't allocate video_device.\n"); - return -ENOMEM; - } - -#ifdef VBI_IS_WORKING - dev->vbi_dev = video_device_alloc(); - if (NULL == dev->vbi_dev) { - dprintk(1, "Can't allocate vbi_device.\n"); - kfree(dev->vdev); - return -ENOMEM; - } -#endif - - /* Fill the video capture device struct */ - *dev->vdev = au0828_video_template; - dev->vdev->parent = &dev->usbdev->dev; - strcpy(dev->vdev->name, "au0828a video"); - -#ifdef VBI_IS_WORKING - /* Setup the VBI device */ - *dev->vbi_dev = au0828_video_template; - dev->vbi_dev->parent = &dev->usbdev->dev; - strcpy(dev->vbi_dev->name, "au0828a vbi"); -#endif - - list_add_tail(&dev->au0828list, &au0828_devlist); - - /* Register the v4l2 device */ - retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1); - if (retval != 0) { - dprintk(1, "unable to register video device (error = %d).\n", - retval); - list_del(&dev->au0828list); - video_device_release(dev->vdev); - return -ENODEV; - } - -#ifdef VBI_IS_WORKING - /* Register the vbi device */ - retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1); - if (retval != 0) { - dprintk(1, "unable to register vbi device (error = %d).\n", - retval); - list_del(&dev->au0828list); - video_device_release(dev->vbi_dev); - video_device_release(dev->vdev); - return -ENODEV; - } -#endif - - dprintk(1, "%s completed!\n", __func__); - - return 0; -} - diff --git a/trunk/drivers/media/video/au0828/au0828.h b/trunk/drivers/media/video/au0828/au0828.h index 6ed1a6129731..9d6a1161dc98 100644 --- a/trunk/drivers/media/video/au0828/au0828.h +++ b/trunk/drivers/media/video/au0828/au0828.h @@ -24,11 +24,6 @@ #include #include -/* Analog */ -#include -#include -#include - /* DVB */ #include "demux.h" #include "dmxdev.h" @@ -44,45 +39,8 @@ #define URB_COUNT 16 #define URB_BUFSIZE (0xe522) -/* Analog constants */ -#define NTSC_STD_W 720 -#define NTSC_STD_H 480 - -#define AU0828_INTERLACED_DEFAULT 1 -#define V4L2_CID_PRIVATE_SHARPNESS (V4L2_CID_PRIVATE_BASE + 0) - -/* Defination for AU0828 USB transfer */ -#define AU0828_MAX_ISO_BUFS 12 /* maybe resize this value in the future */ -#define AU0828_ISO_PACKETS_PER_URB 10 - -#define AU0828_MIN_BUF 4 -#define AU0828_DEF_BUF 8 - -#define AU0828_MAX_INPUT 4 - -enum au0828_itype { - AU0828_VMUX_UNDEFINED = 0, - AU0828_VMUX_COMPOSITE, - AU0828_VMUX_SVIDEO, - AU0828_VMUX_CABLE, - AU0828_VMUX_TELEVISION, - AU0828_VMUX_DVB, - AU0828_VMUX_DEBUG -}; - -struct au0828_input { - enum au0828_itype type; - unsigned int vmux; - unsigned int amux; - void (*audio_setup) (void *priv, int enable); -}; - struct au0828_board { char *name; - unsigned int tuner_type; - unsigned char tuner_addr; - struct au0828_input input[AU0828_MAX_INPUT]; - }; struct au0828_dvb { @@ -97,143 +55,31 @@ struct au0828_dvb { int feeding; }; -enum au0828_stream_state { - STREAM_OFF, - STREAM_INTERRUPT, - STREAM_ON -}; - -#define AUVI_INPUT(nr) (dev->board.input[nr]) - -/* device state */ -enum au0828_dev_state { - DEV_INITIALIZED = 0x01, - DEV_DISCONNECTED = 0x02, - DEV_MISCONFIGURED = 0x04 -}; - -struct au0828_fh { - struct au0828_dev *dev; - unsigned int stream_on:1; /* Locks streams */ - struct videobuf_queue vb_vidq; - enum v4l2_buf_type type; -}; - -struct au0828_usb_isoc_ctl { - /* max packet size of isoc transaction */ - int max_pkt_size; - - /* number of allocated urbs */ - int num_bufs; - - /* urb for isoc transfers */ - struct urb **urb; - - /* transfer buffers for isoc transfer */ - char **transfer_buffer; - - /* Last buffer command and region */ - u8 cmd; - int pos, size, pktsize; - - /* Last field: ODD or EVEN? */ - int field; - - /* Stores incomplete commands */ - u32 tmp_buf; - int tmp_buf_len; - - /* Stores already requested buffers */ - struct au0828_buffer *buf; - - /* Stores the number of received fields */ - int nfields; - - /* isoc urb callback */ - int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb); - -}; - -/* buffer for one video frame */ -struct au0828_buffer { - /* common v4l buffer stuff -- must be first */ - struct videobuf_buffer vb; - - struct list_head frame; - int top_field; - int receiving; -}; - -struct au0828_dmaqueue { - struct list_head active; - struct list_head queued; - - wait_queue_head_t wq; - - /* Counters to control buffer fill */ - int pos; -}; - struct au0828_dev { struct mutex mutex; struct usb_device *usbdev; - int boardnr; - struct au0828_board board; + int board; u8 ctrlmsg[64]; /* I2C */ struct i2c_adapter i2c_adap; - struct i2c_algorithm i2c_algo; + struct i2c_algo_bit_data i2c_algo; struct i2c_client i2c_client; u32 i2c_rc; /* Digital */ struct au0828_dvb dvb; - /* Analog */ - struct list_head au0828list; - struct v4l2_device v4l2_dev; - int users; - unsigned int stream_on:1; /* Locks streams */ - struct video_device *vdev; - struct video_device *vbi_dev; - int width; - int height; - u32 field_size; - u32 frame_size; - u32 bytesperline; - int type; - u8 ctrl_ainput; - __u8 isoc_in_endpointaddr; - u8 isoc_init_ok; - int greenscreen_detected; - unsigned int frame_count; - int ctrl_freq; - int input_type; - unsigned int ctrl_input; - enum au0828_dev_state dev_state; - enum au0828_stream_state stream_state; - wait_queue_head_t open; - - struct mutex lock; - - /* Isoc control struct */ - struct au0828_dmaqueue vidq; - struct au0828_usb_isoc_ctl isoc_ctl; - spinlock_t slock; - - /* usb transfer */ - int alt; /* alternate */ - int max_pkt_size; /* max packet size of isoc transaction */ - int num_alt; /* Number of alternative settings */ - unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ - struct urb *urb[AU0828_MAX_ISO_BUFS]; /* urb for isoc transfers */ - char *transfer_buffer[AU0828_MAX_ISO_BUFS];/* transfer buffers for isoc - transfer */ - /* USB / URB Related */ int urb_streaming; struct urb *urbs[URB_COUNT]; + +}; + +struct au0828_buff { + struct au0828_dev *dev; + struct urb *purb; + struct list_head buff_list; }; /* ----------------------------------------------------------- */ @@ -265,13 +111,8 @@ extern void au0828_card_setup(struct au0828_dev *dev); /* au0828-i2c.c */ extern int au0828_i2c_register(struct au0828_dev *dev); extern int au0828_i2c_unregister(struct au0828_dev *dev); - -/* ----------------------------------------------------------- */ -/* au0828-video.c */ -int au0828_analog_register(struct au0828_dev *dev, - struct usb_interface *interface); -int au0828_analog_stream_disable(struct au0828_dev *d); -void au0828_analog_unregister(struct au0828_dev *dev); +extern void au0828_call_i2c_clients(struct au0828_dev *dev, + unsigned int cmd, void *arg); /* ----------------------------------------------------------- */ /* au0828-dvb.c */ diff --git a/trunk/drivers/media/video/bt819.c b/trunk/drivers/media/video/bt819.c index df4516d8dcab..a07b7b88e5b8 100644 --- a/trunk/drivers/media/video/bt819.c +++ b/trunk/drivers/media/video/bt819.c @@ -29,16 +29,16 @@ */ #include +#include #include #include -#include +#include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include MODULE_DESCRIPTION("Brooktree-819 video decoder driver"); MODULE_AUTHOR("Mike Bernson & Dave Perks"); @@ -48,15 +48,13 @@ static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); - /* ----------------------------------------------------------------------- */ struct bt819 { - struct v4l2_subdev sd; unsigned char reg[32]; - v4l2_std_id norm; - int ident; + int initialized; + int norm; int input; int enable; int bright; @@ -65,11 +63,6 @@ struct bt819 { int sat; }; -static inline struct bt819 *to_bt819(struct v4l2_subdev *sd) -{ - return container_of(sd, struct bt819, sd); -} - struct timing { int hactive; int hdelay; @@ -87,23 +80,24 @@ static struct timing timing_data[] = { /* ----------------------------------------------------------------------- */ -static inline int bt819_write(struct bt819 *decoder, u8 reg, u8 value) +static inline int bt819_write(struct i2c_client *client, u8 reg, u8 value) { - struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd); + struct bt819 *decoder = i2c_get_clientdata(client); decoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } -static inline int bt819_setbit(struct bt819 *decoder, u8 reg, u8 bit, u8 value) +static inline int bt819_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value) { - return bt819_write(decoder, reg, + struct bt819 *decoder = i2c_get_clientdata(client); + + return bt819_write(client, reg, (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0)); } -static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int len) +static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned int len) { - struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd); int ret = -1; u8 reg; @@ -111,6 +105,7 @@ static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int * the adapter understands raw I2C */ if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { /* do raw I2C, not smbus compatible */ + struct bt819 *decoder = i2c_get_clientdata(client); u8 block_data[32]; int block_len; @@ -131,8 +126,7 @@ static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - ret = bt819_write(decoder, reg, *data++); - if (ret < 0) + if ((ret = bt819_write(client, reg, *data++)) < 0) break; len -= 2; } @@ -141,15 +135,15 @@ static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int return ret; } -static inline int bt819_read(struct bt819 *decoder, u8 reg) +static inline int bt819_read(struct i2c_client *client, u8 reg) { - struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd); - return i2c_smbus_read_byte_data(client, reg); } -static int bt819_init(struct v4l2_subdev *sd) +static int bt819_init(struct i2c_client *client) { + struct bt819 *decoder = i2c_get_clientdata(client); + static unsigned char init[] = { /*0x1f, 0x00,*/ /* Reset */ 0x01, 0x59, /* 0x01 input format */ @@ -184,8 +178,7 @@ static int bt819_init(struct v4l2_subdev *sd) 0x1a, 0x80, /* 0x1a ADC Interface */ }; - struct bt819 *decoder = to_bt819(sd); - struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0]; + struct timing *timing = &timing_data[decoder->norm]; init[0x03 * 2 - 1] = (((timing->vdelay >> 8) & 0x03) << 6) | @@ -199,306 +192,266 @@ static int bt819_init(struct v4l2_subdev *sd) init[0x08 * 2 - 1] = timing->hscale >> 8; init[0x09 * 2 - 1] = timing->hscale & 0xff; /* 0x15 in array is address 0x19 */ - init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93; /* Chroma burst delay */ + init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93; /* Chroma burst delay */ /* reset */ - bt819_write(decoder, 0x1f, 0x00); + bt819_write(client, 0x1f, 0x00); mdelay(1); /* init */ - return bt819_write_block(decoder, init, sizeof(init)); + return bt819_write_block(client, init, sizeof(init)); } /* ----------------------------------------------------------------------- */ -static int bt819_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd) +static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) { - struct bt819 *decoder = to_bt819(sd); - int status = bt819_read(decoder, 0x00); - int res = V4L2_IN_ST_NO_SIGNAL; - v4l2_std_id std; - - if ((status & 0x80)) - res = 0; + int temp; - if ((status & 0x10)) - std = V4L2_STD_PAL; - else - std = V4L2_STD_NTSC; - if (pstd) - *pstd = std; - if (pstatus) - *pstatus = status; + struct bt819 *decoder = i2c_get_clientdata(client); - v4l2_dbg(1, debug, sd, "get status %x\n", status); - return 0; -} + if (!decoder->initialized) { /* First call to bt819_init could be */ + bt819_init(client); /* without #FRST = 0 */ + decoder->initialized = 1; + } -static int bt819_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) -{ - return bt819_status(sd, NULL, std); -} + switch (cmd) { + case 0: + /* This is just for testing!!! */ + bt819_init(client); + break; -static int bt819_g_input_status(struct v4l2_subdev *sd, u32 *status) -{ - return bt819_status(sd, status, NULL); -} + case DECODER_GET_CAPABILITIES: + { + struct video_decoder_capability *cap = arg; -static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std) -{ - struct bt819 *decoder = to_bt819(sd); - struct timing *timing = NULL; - - v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std); - - if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL) - v4l2_err(sd, "no notify found!\n"); - - if (std & V4L2_STD_NTSC) { - v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0); - bt819_setbit(decoder, 0x01, 0, 1); - bt819_setbit(decoder, 0x01, 1, 0); - bt819_setbit(decoder, 0x01, 5, 0); - bt819_write(decoder, 0x18, 0x68); - bt819_write(decoder, 0x19, 0x5d); - /* bt819_setbit(decoder, 0x1a, 5, 1); */ - timing = &timing_data[1]; - } else if (std & V4L2_STD_PAL) { - v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0); - bt819_setbit(decoder, 0x01, 0, 1); - bt819_setbit(decoder, 0x01, 1, 1); - bt819_setbit(decoder, 0x01, 5, 1); - bt819_write(decoder, 0x18, 0x7f); - bt819_write(decoder, 0x19, 0x72); - /* bt819_setbit(decoder, 0x1a, 5, 0); */ - timing = &timing_data[0]; - } else { - v4l2_dbg(1, debug, sd, "unsupported norm %llx\n", - (unsigned long long)std); - return -EINVAL; + cap->flags = VIDEO_DECODER_PAL | + VIDEO_DECODER_NTSC | + VIDEO_DECODER_AUTO | + VIDEO_DECODER_CCIR; + cap->inputs = 8; + cap->outputs = 1; + break; } - bt819_write(decoder, 0x03, - (((timing->vdelay >> 8) & 0x03) << 6) | - (((timing->vactive >> 8) & 0x03) << 4) | - (((timing->hdelay >> 8) & 0x03) << 2) | - ((timing->hactive >> 8) & 0x03)); - bt819_write(decoder, 0x04, timing->vdelay & 0xff); - bt819_write(decoder, 0x05, timing->vactive & 0xff); - bt819_write(decoder, 0x06, timing->hdelay & 0xff); - bt819_write(decoder, 0x07, timing->hactive & 0xff); - bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff); - bt819_write(decoder, 0x09, timing->hscale & 0xff); - decoder->norm = std; - v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, 0); - return 0; -} -static int bt819_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) -{ - struct bt819 *decoder = to_bt819(sd); - - v4l2_dbg(1, debug, sd, "set input %x\n", route->input); + case DECODER_GET_STATUS: + { + int *iarg = arg; + int status; + int res; - if (route->input < 0 || route->input > 7) - return -EINVAL; + status = bt819_read(client, 0x00); + res = 0; + if ((status & 0x80)) + res |= DECODER_STATUS_GOOD; - if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL) - v4l2_err(sd, "no notify found!\n"); - - if (decoder->input != route->input) { - v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0); - decoder->input = route->input; - /* select mode */ - if (decoder->input == 0) { - bt819_setbit(decoder, 0x0b, 6, 0); - bt819_setbit(decoder, 0x1a, 1, 1); - } else { - bt819_setbit(decoder, 0x0b, 6, 1); - bt819_setbit(decoder, 0x1a, 1, 0); + switch (decoder->norm) { + case VIDEO_MODE_NTSC: + res |= DECODER_STATUS_NTSC; + break; + case VIDEO_MODE_PAL: + res |= DECODER_STATUS_PAL; + break; + default: + case VIDEO_MODE_AUTO: + if ((status & 0x10)) + res |= DECODER_STATUS_PAL; + else + res |= DECODER_STATUS_NTSC; + break; } - v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, 0); + res |= DECODER_STATUS_COLOR; + *iarg = res; + + v4l_dbg(1, debug, client, "get status %x\n", *iarg); + break; } - return 0; -} -static int bt819_s_stream(struct v4l2_subdev *sd, int enable) -{ - struct bt819 *decoder = to_bt819(sd); + case DECODER_SET_NORM: + { + int *iarg = arg; + struct timing *timing = NULL; + + v4l_dbg(1, debug, client, "set norm %x\n", *iarg); + + switch (*iarg) { + case VIDEO_MODE_NTSC: + bt819_setbit(client, 0x01, 0, 1); + bt819_setbit(client, 0x01, 1, 0); + bt819_setbit(client, 0x01, 5, 0); + bt819_write(client, 0x18, 0x68); + bt819_write(client, 0x19, 0x5d); + /* bt819_setbit(client, 0x1a, 5, 1); */ + timing = &timing_data[VIDEO_MODE_NTSC]; + break; + case VIDEO_MODE_PAL: + bt819_setbit(client, 0x01, 0, 1); + bt819_setbit(client, 0x01, 1, 1); + bt819_setbit(client, 0x01, 5, 1); + bt819_write(client, 0x18, 0x7f); + bt819_write(client, 0x19, 0x72); + /* bt819_setbit(client, 0x1a, 5, 0); */ + timing = &timing_data[VIDEO_MODE_PAL]; + break; + case VIDEO_MODE_AUTO: + bt819_setbit(client, 0x01, 0, 0); + bt819_setbit(client, 0x01, 1, 0); + break; + default: + v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg); + return -EINVAL; + } - v4l2_dbg(1, debug, sd, "enable output %x\n", enable); + if (timing) { + bt819_write(client, 0x03, + (((timing->vdelay >> 8) & 0x03) << 6) | + (((timing->vactive >> 8) & 0x03) << 4) | + (((timing->hdelay >> 8) & 0x03) << 2) | + ((timing->hactive >> 8) & 0x03) ); + bt819_write(client, 0x04, timing->vdelay & 0xff); + bt819_write(client, 0x05, timing->vactive & 0xff); + bt819_write(client, 0x06, timing->hdelay & 0xff); + bt819_write(client, 0x07, timing->hactive & 0xff); + bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff); + bt819_write(client, 0x09, timing->hscale & 0xff); + } - if (decoder->enable != enable) { - decoder->enable = enable; - bt819_setbit(decoder, 0x16, 7, !enable); + decoder->norm = *iarg; + break; } - return 0; -} -static int bt819_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) -{ - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); + case DECODER_SET_INPUT: + { + int *iarg = arg; + + v4l_dbg(1, debug, client, "set input %x\n", *iarg); + + if (*iarg < 0 || *iarg > 7) + return -EINVAL; + + if (decoder->input != *iarg) { + decoder->input = *iarg; + /* select mode */ + if (decoder->input == 0) { + bt819_setbit(client, 0x0b, 6, 0); + bt819_setbit(client, 0x1a, 1, 1); + } else { + bt819_setbit(client, 0x0b, 6, 1); + bt819_setbit(client, 0x1a, 1, 0); + } + } break; + } - case V4L2_CID_CONTRAST: - v4l2_ctrl_query_fill(qc, 0, 511, 1, 256); - break; + case DECODER_SET_OUTPUT: + { + int *iarg = arg; - case V4L2_CID_SATURATION: - v4l2_ctrl_query_fill(qc, 0, 511, 1, 256); - break; + v4l_dbg(1, debug, client, "set output %x\n", *iarg); - case V4L2_CID_HUE: - v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); + /* not much choice of outputs */ + if (*iarg != 0) + return -EINVAL; break; - - default: - return -EINVAL; } - return 0; -} -static int bt819_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct bt819 *decoder = to_bt819(sd); - int temp; + case DECODER_ENABLE_OUTPUT: + { + int *iarg = arg; + int enable = (*iarg != 0); - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - if (decoder->bright == ctrl->value) - break; - decoder->bright = ctrl->value; - bt819_write(decoder, 0x0a, decoder->bright); - break; + v4l_dbg(1, debug, client, "enable output %x\n", *iarg); - case V4L2_CID_CONTRAST: - if (decoder->contrast == ctrl->value) - break; - decoder->contrast = ctrl->value; - bt819_write(decoder, 0x0c, decoder->contrast & 0xff); - bt819_setbit(decoder, 0x0b, 2, ((decoder->contrast >> 8) & 0x01)); + if (decoder->enable != enable) { + decoder->enable = enable; + bt819_setbit(client, 0x16, 7, !enable); + } break; + } - case V4L2_CID_SATURATION: - if (decoder->sat == ctrl->value) - break; - decoder->sat = ctrl->value; - bt819_write(decoder, 0x0d, (decoder->sat >> 7) & 0xff); - bt819_setbit(decoder, 0x0b, 1, ((decoder->sat >> 15) & 0x01)); - - /* Ratio between U gain and V gain must stay the same as - the ratio between the default U and V gain values. */ - temp = (decoder->sat * 180) / 254; - bt819_write(decoder, 0x0e, (temp >> 7) & 0xff); - bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01); - break; + case DECODER_SET_PICTURE: + { + struct video_picture *pic = arg; - case V4L2_CID_HUE: - if (decoder->hue == ctrl->value) - break; - decoder->hue = ctrl->value; - bt819_write(decoder, 0x0f, decoder->hue); - break; + v4l_dbg(1, debug, client, + "set picture brightness %d contrast %d colour %d\n", + pic->brightness, pic->contrast, pic->colour); - default: - return -EINVAL; - } - return 0; -} -static int bt819_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct bt819 *decoder = to_bt819(sd); + if (decoder->bright != pic->brightness) { + /* We want -128 to 127 we get 0-65535 */ + decoder->bright = pic->brightness; + bt819_write(client, 0x0a, + (decoder->bright >> 8) - 128); + } - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = decoder->bright; - break; - case V4L2_CID_CONTRAST: - ctrl->value = decoder->contrast; - break; - case V4L2_CID_SATURATION: - ctrl->value = decoder->sat; - break; - case V4L2_CID_HUE: - ctrl->value = decoder->hue; + if (decoder->contrast != pic->contrast) { + /* We want 0 to 511 we get 0-65535 */ + decoder->contrast = pic->contrast; + bt819_write(client, 0x0c, + (decoder->contrast >> 7) & 0xff); + bt819_setbit(client, 0x0b, 2, + ((decoder->contrast >> 15) & 0x01)); + } + + if (decoder->sat != pic->colour) { + /* We want 0 to 511 we get 0-65535 */ + decoder->sat = pic->colour; + bt819_write(client, 0x0d, + (decoder->sat >> 7) & 0xff); + bt819_setbit(client, 0x0b, 1, + ((decoder->sat >> 15) & 0x01)); + + temp = (decoder->sat * 201) / 237; + bt819_write(client, 0x0e, (temp >> 7) & 0xff); + bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01); + } + + if (decoder->hue != pic->hue) { + /* We want -128 to 127 we get 0-65535 */ + decoder->hue = pic->hue; + bt819_write(client, 0x0f, + 128 - (decoder->hue >> 8)); + } break; + } + default: return -EINVAL; } - return 0; -} -static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) -{ - struct bt819 *decoder = to_bt819(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0); + return 0; } /* ----------------------------------------------------------------------- */ -static const struct v4l2_subdev_core_ops bt819_core_ops = { - .g_chip_ident = bt819_g_chip_ident, - .g_ctrl = bt819_g_ctrl, - .s_ctrl = bt819_s_ctrl, - .queryctrl = bt819_queryctrl, -}; - -static const struct v4l2_subdev_tuner_ops bt819_tuner_ops = { - .s_std = bt819_s_std, -}; - -static const struct v4l2_subdev_video_ops bt819_video_ops = { - .s_routing = bt819_s_routing, - .s_stream = bt819_s_stream, - .querystd = bt819_querystd, - .g_input_status = bt819_g_input_status, -}; - -static const struct v4l2_subdev_ops bt819_ops = { - .core = &bt819_core_ops, - .tuner = &bt819_tuner_ops, - .video = &bt819_video_ops, -}; +static unsigned short normal_i2c[] = { 0x8a >> 1, I2C_CLIENT_END }; -/* ----------------------------------------------------------------------- */ +I2C_CLIENT_INSMOD; static int bt819_probe(struct i2c_client *client, const struct i2c_device_id *id) { int i, ver; struct bt819 *decoder; - struct v4l2_subdev *sd; const char *name; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; - decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL); - if (decoder == NULL) - return -ENOMEM; - sd = &decoder->sd; - v4l2_i2c_subdev_init(sd, client, &bt819_ops); - - ver = bt819_read(decoder, 0x17); + ver = bt819_read(client, 0x17); switch (ver & 0xf0) { case 0x70: name = "bt819a"; - decoder->ident = V4L2_IDENT_BT819A; break; case 0x60: name = "bt817a"; - decoder->ident = V4L2_IDENT_BT817A; break; case 0x20: name = "bt815a"; - decoder->ident = V4L2_IDENT_BT815A; break; default: - v4l2_dbg(1, debug, sd, + v4l_dbg(1, debug, client, "unknown chip version 0x%02x\n", ver); return -ENODEV; } @@ -506,26 +459,28 @@ static int bt819_probe(struct i2c_client *client, v4l_info(client, "%s found @ 0x%x (%s)\n", name, client->addr << 1, client->adapter->name); - decoder->norm = V4L2_STD_NTSC; + decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL); + if (decoder == NULL) + return -ENOMEM; + decoder->norm = VIDEO_MODE_NTSC; decoder->input = 0; decoder->enable = 1; - decoder->bright = 0; - decoder->contrast = 0xd8; /* 100% of original signal */ - decoder->hue = 0; - decoder->sat = 0xfe; /* 100% of original signal */ - - i = bt819_init(sd); + decoder->bright = 32768; + decoder->contrast = 32768; + decoder->hue = 32768; + decoder->sat = 32768; + decoder->initialized = 0; + i2c_set_clientdata(client, decoder); + + i = bt819_init(client); if (i < 0) - v4l2_dbg(1, debug, sd, "init status %d\n", i); + v4l_dbg(1, debug, client, "init status %d\n", i); return 0; } static int bt819_remove(struct i2c_client *client) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - - v4l2_device_unregister_subdev(sd); - kfree(to_bt819(sd)); + kfree(i2c_get_clientdata(client)); return 0; } @@ -541,6 +496,8 @@ MODULE_DEVICE_TABLE(i2c, bt819_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "bt819", + .driverid = I2C_DRIVERID_BT819, + .command = bt819_command, .probe = bt819_probe, .remove = bt819_remove, .id_table = bt819_id, diff --git a/trunk/drivers/media/video/bt856.c b/trunk/drivers/media/video/bt856.c index 78db39503947..4213867507f8 100644 --- a/trunk/drivers/media/video/bt856.c +++ b/trunk/drivers/media/video/bt856.c @@ -34,10 +34,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); MODULE_AUTHOR("Mike Bernson & Dave Perks"); @@ -47,46 +47,43 @@ static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); - /* ----------------------------------------------------------------------- */ #define BT856_REG_OFFSET 0xDA #define BT856_NR_REG 6 struct bt856 { - struct v4l2_subdev sd; unsigned char reg[BT856_NR_REG]; - v4l2_std_id norm; + int norm; + int enable; }; -static inline struct bt856 *to_bt856(struct v4l2_subdev *sd) -{ - return container_of(sd, struct bt856, sd); -} - /* ----------------------------------------------------------------------- */ -static inline int bt856_write(struct bt856 *encoder, u8 reg, u8 value) +static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value) { - struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd); + struct bt856 *encoder = i2c_get_clientdata(client); encoder->reg[reg - BT856_REG_OFFSET] = value; return i2c_smbus_write_byte_data(client, reg, value); } -static inline int bt856_setbit(struct bt856 *encoder, u8 reg, u8 bit, u8 value) +static inline int bt856_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value) { - return bt856_write(encoder, reg, + struct bt856 *encoder = i2c_get_clientdata(client); + + return bt856_write(client, reg, (encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) | (value ? (1 << bit) : 0)); } -static void bt856_dump(struct bt856 *encoder) +static void bt856_dump(struct i2c_client *client) { int i; + struct bt856 *encoder = i2c_get_clientdata(client); - v4l2_info(&encoder->sd, "register dump:\n"); + v4l_info(client, "register dump:\n"); for (i = 0; i < BT856_NR_REG; i += 2) printk(KERN_CONT " %02x", encoder->reg[i]); printk(KERN_CONT "\n"); @@ -94,120 +91,153 @@ static void bt856_dump(struct bt856 *encoder) /* ----------------------------------------------------------------------- */ -static int bt856_init(struct v4l2_subdev *sd, u32 arg) +static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) { - struct bt856 *encoder = to_bt856(sd); - - /* This is just for testing!!! */ - v4l2_dbg(1, debug, sd, "init\n"); - bt856_write(encoder, 0xdc, 0x18); - bt856_write(encoder, 0xda, 0); - bt856_write(encoder, 0xde, 0); - - bt856_setbit(encoder, 0xdc, 3, 1); - /*bt856_setbit(encoder, 0xdc, 6, 0);*/ - bt856_setbit(encoder, 0xdc, 4, 1); - - if (encoder->norm & V4L2_STD_NTSC) - bt856_setbit(encoder, 0xdc, 2, 0); - else - bt856_setbit(encoder, 0xdc, 2, 1); - - bt856_setbit(encoder, 0xdc, 1, 1); - bt856_setbit(encoder, 0xde, 4, 0); - bt856_setbit(encoder, 0xde, 3, 1); - if (debug != 0) - bt856_dump(encoder); - return 0; -} + struct bt856 *encoder = i2c_get_clientdata(client); -static int bt856_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) -{ - struct bt856 *encoder = to_bt856(sd); + switch (cmd) { + case 0: + /* This is just for testing!!! */ + v4l_dbg(1, debug, client, "init\n"); + bt856_write(client, 0xdc, 0x18); + bt856_write(client, 0xda, 0); + bt856_write(client, 0xde, 0); + + bt856_setbit(client, 0xdc, 3, 1); + //bt856_setbit(client, 0xdc, 6, 0); + bt856_setbit(client, 0xdc, 4, 1); + + switch (encoder->norm) { + case VIDEO_MODE_NTSC: + bt856_setbit(client, 0xdc, 2, 0); + break; + + case VIDEO_MODE_PAL: + bt856_setbit(client, 0xdc, 2, 1); + break; + } + + bt856_setbit(client, 0xdc, 1, 1); + bt856_setbit(client, 0xde, 4, 0); + bt856_setbit(client, 0xde, 3, 1); + if (debug != 0) + bt856_dump(client); + break; - v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std); + case ENCODER_GET_CAPABILITIES: + { + struct video_encoder_capability *cap = arg; - if (std & V4L2_STD_NTSC) { - bt856_setbit(encoder, 0xdc, 2, 0); - } else if (std & V4L2_STD_PAL) { - bt856_setbit(encoder, 0xdc, 2, 1); - bt856_setbit(encoder, 0xda, 0, 0); - /*bt856_setbit(encoder, 0xda, 0, 1);*/ - } else { - return -EINVAL; - } - encoder->norm = std; - if (debug != 0) - bt856_dump(encoder); - return 0; -} + v4l_dbg(1, debug, client, "get capabilities\n"); -static int bt856_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) -{ - struct bt856 *encoder = to_bt856(sd); + cap->flags = VIDEO_ENCODER_PAL | + VIDEO_ENCODER_NTSC | + VIDEO_ENCODER_CCIR; + cap->inputs = 2; + cap->outputs = 1; + break; + } - v4l2_dbg(1, debug, sd, "set input %d\n", route->input); + case ENCODER_SET_NORM: + { + int *iarg = arg; + + v4l_dbg(1, debug, client, "set norm %d\n", *iarg); + + switch (*iarg) { + case VIDEO_MODE_NTSC: + bt856_setbit(client, 0xdc, 2, 0); + break; + + case VIDEO_MODE_PAL: + bt856_setbit(client, 0xdc, 2, 1); + bt856_setbit(client, 0xda, 0, 0); + //bt856_setbit(client, 0xda, 0, 1); + break; + + default: + return -EINVAL; + } + encoder->norm = *iarg; + if (debug != 0) + bt856_dump(client); + break; + } - /* We only have video bus. - * route->input= 0: input is from bt819 - * route->input= 1: input is from ZR36060 */ - switch (route->input) { - case 0: - bt856_setbit(encoder, 0xde, 4, 0); - bt856_setbit(encoder, 0xde, 3, 1); - bt856_setbit(encoder, 0xdc, 3, 1); - bt856_setbit(encoder, 0xdc, 6, 0); + case ENCODER_SET_INPUT: + { + int *iarg = arg; + + v4l_dbg(1, debug, client, "set input %d\n", *iarg); + + /* We only have video bus. + * iarg = 0: input is from bt819 + * iarg = 1: input is from ZR36060 */ + switch (*iarg) { + case 0: + bt856_setbit(client, 0xde, 4, 0); + bt856_setbit(client, 0xde, 3, 1); + bt856_setbit(client, 0xdc, 3, 1); + bt856_setbit(client, 0xdc, 6, 0); + break; + case 1: + bt856_setbit(client, 0xde, 4, 0); + bt856_setbit(client, 0xde, 3, 1); + bt856_setbit(client, 0xdc, 3, 1); + bt856_setbit(client, 0xdc, 6, 1); + break; + case 2: // Color bar + bt856_setbit(client, 0xdc, 3, 0); + bt856_setbit(client, 0xde, 4, 1); + break; + default: + return -EINVAL; + } + + if (debug != 0) + bt856_dump(client); break; - case 1: - bt856_setbit(encoder, 0xde, 4, 0); - bt856_setbit(encoder, 0xde, 3, 1); - bt856_setbit(encoder, 0xdc, 3, 1); - bt856_setbit(encoder, 0xdc, 6, 1); + } + + case ENCODER_SET_OUTPUT: + { + int *iarg = arg; + + v4l_dbg(1, debug, client, "set output %d\n", *iarg); + + /* not much choice of outputs */ + if (*iarg != 0) + return -EINVAL; break; - case 2: /* Color bar */ - bt856_setbit(encoder, 0xdc, 3, 0); - bt856_setbit(encoder, 0xde, 4, 1); + } + + case ENCODER_ENABLE_OUTPUT: + { + int *iarg = arg; + + encoder->enable = !!*iarg; + + v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable); break; + } + default: return -EINVAL; } - if (debug != 0) - bt856_dump(encoder); return 0; } -static int bt856_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT856, 0); -} - /* ----------------------------------------------------------------------- */ -static const struct v4l2_subdev_core_ops bt856_core_ops = { - .g_chip_ident = bt856_g_chip_ident, - .init = bt856_init, -}; - -static const struct v4l2_subdev_video_ops bt856_video_ops = { - .s_std_output = bt856_s_std_output, - .s_routing = bt856_s_routing, -}; +static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; -static const struct v4l2_subdev_ops bt856_ops = { - .core = &bt856_core_ops, - .video = &bt856_video_ops, -}; - -/* ----------------------------------------------------------------------- */ +I2C_CLIENT_INSMOD; static int bt856_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct bt856 *encoder; - struct v4l2_subdev *sd; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) @@ -219,38 +249,41 @@ static int bt856_probe(struct i2c_client *client, encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - sd = &encoder->sd; - v4l2_i2c_subdev_init(sd, client, &bt856_ops); - encoder->norm = V4L2_STD_NTSC; + encoder->norm = VIDEO_MODE_NTSC; + encoder->enable = 1; + i2c_set_clientdata(client, encoder); - bt856_write(encoder, 0xdc, 0x18); - bt856_write(encoder, 0xda, 0); - bt856_write(encoder, 0xde, 0); + bt856_write(client, 0xdc, 0x18); + bt856_write(client, 0xda, 0); + bt856_write(client, 0xde, 0); - bt856_setbit(encoder, 0xdc, 3, 1); - /*bt856_setbit(encoder, 0xdc, 6, 0);*/ - bt856_setbit(encoder, 0xdc, 4, 1); + bt856_setbit(client, 0xdc, 3, 1); + //bt856_setbit(client, 0xdc, 6, 0); + bt856_setbit(client, 0xdc, 4, 1); - if (encoder->norm & V4L2_STD_NTSC) - bt856_setbit(encoder, 0xdc, 2, 0); - else - bt856_setbit(encoder, 0xdc, 2, 1); + switch (encoder->norm) { - bt856_setbit(encoder, 0xdc, 1, 1); - bt856_setbit(encoder, 0xde, 4, 0); - bt856_setbit(encoder, 0xde, 3, 1); + case VIDEO_MODE_NTSC: + bt856_setbit(client, 0xdc, 2, 0); + break; + + case VIDEO_MODE_PAL: + bt856_setbit(client, 0xdc, 2, 1); + break; + } + + bt856_setbit(client, 0xdc, 1, 1); + bt856_setbit(client, 0xde, 4, 0); + bt856_setbit(client, 0xde, 3, 1); if (debug != 0) - bt856_dump(encoder); + bt856_dump(client); return 0; } static int bt856_remove(struct i2c_client *client) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - - v4l2_device_unregister_subdev(sd); - kfree(to_bt856(sd)); + kfree(i2c_get_clientdata(client)); return 0; } @@ -262,6 +295,8 @@ MODULE_DEVICE_TABLE(i2c, bt856_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "bt856", + .driverid = I2C_DRIVERID_BT856, + .command = bt856_command, .probe = bt856_probe, .remove = bt856_remove, .id_table = bt856_id, diff --git a/trunk/drivers/media/video/bt866.c b/trunk/drivers/media/video/bt866.c index 350cae4b02c3..596f9e2376be 100644 --- a/trunk/drivers/media/video/bt866.c +++ b/trunk/drivers/media/video/bt866.c @@ -34,10 +34,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include MODULE_DESCRIPTION("Brooktree-866 video encoder driver"); MODULE_AUTHOR("Mike Bernson & Dave Perks"); @@ -47,22 +47,22 @@ static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); - /* ----------------------------------------------------------------------- */ struct bt866 { - struct v4l2_subdev sd; u8 reg[256]; -}; -static inline struct bt866 *to_bt866(struct v4l2_subdev *sd) -{ - return container_of(sd, struct bt866, sd); -} + int norm; + int enable; + int bright; + int contrast; + int hue; + int sat; +}; -static int bt866_write(struct bt866 *encoder, u8 subaddr, u8 data) +static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data) { - struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd); + struct bt866 *encoder = i2c_get_clientdata(client); u8 buffer[2]; int err; @@ -89,120 +89,163 @@ static int bt866_write(struct bt866 *encoder, u8 subaddr, u8 data) return 0; } -static int bt866_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) +static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) { - v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std); + struct bt866 *encoder = i2c_get_clientdata(client); - /* Only PAL supported by this driver at the moment! */ - if (!(std & V4L2_STD_NTSC)) - return -EINVAL; - return 0; -} + switch (cmd) { + case ENCODER_GET_CAPABILITIES: + { + struct video_encoder_capability *cap = arg; -static int bt866_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) -{ - static const __u8 init[] = { - 0xc8, 0xcc, /* CRSCALE */ - 0xca, 0x91, /* CBSCALE */ - 0xcc, 0x24, /* YC16 | OSDNUM */ - 0xda, 0x00, /* */ - 0xdc, 0x24, /* SETMODE | PAL */ - 0xde, 0x02, /* EACTIVE */ - - /* overlay colors */ - 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */ - 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */ - 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */ - 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */ - 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */ - 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */ - 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */ - 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */ - - 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */ - 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */ - 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */ - 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */ - 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */ - 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */ - 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */ - 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */ - }; - struct bt866 *encoder = to_bt866(sd); - u8 val; - int i; - - for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2) - bt866_write(encoder, init[i], init[i+1]); - - val = encoder->reg[0xdc]; - - if (route->input == 0) - val |= 0x40; /* CBSWAP */ - else - val &= ~0x40; /* !CBSWAP */ - - bt866_write(encoder, 0xdc, val); - - val = encoder->reg[0xcc]; - if (route->input == 2) - val |= 0x01; /* OSDBAR */ - else - val &= ~0x01; /* !OSDBAR */ - bt866_write(encoder, 0xcc, val); - - v4l2_dbg(1, debug, sd, "set input %d\n", route->input); - - switch (route->input) { - case 0: - case 1: - case 2: + v4l_dbg(1, debug, client, "get capabilities\n"); + + cap->flags + = VIDEO_ENCODER_PAL + | VIDEO_ENCODER_NTSC + | VIDEO_ENCODER_CCIR; + cap->inputs = 2; + cap->outputs = 1; break; - default: - return -EINVAL; } - return 0; -} -#if 0 -/* Code to setup square pixels, might be of some use in the future, - but is currently unused. */ - val = encoder->reg[0xdc]; - if (*iarg) - val |= 1; /* SQUARE */ - else - val &= ~1; /* !SQUARE */ - bt866_write(client, 0xdc, val); -#endif - -static int bt866_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); + case ENCODER_SET_NORM: + { + int *iarg = arg; - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT866, 0); -} + v4l_dbg(1, debug, client, "set norm %d\n", *iarg); -/* ----------------------------------------------------------------------- */ + switch (*iarg) { + case VIDEO_MODE_NTSC: + break; -static const struct v4l2_subdev_core_ops bt866_core_ops = { - .g_chip_ident = bt866_g_chip_ident, -}; + case VIDEO_MODE_PAL: + break; -static const struct v4l2_subdev_video_ops bt866_video_ops = { - .s_std_output = bt866_s_std_output, - .s_routing = bt866_s_routing, -}; + default: + return -EINVAL; + } + encoder->norm = *iarg; + break; + } -static const struct v4l2_subdev_ops bt866_ops = { - .core = &bt866_core_ops, - .video = &bt866_video_ops, -}; + case ENCODER_SET_INPUT: + { + int *iarg = arg; + static const __u8 init[] = { + 0xc8, 0xcc, /* CRSCALE */ + 0xca, 0x91, /* CBSCALE */ + 0xcc, 0x24, /* YC16 | OSDNUM */ + 0xda, 0x00, /* */ + 0xdc, 0x24, /* SETMODE | PAL */ + 0xde, 0x02, /* EACTIVE */ + + /* overlay colors */ + 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */ + 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */ + 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */ + 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */ + 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */ + 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */ + 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */ + 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */ + + 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */ + 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */ + 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */ + 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */ + 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */ + 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */ + 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */ + 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */ + }; + int i; + u8 val; + + for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2) + bt866_write(client, init[i], init[i+1]); + + val = encoder->reg[0xdc]; + + if (*iarg == 0) + val |= 0x40; /* CBSWAP */ + else + val &= ~0x40; /* !CBSWAP */ + + bt866_write(client, 0xdc, val); + + val = encoder->reg[0xcc]; + if (*iarg == 2) + val |= 0x01; /* OSDBAR */ + else + val &= ~0x01; /* !OSDBAR */ + bt866_write(client, 0xcc, val); + + v4l_dbg(1, debug, client, "set input %d\n", *iarg); + + switch (*iarg) { + case 0: + break; + case 1: + break; + default: + return -EINVAL; + } + break; + } + + case ENCODER_SET_OUTPUT: + { + int *iarg = arg; + + v4l_dbg(1, debug, client, "set output %d\n", *iarg); + + /* not much choice of outputs */ + if (*iarg != 0) + return -EINVAL; + break; + } + + case ENCODER_ENABLE_OUTPUT: + { + int *iarg = arg; + encoder->enable = !!*iarg; + + v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable); + break; + } + + case 4711: + { + int *iarg = arg; + __u8 val; + + v4l_dbg(1, debug, client, "square %d\n", *iarg); + + val = encoder->reg[0xdc]; + if (*iarg) + val |= 1; /* SQUARE */ + else + val &= ~1; /* !SQUARE */ + bt866_write(client, 0xdc, val); + break; + } + + default: + return -EINVAL; + } + + return 0; +} + +static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; static int bt866_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct bt866 *encoder; - struct v4l2_subdev *sd; v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); @@ -210,20 +253,22 @@ static int bt866_probe(struct i2c_client *client, encoder = kzalloc(sizeof(*encoder), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - sd = &encoder->sd; - v4l2_i2c_subdev_init(sd, client, &bt866_ops); + + i2c_set_clientdata(client, encoder); return 0; } static int bt866_remove(struct i2c_client *client) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - - v4l2_device_unregister_subdev(sd); - kfree(to_bt866(sd)); + kfree(i2c_get_clientdata(client)); return 0; } +static int bt866_legacy_probe(struct i2c_adapter *adapter) +{ + return adapter->id == I2C_HW_B_ZR36067; +} + static const struct i2c_device_id bt866_id[] = { { "bt866", 0 }, { } @@ -232,7 +277,10 @@ MODULE_DEVICE_TABLE(i2c, bt866_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "bt866", + .driverid = I2C_DRIVERID_BT866, + .command = bt866_command, .probe = bt866_probe, .remove = bt866_remove, + .legacy_probe = bt866_legacy_probe, .id_table = bt866_id, }; diff --git a/trunk/drivers/media/video/bt8xx/Kconfig b/trunk/drivers/media/video/bt8xx/Kconfig index 3077c45015f5..ce71e8e7b835 100644 --- a/trunk/drivers/media/video/bt8xx/Kconfig +++ b/trunk/drivers/media/video/bt8xx/Kconfig @@ -10,7 +10,7 @@ config VIDEO_BT848 select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TDA7432 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_TDA9875 if VIDEO_HELPER_CHIPS_AUTO ---help--- Support for BT848 based frame grabber/overlay boards. This includes the Miro, Hauppauge and STB boards. Please read the material in diff --git a/trunk/drivers/media/video/bt8xx/bttv-cards.c b/trunk/drivers/media/video/bt8xx/bttv-cards.c index b9c3ba51fb86..d24dcc025e37 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-cards.c +++ b/trunk/drivers/media/video/bt8xx/bttv-cards.c @@ -73,11 +73,6 @@ static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input); static void geovision_muxsel(struct bttv *btv, unsigned int input); -static void phytec_muxsel(struct bttv *btv, unsigned int input); - -static void gv800s_muxsel(struct bttv *btv, unsigned int input); -static void gv800s_init(struct bttv *btv); - static int terratec_active_radio_upgrade(struct bttv *btv); static int tea5757_read(struct bttv *btv); static int tea5757_write(struct bttv *btv, int value); @@ -96,10 +91,12 @@ static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; static unsigned int svhs[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; static unsigned int remote[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; -static unsigned int audiodev[BTTV_MAX]; -static unsigned int saa6588[BTTV_MAX]; static struct bttv *master[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = NULL }; -static unsigned int autoload = UNSET; +#ifdef MODULE +static unsigned int autoload = 1; +#else +static unsigned int autoload; +#endif static unsigned int gpiomask = UNSET; static unsigned int audioall = UNSET; static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET }; @@ -118,7 +115,6 @@ module_param_array(pll, int, NULL, 0444); module_param_array(tuner, int, NULL, 0444); module_param_array(svhs, int, NULL, 0444); module_param_array(remote, int, NULL, 0444); -module_param_array(audiodev, int, NULL, 0444); module_param_array(audiomux, int, NULL, 0444); MODULE_PARM_DESC(triton1,"set ETBF pci config bit " @@ -129,14 +125,7 @@ MODULE_PARM_DESC(latency,"pci latency timer"); MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list"); MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)"); MODULE_PARM_DESC(tuner,"specify installed tuner type"); -MODULE_PARM_DESC(autoload, "obsolete option, please do not use anymore"); -MODULE_PARM_DESC(audiodev, "specify audio device:\n" - "\t\t-1 = no audio\n" - "\t\t 0 = autodetect (default)\n" - "\t\t 1 = msp3400\n" - "\t\t 2 = tda7432\n" - "\t\t 3 = tvaudio"); -MODULE_PARM_DESC(saa6588, "if 1, then load the saa6588 RDS module, default (0) is to use the card definition."); +MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default is 1 (yes)"); MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)" " [some VIA/SIS chipsets are known to have problem with overlay]"); @@ -257,10 +246,6 @@ static struct CARD { { 0xa182ff0d, BTTV_BOARD_IVC120, "IVC-120G" }, { 0xa182ff0e, BTTV_BOARD_IVC120, "IVC-120G" }, { 0xa182ff0f, BTTV_BOARD_IVC120, "IVC-120G" }, - { 0xf0500000, BTTV_BOARD_IVCE8784, "IVCE-8784" }, - { 0xf0500001, BTTV_BOARD_IVCE8784, "IVCE-8784" }, - { 0xf0500002, BTTV_BOARD_IVCE8784, "IVCE-8784" }, - { 0xf0500003, BTTV_BOARD_IVCE8784, "IVCE-8784" }, { 0x41424344, BTTV_BOARD_GRANDTEC, "GrandTec Multi Capture" }, { 0x01020304, BTTV_BOARD_XGUARD, "Grandtec Grand X-Guard" }, @@ -304,8 +289,6 @@ static struct CARD { /* Duplicate PCI ID, reconfigure for this board during the eeprom read. * { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB, "Hauppauge ImpactVCB" }, */ - { 0x109e036e, BTTV_BOARD_CONCEPTRONIC_CTVFMI2, "Conceptronic CTVFMi v2"}, - /* DVB cards (using pci function .1 for mpeg data xfer) */ { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" }, { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, @@ -322,20 +305,6 @@ static struct CARD { { 0xd200dbc0, BTTV_BOARD_DVICO_FUSIONHDTV_2, "DViCO FusionHDTV 2" }, { 0x763c008a, BTTV_BOARD_GEOVISION_GV600, "GeoVision GV-600" }, { 0x18011000, BTTV_BOARD_ENLTV_FM_2, "Encore ENL TV-FM-2" }, - { 0x763d800a, BTTV_BOARD_GEOVISION_GV800S, "GeoVision GV-800(S) (master)" }, - { 0x763d800b, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" }, - { 0x763d800c, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" }, - { 0x763d800d, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" }, - - { 0x15401830, BTTV_BOARD_PV183, "Provideo PV183-1" }, - { 0x15401831, BTTV_BOARD_PV183, "Provideo PV183-2" }, - { 0x15401832, BTTV_BOARD_PV183, "Provideo PV183-3" }, - { 0x15401833, BTTV_BOARD_PV183, "Provideo PV183-4" }, - { 0x15401834, BTTV_BOARD_PV183, "Provideo PV183-5" }, - { 0x15401835, BTTV_BOARD_PV183, "Provideo PV183-6" }, - { 0x15401836, BTTV_BOARD_PV183, "Provideo PV183-7" }, - { 0x15401837, BTTV_BOARD_PV183, "Provideo PV183-8" }, - { 0, -1, NULL } }; @@ -347,50 +316,59 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_UNKNOWN] = { .name = " *** UNKNOWN/GENERIC *** ", .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, .svhs = 2, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MIRO] = { .name = "MIRO PCTV", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_HAUPPAUGE] = { .name = "Hauppauge (bt848)", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 7, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_STB] = { .name = "STB, Gateway P/N 6000699 (bt848)", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 7, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 4, 0, 2, 3 }, .gpiomute = 1, .no_msp34xx = 1, .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, }, @@ -399,177 +377,202 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_INTEL] = { .name = "Intel Create and Share PCI/ Smart Video Recorder III", .video_inputs = 4, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, .svhs = 2, .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0 }, .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_DIAMOND] = { .name = "Diamond DTV2000", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 3, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, .gpiomux = { 0, 1, 0, 1 }, .gpiomute = 3, .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_AVERMEDIA] = { .name = "AVerMedia TVPhone", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 3, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomask = 0x0f, .gpiomux = { 0x0c, 0x04, 0x08, 0x04 }, /* 0x04 for some cards ?? */ .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .audio_mode_gpio= avermedia_tvphone_audio, .has_remote = 1, }, [BTTV_BOARD_MATRIX_VISION] = { .name = "MATRIX-Vision MV-Delta", .video_inputs = 5, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = UNSET, .svhs = 3, .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 0, 0), + .muxsel = { 2, 3, 1, 0, 0 }, .gpiomux = { 0 }, .needs_tvaudio = 1, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x08 ---------------------------------- */ [BTTV_BOARD_FLYVIDEO] = { .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0xc00, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 0xc00, 0x800, 0x400 }, .gpiomute = 0xc00, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_TURBOTV] = { .name = "IMS/IXmicro TurboTV", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 3, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 1, 1, 2, 3 }, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_HAUPPAUGE878] = { .name = "Hauppauge (bt878)", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x0f, /* old: 7 */ - .muxsel = MUXSEL(2, 0, 1, 1), + .muxsel = { 2, 0, 1, 1 }, .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MIROPRO] = { .name = "MIRO PCTV pro", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x3014f, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0x20001,0x10001, 0, 0 }, .gpiomute = 10, .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x0c ---------------------------------- */ [BTTV_BOARD_ADSTECH_TV] = { .name = "ADS Technologies Channel Surfer TV (bt848)", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 13, 14, 11, 7 }, .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_AVERMEDIA98] = { .name = "AVerMedia TVCapture 98", .video_inputs = 3, - /* .audio_inputs= 4, */ + .audio_inputs = 4, + .tuner = 0, .svhs = 2, .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 13, 14, 11, 7 }, .needs_tvaudio = 1, .msp34xx_alt = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .audio_mode_gpio= avermedia_tv_stereo_audio, .no_gpioirq = 1, }, [BTTV_BOARD_VHX] = { .name = "Aimslab Video Highway Xtreme (VHX)", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 7, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */ .gpiomute = 4, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_ZOLTRIX] = { .name = "Zoltrix TV-Max", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 0, 1, 0 }, .gpiomute = 10, .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x10 ---------------------------------- */ [BTTV_BOARD_PIXVIEWPLAYTV] = { .name = "Prolink Pixelview PlayTV (bt878)", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x01fe00, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, /* 2003-10-20 by "Anton A. Arapov" */ .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, .gpiomute = 0x002000, @@ -577,170 +580,194 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_WINVIEW_601] = { .name = "Leadtek WinView 601", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x8300f8, - .muxsel = MUXSEL(2, 3, 1, 1, 0), + .muxsel = { 2, 3, 1, 1,0 }, .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 }, .gpiomute = 0xcfa007, .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .volume_gpio = winview_volume, .has_radio = 1, }, [BTTV_BOARD_AVEC_INTERCAP] = { .name = "AVEC Intercapture", .video_inputs = 3, - /* .audio_inputs= 2, */ + .audio_inputs = 2, + .tuner = 0, .svhs = 2, .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 1, 0, 0, 0 }, .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_LIFE_FLYKIT] = { .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, + .audio_inputs = 1, + .tuner = UNSET, + .svhs = UNSET, .gpiomask = 0x8dff00, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0 }, .no_msp34xx = 1, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x14 ---------------------------------- */ [BTTV_BOARD_CEI_RAFFLES] = { .name = "CEI Raffles Card", .video_inputs = 3, - /* .audio_inputs= 3, */ + .audio_inputs = 3, + .tuner = 0, .svhs = 2, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_CONFERENCETV] = { .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50", .video_inputs = 4, - /* .audio_inputs= 2, tuner, line in */ + .audio_inputs = 2, /* tuner, line in */ + .tuner = 0, .svhs = 2, .gpiomask = 0x1800, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, .gpiomute = 0x1800, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_PHOEBE_TVMAS] = { .name = "Askey CPH050/ Phoebe Tv Master + FM", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0xc00, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 1, 0x800, 0x400 }, .gpiomute = 0xc00, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MODTEC_205] = { .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878", .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, - .has_dig_in = 1, + .audio_inputs = 1, + .tuner = 0, + .svhs = UNSET, .gpiomask = 7, - .muxsel = MUXSEL(2, 3, 0), /* input 2 is digital */ - /* .digital_mode= DIGITAL_MODE_CAMERA, */ + .muxsel = { 2, 3, -1 }, + .digital_mode = DIGITAL_MODE_CAMERA, .gpiomux = { 0, 0, 0, 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ALPS_TSBB5_PAL_I, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x18 ---------------------------------- */ [BTTV_BOARD_MAGICTVIEW061] = { .name = "Askey CPH05X/06X (bt878) [many vendors]", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0xe00, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = {0x400, 0x400, 0x400, 0x400 }, .gpiomute = 0xc00, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_remote = 1, }, [BTTV_BOARD_VOBIS_BOOSTAR] = { .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x1f0fff, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, .gpiomute = 0x40000, .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .audio_mode_gpio= terratv_audio, }, [BTTV_BOARD_HAUPPAUG_WCAM] = { .name = "Hauppauge WinCam newer (bt878)", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 3, .gpiomask = 7, - .muxsel = MUXSEL(2, 0, 1, 1), + .muxsel = { 2, 0, 1, 1 }, .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MAXI] = { .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50", .video_inputs = 4, - /* .audio_inputs= 2, */ + .audio_inputs = 2, + .tuner = 0, .svhs = 2, .gpiomask = 0x1800, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, .gpiomute = 0x1800, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_SECAM, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x1c ---------------------------------- */ [BTTV_BOARD_TERRATV] = { .name = "Terratec TerraTV+ Version 1.1 (bt878)", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x1f0fff, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 }, .gpiomute = 0x40000, .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .audio_mode_gpio= terratv_audio, /* GPIO wiring: External 20 pin connector (for Active Radio Upgrade board) @@ -778,77 +805,87 @@ struct tvcard bttv_tvcards[] = { /* Jannik Fritsch */ .name = "Imagenation PXC200", .video_inputs = 5, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = UNSET, .svhs = 1, /* was: 4 */ .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 0, 0), + .muxsel = { 2, 3, 1, 0, 0}, .gpiomux = { 0 }, .needs_tvaudio = 1, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .muxsel_hook = PXC200_muxsel, }, [BTTV_BOARD_FLYVIDEO_98] = { .name = "Lifeview FlyVideo 98 LR50", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x1800, /* 0x8dfe00 */ - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 0x0800, 0x1000, 0x1000 }, .gpiomute = 0x1800, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_IPROTV] = { .name = "Formac iProTV, Formac ProTV I (bt848)", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 3, .gpiomask = 1, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 1, 0, 0, 0 }, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x20 ---------------------------------- */ [BTTV_BOARD_INTEL_C_S_PCI] = { .name = "Intel Create and Share PCI/ Smart Video Recorder III", .video_inputs = 4, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, .svhs = 2, .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0 }, .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_TERRATVALUE] = { .name = "Terratec TerraTValue Version Bt878", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0xffff00, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0x500, 0, 0x300, 0x900 }, .gpiomute = 0x900, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_WINFAST2000] = { .name = "Leadtek WinFast 2000/ WinFast 2000 XP", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, - /* TV, CVid, SVid, CVid over SVid connector */ - .muxsel = MUXSEL(2, 3, 1, 1, 0), + .muxsel = { 2, 3, 1, 1, 0 }, /* TV, CVid, SVid, CVid over SVid connector */ /* Alexander Varakin [stereo version] */ .gpiomask = 0xb33000, .gpiomux = { 0x122000,0x1000,0x0000,0x620000 }, @@ -869,191 +906,217 @@ struct tvcard bttv_tvcards[] = { .has_radio = 1, .tuner_type = TUNER_PHILIPS_PAL, /* default for now, gpio reads BFFF06 for Pal bg+dk */ .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .audio_mode_gpio= winfast2000_audio, .has_remote = 1, }, [BTTV_BOARD_CHRONOS_VS2] = { .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II", .video_inputs = 4, - /* .audio_inputs= 3, */ + .audio_inputs = 3, + .tuner = 0, .svhs = 2, .gpiomask = 0x1800, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, .gpiomute = 0x1800, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x24 ---------------------------------- */ [BTTV_BOARD_TYPHOON_TVIEW] = { .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner", .video_inputs = 4, - /* .audio_inputs= 3, */ + .audio_inputs = 3, + .tuner = 0, .svhs = 2, .gpiomask = 0x1800, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, .gpiomute = 0x1800, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_radio = 1, }, [BTTV_BOARD_PXELVWPLTVPRO] = { .name = "Prolink PixelView PlayTV pro", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0xff, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0x21, 0x20, 0x24, 0x2c }, .gpiomute = 0x29, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MAGICTVIEW063] = { .name = "Askey CPH06X TView99", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x551e00, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, .gpiomux = { 0x551400, 0x551200, 0, 0 }, .gpiomute = 0x551c00, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_remote = 1, }, [BTTV_BOARD_PINNACLE] = { .name = "Pinnacle PCTV Studio/Rave", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x03000F, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 2, 0xd0001, 0, 0 }, .gpiomute = 1, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x28 ---------------------------------- */ [BTTV_BOARD_STB2] = { .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 7, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 4, 0, 2, 3 }, .gpiomute = 1, .no_msp34xx = 1, .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, }, [BTTV_BOARD_AVPHONE98] = { .name = "AVerMedia TVPhone 98", .video_inputs = 3, - /* .audio_inputs= 4, */ + .audio_inputs = 4, + .tuner = 0, .svhs = 2, .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 13, 4, 11, 7 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_radio = 1, .audio_mode_gpio= avermedia_tvphone_audio, }, [BTTV_BOARD_PV951] = { .name = "ProVideo PV951", /* pic16c54 */ .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1}, .gpiomux = { 0, 0, 0, 0}, .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_ONAIR_TV] = { .name = "Little OnAir TV", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0xe00b, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 }, .gpiomute = 0xff3ffc, .no_msp34xx = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x2c ---------------------------------- */ [BTTV_BOARD_SIGMA_TVII_FM] = { .name = "Sigma TVII-FM", .video_inputs = 2, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, + .audio_inputs = 1, + .tuner = 0, + .svhs = UNSET, .gpiomask = 3, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 1, 1, 0, 2 }, .gpiomute = 3, .no_msp34xx = 1, .pll = PLL_NONE, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MATRIX_VISION2] = { .name = "MATRIX-Vision MV-Delta 2", .video_inputs = 5, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = UNSET, .svhs = 3, .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 0, 0), + .muxsel = { 2, 3, 1, 0, 0 }, .gpiomux = { 0 }, .no_msp34xx = 1, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_ZOLTRIX_GENIE] = { .name = "Zoltrix Genie TV/FM", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0xbcf03f, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0 }, .gpiomute = 0xbcb03f, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4039FR5_NTSC, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_TERRATVRADIO] = { .name = "Terratec TV/Radio+", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x70000, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, .gpiomute = 0x40000, .needs_tvaudio = 1, @@ -1061,6 +1124,7 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_35, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_radio = 1, }, @@ -1068,46 +1132,51 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_DYNALINK] = { .name = "Askey CPH03x/ Dynalink Magic TView", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = {2,0,0,0 }, .gpiomute = 1, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_GVBCTV3PCI] = { .name = "IODATA GV-BCTV3/PCI", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x010f00, - .muxsel = MUXSEL(2, 3, 0, 0), + .muxsel = {2, 3, 0, 0 }, .gpiomux = {0x10000, 0, 0x10000, 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ALPS_TSHC6_NTSC, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .audio_mode_gpio= gvbctv3pci_audio, }, [BTTV_BOARD_PXELVWPLTVPAK] = { .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP", .video_inputs = 5, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 3, - .has_dig_in = 1, .gpiomask = 0xAA0000, - .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */ - /* .digital_mode= DIGITAL_MODE_CAMERA, */ + .muxsel = { 2,3,1,1,-1 }, + .digital_mode = DIGITAL_MODE_CAMERA, .gpiomux = { 0x20000, 0, 0x80000, 0x80000 }, .gpiomute = 0xa8000, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_remote = 1, /* GPIO wiring: (different from Rev.4C !) GPIO17: U4.A0 (first hef4052bt) @@ -1122,15 +1191,17 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_EAGLE] = { .name = "Eagle Wireless Capricorn2 (bt878A)", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 7, - .muxsel = MUXSEL(2, 0, 1, 1), + .muxsel = { 2, 0, 1, 1 }, .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, .pll = PLL_28, .tuner_type = UNSET /* TUNER_ALPS_TMDH2_NTSC */, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x34 ---------------------------------- */ @@ -1138,10 +1209,11 @@ struct tvcard bttv_tvcards[] = { /* David Härdeman */ .name = "Pinnacle PCTV Studio Pro", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 3, .gpiomask = 0x03000F, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 1, 0xd0001, 0, 0 }, .gpiomute = 10, /* sound path (5 sources): @@ -1157,22 +1229,25 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_TVIEW_RDS_FM] = { /* Claas Langbehn , Sven Grothklags */ .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS", .video_inputs = 4, - /* .audio_inputs= 3, */ + .audio_inputs = 3, + .tuner = 0, .svhs = 2, .gpiomask = 0x1c, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 0, 0x10, 8 }, .gpiomute = 4, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_radio = 1, }, [BTTV_BOARD_LIFETEC_9415] = { @@ -1183,10 +1258,11 @@ struct tvcard bttv_tvcards[] = { options tuner type=5 */ .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x18e0, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0x0000,0x0800,0x1000,0x1000 }, .gpiomute = 0x18e0, /* For cards with tda9820/tda9821: @@ -1196,22 +1272,25 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_BESTBUY_EASYTV] = { /* Miguel Angel Alvarez old Easy TV BT848 version (model CPH031) */ .name = "Askey CPH031/ BESTBUY Easy TV", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0xF, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x38 ---------------------------------- */ @@ -1219,15 +1298,17 @@ struct tvcard bttv_tvcards[] = { /* Gordon Heydon */ .name = "Askey CPH060/ Phoebe TV Master Only (No FM)", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0xe00, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1}, .gpiomux = { 0x400, 0x400, 0x400, 0x400 }, .gpiomute = 0x800, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4036FY5_NTSC, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_ASKEY_CPH03X] = { /* Matti Mottus */ .name = "Askey CPH03x TV Capturer", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x03000F, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 1, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x3c ---------------------------------- */ @@ -1281,30 +1368,34 @@ struct tvcard bttv_tvcards[] = { /* Philip Blundell */ .name = "Modular Technology MM100PCTV", .video_inputs = 2, - /* .audio_inputs= 2, */ - .svhs = NO_SVHS, + .audio_inputs = 2, + .tuner = 0, + .svhs = UNSET, .gpiomask = 11, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 2, 0, 0, 1 }, .gpiomute = 8, .pll = PLL_35, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_GMV1] = { /* Adrian Cox @@ -1312,30 +1403,34 @@ struct tvcard bttv_tvcards[] = { special thanks to Informatica Mieres for providing the card */ .name = "Askey CPH061/ BESTBUY Easy TV (bt878)", .video_inputs = 3, - /* .audio_inputs= 2, */ + .audio_inputs = 2, + .tuner = 0, .svhs = 2, .gpiomask = 0xFF, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, .gpiomux = { 1, 0, 4, 4 }, .gpiomute = 9, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_ATI_TVWONDER] = { /* Lukas Gebauer */ .name = "ATI TV-Wonder", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0xf03f, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, .gpiomux = { 0xbffe, 0, 0xbfff, 0 }, .gpiomute = 0xbffe, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x40 ---------------------------------- */ @@ -1343,24 +1438,27 @@ struct tvcard bttv_tvcards[] = { /* Lukas Gebauer */ .name = "ATI TV-Wonder VE", .video_inputs = 2, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, + .audio_inputs = 1, + .tuner = 0, + .svhs = UNSET, .gpiomask = 1, - .muxsel = MUXSEL(2, 3, 0, 1), + .muxsel = { 2, 3, 0, 1 }, .gpiomux = { 0, 0, 1, 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_FLYVIDEO2000] = { /* DeeJay */ .name = "IODATA GV-BCTV4/PCI", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x010f00, - .muxsel = MUXSEL(2, 3, 0, 0), + .muxsel = {2, 3, 0, 0 }, .gpiomux = {0x10000, 0, 0x10000, 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_SHARP_2U5JF5540_NTSC, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .audio_mode_gpio= gvbctv3pci_audio, }, @@ -1411,8 +1514,9 @@ struct tvcard bttv_tvcards[] = { /* try "insmod msp3400 simple=0" if you have * sound problems with this card. */ .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, + .audio_inputs = 1, + .tuner = 0, + .svhs = UNSET, .gpiomask = 0x4f8a00, /* 0x100000: 1=MSP enabled (0=disable again) * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */ @@ -1420,9 +1524,10 @@ struct tvcard bttv_tvcards[] = { .gpiomute = 0x947fff, /* tvtuner, radio, external,internal, mute, stereo * tuner, Composit, SVid, Composit-on-Svid-adapter */ - .muxsel = MUXSEL(2, 3, 0, 1), + .muxsel = { 2, 3 ,0 ,1 }, .tuner_type = TUNER_MT2032, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, }, @@ -1431,8 +1536,9 @@ struct tvcard bttv_tvcards[] = { /* try "insmod msp3400 simple=0" if you have * sound problems with this card. */ .video_inputs = 4, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, + .audio_inputs = 1, + .tuner = 0, + .svhs = UNSET, .gpiomask = 0x4f8a00, /* 0x100000: 1=MSP enabled (0=disable again) * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */ @@ -1440,9 +1546,10 @@ struct tvcard bttv_tvcards[] = { .gpiomute = 0x947fff, /* tvtuner, radio, external,internal, mute, stereo * tuner, Composit, SVid, Composit-on-Svid-adapter */ - .muxsel = MUXSEL(2, 3, 0, 1), + .muxsel = { 2, 3 ,0 ,1 }, .tuner_type = TUNER_MT2032, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, }, @@ -1450,27 +1557,31 @@ struct tvcard bttv_tvcards[] = { /* Philip Blundell */ .name = "Active Imaging AIMMS", .video_inputs = 1, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, + .audio_inputs = 0, + .tuner = UNSET, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .pll = PLL_28, - .muxsel = MUXSEL(2), + .muxsel = { 2 }, .gpiomask = 0 }, [BTTV_BOARD_PV_BT878P_PLUS] = { /* Tomasz Pyra */ .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)", .video_inputs = 3, - /* .audio_inputs= 4, */ + .audio_inputs = 4, + .tuner = 0, .svhs = 2, .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */ .gpiomute = 13, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_LG_PAL_I_FM, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_remote = 1, /* GPIO wiring: GPIO0: U4.A0 (hef4052bt) @@ -1483,14 +1594,15 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_FLYVIDEO98EZ] = { .name = "Lifeview FlyVideo 98EZ (capture only) LR51", .video_inputs = 4, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, .svhs = 2, - /* AV1, AV2, SVHS, CVid adapter on SVHS */ - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, /* AV1, AV2, SVHS, CVid adapter on SVHS */ .pll = PLL_28, .no_msp34xx = 1, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x48 ---------------------------------- */ @@ -1498,10 +1610,11 @@ struct tvcard bttv_tvcards[] = { /* Dariusz Kowalewski */ .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x3f, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0x01, 0x00, 0x03, 0x03 }, .gpiomute = 0x09, .needs_tvaudio = 1, @@ -1510,6 +1623,7 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .audio_mode_gpio= pvbt878p9b_audio, /* Note: not all cards have stereo */ .has_radio = 1, /* Note: not all cards have radio */ .has_remote = 1, @@ -1526,42 +1640,49 @@ struct tvcard bttv_tvcards[] = { /* you must jumper JP5 for the card to work */ .name = "Sensoray 311", .video_inputs = 5, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, .svhs = 4, .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 0, 0), + .muxsel = { 2, 3, 1, 0, 0 }, .gpiomux = { 0 }, .needs_tvaudio = 0, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_RV605] = { /* Miguel Freitas */ .name = "RemoteVision MX (RV605)", .video_inputs = 16, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, .gpiomask = 0x00, .gpiomask2 = 0x07ff, - .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3), + .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03, + 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 }, .no_msp34xx = 1, .no_tda9875 = 1, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .muxsel_hook = rv605_muxsel, }, [BTTV_BOARD_POWERCLR_MTV878] = { .name = "Powercolor MTV878/ MTV878R/ MTV878F", .video_inputs = 3, - /* .audio_inputs= 2, */ + .audio_inputs = 2, + .tuner = 0, .svhs = 2, .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */ - .muxsel = MUXSEL(2, 1, 1), + .muxsel = { 2, 1, 1, }, .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 4, .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, }, @@ -1571,38 +1692,42 @@ struct tvcard bttv_tvcards[] = { /* Masaki Suzuki */ .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x140007, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .audio_mode_gpio= windvr_audio, }, [BTTV_BOARD_GRANDTEC_MULTI] = { .name = "GrandTec Multi Capture Card (Bt878)", .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, .gpiomux = { 0 }, .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_KWORLD] = { .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", .video_inputs = 4, - /* .audio_inputs= 3, */ + .audio_inputs = 3, + .tuner = 0, .svhs = 2, .gpiomask = 7, - /* Tuner, SVid, SVHS, SVid to SVHS connector */ - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */ .gpiomux = { 0, 0, 4, 4 },/* Yes, this tuner uses the same audio output for TV and FM radio! * This card lacks external Audio In, so we mute it on Ext. & Int. * The PCB can take a sbx1637/sbx1673, wiring unknown. @@ -1616,6 +1741,7 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and radio signal strength indicators work fine. */ .has_radio = 1, @@ -1633,24 +1759,27 @@ struct tvcard bttv_tvcards[] = { /* Arthur Tetzlaff-Deas, DSP Design Ltd */ .name = "DSP Design TCVIDEO", .video_inputs = 4, - .svhs = NO_SVHS, - .muxsel = MUXSEL(2, 3, 1, 0), + .svhs = UNSET, + .muxsel = { 2, 3, 1, 0 }, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x50 ---------------------------------- */ [BTTV_BOARD_HAUPPAUGEPVR] = { .name = "Hauppauge WinTV PVR", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, - .muxsel = MUXSEL(2, 0, 1, 1), + .muxsel = { 2, 0, 1, 1 }, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .gpiomask = 7, .gpiomux = {7}, @@ -1658,28 +1787,32 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_GVBCTV5PCI] = { .name = "IODATA GV-BCTV5/PCI", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x0f0f80, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = {2, 3, 1, 0 }, .gpiomux = {0x030000, 0x010000, 0, 0 }, .gpiomute = 0x020000, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC_M, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .audio_mode_gpio= gvbctv5pci_audio, .has_radio = 1, }, [BTTV_BOARD_OSPREY1x0] = { .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ .video_inputs = 4, /* id-inputs-clock */ - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, .svhs = 3, - .muxsel = MUXSEL(3, 2, 0, 1), + .muxsel = { 3, 2, 0, 1 }, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1687,12 +1820,14 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY1x0_848] = { .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ .video_inputs = 3, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, .svhs = 2, - .muxsel = MUXSEL(2, 3, 1), + .muxsel = { 2, 3, 1 }, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1702,12 +1837,14 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY101_848] = { .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */ .video_inputs = 2, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, .svhs = 1, - .muxsel = MUXSEL(3, 1), + .muxsel = { 3, 1 }, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1715,12 +1852,14 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY1x1] = { .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ .video_inputs = 1, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .muxsel = MUXSEL(0), + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, + .muxsel = { 0 }, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1728,12 +1867,14 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY1x1_SVID] = { .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ .video_inputs = 2, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, .svhs = 1, - .muxsel = MUXSEL(0, 1), + .muxsel = { 0, 1 }, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1741,12 +1882,14 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY2xx] = { .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ .video_inputs = 1, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, - .muxsel = MUXSEL(0), + .audio_inputs = 1, + .tuner = UNSET, + .svhs = UNSET, + .muxsel = { 0 }, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1756,12 +1899,14 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY2x0_SVID] = { .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ .video_inputs = 2, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = UNSET, .svhs = 1, - .muxsel = MUXSEL(0, 1), + .muxsel = { 0, 1 }, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1769,12 +1914,14 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY2x0] = { .name = "Osprey 210/220/230", /* 0x1(A|B)-04C0-C1 */ .video_inputs = 2, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = UNSET, .svhs = 1, - .muxsel = MUXSEL(2, 3), + .muxsel = { 2, 3 }, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1782,12 +1929,14 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY500] = { .name = "Osprey 500", /* 500 */ .video_inputs = 2, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = UNSET, .svhs = 1, - .muxsel = MUXSEL(2, 3), + .muxsel = { 2, 3 }, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1795,10 +1944,12 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY540] = { .name = "Osprey 540", /* 540 */ .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = UNSET, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -1808,12 +1959,14 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY2000] = { .name = "Osprey 2000", /* 2000 */ .video_inputs = 2, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = UNSET, .svhs = 1, - .muxsel = MUXSEL(2, 3), + .muxsel = { 2, 3 }, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */ @@ -1822,12 +1975,14 @@ struct tvcard bttv_tvcards[] = { /* M G Berberich */ .name = "IDS Eagle", .video_inputs = 4, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, + .audio_inputs = 0, + .tuner = UNSET, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, + .radio_addr = ADDR_UNSET, + .svhs = UNSET, .gpiomask = 0, - .muxsel = MUXSEL(2, 2, 2, 2), + .muxsel = { 0, 1, 2, 3 }, .muxsel_hook = eagle_muxsel, .no_msp34xx = 1, .no_tda9875 = 1, @@ -1836,14 +1991,16 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_PINNACLESAT] = { .name = "Pinnacle PCTV Sat", .video_inputs = 2, - /* .audio_inputs= 0, */ + .audio_inputs = 0, .svhs = 1, - .tuner_type = TUNER_ABSENT, + .tuner = UNSET, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, - .muxsel = MUXSEL(3, 1), + .muxsel = { 3, 1 }, .pll = PLL_28, .no_gpioirq = 1, .has_dvb = 1, @@ -1851,16 +2008,18 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_FORMAC_PROTV] = { .name = "Formac ProTV II (bt878)", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 3, .gpiomask = 2, /* TV, Comp1, Composite over SVID con, SVID */ - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 2, 2, 0, 0 }, .pll = PLL_28, .has_radio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, /* sound routing: GPIO=0x00,0x01,0x03: mute (?) 0x02: both TV and radio (tuner: FM1216/I) @@ -1874,55 +2033,62 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_MACHTV] = { .name = "MachTV", .video_inputs = 3, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, + .audio_inputs = 1, + .tuner = 0, + .svhs = UNSET, .gpiomask = 7, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1}, .gpiomux = { 0, 1, 2, 3}, .gpiomute = 4, .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .pll = PLL_28, }, [BTTV_BOARD_EURESYS_PICOLO] = { .name = "Euresys Picolo", .video_inputs = 3, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, .svhs = 2, .gpiomask = 0, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, - .muxsel = MUXSEL(2, 0, 1), + .muxsel = { 2, 0, 1}, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_PV150] = { /* Luc Van Hoeylandt */ .name = "ProVideo PV150", /* 0x4f */ .video_inputs = 2, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, .gpiomask = 0, - .muxsel = MUXSEL(2, 3), + .muxsel = { 2, 3 }, .gpiomux = { 0 }, .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_AD_TVK503] = { /* Hiroshi Takekawa */ /* This card lacks subsystem ID */ .name = "AD-TVK503", /* 0x63 */ .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x001e8007, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, /* Tuner, Radio, external, internal, off, on */ .gpiomux = { 0x08, 0x0f, 0x0a, 0x08 }, .gpiomute = 0x0f, @@ -1931,6 +2097,7 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .audio_mode_gpio= adtvk503_audio, }, @@ -1938,15 +2105,17 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_HERCULES_SM_TV] = { .name = "Hercules Smart TV Stereo", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x00, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, /* Notes: - card lacks subsystem ID - stereo variant w/ daughter board with tda9874a @0xb0 @@ -1960,15 +2129,16 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_PACETV] = { .name = "Pace TV & Radio Card", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, - /* Tuner, CVid, SVid, CVid over SVid connector */ - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, /* Tuner, CVid, SVid, CVid over SVid connector */ .gpiomask = 0, .no_tda9875 = 1, .no_tda7432 = 1, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_radio = 1, .pll = PLL_28, /* Bt878, Bt832, FI1246 tuner; no pci subsystem id @@ -1982,34 +2152,27 @@ struct tvcard bttv_tvcards[] = { /* Chris Willing */ .name = "IVC-200", .video_inputs = 1, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, + .audio_inputs = 0, + .tuner = UNSET, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, - .gpiomask = 0xdf, - .muxsel = MUXSEL(2), - .pll = PLL_28, - }, - [BTTV_BOARD_IVCE8784] = { - .name = "IVCE-8784", - .video_inputs = 1, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, + .radio_addr = ADDR_UNSET, + .svhs = UNSET, .gpiomask = 0xdf, - .muxsel = MUXSEL(2), + .muxsel = { 2 }, .pll = PLL_28, }, [BTTV_BOARD_XGUARD] = { .name = "Grand X-Guard / Trust 814PCI", .video_inputs = 16, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .gpiomask2 = 0xff, - .muxsel = MUXSEL(2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0), + .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 }, .muxsel_hook = xguard_muxsel, .no_msp34xx = 1, .no_tda9875 = 1, @@ -2021,14 +2184,16 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_NEBULA_DIGITV] = { .name = "Nebula Electronics DigiTV", .video_inputs = 1, - .svhs = NO_SVHS, - .muxsel = MUXSEL(2, 3, 1, 0), + .tuner = UNSET, + .svhs = UNSET, + .muxsel = { 2, 3, 1, 0 }, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_dvb = 1, .has_remote = 1, .gpiomask = 0x1b, @@ -2038,101 +2203,118 @@ struct tvcard bttv_tvcards[] = { /* Jorge Boncompte - DTI2 */ .name = "ProVideo PV143", .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, .gpiomask = 0, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, .gpiomux = { 0 }, .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_VD009X1_VD011_MINIDIN] = { /* M.Klahr@phytec.de */ .name = "PHYTEC VD-009-X1 VD-011 MiniDIN (bt878)", .video_inputs = 4, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, /* card has no tuner */ .svhs = 3, .gpiomask = 0x00, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_VD009X1_VD011_COMBI] = { .name = "PHYTEC VD-009-X1 VD-011 Combi (bt878)", .video_inputs = 4, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, /* card has no tuner */ .svhs = 3, .gpiomask = 0x00, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x6c ---------------------------------- */ [BTTV_BOARD_VD009_MINIDIN] = { .name = "PHYTEC VD-009 MiniDIN (bt878)", .video_inputs = 10, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, /* card has no tuner */ .svhs = 9, .gpiomask = 0x00, - .gpiomask2 = 0x03, /* used for external vodeo mux */ - .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 0), - .muxsel_hook = phytec_muxsel, + .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio + via the upper nibble of muxsel. here: used for + xternal video-mux */ + .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 }, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 1, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_VD009_COMBI] = { .name = "PHYTEC VD-009 Combi (bt878)", .video_inputs = 10, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, /* card has no tuner */ .svhs = 9, .gpiomask = 0x00, - .gpiomask2 = 0x03, /* used for external vodeo mux */ - .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1), - .muxsel_hook = phytec_muxsel, + .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio + via the upper nibble of muxsel. here: used for + xternal video-mux */ + .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 }, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 1, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_IVC100] = { .name = "IVC-100", .video_inputs = 4, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, + .audio_inputs = 0, + .tuner = UNSET, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, + .radio_addr = ADDR_UNSET, + .svhs = UNSET, .gpiomask = 0xdf, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, .pll = PLL_28, }, [BTTV_BOARD_IVC120] = { /* IVC-120G - Alan Garfield */ .name = "IVC-120G", .video_inputs = 16, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, + .audio_inputs = 0, /* card has no audio */ + .tuner = UNSET, /* card has no tuner */ + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, /* card has no svhs */ + .radio_addr = ADDR_UNSET, + .svhs = UNSET, /* card has no svhs */ .needs_tvaudio = 0, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, .gpiomask = 0x00, - .muxsel = MUXSEL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), + .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }, .muxsel_hook = ivc120_muxsel, .pll = PLL_28, }, @@ -2141,11 +2323,13 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_PC_HDTV] = { .name = "pcHDTV HD-2000 TV", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, .tuner_type = TUNER_PHILIPS_FCV1236D, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_dvb = 1, }, [BTTV_BOARD_TWINHAN_DST] = { @@ -2155,34 +2339,38 @@ struct tvcard bttv_tvcards[] = { .no_tda7432 = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_video = 1, .has_dvb = 1, }, [BTTV_BOARD_WINFASTVC100] = { .name = "Winfast VC100", .video_inputs = 3, - /* .audio_inputs= 0, */ + .audio_inputs = 0, .svhs = 1, - /* Vid In, SVid In, Vid over SVid in connector */ - .muxsel = MUXSEL(3, 1, 1, 3), + .tuner = UNSET, + .muxsel = { 3, 1, 1, 3 }, /* Vid In, SVid In, Vid over SVid in connector */ .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .pll = PLL_28, }, [BTTV_BOARD_TEV560] = { .name = "Teppro TEV-560/InterVision IV-560", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 3, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 1, 1, 1, 1 }, .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .pll = PLL_35, }, @@ -2190,12 +2378,14 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_SIMUS_GVC1100] = { .name = "SIMUS GVC1100", .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .tuner_type = TUNER_ABSENT, + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .pll = PLL_28, - .muxsel = MUXSEL(2, 2, 2, 2), + .muxsel = { 2, 2, 2, 2 }, .gpiomask = 0x3F, .muxsel_hook = gvc1100_muxsel, }, @@ -2203,41 +2393,47 @@ struct tvcard bttv_tvcards[] = { /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */ .name = "NGS NGSTV+", .video_inputs = 3, + .tuner = 0, .svhs = 2, .gpiomask = 0x008007, - .muxsel = MUXSEL(2, 3, 0, 0), + .muxsel = { 2, 3, 0, 0 }, .gpiomux = { 0, 0, 0, 0 }, .gpiomute = 0x000003, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_remote = 1, }, [BTTV_BOARD_LMLBT4] = { /* http://linuxmedialabs.com */ .name = "LMLBT4", .video_inputs = 4, /* IN1,IN2,IN3,IN4 */ - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .muxsel = MUXSEL(2, 3, 1, 0), + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, + .muxsel = { 2, 3, 1, 0 }, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, .needs_tvaudio = 0, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_TEKRAM_M205] = { /* Helmroos Harri */ .name = "Tekram M205 PRO", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .svhs = 2, .needs_tvaudio = 0, .gpiomask = 0x68, - .muxsel = MUXSEL(2, 3, 1), + .muxsel = { 2, 3, 1 }, .gpiomux = { 0x68, 0x68, 0x61, 0x61 }, .pll = PLL_28, }, @@ -2248,16 +2444,18 @@ struct tvcard bttv_tvcards[] = { /* bt878 TV + FM without subsystem ID */ .name = "Conceptronic CONTVFMi", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x008007, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 3, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_remote = 1, .has_radio = 1, }, @@ -2268,34 +2466,37 @@ struct tvcard bttv_tvcards[] = { /*0x79 in bttv.h*/ .name = "Euresys Picolo Tetra", .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, .gpiomask = 0, .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/ .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, - /*878A input is always MUX0, see above.*/ - .muxsel = MUXSEL(2, 2, 2, 2), + .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/ .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .pll = PLL_28, .needs_tvaudio = 0, .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_SPIRIT_TV] = { /* Spirit TV Tuner from http://spiritmodems.com.au */ /* Stafford Goodsell */ .name = "Spirit TV Tuner", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x0000000f, - .muxsel = MUXSEL(2, 1, 1), + .muxsel = { 2, 1, 1 }, .gpiomux = { 0x02, 0x00, 0x00, 0x00 }, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, }, @@ -2304,9 +2505,11 @@ struct tvcard bttv_tvcards[] = { .name = "AVerMedia AVerTV DVB-T 771", .video_inputs = 2, .svhs = 1, + .tuner = UNSET, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, - .muxsel = MUXSEL(3, 3), + .radio_addr = ADDR_UNSET, + .muxsel = { 3 , 3 }, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -2321,47 +2524,54 @@ struct tvcard bttv_tvcards[] = { /* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */ .name = "AverMedia AverTV DVB-T 761", .video_inputs = 2, + .tuner = UNSET, .svhs = 1, - .muxsel = MUXSEL(3, 1, 2, 0), /* Comp0, S-Video, ?, ? */ + .muxsel = { 3, 1, 2, 0 }, /* Comp0, S-Video, ?, ? */ .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_dvb = 1, .no_gpioirq = 1, .has_remote = 1, }, [BTTV_BOARD_MATRIX_VISIONSQ] = { /* andre.schwarz@matrix-vision.de */ - .name = "MATRIX Vision Sigma-SQ", - .video_inputs = 16, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0x0, - .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3), - .muxsel_hook = sigmaSQ_muxsel, - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, + .name = "MATRIX Vision Sigma-SQ", + .video_inputs = 16, + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, + .gpiomask = 0x0, + .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3 }, + .muxsel_hook = sigmaSQ_muxsel, + .gpiomux = { 0 }, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MATRIX_VISIONSLC] = { /* andre.schwarz@matrix-vision.de */ - .name = "MATRIX Vision Sigma-SLC", - .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0x0, - .muxsel = MUXSEL(2, 2, 2, 2), - .muxsel_hook = sigmaSLC_muxsel, - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, + .name = "MATRIX Vision Sigma-SLC", + .video_inputs = 4, + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, + .gpiomask = 0x0, + .muxsel = { 2, 2, 2, 2 }, + .muxsel_hook = sigmaSLC_muxsel, + .gpiomux = { 0 }, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* BTTV_BOARD_APAC_VIEWCOMP */ [BTTV_BOARD_APAC_VIEWCOMP] = { @@ -2369,16 +2579,18 @@ struct tvcard bttv_tvcards[] = { /* bt878 TV + FM 0x00000000 subsystem ID */ .name = "APAC Viewcomp 878(AMAX)", .video_inputs = 2, - /* .audio_inputs= 1, */ - .svhs = NO_SVHS, + .audio_inputs = 1, + .tuner = 0, + .svhs = UNSET, .gpiomask = 0xFF, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */ .has_radio = 1, /* not every card has radio */ }, @@ -2387,40 +2599,46 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_DVICO_DVBT_LITE] = { /* Chris Pascoe */ .name = "DViCO FusionHDTV DVB-T Lite", + .tuner = UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, .pll = PLL_28, .no_video = 1, .has_dvb = 1, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_VGEAR_MYVCD] = { /* Steven */ .name = "V-Gear MyVCD", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x3f, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = {2, 3, 1, 0 }, .gpiomux = {0x31, 0x31, 0x31, 0x31 }, .gpiomute = 0x31, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC_M, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_radio = 0, }, [BTTV_BOARD_SUPER_TV] = { /* Rick C */ .name = "Super TV Tuner", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .gpiomask = 0x008007, .gpiomux = { 0, 0x000001,0,0 }, .needs_tvaudio = 1, @@ -2430,15 +2648,17 @@ struct tvcard bttv_tvcards[] = { /* Chris Fanning */ .name = "Tibet Systems 'Progress DVR' CS16", .video_inputs = 16, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, + .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, .pll = PLL_28, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .muxsel_hook = tibetCS16_muxsel, }, [BTTV_BOARD_KODICOM_4400R] = { @@ -2455,10 +2675,12 @@ struct tvcard bttv_tvcards[] = { */ .name = "Kodicom 4400R (master)", .video_inputs = 16, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, + .audio_inputs = 0, + .tuner = UNSET, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, + .radio_addr = ADDR_UNSET, + .svhs = UNSET, /* GPIO bits 0-9 used for analog switch: * 00 - 03: camera selector * 04 - 06: channel (controller) selector @@ -2469,7 +2691,7 @@ struct tvcard bttv_tvcards[] = { */ .gpiomask = 0x0003ff, .no_gpioirq = 1, - .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3), + .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, .pll = PLL_28, .no_msp34xx = 1, .no_tda7432 = 1, @@ -2485,13 +2707,15 @@ struct tvcard bttv_tvcards[] = { */ .name = "Kodicom 4400R (slave)", .video_inputs = 16, - /* .audio_inputs= 0, */ - .tuner_type = TUNER_ABSENT, + .audio_inputs = 0, + .tuner = UNSET, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, + .radio_addr = ADDR_UNSET, + .svhs = UNSET, .gpiomask = 0x010000, .no_gpioirq = 1, - .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3), + .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, .pll = PLL_28, .no_msp34xx = 1, .no_tda7432 = 1, @@ -2504,23 +2728,27 @@ struct tvcard bttv_tvcards[] = { /* Adlink RTV24 with special unlock codes */ .name = "Adlink RTV24", .video_inputs = 4, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, - .muxsel = MUXSEL(2, 3, 1, 0), + .muxsel = { 2, 3, 1, 0 }, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .pll = PLL_28, }, /* ---- card 0x87---------------------------------- */ [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = { /* Michael Krufky */ .name = "DViCO FusionHDTV 5 Lite", + .tuner = 0, .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */ .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, .svhs = 2, - .muxsel = MUXSEL(2, 3, 1), + .muxsel = { 2, 3, 1 }, .gpiomask = 0x00e00007, .gpiomux = { 0x00400005, 0, 0x00000001, 0 }, .gpiomute = 0x00c00007, @@ -2534,68 +2762,75 @@ struct tvcard bttv_tvcards[] = { /* Mauro Carvalho Chehab */ .name = "Acorp Y878F", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x01fe00, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, .gpiomute = 0x002000, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, .tuner_addr = 0xc1 >>1, + .radio_addr = 0xc1 >>1, .has_radio = 1, }, /* ---- card 0x89 ---------------------------------- */ [BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = { .name = "Conceptronic CTVFMi v2", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x001c0007, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 3, .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TENA_9533_DI, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_remote = 1, .has_radio = 1, }, /* ---- card 0x8a ---------------------------------- */ [BTTV_BOARD_PV_BT878P_2E] = { - .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)", - .video_inputs = 5, - /* .audio_inputs= 1, */ - .svhs = 3, - .has_dig_in = 1, - .gpiomask = 0x01fe00, - .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */ - /* .digital_mode= DIGITAL_MODE_CAMERA, */ - .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 }, - .gpiomute = 0x12400, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_LG_PAL_FM, - .tuner_addr = ADDR_UNSET, - .has_remote = 1, + .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)", + .video_inputs = 5, + .audio_inputs = 1, + .tuner = 0, + .svhs = 3, + .gpiomask = 0x01fe00, + .muxsel = { 2,3,1,1,-1 }, + .digital_mode = DIGITAL_MODE_CAMERA, + .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 }, + .gpiomute = 0x12400, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = TUNER_LG_PAL_FM, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .has_remote = 1, }, /* ---- card 0x8b ---------------------------------- */ [BTTV_BOARD_PV_M4900] = { /* Sérgio Fortier */ .name = "Prolink PixelView PlayTV MPEG2 PV-M4900", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x3f, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0x21, 0x20, 0x24, 0x2c }, .gpiomute = 0x29, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_YMEC_TVF_5533MF, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .has_radio = 1, .has_remote = 1, }, @@ -2615,15 +2850,17 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_OSPREY440] = { .name = "Osprey 440", .video_inputs = 4, - /* .audio_inputs= 2, */ - .svhs = NO_SVHS, - .muxsel = MUXSEL(2, 3, 0, 1), /* 3,0,1 are guesses */ + .audio_inputs = 2, /* this is meaningless */ + .tuner = UNSET, + .svhs = UNSET, + .muxsel = { 2, 3, 0, 1 }, /* 3,0,1 are guesses */ .gpiomask = 0x303, .gpiomute = 0x000, /* int + 32kHz */ .gpiomux = { 0, 0, 0x000, 0x100}, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -2632,25 +2869,28 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_ASOUND_SKYEYE] = { .name = "Asound Skyeye PCTV", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 15, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 1, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x8e ---------------------------------- */ [BTTV_BOARD_SABRENT_TVFM] = { .name = "Sabrent TV-FM (bttv version)", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x108007, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 100000, 100002, 100002, 100000 }, .no_msp34xx = 1, .no_tda9875 = 1, @@ -2664,15 +2904,17 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_HAUPPAUGE_IMPACTVCB] = { .name = "Hauppauge ImpactVCB (bt878)", .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, .gpiomask = 0x0f, /* old: 7 */ - .muxsel = MUXSEL(0, 1, 3, 2), /* Composite 0-3 */ + .muxsel = { 0, 1, 3, 2 }, /* Composite 0-3 */ .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_MACHTV_MAGICTV] = { /* Julian Calaby @@ -2684,14 +2926,16 @@ struct tvcard bttv_tvcards[] = { .name = "MagicTV", /* rebranded MachTV */ .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 7, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, .tuner_type = TUNER_TEMIC_4009FR5_PAL, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, .has_remote = 1, @@ -2699,30 +2943,36 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_SSAI_SECURITY] = { .name = "SSAI Security Video Interface", .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .muxsel = MUXSEL(0, 1, 2, 3), - .tuner_type = TUNER_ABSENT, + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, + .muxsel = { 0, 1, 2, 3 }, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_SSAI_ULTRASOUND] = { .name = "SSAI Ultrasound Video Interface", .video_inputs = 2, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, .svhs = 1, - .muxsel = MUXSEL(2, 0, 1, 3), - .tuner_type = TUNER_ABSENT, + .muxsel = { 2, 0, 1, 3 }, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, /* ---- card 0x94---------------------------------- */ [BTTV_BOARD_DVICO_FUSIONHDTV_2] = { .name = "DViCO FusionHDTV 2", + .tuner = 0, .tuner_type = TUNER_PHILIPS_FCV1236D, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, .svhs = 2, - .muxsel = MUXSEL(2, 3, 1), + .muxsel = { 2, 3, 1 }, .gpiomask = 0x00e00007, .gpiomux = { 0x00400005, 0, 0x00000001, 0 }, .gpiomute = 0x00c00007, @@ -2734,31 +2984,36 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_TYPHOON_TVTUNERPCI] = { .name = "Typhoon TV-Tuner PCI (50684)", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x3014f, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0x20001,0x10001, 0, 0 }, .gpiomute = 10, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_GEOVISION_GV600] = { /* emhn@usb.ve */ - .name = "Geovision GV-600", - .video_inputs = 16, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0x0, - .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), - .muxsel_hook = geovision_muxsel, - .gpiomux = { 0 }, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, + .name = "Geovision GV-600", + .video_inputs = 16, + .audio_inputs = 0, + .tuner = UNSET, + .svhs = UNSET, + .gpiomask = 0x0, + .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2 }, + .muxsel_hook = geovision_muxsel, + .gpiomux = { 0 }, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_KOZUMI_KTV_01C] = { /* Mauro Lacy @@ -2766,15 +3021,17 @@ struct tvcard bttv_tvcards[] = { .name = "Kozumi KTV-01C", .video_inputs = 3, - /* .audio_inputs= 1, */ + .audio_inputs = 1, + .tuner = 0, .svhs = 2, .gpiomask = 0x008007, - .muxsel = MUXSEL(2, 3, 1, 1), + .muxsel = { 2, 3, 1, 1 }, .gpiomux = { 0, 1, 2, 2 }, /* CONTVFMi */ .gpiomute = 3, /* CONTVFMi */ .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */ .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, .has_remote = 1, @@ -2784,7 +3041,8 @@ struct tvcard bttv_tvcards[] = { Mauro Carvalho Chehab IR disabled bit 18/17 = 00 -> mute @@ -2793,11 +3051,12 @@ struct tvcard bttv_tvcards[] = { 11 -> internal audio input */ .gpiomask = 0x060040, - .muxsel = MUXSEL(2, 3, 3), + .muxsel = { 2, 3, 3 }, .gpiomux = { 0x60000, 0x60000, 0x20000, 0x20000 }, .gpiomute = 0, .tuner_type = TUNER_TCL_MF02GIP_5N, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, .pll = PLL_28, .has_radio = 1, .has_remote = 1, @@ -2806,111 +3065,50 @@ struct tvcard bttv_tvcards[] = { /* D.Heer@Phytec.de */ .name = "PHYTEC VD-012 (bt878)", .video_inputs = 4, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, + .audio_inputs = 0, + .tuner = UNSET, /* card has no tuner */ + .svhs = UNSET, /* card has no s-video */ .gpiomask = 0x00, - .muxsel = MUXSEL(0, 2, 3, 1), + .muxsel = { 0, 2, 3, 1 }, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_VD012_X1] = { /* D.Heer@Phytec.de */ .name = "PHYTEC VD-012-X1 (bt878)", .video_inputs = 4, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, /* card has no tuner */ .svhs = 3, .gpiomask = 0x00, - .muxsel = MUXSEL(2, 3, 1), + .muxsel = { 2, 3, 1 }, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, }, [BTTV_BOARD_VD012_X2] = { /* D.Heer@Phytec.de */ .name = "PHYTEC VD-012-X2 (bt878)", .video_inputs = 4, - /* .audio_inputs= 0, */ + .audio_inputs = 0, + .tuner = UNSET, /* card has no tuner */ .svhs = 3, .gpiomask = 0x00, - .muxsel = MUXSEL(3, 2, 1), + .muxsel = { 3, 2, 1 }, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 0, .pll = PLL_28, - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - }, - [BTTV_BOARD_GEOVISION_GV800S] = { - /* Bruno Christo - * - * GeoVision GV-800(S) has 4 Conexant Fusion 878A: - * 1 audio input per BT878A = 4 audio inputs - * 4 video inputs per BT878A = 16 video inputs - * This is the first BT878A chip of the GV-800(S). It's the - * "master" chip and it controls the video inputs through an - * analog multiplexer (a CD22M3494) via some GPIO pins. The - * slaves should use card type 0x9e (following this one). - * There is a EEPROM on the card which is currently not handled. - * The audio input is not working yet. - */ - .name = "Geovision GV-800(S) (master)", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, - .gpiomask = 0xf107f, - .no_gpioirq = 1, - .muxsel = MUXSEL(2, 2, 2, 2), - .pll = PLL_28, - .no_msp34xx = 1, - .no_tda7432 = 1, - .no_tda9875 = 1, - .muxsel_hook = gv800s_muxsel, - }, - [BTTV_BOARD_GEOVISION_GV800S_SL] = { - /* Bruno Christo - * - * GeoVision GV-800(S) has 4 Conexant Fusion 878A: - * 1 audio input per BT878A = 4 audio inputs - * 4 video inputs per BT878A = 16 video inputs - * The 3 other BT878A chips are "slave" chips of the GV-800(S) - * and should use this card type. - * The audio input is not working yet. - */ - .name = "Geovision GV-800(S) (slave)", - .video_inputs = 4, - /* .audio_inputs= 1, */ - .tuner_type = TUNER_ABSENT, - .tuner_addr = ADDR_UNSET, - .svhs = NO_SVHS, - .gpiomask = 0x00, - .no_gpioirq = 1, - .muxsel = MUXSEL(2, 2, 2, 2), - .pll = PLL_28, - .no_msp34xx = 1, - .no_tda7432 = 1, - .no_tda9875 = 1, - .muxsel_hook = gv800s_muxsel, - }, - [BTTV_BOARD_PV183] = { - .name = "ProVideo PV183", /* 0x9f */ - .video_inputs = 2, - /* .audio_inputs= 0, */ - .svhs = NO_SVHS, - .gpiomask = 0, - .muxsel = MUXSEL(2, 3), - .gpiomux = { 0 }, - .needs_tvaudio = 0, - .no_msp34xx = 1, - .pll = PLL_28, - .tuner_type = TUNER_ABSENT, + .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, - }, + .radio_addr = ADDR_UNSET, + } }; static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); @@ -2954,7 +3152,7 @@ void __devinit bttv_idcard(struct bttv *btv) btv->c.nr, btv->cardid & 0xffff, (btv->cardid >> 16) & 0xffff); printk(KERN_DEBUG "please mail id, board name and " - "the correct card= insmod option to linux-media@vger.kernel.org\n"); + "the correct card= insmod option to video4linux-list@redhat.com\n"); } } @@ -3205,7 +3403,8 @@ static void init_ids_eagle(struct bttv *btv) * has its own multiplexer */ static void eagle_muxsel(struct bttv *btv, unsigned int input) { - gpio_bits(3, input & 3); + btaor((2)<<5, ~(3<<5), BT848_IFORM); + gpio_bits(3,bttv_tvcards[btv->c.type].muxsel[input&7]); /* composite */ /* set chroma ADC to sleep */ @@ -3324,17 +3523,6 @@ void __devinit bttv_init_card1(struct bttv *btv) /* initialization part two -- after registering i2c bus */ void __devinit bttv_init_card2(struct bttv *btv) { - static const unsigned short tvaudio_addrs[] = { - I2C_ADDR_TDA8425 >> 1, - I2C_ADDR_TEA6300 >> 1, - I2C_ADDR_TEA6420 >> 1, - I2C_ADDR_TDA9840 >> 1, - I2C_ADDR_TDA985x_L >> 1, - I2C_ADDR_TDA985x_H >> 1, - I2C_ADDR_TDA9874 >> 1, - I2C_ADDR_PIC16C54 >> 1, - I2C_CLIENT_END - }; int addr=ADDR_UNSET; btv->tuner_type = UNSET; @@ -3441,9 +3629,6 @@ void __devinit bttv_init_card2(struct bttv *btv) case BTTV_BOARD_KODICOM_4400R: kodicom4400r_init(btv); break; - case BTTV_BOARD_GEOVISION_GV800S: - gv800s_init(btv); - break; } /* pll configuration */ @@ -3485,12 +3670,13 @@ void __devinit bttv_init_card2(struct bttv *btv) addr = bttv_tvcards[btv->c.type].tuner_addr; if (UNSET != bttv_tvcards[btv->c.type].tuner_type) - if (UNSET == btv->tuner_type) + if(UNSET == btv->tuner_type) btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; if (UNSET != tuner[btv->c.nr]) btv->tuner_type = tuner[btv->c.nr]; - if (btv->tuner_type == TUNER_ABSENT) + if (btv->tuner_type == TUNER_ABSENT || + bttv_tvcards[btv->c.type].tuner == UNSET) printk(KERN_INFO "bttv%d: tuner absent\n", btv->c.nr); else if(btv->tuner_type == UNSET) printk(KERN_WARNING "bttv%d: tuner type unset\n", btv->c.nr); @@ -3498,35 +3684,14 @@ void __devinit bttv_init_card2(struct bttv *btv) printk(KERN_INFO "bttv%d: tuner type=%d\n", btv->c.nr, btv->tuner_type); - if (autoload != UNSET) { - printk(KERN_WARNING "bttv%d: the autoload option is obsolete.\n", btv->c.nr); - printk(KERN_WARNING "bttv%d: use option msp3400, tda7432 or tvaudio to\n", btv->c.nr); - printk(KERN_WARNING "bttv%d: override which audio module should be used.\n", btv->c.nr); - } - - if (UNSET == btv->tuner_type) - btv->tuner_type = TUNER_ABSENT; - - if (btv->tuner_type != TUNER_ABSENT) { + if (btv->tuner_type != UNSET) { struct tuner_setup tun_setup; - /* Load tuner module before issuing tuner config call! */ - if (bttv_tvcards[btv->c.type].has_radio) - v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, - "tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_RADIO)); - v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, "tuner", - "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); - v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, "tuner", - "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); - tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; tun_setup.type = btv->tuner_type; tun_setup.addr = addr; - if (bttv_tvcards[btv->c.type].has_radio) - tun_setup.mode_mask |= T_RADIO; - - bttv_call_all(btv, tuner, s_type_addr, &tun_setup); + bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); } if (btv->tda9887_conf) { @@ -3535,13 +3700,10 @@ void __devinit bttv_init_card2(struct bttv *btv) tda9887_cfg.tuner = TUNER_TDA9887; tda9887_cfg.priv = &btv->tda9887_conf; - bttv_call_all(btv, tuner, s_config, &tda9887_cfg); + bttv_call_i2c_clients(btv, TUNER_SET_CONFIG, &tda9887_cfg); } - btv->dig = bttv_tvcards[btv->c.type].has_dig_in ? - bttv_tvcards[btv->c.type].video_inputs - 1 : UNSET; - btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ? - UNSET : bttv_tvcards[btv->c.type].svhs; + btv->svhs = bttv_tvcards[btv->c.type].svhs; if (svhs[btv->c.nr] != UNSET) btv->svhs = svhs[btv->c.nr]; if (remote[btv->c.nr] != UNSET) @@ -3558,127 +3720,34 @@ void __devinit bttv_init_card2(struct bttv *btv) if (bttv_tvcards[btv->c.type].audio_mode_gpio) btv->audio_mode_gpio=bttv_tvcards[btv->c.type].audio_mode_gpio; - if (btv->tuner_type == TUNER_ABSENT) - return; /* no tuner or related drivers to load */ + if (!autoload) + return; - if (btv->has_saa6588 || saa6588[btv->c.nr]) { - /* Probe for RDS receiver chip */ - static const unsigned short addrs[] = { - 0x20 >> 1, - 0x22 >> 1, - I2C_CLIENT_END - }; - struct v4l2_subdev *sd; - - sd = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, - "saa6588", "saa6588", addrs); - btv->has_saa6588 = (sd != NULL); - } + if (bttv_tvcards[btv->c.type].tuner == UNSET) + return; /* no tuner or related drivers to load */ /* try to detect audio/fader chips */ + if (!bttv_tvcards[btv->c.type].no_msp34xx && + bttv_I2CRead(btv, I2C_ADDR_MSP3400, "MSP34xx") >=0) + request_module("msp3400"); - /* First check if the user specified the audio chip via a module - option. */ - - switch (audiodev[btv->c.nr]) { - case -1: - return; /* do not load any audio module */ - - case 0: /* autodetect */ - break; - - case 1: { - /* The user specified that we should probe for msp3400 */ - static const unsigned short addrs[] = { - I2C_ADDR_MSP3400 >> 1, - I2C_ADDR_MSP3400_ALT >> 1, - I2C_CLIENT_END - }; - - btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, - "msp3400", "msp3400", addrs); - if (btv->sd_msp34xx) - return; - goto no_audio; - } - - case 2: { - /* The user specified that we should probe for tda7432 */ - static const unsigned short addrs[] = { - I2C_ADDR_TDA7432 >> 1, - I2C_CLIENT_END - }; - - if (v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, - "tda7432", "tda7432", addrs)) - return; - goto no_audio; - } - - case 3: { - /* The user specified that we should probe for tvaudio */ - btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, - "tvaudio", "tvaudio", tvaudio_addrs); - if (btv->sd_tvaudio) - return; - goto no_audio; - } - - default: - printk(KERN_WARNING "bttv%d: unknown audiodev value!\n", - btv->c.nr); - return; - } + if (bttv_tvcards[btv->c.type].msp34xx_alt && + bttv_I2CRead(btv, I2C_ADDR_MSP3400_ALT, "MSP34xx (alternate address)") >=0) + request_module("msp3400"); - /* There were no overrides, so now we try to discover this through the - card definition */ - - /* probe for msp3400 first: this driver can detect whether or not - it really is a msp3400, so it will return NULL when the device - found is really something else (e.g. a tea6300). */ - if (!bttv_tvcards[btv->c.type].no_msp34xx) { - static const unsigned short addrs[] = { - I2C_ADDR_MSP3400 >> 1, - I2C_CLIENT_END - }; - - btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, - "msp3400", "msp3400", addrs); - } else if (bttv_tvcards[btv->c.type].msp34xx_alt) { - static const unsigned short addrs[] = { - I2C_ADDR_MSP3400_ALT >> 1, - I2C_CLIENT_END - }; - - btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, - "msp3400", "msp3400", addrs); - } + if (!bttv_tvcards[btv->c.type].no_tda9875 && + bttv_I2CRead(btv, I2C_ADDR_TDA9875, "TDA9875") >=0) + request_module("tda9875"); - /* If we found a msp34xx, then we're done. */ - if (btv->sd_msp34xx) - return; + if (!bttv_tvcards[btv->c.type].no_tda7432 && + bttv_I2CRead(btv, I2C_ADDR_TDA7432, "TDA7432") >=0) + request_module("tda7432"); - /* it might also be a tda7432. */ - if (!bttv_tvcards[btv->c.type].no_tda7432) { - static const unsigned short addrs[] = { - I2C_ADDR_TDA7432 >> 1, - I2C_CLIENT_END - }; + if (bttv_tvcards[btv->c.type].needs_tvaudio) + request_module("tvaudio"); - if (v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, - "tda7432", "tda7432", addrs)) - return; - } - - /* Now see if we can find one of the tvaudio devices. */ - btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, - "tvaudio", "tvaudio", tvaudio_addrs); - if (btv->sd_tvaudio) - return; - -no_audio: - printk(KERN_WARNING "bttv%d: audio absent, no audio device found!\n", - btv->c.nr); + if (btv->tuner_type != UNSET && btv->tuner_type != TUNER_ABSENT) + request_module("tuner"); } @@ -3750,7 +3819,6 @@ static int terratec_active_radio_upgrade(struct bttv *btv) printk("bttv%d: Terratec Active Radio Upgrade found.\n", btv->c.nr); btv->has_radio = 1; - btv->has_saa6588 = 1; btv->has_matchbox = 1; } else { btv->has_radio = 0; @@ -3999,26 +4067,27 @@ static void __devinit avermedia_eeprom(struct bttv *btv) btv->has_remote ? "yes" : "no"); } -/* - * For Voodoo TV/FM and Voodoo 200. These cards' tuners use a TDA9880 - * analog demod, which is not I2C controlled like the newer and more common - * TDA9887 series. Instead is has two tri-state input pins, S0 and S1, - * that control the IF for the video and audio. Apparently, bttv GPIO - * 0x10000 is connected to S0. S0 low selects a 38.9 MHz VIF for B/G/D/K/I - * (i.e., PAL) while high selects 45.75 MHz for M/N (i.e., NTSC). - */ -u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits) +/* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */ +void bttv_tda9880_setnorm(struct bttv *btv, int norm) { - - if (btv->audio == TVAUDIO_INPUT_TUNER) { - if (bttv_tvnorms[btv->tvnorm].v4l2_id & V4L2_STD_MN) - gpiobits |= 0x10000; - else - gpiobits &= ~0x10000; + /* fix up our card entry */ + if(norm==V4L2_STD_NTSC) { + bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff; + bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x957fff; + bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff; + bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomute=0x957fff; + dprintk("bttv_tda9880_setnorm to NTSC\n"); } - - gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpiobits); - return gpiobits; + else { + bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff; + bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x947fff; + bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff; + bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomute=0x947fff; + dprintk("bttv_tda9880_setnorm to PAL\n"); + } + /* set GPIO according */ + gpio_bits(bttv_tvcards[btv->c.type].gpiomask, + bttv_tvcards[btv->c.type].gpiomux[btv->audio]); } @@ -4394,11 +4463,6 @@ void tea5757_set_freq(struct bttv *btv, unsigned short freq) */ static void rv605_muxsel(struct bttv *btv, unsigned int input) { - static const u8 muxgpio[] = { 0x3, 0x1, 0x2, 0x4, 0xf, 0x7, 0xe, 0x0, - 0xd, 0xb, 0xc, 0x6, 0x9, 0x5, 0x8, 0xa }; - - gpio_bits(0x07f, muxgpio[input]); - /* reset all conections */ gpio_bits(0x200,0x200); mdelay(1); @@ -4406,6 +4470,7 @@ static void rv605_muxsel(struct bttv *btv, unsigned int input) mdelay(1); /* create a new connection */ + gpio_bits(0x480,0x080); gpio_bits(0x480,0x480); mdelay(1); gpio_bits(0x480,0x080); @@ -4664,7 +4729,8 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input) bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02, ((matrix == 2) ? 0x03 : 0x00), 1); /* 9-12 */ - /* 878's MUX0 is already selected for input via muxsel values */ + /* Selects MUX0 for input on the 878 */ + btaor((0)<<5, ~(3<<5), BT848_IFORM); } @@ -4748,132 +4814,6 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input) printk(KERN_DEBUG "bttv%d: setting input channel to:%d\n", btv->c.nr,(int)mux); } -static void phytec_muxsel(struct bttv *btv, unsigned int input) -{ - unsigned int mux = input % 4; - - if (input == btv->svhs) - mux = 0; - - gpio_bits(0x3, mux); -} - -/* - * GeoVision GV-800(S) functions - * Bruno Christo -*/ - -/* This is a function to control the analog switch, which determines which - * camera is routed to which controller. The switch comprises an X-address - * (gpio bits 0-3, representing the camera, ranging from 0-15), and a - * Y-address (gpio bits 4-6, representing the controller, ranging from 0-3). - * A data value (gpio bit 18) of '1' enables the switch, and '0' disables - * the switch. A STROBE bit (gpio bit 17) latches the data value into the - * specified address. There is also a chip select (gpio bit 16). - * The idea is to set the address and chip select together, bring - * STROBE high, write the data, and finally bring STROBE back to low. - */ -static void gv800s_write(struct bttv *btv, - unsigned char xaddr, - unsigned char yaddr, - unsigned char data) { - /* On the "master" 878A: - * GPIO bits 0-9 are used for the analog switch: - * 00 - 03: camera selector - * 04 - 06: 878A (controller) selector - * 16: cselect - * 17: strobe - * 18: data (1->on, 0->off) - * 19: reset - */ - const u32 ADDRESS = ((xaddr&0xf) | (yaddr&3)<<4); - const u32 CSELECT = 1<<16; - const u32 STROBE = 1<<17; - const u32 DATA = data<<18; - - gpio_bits(0x1007f, ADDRESS | CSELECT); /* write ADDRESS and CSELECT */ - gpio_bits(0x20000, STROBE); /* STROBE high */ - gpio_bits(0x40000, DATA); /* write DATA */ - gpio_bits(0x20000, ~STROBE); /* STROBE low */ -} - -/* - * GeoVision GV-800(S) muxsel - * - * Each of the 4 cards (controllers) use this function. - * The controller using this function selects the input through the GPIO pins - * of the "master" card. A pointer to this card is stored in master[btv->c.nr]. - * - * The parameter 'input' is the requested camera number (0-4) on the controller. - * The map array has the address of each input. Note that the addresses in the - * array are in the sequence the original GeoVision driver uses, that is, set - * every controller to input 0, then to input 1, 2, 3, repeat. This means that - * the physical "camera 1" connector corresponds to controller 0 input 0, - * "camera 2" corresponds to controller 1 input 0, and so on. - * - * After getting the input address, the function then writes the appropriate - * data to the analog switch, and housekeeps the local copy of the switch - * information. - */ -static void gv800s_muxsel(struct bttv *btv, unsigned int input) -{ - struct bttv *mctlr; - char *sw_status; - int xaddr, yaddr; - static unsigned int map[4][4] = { { 0x0, 0x4, 0xa, 0x6 }, - { 0x1, 0x5, 0xb, 0x7 }, - { 0x2, 0x8, 0xc, 0xe }, - { 0x3, 0x9, 0xd, 0xf } }; - input = input%4; - mctlr = master[btv->c.nr]; - if (mctlr == NULL) { - /* do nothing until the "master" is detected */ - return; - } - yaddr = (btv->c.nr - mctlr->c.nr) & 3; - sw_status = (char *)(&mctlr->mbox_we); - xaddr = map[yaddr][input] & 0xf; - - /* Check if the controller/camera pair has changed, ignore otherwise */ - if (sw_status[yaddr] != xaddr) { - /* disable the old switch, enable the new one and save status */ - gv800s_write(mctlr, sw_status[yaddr], yaddr, 0); - sw_status[yaddr] = xaddr; - gv800s_write(mctlr, xaddr, yaddr, 1); - } -} - -/* GeoVision GV-800(S) "master" chip init */ -static void gv800s_init(struct bttv *btv) -{ - char *sw_status = (char *)(&btv->mbox_we); - int ix; - - gpio_inout(0xf107f, 0xf107f); - gpio_write(1<<19); /* reset the analog MUX */ - gpio_write(0); - - /* Preset camera 0 to the 4 controllers */ - for (ix = 0; ix < 4; ix++) { - sw_status[ix] = ix; - gv800s_write(btv, ix, ix, 1); - } - - /* Inputs on the "master" controller need this brightness fix */ - bttv_I2CWrite(btv, 0x18, 0x5, 0x90, 1); - - if (btv->c.nr > BTTV_MAX-4) - return; - /* - * Store the "master" controller pointer in the master - * array for later use in the muxsel function. - */ - master[btv->c.nr] = btv; - master[btv->c.nr+1] = btv; - master[btv->c.nr+2] = btv; - master[btv->c.nr+3] = btv; -} - /* ----------------------------------------------------------------------- */ /* motherboard chipset specific stuff */ diff --git a/trunk/drivers/media/video/bt8xx/bttv-driver.c b/trunk/drivers/media/video/bt8xx/bttv-driver.c index 7a8ca0d8356f..c71f394fc0ea 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-driver.c +++ b/trunk/drivers/media/video/bt8xx/bttv-driver.c @@ -58,7 +58,7 @@ unsigned int bttv_num; /* number of Bt848s in use */ -struct bttv *bttvs[BTTV_MAX]; +struct bttv bttvs[BTTV_MAX]; unsigned int bttv_debug; unsigned int bttv_verbose = 1; @@ -167,7 +167,7 @@ static ssize_t show_card(struct device *cd, struct device_attribute *attr, char *buf) { struct video_device *vfd = container_of(cd, struct video_device, dev); - struct bttv *btv = video_get_drvdata(vfd); + struct bttv *btv = dev_get_drvdata(vfd->parent); return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET); } static DEVICE_ATTR(card, S_IRUGO, show_card, NULL); @@ -1040,7 +1040,7 @@ static void bt848A_set_timing(struct bttv *btv) int table_idx = bttv_tvnorms[btv->tvnorm].sram; int fsc = bttv_tvnorms[btv->tvnorm].Fsc; - if (btv->input == btv->dig) { + if (UNSET == bttv_tvcards[btv->c.type].muxsel[btv->input]) { dprintk("bttv%d: load digital timing table (table_idx=%d)\n", btv->c.nr,table_idx); @@ -1142,7 +1142,7 @@ video_mux(struct bttv *btv, unsigned int input) btand(~BT848_CONTROL_COMP, BT848_E_CONTROL); btand(~BT848_CONTROL_COMP, BT848_O_CONTROL); } - mux = bttv_muxsel(btv, input); + mux = bttv_tvcards[btv->c.type].muxsel[input] & 3; btaor(mux<<5, ~(3<<5), BT848_IFORM); dprintk(KERN_DEBUG "bttv%d: video mux: input=%d mux=%d\n", btv->c.nr,input,mux); @@ -1163,6 +1163,7 @@ audio_mux(struct bttv *btv, int input, int mute) { int gpio_val, signal; struct v4l2_control ctrl; + struct i2c_client *c; gpio_inout(bttv_tvcards[btv->c.type].gpiomask, bttv_tvcards[btv->c.type].gpiomask); @@ -1179,16 +1180,7 @@ audio_mux(struct bttv *btv, int input, int mute) else gpio_val = bttv_tvcards[btv->c.type].gpiomux[input]; - switch (btv->c.type) { - case BTTV_BOARD_VOODOOTV_FM: - case BTTV_BOARD_VOODOOTV_200: - gpio_val = bttv_tda9880_setnorm(btv, gpio_val); - break; - - default: - gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val); - } - + gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val); if (bttv_gpio) bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]); if (in_interrupt()) @@ -1196,8 +1188,9 @@ audio_mux(struct bttv *btv, int input, int mute) ctrl.id = V4L2_CID_AUDIO_MUTE; ctrl.value = btv->mute; - bttv_call_all(btv, core, s_ctrl, &ctrl); - if (btv->sd_msp34xx) { + bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, &ctrl); + c = btv->i2c_msp34xx_client; + if (c) { struct v4l2_routing route; /* Note: the inputs tuner/radio/extern/intern are translated @@ -1236,14 +1229,15 @@ audio_mux(struct bttv *btv, int input, int mute) break; } route.output = MSP_OUTPUT_DEFAULT; - v4l2_subdev_call(btv->sd_msp34xx, audio, s_routing, &route); + c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route); } - if (btv->sd_tvaudio) { + c = btv->i2c_tvaudio_client; + if (c) { struct v4l2_routing route; route.input = input; route.output = 0; - v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing, &route); + c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route); } return 0; } @@ -1283,7 +1277,7 @@ bttv_crop_calc_limits(struct bttv_crop *c) } static void -bttv_crop_reset(struct bttv_crop *c, unsigned int norm) +bttv_crop_reset(struct bttv_crop *c, int norm) { c->rect = bttv_tvnorms[norm].cropcap.defrect; bttv_crop_calc_limits(c); @@ -1296,13 +1290,16 @@ set_tvnorm(struct bttv *btv, unsigned int norm) const struct bttv_tvnorm *tvnorm; v4l2_std_id id; - BUG_ON(norm >= BTTV_TVNORMS); - BUG_ON(btv->tvnorm >= BTTV_TVNORMS); + if (norm < 0 || norm >= BTTV_TVNORMS) + return -EINVAL; tvnorm = &bttv_tvnorms[norm]; - if (!memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap, - sizeof (tvnorm->cropcap))) { + if (btv->tvnorm < 0 || + btv->tvnorm >= BTTV_TVNORMS || + 0 != memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, + &tvnorm->cropcap, + sizeof (tvnorm->cropcap))) { bttv_crop_reset(&btv->crop[0], norm); btv->crop[1] = btv->crop[0]; /* current = default */ @@ -1325,11 +1322,11 @@ set_tvnorm(struct bttv *btv, unsigned int norm) switch (btv->c.type) { case BTTV_BOARD_VOODOOTV_FM: case BTTV_BOARD_VOODOOTV_200: - bttv_tda9880_setnorm(btv, gpio_read()); + bttv_tda9880_setnorm(btv,norm); break; } id = tvnorm->v4l2_id; - bttv_call_all(btv, tuner, s_std, id); + bttv_call_i2c_clients(btv, VIDIOC_S_STD, &id); return 0; } @@ -1353,8 +1350,8 @@ set_input(struct bttv *btv, unsigned int input, unsigned int norm) } else { video_mux(btv,input); } - audio_input(btv, (btv->tuner_type != TUNER_ABSENT && input == 0) ? - TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN); + audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ? + TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN)); set_tvnorm(btv, norm); } @@ -1473,7 +1470,7 @@ static int bttv_g_ctrl(struct file *file, void *priv, case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_BASS: case V4L2_CID_AUDIO_TREBLE: - bttv_call_all(btv, core, g_ctrl, c); + bttv_call_i2c_clients(btv, VIDIOC_G_CTRL, c); break; case V4L2_CID_PRIVATE_CHROMA_AGC: @@ -1547,12 +1544,12 @@ static int bttv_s_ctrl(struct file *file, void *f, if (btv->volume_gpio) btv->volume_gpio(btv, c->value); - bttv_call_all(btv, core, s_ctrl, c); + bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, c); break; case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_BASS: case V4L2_CID_AUDIO_TREBLE: - bttv_call_all(btv, core, s_ctrl, c); + bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, c); break; case V4L2_CID_PRIVATE_CHROMA_AGC: @@ -1891,15 +1888,20 @@ static int bttv_enum_input(struct file *file, void *priv, { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; - int n; + unsigned int n; + + n = i->index; - if (i->index >= bttv_tvcards[btv->c.type].video_inputs) + if (n >= bttv_tvcards[btv->c.type].video_inputs) return -EINVAL; + memset(i, 0, sizeof(*i)); + + i->index = n; i->type = V4L2_INPUT_TYPE_CAMERA; i->audioset = 1; - if (btv->tuner_type != TUNER_ABSENT && i->index == 0) { + if (i->index == bttv_tvcards[btv->c.type].tuner) { sprintf(i->name, "Television"); i->type = V4L2_INPUT_TYPE_TUNER; i->tuner = 0; @@ -1963,14 +1965,14 @@ static int bttv_s_tuner(struct file *file, void *priv, if (0 != err) return err; - if (btv->tuner_type == TUNER_ABSENT) + if (UNSET == bttv_tvcards[btv->c.type].tuner) return -EINVAL; if (0 != t->index) return -EINVAL; mutex_lock(&btv->lock); - bttv_call_all(btv, tuner, s_tuner, t); + bttv_call_i2c_clients(btv, VIDIOC_S_TUNER, t); if (btv->audio_mode_gpio) btv->audio_mode_gpio(btv, t, 1); @@ -2015,7 +2017,7 @@ static int bttv_s_frequency(struct file *file, void *priv, return -EINVAL; mutex_lock(&btv->lock); btv->freq = f->frequency; - bttv_call_all(btv, tuner, s_frequency, f); + bttv_call_i2c_clients(btv, VIDIOC_S_FREQUENCY, f); if (btv->has_matchbox && btv->radio_user) tea5757_set_freq(btv, btv->freq); mutex_unlock(&btv->lock); @@ -2029,7 +2031,7 @@ static int bttv_log_status(struct file *file, void *f) printk(KERN_INFO "bttv%d: ======== START STATUS CARD #%d ========\n", btv->c.nr, btv->c.nr); - bttv_call_all(btv, core, log_status); + bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL); printk(KERN_INFO "bttv%d: ======== END STATUS CARD #%d ========\n", btv->c.nr, btv->c.nr); return 0; @@ -2657,7 +2659,8 @@ static int bttv_querycap(struct file *file, void *priv, if (no_overlay <= 0) cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; - if (btv->tuner_type != TUNER_ABSENT) + if (bttv_tvcards[btv->c.type].tuner != UNSET && + bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT) cap->capabilities |= V4L2_CAP_TUNER; return 0; } @@ -2924,9 +2927,13 @@ static int bttv_g_parm(struct file *file, void *f, { struct bttv_fh *fh = f; struct bttv *btv = fh->btv; + struct v4l2_standard s; - v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id, - &parm->parm.capture.timeperframe); + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + v4l2_video_std_construct(&s, bttv_tvnorms[btv->tvnorm].v4l2_id, + bttv_tvnorms[btv->tvnorm].name); + parm->parm.capture.timeperframe = s.frameperiod; return 0; } @@ -2936,14 +2943,15 @@ static int bttv_g_tuner(struct file *file, void *priv, struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; - if (btv->tuner_type == TUNER_ABSENT) + if (UNSET == bttv_tvcards[btv->c.type].tuner) return -EINVAL; if (0 != t->index) return -EINVAL; mutex_lock(&btv->lock); + memset(t, 0, sizeof(*t)); t->rxsubchans = V4L2_TUNER_SUB_MONO; - bttv_call_all(btv, tuner, g_tuner, t); + bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t); strcpy(t->name, "Television"); t->capability = V4L2_TUNER_CAP_NORM; t->type = V4L2_TUNER_ANALOG_TV; @@ -3204,19 +3212,29 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) static int bttv_open(struct file *file) { int minor = video_devdata(file)->minor; - struct bttv *btv = video_drvdata(file); + struct bttv *btv = NULL; struct bttv_fh *fh; enum v4l2_buf_type type = 0; + unsigned int i; dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor); lock_kernel(); - if (btv->video_dev->minor == minor) { - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } else if (btv->vbi_dev->minor == minor) { - type = V4L2_BUF_TYPE_VBI_CAPTURE; - } else { - WARN_ON(1); + for (i = 0; i < bttv_num; i++) { + if (bttvs[i].video_dev && + bttvs[i].video_dev->minor == minor) { + btv = &bttvs[i]; + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + break; + } + if (bttvs[i].vbi_dev && + bttvs[i].vbi_dev->minor == minor) { + btv = &bttvs[i]; + type = V4L2_BUF_TYPE_VBI_CAPTURE; + break; + } + } + if (NULL == btv) { unlock_kernel(); return -ENODEV; } @@ -3406,14 +3424,20 @@ static struct video_device bttv_video_template = { static int radio_open(struct file *file) { int minor = video_devdata(file)->minor; - struct bttv *btv = video_drvdata(file); + struct bttv *btv = NULL; struct bttv_fh *fh; + unsigned int i; dprintk("bttv: open minor=%d\n",minor); lock_kernel(); - WARN_ON(btv->radio_dev && btv->radio_dev->minor != minor); - if (!btv->radio_dev || btv->radio_dev->minor != minor) { + for (i = 0; i < bttv_num; i++) { + if (bttvs[i].radio_dev && bttvs[i].radio_dev->minor == minor) { + btv = &bttvs[i]; + break; + } + } + if (NULL == btv) { unlock_kernel(); return -ENODEV; } @@ -3434,7 +3458,7 @@ static int radio_open(struct file *file) btv->radio_user++; - bttv_call_all(btv, tuner, s_radio); + bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL); audio_input(btv,TVAUDIO_INPUT_RADIO); mutex_unlock(&btv->lock); @@ -3454,7 +3478,7 @@ static int radio_release(struct file *file) btv->radio_user--; - bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd); + bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd); return 0; } @@ -3479,15 +3503,16 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; - if (btv->tuner_type == TUNER_ABSENT) + if (UNSET == bttv_tvcards[btv->c.type].tuner) return -EINVAL; if (0 != t->index) return -EINVAL; mutex_lock(&btv->lock); + memset(t, 0, sizeof(*t)); strcpy(t->name, "Radio"); t->type = V4L2_TUNER_RADIO; - bttv_call_all(btv, tuner, g_tuner, t); + bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t); if (btv->audio_mode_gpio) btv->audio_mode_gpio(btv, t, 0); @@ -3529,7 +3554,7 @@ static int radio_s_tuner(struct file *file, void *priv, if (0 != t->index) return -EINVAL; - bttv_call_all(btv, tuner, g_tuner, t); + bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t); return 0; } @@ -3590,7 +3615,7 @@ static ssize_t radio_read(struct file *file, char __user *data, cmd.instance = file; cmd.result = -ENODEV; - bttv_call_all(btv, core, ioctl, RDS_CMD_READ, &cmd); + bttv_call_i2c_clients(btv, RDS_CMD_READ, &cmd); return cmd.result; } @@ -3603,7 +3628,7 @@ static unsigned int radio_poll(struct file *file, poll_table *wait) cmd.instance = file; cmd.event_list = wait; cmd.result = -ENODEV; - bttv_call_all(btv, core, ioctl, RDS_CMD_POLL, &cmd); + bttv_call_i2c_clients(btv, RDS_CMD_POLL, &cmd); return cmd.result; } @@ -3687,14 +3712,14 @@ static void bttv_risc_disasm(struct bttv *btv, unsigned int i,j,n; printk("%s: risc disasm: %p [dma=0x%08lx]\n", - btv->c.v4l2_dev.name, risc->cpu, (unsigned long)risc->dma); + btv->c.name, risc->cpu, (unsigned long)risc->dma); for (i = 0; i < (risc->size >> 2); i += n) { - printk("%s: 0x%lx: ", btv->c.v4l2_dev.name, + printk("%s: 0x%lx: ", btv->c.name, (unsigned long)(risc->dma + (i<<2))); n = bttv_risc_decode(le32_to_cpu(risc->cpu[i])); for (j = 1; j < n; j++) printk("%s: 0x%lx: 0x%08x [ arg #%d ]\n", - btv->c.v4l2_dev.name, (unsigned long)(risc->dma + ((i+j)<<2)), + btv->c.name, (unsigned long)(risc->dma + ((i+j)<<2)), risc->cpu[i+j], j); if (0 == risc->cpu[i]) break; @@ -4170,10 +4195,9 @@ static struct video_device *vdev_init(struct bttv *btv, return NULL; *vfd = *template; vfd->minor = -1; - vfd->v4l2_dev = &btv->c.v4l2_dev; + vfd->parent = &btv->c.pci->dev; vfd->release = video_device_release; vfd->debug = bttv_debug; - video_set_drvdata(vfd, btv); snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", type_name, bttv_tvcards[btv->c.type].name); @@ -4283,14 +4307,10 @@ static int __devinit bttv_probe(struct pci_dev *dev, if (bttv_num == BTTV_MAX) return -ENOMEM; printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num); - bttvs[bttv_num] = btv = kzalloc(sizeof(*btv), GFP_KERNEL); - if (btv == NULL) { - printk(KERN_ERR "bttv: out of memory.\n"); - return -ENOMEM; - } + btv=&bttvs[bttv_num]; + memset(btv,0,sizeof(*btv)); btv->c.nr = bttv_num; - snprintf(btv->c.v4l2_dev.name, sizeof(btv->c.v4l2_dev.name), - "bttv%d", btv->c.nr); + sprintf(btv->c.name,"bttv%d",btv->c.nr); /* initialize structs / fill in defaults */ mutex_init(&btv->lock); @@ -4327,7 +4347,7 @@ static int __devinit bttv_probe(struct pci_dev *dev, } if (!request_mem_region(pci_resource_start(dev,0), pci_resource_len(dev,0), - btv->c.v4l2_dev.name)) { + btv->c.name)) { printk(KERN_WARNING "bttv%d: can't request iomem (0x%llx).\n", btv->c.nr, (unsigned long long)pci_resource_start(dev,0)); @@ -4335,12 +4355,7 @@ static int __devinit bttv_probe(struct pci_dev *dev, } pci_set_master(dev); pci_set_command(dev); - - result = v4l2_device_register(&dev->dev, &btv->c.v4l2_dev); - if (result < 0) { - printk(KERN_WARNING "bttv%d: v4l2_device_register() failed\n", btv->c.nr); - goto fail0; - } + pci_set_drvdata(dev,btv); pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision); pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); @@ -4364,7 +4379,7 @@ static int __devinit bttv_probe(struct pci_dev *dev, /* disable irqs, register irq handler */ btwrite(0, BT848_INT_MASK); result = request_irq(btv->c.pci->irq, bttv_irq, - IRQF_SHARED | IRQF_DISABLED, btv->c.v4l2_dev.name, (void *)btv); + IRQF_SHARED | IRQF_DISABLED,btv->c.name,(void *)btv); if (result < 0) { printk(KERN_ERR "bttv%d: can't get IRQ %d\n", bttv_num,btv->c.pci->irq); @@ -4448,24 +4463,21 @@ static int __devinit bttv_probe(struct pci_dev *dev, bttv_num++; return 0; -fail2: + fail2: free_irq(btv->c.pci->irq,btv); -fail1: - v4l2_device_unregister(&btv->c.v4l2_dev); - -fail0: + fail1: if (btv->bt848_mmio) iounmap(btv->bt848_mmio); release_mem_region(pci_resource_start(btv->c.pci,0), pci_resource_len(btv->c.pci,0)); + pci_set_drvdata(dev,NULL); return result; } static void __devexit bttv_remove(struct pci_dev *pci_dev) { - struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); - struct bttv *btv = to_bttv(v4l2_dev); + struct bttv *btv = pci_get_drvdata(pci_dev); if (bttv_verbose) printk("bttv%d: unloading\n",btv->c.nr); @@ -4499,18 +4511,14 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev) release_mem_region(pci_resource_start(btv->c.pci,0), pci_resource_len(btv->c.pci,0)); - v4l2_device_unregister(&btv->c.v4l2_dev); - bttvs[btv->c.nr] = NULL; - kfree(btv); - + pci_set_drvdata(pci_dev, NULL); return; } #ifdef CONFIG_PM static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state) { - struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); - struct bttv *btv = to_bttv(v4l2_dev); + struct bttv *btv = pci_get_drvdata(pci_dev); struct bttv_buffer_set idle; unsigned long flags; @@ -4545,8 +4553,7 @@ static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state) static int bttv_resume(struct pci_dev *pci_dev) { - struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); - struct bttv *btv = to_bttv(v4l2_dev); + struct bttv *btv = pci_get_drvdata(pci_dev); unsigned long flags; int err; diff --git a/trunk/drivers/media/video/bt8xx/bttv-i2c.c b/trunk/drivers/media/video/bt8xx/bttv-i2c.c index a99d92fac3dc..bcd2cd240a16 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-i2c.c +++ b/trunk/drivers/media/video/bt8xx/bttv-i2c.c @@ -36,6 +36,8 @@ #include #include +static int attach_inform(struct i2c_client *client); + static int i2c_debug; static int i2c_hw; static int i2c_scan; @@ -229,8 +231,7 @@ bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last) static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { - struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap); - struct bttv *btv = to_bttv(v4l2_dev); + struct bttv *btv = i2c_get_adapdata(i2c_adap); int retval = 0; int i; @@ -264,6 +265,52 @@ static const struct i2c_algorithm bttv_algo = { /* ----------------------------------------------------------------------- */ /* I2C functions - common stuff */ +static int attach_inform(struct i2c_client *client) +{ + struct bttv *btv = i2c_get_adapdata(client->adapter); + int addr=ADDR_UNSET; + + + if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr) + addr = bttv_tvcards[btv->c.type].tuner_addr; + + + if (bttv_debug) + printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n", + btv->c.nr, client->driver->driver.name, client->addr, + client->name); + if (!client->driver->command) + return 0; + + if (client->driver->id == I2C_DRIVERID_MSP3400) + btv->i2c_msp34xx_client = client; + if (client->driver->id == I2C_DRIVERID_TVAUDIO) + btv->i2c_tvaudio_client = client; + if (btv->tuner_type != UNSET) { + struct tuner_setup tun_setup; + + if ((addr==ADDR_UNSET) || + (addr==client->addr)) { + + tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | T_RADIO; + tun_setup.type = btv->tuner_type; + tun_setup.addr = addr; + bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); + } + + } + + return 0; +} + +void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg) +{ + if (0 != btv->i2c_rc) + return; + i2c_clients_command(&btv->c.i2c_adap, cmd, arg); +} + + /* read I2C */ int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) { @@ -370,15 +417,21 @@ int __devinit init_bttv_i2c(struct bttv *btv) btv->c.i2c_adap.algo_data = &btv->i2c_algo; } btv->c.i2c_adap.owner = THIS_MODULE; + btv->c.i2c_adap.class = I2C_CLASS_TV_ANALOG; + btv->c.i2c_adap.client_register = attach_inform; btv->c.i2c_adap.dev.parent = &btv->c.pci->dev; snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name), "bt%d #%d [%s]", btv->id, btv->c.nr, btv->use_i2c_hw ? "hw" : "sw"); - i2c_set_adapdata(&btv->c.i2c_adap, &btv->c.v4l2_dev); + i2c_set_adapdata(&btv->c.i2c_adap, btv); btv->i2c_client.adapter = &btv->c.i2c_adap; + if (bttv_tvcards[btv->c.type].no_video) + btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG; + if (bttv_tvcards[btv->c.type].has_dvb) + btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL; if (btv->use_i2c_hw) { btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap); @@ -388,7 +441,7 @@ int __devinit init_bttv_i2c(struct bttv *btv) btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap); } if (0 == btv->i2c_rc && i2c_scan) - do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client); + do_i2c_scan(btv->c.name,&btv->i2c_client); return btv->i2c_rc; } diff --git a/trunk/drivers/media/video/bt8xx/bttv-if.c b/trunk/drivers/media/video/bt8xx/bttv-if.c index a6a540dc9e4b..ecf07988cd33 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-if.c +++ b/trunk/drivers/media/video/bt8xx/bttv-if.c @@ -47,10 +47,7 @@ struct pci_dev* bttv_get_pcidev(unsigned int card) { if (card >= bttv_num) return NULL; - if (!bttvs[card]) - return NULL; - - return bttvs[card]->c.pci; + return bttvs[card].c.pci; } @@ -62,10 +59,7 @@ int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data) return -EINVAL; } - btv = bttvs[card]; - if (!btv) - return -ENODEV; - + btv = &bttvs[card]; gpio_inout(mask,data); if (bttv_gpio) bttv_gpio_tracking(btv,"extern enable"); @@ -80,9 +74,7 @@ int bttv_read_gpio(unsigned int card, unsigned long *data) return -EINVAL; } - btv = bttvs[card]; - if (!btv) - return -ENODEV; + btv = &bttvs[card]; if(btv->shutdown) { return -ENODEV; @@ -102,9 +94,7 @@ int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data) return -EINVAL; } - btv = bttvs[card]; - if (!btv) - return -ENODEV; + btv = &bttvs[card]; /* prior setting BT848_GPIO_REG_INP is (probably) not needed because direct input is set on init */ diff --git a/trunk/drivers/media/video/bt8xx/bttv-risc.c b/trunk/drivers/media/video/bt8xx/bttv-risc.c index d16af2836379..5b1b8e4c78ba 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-risc.c +++ b/trunk/drivers/media/video/bt8xx/bttv-risc.c @@ -341,7 +341,7 @@ bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo, int totalwidth = tvnorm->totalwidth; int scaledtwidth = tvnorm->scaledtwidth; - if (btv->input == btv->dig) { + if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) { swidth = 720; totalwidth = 858; scaledtwidth = 858; @@ -391,7 +391,7 @@ bttv_calc_geo (struct bttv * btv, && crop->width == tvnorm->cropcap.defrect.width && crop->height == tvnorm->cropcap.defrect.height && width <= tvnorm->swidth /* see PAL-Nc et al */) - || btv->input == btv->dig) { + || bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) { bttv_calc_geo_old(btv, geo, width, height, both_fields, tvnorm); return; diff --git a/trunk/drivers/media/video/bt8xx/bttv-vbi.c b/trunk/drivers/media/video/bt8xx/bttv-vbi.c index e79a402fa6cd..6819e21a3773 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-vbi.c +++ b/trunk/drivers/media/video/bt8xx/bttv-vbi.c @@ -411,7 +411,7 @@ int bttv_g_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt) return 0; } -void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm) +void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm) { const struct bttv_tvnorm *tvnorm; unsigned int real_samples_per_line; diff --git a/trunk/drivers/media/video/bt8xx/bttv.h b/trunk/drivers/media/video/bt8xx/bttv.h index 3d36daf206f3..529bf6cf634d 100644 --- a/trunk/drivers/media/video/bt8xx/bttv.h +++ b/trunk/drivers/media/video/bt8xx/bttv.h @@ -14,9 +14,8 @@ #ifndef _BTTV_H_ #define _BTTV_H_ -#include +#include #include -#include #include #include #include @@ -181,10 +180,6 @@ #define BTTV_BOARD_VD012 0x99 #define BTTV_BOARD_VD012_X1 0x9a #define BTTV_BOARD_VD012_X2 0x9b -#define BTTV_BOARD_IVCE8784 0x9c -#define BTTV_BOARD_GEOVISION_GV800S 0x9d -#define BTTV_BOARD_GEOVISION_GV800S_SL 0x9e -#define BTTV_BOARD_PV183 0x9f /* more card-specific defines */ @@ -196,9 +191,12 @@ #define WINVIEW_PT2254_DATA 0x20 #define WINVIEW_PT2254_STROBE 0x80 +/* digital_mode */ +#define DIGITAL_MODE_VIDEO 1 +#define DIGITAL_MODE_CAMERA 2 + struct bttv_core { /* device structs */ - struct v4l2_device v4l2_dev; struct pci_dev *pci; struct i2c_adapter i2c_adap; struct list_head subs; /* struct bttv_sub_device */ @@ -206,79 +204,59 @@ struct bttv_core { /* device config */ unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ unsigned int type; /* card type (pointer into tvcards[]) */ + char name[8]; /* dev name */ }; struct bttv; -struct tvcard { - char *name; - void (*volume_gpio)(struct bttv *btv, __u16 volume); - void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set); - void (*muxsel_hook)(struct bttv *btv, unsigned int input); - - /* MUX bits for each input, two bits per input starting with the LSB */ - u32 muxsel; /* Use MUXSEL() to set */ +struct tvcard +{ + char *name; + unsigned int video_inputs; + unsigned int audio_inputs; + unsigned int tuner; + unsigned int svhs; + unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO u32 gpiomask; + u32 muxsel[16]; u32 gpiomux[4]; /* Tuner, Radio, external, internal */ u32 gpiomute; /* GPIO mute setting */ u32 gpiomask2; /* GPIO MUX mask */ - unsigned int tuner_type; - u8 tuner_addr; - u8 video_inputs; /* Number of inputs */ - unsigned int svhs:4; /* Which input is s-video */ -#define NO_SVHS 15 - unsigned int pll:2; -#define PLL_NONE 0 -#define PLL_28 1 -#define PLL_35 2 - /* i2c audio flags */ unsigned int no_msp34xx:1; unsigned int no_tda9875:1; unsigned int no_tda7432:1; unsigned int needs_tvaudio:1; unsigned int msp34xx_alt:1; - /* Note: currently no card definition needs to mark the presence - of a RDS saa6588 chip. If this is ever needed, then add a new - 'has_saa6588' bit here. */ - unsigned int no_video:1; /* video pci function is unused */ + /* flag: video pci function is unused */ + unsigned int no_video:1; unsigned int has_dvb:1; unsigned int has_remote:1; - unsigned int has_radio:1; - unsigned int has_dig_in:1; /* Has digital input (always last input) */ unsigned int no_gpioirq:1; + + /* other settings */ + unsigned int pll; +#define PLL_NONE 0 +#define PLL_28 1 +#define PLL_35 2 + + unsigned int tuner_type; + unsigned int tuner_addr; + unsigned int radio_addr; + + unsigned int has_radio; + + void (*volume_gpio)(struct bttv *btv, __u16 volume); + void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set); + + void (*muxsel_hook)(struct bttv *btv, unsigned int input); }; extern struct tvcard bttv_tvcards[]; -/* - * This bit of cpp voodoo is used to create a macro with a variable number of - * arguments (1 to 16). It will pack each argument into a word two bits at a - * time. It can't be a function because it needs to be compile time constant to - * initialize structures. Since each argument must fit in two bits, it's ok - * that they are changed to octal. One should not use hex number, macros, or - * anything else with this macro. Just use plain integers from 0 to 3. - */ -#define _MUXSELf(a) 0##a << 30 -#define _MUXSELe(a, b...) 0##a << 28 | _MUXSELf(b) -#define _MUXSELd(a, b...) 0##a << 26 | _MUXSELe(b) -#define _MUXSELc(a, b...) 0##a << 24 | _MUXSELd(b) -#define _MUXSELb(a, b...) 0##a << 22 | _MUXSELc(b) -#define _MUXSELa(a, b...) 0##a << 20 | _MUXSELb(b) -#define _MUXSEL9(a, b...) 0##a << 18 | _MUXSELa(b) -#define _MUXSEL8(a, b...) 0##a << 16 | _MUXSEL9(b) -#define _MUXSEL7(a, b...) 0##a << 14 | _MUXSEL8(b) -#define _MUXSEL6(a, b...) 0##a << 12 | _MUXSEL7(b) -#define _MUXSEL5(a, b...) 0##a << 10 | _MUXSEL6(b) -#define _MUXSEL4(a, b...) 0##a << 8 | _MUXSEL5(b) -#define _MUXSEL3(a, b...) 0##a << 6 | _MUXSEL4(b) -#define _MUXSEL2(a, b...) 0##a << 4 | _MUXSEL3(b) -#define _MUXSEL1(a, b...) 0##a << 2 | _MUXSEL2(b) -#define MUXSEL(a, b...) (a | _MUXSEL1(b)) - /* identification / initialization of the card */ extern void bttv_idcard(struct bttv *btv); extern void bttv_init_card1(struct bttv *btv); @@ -286,7 +264,7 @@ extern void bttv_init_card2(struct bttv *btv); /* card-specific funtions */ extern void tea5757_set_freq(struct bttv *btv, unsigned short freq); -extern u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits); +extern void bttv_tda9880_setnorm(struct bttv *btv, int norm); /* extra tweaks for some chipsets */ extern void bttv_check_chipset(void); @@ -358,9 +336,7 @@ void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits); /* ---------------------------------------------------------- */ /* i2c */ -#define bttv_call_all(btv, o, f, args...) \ - v4l2_device_call_all(&btv->c.v4l2_dev, 0, o, f, ##args) - +extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg); extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for); extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, unsigned char b2, int both); diff --git a/trunk/drivers/media/video/bt8xx/bttvp.h b/trunk/drivers/media/video/bt8xx/bttvp.h index 96498489199d..199a4d225caf 100644 --- a/trunk/drivers/media/video/bt8xx/bttvp.h +++ b/trunk/drivers/media/video/bt8xx/bttvp.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -134,7 +135,7 @@ struct bttv_buffer { /* bttv specific */ const struct bttv_format *fmt; - unsigned int tvnorm; + int tvnorm; int btformat; int btswap; struct bttv_geometry geo; @@ -153,7 +154,7 @@ struct bttv_buffer_set { }; struct bttv_overlay { - unsigned int tvnorm; + int tvnorm; struct v4l2_rect w; enum v4l2_field field; struct v4l2_clip *clips; @@ -173,7 +174,7 @@ struct bttv_vbi_fmt { }; /* bttv-vbi.c */ -void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm); +void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm); struct bttv_crop { /* A cropping rectangle in struct bttv_tvnorm.cropcap units. */ @@ -328,8 +329,7 @@ struct bttv { unsigned int cardid; /* pci subsystem id (bt878 based ones) */ unsigned int tuner_type; /* tuner chip type */ unsigned int tda9887_conf; - unsigned int svhs, dig; - unsigned int has_saa6588:1; + unsigned int svhs; struct bttv_pll_info pll; int triton1; int gpioirq; @@ -353,8 +353,8 @@ struct bttv { int i2c_state, i2c_rc; int i2c_done; wait_queue_head_t i2c_queue; - struct v4l2_subdev *sd_msp34xx; - struct v4l2_subdev *sd_tvaudio; + struct i2c_client *i2c_msp34xx_client; + struct i2c_client *i2c_tvaudio_client; /* video4linux (1) */ struct video_device *video_dev; @@ -378,8 +378,7 @@ struct bttv { unsigned int audio; unsigned int mute; unsigned long freq; - unsigned int tvnorm; - int hue, contrast, bright, saturation; + int tvnorm,hue,contrast,bright,saturation; struct v4l2_framebuffer fbuf; unsigned int field_count; @@ -459,21 +458,10 @@ struct bttv { __s32 crop_start; }; -static inline struct bttv *to_bttv(struct v4l2_device *v4l2_dev) -{ - return container_of(v4l2_dev, struct bttv, c.v4l2_dev); -} - /* our devices */ #define BTTV_MAX 32 extern unsigned int bttv_num; -extern struct bttv *bttvs[BTTV_MAX]; - -static inline unsigned int bttv_muxsel(const struct bttv *btv, - unsigned int input) -{ - return (bttv_tvcards[btv->c.type].muxsel >> (input * 2)) & 3; -} +extern struct bttv bttvs[BTTV_MAX]; #endif diff --git a/trunk/drivers/media/video/cafe_ccic.c b/trunk/drivers/media/video/cafe_ccic.c index 7abe94d9fb4c..46fd573a4f15 100644 --- a/trunk/drivers/media/video/cafe_ccic.c +++ b/trunk/drivers/media/video/cafe_ccic.c @@ -11,12 +11,6 @@ * * Written by Jonathan Corbet, corbet@lwn.net. * - * v4l2_device/v4l2_subdev conversion by: - * Copyright (C) 2009 Hans Verkuil - * - * Note: this conversion is untested! Please contact the linux-media - * mailinglist if you can test this, together with the test results. - * * This file may be distributed under the terms of the GNU General * Public License, version 2. */ @@ -31,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -39,6 +33,7 @@ #include #include #include +#include #include #include @@ -141,7 +136,6 @@ struct cafe_sio_buffer { */ struct cafe_camera { - struct v4l2_device v4l2_dev; enum cafe_state state; unsigned long flags; /* Buffer status, mainly (dev_lock) */ int users; /* How many open FDs */ @@ -151,10 +145,9 @@ struct cafe_camera * Subsystem structures. */ struct pci_dev *pdev; - struct video_device vdev; + struct video_device v4ldev; struct i2c_adapter i2c_adapter; - struct v4l2_subdev *sensor; - unsigned short sensor_addr; + struct i2c_client *sensor; unsigned char __iomem *regs; struct list_head dev_list; /* link to other devices */ @@ -187,6 +180,10 @@ struct cafe_camera /* Misc */ wait_queue_head_t smbus_wait; /* Waiting on i2c events */ wait_queue_head_t iowait; /* Waiting on frame data */ +#ifdef CONFIG_VIDEO_ADV_DEBUG + struct dentry *dfs_regs; + struct dentry *dfs_cam_regs; +#endif }; /* @@ -198,13 +195,6 @@ struct cafe_camera #define CF_DMA_ACTIVE 3 /* A frame is incoming */ #define CF_CONFIG_NEEDED 4 /* Must configure hardware */ -#define sensor_call(cam, o, f, args...) \ - v4l2_subdev_call(cam->sensor, o, f, ##args) - -static inline struct cafe_camera *to_cam(struct v4l2_device *dev) -{ - return container_of(dev, struct cafe_camera, v4l2_dev); -} /* @@ -248,7 +238,59 @@ static void cafe_set_config_needed(struct cafe_camera *cam, int needed) /* ---------------------------------------------------------------------*/ +/* + * We keep a simple list of known devices to search at open time. + */ +static LIST_HEAD(cafe_dev_list); +static DEFINE_MUTEX(cafe_dev_list_lock); + +static void cafe_add_dev(struct cafe_camera *cam) +{ + mutex_lock(&cafe_dev_list_lock); + list_add_tail(&cam->dev_list, &cafe_dev_list); + mutex_unlock(&cafe_dev_list_lock); +} + +static void cafe_remove_dev(struct cafe_camera *cam) +{ + mutex_lock(&cafe_dev_list_lock); + list_del(&cam->dev_list); + mutex_unlock(&cafe_dev_list_lock); +} + +static struct cafe_camera *cafe_find_dev(int minor) +{ + struct cafe_camera *cam; + + mutex_lock(&cafe_dev_list_lock); + list_for_each_entry(cam, &cafe_dev_list, dev_list) { + if (cam->v4ldev.minor == minor) + goto done; + } + cam = NULL; + done: + mutex_unlock(&cafe_dev_list_lock); + return cam; +} + + +static struct cafe_camera *cafe_find_by_pdev(struct pci_dev *pdev) +{ + struct cafe_camera *cam; + mutex_lock(&cafe_dev_list_lock); + list_for_each_entry(cam, &cafe_dev_list, dev_list) { + if (cam->pdev == pdev) + goto done; + } + cam = NULL; + done: + mutex_unlock(&cafe_dev_list_lock); + return cam; +} + + +/* ------------------------------------------------------------------------ */ /* * Device register I/O */ @@ -439,10 +481,17 @@ static int cafe_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, char rw, u8 command, int size, union i2c_smbus_data *data) { - struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter); - struct cafe_camera *cam = to_cam(v4l2_dev); + struct cafe_camera *cam = i2c_get_adapdata(adapter); int ret = -EINVAL; + /* + * Refuse to talk to anything but OV cam chips. We should + * never even see an attempt to do so, but one never knows. + */ + if (cam->sensor && addr != cam->sensor->addr) { + cam_err(cam, "funky smbus addr %d\n", addr); + return -EINVAL; + } /* * This interface would appear to only do byte data ops. OK * it can do word too, but the cam chip has no use for that. @@ -481,9 +530,38 @@ static struct i2c_algorithm cafe_smbus_algo = { }; /* Somebody is on the bus */ +static int cafe_cam_init(struct cafe_camera *cam); static void cafe_ctlr_stop_dma(struct cafe_camera *cam); static void cafe_ctlr_power_down(struct cafe_camera *cam); +static int cafe_smbus_attach(struct i2c_client *client) +{ + struct cafe_camera *cam = i2c_get_adapdata(client->adapter); + + /* + * Don't talk to chips we don't recognize. + */ + if (client->driver->id == I2C_DRIVERID_OV7670) { + cam->sensor = client; + return cafe_cam_init(cam); + } + return -EINVAL; +} + +static int cafe_smbus_detach(struct i2c_client *client) +{ + struct cafe_camera *cam = i2c_get_adapdata(client->adapter); + + if (cam->sensor == client) { + cafe_ctlr_stop_dma(cam); + cafe_ctlr_power_down(cam); + cam_err(cam, "lost the sensor!\n"); + cam->sensor = NULL; /* Bummer, no camera */ + cam->state = S_NOTREADY; + } + return 0; +} + static int cafe_smbus_setup(struct cafe_camera *cam) { struct i2c_adapter *adap = &cam->i2c_adapter; @@ -492,10 +570,12 @@ static int cafe_smbus_setup(struct cafe_camera *cam) cafe_smbus_enable_irq(cam); adap->id = I2C_HW_SMBUS_CAFE; adap->owner = THIS_MODULE; + adap->client_register = cafe_smbus_attach; + adap->client_unregister = cafe_smbus_detach; adap->algo = &cafe_smbus_algo; strcpy(adap->name, "cafe_ccic"); adap->dev.parent = &cam->pdev->dev; - i2c_set_adapdata(adap, &cam->v4l2_dev); + i2c_set_adapdata(adap, cam); ret = i2c_add_adapter(adap); if (ret) printk(KERN_ERR "Unable to register cafe i2c adapter\n"); @@ -729,9 +809,9 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam) * Control 1 is power down, set to 0 to operate. */ cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN); /* pwr up, reset */ -/* mdelay(1); */ /* Marvell says 1ms will do it */ +// mdelay(1); /* Marvell says 1ms will do it */ cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0); -/* mdelay(1); */ /* Enough? */ +// mdelay(1); /* Enough? */ spin_unlock_irqrestore(&cam->dev_lock, flags); msleep(5); /* Just to be sure */ } @@ -753,9 +833,23 @@ static void cafe_ctlr_power_down(struct cafe_camera *cam) * Communications with the sensor. */ +static int __cafe_cam_cmd(struct cafe_camera *cam, int cmd, void *arg) +{ + struct i2c_client *sc = cam->sensor; + int ret; + + if (sc == NULL || sc->driver == NULL || sc->driver->command == NULL) + return -EINVAL; + ret = sc->driver->command(sc, cmd, arg); + if (ret == -EPERM) /* Unsupported command */ + return 0; + return ret; +} + static int __cafe_cam_reset(struct cafe_camera *cam) { - return sensor_call(cam, core, reset, 0); + int zero = 0; + return __cafe_cam_cmd(cam, VIDIOC_INT_RESET, &zero); } /* @@ -775,13 +869,14 @@ static int cafe_cam_init(struct cafe_camera *cam) if (ret) goto out; chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR; - chip.match.addr = cam->sensor_addr; - ret = sensor_call(cam, core, g_chip_ident, &chip); + chip.match.addr = cam->sensor->addr; + ret = __cafe_cam_cmd(cam, VIDIOC_DBG_G_CHIP_IDENT, &chip); if (ret) goto out; cam->sensor_type = chip.ident; +// if (cam->sensor->addr != OV7xx0_SID) { if (cam->sensor_type != V4L2_IDENT_OV7670) { - cam_err(cam, "Unsupported sensor type 0x%x", cam->sensor_type); + cam_err(cam, "Unsupported sensor type %d", cam->sensor->addr); ret = -EINVAL; goto out; } @@ -805,21 +900,21 @@ static int cafe_cam_set_flip(struct cafe_camera *cam) memset(&ctrl, 0, sizeof(ctrl)); ctrl.id = V4L2_CID_VFLIP; ctrl.value = flip; - return sensor_call(cam, core, s_ctrl, &ctrl); + return __cafe_cam_cmd(cam, VIDIOC_S_CTRL, &ctrl); } static int cafe_cam_configure(struct cafe_camera *cam) { struct v4l2_format fmt; - int ret; + int ret, zero = 0; if (cam->state != S_IDLE) return -EINVAL; fmt.fmt.pix = cam->pix_format; - ret = sensor_call(cam, core, init, 0); + ret = __cafe_cam_cmd(cam, VIDIOC_INT_INIT, &zero); if (ret == 0) - ret = sensor_call(cam, video, s_fmt, &fmt); + ret = __cafe_cam_cmd(cam, VIDIOC_S_FMT, &fmt); /* * OV7670 does weird things if flip is set *before* format... */ @@ -1151,6 +1246,8 @@ static int cafe_vidioc_reqbufs(struct file *filp, void *priv, * Make sure it's something we can do. User pointers could be * implemented without great pain, but that's not been done yet. */ + if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; if (req->memory != V4L2_MEMORY_MMAP) return -EINVAL; /* @@ -1214,7 +1311,9 @@ static int cafe_vidioc_querybuf(struct file *filp, void *priv, int ret = -EINVAL; mutex_lock(&cam->s_mutex); - if (buf->index >= cam->n_sbufs) + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + goto out; + if (buf->index < 0 || buf->index >= cam->n_sbufs) goto out; *buf = cam->sb_bufs[buf->index].v4lbuf; ret = 0; @@ -1232,7 +1331,9 @@ static int cafe_vidioc_qbuf(struct file *filp, void *priv, unsigned long flags; mutex_lock(&cam->s_mutex); - if (buf->index >= cam->n_sbufs) + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + goto out; + if (buf->index < 0 || buf->index >= cam->n_sbufs) goto out; sbuf = cam->sb_bufs + buf->index; if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED) { @@ -1263,6 +1364,8 @@ static int cafe_vidioc_dqbuf(struct file *filp, void *priv, unsigned long flags; mutex_lock(&cam->s_mutex); + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + goto out_unlock; if (cam->state != S_STREAMING) goto out_unlock; if (list_empty(&cam->sb_full) && filp->f_flags & O_NONBLOCK) { @@ -1371,8 +1474,11 @@ static int cafe_v4l_mmap(struct file *filp, struct vm_area_struct *vma) static int cafe_v4l_open(struct file *filp) { - struct cafe_camera *cam = video_drvdata(filp); + struct cafe_camera *cam; + cam = cafe_find_dev(video_devdata(filp)->minor); + if (cam == NULL) + return -ENODEV; filp->private_data = cam; mutex_lock(&cam->s_mutex); @@ -1426,11 +1532,11 @@ static unsigned int cafe_v4l_poll(struct file *filp, static int cafe_vidioc_queryctrl(struct file *filp, void *priv, struct v4l2_queryctrl *qc) { - struct cafe_camera *cam = priv; + struct cafe_camera *cam = filp->private_data; int ret; mutex_lock(&cam->s_mutex); - ret = sensor_call(cam, core, queryctrl, qc); + ret = __cafe_cam_cmd(cam, VIDIOC_QUERYCTRL, qc); mutex_unlock(&cam->s_mutex); return ret; } @@ -1439,11 +1545,11 @@ static int cafe_vidioc_queryctrl(struct file *filp, void *priv, static int cafe_vidioc_g_ctrl(struct file *filp, void *priv, struct v4l2_control *ctrl) { - struct cafe_camera *cam = priv; + struct cafe_camera *cam = filp->private_data; int ret; mutex_lock(&cam->s_mutex); - ret = sensor_call(cam, core, g_ctrl, ctrl); + ret = __cafe_cam_cmd(cam, VIDIOC_G_CTRL, ctrl); mutex_unlock(&cam->s_mutex); return ret; } @@ -1452,11 +1558,11 @@ static int cafe_vidioc_g_ctrl(struct file *filp, void *priv, static int cafe_vidioc_s_ctrl(struct file *filp, void *priv, struct v4l2_control *ctrl) { - struct cafe_camera *cam = priv; + struct cafe_camera *cam = filp->private_data; int ret; mutex_lock(&cam->s_mutex); - ret = sensor_call(cam, core, s_ctrl, ctrl); + ret = __cafe_cam_cmd(cam, VIDIOC_S_CTRL, ctrl); mutex_unlock(&cam->s_mutex); return ret; } @@ -1495,8 +1601,10 @@ static int cafe_vidioc_enum_fmt_vid_cap(struct file *filp, struct cafe_camera *cam = priv; int ret; + if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; mutex_lock(&cam->s_mutex); - ret = sensor_call(cam, video, enum_fmt, fmt); + ret = __cafe_cam_cmd(cam, VIDIOC_ENUM_FMT, fmt); mutex_unlock(&cam->s_mutex); return ret; } @@ -1509,7 +1617,7 @@ static int cafe_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, int ret; mutex_lock(&cam->s_mutex); - ret = sensor_call(cam, video, try_fmt, fmt); + ret = __cafe_cam_cmd(cam, VIDIOC_TRY_FMT, fmt); mutex_unlock(&cam->s_mutex); return ret; } @@ -1618,7 +1726,7 @@ static int cafe_vidioc_g_parm(struct file *filp, void *priv, int ret; mutex_lock(&cam->s_mutex); - ret = sensor_call(cam, video, g_parm, parms); + ret = __cafe_cam_cmd(cam, VIDIOC_G_PARM, parms); mutex_unlock(&cam->s_mutex); parms->parm.capture.readbuffers = n_dma_bufs; return ret; @@ -1631,52 +1739,20 @@ static int cafe_vidioc_s_parm(struct file *filp, void *priv, int ret; mutex_lock(&cam->s_mutex); - ret = sensor_call(cam, video, s_parm, parms); + ret = __cafe_cam_cmd(cam, VIDIOC_S_PARM, parms); mutex_unlock(&cam->s_mutex); parms->parm.capture.readbuffers = n_dma_bufs; return ret; } -static int cafe_vidioc_g_chip_ident(struct file *file, void *priv, - struct v4l2_dbg_chip_ident *chip) -{ - struct cafe_camera *cam = priv; - chip->ident = V4L2_IDENT_NONE; - chip->revision = 0; - if (v4l2_chip_match_host(&chip->match)) { - chip->ident = V4L2_IDENT_CAFE; - return 0; - } - return sensor_call(cam, core, g_chip_ident, chip); -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int cafe_vidioc_g_register(struct file *file, void *priv, - struct v4l2_dbg_register *reg) +static void cafe_v4l_dev_release(struct video_device *vd) { - struct cafe_camera *cam = priv; + struct cafe_camera *cam = container_of(vd, struct cafe_camera, v4ldev); - if (v4l2_chip_match_host(®->match)) { - reg->val = cafe_reg_read(cam, reg->reg); - reg->size = 4; - return 0; - } - return sensor_call(cam, core, g_register, reg); + kfree(cam); } -static int cafe_vidioc_s_register(struct file *file, void *priv, - struct v4l2_dbg_register *reg) -{ - struct cafe_camera *cam = priv; - - if (v4l2_chip_match_host(®->match)) { - cafe_reg_write(cam, reg->reg, reg->val); - return 0; - } - return sensor_call(cam, core, s_register, reg); -} -#endif /* * This template device holds all of those v4l2 methods; we @@ -1714,11 +1790,6 @@ static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { .vidioc_s_ctrl = cafe_vidioc_s_ctrl, .vidioc_g_parm = cafe_vidioc_g_parm, .vidioc_s_parm = cafe_vidioc_s_parm, - .vidioc_g_chip_ident = cafe_vidioc_g_chip_ident, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = cafe_vidioc_g_register, - .vidioc_s_register = cafe_vidioc_s_register, -#endif }; static struct video_device cafe_v4l_template = { @@ -1729,10 +1800,15 @@ static struct video_device cafe_v4l_template = { .fops = &cafe_v4l_fops, .ioctl_ops = &cafe_v4l_ioctl_ops, - .release = video_device_release_empty, + .release = cafe_v4l_dev_release, }; + + + + + /* ---------------------------------------------------------------------- */ /* * Interrupt handler stuff @@ -1886,6 +1962,127 @@ static irqreturn_t cafe_irq(int irq, void *data) /* -------------------------------------------------------------------------- */ +#ifdef CONFIG_VIDEO_ADV_DEBUG +/* + * Debugfs stuff. + */ + +static char cafe_debug_buf[1024]; +static struct dentry *cafe_dfs_root; + +static void cafe_dfs_setup(void) +{ + cafe_dfs_root = debugfs_create_dir("cafe_ccic", NULL); + if (IS_ERR(cafe_dfs_root)) { + cafe_dfs_root = NULL; /* Never mind */ + printk(KERN_NOTICE "cafe_ccic unable to set up debugfs\n"); + } +} + +static void cafe_dfs_shutdown(void) +{ + if (cafe_dfs_root) + debugfs_remove(cafe_dfs_root); +} + +static int cafe_dfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static ssize_t cafe_dfs_read_regs(struct file *file, + char __user *buf, size_t count, loff_t *ppos) +{ + struct cafe_camera *cam = file->private_data; + char *s = cafe_debug_buf; + int offset; + + for (offset = 0; offset < 0x44; offset += 4) + s += sprintf(s, "%02x: %08x\n", offset, + cafe_reg_read(cam, offset)); + for (offset = 0x88; offset <= 0x90; offset += 4) + s += sprintf(s, "%02x: %08x\n", offset, + cafe_reg_read(cam, offset)); + for (offset = 0xb4; offset <= 0xbc; offset += 4) + s += sprintf(s, "%02x: %08x\n", offset, + cafe_reg_read(cam, offset)); + for (offset = 0x3000; offset <= 0x300c; offset += 4) + s += sprintf(s, "%04x: %08x\n", offset, + cafe_reg_read(cam, offset)); + return simple_read_from_buffer(buf, count, ppos, cafe_debug_buf, + s - cafe_debug_buf); +} + +static const struct file_operations cafe_dfs_reg_ops = { + .owner = THIS_MODULE, + .read = cafe_dfs_read_regs, + .open = cafe_dfs_open +}; + +static ssize_t cafe_dfs_read_cam(struct file *file, + char __user *buf, size_t count, loff_t *ppos) +{ + struct cafe_camera *cam = file->private_data; + char *s = cafe_debug_buf; + int offset; + + if (! cam->sensor) + return -EINVAL; + for (offset = 0x0; offset < 0x8a; offset++) + { + u8 v; + + cafe_smbus_read_data(cam, cam->sensor->addr, offset, &v); + s += sprintf(s, "%02x: %02x\n", offset, v); + } + return simple_read_from_buffer(buf, count, ppos, cafe_debug_buf, + s - cafe_debug_buf); +} + +static const struct file_operations cafe_dfs_cam_ops = { + .owner = THIS_MODULE, + .read = cafe_dfs_read_cam, + .open = cafe_dfs_open +}; + + + +static void cafe_dfs_cam_setup(struct cafe_camera *cam) +{ + char fname[40]; + + if (!cafe_dfs_root) + return; + sprintf(fname, "regs-%d", cam->v4ldev.num); + cam->dfs_regs = debugfs_create_file(fname, 0444, cafe_dfs_root, + cam, &cafe_dfs_reg_ops); + sprintf(fname, "cam-%d", cam->v4ldev.num); + cam->dfs_cam_regs = debugfs_create_file(fname, 0444, cafe_dfs_root, + cam, &cafe_dfs_cam_ops); +} + + +static void cafe_dfs_cam_shutdown(struct cafe_camera *cam) +{ + if (! IS_ERR(cam->dfs_regs)) + debugfs_remove(cam->dfs_regs); + if (! IS_ERR(cam->dfs_cam_regs)) + debugfs_remove(cam->dfs_cam_regs); +} + +#else + +#define cafe_dfs_setup() +#define cafe_dfs_shutdown() +#define cafe_dfs_cam_setup(cam) +#define cafe_dfs_cam_shutdown(cam) +#endif /* CONFIG_VIDEO_ADV_DEBUG */ + + + + +/* ------------------------------------------------------------------------*/ /* * PCI interface stuff. */ @@ -1903,10 +2100,6 @@ static int cafe_pci_probe(struct pci_dev *pdev, cam = kzalloc(sizeof(struct cafe_camera), GFP_KERNEL); if (cam == NULL) goto out; - ret = v4l2_device_register(&pdev->dev, &cam->v4l2_dev); - if (ret) - goto out_free; - mutex_init(&cam->s_mutex); mutex_lock(&cam->s_mutex); spin_lock_init(&cam->dev_lock); @@ -1925,14 +2118,14 @@ static int cafe_pci_probe(struct pci_dev *pdev, */ ret = pci_enable_device(pdev); if (ret) - goto out_unreg; + goto out_free; pci_set_master(pdev); ret = -EIO; cam->regs = pci_iomap(pdev, 0, 0); if (! cam->regs) { printk(KERN_ERR "Unable to ioremap cafe-ccic regs\n"); - goto out_unreg; + goto out_free; } ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam); if (ret) @@ -1952,31 +2145,17 @@ static int cafe_pci_probe(struct pci_dev *pdev, ret = cafe_smbus_setup(cam); if (ret) goto out_freeirq; - - cam->sensor_addr = 0x42; - cam->sensor = v4l2_i2c_new_subdev(&cam->i2c_adapter, - "ov7670", "ov7670", cam->sensor_addr); - if (cam->sensor == NULL) { - ret = -ENODEV; - goto out_smbus; - } - ret = cafe_cam_init(cam); - if (ret) - goto out_smbus; - /* * Get the v4l2 setup done. */ mutex_lock(&cam->s_mutex); - cam->vdev = cafe_v4l_template; - cam->vdev.debug = 0; -/* cam->vdev.debug = V4L2_DEBUG_IOCTL_ARG;*/ - cam->vdev.v4l2_dev = &cam->v4l2_dev; - ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1); + cam->v4ldev = cafe_v4l_template; + cam->v4ldev.debug = 0; +// cam->v4ldev.debug = V4L2_DEBUG_IOCTL_ARG; + cam->v4ldev.parent = &pdev->dev; + ret = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER, -1); if (ret) goto out_smbus; - video_set_drvdata(&cam->vdev, cam); - /* * If so requested, try to get our DMA buffers now. */ @@ -1986,21 +2165,21 @@ static int cafe_pci_probe(struct pci_dev *pdev, " will try again later."); } + cafe_dfs_cam_setup(cam); mutex_unlock(&cam->s_mutex); + cafe_add_dev(cam); return 0; -out_smbus: + out_smbus: cafe_smbus_shutdown(cam); -out_freeirq: + out_freeirq: cafe_ctlr_power_down(cam); free_irq(pdev->irq, cam); -out_iounmap: + out_iounmap: pci_iounmap(pdev, cam->regs); -out_free: - v4l2_device_unregister(&cam->v4l2_dev); -out_unreg: + out_free: kfree(cam); -out: + out: return ret; } @@ -2011,23 +2190,25 @@ static int cafe_pci_probe(struct pci_dev *pdev, static void cafe_shutdown(struct cafe_camera *cam) { /* FIXME: Make sure we take care of everything here */ + cafe_dfs_cam_shutdown(cam); if (cam->n_sbufs > 0) /* What if they are still mapped? Shouldn't be, but... */ cafe_free_sio_buffers(cam); + cafe_remove_dev(cam); cafe_ctlr_stop_dma(cam); cafe_ctlr_power_down(cam); cafe_smbus_shutdown(cam); cafe_free_dma_bufs(cam); free_irq(cam->pdev->irq, cam); pci_iounmap(cam->pdev, cam->regs); - video_unregister_device(&cam->vdev); + video_unregister_device(&cam->v4ldev); + /* kfree(cam); done in v4l_release () */ } static void cafe_pci_remove(struct pci_dev *pdev) { - struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); - struct cafe_camera *cam = to_cam(v4l2_dev); + struct cafe_camera *cam = cafe_find_by_pdev(pdev); if (cam == NULL) { printk(KERN_WARNING "pci_remove on unknown pdev %p\n", pdev); @@ -2037,8 +2218,6 @@ static void cafe_pci_remove(struct pci_dev *pdev) if (cam->users > 0) cam_warn(cam, "Removing a device with users!\n"); cafe_shutdown(cam); - v4l2_device_unregister(&cam->v4l2_dev); - kfree(cam); /* No unlock - it no longer exists */ } @@ -2049,8 +2228,7 @@ static void cafe_pci_remove(struct pci_dev *pdev) */ static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state) { - struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); - struct cafe_camera *cam = to_cam(v4l2_dev); + struct cafe_camera *cam = cafe_find_by_pdev(pdev); int ret; enum cafe_state cstate; @@ -2068,8 +2246,7 @@ static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state) static int cafe_pci_resume(struct pci_dev *pdev) { - struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); - struct cafe_camera *cam = to_cam(v4l2_dev); + struct cafe_camera *cam = cafe_find_by_pdev(pdev); int ret = 0; ret = pci_restore_state(pdev); @@ -2130,11 +2307,13 @@ static int __init cafe_init(void) printk(KERN_NOTICE "Marvell M88ALP01 'CAFE' Camera Controller version %d\n", CAFE_VERSION); + cafe_dfs_setup(); ret = pci_register_driver(&cafe_pci_driver); if (ret) { printk(KERN_ERR "Unable to register cafe_ccic driver\n"); goto out; } + request_module("ov7670"); /* FIXME want something more general */ ret = 0; out: @@ -2145,6 +2324,7 @@ static int __init cafe_init(void) static void __exit cafe_exit(void) { pci_unregister_driver(&cafe_pci_driver); + cafe_dfs_shutdown(); } module_init(cafe_init); diff --git a/trunk/drivers/media/video/cpia.c b/trunk/drivers/media/video/cpia.c index 43ab0adf3b61..c3b0c8c63c76 100644 --- a/trunk/drivers/media/video/cpia.c +++ b/trunk/drivers/media/video/cpia.c @@ -1381,7 +1381,9 @@ static void proc_cpia_create(void) { cpia_proc_root = proc_mkdir("cpia", NULL); - if (!cpia_proc_root) + if (cpia_proc_root) + cpia_proc_root->owner = THIS_MODULE; + else LOG("Unable to initialise /proc/cpia\n"); } diff --git a/trunk/drivers/media/video/cpia2/cpia2_v4l.c b/trunk/drivers/media/video/cpia2/cpia2_v4l.c index d4099f5312ac..9c25894fdd8e 100644 --- a/trunk/drivers/media/video/cpia2/cpia2_v4l.c +++ b/trunk/drivers/media/video/cpia2/cpia2_v4l.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include "cpia2.h" diff --git a/trunk/drivers/media/video/cs5345.c b/trunk/drivers/media/video/cs5345.c index 9714059ee949..87e91072627a 100644 --- a/trunk/drivers/media/video/cs5345.c +++ b/trunk/drivers/media/video/cs5345.c @@ -141,6 +141,11 @@ static int cs5345_log_status(struct v4l2_subdev *sd) return 0; } +static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops cs5345_core_ops = { @@ -209,6 +214,8 @@ MODULE_DEVICE_TABLE(i2c, cs5345_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "cs5345", + .driverid = I2C_DRIVERID_CS5345, + .command = cs5345_command, .probe = cs5345_probe, .remove = cs5345_remove, .id_table = cs5345_id, diff --git a/trunk/drivers/media/video/cs53l32a.c b/trunk/drivers/media/video/cs53l32a.c index 5aeb066857a7..7292a6316e63 100644 --- a/trunk/drivers/media/video/cs53l32a.c +++ b/trunk/drivers/media/video/cs53l32a.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC"); MODULE_AUTHOR("Martin Vaughan"); @@ -41,6 +41,9 @@ module_param(debug, bool, 0644); MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On"); +static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; /* ----------------------------------------------------------------------- */ @@ -119,6 +122,11 @@ static int cs53l32a_log_status(struct v4l2_subdev *sd) return 0; } +static int cs53l32a_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops cs53l32a_core_ops = { @@ -210,6 +218,8 @@ MODULE_DEVICE_TABLE(i2c, cs53l32a_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "cs53l32a", + .driverid = I2C_DRIVERID_CS53L32A, + .command = cs53l32a_command, .remove = cs53l32a_remove, .probe = cs53l32a_probe, .id_table = cs53l32a_id, diff --git a/trunk/drivers/media/video/cx18/Kconfig b/trunk/drivers/media/video/cx18/Kconfig index e8a50a611ebc..8940b5387dec 100644 --- a/trunk/drivers/media/video/cx18/Kconfig +++ b/trunk/drivers/media/video/cx18/Kconfig @@ -9,7 +9,7 @@ config VIDEO_CX18 select VIDEO_CX2341X select VIDEO_CS5345 select DVB_S5H1409 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE ---help--- This is a video4linux driver for Conexant cx23418 based PCI combo video recorder devices. diff --git a/trunk/drivers/media/video/cx18/cx18-audio.c b/trunk/drivers/media/video/cx18/cx18-audio.c index bb5c5165dd5f..57beddf0af4d 100644 --- a/trunk/drivers/media/video/cx18/cx18-audio.c +++ b/trunk/drivers/media/video/cx18/cx18-audio.c @@ -23,6 +23,7 @@ #include "cx18-driver.h" #include "cx18-io.h" +#include "cx18-i2c.h" #include "cx18-cards.h" #include "cx18-audio.h" @@ -32,32 +33,55 @@ settings. */ int cx18_audio_set_io(struct cx18 *cx) { - const struct cx18_card_audio_input *in; struct v4l2_routing route; + u32 audio_input; u32 val; + int mux_input; int err; /* Determine which input to use */ - if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) - in = &cx->card->radio_input; - else - in = &cx->card->audio_inputs[cx->audio_input]; + if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { + audio_input = cx->card->radio_input.audio_input; + mux_input = cx->card->radio_input.muxer_input; + } else { + audio_input = + cx->card->audio_inputs[cx->audio_input].audio_input; + mux_input = + cx->card->audio_inputs[cx->audio_input].muxer_input; + } /* handle muxer chips */ - route.input = in->muxer_input; + route.input = mux_input; route.output = 0; - v4l2_subdev_call(cx->sd_extmux, audio, s_routing, &route); + cx18_i2c_hw(cx, cx->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route); - route.input = in->audio_input; - err = cx18_call_hw_err(cx, cx->card->hw_audio_ctrl, - audio, s_routing, &route); + route.input = audio_input; + err = cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, + VIDIOC_INT_S_AUDIO_ROUTING, &route); if (err) return err; - /* FIXME - this internal mux should be abstracted to a subdev */ val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30; - val |= (in->audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 : - (in->audio_input << 4); - cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30); + val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 : + (audio_input << 4); + cx18_write_reg(cx, val | 0xb00, CX18_AUDIO_ENABLE); + cx18_vapi(cx, CX18_APU_RESETAI, 1, 0); return 0; } + +void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route) +{ + cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, + VIDIOC_INT_S_AUDIO_ROUTING, route); +} + +void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq) +{ + static u32 freqs[3] = { 44100, 48000, 32000 }; + + /* The audio clock of the digitizer must match the codec sample + rate otherwise you get some very strange effects. */ + if (freq > 2) + return; + cx18_call_i2c_clients(cx, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[freq]); +} diff --git a/trunk/drivers/media/video/cx18/cx18-audio.h b/trunk/drivers/media/video/cx18/cx18-audio.h index 2731d29b0ab9..cb569a69379c 100644 --- a/trunk/drivers/media/video/cx18/cx18-audio.h +++ b/trunk/drivers/media/video/cx18/cx18-audio.h @@ -22,3 +22,5 @@ */ int cx18_audio_set_io(struct cx18 *cx); +void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route); +void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq); diff --git a/trunk/drivers/media/video/cx18/cx18-av-audio.c b/trunk/drivers/media/video/cx18/cx18-av-audio.c index 9e30983f2ff6..a2f0ad570434 100644 --- a/trunk/drivers/media/video/cx18/cx18-av-audio.c +++ b/trunk/drivers/media/video/cx18/cx18-av-audio.c @@ -464,76 +464,82 @@ static void set_mute(struct cx18 *cx, int mute) } } -int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq) +int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg) { - struct cx18 *cx = v4l2_get_subdevdata(sd); struct cx18_av_state *state = &cx->av_state; + struct v4l2_control *ctrl = arg; int retval; - u8 v; - if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { - v = cx18_av_read(cx, 0x803) & ~0x10; - cx18_av_write_expect(cx, 0x803, v, v, 0x1f); - cx18_av_write(cx, 0x8d3, 0x1f); - } - v = cx18_av_read(cx, 0x810) | 0x1; - cx18_av_write_expect(cx, 0x810, v, v, 0x0f); + switch (cmd) { + case VIDIOC_INT_AUDIO_CLOCK_FREQ: + { + u8 v; + if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { + v = cx18_av_read(cx, 0x803) & ~0x10; + cx18_av_write_expect(cx, 0x803, v, v, 0x1f); + cx18_av_write(cx, 0x8d3, 0x1f); + } + v = cx18_av_read(cx, 0x810) | 0x1; + cx18_av_write_expect(cx, 0x810, v, v, 0x0f); - retval = set_audclk_freq(cx, freq); + retval = set_audclk_freq(cx, *(u32 *)arg); - v = cx18_av_read(cx, 0x810) & ~0x1; - cx18_av_write_expect(cx, 0x810, v, v, 0x0f); - if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { - v = cx18_av_read(cx, 0x803) | 0x10; - cx18_av_write_expect(cx, 0x803, v, v, 0x1f); + v = cx18_av_read(cx, 0x810) & ~0x1; + cx18_av_write_expect(cx, 0x810, v, v, 0x0f); + if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { + v = cx18_av_read(cx, 0x803) | 0x10; + cx18_av_write_expect(cx, 0x803, v, v, 0x1f); + } + return retval; } - return retval; -} -int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl) -{ - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - ctrl->value = get_volume(cx); - break; - case V4L2_CID_AUDIO_BASS: - ctrl->value = get_bass(cx); - break; - case V4L2_CID_AUDIO_TREBLE: - ctrl->value = get_treble(cx); - break; - case V4L2_CID_AUDIO_BALANCE: - ctrl->value = get_balance(cx); - break; - case V4L2_CID_AUDIO_MUTE: - ctrl->value = get_mute(cx); + case VIDIOC_G_CTRL: + switch (ctrl->id) { + case V4L2_CID_AUDIO_VOLUME: + ctrl->value = get_volume(cx); + break; + case V4L2_CID_AUDIO_BASS: + ctrl->value = get_bass(cx); + break; + case V4L2_CID_AUDIO_TREBLE: + ctrl->value = get_treble(cx); + break; + case V4L2_CID_AUDIO_BALANCE: + ctrl->value = get_balance(cx); + break; + case V4L2_CID_AUDIO_MUTE: + ctrl->value = get_mute(cx); + break; + default: + return -EINVAL; + } break; - default: - return -EINVAL; - } - return 0; -} -int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl) -{ - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - set_volume(cx, ctrl->value); - break; - case V4L2_CID_AUDIO_BASS: - set_bass(cx, ctrl->value); - break; - case V4L2_CID_AUDIO_TREBLE: - set_treble(cx, ctrl->value); - break; - case V4L2_CID_AUDIO_BALANCE: - set_balance(cx, ctrl->value); - break; - case V4L2_CID_AUDIO_MUTE: - set_mute(cx, ctrl->value); + case VIDIOC_S_CTRL: + switch (ctrl->id) { + case V4L2_CID_AUDIO_VOLUME: + set_volume(cx, ctrl->value); + break; + case V4L2_CID_AUDIO_BASS: + set_bass(cx, ctrl->value); + break; + case V4L2_CID_AUDIO_TREBLE: + set_treble(cx, ctrl->value); + break; + case V4L2_CID_AUDIO_BALANCE: + set_balance(cx, ctrl->value); + break; + case V4L2_CID_AUDIO_MUTE: + set_mute(cx, ctrl->value); + break; + default: + return -EINVAL; + } break; + default: return -EINVAL; } + return 0; } diff --git a/trunk/drivers/media/video/cx18/cx18-av-core.c b/trunk/drivers/media/video/cx18/cx18-av-core.c index f4dd9d78eb3d..0b1c84b4ddd6 100644 --- a/trunk/drivers/media/video/cx18/cx18-av-core.c +++ b/trunk/drivers/media/video/cx18/cx18-av-core.c @@ -22,10 +22,8 @@ * 02110-1301, USA. */ -#include #include "cx18-driver.h" #include "cx18-io.h" -#include "cx18-cards.h" int cx18_av_write(struct cx18 *cx, u16 addr, u8 value) { @@ -99,6 +97,15 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask, or_value); } +/* ----------------------------------------------------------------------- */ + +static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, + enum cx18_av_audio_input aud_input); +static void log_audio_status(struct cx18 *cx); +static void log_video_status(struct cx18 *cx); + +/* ----------------------------------------------------------------------- */ + static void cx18_av_initialize(struct cx18 *cx) { struct cx18_av_state *state = &cx->av_state; @@ -162,14 +169,9 @@ static void cx18_av_initialize(struct cx18 *cx) /* Set VGA_TRACK_RANGE to 0x20 */ cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000); - /* - * Initial VBI setup - * VIP-1.1, 10 bit mode, enable Raw, disable sliced, - * don't clamp raw samples when codes are in use, 1 byte user D-words, - * IDID0 has line #, RP code V bit transition on VBLANK, data during - * blanking intervals - */ - cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4013252e); + /* Enable VBI capture */ + cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253F); + /* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */ /* Set the video input. The setting in MODE_CTRL gets lost when we do the above setup */ @@ -193,61 +195,11 @@ static void cx18_av_initialize(struct cx18 *cx) state->default_volume = ((state->default_volume / 2) + 23) << 9; } -static int cx18_av_reset(struct v4l2_subdev *sd, u32 val) -{ - struct cx18 *cx = v4l2_get_subdevdata(sd); - - cx18_av_initialize(cx); - return 0; -} - -static int cx18_av_init(struct v4l2_subdev *sd, u32 val) -{ - struct cx18_av_state *state = to_cx18_av_state(sd); - struct cx18 *cx = v4l2_get_subdevdata(sd); - - switch (val) { - case CX18_AV_INIT_PLLS: - /* - * The crystal freq used in calculations in this driver will be - * 28.636360 MHz. - * Aim to run the PLLs' VCOs near 400 MHz to minimze errors. - */ - - /* - * VDCLK Integer = 0x0f, Post Divider = 0x04 - * AIMCLK Integer = 0x0e, Post Divider = 0x16 - */ - cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f); - - /* VDCLK Fraction = 0x2be2fe */ - /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */ - cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe); - - /* AIMCLK Fraction = 0x05227ad */ - /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/ - cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad); - - /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */ - cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56); - break; - - case CX18_AV_INIT_NORMAL: - default: - if (!state->is_initialized) { - /* initialize on first use */ - state->is_initialized = 1; - cx18_av_initialize(cx); - } - break; - } - return 0; -} +/* ----------------------------------------------------------------------- */ void cx18_av_std_setup(struct cx18 *cx) { struct cx18_av_state *state = &cx->av_state; - struct v4l2_subdev *sd = &state->sd; v4l2_std_id std = state->std; int hblank, hactive, burst, vblank, vactive, sc; int vblank656, src_decimation; @@ -261,7 +213,6 @@ void cx18_av_std_setup(struct cx18 *cx) cx18_av_write(cx, 0x49f, 0x14); if (std & V4L2_STD_625_50) { - /* FIXME - revisit these for Sliced VBI */ hblank = 132; hactive = 720; burst = 93; @@ -285,40 +236,13 @@ void cx18_av_std_setup(struct cx18 *cx) sc = 672351; } } else { - /* - * The following relationships of half line counts should hold: - * 525 = vsync + vactive + vblank656 - * 12 = vblank656 - vblank - * - * vsync: always 6 half-lines of vsync pulses - * vactive: half lines of active video - * vblank656: half lines, after line 3/mid-266, of blanked video - * vblank: half lines, after line 9/272, of blanked video - * - * As far as I can tell: - * vblank656 starts counting from the falling edge of the first - * vsync pulse (start of line 4 or mid-266) - * vblank starts counting from the after the 6 vsync pulses and - * 6 or 5 equalization pulses (start of line 10 or 272) - * - * For 525 line systems the driver will extract VBI information - * from lines 10-21 and lines 273-284. - */ - vblank656 = 38; /* lines 4 - 22 & 266 - 284 */ - vblank = 26; /* lines 10 - 22 & 272 - 284 */ - vactive = 481; /* lines 23 - 263 & 285 - 525 */ - - /* - * For a 13.5 Mpps clock and 15,734.26 Hz line rate, a line is - * is 858 pixels = 720 active + 138 blanking. The Hsync leading - * edge should happen 1.2 us * 13.5 Mpps ~= 16 pixels after the - * end of active video, leaving 122 pixels of hblank to ignore - * before active video starts. - */ hactive = 720; hblank = 122; + vactive = 487; luma_lpf = 1; uv_lpf = 1; + vblank = 26; + vblank656 = 26; src_decimation = 0x21f; if (std == V4L2_STD_PAL_60) { @@ -341,35 +265,33 @@ void cx18_av_std_setup(struct cx18 *cx) pll_int = cx18_av_read(cx, 0x108); pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff; pll_post = cx18_av_read(cx, 0x109); - CX18_DEBUG_INFO_DEV(sd, "PLL regs = int: %u, frac: %u, post: %u\n", - pll_int, pll_frac, pll_post); + CX18_DEBUG_INFO("PLL regs = int: %u, frac: %u, post: %u\n", + pll_int, pll_frac, pll_post); if (pll_post) { int fin, fsc, pll; pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25; pll /= pll_post; - CX18_DEBUG_INFO_DEV(sd, "PLL = %d.%06d MHz\n", - pll / 1000000, pll % 1000000); - CX18_DEBUG_INFO_DEV(sd, "PLL/8 = %d.%06d MHz\n", - pll / 8000000, (pll / 8) % 1000000); + CX18_DEBUG_INFO("PLL = %d.%06d MHz\n", + pll / 1000000, pll % 1000000); + CX18_DEBUG_INFO("PLL/8 = %d.%06d MHz\n", + pll / 8000000, (pll / 8) % 1000000); fin = ((u64)src_decimation * pll) >> 12; - CX18_DEBUG_INFO_DEV(sd, "ADC Sampling freq = %d.%06d MHz\n", - fin / 1000000, fin % 1000000); + CX18_DEBUG_INFO("ADC Sampling freq = %d.%06d MHz\n", + fin / 1000000, fin % 1000000); fsc = (((u64)sc) * pll) >> 24L; - CX18_DEBUG_INFO_DEV(sd, - "Chroma sub-carrier freq = %d.%06d MHz\n", - fsc / 1000000, fsc % 1000000); - - CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, " - "vactive %i, vblank656 %i, src_dec %i, " - "burst 0x%02x, luma_lpf %i, uv_lpf %i, " - "comb 0x%02x, sc 0x%06x\n", - hblank, hactive, vblank, vactive, vblank656, - src_decimation, burst, luma_lpf, uv_lpf, - comb, sc); + CX18_DEBUG_INFO("Chroma sub-carrier freq = %d.%06d MHz\n", + fsc / 1000000, fsc % 1000000); + + CX18_DEBUG_INFO("hblank %i, hactive %i, " + "vblank %i , vactive %i, vblank656 %i, src_dec %i," + "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x," + " sc 0x%06x\n", + hblank, hactive, vblank, vactive, vblank656, + src_decimation, burst, luma_lpf, uv_lpf, comb, sc); } /* Sets horizontal blanking delay and active lines */ @@ -403,16 +325,18 @@ void cx18_av_std_setup(struct cx18 *cx) cx18_av_write(cx, 0x47d, 0xff & sc >> 8); cx18_av_write(cx, 0x47e, 0xff & sc >> 16); + /* Sets VBI parameters */ if (std & V4L2_STD_625_50) { - state->slicer_line_delay = 1; - state->slicer_line_offset = (6 + state->slicer_line_delay - 2); + cx18_av_write(cx, 0x47f, 0x01); + state->vbi_line_offset = 5; } else { - state->slicer_line_delay = 0; - state->slicer_line_offset = (10 + state->slicer_line_delay - 2); + cx18_av_write(cx, 0x47f, 0x00); + state->vbi_line_offset = 8; } - cx18_av_write(cx, 0x47f, state->slicer_line_delay); } +/* ----------------------------------------------------------------------- */ + static void input_change(struct cx18 *cx) { struct cx18_av_state *state = &cx->av_state; @@ -458,26 +382,17 @@ static void input_change(struct cx18 *cx) } } -static int cx18_av_s_frequency(struct v4l2_subdev *sd, - struct v4l2_frequency *freq) -{ - struct cx18 *cx = v4l2_get_subdevdata(sd); - input_change(cx); - return 0; -} - static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, enum cx18_av_audio_input aud_input) { struct cx18_av_state *state = &cx->av_state; - struct v4l2_subdev *sd = &state->sd; u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 && vid_input <= CX18_AV_COMPOSITE8); u8 reg; u8 v; - CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n", - vid_input, aud_input); + CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n", + vid_input, aud_input); if (is_composite) { reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1); @@ -490,8 +405,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, luma > CX18_AV_SVIDEO_LUMA8 || chroma < CX18_AV_SVIDEO_CHROMA4 || chroma > CX18_AV_SVIDEO_CHROMA8) { - CX18_ERR_DEV(sd, "0x%04x is not a valid video input!\n", - vid_input); + CX18_ERR("0x%04x is not a valid video input!\n", + vid_input); return -EINVAL; } reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4); @@ -516,8 +431,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break; default: - CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n", - aud_input); + CX18_ERR("0x%04x is not a valid audio input!\n", aud_input); return -EINVAL; } @@ -547,118 +461,14 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, return 0; } -static int cx18_av_s_video_routing(struct v4l2_subdev *sd, - const struct v4l2_routing *route) -{ - struct cx18_av_state *state = to_cx18_av_state(sd); - struct cx18 *cx = v4l2_get_subdevdata(sd); - return set_input(cx, route->input, state->aud_input); -} - -static int cx18_av_s_audio_routing(struct v4l2_subdev *sd, - const struct v4l2_routing *route) -{ - struct cx18_av_state *state = to_cx18_av_state(sd); - struct cx18 *cx = v4l2_get_subdevdata(sd); - return set_input(cx, state->vid_input, route->input); -} +/* ----------------------------------------------------------------------- */ -static int cx18_av_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) +static int set_v4lstd(struct cx18 *cx) { - struct cx18_av_state *state = to_cx18_av_state(sd); - struct cx18 *cx = v4l2_get_subdevdata(sd); - u8 vpres; - u8 mode; - int val = 0; - - if (state->radio) - return 0; - - vpres = cx18_av_read(cx, 0x40e) & 0x20; - vt->signal = vpres ? 0xffff : 0x0; - - vt->capability |= - V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | - V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; - - mode = cx18_av_read(cx, 0x804); - - /* get rxsubchans and audmode */ - if ((mode & 0xf) == 1) - val |= V4L2_TUNER_SUB_STEREO; - else - val |= V4L2_TUNER_SUB_MONO; - - if (mode == 2 || mode == 4) - val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; - - if (mode & 0x10) - val |= V4L2_TUNER_SUB_SAP; - - vt->rxsubchans = val; - vt->audmode = state->audmode; - return 0; -} - -static int cx18_av_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) -{ - struct cx18_av_state *state = to_cx18_av_state(sd); - struct cx18 *cx = v4l2_get_subdevdata(sd); - u8 v; - - if (state->radio) - return 0; - - v = cx18_av_read(cx, 0x809); - v &= ~0xf; - - switch (vt->audmode) { - case V4L2_TUNER_MODE_MONO: - /* mono -> mono - stereo -> mono - bilingual -> lang1 */ - break; - case V4L2_TUNER_MODE_STEREO: - case V4L2_TUNER_MODE_LANG1: - /* mono -> mono - stereo -> stereo - bilingual -> lang1 */ - v |= 0x4; - break; - case V4L2_TUNER_MODE_LANG1_LANG2: - /* mono -> mono - stereo -> stereo - bilingual -> lang1/lang2 */ - v |= 0x7; - break; - case V4L2_TUNER_MODE_LANG2: - /* mono -> mono - stereo -> stereo - bilingual -> lang2 */ - v |= 0x1; - break; - default: - return -EINVAL; - } - cx18_av_write_expect(cx, 0x809, v, v, 0xff); - state->audmode = vt->audmode; - return 0; -} - -static int cx18_av_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) -{ - struct cx18_av_state *state = to_cx18_av_state(sd); - struct cx18 *cx = v4l2_get_subdevdata(sd); - + struct cx18_av_state *state = &cx->av_state; u8 fmt = 0; /* zero is autodetect */ u8 pal_m = 0; - if (state->radio == 0 && state->std == norm) - return 0; - - state->radio = 0; - state->std = norm; - /* First tests should be against specific std */ if (state->std == V4L2_STD_NTSC_M_JP) { fmt = 0x2; @@ -683,7 +493,7 @@ static int cx18_av_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) fmt = 0xc; } - CX18_DEBUG_INFO_DEV(sd, "changing video std to fmt %i\n", fmt); + CX18_DEBUG_INFO("changing video std to fmt %i\n", fmt); /* Follow step 9 of section 3.16 in the cx18_av datasheet. Without this PAL may display a vertical ghosting effect. @@ -701,22 +511,15 @@ static int cx18_av_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) return 0; } -static int cx18_av_s_radio(struct v4l2_subdev *sd) -{ - struct cx18_av_state *state = to_cx18_av_state(sd); - state->radio = 1; - return 0; -} +/* ----------------------------------------------------------------------- */ -static int cx18_av_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl) { - struct cx18 *cx = v4l2_get_subdevdata(sd); - switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: if (ctrl->value < 0 || ctrl->value > 255) { - CX18_ERR_DEV(sd, "invalid brightness setting %d\n", - ctrl->value); + CX18_ERR("invalid brightness setting %d\n", + ctrl->value); return -ERANGE; } @@ -725,8 +528,8 @@ static int cx18_av_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) case V4L2_CID_CONTRAST: if (ctrl->value < 0 || ctrl->value > 127) { - CX18_ERR_DEV(sd, "invalid contrast setting %d\n", - ctrl->value); + CX18_ERR("invalid contrast setting %d\n", + ctrl->value); return -ERANGE; } @@ -735,8 +538,8 @@ static int cx18_av_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) case V4L2_CID_SATURATION: if (ctrl->value < 0 || ctrl->value > 127) { - CX18_ERR_DEV(sd, "invalid saturation setting %d\n", - ctrl->value); + CX18_ERR("invalid saturation setting %d\n", + ctrl->value); return -ERANGE; } @@ -745,9 +548,8 @@ static int cx18_av_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) break; case V4L2_CID_HUE: - if (ctrl->value < -128 || ctrl->value > 127) { - CX18_ERR_DEV(sd, "invalid hue setting %d\n", - ctrl->value); + if (ctrl->value < -127 || ctrl->value > 127) { + CX18_ERR("invalid hue setting %d\n", ctrl->value); return -ERANGE; } @@ -759,18 +561,17 @@ static int cx18_av_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_TREBLE: case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_MUTE: - return cx18_av_audio_s_ctrl(cx, ctrl); + return cx18_av_audio(cx, VIDIOC_S_CTRL, ctrl); default: return -EINVAL; } + return 0; } -static int cx18_av_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static int get_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl) { - struct cx18 *cx = v4l2_get_subdevdata(sd); - switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: ctrl->value = (s8)cx18_av_read(cx, 0x414) + 128; @@ -789,57 +590,31 @@ static int cx18_av_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_TREBLE: case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_MUTE: - return cx18_av_audio_g_ctrl(cx, ctrl); + return cx18_av_audio(cx, VIDIOC_G_CTRL, ctrl); default: return -EINVAL; } + return 0; } -static int cx18_av_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) -{ - struct cx18_av_state *state = to_cx18_av_state(sd); +/* ----------------------------------------------------------------------- */ - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); - case V4L2_CID_CONTRAST: - case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64); - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); - default: - break; - } - - switch (qc->id) { - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 65535, - 65535 / 100, state->default_volume); - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768); +static int get_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt) +{ + switch (fmt->type) { + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + return cx18_av_vbi(cx, VIDIOC_G_FMT, fmt); default: return -EINVAL; } - return -EINVAL; -} - -static int cx18_av_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - struct cx18 *cx = v4l2_get_subdevdata(sd); - return cx18_av_vbi_g_fmt(cx, fmt); + return 0; } -static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt) { - struct cx18_av_state *state = to_cx18_av_state(sd); - struct cx18 *cx = v4l2_get_subdevdata(sd); - + struct cx18_av_state *state = &cx->av_state; struct v4l2_pix_format *pix; int HSC, VSC, Vsrc, Hsrc, filter, Vlines; int is_50Hz = !(state->std & V4L2_STD_525_60); @@ -854,26 +629,12 @@ static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4; Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4; - /* - * This adjustment reflects the excess of vactive, set in - * cx18_av_std_setup(), above standard values: - * - * 480 + 1 for 60 Hz systems - * 576 + 4 for 50 Hz systems - */ - Vlines = pix->height + (is_50Hz ? 4 : 1); - - /* - * Invalid height and width scaling requests are: - * 1. width less than 1/16 of the source width - * 2. width greater than the source width - * 3. height less than 1/8 of the source height - * 4. height greater than the source height - */ + Vlines = pix->height + (is_50Hz ? 4 : 7); + if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { - CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n", - pix->width, pix->height); + CX18_ERR("%dx%d is not a valid size!\n", + pix->width, pix->height); return -ERANGE; } @@ -890,9 +651,8 @@ static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) else filter = 3; - CX18_DEBUG_INFO_DEV(sd, - "decoder set size %dx%d -> scale %ux%u\n", - pix->width, pix->height, HSC, VSC); + CX18_DEBUG_INFO("decoder set size %dx%d -> scale %ux%u\n", + pix->width, pix->height, HSC, VSC); /* HSCALE=HSC */ cx18_av_write(cx, 0x418, HSC & 0xff); @@ -906,32 +666,231 @@ static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - return cx18_av_vbi_s_fmt(cx, fmt); + return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt); case V4L2_BUF_TYPE_VBI_CAPTURE: - return cx18_av_vbi_s_fmt(cx, fmt); + return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt); default: return -EINVAL; } + return 0; } -static int cx18_av_s_stream(struct v4l2_subdev *sd, int enable) +/* ----------------------------------------------------------------------- */ + +int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg) { - struct cx18 *cx = v4l2_get_subdevdata(sd); + struct cx18_av_state *state = &cx->av_state; + struct v4l2_tuner *vt = arg; + struct v4l2_routing *route = arg; + + /* ignore these commands */ + switch (cmd) { + case TUNER_SET_TYPE_ADDR: + return 0; + } + + if (!state->is_initialized) { + CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd); + /* initialize on first use */ + state->is_initialized = 1; + cx18_av_initialize(cx); + } - CX18_DEBUG_INFO_DEV(sd, "%s output\n", enable ? "enable" : "disable"); - if (enable) { + switch (cmd) { + case VIDIOC_INT_DECODE_VBI_LINE: + return cx18_av_vbi(cx, cmd, arg); + + case VIDIOC_INT_AUDIO_CLOCK_FREQ: + return cx18_av_audio(cx, cmd, arg); + + case VIDIOC_STREAMON: + CX18_DEBUG_INFO("enable output\n"); cx18_av_write(cx, 0x115, 0x8c); cx18_av_write(cx, 0x116, 0x07); - } else { + break; + + case VIDIOC_STREAMOFF: + CX18_DEBUG_INFO("disable output\n"); cx18_av_write(cx, 0x115, 0x00); cx18_av_write(cx, 0x116, 0x00); + break; + + case VIDIOC_LOG_STATUS: + log_video_status(cx); + log_audio_status(cx); + break; + + case VIDIOC_G_CTRL: + return get_v4lctrl(cx, (struct v4l2_control *)arg); + + case VIDIOC_S_CTRL: + return set_v4lctrl(cx, (struct v4l2_control *)arg); + + case VIDIOC_QUERYCTRL: + { + struct v4l2_queryctrl *qc = arg; + + switch (qc->id) { + case V4L2_CID_BRIGHTNESS: + case V4L2_CID_CONTRAST: + case V4L2_CID_SATURATION: + case V4L2_CID_HUE: + return v4l2_ctrl_query_fill_std(qc); + default: + break; + } + + switch (qc->id) { + case V4L2_CID_AUDIO_VOLUME: + return v4l2_ctrl_query_fill(qc, 0, 65535, + 65535 / 100, state->default_volume); + case V4L2_CID_AUDIO_MUTE: + case V4L2_CID_AUDIO_BALANCE: + case V4L2_CID_AUDIO_BASS: + case V4L2_CID_AUDIO_TREBLE: + return v4l2_ctrl_query_fill_std(qc); + default: + return -EINVAL; + } + return -EINVAL; + } + + case VIDIOC_G_STD: + *(v4l2_std_id *)arg = state->std; + break; + + case VIDIOC_S_STD: + if (state->radio == 0 && state->std == *(v4l2_std_id *)arg) + return 0; + state->radio = 0; + state->std = *(v4l2_std_id *)arg; + return set_v4lstd(cx); + + case AUDC_SET_RADIO: + state->radio = 1; + break; + + case VIDIOC_INT_G_VIDEO_ROUTING: + route->input = state->vid_input; + route->output = 0; + break; + + case VIDIOC_INT_S_VIDEO_ROUTING: + return set_input(cx, route->input, state->aud_input); + + case VIDIOC_INT_G_AUDIO_ROUTING: + route->input = state->aud_input; + route->output = 0; + break; + + case VIDIOC_INT_S_AUDIO_ROUTING: + return set_input(cx, state->vid_input, route->input); + + case VIDIOC_S_FREQUENCY: + input_change(cx); + break; + + case VIDIOC_G_TUNER: + { + u8 vpres = cx18_av_read(cx, 0x40e) & 0x20; + u8 mode; + int val = 0; + + if (state->radio) + break; + + vt->signal = vpres ? 0xffff : 0x0; + + vt->capability |= + V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | + V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; + + mode = cx18_av_read(cx, 0x804); + + /* get rxsubchans and audmode */ + if ((mode & 0xf) == 1) + val |= V4L2_TUNER_SUB_STEREO; + else + val |= V4L2_TUNER_SUB_MONO; + + if (mode == 2 || mode == 4) + val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + + if (mode & 0x10) + val |= V4L2_TUNER_SUB_SAP; + + vt->rxsubchans = val; + vt->audmode = state->audmode; + break; + } + + case VIDIOC_S_TUNER: + { + u8 v; + + if (state->radio) + break; + + v = cx18_av_read(cx, 0x809); + v &= ~0xf; + + switch (vt->audmode) { + case V4L2_TUNER_MODE_MONO: + /* mono -> mono + stereo -> mono + bilingual -> lang1 */ + break; + case V4L2_TUNER_MODE_STEREO: + case V4L2_TUNER_MODE_LANG1: + /* mono -> mono + stereo -> stereo + bilingual -> lang1 */ + v |= 0x4; + break; + case V4L2_TUNER_MODE_LANG1_LANG2: + /* mono -> mono + stereo -> stereo + bilingual -> lang1/lang2 */ + v |= 0x7; + break; + case V4L2_TUNER_MODE_LANG2: + /* mono -> mono + stereo -> stereo + bilingual -> lang2 */ + v |= 0x1; + break; + default: + return -EINVAL; + } + cx18_av_write_expect(cx, 0x809, v, v, 0xff); + state->audmode = vt->audmode; + break; } + + case VIDIOC_G_FMT: + return get_v4lfmt(cx, (struct v4l2_format *)arg); + + case VIDIOC_S_FMT: + return set_v4lfmt(cx, (struct v4l2_format *)arg); + + case VIDIOC_INT_RESET: + cx18_av_initialize(cx); + break; + + default: + return -EINVAL; + } + return 0; } +/* ----------------------------------------------------------------------- */ + +/* ----------------------------------------------------------------------- */ + static void log_video_status(struct cx18 *cx) { static const char *const fmt_strs[] = { @@ -944,40 +903,36 @@ static void log_video_status(struct cx18 *cx) }; struct cx18_av_state *state = &cx->av_state; - struct v4l2_subdev *sd = &state->sd; u8 vidfmt_sel = cx18_av_read(cx, 0x400) & 0xf; u8 gen_stat1 = cx18_av_read(cx, 0x40d); u8 gen_stat2 = cx18_av_read(cx, 0x40e); int vid_input = state->vid_input; - CX18_INFO_DEV(sd, "Video signal: %spresent\n", - (gen_stat2 & 0x20) ? "" : "not "); - CX18_INFO_DEV(sd, "Detected format: %s\n", - fmt_strs[gen_stat1 & 0xf]); + CX18_INFO("Video signal: %spresent\n", + (gen_stat2 & 0x20) ? "" : "not "); + CX18_INFO("Detected format: %s\n", + fmt_strs[gen_stat1 & 0xf]); - CX18_INFO_DEV(sd, "Specified standard: %s\n", - vidfmt_sel ? fmt_strs[vidfmt_sel] - : "automatic detection"); + CX18_INFO("Specified standard: %s\n", + vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); if (vid_input >= CX18_AV_COMPOSITE1 && vid_input <= CX18_AV_COMPOSITE8) { - CX18_INFO_DEV(sd, "Specified video input: Composite %d\n", - vid_input - CX18_AV_COMPOSITE1 + 1); + CX18_INFO("Specified video input: Composite %d\n", + vid_input - CX18_AV_COMPOSITE1 + 1); } else { - CX18_INFO_DEV(sd, "Specified video input: " - "S-Video (Luma In%d, Chroma In%d)\n", - (vid_input & 0xf0) >> 4, - (vid_input & 0xf00) >> 8); + CX18_INFO("Specified video input: S-Video (Luma In%d, Chroma In%d)\n", + (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); } - CX18_INFO_DEV(sd, "Specified audioclock freq: %d Hz\n", - state->audclk_freq); + CX18_INFO("Specified audioclock freq: %d Hz\n", state->audclk_freq); } +/* ----------------------------------------------------------------------- */ + static void log_audio_status(struct cx18 *cx) { struct cx18_av_state *state = &cx->av_state; - struct v4l2_subdev *sd = &state->sd; u8 download_ctl = cx18_av_read(cx, 0x803); u8 mod_det_stat0 = cx18_av_read(cx, 0x804); u8 mod_det_stat1 = cx18_av_read(cx, 0x805); @@ -1000,7 +955,7 @@ static void log_audio_status(struct cx18 *cx) case 0xfe: p = "forced mode"; break; default: p = "not defined"; break; } - CX18_INFO_DEV(sd, "Detected audio mode: %s\n", p); + CX18_INFO("Detected audio mode: %s\n", p); switch (mod_det_stat1) { case 0x00: p = "not defined"; break; @@ -1025,11 +980,11 @@ static void log_audio_status(struct cx18 *cx) case 0xff: p = "no detected audio standard"; break; default: p = "not defined"; break; } - CX18_INFO_DEV(sd, "Detected audio standard: %s\n", p); - CX18_INFO_DEV(sd, "Audio muted: %s\n", - (mute_ctl & 0x2) ? "yes" : "no"); - CX18_INFO_DEV(sd, "Audio microcontroller: %s\n", - (download_ctl & 0x10) ? "running" : "stopped"); + CX18_INFO("Detected audio standard: %s\n", p); + CX18_INFO("Audio muted: %s\n", + (mute_ctl & 0x2) ? "yes" : "no"); + CX18_INFO("Audio microcontroller: %s\n", + (download_ctl & 0x10) ? "running" : "stopped"); switch (audio_config >> 4) { case 0x00: p = "undefined"; break; @@ -1050,7 +1005,7 @@ static void log_audio_status(struct cx18 *cx) case 0x0f: p = "automatic detection"; break; default: p = "undefined"; break; } - CX18_INFO_DEV(sd, "Configured audio standard: %s\n", p); + CX18_INFO("Configured audio standard: %s\n", p); if ((audio_config >> 4) < 0xF) { switch (audio_config & 0xF) { @@ -1064,7 +1019,7 @@ static void log_audio_status(struct cx18 *cx) case 0x07: p = "DUAL3 (AB)"; break; default: p = "undefined"; } - CX18_INFO_DEV(sd, "Configured audio mode: %s\n", p); + CX18_INFO("Configured audio mode: %s\n", p); } else { switch (audio_config & 0xF) { case 0x00: p = "BG"; break; @@ -1082,14 +1037,14 @@ static void log_audio_status(struct cx18 *cx) case 0x0f: p = "automatic standard and mode detection"; break; default: p = "undefined"; break; } - CX18_INFO_DEV(sd, "Configured audio system: %s\n", p); + CX18_INFO("Configured audio system: %s\n", p); } if (aud_input) - CX18_INFO_DEV(sd, "Specified audio input: Tuner (In%d)\n", - aud_input); + CX18_INFO("Specified audio input: Tuner (In%d)\n", + aud_input); else - CX18_INFO_DEV(sd, "Specified audio input: External\n"); + CX18_INFO("Specified audio input: External\n"); switch (pref_mode & 0xf) { case 0: p = "mono/language A"; break; @@ -1102,14 +1057,14 @@ static void log_audio_status(struct cx18 *cx) case 7: p = "language AB"; break; default: p = "undefined"; break; } - CX18_INFO_DEV(sd, "Preferred audio mode: %s\n", p); + CX18_INFO("Preferred audio mode: %s\n", p); if ((audio_config & 0xf) == 0xf) { switch ((afc0 >> 3) & 0x1) { case 0: p = "system DK"; break; case 1: p = "system L"; break; } - CX18_INFO_DEV(sd, "Selected 65 MHz format: %s\n", p); + CX18_INFO("Selected 65 MHz format: %s\n", p); switch (afc0 & 0x7) { case 0: p = "Chroma"; break; @@ -1119,131 +1074,6 @@ static void log_audio_status(struct cx18 *cx) case 4: p = "autodetect"; break; default: p = "undefined"; break; } - CX18_INFO_DEV(sd, "Selected 45 MHz format: %s\n", p); + CX18_INFO("Selected 45 MHz format: %s\n", p); } } - -static int cx18_av_log_status(struct v4l2_subdev *sd) -{ - struct cx18 *cx = v4l2_get_subdevdata(sd); - log_video_status(cx); - log_audio_status(cx); - return 0; -} - -static inline int cx18_av_dbg_match(const struct v4l2_dbg_match *match) -{ - return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 1; -} - -static int cx18_av_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *chip) -{ - struct cx18_av_state *state = to_cx18_av_state(sd); - - if (cx18_av_dbg_match(&chip->match)) { - chip->ident = state->id; - chip->revision = state->rev; - } - return 0; -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int cx18_av_g_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) -{ - struct cx18 *cx = v4l2_get_subdevdata(sd); - - if (!cx18_av_dbg_match(®->match)) - return -EINVAL; - if ((reg->reg & 0x3) != 0) - return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - reg->size = 4; - reg->val = cx18_av_read4(cx, reg->reg & 0x00000ffc); - return 0; -} - -static int cx18_av_s_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) -{ - struct cx18 *cx = v4l2_get_subdevdata(sd); - - if (!cx18_av_dbg_match(®->match)) - return -EINVAL; - if ((reg->reg & 0x3) != 0) - return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - cx18_av_write4(cx, reg->reg & 0x00000ffc, reg->val); - return 0; -} -#endif - -static const struct v4l2_subdev_core_ops cx18_av_general_ops = { - .g_chip_ident = cx18_av_g_chip_ident, - .log_status = cx18_av_log_status, - .init = cx18_av_init, - .reset = cx18_av_reset, - .queryctrl = cx18_av_queryctrl, - .g_ctrl = cx18_av_g_ctrl, - .s_ctrl = cx18_av_s_ctrl, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .g_register = cx18_av_g_register, - .s_register = cx18_av_s_register, -#endif -}; - -static const struct v4l2_subdev_tuner_ops cx18_av_tuner_ops = { - .s_radio = cx18_av_s_radio, - .s_frequency = cx18_av_s_frequency, - .g_tuner = cx18_av_g_tuner, - .s_tuner = cx18_av_s_tuner, - .s_std = cx18_av_s_std, -}; - -static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = { - .s_clock_freq = cx18_av_s_clock_freq, - .s_routing = cx18_av_s_audio_routing, -}; - -static const struct v4l2_subdev_video_ops cx18_av_video_ops = { - .s_routing = cx18_av_s_video_routing, - .decode_vbi_line = cx18_av_decode_vbi_line, - .s_stream = cx18_av_s_stream, - .g_fmt = cx18_av_g_fmt, - .s_fmt = cx18_av_s_fmt, -}; - -static const struct v4l2_subdev_ops cx18_av_ops = { - .core = &cx18_av_general_ops, - .tuner = &cx18_av_tuner_ops, - .audio = &cx18_av_audio_ops, - .video = &cx18_av_video_ops, -}; - -int cx18_av_probe(struct cx18 *cx) -{ - struct cx18_av_state *state = &cx->av_state; - struct v4l2_subdev *sd; - - state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff; - state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO) - ? V4L2_IDENT_CX23418_843 : V4L2_IDENT_UNKNOWN; - - state->vid_input = CX18_AV_COMPOSITE7; - state->aud_input = CX18_AV_AUDIO8; - state->audclk_freq = 48000; - state->audmode = V4L2_TUNER_MODE_LANG1; - state->slicer_line_delay = 0; - state->slicer_line_offset = (10 + state->slicer_line_delay - 2); - - sd = &state->sd; - v4l2_subdev_init(sd, &cx18_av_ops); - v4l2_set_subdevdata(sd, cx); - snprintf(sd->name, sizeof(sd->name), - "%s %03x", cx->v4l2_dev.name, (state->rev >> 4)); - sd->grp_id = CX18_HW_418_AV; - return v4l2_device_register_subdev(&cx->v4l2_dev, sd); -} diff --git a/trunk/drivers/media/video/cx18/cx18-av-core.h b/trunk/drivers/media/video/cx18/cx18-av-core.h index c458120e8c90..cf68a6039091 100644 --- a/trunk/drivers/media/video/cx18/cx18-av-core.h +++ b/trunk/drivers/media/video/cx18/cx18-av-core.h @@ -25,8 +25,6 @@ #ifndef _CX18_AV_CORE_H_ #define _CX18_AV_CORE_H_ -#include - struct cx18; enum cx18_av_video_input { @@ -75,40 +73,17 @@ enum cx18_av_audio_input { }; struct cx18_av_state { - struct v4l2_subdev sd; int radio; v4l2_std_id std; enum cx18_av_video_input vid_input; enum cx18_av_audio_input aud_input; u32 audclk_freq; int audmode; + int vbi_line_offset; int default_volume; u32 id; u32 rev; int is_initialized; - - /* - * The VBI slicer starts operating and counting lines, begining at - * slicer line count of 1, at D lines after the deassertion of VRESET. - * This staring field line, S, is 6 (& 319) or 10 (& 273) for 625 or 525 - * line systems respectively. Sliced ancillary data captured on VBI - * slicer line M is inserted after the VBI slicer is done with line M, - * when VBI slicer line count is N = M+1. Thus when the VBI slicer - * reports a VBI slicer line number with ancillary data, the IDID0 byte - * indicates VBI slicer line N. The actual field line that the captured - * data comes from is - * - * L = M+(S+D-1) = N-1+(S+D-1) = N + (S+D-2). - * - * L is the line in the field, not frame, from which the VBI data came. - * N is the line reported by the slicer in the ancillary data. - * D is the slicer_line_delay value programmed into register 0x47f. - * S is 6 for 625 line systems or 10 for 525 line systems - * (S+D-2) is the slicer_line_offset used to convert slicer reported - * line counts to actual field lines. - */ - int slicer_line_delay; - int slicer_line_offset; }; @@ -323,16 +298,6 @@ struct cx18_av_state { #define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */ #define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */ -static inline struct cx18_av_state *to_cx18_av_state(struct v4l2_subdev *sd) -{ - return container_of(sd, struct cx18_av_state, sd); -} - -enum cx18_av_subdev_init_arg { - CX18_AV_INIT_NORMAL = 0, - CX18_AV_INIT_PLLS = 1, -}; - /* ----------------------------------------------------------------------- */ /* cx18_av-core.c */ int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); @@ -345,26 +310,20 @@ u8 cx18_av_read(struct cx18 *cx, u16 addr); u32 cx18_av_read4(struct cx18 *cx, u16 addr); int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); +int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); void cx18_av_std_setup(struct cx18 *cx); -int cx18_av_probe(struct cx18 *cx); - /* ----------------------------------------------------------------------- */ /* cx18_av-firmware.c */ int cx18_av_loadfw(struct cx18 *cx); /* ----------------------------------------------------------------------- */ /* cx18_av-audio.c */ -int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl); -int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl); -int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq); +int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg); void cx18_av_audio_set_path(struct cx18 *cx); /* ----------------------------------------------------------------------- */ /* cx18_av-vbi.c */ -int cx18_av_decode_vbi_line(struct v4l2_subdev *sd, - struct v4l2_decode_vbi_line *vbi); -int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt); -int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt); +int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg); #endif diff --git a/trunk/drivers/media/video/cx18/cx18-av-firmware.c b/trunk/drivers/media/video/cx18/cx18-av-firmware.c index 49a55cc8d839..c64fd0a05a97 100644 --- a/trunk/drivers/media/video/cx18/cx18-av-firmware.c +++ b/trunk/drivers/media/video/cx18/cx18-av-firmware.c @@ -29,7 +29,6 @@ int cx18_av_loadfw(struct cx18 *cx) { - struct v4l2_subdev *sd = &cx->av_state.sd; const struct firmware *fw = NULL; u32 size; u32 v; @@ -37,8 +36,8 @@ int cx18_av_loadfw(struct cx18 *cx) int i; int retries1 = 0; - if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) { - CX18_ERR_DEV(sd, "unable to open firmware %s\n", FWFILE); + if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) { + CX18_ERR("unable to open firmware %s\n", FWFILE); return -EINVAL; } @@ -89,7 +88,7 @@ int cx18_av_loadfw(struct cx18 *cx) retries1++; } if (retries1 >= 5) { - CX18_ERR_DEV(sd, "unable to load firmware %s\n", FWFILE); + CX18_ERR("unable to load firmware %s\n", FWFILE); release_firmware(fw); return -EIO; } @@ -116,9 +115,9 @@ int cx18_av_loadfw(struct cx18 *cx) are generated) */ cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0); - /* set alt I2s master clock to /0x16 and enable alt divider i2s + /* set alt I2s master clock to /16 and enable alt divider i2s passthrough */ - cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5600B687); + cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687); cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, 0x000000F6, 0x000000F6, 0x3F00FFFF); @@ -132,8 +131,7 @@ int cx18_av_loadfw(struct cx18 *cx) v = cx18_read_reg(cx, CX18_AUDIO_ENABLE); /* If bit 11 is 1, clear bit 10 */ if (v & 0x800) - cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE, - 0, 0x400); + cx18_write_reg(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE); /* Enable WW auto audio standard detection */ v = cx18_av_read4(cx, CXADEC_STD_DET_CTL); @@ -144,6 +142,6 @@ int cx18_av_loadfw(struct cx18 *cx) release_firmware(fw); - CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size); + CX18_INFO("loaded %s firmware (%d bytes)\n", FWFILE, size); return 0; } diff --git a/trunk/drivers/media/video/cx18/cx18-av-vbi.c b/trunk/drivers/media/video/cx18/cx18-av-vbi.c index 23b31670bf1d..1527ea4f6b06 100644 --- a/trunk/drivers/media/video/cx18/cx18-av-vbi.c +++ b/trunk/drivers/media/video/cx18/cx18-av-vbi.c @@ -24,52 +24,6 @@ #include "cx18-driver.h" -/* - * For sliced VBI output, we set up to use VIP-1.1, 8-bit mode, - * NN counts 1 byte Dwords, an IDID with the VBI line # in it. - * Thus, according to the VIP-2 Spec, our VBI ancillary data lines - * (should!) look like: - * 4 byte EAV code: 0xff 0x00 0x00 0xRP - * unknown number of possible idle bytes - * 3 byte Anc data preamble: 0x00 0xff 0xff - * 1 byte data identifier: ne010iii (parity bits, 010, DID bits) - * 1 byte secondary data id: nessssss (parity bits, SDID bits) - * 1 byte data word count: necccccc (parity bits, NN Dword count) - * 2 byte Internal DID: VBI-line-# 0x80 - * NN data bytes - * 1 byte checksum - * Fill bytes needed to fil out to 4*NN bytes of payload - * - * The RP codes for EAVs when in VIP-1.1 mode, not in raw mode, & - * in the vertical blanking interval are: - * 0xb0 (Task 0 VerticalBlank HorizontalBlank 0 0 0 0) - * 0xf0 (Task EvenField VerticalBlank HorizontalBlank 0 0 0 0) - * - * Since the V bit is only allowed to toggle in the EAV RP code, just - * before the first active region line and for active lines, they are: - * 0x90 (Task 0 0 HorizontalBlank 0 0 0 0) - * 0xd0 (Task EvenField 0 HorizontalBlank 0 0 0 0) - * - * The user application DID bytes we care about are: - * 0x91 (1 0 010 0 !ActiveLine AncDataPresent) - * 0x55 (0 1 010 2ndField !ActiveLine AncDataPresent) - * - */ -static const u8 sliced_vbi_did[2] = { 0x91, 0x55 }; - -struct vbi_anc_data { - /* u8 eav[4]; */ - /* u8 idle[]; Variable number of idle bytes */ - u8 preamble[3]; - u8 did; - u8 sdid; - u8 data_count; - u8 idid[2]; - u8 payload[1]; /* data_count of payload */ - /* u8 checksum; */ - /* u8 fill[]; Variable number of fill bytes */ -}; - static int odd_parity(u8 c) { c ^= (c >> 4); @@ -129,189 +83,188 @@ static int decode_vps(u8 *dst, u8 *p) return err & 0xf0; } -int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt) +int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) { struct cx18_av_state *state = &cx->av_state; + struct v4l2_format *fmt; struct v4l2_sliced_vbi_format *svbi; - static const u16 lcr2vbi[] = { - 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ - 0, V4L2_SLICED_WSS_625, 0, /* 4 */ - V4L2_SLICED_CAPTION_525, /* 6 */ - 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ - 0, 0, 0, 0 - }; - int is_pal = !(state->std & V4L2_STD_525_60); - int i; - - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) - return -EINVAL; - svbi = &fmt->fmt.sliced; - memset(svbi, 0, sizeof(*svbi)); - /* we're done if raw VBI is active */ - if ((cx18_av_read(cx, 0x404) & 0x10) == 0) - return 0; - - if (is_pal) { - for (i = 7; i <= 23; i++) { - u8 v = cx18_av_read(cx, 0x424 + i - 7); - svbi->service_lines[0][i] = lcr2vbi[v >> 4]; - svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; - svbi->service_set |= svbi->service_lines[0][i] | - svbi->service_lines[1][i]; - } - } else { - for (i = 10; i <= 21; i++) { - u8 v = cx18_av_read(cx, 0x424 + i - 10); - - svbi->service_lines[0][i] = lcr2vbi[v >> 4]; - svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; - svbi->service_set |= svbi->service_lines[0][i] | - svbi->service_lines[1][i]; + switch (cmd) { + case VIDIOC_G_FMT: + { + static u16 lcr2vbi[] = { + 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ + 0, V4L2_SLICED_WSS_625, 0, /* 4 */ + V4L2_SLICED_CAPTION_525, /* 6 */ + 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ + 0, 0, 0, 0 + }; + int is_pal = !(state->std & V4L2_STD_525_60); + int i; + + fmt = arg; + if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) + return -EINVAL; + svbi = &fmt->fmt.sliced; + memset(svbi, 0, sizeof(*svbi)); + /* we're done if raw VBI is active */ + if ((cx18_av_read(cx, 0x404) & 0x10) == 0) + break; + + if (is_pal) { + for (i = 7; i <= 23; i++) { + u8 v = cx18_av_read(cx, 0x424 + i - 7); + + svbi->service_lines[0][i] = lcr2vbi[v >> 4]; + svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; + svbi->service_set |= svbi->service_lines[0][i] | + svbi->service_lines[1][i]; + } + } else { + for (i = 10; i <= 21; i++) { + u8 v = cx18_av_read(cx, 0x424 + i - 10); + + svbi->service_lines[0][i] = lcr2vbi[v >> 4]; + svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; + svbi->service_set |= svbi->service_lines[0][i] | + svbi->service_lines[1][i]; + } } + break; } - return 0; -} -int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt) -{ - struct cx18_av_state *state = &cx->av_state; - struct v4l2_sliced_vbi_format *svbi; - int is_pal = !(state->std & V4L2_STD_525_60); - int i, x; - u8 lcr[24]; - - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && - fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE) - return -EINVAL; - svbi = &fmt->fmt.sliced; - if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - /* raw VBI */ - memset(svbi, 0, sizeof(*svbi)); + case VIDIOC_S_FMT: + { + int is_pal = !(state->std & V4L2_STD_525_60); + int vbi_offset = is_pal ? 1 : 0; + int i, x; + u8 lcr[24]; + + fmt = arg; + if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && + fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE) + return -EINVAL; + svbi = &fmt->fmt.sliced; + if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { + /* raw VBI */ + memset(svbi, 0, sizeof(*svbi)); + + /* Setup standard */ + cx18_av_std_setup(cx); + + /* VBI Offset */ + cx18_av_write(cx, 0x47f, vbi_offset); + cx18_av_write(cx, 0x404, 0x2e); + break; + } + + for (x = 0; x <= 23; x++) + lcr[x] = 0x00; /* Setup standard */ cx18_av_std_setup(cx); - /* VBI Offset */ - cx18_av_write(cx, 0x47f, state->slicer_line_delay); - cx18_av_write(cx, 0x404, 0x2e); - return 0; - } - - for (x = 0; x <= 23; x++) - lcr[x] = 0x00; - - /* Setup standard */ - cx18_av_std_setup(cx); - - /* Sliced VBI */ - cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */ - cx18_av_write(cx, 0x406, 0x13); - cx18_av_write(cx, 0x47f, state->slicer_line_delay); - - /* Force impossible lines to 0 */ - if (is_pal) { - for (i = 0; i <= 6; i++) - svbi->service_lines[0][i] = - svbi->service_lines[1][i] = 0; - } else { - for (i = 0; i <= 9; i++) - svbi->service_lines[0][i] = - svbi->service_lines[1][i] = 0; - - for (i = 22; i <= 23; i++) - svbi->service_lines[0][i] = - svbi->service_lines[1][i] = 0; - } + /* Sliced VBI */ + cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */ + cx18_av_write(cx, 0x406, 0x13); + cx18_av_write(cx, 0x47f, vbi_offset); + + if (is_pal) { + for (i = 0; i <= 6; i++) + svbi->service_lines[0][i] = + svbi->service_lines[1][i] = 0; + } else { + for (i = 0; i <= 9; i++) + svbi->service_lines[0][i] = + svbi->service_lines[1][i] = 0; + + for (i = 22; i <= 23; i++) + svbi->service_lines[0][i] = + svbi->service_lines[1][i] = 0; + } - /* Build register values for requested service lines */ - for (i = 7; i <= 23; i++) { - for (x = 0; x <= 1; x++) { - switch (svbi->service_lines[1-x][i]) { - case V4L2_SLICED_TELETEXT_B: - lcr[i] |= 1 << (4 * x); - break; - case V4L2_SLICED_WSS_625: - lcr[i] |= 4 << (4 * x); - break; - case V4L2_SLICED_CAPTION_525: - lcr[i] |= 6 << (4 * x); - break; - case V4L2_SLICED_VPS: - lcr[i] |= 9 << (4 * x); - break; + for (i = 7; i <= 23; i++) { + for (x = 0; x <= 1; x++) { + switch (svbi->service_lines[1-x][i]) { + case V4L2_SLICED_TELETEXT_B: + lcr[i] |= 1 << (4 * x); + break; + case V4L2_SLICED_WSS_625: + lcr[i] |= 4 << (4 * x); + break; + case V4L2_SLICED_CAPTION_525: + lcr[i] |= 6 << (4 * x); + break; + case V4L2_SLICED_VPS: + lcr[i] |= 9 << (4 * x); + break; + } } } - } - - if (is_pal) { - for (x = 1, i = 0x424; i <= 0x434; i++, x++) - cx18_av_write(cx, i, lcr[6 + x]); - } else { - for (x = 1, i = 0x424; i <= 0x430; i++, x++) - cx18_av_write(cx, i, lcr[9 + x]); - for (i = 0x431; i <= 0x434; i++) - cx18_av_write(cx, i, 0); - } - cx18_av_write(cx, 0x43c, 0x16); - /* FIXME - should match vblank set in cx18_av_std_setup() */ - cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26); - return 0; -} + if (is_pal) { + for (x = 1, i = 0x424; i <= 0x434; i++, x++) + cx18_av_write(cx, i, lcr[6 + x]); + } else { + for (x = 1, i = 0x424; i <= 0x430; i++, x++) + cx18_av_write(cx, i, lcr[9 + x]); + for (i = 0x431; i <= 0x434; i++) + cx18_av_write(cx, i, 0); + } -int cx18_av_decode_vbi_line(struct v4l2_subdev *sd, - struct v4l2_decode_vbi_line *vbi) -{ - struct cx18 *cx = v4l2_get_subdevdata(sd); - struct cx18_av_state *state = &cx->av_state; - struct vbi_anc_data *anc = (struct vbi_anc_data *)vbi->p; - u8 *p; - int did, sdid, l, err = 0; - - /* - * Check for the ancillary data header for sliced VBI - */ - if (anc->preamble[0] || - anc->preamble[1] != 0xff || anc->preamble[2] != 0xff || - (anc->did != sliced_vbi_did[0] && - anc->did != sliced_vbi_did[1])) { - vbi->line = vbi->type = 0; - return 0; + cx18_av_write(cx, 0x43c, 0x16); + cx18_av_write(cx, 0x474, is_pal ? 0x2a : 0x22); + break; } - did = anc->did; - sdid = anc->sdid & 0xf; - l = anc->idid[0] & 0x3f; - l += state->slicer_line_offset; - p = anc->payload; + case VIDIOC_INT_DECODE_VBI_LINE: + { + struct v4l2_decode_vbi_line *vbi = arg; + u8 *p = vbi->p; + int id1, id2, l, err = 0; - /* Decode the SDID set by the slicer */ - switch (sdid) { - case 1: - sdid = V4L2_SLICED_TELETEXT_B; - break; - case 4: - sdid = V4L2_SLICED_WSS_625; - break; - case 6: - sdid = V4L2_SLICED_CAPTION_525; - err = !odd_parity(p[0]) || !odd_parity(p[1]); - break; - case 9: - sdid = V4L2_SLICED_VPS; - if (decode_vps(p, p) != 0) + if (p[0] || p[1] != 0xff || p[2] != 0xff || + (p[3] != 0x55 && p[3] != 0x91)) { + vbi->line = vbi->type = 0; + break; + } + + p += 4; + id1 = p[-1]; + id2 = p[0] & 0xf; + l = p[2] & 0x3f; + l += state->vbi_line_offset; + p += 4; + + switch (id2) { + case 1: + id2 = V4L2_SLICED_TELETEXT_B; + break; + case 4: + id2 = V4L2_SLICED_WSS_625; + break; + case 6: + id2 = V4L2_SLICED_CAPTION_525; + err = !odd_parity(p[0]) || !odd_parity(p[1]); + break; + case 9: + id2 = V4L2_SLICED_VPS; + if (decode_vps(p, p) != 0) + err = 1; + break; + default: + id2 = 0; err = 1; + break; + } + + vbi->type = err ? 0 : id2; + vbi->line = err ? 0 : l; + vbi->is_second_field = err ? 0 : (id1 == 0x55); + vbi->p = p; break; - default: - sdid = 0; - err = 1; - break; + } } - vbi->type = err ? 0 : sdid; - vbi->line = err ? 0 : l; - vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]); - vbi->p = p; return 0; } diff --git a/trunk/drivers/media/video/cx18/cx18-cards.c b/trunk/drivers/media/video/cx18/cx18-cards.c index 9bc221837847..e274043657dd 100644 --- a/trunk/drivers/media/video/cx18/cx18-cards.c +++ b/trunk/drivers/media/video/cx18/cx18-cards.c @@ -51,12 +51,12 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = { static const struct cx18_card cx18_card_hvr1600_esmt = { .type = CX18_CARD_HVR_1600_ESMT, .name = "Hauppauge HVR-1600", - .comment = "Simultaneous Digital and Analog TV capture supported\n", + .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_418_AV, + .hw_audio_ctrl = CX18_HW_CX23418, .hw_muxer = CX18_HW_CS5345, - .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER | - CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL, + .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | + CX18_HW_CS5345 | CX18_HW_DVB, .video_inputs = { { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, @@ -97,12 +97,12 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { static const struct cx18_card cx18_card_hvr1600_samsung = { .type = CX18_CARD_HVR_1600_SAMSUNG, .name = "Hauppauge HVR-1600 (Preproduction)", - .comment = "Simultaneous Digital and Analog TV capture supported\n", + .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_418_AV, + .hw_audio_ctrl = CX18_HW_CX23418, .hw_muxer = CX18_HW_CS5345, - .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER | - CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL, + .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | + CX18_HW_CS5345 | CX18_HW_DVB, .video_inputs = { { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, @@ -152,10 +152,10 @@ static const struct cx18_card_pci_info cx18_pci_h900[] = { static const struct cx18_card cx18_card_h900 = { .type = CX18_CARD_COMPRO_H900, .name = "Compro VideoMate H900", - .comment = "Analog TV capture supported\n", + .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_418_AV, - .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL, + .hw_audio_ctrl = CX18_HW_CX23418, + .hw_all = CX18_HW_TUNER, .video_inputs = { { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, { CX18_CARD_INPUT_SVIDEO1, 1, @@ -201,8 +201,8 @@ static const struct cx18_card cx18_card_mpc718 = { .name = "Yuan MPC718", .comment = "Analog video capture works; some audio line in may not.\n", .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_418_AV, - .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL, + .hw_audio_ctrl = CX18_HW_CX23418, + .hw_all = CX18_HW_TUNER, .video_inputs = { { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, { CX18_CARD_INPUT_SVIDEO1, 1, @@ -249,11 +249,11 @@ static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = { static const struct cx18_card cx18_card_cnxt_raptor_pal = { .type = CX18_CARD_CNXT_RAPTOR_PAL, .name = "Conexant Raptor PAL/SECAM", - .comment = "Analog TV capture supported\n", + .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_418_AV, - .hw_muxer = CX18_HW_GPIO_MUX, - .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX, + .hw_audio_ctrl = CX18_HW_CX23418, + .hw_muxer = CX18_HW_GPIO, + .hw_all = CX18_HW_TUNER | CX18_HW_GPIO, .video_inputs = { { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, { CX18_CARD_INPUT_SVIDEO1, 1, @@ -306,8 +306,8 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = { .comment = "Experimenters and photos needed for device to work well.\n" "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_418_AV, - .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL, + .hw_audio_ctrl = CX18_HW_CX23418, + .hw_all = CX18_HW_TUNER, .video_inputs = { { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE6 }, { CX18_CARD_INPUT_SVIDEO1, 1, @@ -339,21 +339,19 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = { /* Leadtek WinFast PVR2100 */ static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = { - { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */ - { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */ + { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, { 0, 0, 0 } }; static const struct cx18_card cx18_card_leadtek_pvr2100 = { .type = CX18_CARD_LEADTEK_PVR2100, - .name = "Leadtek WinFast PVR2100/DVR3100 H", + .name = "Leadtek WinFast PVR2100", .comment = "Experimenters and photos needed for device to work well.\n" "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_418_AV, - .hw_muxer = CX18_HW_GPIO_MUX, - .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX | - CX18_HW_GPIO_RESET_CTRL, + .hw_audio_ctrl = CX18_HW_CX23418, + .hw_muxer = CX18_HW_GPIO, + .hw_all = CX18_HW_TUNER | CX18_HW_GPIO, .video_inputs = { { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, { CX18_CARD_INPUT_SVIDEO1, 1, diff --git a/trunk/drivers/media/video/cx18/cx18-cards.h b/trunk/drivers/media/video/cx18/cx18-cards.h index 3c552b6b7c4d..6fa7bcb42dde 100644 --- a/trunk/drivers/media/video/cx18/cx18-cards.h +++ b/trunk/drivers/media/video/cx18/cx18-cards.h @@ -22,13 +22,12 @@ */ /* hardware flags */ -#define CX18_HW_TUNER (1 << 0) -#define CX18_HW_TVEEPROM (1 << 1) -#define CX18_HW_CS5345 (1 << 2) -#define CX18_HW_DVB (1 << 3) -#define CX18_HW_418_AV (1 << 4) -#define CX18_HW_GPIO_MUX (1 << 5) -#define CX18_HW_GPIO_RESET_CTRL (1 << 6) +#define CX18_HW_TUNER (1 << 0) +#define CX18_HW_TVEEPROM (1 << 1) +#define CX18_HW_CS5345 (1 << 2) +#define CX18_HW_GPIO (1 << 3) +#define CX18_HW_CX23418 (1 << 4) +#define CX18_HW_DVB (1 << 5) /* video inputs */ #define CX18_CARD_INPUT_VID_TUNER 1 @@ -50,7 +49,8 @@ /* V4L2 capability aliases */ #define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | \ - V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE) + V4L2_CAP_VBI_CAPTURE) +/* | V4L2_CAP_SLICED_VBI_CAPTURE) not yet */ struct cx18_card_video_input { u8 video_type; /* video input type */ @@ -122,7 +122,7 @@ struct cx18_card { char *comment; u32 v4l2_capabilities; u32 hw_audio_ctrl; /* hardware used for the V4L2 controls (only - 1 dev allowed currently) */ + 1 dev allowed) */ u32 hw_muxer; /* hardware used to multiplex audio input */ u32 hw_all; /* all hardware used by the board */ struct cx18_card_video_input video_inputs[CX18_CARD_MAX_VIDEO_INPUTS]; diff --git a/trunk/drivers/media/video/cx18/cx18-controls.c b/trunk/drivers/media/video/cx18/cx18-controls.c index 82fc2f9d4021..17edf305d649 100644 --- a/trunk/drivers/media/video/cx18/cx18-controls.c +++ b/trunk/drivers/media/video/cx18/cx18-controls.c @@ -22,13 +22,14 @@ */ #include "cx18-driver.h" +#include "cx18-av-core.h" #include "cx18-cards.h" #include "cx18-ioctl.h" #include "cx18-audio.h" +#include "cx18-i2c.h" #include "cx18-mailbox.h" #include "cx18-controls.h" -/* Must be sorted from low to high control ID! */ static const u32 user_ctrls[] = { V4L2_CID_USER_CLASS, V4L2_CID_BRIGHTNESS, @@ -65,7 +66,7 @@ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) case V4L2_CID_HUE: case V4L2_CID_SATURATION: case V4L2_CID_CONTRAST: - if (v4l2_subdev_call(cx->sd_av, core, queryctrl, qctrl)) + if (cx18_av_cmd(cx, VIDIOC_QUERYCTRL, qctrl)) qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; return 0; @@ -75,7 +76,7 @@ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) case V4L2_CID_AUDIO_BASS: case V4L2_CID_AUDIO_TREBLE: case V4L2_CID_AUDIO_LOUDNESS: - if (v4l2_subdev_call(cx->sd_av, core, queryctrl, qctrl)) + if (cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_QUERYCTRL, qctrl)) qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; return 0; @@ -124,7 +125,7 @@ static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) case V4L2_CID_HUE: case V4L2_CID_SATURATION: case V4L2_CID_CONTRAST: - return v4l2_subdev_call(cx->sd_av, core, s_ctrl, vctrl); + return cx18_av_cmd(cx, VIDIOC_S_CTRL, vctrl); case V4L2_CID_AUDIO_VOLUME: case V4L2_CID_AUDIO_MUTE: @@ -132,7 +133,7 @@ static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) case V4L2_CID_AUDIO_BASS: case V4L2_CID_AUDIO_TREBLE: case V4L2_CID_AUDIO_LOUDNESS: - return v4l2_subdev_call(cx->sd_av, core, s_ctrl, vctrl); + return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl); default: CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id); @@ -149,7 +150,7 @@ static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) case V4L2_CID_HUE: case V4L2_CID_SATURATION: case V4L2_CID_CONTRAST: - return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl); + return cx18_av_cmd(cx, VIDIOC_G_CTRL, vctrl); case V4L2_CID_AUDIO_VOLUME: case V4L2_CID_AUDIO_MUTE: @@ -157,8 +158,7 @@ static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) case V4L2_CID_AUDIO_BASS: case V4L2_CID_AUDIO_TREBLE: case V4L2_CID_AUDIO_LOUDNESS: - return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl); - + return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl); default: CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id); return -EINVAL; @@ -166,57 +166,38 @@ static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) return 0; } -static int cx18_setup_vbi_fmt(struct cx18 *cx, - enum v4l2_mpeg_stream_vbi_fmt fmt, - enum v4l2_mpeg_stream_type type) +static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt) { if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE)) return -EINVAL; if (atomic_read(&cx->ana_capturing) > 0) return -EBUSY; - if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV || - type != V4L2_MPEG_STREAM_TYPE_MPEG2_PS) { - /* We don't do VBI insertion aside from IVTV format in a PS */ - cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE; - CX18_DEBUG_INFO("disabled insertion of sliced VBI data into " - "the MPEG stream\n"); - return 0; - } - - /* Allocate sliced VBI buffers if needed. */ - if (cx->vbi.sliced_mpeg_data[0] == NULL) { + /* First try to allocate sliced VBI buffers if needed. */ + if (fmt && cx->vbi.sliced_mpeg_data[0] == NULL) { int i; for (i = 0; i < CX18_VBI_FRAMES; i++) { - cx->vbi.sliced_mpeg_data[i] = - kmalloc(CX18_SLICED_MPEG_DATA_BUFSZ, GFP_KERNEL); + /* Yuck, hardcoded. Needs to be a define */ + cx->vbi.sliced_mpeg_data[i] = kmalloc(2049, GFP_KERNEL); if (cx->vbi.sliced_mpeg_data[i] == NULL) { while (--i >= 0) { kfree(cx->vbi.sliced_mpeg_data[i]); cx->vbi.sliced_mpeg_data[i] = NULL; } - cx->vbi.insert_mpeg = - V4L2_MPEG_STREAM_VBI_FMT_NONE; - CX18_WARN("Unable to allocate buffers for " - "sliced VBI data insertion\n"); return -ENOMEM; } } } cx->vbi.insert_mpeg = fmt; - CX18_DEBUG_INFO("enabled insertion of sliced VBI data into the MPEG PS," - "when sliced VBI is enabled\n"); - /* - * If our current settings have no lines set for capture, store a valid, - * default set of service lines to capture, in our current settings. - */ + if (cx->vbi.insert_mpeg == 0) + return 0; + /* Need sliced data for mpeg insertion */ if (cx18_get_service_set(cx->vbi.sliced_in) == 0) { if (cx->is_60hz) - cx->vbi.sliced_in->service_set = - V4L2_SLICED_CAPTION_525; + cx->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525; else cx->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625; cx18_expand_service_set(cx->vbi.sliced_in, cx->is_50hz); @@ -278,12 +259,10 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) return err; } if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - static u32 freqs[3] = { 44100, 48000, 32000 }; struct cx18_api_func_private priv; struct cx2341x_mpeg_params p = cx->params; int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing), c, VIDIOC_S_EXT_CTRLS); - unsigned int idx; if (err) return err; @@ -298,23 +277,16 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) fmt.fmt.pix.width = cx->params.width / (is_mpeg1 ? 2 : 1); fmt.fmt.pix.height = cx->params.height; - v4l2_subdev_call(cx->sd_av, video, s_fmt, &fmt); + cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt); } priv.cx = cx; priv.s = &cx->streams[id->type]; err = cx2341x_update(&priv, cx18_api_func, &cx->params, &p); - if (!err && - (cx->params.stream_vbi_fmt != p.stream_vbi_fmt || - cx->params.stream_type != p.stream_type)) - err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt, - p.stream_type); + if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt) + err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt); cx->params = p; cx->dualwatch_stereo_mode = p.audio_properties & 0x0300; - idx = p.audio_properties & 0x03; - /* The audio clock of the digitizer must match the codec sample - rate otherwise you get some very strange effects. */ - if (idx < sizeof(freqs)) - cx18_call_all(cx, audio, s_clock_freq, freqs[idx]); + cx18_audio_set_audio_clock_freq(cx, p.audio_properties & 0x03); return err; } return -EINVAL; diff --git a/trunk/drivers/media/video/cx18/cx18-driver.c b/trunk/drivers/media/video/cx18/cx18-driver.c index 210c68aaae00..f50cf2167adc 100644 --- a/trunk/drivers/media/video/cx18/cx18-driver.c +++ b/trunk/drivers/media/video/cx18/cx18-driver.c @@ -39,6 +39,10 @@ #include + +/* var to keep track of the number of array elements in use */ +int cx18_cards_active; + /* If you have already X v4l cards, then set this to X. This way the device numbers stay matched. Example: you have a WinTV card without radio and a Compro H900 with. Normally this would give a @@ -46,6 +50,12 @@ setting this to 1 you ensure that radio0 is now also radio1. */ int cx18_first_minor; +/* Master variable for all cx18 info */ +struct cx18 *cx18_cards[CX18_MAX_CARDS]; + +/* Protects cx18_cards_active */ +DEFINE_SPINLOCK(cx18_cards_lock); + /* add your revision and whatnot here */ static struct pci_device_id cx18_pci_tbl[] __devinitdata = { {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418, @@ -55,8 +65,6 @@ static struct pci_device_id cx18_pci_tbl[] __devinitdata = { MODULE_DEVICE_TABLE(pci, cx18_pci_tbl); -static atomic_t cx18_instance = ATOMIC_INIT(0); - /* Parameter declarations */ static int cardtype[CX18_MAX_CARDS]; static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, @@ -151,7 +159,7 @@ MODULE_PARM_DESC(cardtype, "\t\t\t 4 = Yuan MPC718\n" "\t\t\t 5 = Conexant Raptor PAL/SECAM\n" "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n" - "\t\t\t 7 = Leadtek WinFast PVR2100/DVR3100 H\n" + "\t\t\t 7 = Leadtek WinFast PVR2100\n" "\t\t\t 0 = Autodetect (default)\n" "\t\t\t-1 = Ignore this card\n\t\t"); MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); @@ -269,16 +277,11 @@ static void cx18_iounmap(struct cx18 *cx) /* Hauppauge card? get values from tveeprom */ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv) { - struct i2c_client c; u8 eedata[256]; - memset(&c, 0, sizeof(c)); - strlcpy(c.name, "cx18 tveeprom tmp", sizeof(c.name)); - c.adapter = &cx->i2c_adap[0]; - c.addr = 0xA0 >> 1; - - tveeprom_read(&c, eedata, sizeof(eedata)); - tveeprom_hauppauge_analog(&c, tv, eedata); + cx->i2c_client[0].addr = 0xA0 >> 1; + tveeprom_read(&cx->i2c_client[0], eedata, sizeof(eedata)); + tveeprom_hauppauge_analog(&cx->i2c_client[0], tv, eedata); } static void cx18_process_eeprom(struct cx18 *cx) @@ -445,38 +448,34 @@ static void cx18_process_options(struct cx18 *cx) cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize; cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize; cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize; - cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_active_samples * 36; + cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = 0; /* computed later */ cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize; cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */ - /* Ensure stream_buffers & stream_buf_size are valid */ + /* Except for VBI ensure stream_buffers & stream_buf_size are valid */ for (i = 0; i < CX18_MAX_STREAMS; i++) { - if (cx->stream_buffers[i] == 0 || /* User said 0 buffers */ - cx->options.megabytes[i] <= 0 || /* User said 0 MB total */ - cx->stream_buf_size[i] <= 0) { /* User said buf size 0 */ + /* User said to use 0 buffers */ + if (cx->stream_buffers[i] == 0) { + cx->options.megabytes[i] = 0; + cx->stream_buf_size[i] = 0; + continue; + } + /* User said to use 0 MB total */ + if (cx->options.megabytes[i] <= 0) { cx->options.megabytes[i] = 0; cx->stream_buffers[i] = 0; cx->stream_buf_size[i] = 0; continue; } - /* - * VBI is a special case where the stream_buf_size is fixed - * and already in bytes - */ - if (i == CX18_ENC_STREAM_TYPE_VBI) { - if (cx->stream_buffers[i] < 0) { - cx->stream_buffers[i] = - cx->options.megabytes[i] * 1024 * 1024 - / cx->stream_buf_size[i]; - } else { - /* N.B. This might round down to 0 */ - cx->options.megabytes[i] = - cx->stream_buffers[i] - * cx->stream_buf_size[i]/(1024 * 1024); + /* VBI is computed later or user said buffer has size 0 */ + if (cx->stream_buf_size[i] <= 0) { + if (i != CX18_ENC_STREAM_TYPE_VBI) { + cx->options.megabytes[i] = 0; + cx->stream_buffers[i] = 0; + cx->stream_buf_size[i] = 0; } continue; } - /* All other streams have stream_buf_size in kB at this point */ if (cx->stream_buffers[i] < 0) { cx->stream_buffers[i] = cx->options.megabytes[i] * 1024 / cx->stream_buf_size[i]; @@ -488,9 +487,9 @@ static void cx18_process_options(struct cx18 *cx) cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */ } - cx->options.cardtype = cardtype[cx->instance]; - cx->options.tuner = tuner[cx->instance]; - cx->options.radio = radio[cx->instance]; + cx->options.cardtype = cardtype[cx->num]; + cx->options.tuner = tuner[cx->num]; + cx->options.radio = radio[cx->num]; cx->std = cx18_parse_std(cx); if (cx->options.cardtype == -1) { @@ -503,7 +502,7 @@ static void cx18_process_options(struct cx18 *cx) else if (cx->options.cardtype != 0) CX18_ERR("Unknown user specified type, trying to autodetect card\n"); if (cx->card == NULL) { - if (cx->pci_dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) { + if (cx->dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) { cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); CX18_INFO("Autodetected Hauppauge card\n"); } @@ -513,13 +512,13 @@ static void cx18_process_options(struct cx18 *cx) if (cx->card->pci_list == NULL) continue; for (j = 0; cx->card->pci_list[j].device; j++) { - if (cx->pci_dev->device != + if (cx->dev->device != cx->card->pci_list[j].device) continue; - if (cx->pci_dev->subsystem_vendor != + if (cx->dev->subsystem_vendor != cx->card->pci_list[j].subsystem_vendor) continue; - if (cx->pci_dev->subsystem_device != + if (cx->dev->subsystem_device != cx->card->pci_list[j].subsystem_device) continue; CX18_INFO("Autodetected %s card\n", cx->card->name); @@ -532,10 +531,9 @@ static void cx18_process_options(struct cx18 *cx) if (cx->card == NULL) { cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n", - cx->pci_dev->vendor, cx->pci_dev->device); + cx->dev->vendor, cx->dev->device); CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n", - cx->pci_dev->subsystem_vendor, - cx->pci_dev->subsystem_device); + cx->dev->subsystem_vendor, cx->dev->subsystem_device); CX18_ERR("Defaulting to %s card\n", cx->card->name); CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n"); CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n"); @@ -547,7 +545,7 @@ static void cx18_process_options(struct cx18 *cx) } /* Precondition: the cx18 structure has been memset to 0. Only - the dev and instance fields have been filled in. + the dev and num fields have been filled in. No assumptions on the card type may be made here (see cx18_init_struct2 for that). */ @@ -555,14 +553,18 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) { int i; - cx->base_addr = pci_resource_start(cx->pci_dev, 0); + cx->base_addr = pci_resource_start(cx->dev, 0); mutex_init(&cx->serialize_lock); + mutex_init(&cx->i2c_bus_lock[0]); + mutex_init(&cx->i2c_bus_lock[1]); mutex_init(&cx->gpio_lock); mutex_init(&cx->epu2apu_mb_lock); mutex_init(&cx->epu2cpu_mb_lock); - cx->work_queue = create_singlethread_workqueue(cx->v4l2_dev.name); + spin_lock_init(&cx->lock); + + cx->work_queue = create_singlethread_workqueue(cx->name); if (cx->work_queue == NULL) { CX18_ERR("Unable to create work hander thread\n"); return -ENOMEM; @@ -585,8 +587,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) (cx->params.video_temporal_filter_mode << 1) | (cx->params.video_median_filter_type << 2); cx->params.port = CX2341X_PORT_MEMORY; - cx->params.capabilities = - CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_SLICED_VBI; + cx->params.capabilities = CX2341X_CAP_HAS_TS; init_waitqueue_head(&cx->cap_w); init_waitqueue_head(&cx->mb_apu_waitq); init_waitqueue_head(&cx->mb_cpu_waitq); @@ -596,6 +597,49 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced; + /* + * The VBI line sizes depend on the pixel clock and the horiz rate + * + * (1/Fh)*(2*Fp) = Samples/line + * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples + * + * Sliced VBI is sent as ancillary data during horizontal blanking + * Raw VBI is sent as active video samples during vertcal blanking + * + * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line + * length of 720 pixels @ 4:2:2 sampling. Thus... + * + * For systems that use a 15.734 kHz horizontal rate, such as + * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have: + * + * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line = + * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples + * + * For systems that use a 15.625 kHz horizontal rate, such as + * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have: + * + * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line = + * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples + * + */ + + /* FIXME: init these based on tuner std & modify when std changes */ + /* CX18-AV-Core number of VBI samples output per horizontal line */ + cx->vbi.raw_decoder_line_size = 1444; /* 4 byte SAV + 2 * 720 */ + cx->vbi.sliced_decoder_line_size = 272; /* 60 Hz: 268+4, 50 Hz: 280+4 */ + + /* CX18-AV-Core VBI samples/line possibly rounded up */ + cx->vbi.raw_size = 1444; /* Real max size is 1444 */ + cx->vbi.sliced_size = 284; /* Real max size is 284 */ + + /* + * CX18-AV-Core SAV/EAV RP codes in VIP 1.x mode + * Task Field VerticalBlank HorizontalBlank 0 0 0 0 + */ + cx->vbi.raw_decoder_sav_odd_field = 0x20; /* V */ + cx->vbi.raw_decoder_sav_even_field = 0x60; /* FV */ + cx->vbi.sliced_decoder_sav_odd_field = 0xB0; /* T VH - actually EAV */ + cx->vbi.sliced_decoder_sav_even_field = 0xF0; /* TFVH - actually EAV */ return 0; } @@ -624,9 +668,15 @@ static void __devinit cx18_init_struct2(struct cx18 *cx) i = 0; cx->active_input = i; cx->audio_input = cx->card->video_inputs[i].audio_index; + cx->av_state.vid_input = CX18_AV_COMPOSITE7; + cx->av_state.aud_input = CX18_AV_AUDIO8; + cx->av_state.audclk_freq = 48000; + cx->av_state.audmode = V4L2_TUNER_MODE_LANG1; + /* FIXME - 8 is NTSC value, investigate */ + cx->av_state.vbi_line_offset = 8; } -static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev, +static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev, const struct pci_device_id *pci_id) { u16 cmd; @@ -634,125 +684,124 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev, CX18_DEBUG_INFO("Enabling pci device\n"); - if (pci_enable_device(pci_dev)) { - CX18_ERR("Can't enable device %d!\n", cx->instance); + if (pci_enable_device(dev)) { + CX18_ERR("Can't enable device %d!\n", cx->num); return -EIO; } - if (pci_set_dma_mask(pci_dev, 0xffffffff)) { - CX18_ERR("No suitable DMA available, card %d\n", cx->instance); + if (pci_set_dma_mask(dev, 0xffffffff)) { + CX18_ERR("No suitable DMA available on card %d.\n", cx->num); return -EIO; } if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) { - CX18_ERR("Cannot request encoder memory region, card %d\n", - cx->instance); + CX18_ERR("Cannot request encoder memory region on card %d.\n", cx->num); return -EIO; } /* Enable bus mastering and memory mapped IO for the CX23418 */ - pci_read_config_word(pci_dev, PCI_COMMAND, &cmd); + pci_read_config_word(dev, PCI_COMMAND, &cmd); cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - pci_write_config_word(pci_dev, PCI_COMMAND, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); - pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &cx->card_rev); - pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency); + pci_read_config_byte(dev, PCI_CLASS_REVISION, &cx->card_rev); + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); if (pci_latency < 64 && cx18_pci_latency) { CX18_INFO("Unreasonably low latency timer, " "setting to 64 (was %d)\n", pci_latency); - pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, 64); - pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); } CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, " "irq: %d, latency: %d, memory: 0x%lx\n", - cx->pci_dev->device, cx->card_rev, pci_dev->bus->number, - PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn), - cx->pci_dev->irq, pci_latency, (unsigned long)cx->base_addr); + cx->dev->device, cx->card_rev, dev->bus->number, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), + cx->dev->irq, pci_latency, (unsigned long)cx->base_addr); return 0; } -static void cx18_init_subdevs(struct cx18 *cx) +#ifdef MODULE +static u32 cx18_request_module(struct cx18 *cx, u32 hw, + const char *name, u32 id) +{ + if ((hw & id) == 0) + return hw; + if (request_module(name) != 0) { + CX18_ERR("Failed to load module %s\n", name); + return hw & ~id; + } + CX18_DEBUG_INFO("Loaded module %s\n", name); + return hw; +} +#endif + +static void cx18_load_and_init_modules(struct cx18 *cx) { u32 hw = cx->card->hw_all; - u32 device; int i; - for (i = 0, device = 1; i < 32; i++, device <<= 1) { +#ifdef MODULE + /* load modules */ +#ifdef CONFIG_MEDIA_TUNER_MODULE + hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER); +#endif +#ifdef CONFIG_VIDEO_CS5345_MODULE + hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345); +#endif +#endif + + /* check which i2c devices are actually found */ + for (i = 0; i < 32; i++) { + u32 device = 1 << i; if (!(device & hw)) continue; - - switch (device) { - case CX18_HW_DVB: - case CX18_HW_TVEEPROM: - /* These subordinate devices do not use probing */ - cx->hw_flags |= device; - break; - case CX18_HW_418_AV: - /* The A/V decoder gets probed earlier to set PLLs */ - /* Just note that the card uses it (i.e. has analog) */ + if (device == CX18_HW_GPIO || device == CX18_HW_TVEEPROM || + device == CX18_HW_CX23418 || device == CX18_HW_DVB) { + /* These 'devices' do not use i2c probing */ cx->hw_flags |= device; - break; - case CX18_HW_GPIO_RESET_CTRL: - /* - * The Reset Controller gets probed and added to - * hw_flags earlier for i2c adapter/bus initialization - */ - break; - case CX18_HW_GPIO_MUX: - if (cx18_gpio_register(cx, device) == 0) - cx->hw_flags |= device; - break; - default: - if (cx18_i2c_register(cx, i) == 0) - cx->hw_flags |= device; - break; + continue; } + cx18_i2c_register(cx, i); + if (cx18_i2c_hw_addr(cx, device) > 0) + cx->hw_flags |= device; } - if (cx->hw_flags & CX18_HW_418_AV) - cx->sd_av = cx18_find_hw(cx, CX18_HW_418_AV); - - if (cx->card->hw_muxer != 0) - cx->sd_extmux = cx18_find_hw(cx, cx->card->hw_muxer); + hw = cx->hw_flags; } -static int __devinit cx18_probe(struct pci_dev *pci_dev, +static int __devinit cx18_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) { int retval = 0; int i; + int vbi_buf_size; u32 devtype; struct cx18 *cx; - /* FIXME - module parameter arrays constrain max instances */ - i = atomic_inc_return(&cx18_instance) - 1; - if (i >= CX18_MAX_CARDS) { - printk(KERN_ERR "cx18: cannot manage card %d, driver has a " - "limit of 0 - %d\n", i, CX18_MAX_CARDS - 1); + spin_lock(&cx18_cards_lock); + + /* Make sure we've got a place for this card */ + if (cx18_cards_active == CX18_MAX_CARDS) { + printk(KERN_ERR "cx18: Maximum number of cards detected (%d).\n", + cx18_cards_active); + spin_unlock(&cx18_cards_lock); return -ENOMEM; } cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC); - if (cx == NULL) { - printk(KERN_ERR "cx18: cannot manage card %d, out of memory\n", - i); + if (!cx) { + spin_unlock(&cx18_cards_lock); return -ENOMEM; } - cx->pci_dev = pci_dev; - cx->instance = i; + cx18_cards[cx18_cards_active] = cx; + cx->dev = dev; + cx->num = cx18_cards_active++; + snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num); + CX18_INFO("Initializing card #%d\n", cx->num); - retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev); - if (retval) { - printk(KERN_ERR "cx18: v4l2_device_register of card %d failed" - "\n", cx->instance); - kfree(cx); - return retval; - } - snprintf(cx->v4l2_dev.name, sizeof(cx->v4l2_dev.name), "cx18-%d", - cx->instance); - CX18_INFO("Initializing card %d\n", cx->instance); + spin_unlock(&cx18_cards_lock); cx18_process_options(cx); if (cx->options.cardtype == -1) { @@ -767,10 +816,13 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); /* PCI Device Setup */ - retval = cx18_setup_pci(cx, pci_dev, pci_id); + retval = cx18_setup_pci(cx, dev, pci_id); if (retval != 0) goto free_workqueue; + /* save cx in the pci struct for later use */ + pci_set_drvdata(dev, cx); + /* map io memory */ CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); @@ -804,23 +856,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, cx18_gpio_init(cx); - /* Initialize integrated A/V decoder early to set PLLs, just in case */ - retval = cx18_av_probe(cx); - if (retval) { - CX18_ERR("Could not register A/V decoder subdevice\n"); - goto free_map; - } - cx18_call_hw(cx, CX18_HW_418_AV, core, init, (u32) CX18_AV_INIT_PLLS); - - /* Initialize GPIO Reset Controller to do chip resets during i2c init */ - if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) { - if (cx18_gpio_register(cx, CX18_HW_GPIO_RESET_CTRL) != 0) - CX18_WARN("Could not register GPIO reset controller" - "subdevice; proceeding anyway.\n"); - else - cx->hw_flags |= CX18_HW_GPIO_RESET_CTRL; - } - /* active i2c */ CX18_DEBUG_INFO("activating i2c...\n"); retval = init_cx18_i2c(cx); @@ -829,6 +864,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, goto free_map; } + CX18_DEBUG_INFO("Active card count: %d.\n", cx18_cards_active); + if (cx->card->hw_all & CX18_HW_TVEEPROM) { /* Based on the model number the cardtype may be changed. The PCI IDs are not always reliable. */ @@ -844,9 +881,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, cx18_init_scb(cx); /* Register IRQ */ - retval = request_irq(cx->pci_dev->irq, cx18_irq_handler, - IRQF_SHARED | IRQF_DISABLED, - cx->v4l2_dev.name, (void *)cx); + retval = request_irq(cx->dev->irq, cx18_irq_handler, + IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx); if (retval) { CX18_ERR("Failed to register irq %d\n", retval); goto free_i2c; @@ -881,15 +917,34 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, initialization. */ cx18_init_struct2(cx); - cx18_init_subdevs(cx); + cx18_load_and_init_modules(cx); - if (cx->std & V4L2_STD_525_60) + if (cx->std & V4L2_STD_525_60) { cx->is_60hz = 1; - else + cx->is_out_60hz = 1; + } else { cx->is_50hz = 1; - + cx->is_out_50hz = 1; + } cx->params.video_gop_size = cx->is_60hz ? 15 : 12; + /* + * FIXME: setting the buffer size based on the tuner standard is + * suboptimal, as the CVBS and SVideo inputs could use a different std + * and the buffer could end up being too small in that case. + */ + vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2; + cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size; + + if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0) + cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] = + cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] * 1024 * 1024 + / vbi_buf_size; + else + cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = + cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] * vbi_buf_size + / (1024 * 1024); + if (cx->options.radio > 0) cx->v4l2_cap |= V4L2_CAP_RADIO; @@ -901,7 +956,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */ setup.tuner_callback = (setup.type == TUNER_XC2028) ? cx18_reset_tuner_gpio : NULL; - cx18_call_all(cx, tuner, s_type_addr, &setup); + cx18_call_i2c_clients(cx, TUNER_SET_TYPE_ADDR, &setup); if (setup.type == TUNER_XC2028) { static struct xc2028_ctrl ctrl = { .fname = XC2028_DEFAULT_FIRMWARE, @@ -911,7 +966,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, .tuner = cx->options.tuner, .priv = &ctrl, }; - cx18_call_all(cx, tuner, s_config, &cfg); + cx18_call_i2c_clients(cx, TUNER_SET_CONFIG, &cfg); } } @@ -930,13 +985,14 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, goto free_streams; } - CX18_INFO("Initialized card: %s\n", cx->card_name); + CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name); + return 0; free_streams: cx18_streams_cleanup(cx, 1); free_irq: - free_irq(cx->pci_dev->irq, (void *)cx); + free_irq(cx->dev->irq, (void *)cx); free_i2c: exit_cx18_i2c(cx); free_map: @@ -950,8 +1006,11 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, retval = -ENODEV; CX18_ERR("Error %d on initialization\n", retval); - v4l2_device_unregister(&cx->v4l2_dev); - kfree(cx); + i = cx->num; + spin_lock(&cx18_cards_lock); + kfree(cx18_cards[i]); + cx18_cards[i] = NULL; + spin_unlock(&cx18_cards_lock); return retval; } @@ -984,21 +1043,8 @@ int cx18_init_on_first_open(struct cx18 *cx) } set_bit(CX18_F_I_LOADED_FW, &cx->i_flags); - /* - * Init the firmware twice to work around a silicon bug - * with the digital TS. - * - * The second firmware load requires us to normalize the APU state, - * or the audio for the first analog capture will be badly incorrect. - * - * I can't seem to call APU_RESETAI and have it succeed without the - * APU capturing audio, so we start and stop it here to do the reset - */ - - /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */ - cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0); - cx18_vapi(cx, CX18_APU_RESETAI, 0); - cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG); + /* Init the firmware twice to work around a silicon bug + * transport related. */ fw_retry_count = 3; while (--fw_retry_count > 0) { @@ -1014,22 +1060,6 @@ int cx18_init_on_first_open(struct cx18 *cx) return -ENXIO; } - /* - * The second firmware load requires us to normalize the APU state, - * or the audio for the first analog capture will be badly incorrect. - * - * I can't seem to call APU_RESETAI and have it succeed without the - * APU capturing audio, so we start and stop it here to do the reset - */ - - /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */ - cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0); - cx18_vapi(cx, CX18_APU_RESETAI, 0); - cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG); - - /* Init the A/V decoder, if it hasn't been already */ - v4l2_subdev_call(cx->sd_av, core, init, (u32) CX18_AV_INIT_NORMAL); - vf.tuner = 0; vf.type = V4L2_TUNER_ANALOG_TV; vf.frequency = 6400; /* the tuner 'baseline' frequency */ @@ -1062,11 +1092,9 @@ static void cx18_cancel_epu_work_orders(struct cx18 *cx) static void cx18_remove(struct pci_dev *pci_dev) { - struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); - struct cx18 *cx = to_cx18(v4l2_dev); - int i; + struct cx18 *cx = pci_get_drvdata(pci_dev); - CX18_DEBUG_INFO("Removing Card\n"); + CX18_DEBUG_INFO("Removing Card #%d\n", cx->num); /* Stop all captures */ CX18_DEBUG_INFO("Stopping all streams\n"); @@ -1087,22 +1115,15 @@ static void cx18_remove(struct pci_dev *pci_dev) exit_cx18_i2c(cx); - free_irq(cx->pci_dev->irq, (void *)cx); + free_irq(cx->dev->irq, (void *)cx); cx18_iounmap(cx); release_mem_region(cx->base_addr, CX18_MEM_SIZE); - pci_disable_device(cx->pci_dev); - - if (cx->vbi.sliced_mpeg_data[0] != NULL) - for (i = 0; i < CX18_VBI_FRAMES; i++) - kfree(cx->vbi.sliced_mpeg_data[i]); - - CX18_INFO("Removed %s\n", cx->card_name); + pci_disable_device(cx->dev); - v4l2_device_unregister(v4l2_dev); - kfree(cx); + CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num); } /* define a pci_driver for card detection */ @@ -1117,6 +1138,8 @@ static int module_start(void) { printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION); + memset(cx18_cards, 0, sizeof(cx18_cards)); + /* Validate parameters */ if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n", @@ -1139,7 +1162,16 @@ static int module_start(void) static void module_cleanup(void) { + int i; + pci_unregister_driver(&cx18_pci_driver); + + for (i = 0; i < cx18_cards_active; i++) { + if (cx18_cards[i] == NULL) + continue; + kfree(cx18_cards[i]); + } + } module_init(module_start); diff --git a/trunk/drivers/media/video/cx18/cx18-driver.h b/trunk/drivers/media/video/cx18/cx18-driver.h index ece4f281ef42..0d2edebc39b4 100644 --- a/trunk/drivers/media/video/cx18/cx18-driver.h +++ b/trunk/drivers/media/video/cx18/cx18-driver.h @@ -48,7 +48,6 @@ #include #include #include -#include #include #include "cx18-mailbox.h" #include "cx18-av-core.h" @@ -80,7 +79,7 @@ #define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */ #define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */ #define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/ -#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100/DVR3100 H */ +#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */ #define CX18_CARD_LAST 6 #define CX18_ENC_STREAM_TYPE_MPG 0 @@ -144,12 +143,12 @@ /* Flag to turn on high volume debugging */ #define CX18_DBGFLG_HIGHVOL (1 << 8) -/* NOTE: extra space before comma in 'fmt , ## args' is required for +/* NOTE: extra space before comma in 'cx->num , ## args' is required for gcc-2.95, otherwise it won't compile. */ #define CX18_DEBUG(x, type, fmt, args...) \ do { \ if ((x) & cx18_debug) \ - v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \ + printk(KERN_INFO "cx18-%d " type ": " fmt, cx->num , ## args); \ } while (0) #define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args) #define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args) @@ -163,7 +162,7 @@ #define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \ do { \ if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \ - v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \ + printk(KERN_INFO "cx18%d " type ": " fmt, cx->num , ## args); \ } while (0) #define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args) #define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args) @@ -175,58 +174,9 @@ #define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args) /* Standard kernel messages */ -#define CX18_ERR(fmt, args...) v4l2_err(&cx->v4l2_dev, fmt , ## args) -#define CX18_WARN(fmt, args...) v4l2_warn(&cx->v4l2_dev, fmt , ## args) -#define CX18_INFO(fmt, args...) v4l2_info(&cx->v4l2_dev, fmt , ## args) - -/* Messages for internal subdevs to use */ -#define CX18_DEBUG_DEV(x, dev, type, fmt, args...) \ - do { \ - if ((x) & cx18_debug) \ - v4l2_info(dev, " " type ": " fmt , ## args); \ - } while (0) -#define CX18_DEBUG_WARN_DEV(dev, fmt, args...) \ - CX18_DEBUG_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args) -#define CX18_DEBUG_INFO_DEV(dev, fmt, args...) \ - CX18_DEBUG_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args) -#define CX18_DEBUG_API_DEV(dev, fmt, args...) \ - CX18_DEBUG_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args) -#define CX18_DEBUG_DMA_DEV(dev, fmt, args...) \ - CX18_DEBUG_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args) -#define CX18_DEBUG_IOCTL_DEV(dev, fmt, args...) \ - CX18_DEBUG_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args) -#define CX18_DEBUG_FILE_DEV(dev, fmt, args...) \ - CX18_DEBUG_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args) -#define CX18_DEBUG_I2C_DEV(dev, fmt, args...) \ - CX18_DEBUG_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args) -#define CX18_DEBUG_IRQ_DEV(dev, fmt, args...) \ - CX18_DEBUG_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args) - -#define CX18_DEBUG_HIGH_VOL_DEV(x, dev, type, fmt, args...) \ - do { \ - if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \ - v4l2_info(dev, " " type ": " fmt , ## args); \ - } while (0) -#define CX18_DEBUG_HI_WARN_DEV(dev, fmt, args...) \ - CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args) -#define CX18_DEBUG_HI_INFO_DEV(dev, fmt, args...) \ - CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args) -#define CX18_DEBUG_HI_API_DEV(dev, fmt, args...) \ - CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args) -#define CX18_DEBUG_HI_DMA_DEV(dev, fmt, args...) \ - CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args) -#define CX18_DEBUG_HI_IOCTL_DEV(dev, fmt, args...) \ - CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args) -#define CX18_DEBUG_HI_FILE_DEV(dev, fmt, args...) \ - CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args) -#define CX18_DEBUG_HI_I2C_DEV(dev, fmt, args...) \ - CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args) -#define CX18_DEBUG_HI_IRQ_DEV(dev, fmt, args...) \ - CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args) - -#define CX18_ERR_DEV(dev, fmt, args...) v4l2_err(dev, fmt , ## args) -#define CX18_WARN_DEV(dev, fmt, args...) v4l2_warn(dev, fmt , ## args) -#define CX18_INFO_DEV(dev, fmt, args...) v4l2_info(dev, fmt , ## args) +#define CX18_ERR(fmt, args...) printk(KERN_ERR "cx18-%d: " fmt, cx->num , ## args) +#define CX18_WARN(fmt, args...) printk(KERN_WARNING "cx18-%d: " fmt, cx->num , ## args) +#define CX18_INFO(fmt, args...) printk(KERN_INFO "cx18-%d: " fmt, cx->num , ## args) /* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */ #define MPEG_FRAME_TYPE_IFRAME 1 @@ -329,7 +279,7 @@ struct cx18_epu_work_order { struct cx18_stream { /* These first four fields are always set, even if the stream is not actually created. */ - struct video_device *video_dev; /* NULL when stream not created */ + struct video_device *v4l2dev; /* NULL when stream not created */ struct cx18 *cx; /* for ease of use */ const char *name; /* name of the stream */ int type; /* stream type */ @@ -342,6 +292,7 @@ struct cx18_stream { int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */ + u64 dma_pts; wait_queue_head_t waitq; /* Buffer Stats */ @@ -367,121 +318,59 @@ struct cx18_open_id { /* forward declaration of struct defined in cx18-cards.h */ struct cx18_card; -/* - * A note about "sliced" VBI data as implemented in this driver: - * - * Currently we collect the sliced VBI in the form of Ancillary Data - * packets, inserted by the AV core decoder/digitizer/slicer in the - * horizontal blanking region of the VBI lines, in "raw" mode as far as - * the Encoder is concerned. We don't ever tell the Encoder itself - * to provide sliced VBI. (AV Core: sliced mode - Encoder: raw mode) - * - * We then process the ancillary data ourselves to send the sliced data - * to the user application directly or build up MPEG-2 private stream 1 - * packets to splice into (only!) MPEG-2 PS streams for the user app. - * - * (That's how ivtv essentially does it.) - * - * The Encoder should be able to extract certain sliced VBI data for - * us and provide it in a separate stream or splice it into any type of - * MPEG PS or TS stream, but this isn't implemented yet. - */ - -/* - * Number of "raw" VBI samples per horizontal line we tell the Encoder to - * grab from the decoder/digitizer/slicer output for raw or sliced VBI. - * It depends on the pixel clock and the horiz rate: - * - * (1/Fh)*(2*Fp) = Samples/line - * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples - * - * Sliced VBI data is sent as ancillary data during horizontal blanking - * Raw VBI is sent as active video samples during vertcal blanking - * - * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line - * length of 720 pixels @ 4:2:2 sampling. Thus... - * - * For systems that use a 15.734 kHz horizontal rate, such as - * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have: - * - * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line = - * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples - * - * For systems that use a 15.625 kHz horizontal rate, such as - * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have: - * - * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line = - * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples - */ -static const u32 vbi_active_samples = 1444; /* 4 byte SAV + 720 Y + 720 U/V */ -static const u32 vbi_hblank_samples_60Hz = 272; /* 4 byte EAV + 268 anc/fill */ -static const u32 vbi_hblank_samples_50Hz = 284; /* 4 byte EAV + 280 anc/fill */ #define CX18_VBI_FRAMES 32 +/* VBI data */ struct vbi_info { - /* Current state of v4l2 VBI settings for this device */ + u32 enc_size; + u32 frame; + u8 cc_data_odd[256]; + u8 cc_data_even[256]; + int cc_pos; + u8 cc_no_update; + u8 vps[5]; + u8 vps_found; + int wss; + u8 wss_found; + u8 wss_no_update; + u32 raw_decoder_line_size; + u8 raw_decoder_sav_odd_field; + u8 raw_decoder_sav_even_field; + u32 sliced_decoder_line_size; + u8 sliced_decoder_sav_odd_field; + u8 sliced_decoder_sav_even_field; struct v4l2_format in; - struct v4l2_sliced_vbi_format *sliced_in; /* pointer to in.fmt.sliced */ - u32 count; /* Count of VBI data lines: 60 Hz: 12 or 50 Hz: 18 */ - u32 start[2]; /* First VBI data line per field: 10 & 273 or 6 & 318 */ - - u32 frame; /* Count of VBI buffers/frames received from Encoder */ - - /* - * Vars for creation and insertion of MPEG Private Stream 1 packets - * of sliced VBI data into an MPEG PS - */ - - /* Boolean: create and insert Private Stream 1 packets into the PS */ + /* convenience pointer to sliced struct in vbi_in union */ + struct v4l2_sliced_vbi_format *sliced_in; + u32 service_set_in; int insert_mpeg; - /* - * Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines. - * Used in cx18-vbi.c only for collecting sliced data, and as a source - * during conversion of sliced VBI data into MPEG Priv Stream 1 packets. - * We don't need to save state here, but the array may have been a bit - * too big (2304 bytes) to alloc from the stack. - */ + /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines. + One for /dev/vbi0 and one for /dev/vbi8 */ struct v4l2_sliced_vbi_data sliced_data[36]; - /* - * A ring buffer of driver-generated MPEG-2 PS - * Program Pack/Private Stream 1 packets for sliced VBI data insertion - * into the MPEG PS stream. - * - * In each sliced_mpeg_data[] buffer is: - * 16 byte MPEG-2 PS Program Pack Header - * 16 byte MPEG-2 Private Stream 1 PES Header - * 4 byte magic number: "itv0" or "ITV0" - * 4 byte first field line mask, if "itv0" - * 4 byte second field line mask, if "itv0" - * 36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data - * - * Each line in the payload is - * 1 byte line header derived from the SDID (WSS, CC, VPS, etc.) - * 42 bytes of line data - * - * That's a maximum 1552 bytes of payload in the Private Stream 1 packet - * which is the payload size a PVR-350 (CX23415) MPEG decoder will - * accept for VBI data. So, including the headers, it's a maximum 1584 - * bytes total. - */ -#define CX18_SLICED_MPEG_DATA_MAXSZ 1584 - /* copy_vbi_buf() needs 8 temp bytes on the end for the worst case */ -#define CX18_SLICED_MPEG_DATA_BUFSZ (CX18_SLICED_MPEG_DATA_MAXSZ+8) + /* Buffer for VBI data inserted into MPEG stream. + The first byte is a dummy byte that's never used. + The next 16 bytes contain the MPEG header for the VBI data, + the remainder is the actual VBI data. + The max size accepted by the MPEG VBI reinsertion turns out + to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes, + where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is + a single line header byte and 2 * 18 is the number of VBI lines per frame. + + However, it seems that the data must be 1K aligned, so we have to + pad the data until the 1 or 2 K boundary. + + This pointer array will allocate 2049 bytes to store each VBI frame. */ u8 *sliced_mpeg_data[CX18_VBI_FRAMES]; u32 sliced_mpeg_size[CX18_VBI_FRAMES]; - - /* Count of Program Pack/Program Stream 1 packets inserted into PS */ + struct cx18_buffer sliced_mpeg_buf; u32 inserted_frame; - /* - * A dummy driver stream transfer buffer with a copy of the next - * sliced_mpeg_data[] buffer for output to userland apps. - * Only used in cx18-fileops.c, but its state needs to persist at times. - */ - struct cx18_buffer sliced_mpeg_buf; + u32 start[2], count; + u32 raw_size; + u32 sliced_size; }; /* Per cx23418, per I2C bus private algo callback data */ @@ -494,17 +383,16 @@ struct cx18_i2c_algo_callback_data { /* Struct to hold info about cx18 cards */ struct cx18 { - int instance; - struct pci_dev *pci_dev; - struct v4l2_device v4l2_dev; - struct v4l2_subdev *sd_av; /* A/V decoder/digitizer sub-device */ - struct v4l2_subdev *sd_extmux; /* External multiplexer sub-dev */ - + int num; /* board number, -1 during init! */ + char name[8]; /* board name for printk and interrupts (e.g. 'cx180') */ + struct pci_dev *dev; /* PCI device */ const struct cx18_card *card; /* card information */ const char *card_name; /* full name of the card */ const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */ u8 is_50hz; u8 is_60hz; + u8 is_out_50hz; + u8 is_out_60hz; u8 nof_inputs; /* number of video inputs */ u8 nof_audio_inputs; /* number of audio inputs */ u16 buffer_id; /* buffer ID counter */ @@ -525,7 +413,10 @@ struct cx18 { /* dualwatch */ unsigned long dualwatch_jiffies; - u32 dualwatch_stereo_mode; + u16 dualwatch_stereo_mode; + + /* Digitizer type */ + int digitizer; /* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */ struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */ struct cx18_options options; /* User options */ @@ -535,6 +426,7 @@ struct cx18 { unsigned long i_flags; /* global cx18 flags */ atomic_t ana_capturing; /* count number of active analog capture streams */ atomic_t tot_capturing; /* total count number of active capture streams */ + spinlock_t lock; /* lock access to this struct */ int search_pack_header; int open_id; /* incremented each time an open occurs, used as @@ -576,30 +468,30 @@ struct cx18 { struct i2c_adapter i2c_adap[2]; struct i2c_algo_bit_data i2c_algo[2]; struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2]; + struct i2c_client i2c_client[2]; + struct mutex i2c_bus_lock[2]; + struct i2c_client *i2c_clients[I2C_CLIENTS_MAX]; /* gpio */ u32 gpio_dir; u32 gpio_val; struct mutex gpio_lock; - struct v4l2_subdev sd_gpiomux; - struct v4l2_subdev sd_resetctrl; /* v4l2 and User settings */ /* codec settings */ u32 audio_input; u32 active_input; + u32 active_output; v4l2_std_id std; v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */ }; -static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev) -{ - return container_of(v4l2_dev, struct cx18, v4l2_dev); -} - /* Globals */ +extern struct cx18 *cx18_cards[]; +extern int cx18_cards_active; extern int cx18_first_minor; +extern spinlock_t cx18_cards_lock; /*==============Prototypes==================*/ @@ -619,22 +511,4 @@ static inline int cx18_raw_vbi(const struct cx18 *cx) return cx->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE; } -/* Call the specified callback for all subdevs with a grp_id bit matching the - * mask in hw (if 0, then match them all). Ignore any errors. */ -#define cx18_call_hw(cx, hw, o, f, args...) \ - __v4l2_device_call_subdevs(&(cx)->v4l2_dev, \ - !(hw) || (sd->grp_id & (hw)), o, f , ##args) - -#define cx18_call_all(cx, o, f, args...) cx18_call_hw(cx, 0, o, f , ##args) - -/* Call the specified callback for all subdevs with a grp_id bit matching the - * mask in hw (if 0, then match them all). If the callback returns an error - * other than 0 or -ENOIOCTLCMD, then return with that error code. */ -#define cx18_call_hw_err(cx, hw, o, f, args...) \ - __v4l2_device_call_subdevs_until_err( \ - &(cx)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args) - -#define cx18_call_all_err(cx, o, f, args...) \ - cx18_call_hw_err(cx, 0, o, f , ##args) - #endif /* CX18_DRIVER_H */ diff --git a/trunk/drivers/media/video/cx18/cx18-dvb.c b/trunk/drivers/media/video/cx18/cx18-dvb.c index 3b86f57cd15a..bd5e6f3fd4d0 100644 --- a/trunk/drivers/media/video/cx18/cx18-dvb.c +++ b/trunk/drivers/media/video/cx18/cx18-dvb.c @@ -167,7 +167,7 @@ int cx18_dvb_register(struct cx18_stream *stream) ret = dvb_register_adapter(&dvb->dvb_adapter, CX18_DRIVER_NAME, - THIS_MODULE, &cx->pci_dev->dev, adapter_nr); + THIS_MODULE, &cx->dev->dev, adapter_nr); if (ret < 0) goto err_out; diff --git a/trunk/drivers/media/video/cx18/cx18-fileops.c b/trunk/drivers/media/video/cx18/cx18-fileops.c index 4d7d6d5a7f86..055f6e004b2d 100644 --- a/trunk/drivers/media/video/cx18/cx18-fileops.c +++ b/trunk/drivers/media/video/cx18/cx18-fileops.c @@ -128,15 +128,15 @@ static void cx18_release_stream(struct cx18_stream *s) static void cx18_dualwatch(struct cx18 *cx) { struct v4l2_tuner vt; - u32 new_bitmap; - u32 new_stereo_mode; - const u32 stereo_mask = 0x0300; - const u32 dual = 0x0200; + u16 new_bitmap; + u16 new_stereo_mode; + const u16 stereo_mask = 0x0300; + const u16 dual = 0x0200; u32 h; new_stereo_mode = cx->params.audio_properties & stereo_mask; memset(&vt, 0, sizeof(vt)); - cx18_call_all(cx, tuner, g_tuner, &vt); + cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, &vt); if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && (vt.rxsubchans & V4L2_TUNER_SUB_LANG2)) new_stereo_mode = dual; @@ -176,8 +176,6 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, *err = 0; while (1) { if (s->type == CX18_ENC_STREAM_TYPE_MPG) { - /* Process pending program info updates and pending - VBI data */ if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) { cx->dualwatch_jiffies = jiffies; @@ -188,6 +186,7 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) { /* byteswap and process VBI data */ cx18_process_vbi_data(cx, buf, + s_vbi->dma_pts, s_vbi->type); cx18_stream_put_buf_fw(s_vbi, buf); } @@ -208,7 +207,8 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, cx18_buf_swap(buf); else { /* byteswap and process VBI data */ - cx18_process_vbi_data(cx, buf, s->type); + cx18_process_vbi_data(cx, buf, + s->dma_pts, s->type); } return buf; } @@ -260,20 +260,6 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s, len = ucount; if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG && !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) { - /* - * Try to find a good splice point in the PS, just before - * an MPEG-2 Program Pack start code, and provide only - * up to that point to the user, so it's easy to insert VBI data - * the next time around. - */ - /* FIXME - This only works for an MPEG-2 PS, not a TS */ - /* - * An MPEG-2 Program Stream (PS) is a series of - * MPEG-2 Program Packs terminated by an - * MPEG Program End Code after the last Program Pack. - * A Program Pack may hold a PS System Header packet and any - * number of Program Elementary Stream (PES) Packets - */ const char *start = buf->buf + buf->readpos; const char *p = start + 1; const u8 *q; @@ -281,54 +267,38 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s, int stuffing, i; while (start + len > p) { - /* Scan for a 0 to find a potential MPEG-2 start code */ q = memchr(p, 0, start + len - p); if (q == NULL) break; p = q + 1; - /* - * Keep looking if not a - * MPEG-2 Pack header start code: 0x00 0x00 0x01 0xba - * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0 - */ if ((char *)q + 15 >= buf->buf + buf->bytesused || q[1] != 0 || q[2] != 1 || q[3] != ch) continue; - - /* If expecting the primary video PES */ if (!cx->search_pack_header) { - /* Continue if it couldn't be a PES packet */ if ((q[6] & 0xc0) != 0x80) continue; - /* Check if a PTS or PTS & DTS follow */ - if (((q[7] & 0xc0) == 0x80 && /* PTS only */ - (q[9] & 0xf0) == 0x20) || /* PTS only */ - ((q[7] & 0xc0) == 0xc0 && /* PTS & DTS */ - (q[9] & 0xf0) == 0x30)) { /* DTS follows */ - /* Assume we found the video PES hdr */ - ch = 0xba; /* next want a Program Pack*/ + if (((q[7] & 0xc0) == 0x80 && + (q[9] & 0xf0) == 0x20) || + ((q[7] & 0xc0) == 0xc0 && + (q[9] & 0xf0) == 0x30)) { + ch = 0xba; cx->search_pack_header = 1; - p = q + 9; /* Skip this video PES hdr */ + p = q + 9; } continue; } - - /* We may have found a Program Pack start code */ - - /* Get the count of stuffing bytes & verify them */ stuffing = q[13] & 7; /* all stuffing bytes must be 0xff */ for (i = 0; i < stuffing; i++) if (q[14 + i] != 0xff) break; - if (i == stuffing && /* right number of stuffing bytes*/ - (q[4] & 0xc4) == 0x44 && /* marker check */ - (q[12] & 3) == 3 && /* marker check */ - q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */ + if (i == stuffing && + (q[4] & 0xc4) == 0x44 && + (q[12] & 3) == 3 && + q[14 + stuffing] == 0 && q[15 + stuffing] == 0 && q[16 + stuffing] == 1) { - /* We declare we actually found a Program Pack*/ - cx->search_pack_header = 0; /* expect vid PES */ + cx->search_pack_header = 0; len = (char *)q - start; cx18_setup_sliced_vbi_buf(cx); break; @@ -608,7 +578,7 @@ int cx18_v4l2_close(struct file *filp) /* Mark that the radio is no longer in use */ clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags); /* Switch tuner to TV */ - cx18_call_all(cx, tuner, s_std, cx->std); + cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std); /* Select correct audio input (i.e. TV tuner or Line in) */ cx18_audio_set_io(cx); if (atomic_read(&cx->ana_capturing) > 0) { @@ -671,7 +641,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) /* We have the radio */ cx18_mute(cx); /* Switch tuner to radio */ - cx18_call_all(cx, tuner, s_radio); + cx18_call_i2c_clients(cx, AUDC_SET_RADIO, NULL); /* Select the correct audio input (i.e. radio tuner) */ cx18_audio_set_io(cx); /* Done! Unmute and continue. */ @@ -682,15 +652,38 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) int cx18_v4l2_open(struct file *filp) { - int res; - struct video_device *video_dev = video_devdata(filp); - struct cx18_stream *s = video_get_drvdata(video_dev); - struct cx18 *cx = s->cx;; + int res, x, y = 0; + struct cx18 *cx = NULL; + struct cx18_stream *s = NULL; + int minor = video_devdata(filp)->minor; + + /* Find which card this open was on */ + spin_lock(&cx18_cards_lock); + for (x = 0; cx == NULL && x < cx18_cards_active; x++) { + /* find out which stream this open was on */ + for (y = 0; y < CX18_MAX_STREAMS; y++) { + if (cx18_cards[x] == NULL) + continue; + s = &cx18_cards[x]->streams[y]; + if (s->v4l2dev && s->v4l2dev->minor == minor) { + cx = cx18_cards[x]; + break; + } + } + } + spin_unlock(&cx18_cards_lock); + + if (cx == NULL) { + /* Couldn't find a device registered + on that minor, shouldn't happen! */ + printk(KERN_WARNING "No cx18 device found on minor %d\n", + minor); + return -ENXIO; + } mutex_lock(&cx->serialize_lock); if (cx18_init_on_first_open(cx)) { - CX18_ERR("Failed to initialize on minor %d\n", - video_dev->minor); + CX18_ERR("Failed to initialize on minor %d\n", minor); mutex_unlock(&cx->serialize_lock); return -ENXIO; } diff --git a/trunk/drivers/media/video/cx18/cx18-firmware.c b/trunk/drivers/media/video/cx18/cx18-firmware.c index 83cd559cc609..1fa95da1575e 100644 --- a/trunk/drivers/media/video/cx18/cx18-firmware.c +++ b/trunk/drivers/media/video/cx18/cx18-firmware.c @@ -26,6 +26,7 @@ #include "cx18-irq.h" #include "cx18-firmware.h" #include "cx18-cards.h" +#include "cx18-av-core.h" #include #define CX18_PROC_SOFT_RESET 0xc70010 @@ -106,7 +107,7 @@ static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx) u32 __iomem *dst = (u32 __iomem *)mem; const u32 *src; - if (request_firmware(&fw, fn, &cx->pci_dev->dev)) { + if (request_firmware(&fw, fn, &cx->dev->dev)) { CX18_ERR("Unable to open firmware %s\n", fn); CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n"); return -ENOMEM; @@ -150,7 +151,7 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, u32 apu_version = 0; int sz; - if (request_firmware(&fw, fn, &cx->pci_dev->dev)) { + if (request_firmware(&fw, fn, &cx->dev->dev)) { CX18_ERR("unable to open firmware %s\n", fn); CX18_ERR("did you put the firmware in the hotplug firmware directory?\n"); cx18_setup_page(cx, 0); @@ -285,6 +286,23 @@ void cx18_init_power(struct cx18 *cx, int lowpwr) cx18_write_reg(cx, 0x2BE2FE, CX18_MPEG_CLOCK_PLL_FRAC); cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST); + /* + * VDCLK Integer = 0x0f, Post Divider = 0x04 + * AIMCLK Integer = 0x0e, Post Divider = 0x16 + */ + cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f); + + /* VDCLK Fraction = 0x2be2fe */ + /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */ + cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe); + + /* AIMCLK Fraction = 0x05227ad */ + /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz before post-divide */ + cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad); + + /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */ + cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56); + /* Defaults */ /* APU = SC or SC/2 = 125/62.5 */ /* EPU = SC = 125 */ diff --git a/trunk/drivers/media/video/cx18/cx18-gpio.c b/trunk/drivers/media/video/cx18/cx18-gpio.c index 5518d1424f8f..1a99329f33cb 100644 --- a/trunk/drivers/media/video/cx18/cx18-gpio.c +++ b/trunk/drivers/media/video/cx18/cx18-gpio.c @@ -46,9 +46,6 @@ * gpio13: cs5345 reset pin */ -/* - * File scope utility functions - */ static void gpio_write(struct cx18 *cx) { u32 dir_lo = cx->gpio_dir & 0xffff; @@ -66,201 +63,73 @@ static void gpio_write(struct cx18 *cx) CX18_REG_GPIO_OUT2, val_hi, dir_hi); } -static void gpio_update(struct cx18 *cx, u32 mask, u32 data) +void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) { - if (mask == 0) - return; - - mutex_lock(&cx->gpio_lock); - cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask); - gpio_write(cx); - mutex_unlock(&cx->gpio_lock); -} + const struct cx18_gpio_i2c_slave_reset *p; -static void gpio_reset_seq(struct cx18 *cx, u32 active_lo, u32 active_hi, - unsigned int assert_msecs, - unsigned int recovery_msecs) -{ - u32 mask; + p = &cx->card->gpio_i2c_slave_reset; - mask = active_lo | active_hi; - if (mask == 0) + if ((p->active_lo_mask | p->active_hi_mask) == 0) return; - /* - * Assuming that active_hi and active_lo are a subsets of the bits in - * gpio_dir. Also assumes that active_lo and active_hi don't overlap - * in any bit position - */ + /* Assuming that the masks are a subset of the bits in gpio_dir */ /* Assert */ - gpio_update(cx, mask, ~active_lo); - schedule_timeout_uninterruptible(msecs_to_jiffies(assert_msecs)); + mutex_lock(&cx->gpio_lock); + cx->gpio_val = + (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask); + gpio_write(cx); + schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted)); /* Deassert */ - gpio_update(cx, mask, ~active_hi); - schedule_timeout_uninterruptible(msecs_to_jiffies(recovery_msecs)); -} - -/* - * GPIO Multiplexer - logical device - */ -static int gpiomux_log_status(struct v4l2_subdev *sd) -{ - struct cx18 *cx = v4l2_get_subdevdata(sd); - - mutex_lock(&cx->gpio_lock); - CX18_INFO_DEV(sd, "GPIO: direction 0x%08x, value 0x%08x\n", - cx->gpio_dir, cx->gpio_val); + cx->gpio_val = + (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask); + gpio_write(cx); + schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); mutex_unlock(&cx->gpio_lock); - return 0; -} - -static int gpiomux_s_radio(struct v4l2_subdev *sd) -{ - struct cx18 *cx = v4l2_get_subdevdata(sd); - - /* - * FIXME - work out the cx->active/audio_input mess - this is - * intended to handle the switch to radio mode and set the - * audio routing, but we need to update the state in cx - */ - gpio_update(cx, cx->card->gpio_audio_input.mask, - cx->card->gpio_audio_input.radio); - return 0; -} - -static int gpiomux_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) -{ - struct cx18 *cx = v4l2_get_subdevdata(sd); - u32 data; - - switch (cx->card->audio_inputs[cx->audio_input].muxer_input) { - case 1: - data = cx->card->gpio_audio_input.linein; - break; - case 0: - data = cx->card->gpio_audio_input.tuner; - break; - default: - /* - * FIXME - work out the cx->active/audio_input mess - this is - * intended to handle the switch from radio mode and set the - * audio routing, but we need to update the state in cx - */ - data = cx->card->gpio_audio_input.tuner; - break; - } - gpio_update(cx, cx->card->gpio_audio_input.mask, data); - return 0; } -static int gpiomux_s_audio_routing(struct v4l2_subdev *sd, - const struct v4l2_routing *route) +void cx18_reset_ir_gpio(void *data) { - struct cx18 *cx = v4l2_get_subdevdata(sd); - u32 data; - - switch (route->input) { - case 0: - data = cx->card->gpio_audio_input.tuner; - break; - case 1: - data = cx->card->gpio_audio_input.linein; - break; - case 2: - data = cx->card->gpio_audio_input.radio; - break; - default: - return -EINVAL; - } - gpio_update(cx, cx->card->gpio_audio_input.mask, data); - return 0; -} - -static const struct v4l2_subdev_core_ops gpiomux_core_ops = { - .log_status = gpiomux_log_status, -}; - -static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = { - .s_std = gpiomux_s_std, - .s_radio = gpiomux_s_radio, -}; + struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; + const struct cx18_gpio_i2c_slave_reset *p; -static const struct v4l2_subdev_audio_ops gpiomux_audio_ops = { - .s_routing = gpiomux_s_audio_routing, -}; + p = &cx->card->gpio_i2c_slave_reset; -static const struct v4l2_subdev_ops gpiomux_ops = { - .core = &gpiomux_core_ops, - .tuner = &gpiomux_tuner_ops, - .audio = &gpiomux_audio_ops, -}; + if (p->ir_reset_mask == 0) + return; -/* - * GPIO Reset Controller - logical device - */ -static int resetctrl_log_status(struct v4l2_subdev *sd) -{ - struct cx18 *cx = v4l2_get_subdevdata(sd); + CX18_DEBUG_INFO("Resetting IR microcontroller\n"); + /* + Assert timing for the Z8F0811 on HVR-1600 boards: + 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to initiate + 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock cycles + (6,601,085 nanoseconds ~= 7 milliseconds) + 3. DBG pin must be high before chip exits reset for normal operation. + DBG is open drain and hopefully pulled high since we don't + normally drive it (GPIO 1?) for the HVR-1600 + 4. Z8F0811 won't exit reset until RESET is deasserted + */ mutex_lock(&cx->gpio_lock); - CX18_INFO_DEV(sd, "GPIO: direction 0x%08x, value 0x%08x\n", - cx->gpio_dir, cx->gpio_val); + cx->gpio_val = cx->gpio_val & ~p->ir_reset_mask; + gpio_write(cx); mutex_unlock(&cx->gpio_lock); - return 0; -} - -static int resetctrl_reset(struct v4l2_subdev *sd, u32 val) -{ - struct cx18 *cx = v4l2_get_subdevdata(sd); - const struct cx18_gpio_i2c_slave_reset *p; + schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted)); - p = &cx->card->gpio_i2c_slave_reset; - switch (val) { - case CX18_GPIO_RESET_I2C: - gpio_reset_seq(cx, p->active_lo_mask, p->active_hi_mask, - p->msecs_asserted, p->msecs_recovery); - break; - case CX18_GPIO_RESET_Z8F0811: - /* - * Assert timing for the Z8F0811 on HVR-1600 boards: - * 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to - * initiate - * 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock - * cycles (6,601,085 nanoseconds ~= 7 milliseconds) - * 3. DBG pin must be high before chip exits reset for normal - * operation. DBG is open drain and hopefully pulled high - * since we don't normally drive it (GPIO 1?) for the - * HVR-1600 - * 4. Z8F0811 won't exit reset until RESET is deasserted - * 5. Zilog comes out of reset, loads reset vector address and - * executes from there. Required recovery delay unknown. - */ - gpio_reset_seq(cx, p->ir_reset_mask, 0, - p->msecs_asserted, p->msecs_recovery); - break; - case CX18_GPIO_RESET_XC2028: - if (cx->card->tuners[0].tuner == TUNER_XC2028) - gpio_reset_seq(cx, (1 << cx->card->xceive_pin), 0, - 1, 1); - break; - } - return 0; + /* + Zilog comes out of reset, loads reset vector address and executes + from there. Required recovery delay unknown. + */ + mutex_lock(&cx->gpio_lock); + cx->gpio_val = cx->gpio_val | p->ir_reset_mask; + gpio_write(cx); + mutex_unlock(&cx->gpio_lock); + schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); } +EXPORT_SYMBOL(cx18_reset_ir_gpio); +/* This symbol is exported for use by an infrared module for the IR-blaster */ -static const struct v4l2_subdev_core_ops resetctrl_core_ops = { - .log_status = resetctrl_log_status, - .reset = resetctrl_reset, -}; - -static const struct v4l2_subdev_ops resetctrl_ops = { - .core = &resetctrl_core_ops, -}; - -/* - * External entry points - */ void cx18_gpio_init(struct cx18 *cx) { mutex_lock(&cx->gpio_lock); @@ -287,49 +156,6 @@ void cx18_gpio_init(struct cx18 *cx) mutex_unlock(&cx->gpio_lock); } -int cx18_gpio_register(struct cx18 *cx, u32 hw) -{ - struct v4l2_subdev *sd; - const struct v4l2_subdev_ops *ops; - char *str; - - switch (hw) { - case CX18_HW_GPIO_MUX: - sd = &cx->sd_gpiomux; - ops = &gpiomux_ops; - str = "gpio-mux"; - break; - case CX18_HW_GPIO_RESET_CTRL: - sd = &cx->sd_resetctrl; - ops = &resetctrl_ops; - str = "gpio-reset-ctrl"; - break; - default: - return -EINVAL; - } - - v4l2_subdev_init(sd, ops); - v4l2_set_subdevdata(sd, cx); - snprintf(sd->name, sizeof(sd->name), "%s %s", cx->v4l2_dev.name, str); - sd->grp_id = hw; - return v4l2_device_register_subdev(&cx->v4l2_dev, sd); -} - -void cx18_reset_ir_gpio(void *data) -{ - struct cx18 *cx = to_cx18((struct v4l2_device *)data); - - if (cx->card->gpio_i2c_slave_reset.ir_reset_mask == 0) - return; - - CX18_DEBUG_INFO("Resetting IR microcontroller\n"); - - v4l2_subdev_call(&cx->sd_resetctrl, - core, reset, CX18_GPIO_RESET_Z8F0811); -} -EXPORT_SYMBOL(cx18_reset_ir_gpio); -/* This symbol is exported for use by lirc_pvr150 for the IR-blaster */ - /* Xceive tuner reset function */ int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value) { @@ -337,11 +163,56 @@ int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value) struct cx18_i2c_algo_callback_data *cb_data = algo->data; struct cx18 *cx = cb_data->cx; - if (cmd != XC2028_TUNER_RESET || - cx->card->tuners[0].tuner != TUNER_XC2028) + if (cmd != XC2028_TUNER_RESET) return 0; + CX18_DEBUG_INFO("Resetting tuner\n"); - CX18_DEBUG_INFO("Resetting XCeive tuner\n"); - return v4l2_subdev_call(&cx->sd_resetctrl, - core, reset, CX18_GPIO_RESET_XC2028); + mutex_lock(&cx->gpio_lock); + cx->gpio_val &= ~(1 << cx->card->xceive_pin); + gpio_write(cx); + mutex_unlock(&cx->gpio_lock); + schedule_timeout_interruptible(msecs_to_jiffies(1)); + + mutex_lock(&cx->gpio_lock); + cx->gpio_val |= 1 << cx->card->xceive_pin; + gpio_write(cx); + mutex_unlock(&cx->gpio_lock); + schedule_timeout_interruptible(msecs_to_jiffies(1)); + return 0; +} + +int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg) +{ + struct v4l2_routing *route = arg; + u32 mask, data; + + switch (command) { + case VIDIOC_INT_S_AUDIO_ROUTING: + if (route->input > 2) + return -EINVAL; + mask = cx->card->gpio_audio_input.mask; + switch (route->input) { + case 0: + data = cx->card->gpio_audio_input.tuner; + break; + case 1: + data = cx->card->gpio_audio_input.linein; + break; + case 2: + default: + data = cx->card->gpio_audio_input.radio; + break; + } + break; + + default: + return -EINVAL; + } + if (mask) { + mutex_lock(&cx->gpio_lock); + cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask); + gpio_write(cx); + mutex_unlock(&cx->gpio_lock); + } + return 0; } diff --git a/trunk/drivers/media/video/cx18/cx18-gpio.h b/trunk/drivers/media/video/cx18/cx18-gpio.h index f9a5ca3566af..39ffccc19d8a 100644 --- a/trunk/drivers/media/video/cx18/cx18-gpio.h +++ b/trunk/drivers/media/video/cx18/cx18-gpio.h @@ -22,13 +22,7 @@ */ void cx18_gpio_init(struct cx18 *cx); -int cx18_gpio_register(struct cx18 *cx, u32 hw); - -enum cx18_gpio_reset_type { - CX18_GPIO_RESET_I2C = 0, - CX18_GPIO_RESET_Z8F0811 = 1, - CX18_GPIO_RESET_XC2028 = 2, -}; - +void cx18_reset_i2c_slaves_gpio(struct cx18 *cx); void cx18_reset_ir_gpio(void *data); int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value); +int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg); diff --git a/trunk/drivers/media/video/cx18/cx18-i2c.c b/trunk/drivers/media/video/cx18/cx18-i2c.c index d092643faf46..83e1c6333126 100644 --- a/trunk/drivers/media/video/cx18/cx18-i2c.c +++ b/trunk/drivers/media/video/cx18/cx18-i2c.c @@ -26,6 +26,7 @@ #include "cx18-io.h" #include "cx18-cards.h" #include "cx18-gpio.h" +#include "cx18-av-core.h" #include "cx18-i2c.h" #include "cx18-irq.h" @@ -42,37 +43,31 @@ #define CX18_CS5345_I2C_ADDR 0x4c /* This array should match the CX18_HW_ defines */ -static const u8 hw_addrs[] = { - 0, /* CX18_HW_TUNER */ - 0, /* CX18_HW_TVEEPROM */ - CX18_CS5345_I2C_ADDR, /* CX18_HW_CS5345 */ - 0, /* CX18_HW_DVB */ - 0, /* CX18_HW_418_AV */ - 0, /* CX18_HW_GPIO_MUX */ - 0, /* CX18_HW_GPIO_RESET_CTRL */ +static const u8 hw_driverids[] = { + I2C_DRIVERID_TUNER, + I2C_DRIVERID_TVEEPROM, + I2C_DRIVERID_CS5345, + 0, /* CX18_HW_GPIO dummy driver ID */ + 0 /* CX18_HW_CX23418 dummy driver ID */ }; /* This array should match the CX18_HW_ defines */ -/* This might well become a card-specific array */ -static const u8 hw_bus[] = { - 1, /* CX18_HW_TUNER */ - 0, /* CX18_HW_TVEEPROM */ - 0, /* CX18_HW_CS5345 */ - 0, /* CX18_HW_DVB */ - 0, /* CX18_HW_418_AV */ - 0, /* CX18_HW_GPIO_MUX */ - 0, /* CX18_HW_GPIO_RESET_CTRL */ +static const u8 hw_addrs[] = { + 0, + 0, + CX18_CS5345_I2C_ADDR, + 0, /* CX18_HW_GPIO dummy driver ID */ + 0, /* CX18_HW_CX23418 dummy driver ID */ }; /* This array should match the CX18_HW_ defines */ -static const char * const hw_modules[] = { - "tuner", /* CX18_HW_TUNER */ - NULL, /* CX18_HW_TVEEPROM */ - "cs5345", /* CX18_HW_CS5345 */ - NULL, /* CX18_HW_DVB */ - NULL, /* CX18_HW_418_AV */ - NULL, /* CX18_HW_GPIO_MUX */ - NULL, /* CX18_HW_GPIO_RESET_CTRL */ +/* This might well become a card-specific array */ +static const u8 hw_bus[] = { + 0, + 0, + 0, + 0, /* CX18_HW_GPIO dummy driver ID */ + 0, /* CX18_HW_CX23418 dummy driver ID */ }; /* This array should match the CX18_HW_ defines */ @@ -80,67 +75,83 @@ static const char * const hw_devicenames[] = { "tuner", "tveeprom", "cs5345", - "cx23418_DTV", - "cx23418_AV", - "gpio_mux", - "gpio_reset_ctrl", + "gpio", + "cx23418", }; int cx18_i2c_register(struct cx18 *cx, unsigned idx) { - struct v4l2_subdev *sd; - int bus = hw_bus[idx]; - struct i2c_adapter *adap = &cx->i2c_adap[bus]; - const char *mod = hw_modules[idx]; - const char *type = hw_devicenames[idx]; - u32 hw = 1 << idx; - - if (idx >= ARRAY_SIZE(hw_addrs)) + struct i2c_board_info info; + struct i2c_client *c; + u8 id, bus; + int i; + + CX18_DEBUG_I2C("i2c client register\n"); + if (idx >= ARRAY_SIZE(hw_driverids) || hw_driverids[idx] == 0) return -1; + id = hw_driverids[idx]; + bus = hw_bus[idx]; + memset(&info, 0, sizeof(info)); + strlcpy(info.type, hw_devicenames[idx], sizeof(info.type)); + info.addr = hw_addrs[idx]; + for (i = 0; i < I2C_CLIENTS_MAX; i++) + if (cx->i2c_clients[i] == NULL) + break; - if (hw == CX18_HW_TUNER) { - /* special tuner group handling */ - sd = v4l2_i2c_new_probed_subdev(adap, mod, type, - cx->card_i2c->radio); - if (sd != NULL) - sd->grp_id = hw; - sd = v4l2_i2c_new_probed_subdev(adap, mod, type, - cx->card_i2c->demod); - if (sd != NULL) - sd->grp_id = hw; - sd = v4l2_i2c_new_probed_subdev(adap, mod, type, - cx->card_i2c->tv); - if (sd != NULL) - sd->grp_id = hw; - return sd != NULL ? 0 : -1; + if (i == I2C_CLIENTS_MAX) { + CX18_ERR("insufficient room for new I2C client!\n"); + return -ENOMEM; } - /* Is it not an I2C device or one we do not wish to register? */ - if (!hw_addrs[idx]) - return -1; + if (id != I2C_DRIVERID_TUNER) { + c = i2c_new_device(&cx->i2c_adap[bus], &info); + if (c->driver == NULL) + i2c_unregister_device(c); + else + cx->i2c_clients[i] = c; + return cx->i2c_clients[i] ? 0 : -ENODEV; + } + + /* special tuner handling */ + c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->radio); + if (c && c->driver == NULL) + i2c_unregister_device(c); + else if (c) + cx->i2c_clients[i++] = c; + c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->demod); + if (c && c->driver == NULL) + i2c_unregister_device(c); + else if (c) + cx->i2c_clients[i++] = c; + c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->tv); + if (c && c->driver == NULL) + i2c_unregister_device(c); + else if (c) + cx->i2c_clients[i++] = c; + return 0; +} - /* It's an I2C device other than an analog tuner */ - sd = v4l2_i2c_new_subdev(adap, mod, type, hw_addrs[idx]); - if (sd != NULL) - sd->grp_id = hw; - return sd != NULL ? 0 : -1; +static int attach_inform(struct i2c_client *client) +{ + return 0; } -/* Find the first member of the subdev group id in hw */ -struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw) +static int detach_inform(struct i2c_client *client) { - struct v4l2_subdev *result = NULL; - struct v4l2_subdev *sd; + int i; + struct cx18 *cx = (struct cx18 *)i2c_get_adapdata(client->adapter); - spin_lock(&cx->v4l2_dev.lock); - v4l2_device_for_each_subdev(sd, &cx->v4l2_dev) { - if (sd->grp_id == hw) { - result = sd; + CX18_DEBUG_I2C("i2c client detach\n"); + for (i = 0; i < I2C_CLIENTS_MAX; i++) { + if (cx->i2c_clients[i] == client) { + cx->i2c_clients[i] = NULL; break; } } - spin_unlock(&cx->v4l2_dev.lock); - return result; + CX18_DEBUG_I2C("i2c detach [client=%s,%s]\n", + client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed"); + + return 0; } static void cx18_setscl(void *data, int state) @@ -193,6 +204,8 @@ static struct i2c_adapter cx18_i2c_adap_template = { .id = I2C_HW_B_CX2341X, .algo = NULL, /* set by i2c-algo-bit */ .algo_data = NULL, /* filled from template */ + .client_register = attach_inform, + .client_unregister = detach_inform, .owner = THIS_MODULE, }; @@ -208,28 +221,152 @@ static struct i2c_algo_bit_data cx18_i2c_algo_template = { .timeout = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */ }; +static struct i2c_client cx18_i2c_client_template = { + .name = "cx18 internal", +}; + +int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg) +{ + struct i2c_client *client; + int retval; + int i; + + CX18_DEBUG_I2C("call_i2c_client addr=%02x\n", addr); + for (i = 0; i < I2C_CLIENTS_MAX; i++) { + client = cx->i2c_clients[i]; + if (client == NULL || client->driver == NULL || + client->driver->command == NULL) + continue; + if (addr == client->addr) { + retval = client->driver->command(client, cmd, arg); + return retval; + } + } + if (cmd != VIDIOC_DBG_G_CHIP_IDENT) + CX18_ERR("i2c addr 0x%02x not found for cmd 0x%x!\n", + addr, cmd); + return -ENODEV; +} + +/* Find the i2c device based on the driver ID and return + its i2c address or -ENODEV if no matching device was found. */ +static int cx18_i2c_id_addr(struct cx18 *cx, u32 id) +{ + struct i2c_client *client; + int retval = -ENODEV; + int i; + + for (i = 0; i < I2C_CLIENTS_MAX; i++) { + client = cx->i2c_clients[i]; + if (client == NULL || client->driver == NULL) + continue; + if (id == client->driver->id) { + retval = client->addr; + break; + } + } + return retval; +} + +/* Find the i2c device name matching the CX18_HW_ flag */ +static const char *cx18_i2c_hw_name(u32 hw) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) + if (1 << i == hw) + return hw_devicenames[i]; + return "unknown device"; +} + +/* Find the i2c device matching the CX18_HW_ flag and return + its i2c address or -ENODEV if no matching device was found. */ +int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) + if (1 << i == hw) + return cx18_i2c_id_addr(cx, hw_driverids[i]); + return -ENODEV; +} + +/* Calls i2c device based on CX18_HW_ flag. If hw == 0, then do nothing. + If hw == CX18_HW_GPIO then call the gpio handler. */ +int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg) +{ + int addr; + + if (hw == 0) + return 0; + + if (hw == CX18_HW_GPIO) + return cx18_gpio(cx, cmd, arg); + + if (hw == CX18_HW_CX23418) + return cx18_av_cmd(cx, cmd, arg); + + addr = cx18_i2c_hw_addr(cx, hw); + if (addr < 0) { + CX18_ERR("i2c hardware 0x%08x (%s) not found for cmd 0x%x!\n", + hw, cx18_i2c_hw_name(hw), cmd); + return addr; + } + return cx18_call_i2c_client(cx, addr, cmd, arg); +} + +/* broadcast cmd for all I2C clients and for the gpio subsystem */ +void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg) +{ + if (cx->i2c_adap[0].algo == NULL || cx->i2c_adap[1].algo == NULL) { + CX18_ERR("adapter is not set\n"); + return; + } + cx18_av_cmd(cx, cmd, arg); + i2c_clients_command(&cx->i2c_adap[0], cmd, arg); + i2c_clients_command(&cx->i2c_adap[1], cmd, arg); + if (cx->hw_flags & CX18_HW_GPIO) + cx18_gpio(cx, cmd, arg); +} + /* init + register i2c algo-bit adapter */ int init_cx18_i2c(struct cx18 *cx) { int i; CX18_DEBUG_I2C("i2c init\n"); + /* Sanity checks for the I2C hardware arrays. They must be the + * same size and GPIO/CX23418 must be the last entries. + */ + if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) || + ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) || + CX18_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 2)) || + CX18_HW_CX23418 != (1 << (ARRAY_SIZE(hw_addrs) - 1)) || + hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) { + CX18_ERR("Mismatched I2C hardware arrays\n"); + return -ENODEV; + } + for (i = 0; i < 2; i++) { - /* Setup algorithm for adapter */ + memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template, + sizeof(struct i2c_adapter)); memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template, sizeof(struct i2c_algo_bit_data)); cx->i2c_algo_cb_data[i].cx = cx; cx->i2c_algo_cb_data[i].bus_index = i; cx->i2c_algo[i].data = &cx->i2c_algo_cb_data[i]; - - /* Setup adapter */ - memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template, - sizeof(struct i2c_adapter)); cx->i2c_adap[i].algo_data = &cx->i2c_algo[i]; + sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name), - " #%d-%d", cx->instance, i); - i2c_set_adapdata(&cx->i2c_adap[i], &cx->v4l2_dev); - cx->i2c_adap[i].dev.parent = &cx->pci_dev->dev; + " #%d-%d", cx->num, i); + i2c_set_adapdata(&cx->i2c_adap[i], cx); + + memcpy(&cx->i2c_client[i], &cx18_i2c_client_template, + sizeof(struct i2c_client)); + sprintf(cx->i2c_client[i].name + + strlen(cx->i2c_client[i].name), "%d", i); + cx->i2c_client[i].adapter = &cx->i2c_adap[i]; + cx->i2c_adap[i].dev.parent = &cx->dev->dev; } if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) { @@ -265,8 +402,7 @@ int init_cx18_i2c(struct cx18 *cx) cx18_setscl(&cx->i2c_algo_cb_data[1], 1); cx18_setsda(&cx->i2c_algo_cb_data[1], 1); - cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, - core, reset, (u32) CX18_GPIO_RESET_I2C); + cx18_reset_i2c_slaves_gpio(cx); return i2c_bit_add_bus(&cx->i2c_adap[0]) || i2c_bit_add_bus(&cx->i2c_adap[1]); diff --git a/trunk/drivers/media/video/cx18/cx18-i2c.h b/trunk/drivers/media/video/cx18/cx18-i2c.h index bdfd1921e300..4869739013bd 100644 --- a/trunk/drivers/media/video/cx18/cx18-i2c.h +++ b/trunk/drivers/media/video/cx18/cx18-i2c.h @@ -21,8 +21,11 @@ * 02111-1307 USA */ +int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw); +int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg); +int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg); +void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg); int cx18_i2c_register(struct cx18 *cx, unsigned idx); -struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw); /* init + register i2c algo-bit adapter */ int init_cx18_i2c(struct cx18 *cx); diff --git a/trunk/drivers/media/video/cx18/cx18-ioctl.c b/trunk/drivers/media/video/cx18/cx18-ioctl.c index e4c9e3d8bacd..7086aaba77d6 100644 --- a/trunk/drivers/media/video/cx18/cx18-ioctl.c +++ b/trunk/drivers/media/video/cx18/cx18-ioctl.c @@ -58,21 +58,12 @@ u16 cx18_service2vbi(int type) } } -/* Check if VBI services are allowed on the (field, line) for the video std */ static int valid_service_line(int field, int line, int is_pal) { - return (is_pal && line >= 6 && - ((field == 0 && line <= 23) || (field == 1 && line <= 22))) || + return (is_pal && line >= 6 && (line != 23 || field == 0)) || (!is_pal && line >= 10 && line < 22); } -/* - * For a (field, line, std) and inbound potential set of services for that line, - * return the first valid service of those passed in the incoming set for that - * line in priority order: - * CC, VPS, or WSS over TELETEXT for well known lines - * TELETEXT, before VPS, before CC, before WSS, for other lines - */ static u16 select_service_from_set(int field, int line, u16 set, int is_pal) { u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525); @@ -99,10 +90,6 @@ static u16 select_service_from_set(int field, int line, u16 set, int is_pal) return 0; } -/* - * Expand the service_set of *fmt into valid service_lines for the std, - * and clear the passed in fmt->service_set - */ void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) { u16 set = fmt->service_set; @@ -115,25 +102,7 @@ void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) } } -/* - * Sanitize the service_lines in *fmt per the video std, and return 1 - * if any service_line is left as valid after santization - */ -static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) -{ - int f, l; - u16 set = 0; - - for (f = 0; f < 2; f++) { - for (l = 0; l < 24; l++) { - fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal); - set |= fmt->service_lines[f][l]; - } - } - return set != 0; -} -/* Compute the service_set from the assumed valid service_lines of *fmt */ u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt) { int f, l; @@ -160,8 +129,10 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh, pixfmt->priv = 0; if (id->type == CX18_ENC_STREAM_TYPE_YUV) { pixfmt->pixelformat = V4L2_PIX_FMT_HM12; - /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */ - pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2; + /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ + pixfmt->sizeimage = + pixfmt->height * pixfmt->width + + pixfmt->height * (pixfmt->width / 2); pixfmt->bytesperline = 720; } else { pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; @@ -178,8 +149,8 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi; vbifmt->sampling_rate = 27000000; - vbifmt->offset = 248; /* FIXME - slightly wrong for both 50 & 60 Hz */ - vbifmt->samples_per_line = vbi_active_samples - 4; + vbifmt->offset = 248; + vbifmt->samples_per_line = cx->vbi.raw_decoder_line_size - 4; vbifmt->sample_format = V4L2_PIX_FMT_GREY; vbifmt->start[0] = cx->vbi.start[0]; vbifmt->start[1] = cx->vbi.start[1]; @@ -193,30 +164,7 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh, static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; - - /* sane, V4L2 spec compliant, defaults */ - vbifmt->reserved[0] = 0; - vbifmt->reserved[1] = 0; - vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; - memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines)); - vbifmt->service_set = 0; - - /* - * Fetch the configured service_lines and total service_set from the - * digitizer/slicer. Note, cx18_av_vbi() wipes the passed in - * fmt->fmt.sliced under valid calling conditions - */ - if (v4l2_subdev_call(cx->sd_av, video, g_fmt, fmt)) - return -EINVAL; - - /* Ensure V4L2 spec compliant output */ - vbifmt->reserved[0] = 0; - vbifmt->reserved[1] = 0; - vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; - vbifmt->service_set = cx18_get_service_set(vbifmt); - return 0; + return -EINVAL; } static int cx18_try_fmt_vid_cap(struct file *file, void *fh, @@ -226,18 +174,11 @@ static int cx18_try_fmt_vid_cap(struct file *file, void *fh, struct cx18 *cx = id->cx; int w = fmt->fmt.pix.width; int h = fmt->fmt.pix.height; - int min_h = 2; w = min(w, 720); - w = max(w, 2); - if (id->type == CX18_ENC_STREAM_TYPE_YUV) { - /* YUV height must be a multiple of 32 */ - h &= ~0x1f; - min_h = 32; - } + w = max(w, 1); h = min(h, cx->is_50hz ? 576 : 480); - h = max(h, min_h); - + h = max(h, 2); cx18_g_fmt_vid_cap(file, fh, fmt); fmt->fmt.pix.width = w; fmt->fmt.pix.height = h; @@ -253,20 +194,7 @@ static int cx18_try_fmt_vbi_cap(struct file *file, void *fh, static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; - - vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; - vbifmt->reserved[0] = 0; - vbifmt->reserved[1] = 0; - - /* If given a service set, expand it validly & clear passed in set */ - if (vbifmt->service_set) - cx18_expand_service_set(vbifmt, cx->is_50hz); - /* Sanitize the service_lines, and compute the new set if any valid */ - if (check_service_set(vbifmt, cx->is_50hz)) - vbifmt->service_set = cx18_get_service_set(vbifmt); - return 0; + return -EINVAL; } static int cx18_s_fmt_vid_cap(struct file *file, void *fh, @@ -295,7 +223,7 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, cx->params.width = w; cx->params.height = h; - v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt); + cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); return cx18_g_fmt_vid_cap(file, fh, fmt); } @@ -310,131 +238,54 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, if (ret) return ret; - /* - * Changing the Encoder's Raw VBI parameters won't have any effect - * if any analog capture is ongoing - */ if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0) return -EBUSY; - /* - * Set the digitizer registers for raw active VBI. - * Note cx18_av_vbi_wipes out alot of the passed in fmt under valid - * calling conditions - */ - ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt); - if (ret) - return ret; - - /* Store our new v4l2 (non-)sliced VBI state */ cx->vbi.sliced_in->service_set = 0; cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; - + cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); return cx18_g_fmt_vbi_cap(file, fh, fmt); } static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - int ret; - struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; - - ret = v4l2_prio_check(&cx->prio, &id->prio); - if (ret) - return ret; - - cx18_try_fmt_sliced_vbi_cap(file, fh, fmt); - - /* - * Changing the Encoder's Raw VBI parameters won't have any effect - * if any analog capture is ongoing - */ - if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0) - return -EBUSY; - - /* - * Set the service_lines requested in the digitizer/slicer registers. - * Note, cx18_av_vbi() wipes some "impossible" service lines in the - * passed in fmt->fmt.sliced under valid calling conditions - */ - ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt); - if (ret) - return ret; - /* Store our current v4l2 sliced VBI settings */ - cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; - memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in)); - return 0; + return -EINVAL; } static int cx18_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - int err = 0; chip->ident = V4L2_IDENT_NONE; chip->revision = 0; - switch (chip->match.type) { - case V4L2_CHIP_MATCH_HOST: - switch (chip->match.addr) { - case 0: - chip->ident = V4L2_IDENT_CX23418; - chip->revision = cx18_read_reg(cx, 0xC72028); - break; - case 1: - /* - * The A/V decoder is always present, but in the rare - * case that the card doesn't have analog, we don't - * use it. We find it w/o using the cx->sd_av pointer - */ - cx18_call_hw(cx, CX18_HW_418_AV, - core, g_chip_ident, chip); - break; - default: - /* - * Could return ident = V4L2_IDENT_UNKNOWN if we had - * other host chips at higher addresses, but we don't - */ - err = -EINVAL; /* per V4L2 spec */ - break; - } - break; - case V4L2_CHIP_MATCH_I2C_DRIVER: - /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */ - cx18_call_all(cx, core, g_chip_ident, chip); - break; - case V4L2_CHIP_MATCH_I2C_ADDR: - /* - * We could return V4L2_IDENT_UNKNOWN, but we don't do the work - * to look if a chip is at the address with no driver. That's a - * dangerous thing to do with EEPROMs anyway. - */ - cx18_call_all(cx, core, g_chip_ident, chip); - break; - default: - err = -EINVAL; - break; + if (v4l2_chip_match_host(&chip->match)) { + chip->ident = V4L2_IDENT_CX23418; + return 0; } - return err; + cx18_call_i2c_clients(cx, VIDIOC_DBG_G_CHIP_IDENT, chip); + return 0; } #ifdef CONFIG_VIDEO_ADV_DEBUG static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) { struct v4l2_dbg_register *regs = arg; + unsigned long flags; if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE) return -EINVAL; + spin_lock_irqsave(&cx18_cards_lock, flags); regs->size = 4; - if (cmd == VIDIOC_DBG_S_REGISTER) - cx18_write_enc(cx, regs->val, regs->reg); - else + if (cmd == VIDIOC_DBG_G_REGISTER) regs->val = cx18_read_enc(cx, regs->reg); + else + cx18_write_enc(cx, regs->val, regs->reg); + spin_unlock_irqrestore(&cx18_cards_lock, flags); return 0; } @@ -445,8 +296,7 @@ static int cx18_g_register(struct file *file, void *fh, if (v4l2_chip_match_host(®->match)) return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg); - /* FIXME - errors shouldn't be ignored */ - cx18_call_all(cx, core, g_register, reg); + cx18_call_i2c_clients(cx, VIDIOC_DBG_G_REGISTER, reg); return 0; } @@ -457,8 +307,7 @@ static int cx18_s_register(struct file *file, void *fh, if (v4l2_chip_match_host(®->match)) return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg); - /* FIXME - errors shouldn't be ignored */ - cx18_call_all(cx, core, s_register, reg); + cx18_call_i2c_clients(cx, VIDIOC_DBG_S_REGISTER, reg); return 0; } #endif @@ -486,8 +335,7 @@ static int cx18_querycap(struct file *file, void *fh, strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver)); strlcpy(vcap->card, cx->card_name, sizeof(vcap->card)); - snprintf(vcap->bus_info, sizeof(vcap->bus_info), - "PCI:%s", pci_name(cx->pci_dev)); + snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(cx->dev)); vcap->version = CX18_DRIVER_VERSION; /* version */ vcap->capabilities = cx->v4l2_cap; /* capabilities */ return 0; @@ -555,8 +403,7 @@ static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n"); - return -EINVAL; + return cx18_av_cmd(cx, VIDIOC_S_CROP, crop); } static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) @@ -565,8 +412,7 @@ static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n"); - return -EINVAL; + return cx18_av_cmd(cx, VIDIOC_G_CROP, crop); } static int cx18_enum_fmt_vid_cap(struct file *file, void *fh, @@ -637,7 +483,7 @@ static int cx18_g_frequency(struct file *file, void *fh, if (vf->tuner != 0) return -EINVAL; - cx18_call_all(cx, tuner, g_frequency, vf); + cx18_call_i2c_clients(cx, VIDIOC_G_FREQUENCY, vf); return 0; } @@ -656,7 +502,7 @@ int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) cx18_mute(cx); CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency); - cx18_call_all(cx, tuner, s_frequency, vf); + cx18_call_i2c_clients(cx, VIDIOC_S_FREQUENCY, vf); cx18_unmute(cx); return 0; } @@ -701,11 +547,12 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std) cx->vbi.count = cx->is_50hz ? 18 : 12; cx->vbi.start[0] = cx->is_50hz ? 6 : 10; cx->vbi.start[1] = cx->is_50hz ? 318 : 273; + cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284; CX18_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long) cx->std); /* Tuner */ - cx18_call_all(cx, tuner, s_std, cx->std); + cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std); return 0; } @@ -722,7 +569,9 @@ static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) if (vt->index != 0) return -EINVAL; - cx18_call_all(cx, tuner, s_tuner, vt); + /* Setting tuner can only set audio mode */ + cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt); + return 0; } @@ -733,7 +582,7 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) if (vt->index != 0) return -EINVAL; - cx18_call_all(cx, tuner, g_tuner, vt); + cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt); if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name)); @@ -749,30 +598,7 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) static int cx18_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap) { - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; - int f, l; - - if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) - return -EINVAL; - - cap->service_set = 0; - for (f = 0; f < 2; f++) { - for (l = 0; l < 24; l++) { - if (valid_service_line(f, l, cx->is_50hz)) { - /* - * We can find all v4l2 supported vbi services - * for the standard, on a valid line for the std - */ - cap->service_lines[f][l] = set; - cap->service_set |= set; - } else - cap->service_lines[f][l] = 0; - } - } - for (f = 0; f < 3; f++) - cap->reserved[f] = 0; - return 0; + return -EINVAL; } static int cx18_g_enc_index(struct file *file, void *fh, @@ -882,15 +708,13 @@ static int cx18_log_status(struct file *file, void *fh) struct v4l2_audio audin; int i; - CX18_INFO("================= START STATUS CARD #%d " - "=================\n", cx->instance); - CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name); + CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num); if (cx->hw_flags & CX18_HW_TVEEPROM) { struct tveeprom tv; cx18_read_eeprom(cx, &tv); } - cx18_call_all(cx, core, log_status); + cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL); cx18_get_input(cx, cx->active_input, &vidin); cx18_get_audio_input(cx, cx->audio_input, &audin); CX18_INFO("Video Input: %s\n", vidin.name); @@ -901,12 +725,12 @@ static int cx18_log_status(struct file *file, void *fh) mutex_unlock(&cx->gpio_lock); CX18_INFO("Tuner: %s\n", test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); - cx2341x_log_status(&cx->params, cx->v4l2_dev.name); + cx2341x_log_status(&cx->params, cx->name); CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags); for (i = 0; i < CX18_MAX_STREAMS; i++) { struct cx18_stream *s = &cx->streams[i]; - if (s->video_dev == NULL || s->buffers == 0) + if (s->v4l2dev == NULL || s->buffers == 0) continue; CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, @@ -916,8 +740,7 @@ static int cx18_log_status(struct file *file, void *fh) CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", (long long)cx->mpg_data_received, (long long)cx->vbi_data_inserted); - CX18_INFO("================== END STATUS CARD #%d " - "==================\n", cx->instance); + CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num); return 0; } @@ -931,8 +754,7 @@ static long cx18_default(struct file *file, void *fh, int cmd, void *arg) CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n", route->input, route->output); - cx18_call_hw(cx, cx->card->hw_audio_ctrl, audio, s_routing, - route); + cx18_audio_set_route(cx, route); break; } @@ -940,8 +762,7 @@ static long cx18_default(struct file *file, void *fh, int cmd, void *arg) u32 val = *(u32 *)arg; if ((val == 0) || (val & 0x01)) - cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, core, reset, - (u32) CX18_GPIO_RESET_Z8F0811); + cx18_reset_ir_gpio(&cx->i2c_algo_cb_data[0]); break; } @@ -961,8 +782,6 @@ long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd, mutex_lock(&cx->serialize_lock); - /* FIXME - consolidate v4l2_prio_check()'s here */ - if (cx18_debug & CX18_DBGFLG_IOCTL) vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; res = video_ioctl2(filp, cmd, arg); diff --git a/trunk/drivers/media/video/cx18/cx18-mailbox.c b/trunk/drivers/media/video/cx18/cx18-mailbox.c index 2226e5791e99..de5e723fdf44 100644 --- a/trunk/drivers/media/video/cx18/cx18-mailbox.c +++ b/trunk/drivers/media/video/cx18/cx18-mailbox.c @@ -83,8 +83,6 @@ static const struct cx18_api_info api_info[] = { API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW), - API_ENTRY(APU, CX18_APU_START, 0), - API_ENTRY(APU, CX18_APU_STOP, 0), API_ENTRY(APU, CX18_APU_RESETAI, 0), API_ENTRY(CPU, CX18_CPU_DEBUG_PEEK32, 0), API_ENTRY(0, 0, 0), @@ -100,30 +98,21 @@ static const struct cx18_api_info *find_api_info(u32 cmd) return NULL; } -/* Call with buf of n*11+1 bytes */ -static char *u32arr2hex(u32 data[], int n, char *buf) -{ - char *p; - int i; - - for (i = 0, p = buf; i < n; i++, p += 11) { - /* kernel snprintf() appends '\0' always */ - snprintf(p, 12, " %#010x", data[i]); - } - *p = '\0'; - return buf; -} - static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name) { char argstr[MAX_MB_ARGUMENTS*11+1]; + char *p; + int i; if (!(cx18_debug & CX18_DBGFLG_API)) return; + for (i = 0, p = argstr; i < MAX_MB_ARGUMENTS; i++, p += 11) { + /* kernel snprintf() appends '\0' always */ + snprintf(p, 12, " %#010x", mb->args[i]); + } CX18_DEBUG_API("%s: req %#010x ack %#010x cmd %#010x err %#010x args%s" - "\n", name, mb->request, mb->ack, mb->cmd, mb->error, - u32arr2hex(mb->args, MAX_MB_ARGUMENTS, argstr)); + "\n", name, mb->request, mb->ack, mb->cmd, mb->error, argstr); } @@ -450,8 +439,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) "incoming %s to EPU mailbox (sequence no. %u)" "\n", rpu_str[rpu], rpu_str[rpu], order_mb->request); - if (cx18_debug & CX18_DBGFLG_WARN) - dump_mb(cx, order_mb, "incoming"); + dump_mb(cx, order_mb, "incoming"); order->flags = CX18_F_EWO_MB_STALE_UPON_RECEIPT; } @@ -480,24 +468,16 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) struct mutex *mb_lock; long int timeout, ret; int i; - char argstr[MAX_MB_ARGUMENTS*11+1]; if (info == NULL) { CX18_WARN("unknown cmd %x\n", cmd); return -EINVAL; } - if (cx18_debug & CX18_DBGFLG_API) { /* only call u32arr2hex if needed */ - if (cmd == CX18_CPU_DE_SET_MDL) { - if (cx18_debug & CX18_DBGFLG_HIGHVOL) - CX18_DEBUG_HI_API("%s\tcmd %#010x args%s\n", - info->name, cmd, - u32arr2hex(data, args, argstr)); - } else - CX18_DEBUG_API("%s\tcmd %#010x args%s\n", - info->name, cmd, - u32arr2hex(data, args, argstr)); - } + if (cmd == CX18_CPU_DE_SET_MDL) + CX18_DEBUG_HI_API("%s\n", info->name); + else + CX18_DEBUG_API("%s\n", info->name); switch (info->rpu) { case APU: diff --git a/trunk/drivers/media/video/cx18/cx18-queue.c b/trunk/drivers/media/video/cx18/cx18-queue.c index 3046b8e74345..8d9441e88c4e 100644 --- a/trunk/drivers/media/video/cx18/cx18-queue.c +++ b/trunk/drivers/media/video/cx18/cx18-queue.c @@ -204,7 +204,7 @@ int cx18_stream_alloc(struct cx18_stream *s) } buf->id = cx->buffer_id++; INIT_LIST_HEAD(&buf->list); - buf->dma_handle = pci_map_single(s->cx->pci_dev, + buf->dma_handle = pci_map_single(s->cx->dev, buf->buf, s->buf_size, s->dma); cx18_buf_sync_for_cpu(s, buf); cx18_enqueue(s, buf, &s->q_free); @@ -227,7 +227,7 @@ void cx18_stream_free(struct cx18_stream *s) /* empty q_free */ while ((buf = cx18_dequeue(s, &s->q_free))) { - pci_unmap_single(s->cx->pci_dev, buf->dma_handle, + pci_unmap_single(s->cx->dev, buf->dma_handle, s->buf_size, s->dma); kfree(buf->buf); kfree(buf); diff --git a/trunk/drivers/media/video/cx18/cx18-queue.h b/trunk/drivers/media/video/cx18/cx18-queue.h index 4de06269d88f..456cec3bc28f 100644 --- a/trunk/drivers/media/video/cx18/cx18-queue.h +++ b/trunk/drivers/media/video/cx18/cx18-queue.h @@ -29,14 +29,14 @@ static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s, struct cx18_buffer *buf) { - pci_dma_sync_single_for_cpu(s->cx->pci_dev, buf->dma_handle, + pci_dma_sync_single_for_cpu(s->cx->dev, buf->dma_handle, s->buf_size, s->dma); } static inline void cx18_buf_sync_for_device(struct cx18_stream *s, struct cx18_buffer *buf) { - pci_dma_sync_single_for_device(s->cx->pci_dev, buf->dma_handle, + pci_dma_sync_single_for_device(s->cx->dev, buf->dma_handle, s->buf_size, s->dma); } diff --git a/trunk/drivers/media/video/cx18/cx18-streams.c b/trunk/drivers/media/video/cx18/cx18-streams.c index 0932b76b2373..89c1ec94f335 100644 --- a/trunk/drivers/media/video/cx18/cx18-streams.c +++ b/trunk/drivers/media/video/cx18/cx18-streams.c @@ -32,6 +32,7 @@ #include "cx18-streams.h" #include "cx18-cards.h" #include "cx18-scb.h" +#include "cx18-av-core.h" #include "cx18-dvb.h" #define CX18_DSP0_INTERRUPT_MASK 0xd0004C @@ -100,11 +101,11 @@ static struct { static void cx18_stream_init(struct cx18 *cx, int type) { struct cx18_stream *s = &cx->streams[type]; - struct video_device *video_dev = s->video_dev; + struct video_device *dev = s->v4l2dev; - /* we need to keep video_dev, so restore it afterwards */ + /* we need to keep v4l2dev, so restore it afterwards */ memset(s, 0, sizeof(*s)); - s->video_dev = video_dev; + s->v4l2dev = dev; /* initialize cx18_stream fields */ s->cx = cx; @@ -129,12 +130,12 @@ static int cx18_prep_dev(struct cx18 *cx, int type) struct cx18_stream *s = &cx->streams[type]; u32 cap = cx->v4l2_cap; int num_offset = cx18_stream_info[type].num_offset; - int num = cx->instance + cx18_first_minor + num_offset; + int num = cx->num + cx18_first_minor + num_offset; - /* These four fields are always initialized. If video_dev == NULL, then + /* These four fields are always initialized. If v4l2dev == NULL, then this stream is not in use. In that case no other fields but these four can be used. */ - s->video_dev = NULL; + s->v4l2dev = NULL; s->cx = cx; s->type = type; s->name = cx18_stream_info[type].name; @@ -162,22 +163,22 @@ static int cx18_prep_dev(struct cx18 *cx, int type) return 0; /* allocate and initialize the v4l2 video device structure */ - s->video_dev = video_device_alloc(); - if (s->video_dev == NULL) { + s->v4l2dev = video_device_alloc(); + if (s->v4l2dev == NULL) { CX18_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name); return -ENOMEM; } - snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s", - cx->v4l2_dev.name, s->name); + snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d", + cx->num); - s->video_dev->num = num; - s->video_dev->v4l2_dev = &cx->v4l2_dev; - s->video_dev->fops = &cx18_v4l2_enc_fops; - s->video_dev->release = video_device_release; - s->video_dev->tvnorms = V4L2_STD_ALL; - cx18_set_funcs(s->video_dev); + s->v4l2dev->num = num; + s->v4l2dev->parent = &cx->dev->dev; + s->v4l2dev->fops = &cx18_v4l2_enc_fops; + s->v4l2dev->release = video_device_release; + s->v4l2dev->tvnorms = V4L2_STD_ALL; + cx18_set_funcs(s->v4l2dev); return 0; } @@ -226,30 +227,28 @@ static int cx18_reg_dev(struct cx18 *cx, int type) } } - if (s->video_dev == NULL) + if (s->v4l2dev == NULL) return 0; - num = s->video_dev->num; + num = s->v4l2dev->num; /* card number + user defined offset + device offset */ if (type != CX18_ENC_STREAM_TYPE_MPG) { struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG]; - if (s_mpg->video_dev) - num = s_mpg->video_dev->num - + cx18_stream_info[type].num_offset; + if (s_mpg->v4l2dev) + num = s_mpg->v4l2dev->num + cx18_stream_info[type].num_offset; } - video_set_drvdata(s->video_dev, s); /* Register device. First try the desired minor, then any free one. */ - ret = video_register_device(s->video_dev, vfl_type, num); + ret = video_register_device(s->v4l2dev, vfl_type, num); if (ret < 0) { CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n", s->name, num); - video_device_release(s->video_dev); - s->video_dev = NULL; + video_device_release(s->v4l2dev); + s->v4l2dev = NULL; return ret; } - num = s->video_dev->num; + num = s->v4l2dev->num; switch (vfl_type) { case VFL_TYPE_GRABBER: @@ -313,9 +312,9 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister) cx->streams[type].dvb.enabled = false; } - vdev = cx->streams[type].video_dev; + vdev = cx->streams[type].v4l2dev; - cx->streams[type].video_dev = NULL; + cx->streams[type].v4l2dev = NULL; if (vdev == NULL) continue; @@ -347,88 +346,46 @@ static void cx18_vbi_setup(struct cx18_stream *s) } /* setup VBI registers */ - v4l2_subdev_call(cx->sd_av, video, s_fmt, &cx->vbi.in); - - /* - * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw - * VBI when the first analog capture channel starts, as once it starts - * (e.g. MPEG), we can't effect any change in the Encoder Raw VBI setup - * (i.e. for the VBI capture channels). We also send it for each - * analog capture channel anyway just to make sure we get the proper - * behavior - */ + cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); + + /* determine number of lines and total number of VBI bytes. + A raw line takes 1444 bytes: 4 byte SAV code + 2 * 720 + A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal + header, 42 data bytes + checksum (to be confirmed) */ if (raw) { lines = cx->vbi.count * 2; } else { - /* - * For 525/60 systems, according to the VIP 2 & BT.656 std: - * The EAV RP code's Field bit toggles on line 4, a few lines - * after the Vertcal Blank bit has already toggled. - * Tell the encoder to capture 21-4+1=18 lines per field, - * since we want lines 10 through 21. - * - * FIXME - revisit for 625/50 systems - */ - lines = cx->is_60hz ? (21 - 4 + 1) * 2 : 38; + lines = cx->is_60hz ? 24 : 38; + if (cx->is_60hz) + lines += 2; } + cx->vbi.enc_size = lines * + (raw ? cx->vbi.raw_size : cx->vbi.sliced_size); + data[0] = s->handle; /* Lines per field */ data[1] = (lines / 2) | ((lines / 2) << 16); /* bytes per line */ - data[2] = (raw ? vbi_active_samples - : (cx->is_60hz ? vbi_hblank_samples_60Hz - : vbi_hblank_samples_50Hz)); + data[2] = (raw ? cx->vbi.raw_decoder_line_size + : cx->vbi.sliced_decoder_line_size); /* Every X number of frames a VBI interrupt arrives (frames as in 25 or 30 fps) */ data[3] = 1; - /* - * Set the SAV/EAV RP codes to look for as start/stop points - * when in VIP-1.1 mode - */ + /* Setup VBI for the cx25840 digitizer */ if (raw) { - /* - * Start codes for beginning of "active" line in vertical blank - * 0x20 ( VerticalBlank ) - * 0x60 ( EvenField VerticalBlank ) - */ data[4] = 0x20602060; - /* - * End codes for end of "active" raw lines and regular lines - * 0x30 ( VerticalBlank HorizontalBlank) - * 0x70 ( EvenField VerticalBlank HorizontalBlank) - * 0x90 (Task HorizontalBlank) - * 0xd0 (Task EvenField HorizontalBlank) - */ data[5] = 0x307090d0; } else { - /* - * End codes for active video, we want data in the hblank region - * 0xb0 (Task 0 VerticalBlank HorizontalBlank) - * 0xf0 (Task EvenField VerticalBlank HorizontalBlank) - * - * Since the V bit is only allowed to toggle in the EAV RP code, - * just before the first active region line, these two - * are problematic: - * 0x90 (Task HorizontalBlank) - * 0xd0 (Task EvenField HorizontalBlank) - * - * We have set the digitzer such that we don't have to worry - * about these problem codes. - */ data[4] = 0xB0F0B0F0; - /* - * Start codes for beginning of active line in vertical blank - * 0xa0 (Task VerticalBlank ) - * 0xe0 (Task EvenField VerticalBlank ) - */ data[5] = 0xA0E0A0E0; } CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n", data[0], data[1], data[2], data[3], data[4], data[5]); - cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); + if (s->type == CX18_ENC_STREAM_TYPE_VBI) + cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); } struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s, @@ -477,10 +434,10 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) u32 data[MAX_MB_ARGUMENTS]; struct cx18 *cx = s->cx; struct cx18_buffer *buf; + int ts = 0; int captype = 0; - struct cx18_api_func_private priv; - if (s->video_dev == NULL && s->dvb.enabled == 0) + if (s->v4l2dev == NULL && s->dvb.enabled == 0) return -EINVAL; CX18_DEBUG_INFO("Start encoder stream %s\n", s->name); @@ -496,6 +453,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) case CX18_ENC_STREAM_TYPE_TS: captype = CAPTURE_CHANNEL_TYPE_TS; + ts = 1; break; case CX18_ENC_STREAM_TYPE_YUV: captype = CAPTURE_CHANNEL_TYPE_YUV; @@ -504,16 +462,8 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) captype = CAPTURE_CHANNEL_TYPE_PCM; break; case CX18_ENC_STREAM_TYPE_VBI: -#ifdef CX18_ENCODER_PARSES_SLICED captype = cx18_raw_vbi(cx) ? CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI; -#else - /* - * Currently we set things up so that Sliced VBI from the - * digitizer is handled as Raw VBI by the encoder - */ - captype = CAPTURE_CHANNEL_TYPE_VBI; -#endif cx->vbi.frame = 0; cx->vbi.inserted_frame = 0; memset(cx->vbi.sliced_mpeg_size, @@ -523,6 +473,10 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) return -EINVAL; } + /* mute/unmute video */ + cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, + s->handle, !!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)); + /* Clear Streamoff flags in case left from last capture */ clear_bit(CX18_F_S_STREAMOFF, &s->s_flags); @@ -530,63 +484,31 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) s->handle = data[0]; cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype); - /* - * For everything but CAPTURE_CHANNEL_TYPE_TS, play it safe and - * set up all the parameters, as it is not obvious which parameters the - * firmware shares across capture channel types and which it does not. - * - * Some of the cx18_vapi() calls below apply to only certain capture - * channel types. We're hoping there's no harm in calling most of them - * anyway, as long as the values are all consistent. Setting some - * shared parameters will have no effect once an analog capture channel - * has started streaming. - */ - if (captype != CAPTURE_CHANNEL_TYPE_TS) { + if (atomic_read(&cx->ana_capturing) == 0 && !ts) { + struct cx18_api_func_private priv; + + /* Stuff from Windows, we don't know what it is */ cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0); cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1); cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0); cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1); + cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, s->handle, 12); - /* - * Audio related reset according to - * Documentation/video4linux/cx2341x/fw-encoder-api.txt - */ - if (atomic_read(&cx->ana_capturing) == 0) - cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, - s->handle, 12); - - /* - * Number of lines for Field 1 & Field 2 according to - * Documentation/video4linux/cx2341x/fw-encoder-api.txt - * Field 1 is 312 for 625 line systems in BT.656 - * Field 2 is 313 for 625 line systems in BT.656 - */ cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3, - s->handle, 312, 313); + s->handle, cx->digitizer, cx->digitizer); + /* Setup VBI */ if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE) cx18_vbi_setup(s); - /* - * assign program index info. - * Mask 7: select I/P/B, Num_req: 400 max - * FIXME - currently we have this hardcoded as disabled - */ + /* assign program index info. + Mask 7: select I/P/B, Num_req: 400 max */ cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0); - /* Call out to the common CX2341x API setup for user controls */ + /* Setup API for Stream */ priv.cx = cx; priv.s = s; cx2341x_update(&priv, cx18_api_func, NULL, &cx->params); - - /* - * When starting a capture and we're set for radio, - * ensure the video is muted, despite the user control. - */ - if (!cx->params.video_mute && - test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) - cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle, - (cx->params.video_mute_yuv << 8) | 1); } if (atomic_read(&cx->tot_capturing) == 0) { @@ -630,7 +552,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) } /* you're live! sit back and await interrupts :) */ - if (captype != CAPTURE_CHANNEL_TYPE_TS) + if (!ts) atomic_inc(&cx->ana_capturing); atomic_inc(&cx->tot_capturing); return 0; @@ -643,7 +565,7 @@ void cx18_stop_all_captures(struct cx18 *cx) for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) { struct cx18_stream *s = &cx->streams[i]; - if (s->video_dev == NULL && s->dvb.enabled == 0) + if (s->v4l2dev == NULL && s->dvb.enabled == 0) continue; if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) cx18_stop_v4l2_encode_stream(s, 0); @@ -655,7 +577,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) struct cx18 *cx = s->cx; unsigned long then; - if (s->video_dev == NULL && s->dvb.enabled == 0) + if (s->v4l2dev == NULL && s->dvb.enabled == 0) return -EINVAL; /* This function assumes that you are allowed to stop the capture @@ -707,7 +629,7 @@ u32 cx18_find_handle(struct cx18 *cx) for (i = 0; i < CX18_MAX_STREAMS; i++) { struct cx18_stream *s = &cx->streams[i]; - if (s->video_dev && (s->handle != CX18_INVALID_TASK_HANDLE)) + if (s->v4l2dev && (s->handle != CX18_INVALID_TASK_HANDLE)) return s->handle; } return CX18_INVALID_TASK_HANDLE; @@ -725,7 +647,7 @@ struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle) s = &cx->streams[i]; if (s->handle != handle) continue; - if (s->video_dev || s->dvb.enabled) + if (s->v4l2dev || s->dvb.enabled) return s; } return NULL; diff --git a/trunk/drivers/media/video/cx18/cx18-vbi.c b/trunk/drivers/media/video/cx18/cx18-vbi.c index c2aef4add31d..fb595bd548e8 100644 --- a/trunk/drivers/media/video/cx18/cx18-vbi.c +++ b/trunk/drivers/media/video/cx18/cx18-vbi.c @@ -25,16 +25,7 @@ #include "cx18-vbi.h" #include "cx18-ioctl.h" #include "cx18-queue.h" - -/* - * Raster Reference/Protection (RP) bytes, used in Start/End Active - * Video codes emitted from the digitzer in VIP 1.x mode, that flag the start - * of VBI sample or VBI ancilliary data regions in the digitial ratser line. - * - * Task FieldEven VerticalBlank HorizontalBlank 0 0 0 0 - */ -static const u8 raw_vbi_sav_rp[2] = { 0x20, 0x60 }; /* __V_, _FV_ */ -static const u8 sliced_vbi_eav_rp[2] = { 0xb0, 0xf0 }; /* T_VH, TFVH */ +#include "cx18-av-core.h" static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp) { @@ -43,17 +34,10 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp) u32 linemask[2] = { 0, 0 }; unsigned short size; static const u8 mpeg_hdr_data[] = { - /* MPEG-2 Program Pack */ - 0x00, 0x00, 0x01, 0xba, /* Prog Pack start code */ - 0x44, 0x00, 0x0c, 0x66, 0x24, 0x01, /* SCR, SCR Ext, markers */ - 0x01, 0xd1, 0xd3, /* Mux Rate, markers */ - 0xfa, 0xff, 0xff, /* Res, Suff cnt, Stuff */ - /* MPEG-2 Private Stream 1 PES Packet */ - 0x00, 0x00, 0x01, 0xbd, /* Priv Stream 1 start */ - 0x00, 0x1a, /* length */ - 0x84, 0x80, 0x07, /* flags, hdr data len */ - 0x21, 0x00, 0x5d, 0x63, 0xa7, /* PTS, markers */ - 0xff, 0xff /* stuffing */ + 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66, + 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff, + 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80, + 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff }; const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */ int idx = cx->vbi.frame % CX18_VBI_FRAMES; @@ -87,9 +71,7 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp) memcpy(dst + sd + 4, dst + sd + 12, line * 43); size = 4 + ((43 * line + 3) & ~3); } else { - memcpy(dst + sd, "itv0", 4); - cpu_to_le32s(&linemask[0]); - cpu_to_le32s(&linemask[1]); + memcpy(dst + sd, "cx0", 4); memcpy(dst + sd + 4, &linemask[0], 8); size = 12 + ((43 * line + 3) & ~3); } @@ -104,76 +86,58 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp) } /* Compress raw VBI format, removes leading SAV codes and surplus space - after the frame. Returns new compressed size. */ -static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size) + after the field. + Returns new compressed size. */ +static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size) { - u32 line_size = vbi_active_samples; - u32 lines = cx->vbi.count * 2; + u32 line_size = cx->vbi.raw_decoder_line_size; + u32 lines = cx->vbi.count; + u8 sav1 = cx->vbi.raw_decoder_sav_odd_field; + u8 sav2 = cx->vbi.raw_decoder_sav_even_field; u8 *q = buf; u8 *p; int i; - /* Skip the header */ - buf += hdr_size; - for (i = 0; i < lines; i++) { p = buf + i * line_size; /* Look for SAV code */ if (p[0] != 0xff || p[1] || p[2] || - (p[3] != raw_vbi_sav_rp[0] && - p[3] != raw_vbi_sav_rp[1])) + (p[3] != sav1 && p[3] != sav2)) break; - if (i == lines - 1) { - /* last line is hdr_size bytes short - extrapolate it */ - memcpy(q, p + 4, line_size - 4 - hdr_size); - q += line_size - 4 - hdr_size; - p += line_size - hdr_size - 1; - memset(q, (int) *p, hdr_size); - } else { - memcpy(q, p + 4, line_size - 4); - q += line_size - 4; - } + memcpy(q, p + 4, line_size - 4); + q += line_size - 4; } return lines * (line_size - 4); } -static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size, - const u32 hdr_size) + +/* Compressed VBI format, all found sliced blocks put next to one another + Returns new compressed size */ +static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf, + u32 size, u8 sav) { + u32 line_size = cx->vbi.sliced_decoder_line_size; struct v4l2_decode_vbi_line vbi; int i; - u32 line = 0; - u32 line_size = cx->is_60hz ? vbi_hblank_samples_60Hz - : vbi_hblank_samples_50Hz; /* find the first valid line */ - for (i = hdr_size, buf += hdr_size; i < size; i++, buf++) { - if (buf[0] == 0xff && !buf[1] && !buf[2] && - (buf[3] == sliced_vbi_eav_rp[0] || - buf[3] == sliced_vbi_eav_rp[1])) + for (i = 0; i < size; i++, buf++) { + if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav) break; } - /* - * The last line is short by hdr_size bytes, but for the remaining - * checks against size, we pretend that it is not, by counting the - * header bytes we knowingly skipped - */ - size -= (i - hdr_size); + size -= i; if (size < line_size) return line; - for (i = 0; i < size / line_size; i++) { u8 *p = buf + i * line_size; - /* Look for EAV code */ - if (p[0] != 0xff || p[1] || p[2] || - (p[3] != sliced_vbi_eav_rp[0] && - p[3] != sliced_vbi_eav_rp[1])) + /* Look for SAV code */ + if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) continue; vbi.p = p + 4; - v4l2_subdev_call(cx->sd_av, video, decode_vbi_line, &vbi); + cx18_av_cmd(cx, VIDIOC_INT_DECODE_VBI_LINE, &vbi); if (vbi.type) { cx->vbi.sliced_data[line].id = vbi.type; cx->vbi.sliced_data[line].field = vbi.is_second_field; @@ -186,56 +150,51 @@ static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size, } void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, - int streamtype) + u64 pts_stamp, int streamtype) { - /* - * The CX23418 provides a 12 byte header in its raw VBI buffers to us: - * 0x3fffffff [4 bytes of something] [4 byte presentation time stamp] - */ - struct vbi_data_hdr { - __be32 magic; - __be32 unknown; - __be32 pts; - } *hdr = (struct vbi_data_hdr *) buf->buf; - u8 *p = (u8 *) buf->buf; u32 size = buf->bytesused; - u32 pts; int lines; if (streamtype != CX18_ENC_STREAM_TYPE_VBI) return; - /* - * The CX23418 sends us data that is 32 bit little-endian swapped, - * but we want the raw VBI bytes in the order they were in the raster - * line. This has a side effect of making the header big endian - */ - cx18_buf_swap(buf); - /* Raw VBI data */ if (cx18_raw_vbi(cx)) { + u8 type; + + cx18_buf_swap(buf); + + /* Skip 12 bytes of header that gets stuffed in */ + size -= 12; + memcpy(p, &buf->buf[12], size); + type = p[3]; - size = buf->bytesused = - compress_raw_buf(cx, p, size, sizeof(struct vbi_data_hdr)); + size = buf->bytesused = compress_raw_buf(cx, p, size); - /* - * Hack needed for compatibility with old VBI software. - * Write the frame # at the last 4 bytes of the frame - */ - p += size - 4; - memcpy(p, &cx->vbi.frame, 4); - cx->vbi.frame++; + /* second field of the frame? */ + if (type == cx->vbi.raw_decoder_sav_even_field) { + /* Dirty hack needed for backwards + compatibility of old VBI software. */ + p += size - 4; + memcpy(p, &cx->vbi.frame, 4); + cx->vbi.frame++; + } return; } /* Sliced VBI data with data insertion */ + cx18_buf_swap(buf); - pts = (be32_to_cpu(hdr->magic) == 0x3fffffff) ? be32_to_cpu(hdr->pts) - : 0; - - lines = compress_sliced_buf(cx, p, size, sizeof(struct vbi_data_hdr)); - + /* first field */ + lines = compress_sliced_buf(cx, 0, p, size / 2, + cx->vbi.sliced_decoder_sav_odd_field); + /* second field */ + /* experimentation shows that the second half does not always + begin at the exact address. So start a bit earlier + (hence 32). */ + lines = compress_sliced_buf(cx, lines, p + size / 2 - 32, + size / 2 + 32, cx->vbi.sliced_decoder_sav_even_field); /* always return at least one empty line */ if (lines == 0) { cx->vbi.sliced_data[0].id = 0; @@ -247,6 +206,6 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, memcpy(p, &cx->vbi.sliced_data[0], size); if (cx->vbi.insert_mpeg) - copy_vbi_data(cx, lines, pts); + copy_vbi_data(cx, lines, pts_stamp); cx->vbi.frame++; } diff --git a/trunk/drivers/media/video/cx18/cx18-vbi.h b/trunk/drivers/media/video/cx18/cx18-vbi.h index e7e1ae427f34..c56ff7d28f20 100644 --- a/trunk/drivers/media/video/cx18/cx18-vbi.h +++ b/trunk/drivers/media/video/cx18/cx18-vbi.h @@ -22,5 +22,5 @@ */ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, - int streamtype); + u64 pts_stamp, int streamtype); int cx18_used_line(struct cx18 *cx, int line, int field); diff --git a/trunk/drivers/media/video/cx18/cx18-version.h b/trunk/drivers/media/video/cx18/cx18-version.h index bd9bd44da791..84c0ff13b607 100644 --- a/trunk/drivers/media/video/cx18/cx18-version.h +++ b/trunk/drivers/media/video/cx18/cx18-version.h @@ -24,8 +24,8 @@ #define CX18_DRIVER_NAME "cx18" #define CX18_DRIVER_VERSION_MAJOR 1 -#define CX18_DRIVER_VERSION_MINOR 1 -#define CX18_DRIVER_VERSION_PATCHLEVEL 0 +#define CX18_DRIVER_VERSION_MINOR 0 +#define CX18_DRIVER_VERSION_PATCHLEVEL 4 #define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL) #define CX18_DRIVER_VERSION KERNEL_VERSION(CX18_DRIVER_VERSION_MAJOR, \ diff --git a/trunk/drivers/media/video/cx18/cx18-video.c b/trunk/drivers/media/video/cx18/cx18-video.c index 6fdadedf17a8..2e5c41939330 100644 --- a/trunk/drivers/media/video/cx18/cx18-video.c +++ b/trunk/drivers/media/video/cx18/cx18-video.c @@ -21,6 +21,7 @@ #include "cx18-driver.h" #include "cx18-video.h" +#include "cx18-av-core.h" #include "cx18-cards.h" void cx18_video_set_io(struct cx18 *cx) @@ -31,7 +32,7 @@ void cx18_video_set_io(struct cx18 *cx) route.input = cx->card->video_inputs[inp].video_input; route.output = 0; - v4l2_subdev_call(cx->sd_av, video, s_routing, &route); + cx18_av_cmd(cx, VIDIOC_INT_S_VIDEO_ROUTING, &route); type = cx->card->video_inputs[inp].video_type; diff --git a/trunk/drivers/media/video/cx18/cx23418.h b/trunk/drivers/media/video/cx18/cx23418.h index 9956abf576c5..601f3a2ab742 100644 --- a/trunk/drivers/media/video/cx18/cx23418.h +++ b/trunk/drivers/media/video/cx18/cx23418.h @@ -56,22 +56,6 @@ #define APU_CMD_MASK 0x10000000 #define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000) -#define CX18_APU_ENCODING_METHOD_MPEG (0 << 28) -#define CX18_APU_ENCODING_METHOD_AC3 (1 << 28) - -/* Description: Command APU to start audio - IN[0] - audio parameters (same as CX18_CPU_SET_AUDIO_PARAMETERS?) - IN[1] - caller buffer address, or 0 - ReturnCode - ??? */ -#define CX18_APU_START (APU_CMD_MASK | 0x01) - -/* Description: Command APU to stop audio - IN[0] - encoding method to stop - ReturnCode - ??? */ -#define CX18_APU_STOP (APU_CMD_MASK | 0x02) - -/* Description: Command APU to reset the AI - ReturnCode - ??? */ #define CX18_APU_RESETAI (APU_CMD_MASK | 0x05) /* Description: This command indicates that a Memory Descriptor List has been diff --git a/trunk/drivers/media/video/cx2341x.c b/trunk/drivers/media/video/cx2341x.c index 8ded52946334..cbbe47fb87b7 100644 --- a/trunk/drivers/media/video/cx2341x.c +++ b/trunk/drivers/media/video/cx2341x.c @@ -1,5 +1,5 @@ /* - * cx2341x - generic code for cx23415/6/8 based devices + * cx2341x - generic code for cx23415/6 based devices * * Copyright (C) 2006 Hans Verkuil * @@ -30,7 +30,7 @@ #include #include -MODULE_DESCRIPTION("cx23415/6/8 driver"); +MODULE_DESCRIPTION("cx23415/6 driver"); MODULE_AUTHOR("Hans Verkuil"); MODULE_LICENSE("GPL"); @@ -38,7 +38,6 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -/* Must be sorted from low to high control ID! */ const u32 cx2341x_mpeg_ctrls[] = { V4L2_CID_MPEG_CLASS, V4L2_CID_MPEG_STREAM_TYPE, @@ -51,7 +50,6 @@ const u32 cx2341x_mpeg_ctrls[] = { V4L2_CID_MPEG_AUDIO_EMPHASIS, V4L2_CID_MPEG_AUDIO_CRC, V4L2_CID_MPEG_AUDIO_MUTE, - V4L2_CID_MPEG_AUDIO_AC3_BITRATE, V4L2_CID_MPEG_VIDEO_ENCODING, V4L2_CID_MPEG_VIDEO_ASPECT, V4L2_CID_MPEG_VIDEO_B_FRAMES, @@ -96,7 +94,6 @@ static const struct cx2341x_mpeg_params default_params = { .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2, .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K, - .audio_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_224K, .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO, .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4, .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE, @@ -151,9 +148,6 @@ static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params *params, case V4L2_CID_MPEG_AUDIO_L2_BITRATE: ctrl->value = params->audio_l2_bitrate; break; - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: - ctrl->value = params->audio_ac3_bitrate; - break; case V4L2_CID_MPEG_AUDIO_MODE: ctrl->value = params->audio_mode; break; @@ -262,12 +256,6 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy, params->audio_sampling_freq = ctrl->value; break; case V4L2_CID_MPEG_AUDIO_ENCODING: - if (busy) - return -EBUSY; - if (params->capabilities & CX2341X_CAP_HAS_AC3) - if (ctrl->value != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 && - ctrl->value != V4L2_MPEG_AUDIO_ENCODING_AC3) - return -ERANGE; params->audio_encoding = ctrl->value; break; case V4L2_CID_MPEG_AUDIO_L2_BITRATE: @@ -275,13 +263,6 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy, return -EBUSY; params->audio_l2_bitrate = ctrl->value; break; - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: - if (busy) - return -EBUSY; - if (!(params->capabilities & CX2341X_CAP_HAS_AC3)) - return -EINVAL; - params->audio_ac3_bitrate = ctrl->value; - break; case V4L2_CID_MPEG_AUDIO_MODE: params->audio_mode = ctrl->value; break; @@ -500,106 +481,29 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, int err; switch (qctrl->id) { - case V4L2_CID_MPEG_STREAM_TYPE: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_STREAM_TYPE_MPEG2_PS, - V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1, - V4L2_MPEG_STREAM_TYPE_MPEG2_PS); - - case V4L2_CID_MPEG_STREAM_VBI_FMT: - if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI) - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_STREAM_VBI_FMT_NONE, - V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1, - V4L2_MPEG_STREAM_VBI_FMT_NONE); - return cx2341x_ctrl_query_fill(qctrl, - V4L2_MPEG_STREAM_VBI_FMT_NONE, - V4L2_MPEG_STREAM_VBI_FMT_NONE, 1, - default_params.stream_vbi_fmt); - - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100, - V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1, - V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000); - case V4L2_CID_MPEG_AUDIO_ENCODING: - if (params->capabilities & CX2341X_CAP_HAS_AC3) { - /* - * The state of L2 & AC3 bitrate controls can change - * when this control changes, but v4l2_ctrl_query_fill() - * already sets V4L2_CTRL_FLAG_UPDATE for - * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here. - */ - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_ENCODING_LAYER_2, - V4L2_MPEG_AUDIO_ENCODING_AC3, 1, - default_params.audio_encoding); - } - return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_AUDIO_ENCODING_LAYER_2, V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1, default_params.audio_encoding); case V4L2_CID_MPEG_AUDIO_L2_BITRATE: - err = v4l2_ctrl_query_fill(qctrl, + return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_AUDIO_L2_BITRATE_192K, V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, default_params.audio_l2_bitrate); - if (err) - return err; - if (params->capabilities & CX2341X_CAP_HAS_AC3 && - params->audio_encoding != V4L2_MPEG_AUDIO_ENCODING_LAYER_2) - qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - return 0; - case V4L2_CID_MPEG_AUDIO_MODE: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_MODE_STEREO, - V4L2_MPEG_AUDIO_MODE_MONO, 1, - V4L2_MPEG_AUDIO_MODE_STEREO); + case V4L2_CID_MPEG_AUDIO_L1_BITRATE: + case V4L2_CID_MPEG_AUDIO_L3_BITRATE: + return -EINVAL; case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: - err = v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4, - V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1, - V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4); + err = v4l2_ctrl_query_fill_std(qctrl); if (err == 0 && params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; return err; - case V4L2_CID_MPEG_AUDIO_EMPHASIS: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_EMPHASIS_NONE, - V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1, - V4L2_MPEG_AUDIO_EMPHASIS_NONE); - - case V4L2_CID_MPEG_AUDIO_CRC: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_CRC_NONE, - V4L2_MPEG_AUDIO_CRC_CRC16, 1, - V4L2_MPEG_AUDIO_CRC_NONE); - - case V4L2_CID_MPEG_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0); - - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: - err = v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_AUDIO_AC3_BITRATE_48K, - V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 1, - default_params.audio_ac3_bitrate); - if (err) - return err; - if (params->capabilities & CX2341X_CAP_HAS_AC3) { - if (params->audio_encoding != - V4L2_MPEG_AUDIO_ENCODING_AC3) - qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - } else - qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; - return 0; - case V4L2_CID_MPEG_VIDEO_ENCODING: /* this setting is read-only for the cx2341x since the V4L2_CID_MPEG_STREAM_TYPE really determines the @@ -612,51 +516,32 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; return err; - case V4L2_CID_MPEG_VIDEO_ASPECT: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_VIDEO_ASPECT_1x1, - V4L2_MPEG_VIDEO_ASPECT_221x100, 1, - V4L2_MPEG_VIDEO_ASPECT_4x3); - - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2); - - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - return v4l2_ctrl_query_fill(qctrl, 1, 34, 1, - params->is_50hz ? 12 : 15); - - case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: - return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1); - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - err = v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1, - V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); + err = v4l2_ctrl_query_fill_std(qctrl); if (err == 0 && params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; return err; - case V4L2_CID_MPEG_VIDEO_BITRATE: - return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000); - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000); + err = v4l2_ctrl_query_fill_std(qctrl); if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; return err; - case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: - return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0); - - case V4L2_CID_MPEG_VIDEO_MUTE: - return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0); + case V4L2_CID_MPEG_STREAM_VBI_FMT: + if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI) + return v4l2_ctrl_query_fill_std(qctrl); + return cx2341x_ctrl_query_fill(qctrl, + V4L2_MPEG_STREAM_VBI_FMT_NONE, + V4L2_MPEG_STREAM_VBI_FMT_NONE, 1, + default_params.stream_vbi_fmt); - case V4L2_CID_MPEG_VIDEO_MUTE_YUV: /* Init YUV (really YCbCr) to black */ - return v4l2_ctrl_query_fill(qctrl, 0, 0xffffff, 1, 0x008080); + case V4L2_CID_MPEG_VIDEO_GOP_SIZE: + return v4l2_ctrl_query_fill(qctrl, 1, 34, 1, + params->is_50hz ? 12 : 15); /* CX23415/6 specific */ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: @@ -758,7 +643,7 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, default_params.stream_insert_nav_packets); default: - return -EINVAL; + return v4l2_ctrl_query_fill_std(qctrl); } } @@ -786,15 +671,6 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id) NULL }; - static const char *mpeg_audio_encoding_l2_ac3[] = { - "", - "MPEG-1/2 Layer II", - "", - "", - "AC-3", - NULL - }; - static const char *cx2341x_video_spatial_filter_mode_menu[] = { "Manual", "Auto", @@ -835,9 +711,6 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id) case V4L2_CID_MPEG_STREAM_TYPE: return (p->capabilities & CX2341X_CAP_HAS_TS) ? mpeg_stream_type_with_ts : mpeg_stream_type_without_ts; - case V4L2_CID_MPEG_AUDIO_ENCODING: - return (p->capabilities & CX2341X_CAP_HAS_AC3) ? - mpeg_audio_encoding_l2_ac3 : v4l2_ctrl_get_menu(id); case V4L2_CID_MPEG_AUDIO_L1_BITRATE: case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return NULL; @@ -857,34 +730,16 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id) } EXPORT_SYMBOL(cx2341x_ctrl_get_menu); -/* definitions for audio properties bits 29-28 */ -#define CX2341X_AUDIO_ENCODING_METHOD_MPEG 0 -#define CX2341X_AUDIO_ENCODING_METHOD_AC3 1 -#define CX2341X_AUDIO_ENCODING_METHOD_LPCM 2 - static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params) { - params->audio_properties = - (params->audio_sampling_freq << 0) | + params->audio_properties = (params->audio_sampling_freq << 0) | + ((3 - params->audio_encoding) << 2) | + ((1 + params->audio_l2_bitrate) << 4) | (params->audio_mode << 8) | (params->audio_mode_extension << 10) | (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17) ? 3 : params->audio_emphasis) << 12) | (params->audio_crc << 14); - - if ((params->capabilities & CX2341X_CAP_HAS_AC3) && - params->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) { - params->audio_properties |= - /* Not sure if this MPEG Layer II setting is required */ - ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) | - (params->audio_ac3_bitrate << 4) | - (CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28); - } else { - /* Assuming MPEG Layer II */ - params->audio_properties |= - ((3 - params->audio_encoding) << 2) | - ((1 + params->audio_l2_bitrate) << 4); - } } int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy, @@ -1167,10 +1022,7 @@ void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix) prefix, cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ), cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING), - cx2341x_menu_item(p, - p->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3 - ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE - : V4L2_CID_MPEG_AUDIO_L2_BITRATE), + cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE), cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE), p->audio_mute ? " (muted)" : ""); if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) diff --git a/trunk/drivers/media/video/cx23885/Kconfig b/trunk/drivers/media/video/cx23885/Kconfig index fd3fc3e3198a..00f1e2e8889e 100644 --- a/trunk/drivers/media/video/cx23885/Kconfig +++ b/trunk/drivers/media/video/cx23885/Kconfig @@ -15,15 +15,12 @@ config VIDEO_CX23885 select DVB_S5H1411 if !DVB_FE_CUSTOMISE select DVB_LGDT330X if !DVB_FE_CUSTOMISE select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select DVB_TDA10048 if !DVB_FE_CUSTOMISE - select DVB_LNBP21 if !DVB_FE_CUSTOMISE - select DVB_STV6110 if !DVB_FE_CUSTOMISE - select DVB_STV0900 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE + select DVB_TDA10048 if !DVB_FE_CUSTOMIZE + select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE + select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE + select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE + select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE ---help--- This is a video4linux driver for Conexant 23885 based TV cards. diff --git a/trunk/drivers/media/video/cx23885/Makefile b/trunk/drivers/media/video/cx23885/Makefile index ab8ea35c9bfb..29c23b44c13c 100644 --- a/trunk/drivers/media/video/cx23885/Makefile +++ b/trunk/drivers/media/video/cx23885/Makefile @@ -1,6 +1,4 @@ -cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \ - cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \ - netup-init.o cimax2.o netup-eeprom.o +cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o obj-$(CONFIG_VIDEO_CX23885) += cx23885.o diff --git a/trunk/drivers/media/video/cx23885/cimax2.c b/trunk/drivers/media/video/cx23885/cimax2.c deleted file mode 100644 index 9a6536998d90..000000000000 --- a/trunk/drivers/media/video/cx23885/cimax2.c +++ /dev/null @@ -1,472 +0,0 @@ -/* - * cimax2.c - * - * CIMax2(R) SP2 driver in conjunction with NetUp Dual DVB-S2 CI card - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin - * Copyright (C) 2009 Abylay Ospan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "cx23885.h" -#include "dvb_ca_en50221.h" -/**** Bit definitions for MC417_RWD and MC417_OEN registers *** - bits 31-16 -+-----------+ -| Reserved | -+-----------+ - bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8 -+-------+-------+-------+-------+-------+-------+-------+-------+ -| WR# | RD# | | ACK# | ADHI | ADLO | CS1# | CS0# | -+-------+-------+-------+-------+-------+-------+-------+-------+ - bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 -+-------+-------+-------+-------+-------+-------+-------+-------+ -| DATA7| DATA6| DATA5| DATA4| DATA3| DATA2| DATA1| DATA0| -+-------+-------+-------+-------+-------+-------+-------+-------+ -***/ -/* MC417 */ -#define NETUP_DATA 0x000000ff -#define NETUP_WR 0x00008000 -#define NETUP_RD 0x00004000 -#define NETUP_ACK 0x00001000 -#define NETUP_ADHI 0x00000800 -#define NETUP_ADLO 0x00000400 -#define NETUP_CS1 0x00000200 -#define NETUP_CS0 0x00000100 -#define NETUP_EN_ALL 0x00001000 -#define NETUP_CTRL_OFF (NETUP_CS1 | NETUP_CS0 | NETUP_WR | NETUP_RD) -#define NETUP_CI_CTL 0x04 -#define NETUP_CI_RD 1 - - -static unsigned int ci_dbg; -module_param(ci_dbg, int, 0644); -MODULE_PARM_DESC(ci_dbg, "Enable CI debugging"); - -#define ci_dbg_print(args...) \ - do { \ - if (ci_dbg) \ - printk(KERN_DEBUG args); \ - } while (0) - -/* stores all private variables for communication with CI */ -struct netup_ci_state { - struct dvb_ca_en50221 ca; - struct mutex ca_mutex; - struct i2c_adapter *i2c_adap; - u8 ci_i2c_addr; - int status; - struct work_struct work; - void *priv; -}; - -struct mutex gpio_mutex;/* Two CiMax's uses same GPIO lines */ - -int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg, - u8 *buf, int len) -{ - int ret; - struct i2c_msg msg[] = { - { - .addr = addr, - .flags = 0, - .buf = ®, - .len = 1 - }, { - .addr = addr, - .flags = I2C_M_RD, - .buf = buf, - .len = len - } - }; - - ret = i2c_transfer(i2c_adap, msg, 2); - - if (ret != 2) { - ci_dbg_print("%s: i2c read error, Reg = 0x%02x, Status = %d\n", - __func__, reg, ret); - - return -1; - } - - ci_dbg_print("%s: i2c read Addr=0x%04x, Reg = 0x%02x, data = %02x\n", - __func__, addr, reg, buf[0]); - - return 0; -} - -int netup_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg, - u8 *buf, int len) -{ - int ret; - u8 buffer[len + 1]; - - struct i2c_msg msg = { - .addr = addr, - .flags = 0, - .buf = &buffer[0], - .len = len + 1 - }; - - buffer[0] = reg; - memcpy(&buffer[1], buf, len); - - ret = i2c_transfer(i2c_adap, &msg, 1); - - if (ret != 1) { - ci_dbg_print("%s: i2c write error, Reg=[0x%02x], Status=%d\n", - __func__, reg, ret); - return -1; - } - - return 0; -} - -int netup_ci_get_mem(struct cx23885_dev *dev) -{ - int mem; - unsigned long timeout = jiffies + msecs_to_jiffies(1); - - for (;;) { - mem = cx_read(MC417_RWD); - if ((mem & NETUP_ACK) == 0) - break; - if (time_after(jiffies, timeout)) - break; - udelay(1); - } - - cx_set(MC417_RWD, NETUP_CTRL_OFF); - - return mem & 0xff; -} - -int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, - u8 flag, u8 read, int addr, u8 data) -{ - struct netup_ci_state *state = en50221->data; - struct cx23885_tsport *port = state->priv; - struct cx23885_dev *dev = port->dev; - - u8 store; - int mem; - int ret; - - if (0 != slot) - return -EINVAL; - - ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &store, 1); - if (ret != 0) - return ret; - - store &= ~0x0c; - store |= flag; - - ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &store, 1); - if (ret != 0) - return ret; - - mutex_lock(&gpio_mutex); - - /* write addr */ - cx_write(MC417_OEN, NETUP_EN_ALL); - cx_write(MC417_RWD, NETUP_CTRL_OFF | - NETUP_ADLO | (0xff & addr)); - cx_clear(MC417_RWD, NETUP_ADLO); - cx_write(MC417_RWD, NETUP_CTRL_OFF | - NETUP_ADHI | (0xff & (addr >> 8))); - cx_clear(MC417_RWD, NETUP_ADHI); - - if (read) /* data in */ - cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA); - else /* data out */ - cx_write(MC417_RWD, NETUP_CTRL_OFF | data); - - /* choose chip */ - cx_clear(MC417_RWD, - (state->ci_i2c_addr == 0x40) ? NETUP_CS0 : NETUP_CS1); - /* read/write */ - cx_clear(MC417_RWD, (read) ? NETUP_RD : NETUP_WR); - mem = netup_ci_get_mem(dev); - - mutex_unlock(&gpio_mutex); - - if (!read) - if (mem < 0) - return -EREMOTEIO; - - ci_dbg_print("%s: %s: addr=[0x%02x], %s=%x\n", __func__, - (read) ? "read" : "write", addr, - (flag == NETUP_CI_CTL) ? "ctl" : "mem", - (read) ? mem : data); - - if (read) - return mem; - - return 0; -} - -int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221, - int slot, int addr) -{ - return netup_ci_op_cam(en50221, slot, 0, NETUP_CI_RD, addr, 0); -} - -int netup_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221, - int slot, int addr, u8 data) -{ - return netup_ci_op_cam(en50221, slot, 0, 0, addr, data); -} - -int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr) -{ - return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL, - NETUP_CI_RD, addr, 0); -} - -int netup_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, - u8 addr, u8 data) -{ - return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL, 0, addr, data); -} - -int netup_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot) -{ - struct netup_ci_state *state = en50221->data; - u8 buf = 0x80; - int ret; - - if (0 != slot) - return -EINVAL; - - udelay(500); - ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &buf, 1); - - if (ret != 0) - return ret; - - udelay(500); - - buf = 0x00; - ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &buf, 1); - - msleep(1000); - dvb_ca_en50221_camready_irq(&state->ca, 0); - - return 0; - -} - -int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot) -{ - /* not implemented */ - return 0; -} - -int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot) -{ - struct netup_ci_state *state = en50221->data; - u8 buf = 0x60; - - if (0 != slot) - return -EINVAL; - - return netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &buf, 1); -} - -/* work handler */ -static void netup_read_ci_status(struct work_struct *work) -{ - struct netup_ci_state *state = - container_of(work, struct netup_ci_state, work); - u8 buf[33]; - int ret; - - ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &buf[0], 33); - - if (ret != 0) - return; - - ci_dbg_print("%s: Slot Status Addr=[0x%04x], Reg=[0x%02x], data=%02x, " - "TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0], - buf[32]); - - if (buf[0] && 1) - state->status = DVB_CA_EN50221_POLL_CAM_PRESENT | - DVB_CA_EN50221_POLL_CAM_READY; - else - state->status = 0; -} - -/* CI irq handler */ -int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status) -{ - struct cx23885_tsport *port = NULL; - struct netup_ci_state *state = NULL; - - if (pci_status & PCI_MSK_GPIO0) - port = &dev->ts1; - else if (pci_status & PCI_MSK_GPIO1) - port = &dev->ts2; - else /* who calls ? */ - return 0; - - state = port->port_priv; - - schedule_work(&state->work); - - return 1; -} - -int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open) -{ - struct netup_ci_state *state = en50221->data; - - if (0 != slot) - return -EINVAL; - - return state->status; -} - -int netup_ci_init(struct cx23885_tsport *port) -{ - struct netup_ci_state *state; - u8 cimax_init[34] = { - 0x00, /* module A control*/ - 0x00, /* auto select mask high A */ - 0x00, /* auto select mask low A */ - 0x00, /* auto select pattern high A */ - 0x00, /* auto select pattern low A */ - 0x44, /* memory access time A */ - 0x00, /* invert input A */ - 0x00, /* RFU */ - 0x00, /* RFU */ - 0x00, /* module B control*/ - 0x00, /* auto select mask high B */ - 0x00, /* auto select mask low B */ - 0x00, /* auto select pattern high B */ - 0x00, /* auto select pattern low B */ - 0x44, /* memory access time B */ - 0x00, /* invert input B */ - 0x00, /* RFU */ - 0x00, /* RFU */ - 0x00, /* auto select mask high Ext */ - 0x00, /* auto select mask low Ext */ - 0x00, /* auto select pattern high Ext */ - 0x00, /* auto select pattern low Ext */ - 0x00, /* RFU */ - 0x02, /* destination - module A */ - 0x01, /* power on (use it like store place) */ - 0x00, /* RFU */ - 0x00, /* int status read only */ - 0x01, /* all int unmasked */ - 0x04, /* int config */ - 0x00, /* USCG1 */ - 0x04, /* ack active low */ - 0x00, /* LOCK = 0 */ - 0x33, /* serial mode, rising in, rising out, MSB first*/ - 0x31, /* syncronization */ - }; - int ret; - - ci_dbg_print("%s\n", __func__); - state = kzalloc(sizeof(struct netup_ci_state), GFP_KERNEL); - if (!state) { - ci_dbg_print("%s: Unable create CI structure!\n", __func__); - ret = -ENOMEM; - goto err; - } - - port->port_priv = state; - - switch (port->nr) { - case 1: - state->ci_i2c_addr = 0x40; - mutex_init(&gpio_mutex); - break; - case 2: - state->ci_i2c_addr = 0x41; - break; - } - - state->i2c_adap = &port->dev->i2c_bus[0].i2c_adap; - state->ca.owner = THIS_MODULE; - state->ca.read_attribute_mem = netup_ci_read_attribute_mem; - state->ca.write_attribute_mem = netup_ci_write_attribute_mem; - state->ca.read_cam_control = netup_ci_read_cam_ctl; - state->ca.write_cam_control = netup_ci_write_cam_ctl; - state->ca.slot_reset = netup_ci_slot_reset; - state->ca.slot_shutdown = netup_ci_slot_shutdown; - state->ca.slot_ts_enable = netup_ci_slot_ts_ctl; - state->ca.poll_slot_status = netup_poll_ci_slot_status; - state->ca.data = state; - state->priv = port; - - ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &cimax_init[0], 34); - /* lock registers */ - ret |= netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0x1f, &cimax_init[0x18], 1); - /* power on slots */ - ret |= netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0x18, &cimax_init[0x18], 1); - - if (0 != ret) - goto err; - - ret = dvb_ca_en50221_init(&port->frontends.adapter, - &state->ca, - /* flags */ 0, - /* n_slots */ 1); - if (0 != ret) - goto err; - - INIT_WORK(&state->work, netup_read_ci_status); - - ci_dbg_print("%s: CI initialized!\n", __func__); - - return 0; -err: - ci_dbg_print("%s: Cannot initialize CI: Error %d.\n", __func__, ret); - kfree(state); - return ret; -} - -void netup_ci_exit(struct cx23885_tsport *port) -{ - struct netup_ci_state *state; - - if (NULL == port) - return; - - state = (struct netup_ci_state *)port->port_priv; - if (NULL == state) - return; - - if (NULL == state->ca.data) - return; - - dvb_ca_en50221_release(&state->ca); - kfree(state); -} diff --git a/trunk/drivers/media/video/cx23885/cimax2.h b/trunk/drivers/media/video/cx23885/cimax2.h deleted file mode 100644 index 518744a4c8a5..000000000000 --- a/trunk/drivers/media/video/cx23885/cimax2.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * cimax2.h - * - * CIMax(R) SP2 driver in conjunction with NetUp Dual DVB-S2 CI card - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin - * Copyright (C) 2009 Abylay Ospan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef CIMAX2_H -#define CIMAX2_H -#include "dvb_ca_en50221.h" - -extern int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221, - int slot, int addr); -extern int netup_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221, - int slot, int addr, u8 data); -extern int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, - int slot, u8 addr); -extern int netup_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, - int slot, u8 addr, u8 data); -extern int netup_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot); -extern int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot); -extern int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot); -extern int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status); -extern int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, - int slot, int open); -extern int netup_ci_init(struct cx23885_tsport *port); -extern void netup_ci_exit(struct cx23885_tsport *port); - -#endif diff --git a/trunk/drivers/media/video/cx23885/cx23885-417.c b/trunk/drivers/media/video/cx23885/cx23885-417.c index 6f5df90af93e..bfe25841dbf4 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-417.c +++ b/trunk/drivers/media/video/cx23885/cx23885-417.c @@ -896,7 +896,7 @@ static int cx23885_load_firmware(struct cx23885_dev *dev) if (retval != 0) { printk(KERN_ERR "ERROR: Hotplug firmware request failed (%s).\n", - CX23885_FIRM_IMAGE_NAME); + CX2341X_FIRM_ENC_FILENAME); printk(KERN_ERR "Please fix your hotplug setup, the board will " "not work without firmware loaded!\n"); return -1; @@ -1198,16 +1198,21 @@ static int vidioc_enum_input(struct file *file, void *priv, struct cx23885_fh *fh = file->private_data; struct cx23885_dev *dev = fh->dev; struct cx23885_input *input; - int n; + unsigned int n; - if (i->index >= 4) + n = i->index; + + if (n >= 4) return -EINVAL; - input = &cx23885_boards[dev->board].input[i->index]; + input = &cx23885_boards[dev->board].input[n]; if (input->type == 0) return -EINVAL; + memset(i, 0, sizeof(*i)); + i->index = n; + /* FIXME * strcpy(i->name, input->name); */ strcpy(i->name, "unset"); @@ -1250,8 +1255,10 @@ static int vidioc_g_tuner(struct file *file, void *priv, return -EINVAL; if (0 != t->index) return -EINVAL; + memset(t, 0, sizeof(*t)); strcpy(t->name, "Television"); - call_all(dev, tuner, g_tuner, t); + cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t); + cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t); dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type); @@ -1268,7 +1275,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, return -EINVAL; /* Update the A/V core */ - call_all(dev, tuner, s_tuner, t); + cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t); return 0; } @@ -1279,12 +1286,14 @@ static int vidioc_g_frequency(struct file *file, void *priv, struct cx23885_fh *fh = file->private_data; struct cx23885_dev *dev = fh->dev; + memset(f, 0, sizeof(*f)); if (UNSET == dev->tuner_type) return -EINVAL; f->type = V4L2_TUNER_ANALOG_TV; f->frequency = dev->freq; - call_all(dev, tuner, g_frequency, f); + /* Assumption that tuner is always on bus 1 */ + cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f); return 0; } @@ -1311,7 +1320,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, return -EINVAL; dev->freq = f->frequency; - call_all(dev, tuner, s_frequency, f); + /* Assumption that tuner is always on bus 1 */ + cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f); cx23885_initialize_codec(dev); @@ -1325,7 +1335,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, struct cx23885_dev *dev = fh->dev; /* Update the A/V core */ - call_all(dev, core, s_ctrl, ctl); + cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl); return 0; } @@ -1336,6 +1346,7 @@ static int vidioc_querycap(struct file *file, void *priv, struct cx23885_dev *dev = fh->dev; struct cx23885_tsport *tsport = &dev->ts1; + memset(cap, 0, sizeof(*cap)); strcpy(cap->driver, dev->name); strlcpy(cap->card, cx23885_boards[tsport->dev->board].name, sizeof(cap->card)); @@ -1355,10 +1366,16 @@ static int vidioc_querycap(struct file *file, void *priv, static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { - if (f->index != 0) + int index; + + index = f->index; + if (index != 0) return -EINVAL; + memset(f, 0, sizeof(*f)); + f->index = index; strlcpy(f->description, "MPEG", sizeof(f->description)); + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->pixelformat = V4L2_PIX_FMT_MPEG; return 0; @@ -1370,6 +1387,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct cx23885_fh *fh = file->private_data; struct cx23885_dev *dev = fh->dev; + memset(f, 0, sizeof(*f)); + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; f->fmt.pix.sizeimage = @@ -1389,10 +1408,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct cx23885_fh *fh = file->private_data; struct cx23885_dev *dev = fh->dev; + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; f->fmt.pix.sizeimage = dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; + f->fmt.pix.sizeimage = f->fmt.pix.colorspace = 0; dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", dev->ts1.width, dev->ts1.height, fh->mpegq.field); @@ -1405,6 +1426,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct cx23885_fh *fh = file->private_data; struct cx23885_dev *dev = fh->dev; + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; f->fmt.pix.sizeimage = @@ -1521,7 +1543,12 @@ static int vidioc_log_status(struct file *file, void *priv) printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n", dev->name); - call_all(dev, core, log_status); + cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS, + NULL); + cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS, + NULL); + cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS, + NULL); cx2341x_log_status(&dev->mpeg_params, name); printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n", diff --git a/trunk/drivers/media/video/cx23885/cx23885-cards.c b/trunk/drivers/media/video/cx23885/cx23885-cards.c index 5e4b7e790d94..caa098beeecf 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-cards.c +++ b/trunk/drivers/media/video/cx23885/cx23885-cards.c @@ -27,7 +27,6 @@ #include "cx23885.h" #include "tuner-xc2028.h" -#include "netup-init.h" /* ------------------------------------------------------------------ */ /* board config info */ @@ -163,24 +162,6 @@ struct cx23885_board cx23885_boards[] = { .name = "Compro VideoMate E650F", .portc = CX23885_MPEG_DVB, }, - [CX23885_BOARD_TBS_6920] = { - .name = "TurboSight TBS 6920", - .portb = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_TEVII_S470] = { - .name = "TeVii S470", - .portb = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_DVBWORLD_2005] = { - .name = "DVBWorld DVB-S2 2005", - .portb = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_NETUP_DUAL_DVBS2_CI] = { - .cimax = 1, - .name = "NetUP Dual DVB-S2 CI", - .portb = CX23885_MPEG_DVB, - .portc = CX23885_MPEG_DVB, - }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -264,22 +245,6 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x185b, .subdevice = 0xe800, .card = CX23885_BOARD_COMPRO_VIDEOMATE_E650F, - }, { - .subvendor = 0x6920, - .subdevice = 0x8888, - .card = CX23885_BOARD_TBS_6920, - }, { - .subvendor = 0xd470, - .subdevice = 0x9022, - .card = CX23885_BOARD_TEVII_S470, - }, { - .subvendor = 0x0001, - .subdevice = 0x2005, - .card = CX23885_BOARD_DVBWORLD_2005, - }, { - .subvendor = 0x1b55, - .subdevice = 0x2a2c, - .card = CX23885_BOARD_NETUP_DUAL_DVBS2_CI, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -587,38 +552,6 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) mdelay(20); cx_set(GP0_IO, 0x00040004); break; - case CX23885_BOARD_TBS_6920: - case CX23885_BOARD_TEVII_S470: - cx_write(MC417_CTL, 0x00000036); - cx_write(MC417_OEN, 0x00001000); - cx_write(MC417_RWD, 0x00001800); - break; - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: - /* GPIO-0 INTA from CiMax1 - GPIO-1 INTB from CiMax2 - GPIO-2 reset chips - GPIO-3 to GPIO-10 data/addr for CA - GPIO-11 ~CS0 to CiMax1 - GPIO-12 ~CS1 to CiMax2 - GPIO-13 ADL0 load LSB addr - GPIO-14 ADL1 load MSB addr - GPIO-15 ~RDY from CiMax - GPIO-17 ~RD to CiMax - GPIO-18 ~WR to CiMax - */ - cx_set(GP0_IO, 0x00040000); /* GPIO as out */ - /* GPIO1 and GPIO2 as INTA and INTB from CiMaxes, reset low */ - cx_clear(GP0_IO, 0x00030004); - mdelay(100);/* reset delay */ - cx_set(GP0_IO, 0x00040004); /* GPIO as out, reset high */ - cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */ - /* GPIO-15 IN as ~ACK, rest as OUT */ - cx_write(MC417_OEN, 0x00001000); - /* ~RD, ~WR high; ADL0, ADL1 low; ~CS0, ~CS1 high */ - cx_write(MC417_RWD, 0x0000c300); - /* enable irq */ - cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ - break; } } @@ -699,21 +632,6 @@ void cx23885_card_setup(struct cx23885_dev *dev) ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; - case CX23885_BOARD_TEVII_S470: - case CX23885_BOARD_TBS_6920: - case CX23885_BOARD_DVBWORLD_2005: - ts1->gen_ctrl_val = 0x5; /* Parallel */ - ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - break; - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: - ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - break; case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_HAUPPAUGE_HVR1500Q: @@ -738,17 +656,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1700: case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: - dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->i2c_bus[2].i2c_adap, - "cx25840", "cx25840", 0x88 >> 1); - v4l2_subdev_call(dev->sd_cx25840, core, init, 0); - break; - } - - /* AUX-PLL 27MHz CLK */ - switch (dev->board) { - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: - netup_initialize(dev); + request_module("cx25840"); break; } } diff --git a/trunk/drivers/media/video/cx23885/cx23885-core.c b/trunk/drivers/media/video/cx23885/cx23885-core.c index dc7fff22cfdd..8f6fb2add7de 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-core.c +++ b/trunk/drivers/media/video/cx23885/cx23885-core.c @@ -31,7 +31,6 @@ #include #include "cx23885.h" -#include "cimax2.h" MODULE_DESCRIPTION("Driver for cx23885 based TV cards"); MODULE_AUTHOR("Steven Toth "); @@ -792,8 +791,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) dev->pci_bus = dev->pci->bus->number; dev->pci_slot = PCI_SLOT(dev->pci->devfn); dev->pci_irqmask = 0x001f00; - if (cx23885_boards[dev->board].cimax > 0) - dev->pci_irqmask |= 0x01800000; /* for CiMaxes */ /* External Master 1 Bus */ dev->i2c_bus[0].nr = 0; @@ -875,7 +872,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) cx23885_i2c_register(&dev->i2c_bus[1]); cx23885_i2c_register(&dev->i2c_bus[2]); cx23885_card_setup(dev); - call_all(dev, core, s_standby, 0); + cx23885_call_i2c_clients(&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); cx23885_ir_init(dev); if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { @@ -1646,9 +1643,7 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) (pci_status & PCI_MSK_VID_B) || (pci_status & PCI_MSK_VID_A) || (pci_status & PCI_MSK_AUD_INT) || - (pci_status & PCI_MSK_AUD_EXT) || - (pci_status & PCI_MSK_GPIO0) || - (pci_status & PCI_MSK_GPIO1)) { + (pci_status & PCI_MSK_AUD_EXT)) { if (pci_status & PCI_MSK_RISC_RD) dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n", @@ -1690,20 +1685,8 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n", PCI_MSK_AUD_EXT); - if (pci_status & PCI_MSK_GPIO0) - dprintk(7, " (PCI_MSK_GPIO0 0x%08x)\n", - PCI_MSK_GPIO0); - - if (pci_status & PCI_MSK_GPIO1) - dprintk(7, " (PCI_MSK_GPIO1 0x%08x)\n", - PCI_MSK_GPIO1); } - if (cx23885_boards[dev->board].cimax > 0 && - ((pci_status & PCI_MSK_GPIO0) || (pci_status & PCI_MSK_GPIO1))) - /* handled += cx23885_irq_gpio(dev, pci_status); */ - handled += netup_ci_slot_status(dev, pci_status); - if (ts1_status) { if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) handled += cx23885_irq_ts(ts1, ts1_status); @@ -1739,20 +1722,16 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev, if (NULL == dev) return -ENOMEM; - err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev); - if (err < 0) - goto fail_free; - /* pci init */ dev->pci = pci_dev; if (pci_enable_device(pci_dev)) { err = -EIO; - goto fail_unreg; + goto fail_free; } if (cx23885_dev_setup(dev) < 0) { err = -EINVAL; - goto fail_unreg; + goto fail_free; } /* print pci info */ @@ -1779,18 +1758,11 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev, goto fail_irq; } - switch (dev->board) { - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: - cx_set(PCI_INT_MSK, 0x01800000); /* for NetUP */ - break; - } - + pci_set_drvdata(pci_dev, dev); return 0; fail_irq: cx23885_dev_unregister(dev); -fail_unreg: - v4l2_device_unregister(&dev->v4l2_dev); fail_free: kfree(dev); return err; @@ -1798,8 +1770,7 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev, static void __devexit cx23885_finidev(struct pci_dev *pci_dev) { - struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); - struct cx23885_dev *dev = to_cx23885(v4l2_dev); + struct cx23885_dev *dev = pci_get_drvdata(pci_dev); cx23885_shutdown(dev); @@ -1807,13 +1778,13 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev) /* unregister stuff */ free_irq(pci_dev->irq, dev); + pci_set_drvdata(pci_dev, NULL); mutex_lock(&devlist); list_del(&dev->devlist); mutex_unlock(&devlist); cx23885_dev_unregister(dev); - v4l2_device_unregister(v4l2_dev); kfree(dev); } diff --git a/trunk/drivers/media/video/cx23885/cx23885-dvb.c b/trunk/drivers/media/video/cx23885/cx23885-dvb.c index d43c74396767..1c454128a9df 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-dvb.c +++ b/trunk/drivers/media/video/cx23885/cx23885-dvb.c @@ -30,7 +30,6 @@ #include "cx23885.h" #include -#include "dvb_ca_en50221.h" #include "s5h1409.h" #include "s5h1411.h" #include "mt2131.h" @@ -44,13 +43,6 @@ #include "dib7000p.h" #include "dibx000_common.h" #include "zl10353.h" -#include "stv0900.h" -#include "stv6110.h" -#include "lnbh24.h" -#include "cx24116.h" -#include "cimax2.h" -#include "netup-eeprom.h" -#include "netup-init.h" static unsigned int debug; @@ -316,63 +308,11 @@ static struct zl10353_config dvico_fusionhdtv_xc3028 = { .no_tuner = 1, }; -static struct stv0900_config netup_stv0900_config = { - .demod_address = 0x68, - .xtal = 27000000, - .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ - .diseqc_mode = 2,/* 2/3 PWM */ - .path1_mode = 2,/*Serial continues clock */ - .path2_mode = 2,/*Serial continues clock */ - .tun1_maddress = 0,/* 0x60 */ - .tun2_maddress = 3,/* 0x63 */ - .tun1_adc = 1,/* 1 Vpp */ - .tun2_adc = 1,/* 1 Vpp */ -}; - -static struct stv6110_config netup_stv6110_tunerconfig_a = { - .i2c_address = 0x60, - .mclk = 27000000, - .iq_wiring = 0, -}; - -static struct stv6110_config netup_stv6110_tunerconfig_b = { - .i2c_address = 0x63, - .mclk = 27000000, - .iq_wiring = 1, -}; - -static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct cx23885_tsport *port = fe->dvb->priv; - struct cx23885_dev *dev = port->dev; - - if (voltage == SEC_VOLTAGE_18) - cx_write(MC417_RWD, 0x00001e00);/* GPIO-13 high */ - else if (voltage == SEC_VOLTAGE_13) - cx_write(MC417_RWD, 0x00001a00);/* GPIO-13 low */ - else - cx_write(MC417_RWD, 0x00001800);/* GPIO-12 low */ - return 0; -} - -static struct cx24116_config tbs_cx24116_config = { - .demod_address = 0x05, -}; - -static struct cx24116_config tevii_cx24116_config = { - .demod_address = 0x55, -}; - -static struct cx24116_config dvbworld_cx24116_config = { - .demod_address = 0x05, -}; - static int dvb_register(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; struct cx23885_i2c *i2c_bus = NULL; struct videobuf_dvb_frontend *fe0; - int ret; /* Get the first frontend */ fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); @@ -586,78 +526,6 @@ static int dvb_register(struct cx23885_tsport *port) fe->ops.tuner_ops.set_config(fe, &ctl); } break; - case CX23885_BOARD_TBS_6920: - i2c_bus = &dev->i2c_bus[0]; - - fe0->dvb.frontend = dvb_attach(cx24116_attach, - &tbs_cx24116_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage; - - break; - case CX23885_BOARD_TEVII_S470: - i2c_bus = &dev->i2c_bus[1]; - - fe0->dvb.frontend = dvb_attach(cx24116_attach, - &tevii_cx24116_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage; - - break; - case CX23885_BOARD_DVBWORLD_2005: - i2c_bus = &dev->i2c_bus[1]; - - fe0->dvb.frontend = dvb_attach(cx24116_attach, - &dvbworld_cx24116_config, - &i2c_bus->i2c_adap); - break; - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: - i2c_bus = &dev->i2c_bus[0]; - switch (port->nr) { - /* port B */ - case 1: - fe0->dvb.frontend = dvb_attach(stv0900_attach, - &netup_stv0900_config, - &i2c_bus->i2c_adap, 0); - if (fe0->dvb.frontend != NULL) { - if (dvb_attach(stv6110_attach, - fe0->dvb.frontend, - &netup_stv6110_tunerconfig_a, - &i2c_bus->i2c_adap)) { - if (!dvb_attach(lnbh24_attach, - fe0->dvb.frontend, - &i2c_bus->i2c_adap, - LNBH24_PCL, 0, 0x09)) - printk(KERN_ERR - "No LNBH24 found!\n"); - - } - } - break; - /* port C */ - case 2: - fe0->dvb.frontend = dvb_attach(stv0900_attach, - &netup_stv0900_config, - &i2c_bus->i2c_adap, 1); - if (fe0->dvb.frontend != NULL) { - if (dvb_attach(stv6110_attach, - fe0->dvb.frontend, - &netup_stv6110_tunerconfig_b, - &i2c_bus->i2c_adap)) { - if (!dvb_attach(lnbh24_attach, - fe0->dvb.frontend, - &i2c_bus->i2c_adap, - LNBH24_PCL, 0, 0x0a)) - printk(KERN_ERR - "No LNBH24 found!\n"); - - } - } - break; - } - break; default: printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " " isn't supported yet\n", @@ -673,39 +541,15 @@ static int dvb_register(struct cx23885_tsport *port) fe0->dvb.frontend->callback = cx23885_tuner_callback; /* Put the analog decoder in standby to keep it quiet */ - call_all(dev, core, s_standby, 0); + cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); if (fe0->dvb.frontend->ops.analog_ops.standby) fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); /* register everything */ - ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, + return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, &dev->pci->dev, adapter_nr, 0); - /* init CI & MAC */ - switch (dev->board) { - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: { - static struct netup_card_info cinfo; - - netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo); - memcpy(port->frontends.adapter.proposed_mac, - cinfo.port[port->nr - 1].mac, 6); - printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=" - "%02X:%02X:%02X:%02X:%02X:%02X\n", - port->nr, - port->frontends.adapter.proposed_mac[0], - port->frontends.adapter.proposed_mac[1], - port->frontends.adapter.proposed_mac[2], - port->frontends.adapter.proposed_mac[3], - port->frontends.adapter.proposed_mac[4], - port->frontends.adapter.proposed_mac[5]); - - netup_ci_init(port); - break; - } - } - - return ret; } int cx23885_dvb_register(struct cx23885_tsport *port) @@ -778,12 +622,6 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port) if (fe0->dvb.frontend) videobuf_dvb_unregister_bus(&port->frontends); - switch (port->dev->board) { - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: - netup_ci_exit(port); - break; - } - return 0; } diff --git a/trunk/drivers/media/video/cx23885/cx23885-i2c.c b/trunk/drivers/media/video/cx23885/cx23885-i2c.c index 3421bd12056a..bb7f71a1fcbe 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-i2c.c +++ b/trunk/drivers/media/video/cx23885/cx23885-i2c.c @@ -268,6 +268,64 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap, return retval; } +static int attach_inform(struct i2c_client *client) +{ + struct cx23885_i2c *bus = i2c_get_adapdata(client->adapter); + struct cx23885_dev *dev = bus->dev; + struct tuner_setup tun_setup; + + dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", + client->driver->driver.name, client->addr, client->name); + + if (!client->driver->command) + return 0; + + if (dev->tuner_type != UNSET) { + + dprintk(1, "%s (tuner) i2c attach [addr=0x%x,client=%s]\n", + client->driver->driver.name, client->addr, + client->name); + + if ((dev->tuner_addr == ADDR_UNSET) || + (dev->tuner_addr == client->addr)) { + + dprintk(1, "%s (tuner || addr UNSET)\n", + client->driver->driver.name); + + dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", + client->driver->driver.name, + client->addr, client->name); + + tun_setup.mode_mask = T_ANALOG_TV; + tun_setup.type = dev->tuner_type; + tun_setup.addr = dev->tuner_addr; + + client->driver->command(client, TUNER_SET_TYPE_ADDR, + &tun_setup); + } + } + + return 0; +} + +static int detach_inform(struct i2c_client *client) +{ + struct cx23885_dev *dev = i2c_get_adapdata(client->adapter); + + dprintk(1, "i2c detach [client=%s]\n", client->name); + + return 0; +} + +void cx23885_call_i2c_clients(struct cx23885_i2c *bus, + unsigned int cmd, void *arg) +{ + if (bus->i2c_rc != 0) + return; + + i2c_clients_command(&bus->i2c_adap, cmd, arg); +} + static u32 cx23885_functionality(struct i2c_adapter *adap) { return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; @@ -285,6 +343,9 @@ static struct i2c_adapter cx23885_i2c_adap_template = { .owner = THIS_MODULE, .id = I2C_HW_B_CX23885, .algo = &cx23885_i2c_algo_template, + .class = I2C_CLASS_TV_ANALOG, + .client_register = attach_inform, + .client_unregister = detach_inform, }; static struct i2c_client cx23885_i2c_client_template = { @@ -341,18 +402,15 @@ int cx23885_i2c_register(struct cx23885_i2c *bus) bus->i2c_algo.data = bus; bus->i2c_adap.algo_data = bus; - i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev); + i2c_set_adapdata(&bus->i2c_adap, bus); i2c_add_adapter(&bus->i2c_adap); bus->i2c_client.adapter = &bus->i2c_adap; if (0 == bus->i2c_rc) { dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr); - if (i2c_scan) { - printk(KERN_INFO "%s: scan bus %d:\n", - dev->name, bus->nr); + if (i2c_scan) do_i2c_scan(dev->name, &bus->i2c_client); - } } else printk(KERN_WARNING "%s: i2c bus %d register FAILED\n", dev->name, bus->nr); diff --git a/trunk/drivers/media/video/cx23885/cx23885-reg.h b/trunk/drivers/media/video/cx23885/cx23885-reg.h index eafbe5226bae..20b68a236260 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-reg.h +++ b/trunk/drivers/media/video/cx23885/cx23885-reg.h @@ -212,8 +212,6 @@ Channel manager Data Structure entry = 20 DWORD #define DEV_CNTRL2 0x00040000 -#define PCI_MSK_GPIO1 (1 << 24) -#define PCI_MSK_GPIO0 (1 << 23) #define PCI_MSK_APB_DMA (1 << 12) #define PCI_MSK_AL_WR (1 << 11) #define PCI_MSK_AL_RD (1 << 10) diff --git a/trunk/drivers/media/video/cx23885/cx23885-video.c b/trunk/drivers/media/video/cx23885/cx23885-video.c index f0ac62c5dc83..eaa11893bfe9 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-video.c +++ b/trunk/drivers/media/video/cx23885/cx23885-video.c @@ -35,6 +35,11 @@ #include #include +#ifdef CONFIG_VIDEO_V4L1_COMPAT +/* Include V4L1 specific functions. Should be removed soon */ +#include +#endif + MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); MODULE_AUTHOR("Steven Toth "); MODULE_LICENSE("GPL"); @@ -239,7 +244,6 @@ static struct cx23885_ctrl cx23885_ctls[] = { }; static const int CX23885_CTLS = ARRAY_SIZE(cx23885_ctls); -/* Must be sorted from low to high control ID! */ static const u32 cx23885_user_ctrls[] = { V4L2_CID_USER_CLASS, V4L2_CID_BRIGHTNESS, @@ -299,7 +303,11 @@ static int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) dev->tvnorm = norm; - call_all(dev, tuner, s_std, norm); + /* Tell the analog tuner/demods */ + cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_STD, &norm); + + /* Tell the internal A/V decoder */ + cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_STD, &norm); return 0; } @@ -316,8 +324,8 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, if (NULL == vfd) return NULL; *vfd = *template; - vfd->minor = -1; - vfd->v4l2_dev = &dev->v4l2_dev; + vfd->minor = -1; + vfd->parent = &pci->dev; vfd->release = video_device_release; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, cx23885_boards[dev->board].name); @@ -406,7 +414,8 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) route.input = INPUT(input)->vmux; /* Tell the internal A/V decoder */ - v4l2_subdev_call(dev->sd_cx25840, video, s_routing, &route); + cx23885_call_i2c_clients(&dev->i2c_bus[2], + VIDIOC_INT_S_VIDEO_ROUTING, &route); return 0; } @@ -882,7 +891,7 @@ static int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl) { dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__); - call_all(dev, core, g_ctrl, ctl); + cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl); return 0; } @@ -996,7 +1005,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, fh->vidq.field = f->fmt.pix.field; dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field); - call_all(dev, video, s_fmt, f); + cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_FMT, f); return 0; } @@ -1276,7 +1285,7 @@ static int vidioc_g_frequency(struct file *file, void *priv, f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; f->frequency = dev->freq; - call_all(dev, tuner, g_frequency, f); + cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f); return 0; } @@ -1291,7 +1300,7 @@ static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f) mutex_lock(&dev->lock); dev->freq = f->frequency; - call_all(dev, tuner, s_frequency, f); + cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f); /* When changing channels it is required to reset TVAUDIO */ msleep(10); @@ -1325,7 +1334,7 @@ static int vidioc_g_register(struct file *file, void *fh, if (!v4l2_chip_match_host(®->match)) return -EINVAL; - call_all(dev, core, g_register, reg); + cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_G_REGISTER, reg); return 0; } @@ -1338,7 +1347,7 @@ static int vidioc_s_register(struct file *file, void *fh, if (!v4l2_chip_match_host(®->match)) return -EINVAL; - call_all(dev, core, s_register, reg); + cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_S_REGISTER, reg); return 0; } @@ -1519,26 +1528,6 @@ int cx23885_video_register(struct cx23885_dev *dev) /* Don't enable VBI yet */ cx_set(PCI_INT_MSK, 1); - if (TUNER_ABSENT != dev->tuner_type) { - struct v4l2_subdev *sd = NULL; - - if (dev->tuner_addr) - sd = v4l2_i2c_new_subdev(&dev->i2c_bus[1].i2c_adap, - "tuner", "tuner", dev->tuner_addr); - else - sd = v4l2_i2c_new_probed_subdev(&dev->i2c_bus[1].i2c_adap, - "tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV)); - if (sd) { - struct tuner_setup tun_setup; - - tun_setup.mode_mask = T_ANALOG_TV; - tun_setup.type = dev->tuner_type; - tun_setup.addr = v4l2_i2c_subdev_addr(sd); - - v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup); - } - } - /* register v4l devices */ dev->video_dev = cx23885_vdev_init(dev, dev->pci, diff --git a/trunk/drivers/media/video/cx23885/cx23885.h b/trunk/drivers/media/video/cx23885/cx23885.h index 02d980a29962..67828029fc69 100644 --- a/trunk/drivers/media/video/cx23885/cx23885.h +++ b/trunk/drivers/media/video/cx23885/cx23885.h @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include @@ -67,10 +67,6 @@ #define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP 11 #define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H 12 #define CX23885_BOARD_COMPRO_VIDEOMATE_E650F 13 -#define CX23885_BOARD_TBS_6920 14 -#define CX23885_BOARD_TEVII_S470 15 -#define CX23885_BOARD_DVBWORLD_2005 16 -#define CX23885_BOARD_NETUP_DUAL_DVBS2_CI 17 /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ #define CX23885_NORMS (\ @@ -188,7 +184,6 @@ struct cx23885_board { */ u32 clk_freq; struct cx23885_input input[MAX_CX23885_INPUT]; - int cimax; /* for NetUP */ }; struct cx23885_subid { @@ -271,13 +266,11 @@ struct cx23885_tsport { /* Allow a single tsport to have multiple frontends */ u32 num_frontends; - void *port_priv; }; struct cx23885_dev { struct list_head devlist; atomic_t refcount; - struct v4l2_device v4l2_dev; /* pci stuff */ struct pci_dev *pci; @@ -323,7 +316,6 @@ struct cx23885_dev { unsigned int radio_type; unsigned char radio_addr; unsigned int has_radio; - struct v4l2_subdev *sd_cx25840; /* V4l */ u32 freq; @@ -344,14 +336,6 @@ struct cx23885_dev { }; -static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev) -{ - return container_of(v4l2_dev, struct cx23885_dev, v4l2_dev); -} - -#define call_all(dev, o, f, args...) \ - v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args) - extern struct list_head cx23885_devlist; #define SRAM_CH01 0 /* Video A */ @@ -468,6 +452,8 @@ extern struct videobuf_queue_ops cx23885_vbi_qops; /* cx23885-i2c.c */ extern int cx23885_i2c_register(struct cx23885_i2c *bus); extern int cx23885_i2c_unregister(struct cx23885_i2c *bus); +extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd, + void *arg); extern void cx23885_av_clk(struct cx23885_dev *dev, int enable); /* ----------------------------------------------------------- */ diff --git a/trunk/drivers/media/video/cx23885/netup-eeprom.c b/trunk/drivers/media/video/cx23885/netup-eeprom.c deleted file mode 100644 index 042bbbbd48f8..000000000000 --- a/trunk/drivers/media/video/cx23885/netup-eeprom.c +++ /dev/null @@ -1,107 +0,0 @@ - -/* - * netup-eeprom.c - * - * 24LC02 EEPROM driver in conjunction with NetUP Dual DVB-S2 CI card - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Abylay Ospan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -# -#include "cx23885.h" -#include "netup-eeprom.h" - -#define EEPROM_I2C_ADDR 0x50 - -int netup_eeprom_read(struct i2c_adapter *i2c_adap, u8 addr) -{ - int ret; - unsigned char buf[2]; - - /* Read from EEPROM */ - struct i2c_msg msg[] = { - { - .addr = EEPROM_I2C_ADDR, - .flags = 0, - .buf = &buf[0], - .len = 1 - }, { - .addr = EEPROM_I2C_ADDR, - .flags = I2C_M_RD, - .buf = &buf[1], - .len = 1 - } - - }; - - buf[0] = addr; - buf[1] = 0x0; - - ret = i2c_transfer(i2c_adap, msg, 2); - - if (ret != 2) { - printk(KERN_ERR "eeprom i2c read error, status=%d\n", ret); - return -1; - } - - return buf[1]; -}; - -int netup_eeprom_write(struct i2c_adapter *i2c_adap, u8 addr, u8 data) -{ - int ret; - unsigned char bufw[2]; - - /* Write into EEPROM */ - struct i2c_msg msg[] = { - { - .addr = EEPROM_I2C_ADDR, - .flags = 0, - .buf = &bufw[0], - .len = 2 - } - }; - - bufw[0] = addr; - bufw[1] = data; - - ret = i2c_transfer(i2c_adap, msg, 1); - - if (ret != 1) { - printk(KERN_ERR "eeprom i2c write error, status=%d\n", ret); - return -1; - } - - mdelay(10); /* prophylactic delay, datasheet write cycle time = 5 ms */ - return 0; -}; - -void netup_get_card_info(struct i2c_adapter *i2c_adap, - struct netup_card_info *cinfo) -{ - int i, j; - - cinfo->rev = netup_eeprom_read(i2c_adap, 13); - - for (i = 0, j = 0; i < 6; i++, j++) - cinfo->port[0].mac[j] = netup_eeprom_read(i2c_adap, i); - - for (i = 6, j = 0; i < 12; i++, j++) - cinfo->port[1].mac[j] = netup_eeprom_read(i2c_adap, i); -}; diff --git a/trunk/drivers/media/video/cx23885/netup-eeprom.h b/trunk/drivers/media/video/cx23885/netup-eeprom.h deleted file mode 100644 index 13926e18feba..000000000000 --- a/trunk/drivers/media/video/cx23885/netup-eeprom.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * netup-eeprom.h - * - * 24LC02 EEPROM driver in conjunction with NetUP Dual DVB-S2 CI card - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Abylay Ospan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef NETUP_EEPROM_H -#define NETUP_EEPROM_H - -struct netup_port_info { - u8 mac[6];/* card MAC address */ -}; - -struct netup_card_info { - struct netup_port_info port[2];/* ports - 1,2 */ - u8 rev;/* card revision */ -}; - -extern int netup_eeprom_read(struct i2c_adapter *i2c_adap, u8 addr); -extern int netup_eeprom_write(struct i2c_adapter *i2c_adap, u8 addr, u8 data); -extern void netup_get_card_info(struct i2c_adapter *i2c_adap, - struct netup_card_info *cinfo); - -#endif diff --git a/trunk/drivers/media/video/cx23885/netup-init.c b/trunk/drivers/media/video/cx23885/netup-init.c deleted file mode 100644 index f4893e69cd89..000000000000 --- a/trunk/drivers/media/video/cx23885/netup-init.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * netup-init.c - * - * NetUP Dual DVB-S2 CI driver - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin - * Copyright (C) 2009 Abylay Ospan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "cx23885.h" - -static void i2c_av_write(struct i2c_adapter *i2c, u16 reg, u8 val) -{ - int ret; - u8 buf[3]; - struct i2c_msg msg = { - .addr = 0x88 >> 1, - .flags = 0, - .buf = buf, - .len = 3 - }; - - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - buf[2] = val; - - ret = i2c_transfer(i2c, &msg, 1); - - if (ret != 1) - printk(KERN_ERR "%s: i2c write error!\n", __func__); -} - -static void i2c_av_write4(struct i2c_adapter *i2c, u16 reg, u32 val) -{ - int ret; - u8 buf[6]; - struct i2c_msg msg = { - .addr = 0x88 >> 1, - .flags = 0, - .buf = buf, - .len = 6 - }; - - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - buf[2] = val & 0xff; - buf[3] = (val >> 8) & 0xff; - buf[4] = (val >> 16) & 0xff; - buf[5] = val >> 24; - - ret = i2c_transfer(i2c, &msg, 1); - - if (ret != 1) - printk(KERN_ERR "%s: i2c write error!\n", __func__); -} - -static u8 i2c_av_read(struct i2c_adapter *i2c, u16 reg) -{ - int ret; - u8 buf[2]; - struct i2c_msg msg = { - .addr = 0x88 >> 1, - .flags = 0, - .buf = buf, - .len = 2 - }; - - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - - ret = i2c_transfer(i2c, &msg, 1); - - if (ret != 1) - printk(KERN_ERR "%s: i2c write error!\n", __func__); - - msg.flags = I2C_M_RD; - msg.len = 1; - - ret = i2c_transfer(i2c, &msg, 1); - - if (ret != 1) - printk(KERN_ERR "%s: i2c read error!\n", __func__); - - return buf[0]; -} - -static void i2c_av_and_or(struct i2c_adapter *i2c, u16 reg, unsigned and_mask, - u8 or_value) -{ - i2c_av_write(i2c, reg, (i2c_av_read(i2c, reg) & and_mask) | or_value); -} -/* set 27MHz on AUX_CLK */ -void netup_initialize(struct cx23885_dev *dev) -{ - struct cx23885_i2c *i2c_bus = &dev->i2c_bus[2]; - struct i2c_adapter *i2c = &i2c_bus->i2c_adap; - - /* Stop microcontroller */ - i2c_av_and_or(i2c, 0x803, ~0x10, 0x00); - - /* Aux PLL frac for 27 MHz */ - i2c_av_write4(i2c, 0x114, 0xea0eb3); - - /* Aux PLL int for 27 MHz */ - i2c_av_write4(i2c, 0x110, 0x090319); - - /* start microcontroller */ - i2c_av_and_or(i2c, 0x803, ~0x10, 0x10); -} diff --git a/trunk/drivers/media/video/cx23885/netup-init.h b/trunk/drivers/media/video/cx23885/netup-init.h deleted file mode 100644 index d26ae4b1590e..000000000000 --- a/trunk/drivers/media/video/cx23885/netup-init.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * netup-init.h - * - * NetUP Dual DVB-S2 CI driver - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin - * Copyright (C) 2009 Abylay Ospan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -extern void netup_initialize(struct cx23885_dev *dev); diff --git a/trunk/drivers/media/video/cx25840/cx25840-audio.c b/trunk/drivers/media/video/cx25840/cx25840-audio.c index 93d74bee292a..d199d80ea0a3 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-audio.c +++ b/trunk/drivers/media/video/cx25840/cx25840-audio.c @@ -363,74 +363,75 @@ static void set_mute(struct i2c_client *client, int mute) } } -int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq) +int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct cx25840_state *state = to_state(sd); + struct cx25840_state *state = to_state(i2c_get_clientdata(client)); + struct v4l2_control *ctrl = arg; int retval; - if (!state->is_cx25836) - cx25840_and_or(client, 0x810, ~0x1, 1); - if (state->aud_input != CX25840_AUDIO_SERIAL) { - cx25840_and_or(client, 0x803, ~0x10, 0); - cx25840_write(client, 0x8d3, 0x1f); - } - retval = set_audclk_freq(client, freq); - if (state->aud_input != CX25840_AUDIO_SERIAL) - cx25840_and_or(client, 0x803, ~0x10, 0x10); - if (!state->is_cx25836) - cx25840_and_or(client, 0x810, ~0x1, 0); - return retval; -} - -int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - ctrl->value = get_volume(client); - break; - case V4L2_CID_AUDIO_BASS: - ctrl->value = get_bass(client); - break; - case V4L2_CID_AUDIO_TREBLE: - ctrl->value = get_treble(client); - break; - case V4L2_CID_AUDIO_BALANCE: - ctrl->value = get_balance(client); - break; - case V4L2_CID_AUDIO_MUTE: - ctrl->value = get_mute(client); + switch (cmd) { + case VIDIOC_INT_AUDIO_CLOCK_FREQ: + if (!state->is_cx25836) + cx25840_and_or(client, 0x810, ~0x1, 1); + if (state->aud_input != CX25840_AUDIO_SERIAL) { + cx25840_and_or(client, 0x803, ~0x10, 0); + cx25840_write(client, 0x8d3, 0x1f); + } + retval = set_audclk_freq(client, *(u32 *)arg); + if (state->aud_input != CX25840_AUDIO_SERIAL) { + cx25840_and_or(client, 0x803, ~0x10, 0x10); + } + if (!state->is_cx25836) + cx25840_and_or(client, 0x810, ~0x1, 0); + return retval; + + case VIDIOC_G_CTRL: + switch (ctrl->id) { + case V4L2_CID_AUDIO_VOLUME: + ctrl->value = get_volume(client); + break; + case V4L2_CID_AUDIO_BASS: + ctrl->value = get_bass(client); + break; + case V4L2_CID_AUDIO_TREBLE: + ctrl->value = get_treble(client); + break; + case V4L2_CID_AUDIO_BALANCE: + ctrl->value = get_balance(client); + break; + case V4L2_CID_AUDIO_MUTE: + ctrl->value = get_mute(client); + break; + default: + return -EINVAL; + } break; - default: - return -EINVAL; - } - return 0; -} -int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - set_volume(client, ctrl->value); - break; - case V4L2_CID_AUDIO_BASS: - set_bass(client, ctrl->value); - break; - case V4L2_CID_AUDIO_TREBLE: - set_treble(client, ctrl->value); - break; - case V4L2_CID_AUDIO_BALANCE: - set_balance(client, ctrl->value); - break; - case V4L2_CID_AUDIO_MUTE: - set_mute(client, ctrl->value); + case VIDIOC_S_CTRL: + switch (ctrl->id) { + case V4L2_CID_AUDIO_VOLUME: + set_volume(client, ctrl->value); + break; + case V4L2_CID_AUDIO_BASS: + set_bass(client, ctrl->value); + break; + case V4L2_CID_AUDIO_TREBLE: + set_treble(client, ctrl->value); + break; + case V4L2_CID_AUDIO_BALANCE: + set_balance(client, ctrl->value); + break; + case V4L2_CID_AUDIO_MUTE: + set_mute(client, ctrl->value); + break; + default: + return -EINVAL; + } break; + default: return -EINVAL; } + return 0; } diff --git a/trunk/drivers/media/video/cx25840/cx25840-core.c b/trunk/drivers/media/video/cx25840/cx25840-core.c index 737ee4ea8830..25eb3bec9e5d 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-core.c +++ b/trunk/drivers/media/video/cx25840/cx25840-core.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include "cx25840-core.h" @@ -48,12 +48,15 @@ MODULE_DESCRIPTION("Conexant CX25840 audio/video decoder driver"); MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford"); MODULE_LICENSE("GPL"); +static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; + static int cx25840_debug; module_param_named(debug,cx25840_debug, int, 0644); MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]"); +I2C_CLIENT_INSMOD; /* ----------------------------------------------------------------------- */ @@ -760,7 +763,7 @@ static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) break; case V4L2_CID_HUE: - if (ctrl->value < -128 || ctrl->value > 127) { + if (ctrl->value < -127 || ctrl->value > 127) { v4l_err(client, "invalid hue setting %d\n", ctrl->value); return -ERANGE; } @@ -775,7 +778,7 @@ static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_MUTE: if (state->is_cx25836) return -EINVAL; - return cx25840_audio_s_ctrl(sd, ctrl); + return cx25840_audio(client, VIDIOC_S_CTRL, ctrl); default: return -EINVAL; @@ -812,7 +815,7 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_MUTE: if (state->is_cx25836) return -EINVAL; - return cx25840_audio_g_ctrl(sd, ctrl); + return cx25840_audio(client, VIDIOC_G_CTRL, ctrl); default: return -EINVAL; } @@ -824,9 +827,11 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) { + struct i2c_client *client = v4l2_get_subdevdata(sd); + switch (fmt->type) { case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - return cx25840_vbi_g_fmt(sd, fmt); + return cx25840_vbi(client, VIDIOC_G_FMT, fmt); default: return -EINVAL; } @@ -888,10 +893,10 @@ static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - return cx25840_vbi_s_fmt(sd, fmt); + return cx25840_vbi(client, VIDIOC_S_FMT, fmt); case V4L2_BUF_TYPE_VBI_CAPTURE: - return cx25840_vbi_s_fmt(sd, fmt); + return cx25840_vbi(client, VIDIOC_S_FMT, fmt); default: return -EINVAL; @@ -1096,16 +1101,6 @@ static void log_audio_status(struct i2c_client *client) /* ----------------------------------------------------------------------- */ -/* This init operation must be called to load the driver's firmware. - Without this the audio standard detection will fail and you will - only get mono. - - Since loading the firmware is often problematic when the driver is - compiled into the kernel I recommend postponing calling this function - until the first open of the video device. Another reason for - postponing it is that loading this firmware takes a long time (seconds) - due to the slow i2c bus speed. So it will speed up the boot process if - you can avoid loading the fw as long as the video device isn't used. */ static int cx25840_init(struct v4l2_subdev *sd, u32 val) { struct cx25840_state *state = to_state(sd); @@ -1151,6 +1146,20 @@ static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register * } #endif +static int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + return cx25840_vbi(client, VIDIOC_INT_DECODE_VBI_LINE, vbi); +} + +static int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + return cx25840_audio(client, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freq); +} + static int cx25840_s_stream(struct v4l2_subdev *sd, int enable) { struct cx25840_state *state = to_state(sd); @@ -1186,12 +1195,10 @@ static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) switch (qc->id) { case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); case V4L2_CID_CONTRAST: case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64); case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); + return v4l2_ctrl_query_fill_std(qc); default: break; } @@ -1203,11 +1210,10 @@ static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, state->default_volume); case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_BASS: case V4L2_CID_AUDIO_TREBLE: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768); + return v4l2_ctrl_query_fill_std(qc); default: return -EINVAL; } @@ -1374,6 +1380,19 @@ static int cx25840_log_status(struct v4l2_subdev *sd) return 0; } +static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + /* ignore this command */ + if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG) + return 0; + + /* Old-style drivers rely on initialization on first use, so + call the init whenever a command is issued to this driver. + New-style drivers using v4l2_subdev should call init explicitly. */ + cx25840_init(i2c_get_clientdata(client), 0); + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops cx25840_core_ops = { @@ -1509,6 +1528,8 @@ MODULE_DEVICE_TABLE(i2c, cx25840_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "cx25840", + .driverid = I2C_DRIVERID_CX25840, + .command = cx25840_command, .probe = cx25840_probe, .remove = cx25840_remove, .id_table = cx25840_id, diff --git a/trunk/drivers/media/video/cx25840/cx25840-core.h b/trunk/drivers/media/video/cx25840/cx25840-core.h index 9ad0eb86ecfd..be0558277ca3 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-core.h +++ b/trunk/drivers/media/video/cx25840/cx25840-core.h @@ -75,15 +75,11 @@ int cx25840_loadfw(struct i2c_client *client); /* ----------------------------------------------------------------------- */ /* cx25850-audio.c */ +int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg); void cx25840_audio_set_path(struct i2c_client *client); -int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq); -int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl); /* ----------------------------------------------------------------------- */ /* cx25850-vbi.c */ -int cx25840_vbi_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt); -int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt); -int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi); +int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg); #endif diff --git a/trunk/drivers/media/video/cx25840/cx25840-vbi.c b/trunk/drivers/media/video/cx25840/cx25840-vbi.c index 35f6592f6c47..03f09b288eb8 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-vbi.c +++ b/trunk/drivers/media/video/cx25840/cx25840-vbi.c @@ -82,181 +82,199 @@ static int decode_vps(u8 * dst, u8 * p) return err & 0xf0; } -int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct cx25840_state *state = to_state(sd); + struct cx25840_state *state = to_state(i2c_get_clientdata(client)); + struct v4l2_format *fmt; struct v4l2_sliced_vbi_format *svbi; - static const u16 lcr2vbi[] = { - 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ - 0, V4L2_SLICED_WSS_625, 0, /* 4 */ - V4L2_SLICED_CAPTION_525, /* 6 */ - 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ - 0, 0, 0, 0 - }; - int is_pal = !(state->std & V4L2_STD_525_60); - int i; - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) - return -EINVAL; - svbi = &fmt->fmt.sliced; - memset(svbi, 0, sizeof(*svbi)); - /* we're done if raw VBI is active */ - if ((cx25840_read(client, 0x404) & 0x10) == 0) - return 0; + switch (cmd) { + case VIDIOC_G_FMT: + { + static u16 lcr2vbi[] = { + 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ + 0, V4L2_SLICED_WSS_625, 0, /* 4 */ + V4L2_SLICED_CAPTION_525, /* 6 */ + 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ + 0, 0, 0, 0 + }; + int is_pal = !(state->std & V4L2_STD_525_60); + int i; - if (is_pal) { - for (i = 7; i <= 23; i++) { - u8 v = cx25840_read(client, 0x424 + i - 7); + fmt = arg; + if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) + return -EINVAL; + svbi = &fmt->fmt.sliced; + memset(svbi, 0, sizeof(*svbi)); + /* we're done if raw VBI is active */ + if ((cx25840_read(client, 0x404) & 0x10) == 0) + break; + + if (is_pal) { + for (i = 7; i <= 23; i++) { + u8 v = cx25840_read(client, 0x424 + i - 7); - svbi->service_lines[0][i] = lcr2vbi[v >> 4]; - svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; - svbi->service_set |= svbi->service_lines[0][i] | - svbi->service_lines[1][i]; + svbi->service_lines[0][i] = lcr2vbi[v >> 4]; + svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; + svbi->service_set |= + svbi->service_lines[0][i] | svbi->service_lines[1][i]; + } } - } else { - for (i = 10; i <= 21; i++) { - u8 v = cx25840_read(client, 0x424 + i - 10); - - svbi->service_lines[0][i] = lcr2vbi[v >> 4]; - svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; - svbi->service_set |= svbi->service_lines[0][i] | - svbi->service_lines[1][i]; + else { + for (i = 10; i <= 21; i++) { + u8 v = cx25840_read(client, 0x424 + i - 10); + + svbi->service_lines[0][i] = lcr2vbi[v >> 4]; + svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; + svbi->service_set |= + svbi->service_lines[0][i] | svbi->service_lines[1][i]; + } } + break; } - return 0; -} -int cx25840_vbi_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct cx25840_state *state = to_state(sd); - struct v4l2_sliced_vbi_format *svbi; - int is_pal = !(state->std & V4L2_STD_525_60); - int vbi_offset = is_pal ? 1 : 0; - int i, x; - u8 lcr[24]; - - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && - fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE) - return -EINVAL; - svbi = &fmt->fmt.sliced; - if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - /* raw VBI */ - memset(svbi, 0, sizeof(*svbi)); + case VIDIOC_S_FMT: + { + int is_pal = !(state->std & V4L2_STD_525_60); + int vbi_offset = is_pal ? 1 : 0; + int i, x; + u8 lcr[24]; + + fmt = arg; + if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && + fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE) + return -EINVAL; + svbi = &fmt->fmt.sliced; + if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { + /* raw VBI */ + memset(svbi, 0, sizeof(*svbi)); + + /* Setup standard */ + cx25840_std_setup(client); + + /* VBI Offset */ + cx25840_write(client, 0x47f, vbi_offset); + cx25840_write(client, 0x404, 0x2e); + break; + } + + for (x = 0; x <= 23; x++) + lcr[x] = 0x00; /* Setup standard */ cx25840_std_setup(client); - /* VBI Offset */ + /* Sliced VBI */ + cx25840_write(client, 0x404, 0x32); /* Ancillary data */ + cx25840_write(client, 0x406, 0x13); cx25840_write(client, 0x47f, vbi_offset); - cx25840_write(client, 0x404, 0x2e); - return 0; - } - for (x = 0; x <= 23; x++) - lcr[x] = 0x00; - - /* Setup standard */ - cx25840_std_setup(client); - - /* Sliced VBI */ - cx25840_write(client, 0x404, 0x32); /* Ancillary data */ - cx25840_write(client, 0x406, 0x13); - cx25840_write(client, 0x47f, vbi_offset); - - if (is_pal) { - for (i = 0; i <= 6; i++) - svbi->service_lines[0][i] = - svbi->service_lines[1][i] = 0; - } else { - for (i = 0; i <= 9; i++) - svbi->service_lines[0][i] = - svbi->service_lines[1][i] = 0; - - for (i = 22; i <= 23; i++) - svbi->service_lines[0][i] = - svbi->service_lines[1][i] = 0; - } + if (is_pal) { + for (i = 0; i <= 6; i++) + svbi->service_lines[0][i] = + svbi->service_lines[1][i] = 0; + } else { + for (i = 0; i <= 9; i++) + svbi->service_lines[0][i] = + svbi->service_lines[1][i] = 0; - for (i = 7; i <= 23; i++) { - for (x = 0; x <= 1; x++) { - switch (svbi->service_lines[1-x][i]) { - case V4L2_SLICED_TELETEXT_B: - lcr[i] |= 1 << (4 * x); - break; - case V4L2_SLICED_WSS_625: - lcr[i] |= 4 << (4 * x); - break; - case V4L2_SLICED_CAPTION_525: - lcr[i] |= 6 << (4 * x); - break; - case V4L2_SLICED_VPS: - lcr[i] |= 9 << (4 * x); - break; + for (i = 22; i <= 23; i++) + svbi->service_lines[0][i] = + svbi->service_lines[1][i] = 0; + } + + for (i = 7; i <= 23; i++) { + for (x = 0; x <= 1; x++) { + switch (svbi->service_lines[1-x][i]) { + case V4L2_SLICED_TELETEXT_B: + lcr[i] |= 1 << (4 * x); + break; + case V4L2_SLICED_WSS_625: + lcr[i] |= 4 << (4 * x); + break; + case V4L2_SLICED_CAPTION_525: + lcr[i] |= 6 << (4 * x); + break; + case V4L2_SLICED_VPS: + lcr[i] |= 9 << (4 * x); + break; + } } } - } - if (is_pal) { - for (x = 1, i = 0x424; i <= 0x434; i++, x++) - cx25840_write(client, i, lcr[6 + x]); - } else { - for (x = 1, i = 0x424; i <= 0x430; i++, x++) - cx25840_write(client, i, lcr[9 + x]); - for (i = 0x431; i <= 0x434; i++) - cx25840_write(client, i, 0); - } + if (is_pal) { + for (x = 1, i = 0x424; i <= 0x434; i++, x++) { + cx25840_write(client, i, lcr[6 + x]); + } + } + else { + for (x = 1, i = 0x424; i <= 0x430; i++, x++) { + cx25840_write(client, i, lcr[9 + x]); + } + for (i = 0x431; i <= 0x434; i++) { + cx25840_write(client, i, 0); + } + } - cx25840_write(client, 0x43c, 0x16); - cx25840_write(client, 0x474, is_pal ? 0x2a : 0x22); - return 0; -} + cx25840_write(client, 0x43c, 0x16); -int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi) -{ - struct cx25840_state *state = to_state(sd); - u8 *p = vbi->p; - int id1, id2, l, err = 0; - - if (p[0] || p[1] != 0xff || p[2] != 0xff || - (p[3] != 0x55 && p[3] != 0x91)) { - vbi->line = vbi->type = 0; - return 0; + if (is_pal) { + cx25840_write(client, 0x474, 0x2a); + } else { + cx25840_write(client, 0x474, 0x22); + } + break; } - p += 4; - id1 = p[-1]; - id2 = p[0] & 0xf; - l = p[2] & 0x3f; - l += state->vbi_line_offset; - p += 4; + case VIDIOC_INT_DECODE_VBI_LINE: + { + struct v4l2_decode_vbi_line *vbi = arg; + u8 *p = vbi->p; + int id1, id2, l, err = 0; - switch (id2) { - case 1: - id2 = V4L2_SLICED_TELETEXT_B; - break; - case 4: - id2 = V4L2_SLICED_WSS_625; - break; - case 6: - id2 = V4L2_SLICED_CAPTION_525; - err = !odd_parity(p[0]) || !odd_parity(p[1]); - break; - case 9: - id2 = V4L2_SLICED_VPS; - if (decode_vps(p, p) != 0) + if (p[0] || p[1] != 0xff || p[2] != 0xff || + (p[3] != 0x55 && p[3] != 0x91)) { + vbi->line = vbi->type = 0; + break; + } + + p += 4; + id1 = p[-1]; + id2 = p[0] & 0xf; + l = p[2] & 0x3f; + l += state->vbi_line_offset; + p += 4; + + switch (id2) { + case 1: + id2 = V4L2_SLICED_TELETEXT_B; + break; + case 4: + id2 = V4L2_SLICED_WSS_625; + break; + case 6: + id2 = V4L2_SLICED_CAPTION_525; + err = !odd_parity(p[0]) || !odd_parity(p[1]); + break; + case 9: + id2 = V4L2_SLICED_VPS; + if (decode_vps(p, p) != 0) { + err = 1; + } + break; + default: + id2 = 0; err = 1; + break; + } + + vbi->type = err ? 0 : id2; + vbi->line = err ? 0 : l; + vbi->is_second_field = err ? 0 : (id1 == 0x55); + vbi->p = p; break; - default: - id2 = 0; - err = 1; - break; + } } - vbi->type = err ? 0 : id2; - vbi->line = err ? 0 : l; - vbi->is_second_field = err ? 0 : (id1 == 0x55); - vbi->p = p; return 0; } diff --git a/trunk/drivers/media/video/cx88/Kconfig b/trunk/drivers/media/video/cx88/Kconfig index 49952980dab3..2d250a2a7bc3 100644 --- a/trunk/drivers/media/video/cx88/Kconfig +++ b/trunk/drivers/media/video/cx88/Kconfig @@ -61,7 +61,7 @@ config VIDEO_CX88_DVB select DVB_STV0299 if !DVB_FE_CUSTOMISE select DVB_STV0288 if !DVB_FE_CUSTOMISE select DVB_STB6000 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE ---help--- This adds support for DVB/ATSC cards based on the Conexant 2388x chip. diff --git a/trunk/drivers/media/video/cx88/cx88-blackbird.c b/trunk/drivers/media/video/cx88/cx88-blackbird.c index 44eacfb0d0d6..7f5b8bfd08ac 100644 --- a/trunk/drivers/media/video/cx88/cx88-blackbird.c +++ b/trunk/drivers/media/video/cx88/cx88-blackbird.c @@ -746,6 +746,7 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, return -EINVAL; strlcpy(f->description, "MPEG", sizeof(f->description)); + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->pixelformat = V4L2_PIX_FMT_MPEG; return 0; } @@ -756,6 +757,7 @@ static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, struct cx8802_fh *fh = priv; struct cx8802_dev *dev = fh->dev; + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */ @@ -774,6 +776,7 @@ static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, struct cx8802_fh *fh = priv; struct cx8802_dev *dev = fh->dev; + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */; @@ -790,6 +793,7 @@ static int vidioc_s_fmt_vid_cap (struct file *file, void *priv, struct cx8802_dev *dev = fh->dev; struct cx88_core *core = dev->core; + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.bytesperline = 0; f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */; @@ -915,7 +919,7 @@ static int vidioc_log_status (struct file *file, void *priv) snprintf(name, sizeof(name), "%s/2", core->name); printk("%s/2: ============ START LOG STATUS ============\n", core->name); - call_all(core, core, log_status); + cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, NULL); cx2341x_log_status(&dev->params, name); printk("%s/2: ============= END LOG STATUS =============\n", core->name); @@ -970,7 +974,7 @@ static int vidioc_g_frequency (struct file *file, void *priv, f->type = V4L2_TUNER_ANALOG_TV; f->frequency = core->freq; - call_all(core, tuner, g_frequency, f); + cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f); return 0; } diff --git a/trunk/drivers/media/video/cx88/cx88-cards.c b/trunk/drivers/media/video/cx88/cx88-cards.c index 0363971a23a8..733ede34f93a 100644 --- a/trunk/drivers/media/video/cx88/cx88-cards.c +++ b/trunk/drivers/media/video/cx88/cx88-cards.c @@ -732,8 +732,6 @@ static const struct cx88_board cx88_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - /* Some variants use a tda9874 and so need the tvaudio module. */ - .audio_chip = V4L2_IDENT_TVAUDIO, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, @@ -1936,39 +1934,6 @@ static const struct cx88_board cx88_boards[] = { } }, .mpeg = CX88_MPEG_DVB, }, - [CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII] = { - .name = "Terratec Cinergy HT PCI MKII", - .tuner_type = TUNER_XC2028, - .tuner_addr = 0x61, - .radio_type = TUNER_XC2028, - .radio_addr = 0x61, - .input = { { - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0x004ff, - .gpio1 = 0x010ff, - .gpio2 = 0x00001, - }, { - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0x004fb, - .gpio1 = 0x010ef, - .audioroute = 1, - }, { - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0x004fb, - .gpio1 = 0x010ef, - .audioroute = 1, - } }, - .radio = { - .type = CX88_RADIO, - .gpio0 = 0x004ff, - .gpio1 = 0x010ff, - .gpio2 = 0x0ff, - }, - .mpeg = CX88_MPEG_DVB, - }, }; /* ------------------------------------------------------------------ */ @@ -2378,10 +2343,6 @@ static const struct cx88_subid cx88_subids[] = { .subvendor = 0xb200, .subdevice = 0x4200, .card = CX88_BOARD_SATTRADE_ST4200, - }, { - .subvendor = 0x153b, - .subdevice = 0x1177, - .card = CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII, }, }; @@ -2858,7 +2819,6 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl) */ break; case CX88_BOARD_PINNACLE_HYBRID_PCTV: - case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII: ctl->demod = XC3028_FE_ZARLINK456; ctl->mts = 1; break; @@ -2987,7 +2947,7 @@ static void cx88_card_setup(struct cx88_core *core) tea5767_cfg.tuner = TUNER_TEA5767; tea5767_cfg.priv = &ctl; - call_all(core, tuner, s_config, &tea5767_cfg); + cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg); break; } case CX88_BOARD_TEVII_S420: @@ -3012,7 +2972,7 @@ static void cx88_card_setup(struct cx88_core *core) tun_setup.type = core->board.radio_type; tun_setup.addr = core->board.radio_addr; tun_setup.tuner_callback = cx88_tuner_callback; - call_all(core, tuner, s_type_addr, &tun_setup); + cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup); mode_mask &= ~T_RADIO; } @@ -3022,7 +2982,7 @@ static void cx88_card_setup(struct cx88_core *core) tun_setup.addr = core->board.tuner_addr; tun_setup.tuner_callback = cx88_tuner_callback; - call_all(core, tuner, s_type_addr, &tun_setup); + cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup); } if (core->board.tda9887_conf) { @@ -3031,7 +2991,7 @@ static void cx88_card_setup(struct cx88_core *core) tda9887_cfg.tuner = TUNER_TDA9887; tda9887_cfg.priv = &core->board.tda9887_conf; - call_all(core, tuner, s_config, &tda9887_cfg); + cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tda9887_cfg); } if (core->board.tuner_type == TUNER_XC2028) { @@ -3047,9 +3007,9 @@ static void cx88_card_setup(struct cx88_core *core) xc2028_cfg.priv = &ctl; info_printk(core, "Asking xc2028/3028 to load firmware %s\n", ctl.fname); - call_all(core, tuner, s_config, &xc2028_cfg); + cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg); } - call_all(core, core, s_standby, 0); + cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL); } /* ------------------------------------------------------------------ */ @@ -3129,8 +3089,6 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) int i; core = kzalloc(sizeof(*core), GFP_KERNEL); - if (core == NULL) - return NULL; atomic_inc(&core->refcount); core->pci_bus = pci->bus->number; @@ -3142,15 +3100,7 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) core->nr = nr; sprintf(core->name, "cx88[%d]", core->nr); - - strcpy(core->v4l2_dev.name, core->name); - if (v4l2_device_register(NULL, &core->v4l2_dev)) { - kfree(core); - return NULL; - } - if (0 != cx88_get_resources(core, pci)) { - v4l2_device_unregister(&core->v4l2_dev); kfree(core); return NULL; } @@ -3161,11 +3111,6 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) pci_resource_len(pci, 0)); core->bmmio = (u8 __iomem *)core->lmmio; - if (core->lmmio == NULL) { - kfree(core); - return NULL; - } - /* board config */ core->boardnr = UNSET; if (card[core->nr] < ARRAY_SIZE(cx88_boards)) @@ -3204,36 +3149,8 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) cx88_i2c_init(core, pci); /* load tuner module, if needed */ - if (TUNER_ABSENT != core->board.tuner_type) { - /* Ignore 0x6b and 0x6f on cx88 boards. - * FusionHDTV5 RT Gold has an ir receiver at 0x6b - * and an RTC at 0x6f which can get corrupted if probed. */ - static const unsigned short tv_addrs[] = { - 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */ - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x6e, - I2C_CLIENT_END - }; - int has_demod = (core->board.tda9887_conf & TDA9887_PRESENT); - - /* I don't trust the radio_type as is stored in the card - definitions, so we just probe for it. - The radio_type is sometimes missing, or set to UNSET but - later code configures a tea5767. - */ - v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner", "tuner", - v4l2_i2c_tuner_addrs(ADDRS_RADIO)); - if (has_demod) - v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner", - "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); - if (core->board.tuner_addr == ADDR_UNSET) { - v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner", - "tuner", has_demod ? tv_addrs + 4 : tv_addrs); - } else { - v4l2_i2c_new_subdev(&core->i2c_adap, - "tuner", "tuner", core->board.tuner_addr); - } - } + if (TUNER_ABSENT != core->board.tuner_type) + request_module("tuner"); cx88_card_setup(core); cx88_ir_init(core, pci); diff --git a/trunk/drivers/media/video/cx88/cx88-core.c b/trunk/drivers/media/video/cx88/cx88-core.c index f2fb9f30bfc1..b045874ad04f 100644 --- a/trunk/drivers/media/video/cx88/cx88-core.c +++ b/trunk/drivers/media/video/cx88/cx88-core.c @@ -991,7 +991,7 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) set_tvaudio(core); // tell i2c chips - call_all(core, tuner, s_std, norm); + cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm); // done return 0; @@ -1011,8 +1011,7 @@ struct video_device *cx88_vdev_init(struct cx88_core *core, return NULL; *vfd = *template; vfd->minor = -1; - vfd->v4l2_dev = &core->v4l2_dev; - vfd->parent = &pci->dev; + vfd->parent = &pci->dev; vfd->release = video_device_release; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", core->name, type, core->board.name); @@ -1059,16 +1058,12 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci) mutex_lock(&devlist); cx88_ir_fini(core); - if (0 == core->i2c_rc) { - if (core->i2c_rtc) - i2c_unregister_device(core->i2c_rtc); + if (0 == core->i2c_rc) i2c_del_adapter(&core->i2c_adap); - } list_del(&core->devlist); iounmap(core->lmmio); cx88_devcount--; mutex_unlock(&devlist); - v4l2_device_unregister(&core->v4l2_dev); kfree(core); } diff --git a/trunk/drivers/media/video/cx88/cx88-dvb.c b/trunk/drivers/media/video/cx88/cx88-dvb.c index 4ff4d9fe0355..aef5297534af 100644 --- a/trunk/drivers/media/video/cx88/cx88-dvb.c +++ b/trunk/drivers/media/video/cx88/cx88-dvb.c @@ -241,12 +241,6 @@ static struct mt352_config dvico_fusionhdtv_dual = { .demod_init = dvico_dual_demod_init, }; -static struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = { - .demod_address = (0x1e >> 1), - .no_tuner = 1, - .if2 = 45600, -}; - #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe) { @@ -1137,16 +1131,6 @@ static int dvb_register(struct cx8802_dev *dev) if (fe0->dvb.frontend != NULL) fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; break; - case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII: - fe0->dvb.frontend = dvb_attach(zl10353_attach, - &cx88_terratec_cinergy_ht_pci_mkii_config, - &core->i2c_adap); - if (fe0->dvb.frontend) { - fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; - if (attach_xc3028(0x61, dev) < 0) - goto frontend_detach; - } - break; default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", core->name); @@ -1168,7 +1152,7 @@ static int dvb_register(struct cx8802_dev *dev) fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; /* Put the analog decoder in standby to keep it quiet */ - call_all(core, core, s_standby, 0); + cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL); /* register everything */ return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, diff --git a/trunk/drivers/media/video/cx88/cx88-i2c.c b/trunk/drivers/media/video/cx88/cx88-i2c.c index 996b4ed5a4fc..c0ff2305d804 100644 --- a/trunk/drivers/media/video/cx88/cx88-i2c.c +++ b/trunk/drivers/media/video/cx88/cx88-i2c.c @@ -97,6 +97,37 @@ static int cx8800_bit_getsda(void *data) /* ----------------------------------------------------------------------- */ +static int attach_inform(struct i2c_client *client) +{ + struct cx88_core *core = i2c_get_adapdata(client->adapter); + + dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", + client->driver->driver.name, client->addr, client->name); + return 0; +} + +static int detach_inform(struct i2c_client *client) +{ + struct cx88_core *core = i2c_get_adapdata(client->adapter); + + dprintk(1, "i2c detach [client=%s]\n", client->name); + return 0; +} + +void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg) +{ + if (0 != core->i2c_rc) + return; + + if (core->gate_ctrl) + core->gate_ctrl(core, 1); + + i2c_clients_command(&core->i2c_adap, cmd, arg); + + if (core->gate_ctrl) + core->gate_ctrl(core, 0); +} + static const struct i2c_algo_bit_data cx8800_i2c_algo_template = { .setsda = cx8800_bit_setsda, .setscl = cx8800_bit_setscl, @@ -142,14 +173,20 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) memcpy(&core->i2c_algo, &cx8800_i2c_algo_template, sizeof(core->i2c_algo)); + if (core->board.tuner_type != TUNER_ABSENT) + core->i2c_adap.class |= I2C_CLASS_TV_ANALOG; + if (core->board.mpeg & CX88_MPEG_DVB) + core->i2c_adap.class |= I2C_CLASS_TV_DIGITAL; core->i2c_adap.dev.parent = &pci->dev; strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name)); core->i2c_adap.owner = THIS_MODULE; core->i2c_adap.id = I2C_HW_B_CX2388x; + core->i2c_adap.client_register = attach_inform; + core->i2c_adap.client_unregister = detach_inform; core->i2c_algo.udelay = i2c_udelay; core->i2c_algo.data = core; - i2c_set_adapdata(&core->i2c_adap, &core->v4l2_dev); + i2c_set_adapdata(&core->i2c_adap,core); core->i2c_adap.algo_data = &core->i2c_algo; core->i2c_client.adapter = &core->i2c_adap; strlcpy(core->i2c_client.name, "cx88xx internal", I2C_NAME_SIZE); @@ -185,6 +222,8 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) /* ----------------------------------------------------------------------- */ +EXPORT_SYMBOL(cx88_call_i2c_clients); + /* * Local variables: * c-basic-offset: 8 diff --git a/trunk/drivers/media/video/cx88/cx88-input.c b/trunk/drivers/media/video/cx88/cx88-input.c index ec05312a9b62..8683d104de72 100644 --- a/trunk/drivers/media/video/cx88/cx88-input.c +++ b/trunk/drivers/media/video/cx88/cx88-input.c @@ -48,7 +48,8 @@ struct cx88_IR { /* poll external decoder */ int polling; - struct delayed_work work; + struct work_struct work; + struct timer_list timer; u32 gpio_addr; u32 last_gpio; u32 mask_keycode; @@ -142,19 +143,27 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) } } +static void ir_timer(unsigned long data) +{ + struct cx88_IR *ir = (struct cx88_IR *)data; + + schedule_work(&ir->work); +} + static void cx88_ir_work(struct work_struct *work) { - struct cx88_IR *ir = container_of(work, struct cx88_IR, work.work); + struct cx88_IR *ir = container_of(work, struct cx88_IR, work); cx88_ir_handle_key(ir); - schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); + mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); } void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir) { if (ir->polling) { - INIT_DELAYED_WORK(&ir->work, cx88_ir_work); - schedule_delayed_work(&ir->work, 0); + setup_timer(&ir->timer, ir_timer, (unsigned long)ir); + INIT_WORK(&ir->work, cx88_ir_work); + schedule_work(&ir->work); } if (ir->sampling) { core->pci_irqmask |= PCI_INT_IR_SMPINT; @@ -170,8 +179,10 @@ void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir) core->pci_irqmask &= ~PCI_INT_IR_SMPINT; } - if (ir->polling) - cancel_delayed_work_sync(&ir->work); + if (ir->polling) { + del_timer_sync(&ir->timer); + flush_scheduled_work(); + } } /* ---------------------------------------------------------------------- */ @@ -215,8 +226,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) case CX88_BOARD_HAUPPAUGE_HVR3000: case CX88_BOARD_HAUPPAUGE_HVR4000: case CX88_BOARD_HAUPPAUGE_HVR4000LITE: - case CX88_BOARD_PCHDTV_HD3000: - case CX88_BOARD_PCHDTV_HD5500: ir_codes = ir_codes_hauppauge_new; ir_type = IR_TYPE_RC5; ir->sampling = 1; @@ -457,8 +466,6 @@ void cx88_ir_irq(struct cx88_core *core) case CX88_BOARD_HAUPPAUGE_HVR3000: case CX88_BOARD_HAUPPAUGE_HVR4000: case CX88_BOARD_HAUPPAUGE_HVR4000LITE: - case CX88_BOARD_PCHDTV_HD3000: - case CX88_BOARD_PCHDTV_HD5500: ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); ir_dprintk("biphase decoded: %x\n", ircode); /* diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c index 434237af5184..791e69d804f9 100644 --- a/trunk/drivers/media/video/cx88/cx88-video.c +++ b/trunk/drivers/media/video/cx88/cx88-video.c @@ -41,6 +41,11 @@ #include #include +#ifdef CONFIG_VIDEO_V4L1_COMPAT +/* Include V4L1 specific functions. Should be removed soon */ +#include +#endif + MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); MODULE_LICENSE("GPL"); @@ -293,7 +298,6 @@ static struct cx88_ctrl cx8800_ctls[] = { }; static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls); -/* Must be sorted from low to high control ID! */ const u32 cx88_user_ctrls[] = { V4L2_CID_USER_CLASS, V4L2_CID_BRIGHTNESS, @@ -431,7 +435,8 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input) struct v4l2_routing route; route.input = INPUT(input).audioroute; - call_all(core, audio, s_routing, &route); + cx88_call_i2c_clients(core, + VIDIOC_INT_S_AUDIO_ROUTING, &route); } /* cx2388's C-ADC is connected to the tuner only. When used with S-Video, that ADC is busy dealing with @@ -826,7 +831,8 @@ static int video_open(struct file *file) struct v4l2_routing route; route.input = core->board.radio.audioroute; - call_all(core, audio, s_routing, &route); + cx88_call_i2c_clients(core, + VIDIOC_INT_S_AUDIO_ROUTING, &route); } /* "I2S ADC mode" */ core->tvaudio = WW_I2SADC; @@ -837,7 +843,7 @@ static int video_open(struct file *file) cx88_set_tvaudio(core); cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); } - call_all(core, tuner, s_radio); + cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); } unlock_kernel(); @@ -931,7 +937,7 @@ static int video_release(struct file *file) kfree(fh); if(atomic_dec_and_test(&dev->core->users)) - call_all(dev->core, core, s_standby, 0); + cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); return 0; } @@ -1270,12 +1276,15 @@ int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i) [ CX88_VMUX_DVB ] = "DVB", [ CX88_VMUX_DEBUG ] = "for debug only", }; - unsigned int n = i->index; + unsigned int n; + n = i->index; if (n >= 4) return -EINVAL; if (0 == INPUT(n).type) return -EINVAL; + memset(i,0,sizeof(*i)); + i->index = n; i->type = V4L2_INPUT_TYPE_CAMERA; strcpy(i->name,iname[INPUT(n).type]); if ((CX88_VMUX_TELEVISION == INPUT(n).type) || @@ -1393,7 +1402,7 @@ static int vidioc_g_frequency (struct file *file, void *priv, f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; f->frequency = core->freq; - call_all(core, tuner, g_frequency, f); + cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f); return 0; } @@ -1409,7 +1418,7 @@ int cx88_set_freq (struct cx88_core *core, mutex_lock(&core->lock); core->freq = f->frequency; cx88_newstation(core); - call_all(core, tuner, s_frequency, f); + cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f); /* When changing channels it is required to reset TVAUDIO */ msleep (10); @@ -1491,7 +1500,7 @@ static int radio_g_tuner (struct file *file, void *priv, strcpy(t->name, "Radio"); t->type = V4L2_TUNER_RADIO; - call_all(core, tuner, g_tuner, t); + cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t); return 0; } @@ -1511,6 +1520,7 @@ static int radio_g_audio (struct file *file, void *priv, struct v4l2_audio *a) if (unlikely(a->index)) return -EINVAL; + memset(a,0,sizeof(*a)); strcpy(a->name,"Radio"); return 0; } @@ -1525,7 +1535,7 @@ static int radio_s_tuner (struct file *file, void *priv, if (0 != t->index) return -EINVAL; - call_all(core, tuner, s_tuner, t); + cx88_call_i2c_clients(core,VIDIOC_S_TUNER,t); return 0; } @@ -1882,30 +1892,12 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, /* load and configure helper modules */ if (core->board.audio_chip == V4L2_IDENT_WM8775) - v4l2_i2c_new_subdev(&core->i2c_adap, - "wm8775", "wm8775", 0x36 >> 1); - - if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) { - /* This probes for a tda9874 as is used on some - Pixelview Ultra boards. */ - static const unsigned short i2c_addr[] = { - 0xb0 >> 1, I2C_CLIENT_END - }; - - v4l2_i2c_new_probed_subdev(&core->i2c_adap, - "tvaudio", "tvaudio", i2c_addr); - } + request_module("wm8775"); switch (core->boardnr) { case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: - case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: { - static struct i2c_board_info rtc_info = { - I2C_BOARD_INFO("isl1208", 0x6f) - }; - + case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: request_module("rtc-isl1208"); - core->i2c_rtc = i2c_new_device(&core->i2c_adap, &rtc_info); - } /* break intentionally omitted */ case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: request_module("ir-kbd-i2c"); diff --git a/trunk/drivers/media/video/cx88/cx88.h b/trunk/drivers/media/video/cx88/cx88.h index 9a43fdf20fae..6025fdd23344 100644 --- a/trunk/drivers/media/video/cx88/cx88.h +++ b/trunk/drivers/media/video/cx88/cx88.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include @@ -231,7 +231,6 @@ extern struct sram_channel cx88_sram_channels[]; #define CX88_BOARD_SATTRADE_ST4200 76 #define CX88_BOARD_TBS_8910 77 #define CX88_BOARD_PROF_6200 78 -#define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, @@ -303,6 +302,7 @@ struct cx88_dmaqueue { struct btcx_riscmem stopper; u32 count; }; +struct cx88_core; struct cx88_core { struct list_head devlist; @@ -327,8 +327,6 @@ struct cx88_core { u32 i2c_state, i2c_rc; /* config info -- analog */ - struct v4l2_device v4l2_dev; - struct i2c_client *i2c_rtc; unsigned int boardnr; struct cx88_board board; @@ -367,22 +365,6 @@ struct cx88_core { int active_fe_id; }; -static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev) -{ - return container_of(v4l2_dev, struct cx88_core, v4l2_dev); -} - -#define call_all(core, o, f, args...) \ - do { \ - if (!core->i2c_rc) { \ - if (core->gate_ctrl) \ - core->gate_ctrl(core, 1); \ - v4l2_device_call_all(&core->v4l2_dev, 0, o, f, ##args); \ - if (core->gate_ctrl) \ - core->gate_ctrl(core, 0); \ - } \ - } while (0) - struct cx8800_dev; struct cx8802_dev; @@ -628,6 +610,8 @@ extern struct videobuf_queue_ops cx8800_vbi_qops; /* cx88-i2c.c */ extern int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci); +extern void cx88_call_i2c_clients(struct cx88_core *core, + unsigned int cmd, void *arg); /* ----------------------------------------------------------- */ diff --git a/trunk/drivers/media/video/dabusb.c b/trunk/drivers/media/video/dabusb.c index ba3709bec3f0..298810d5262b 100644 --- a/trunk/drivers/media/video/dabusb.c +++ b/trunk/drivers/media/video/dabusb.c @@ -189,20 +189,17 @@ static void dabusb_iso_complete (struct urb *purb) dst += len; } else - dev_err(&purb->dev->dev, - "dabusb_iso_complete: invalid len %d\n", len); + err("dabusb_iso_complete: invalid len %d", len); } else dev_warn(&purb->dev->dev, "dabusb_iso_complete: corrupted packet status: %d\n", purb->iso_frame_desc[i].status); if (dst != purb->actual_length) - dev_err(&purb->dev->dev, - "dst!=purb->actual_length:%d!=%d\n", - dst, purb->actual_length); + err("dst!=purb->actual_length:%d!=%d", dst, purb->actual_length); } if (atomic_dec_and_test (&s->pending_io) && !s->remove_pending && s->state != _stopped) { s->overruns++; - dev_err(&purb->dev->dev, "overrun (%d)\n", s->overruns); + err("overrun (%d)", s->overruns); } wake_up (&s->wait); } @@ -223,14 +220,13 @@ static int dabusb_alloc_buffers (pdabusb_t s) while (transfer_len < (s->total_buffer_size << 10)) { b = kzalloc(sizeof (buff_t), GFP_KERNEL); if (!b) { - dev_err(&s->usbdev->dev, - "kzalloc(sizeof(buff_t))==NULL\n"); + err("kzalloc(sizeof(buff_t))==NULL"); goto err; } b->s = s; b->purb = usb_alloc_urb(packets, GFP_KERNEL); if (!b->purb) { - dev_err(&s->usbdev->dev, "usb_alloc_urb == NULL\n"); + err("usb_alloc_urb == NULL"); kfree (b); goto err; } @@ -239,8 +235,7 @@ static int dabusb_alloc_buffers (pdabusb_t s) if (!b->purb->transfer_buffer) { kfree (b->purb); kfree (b); - dev_err(&s->usbdev->dev, - "kmalloc(%d)==NULL\n", transfer_buffer_length); + err("kmalloc(%d)==NULL", transfer_buffer_length); goto err; } @@ -284,11 +279,10 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb) ret=usb_bulk_msg(s->usbdev, pipe, pb->data, pb->size, &actual_length, 100); if(ret<0) { - dev_err(&s->usbdev->dev, - "usb_bulk_msg failed(%d)\n", ret); + err("dabusb: usb_bulk_msg failed(%d)",ret); if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) { - dev_err(&s->usbdev->dev, "set_interface failed\n"); + err("set_interface failed"); return -EINVAL; } @@ -297,7 +291,7 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb) if( ret == -EPIPE ) { dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n"); if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe))) - dev_err(&s->usbdev->dev, "request failed\n"); + err("request failed"); } pb->size = actual_length; @@ -311,8 +305,7 @@ static int dabusb_writemem (pdabusb_t s, int pos, const unsigned char *data, unsigned char *transfer_buffer = kmalloc (len, GFP_KERNEL); if (!transfer_buffer) { - dev_err(&s->usbdev->dev, - "dabusb_writemem: kmalloc(%d) failed.\n", len); + err("dabusb_writemem: kmalloc(%d) failed.", len); return -ENOMEM; } @@ -334,14 +327,13 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname) { int ret; const struct ihex_binrec *rec; - const struct firmware *uninitialized_var(fw); + const struct firmware *fw; dbg("Enter dabusb_loadmem (internal)"); ret = request_ihex_firmware(&fw, "dabusb/firmware.fw", &s->usbdev->dev); if (ret) { - dev_err(&s->usbdev->dev, - "Failed to load \"dabusb/firmware.fw\": %d\n", ret); + err("Failed to load \"dabusb/firmware.fw\": %d\n", ret); goto out; } ret = dabusb_8051_reset (s, 1); @@ -354,10 +346,9 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname) ret = dabusb_writemem(s, be32_to_cpu(rec->addr), rec->data, be16_to_cpu(rec->len)); if (ret < 0) { - dev_err(&s->usbdev->dev, - "dabusb_writemem failed (%d %04X %p %d)\n", - ret, be32_to_cpu(rec->addr), - rec->data, be16_to_cpu(rec->len)); + err("dabusb_writemem failed (%d %04X %p %d)", ret, + be32_to_cpu(rec->addr), rec->data, + be16_to_cpu(rec->len)); break; } } @@ -405,15 +396,13 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname) dbg("Enter dabusb_fpga_download (internal)"); if (!b) { - dev_err(&s->usbdev->dev, - "kmalloc(sizeof(bulk_transfer_t))==NULL\n"); + err("kmalloc(sizeof(bulk_transfer_t))==NULL"); return -ENOMEM; } ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev); if (ret) { - dev_err(&s->usbdev->dev, - "Failed to load \"dabusb/bitstream.bin\": %d\n", ret); + err("Failed to load \"dabusb/bitstream.bin\": %d\n", ret); kfree(b); return ret; } @@ -436,7 +425,7 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname) memcpy (b->data + 4, fw->data + 74 + n, 60); ret = dabusb_bulk (s, b); if (ret < 0) { - dev_err(&s->usbdev->dev, "dabusb_bulk failed.\n"); + err("dabusb_bulk failed."); break; } mdelay (1); @@ -489,11 +478,9 @@ static int dabusb_startrek (pdabusb_t s) ret = usb_submit_urb (end->purb, GFP_KERNEL); if (ret) { - dev_err(&s->usbdev->dev, - "usb_submit_urb returned:%d\n", ret); + err("usb_submit_urb returned:%d", ret); if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list)) - dev_err(&s->usbdev->dev, - "startrek: dabusb_add_buf_tail failed\n"); + err("startrek: dabusb_add_buf_tail failed"); break; } else @@ -536,8 +523,7 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l spin_unlock_irqrestore(&s->lock, flags); - dev_err(&s->usbdev->dev, - "error: rec_buf_list is empty\n"); + err("error: rec_buf_list is empty"); goto err; } @@ -566,8 +552,7 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l if (list_empty (&s->rec_buff_list)) { spin_unlock_irqrestore(&s->lock, flags); - dev_err(&s->usbdev->dev, - "error: still no buffer available.\n"); + err("error: still no buffer available."); goto err; } spin_unlock_irqrestore(&s->lock, flags); @@ -588,7 +573,7 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l dbg("copy_to_user:%p %p %d",buf, purb->transfer_buffer + s->readptr, cnt); if (copy_to_user (buf, purb->transfer_buffer + s->readptr, cnt)) { - dev_err(&s->usbdev->dev, "read: copy_to_user failed\n"); + err("read: copy_to_user failed"); if (!ret) ret = -EFAULT; goto err; @@ -602,8 +587,7 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l if (s->readptr == purb->actual_length) { // finished, take next buffer if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list)) - dev_err(&s->usbdev->dev, - "read: dabusb_add_buf_tail failed\n"); + err("read: dabusb_add_buf_tail failed"); s->readptr = 0; } } @@ -639,7 +623,7 @@ static int dabusb_open (struct inode *inode, struct file *file) } if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) { mutex_unlock(&s->mutex); - dev_err(&s->usbdev->dev, "set_interface failed\n"); + err("set_interface failed"); return -EINVAL; } s->opened = 1; @@ -664,7 +648,7 @@ static int dabusb_release (struct inode *inode, struct file *file) if (!s->remove_pending) { if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) - dev_err(&s->usbdev->dev, "set_interface failed\n"); + err("set_interface failed"); } else wake_up (&s->remove_ok); @@ -673,7 +657,7 @@ static int dabusb_release (struct inode *inode, struct file *file) return 0; } -static long dabusb_ioctl (struct file *file, unsigned int cmd, unsigned long arg) +static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { pdabusb_t s = (pdabusb_t) file->private_data; pbulk_transfer_t pbulk; @@ -682,17 +666,13 @@ static long dabusb_ioctl (struct file *file, unsigned int cmd, unsigned long arg dbg("dabusb_ioctl"); - lock_kernel(); - if (s->remove_pending) { - unlock_kernel(); + if (s->remove_pending) return -EIO; - } mutex_lock(&s->mutex); if (!s->usbdev) { mutex_unlock(&s->mutex); - unlock_kernel(); return -EIO; } @@ -733,7 +713,6 @@ static long dabusb_ioctl (struct file *file, unsigned int cmd, unsigned long arg break; } mutex_unlock(&s->mutex); - unlock_kernel(); return ret; } @@ -742,7 +721,7 @@ static const struct file_operations dabusb_fops = .owner = THIS_MODULE, .llseek = no_llseek, .read = dabusb_read, - .unlocked_ioctl = dabusb_ioctl, + .ioctl = dabusb_ioctl, .open = dabusb_open, .release = dabusb_release, }; @@ -785,7 +764,7 @@ static int dabusb_probe (struct usb_interface *intf, s->devnum = intf->minor; if (usb_reset_configuration (usbdev) < 0) { - dev_err(&intf->dev, "reset_configuration failed\n"); + err("reset_configuration failed"); goto reject; } if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) { @@ -796,7 +775,7 @@ static int dabusb_probe (struct usb_interface *intf, dabusb_fpga_download (s, NULL); if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) { - dev_err(&intf->dev, "set_interface failed\n"); + err("set_interface failed"); goto reject; } } diff --git a/trunk/drivers/media/video/em28xx/em28xx-audio.c b/trunk/drivers/media/video/em28xx/em28xx-audio.c index 0131322475bf..f132e31f6edd 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-audio.c +++ b/trunk/drivers/media/video/em28xx/em28xx-audio.c @@ -56,7 +56,7 @@ MODULE_PARM_DESC(debug, "activates debug info"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -static int em28xx_deinit_isoc_audio(struct em28xx *dev) +static int em28xx_isoc_audio_deinit(struct em28xx *dev) { int i; @@ -66,7 +66,6 @@ static int em28xx_deinit_isoc_audio(struct em28xx *dev) usb_kill_urb(dev->adev.urb[i]); else usb_unlink_urb(dev->adev.urb[i]); - usb_free_urb(dev->adev.urb[i]); dev->adev.urb[i] = NULL; @@ -88,20 +87,6 @@ static void em28xx_audio_isocirq(struct urb *urb) unsigned int stride; struct snd_pcm_substream *substream; struct snd_pcm_runtime *runtime; - - switch (urb->status) { - case 0: /* success */ - case -ETIMEDOUT: /* NAK */ - break; - case -ECONNRESET: /* kill */ - case -ENOENT: - case -ESHUTDOWN: - return; - default: /* error */ - dprintk("urb completition error %d.\n", urb->status); - break; - } - if (dev->adev.capture_pcm_substream) { substream = dev->adev.capture_pcm_substream; runtime = substream->runtime; @@ -152,6 +137,9 @@ static void em28xx_audio_isocirq(struct urb *urb) } urb->status = 0; + if (dev->adev.shutdown) + return; + status = usb_submit_urb(urb, GFP_ATOMIC); if (status < 0) { em28xx_errdev("resubmit of audio urb failed (error=%i)\n", @@ -209,7 +197,8 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); if (errCode) { - em28xx_deinit_isoc_audio(dev); + em28xx_isoc_audio_deinit(dev); + return errCode; } } @@ -224,16 +213,14 @@ static int em28xx_cmd(struct em28xx *dev, int cmd, int arg) switch (cmd) { case EM28XX_CAPTURE_STREAM_EN: - if (dev->adev.capture_stream == STREAM_OFF && - arg == EM28XX_START_AUDIO) { + if (dev->adev.capture_stream == STREAM_OFF && arg == 1) { dev->adev.capture_stream = STREAM_ON; em28xx_init_audio_isoc(dev); - } else if (dev->adev.capture_stream == STREAM_ON && - arg == EM28XX_STOP_AUDIO) { + } else if (dev->adev.capture_stream == STREAM_ON && arg == 0) { dev->adev.capture_stream = STREAM_OFF; - em28xx_deinit_isoc_audio(dev); + em28xx_isoc_audio_deinit(dev); } else { - em28xx_errdev("An underrun very likely occurred. " + printk(KERN_ERR "An underrun very likely occurred. " "Ignoring it.\n"); } return 0; @@ -247,7 +234,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, { struct snd_pcm_runtime *runtime = subs->runtime; - dprintk("Allocating vbuffer\n"); + dprintk("Alocating vbuffer\n"); if (runtime->dma_area) { if (runtime->dma_bytes > size) return 0; @@ -315,9 +302,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) dprintk("changing alternate number to 7\n"); } - mutex_lock(&dev->lock); dev->adev.users++; - mutex_unlock(&dev->lock); snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); dev->adev.capture_pcm_substream = substream; @@ -332,15 +317,22 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) { struct em28xx *dev = snd_pcm_substream_chip(substream); + dev->adev.users--; dprintk("closing device\n"); dev->mute = 1; mutex_lock(&dev->lock); - dev->adev.users--; em28xx_audio_analog_set(dev); mutex_unlock(&dev->lock); + if (dev->adev.users == 0 && dev->adev.shutdown == 1) { + dprintk("audio users: %d\n", dev->adev.users); + dprintk("disabling audio stream!\n"); + dev->adev.shutdown = 0; + dprintk("released lock\n"); + em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); + } return 0; } @@ -371,7 +363,7 @@ static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream) dprintk("Stop capture, if needed\n"); if (dev->adev.capture_stream == STREAM_ON) - em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO); + em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0); return 0; } @@ -385,40 +377,33 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, int cmd) { struct em28xx *dev = snd_pcm_substream_chip(substream); - int retval; - dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START) ? - "start" : "stop"); - - spin_lock(&dev->adev.slock); + dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START)? + "start": "stop"); switch (cmd) { case SNDRV_PCM_TRIGGER_START: - em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_START_AUDIO); - retval = 0; - break; + em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1); + return 0; case SNDRV_PCM_TRIGGER_STOP: - em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO); - retval = 0; - break; + dev->adev.shutdown = 1; + return 0; default: - retval = -EINVAL; + return -EINVAL; } - - spin_unlock(&dev->adev.slock); - return retval; } static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream *substream) { - unsigned long flags; + unsigned long flags; + struct em28xx *dev; snd_pcm_uframes_t hwptr_done; dev = snd_pcm_substream_chip(substream); - spin_lock_irqsave(&dev->adev.slock, flags); + spin_lock_irqsave(&dev->adev.slock, flags); hwptr_done = dev->adev.hwptr_done_capture; - spin_unlock_irqrestore(&dev->adev.slock, flags); + spin_unlock_irqrestore(&dev->adev.slock, flags); return hwptr_done; } diff --git a/trunk/drivers/media/video/em28xx/em28xx-cards.c b/trunk/drivers/media/video/em28xx/em28xx-cards.c index 0f48c0ff5ac3..3b3ca3f46d52 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-cards.c +++ b/trunk/drivers/media/video/em28xx/em28xx-cards.c @@ -122,22 +122,6 @@ static struct em28xx_reg_seq default_tuner_gpio[] = { { -1, -1, -1, -1}, }; -/* Mute/unmute */ -static struct em28xx_reg_seq compro_unmute_tv_gpio[] = { - {EM28XX_R08_GPIO, 5, 7, 10}, - { -1, -1, -1, -1}, -}; - -static struct em28xx_reg_seq compro_unmute_svid_gpio[] = { - {EM28XX_R08_GPIO, 4, 7, 10}, - { -1, -1, -1, -1}, -}; - -static struct em28xx_reg_seq compro_mute_gpio[] = { - {EM28XX_R08_GPIO, 6, 7, 10}, - { -1, -1, -1, -1}, -}; - /* * Board definitions */ @@ -199,25 +183,6 @@ struct em28xx_board em28xx_boards[] = { .amux = EM28XX_AMUX_LINE_IN, } }, }, - [EM2820_BOARD_GADMEI_TVR200] = { - .name = "Gadmei TVR200", - .tuner_type = TUNER_LG_PAL_NEW_TAPC, - .tda9887_conf = TDA9887_PRESENT, - .decoder = EM28XX_SAA711X, - .input = { { - .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, - .amux = EM28XX_AMUX_LINE_IN, - }, { - .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, - .amux = EM28XX_AMUX_LINE_IN, - }, { - .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, - .amux = EM28XX_AMUX_LINE_IN, - } }, - }, [EM2820_BOARD_TERRATEC_CINERGY_250] = { .name = "Terratec Cinergy 250 USB", .tuner_type = TUNER_LG_PAL_NEW_TAPC, @@ -260,7 +225,7 @@ struct em28xx_board em28xx_boards[] = { .name = "Hauppauge WinTV USB 2", .tuner_type = TUNER_PHILIPS_FM1236_MK3, .tda9887_conf = TDA9887_PRESENT | - TDA9887_PORT1_ACTIVE | + TDA9887_PORT1_ACTIVE| TDA9887_PORT2_ACTIVE, .decoder = EM28XX_TVP5150, .has_msp34xx = 1, @@ -385,6 +350,26 @@ struct em28xx_board em28xx_boards[] = { .amux = EM28XX_AMUX_VIDEO, } }, }, + [EM2821_BOARD_PROLINK_PLAYTV_USB2] = { + .name = "SIIG AVTuner-PVR/Prolink PlayTV USB 2.0", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, /* unknown? */ + .tda9887_conf = TDA9887_PRESENT, /* unknown? */ + .decoder = EM28XX_SAA711X, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = EM28XX_AMUX_LINE_IN, + } }, + }, [EM2821_BOARD_SUPERCOMP_USB_2] = { .name = "Supercomp USB 2.0 TV", .valid = EM28XX_BOARD_NOT_VALIDATED, @@ -513,7 +498,7 @@ struct em28xx_board em28xx_boards[] = { }, [EM2861_BOARD_YAKUMO_MOVIE_MIXER] = { .name = "Yakumo MovieMixer", - .tuner_type = TUNER_ABSENT, /* Capture only device */ + .tuner_type = TUNER_ABSENT, /* Capture only device */ .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -619,7 +604,6 @@ struct em28xx_board em28xx_boards[] = { .mts_firmware = 1, .has_dvb = 1, .dvb_gpio = hauppauge_wintv_hvr_900_digital, - .ir_codes = ir_codes_hauppauge_new, .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -644,7 +628,6 @@ struct em28xx_board em28xx_boards[] = { .tuner_type = TUNER_XC2028, .tuner_gpio = default_tuner_gpio, .mts_firmware = 1, - .ir_codes = ir_codes_hauppauge_new, .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -859,11 +842,11 @@ struct em28xx_board em28xx_boards[] = { } }, }, [EM2800_BOARD_GRABBEEX_USB2800] = { - .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", - .is_em2800 = 1, - .decoder = EM28XX_SAA711X, - .tuner_type = TUNER_ABSENT, /* capture only board */ - .input = { { + .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", + .is_em2800 = 1, + .decoder = EM28XX_SAA711X, + .tuner_type = TUNER_ABSENT, /* capture only board */ + .input = { { .type = EM28XX_VMUX_COMPOSITE1, .vmux = SAA7115_COMPOSITE0, .amux = EM28XX_AMUX_LINE_IN, @@ -914,7 +897,7 @@ struct em28xx_board em28xx_boards[] = { } }, }, [EM2820_BOARD_PINNACLE_DVC_90] = { - .name = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker", + .name = "Pinnacle Dazzle DVC 90/DVC 100", .tuner_type = TUNER_ABSENT, /* capture only board */ .decoder = EM28XX_SAA711X, .input = { { @@ -969,7 +952,7 @@ struct em28xx_board em28xx_boards[] = { } }, }, [EM2820_BOARD_PROLINK_PLAYTV_USB2] = { - .name = "SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0", + .name = "Pixelview Prolink PlayTV USB 2.0", .has_snapshot_button = 1, .tda9887_conf = TDA9887_PRESENT, .tuner_type = TUNER_YMEC_TVF_5533MF, @@ -1215,9 +1198,7 @@ struct em28xx_board em28xx_boards[] = { .has_dvb = 1, .dvb_gpio = kworld_330u_digital, .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, - .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | - EM28XX_I2C_EEPROM_ON_BOARD | - EM28XX_I2C_EEPROM_KEY_VALID, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_EEPROM_ON_BOARD | EM28XX_I2C_EEPROM_KEY_VALID, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, @@ -1242,88 +1223,21 @@ struct em28xx_board em28xx_boards[] = { .tuner_type = TUNER_LG_PAL_NEW_TAPC, .tda9887_conf = TDA9887_PRESENT, .decoder = EM28XX_TVP5150, - .adecoder = EM28XX_TVAUDIO, - .mute_gpio = compro_mute_gpio, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, - .amux = EM28XX_AMUX_VIDEO, - .gpio = compro_unmute_tv_gpio, - }, { - .type = EM28XX_VMUX_SVIDEO, - .vmux = TVP5150_SVIDEO, - .amux = EM28XX_AMUX_LINE_IN, - .gpio = compro_unmute_svid_gpio, - } }, - }, - [EM2860_BOARD_KAIOMY_TVNPC_U2] = { - .name = "Kaiomy TVnPC U2", - .vchannels = 3, - .tuner_type = TUNER_XC2028, - .tuner_addr = 0x61, - .mts_firmware = 1, - .decoder = EM28XX_TVP5150, - .tuner_gpio = default_tuner_gpio, - .ir_codes = ir_codes_kaiomy, - .input = { { - .type = EM28XX_VMUX_TELEVISION, - .vmux = TVP5150_COMPOSITE0, - .amux = EM28XX_AMUX_VIDEO, - - }, { - .type = EM28XX_VMUX_COMPOSITE1, - .vmux = TVP5150_COMPOSITE1, .amux = EM28XX_AMUX_LINE_IN, }, { .type = EM28XX_VMUX_SVIDEO, .vmux = TVP5150_SVIDEO, .amux = EM28XX_AMUX_LINE_IN, } }, - .radio = { - .type = EM28XX_RADIO, - .amux = EM28XX_AMUX_LINE_IN, - } - }, - [EM2860_BOARD_EASYCAP] = { - .name = "Easy Cap Capture DC-60", - .vchannels = 2, - .tuner_type = TUNER_ABSENT, - .decoder = EM28XX_SAA711X, - .input = { { - .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, - .amux = EM28XX_AMUX_LINE_IN, - }, { - .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, - .amux = EM28XX_AMUX_LINE_IN, - } }, - }, - [EM2820_BOARD_IODATA_GVMVP_SZ] = { - .name = "IO-DATA GV-MVP/SZ", - .tuner_type = TUNER_PHILIPS_FM1236_MK3, - .tuner_gpio = default_tuner_gpio, - .tda9887_conf = TDA9887_PRESENT, - .decoder = EM28XX_TVP5150, - .input = { { - .type = EM28XX_VMUX_TELEVISION, - .vmux = TVP5150_COMPOSITE0, - .amux = EM28XX_AMUX_VIDEO, - }, { /* Composite has not been tested yet */ - .type = EM28XX_VMUX_COMPOSITE1, - .vmux = TVP5150_COMPOSITE1, - .amux = EM28XX_AMUX_VIDEO, - }, { /* S-video has not been tested yet */ - .type = EM28XX_VMUX_SVIDEO, - .vmux = TVP5150_SVIDEO, - .amux = EM28XX_AMUX_VIDEO, - } }, }, }; const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); /* table of devices that work with this driver */ -struct usb_device_id em28xx_id_table[] = { +struct usb_device_id em28xx_id_table [] = { { USB_DEVICE(0xeb1a, 0x2750), .driver_info = EM2750_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0x2751), @@ -1346,8 +1260,6 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM2820_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0xe300), .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U }, - { USB_DEVICE(0xeb1a, 0xe303), - .driver_info = EM2860_BOARD_KAIOMY_TVNPC_U2 }, { USB_DEVICE(0xeb1a, 0xe305), .driver_info = EM2880_BOARD_KWORLD_DVB_305U }, { USB_DEVICE(0xeb1a, 0xe310), @@ -1366,8 +1278,6 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM2800_BOARD_GRABBEEX_USB2800 }, { USB_DEVICE(0xeb1a, 0xe357), .driver_info = EM2870_BOARD_KWORLD_355U }, - { USB_DEVICE(0x1b80, 0xe302), - .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kaiser Baas Video to DVD maker */ { USB_DEVICE(0x0ccd, 0x0036), .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 }, { USB_DEVICE(0x0ccd, 0x004c), @@ -1420,8 +1330,6 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII }, { USB_DEVICE(0x093b, 0xa005), .driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U }, - { USB_DEVICE(0x04bb, 0x0515), - .driver_info = EM2820_BOARD_IODATA_GVMVP_SZ }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); @@ -1429,7 +1337,7 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table); /* * EEPROM hash table for devices with generic USB IDs */ -static struct em28xx_hash_table em28xx_eeprom_hash[] = { +static struct em28xx_hash_table em28xx_eeprom_hash [] = { /* P/N: SA 60002070465 Tuner: TVF7533-MF */ {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, @@ -1441,7 +1349,6 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = { {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, {0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT}, - {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC}, }; int em28xx_tuner_callback(void *ptr, int component, int command, int arg) @@ -1461,7 +1368,7 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg) } EXPORT_SYMBOL_GPL(em28xx_tuner_callback); -static inline void em28xx_set_model(struct em28xx *dev) +static void inline em28xx_set_model(struct em28xx *dev) { memcpy(&dev->board, &em28xx_boards[dev->model], sizeof(dev->board)); @@ -1597,34 +1504,6 @@ void em28xx_pre_card_setup(struct em28xx *dev) /* enables audio for that devices */ em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); break; - - case EM2860_BOARD_KAIOMY_TVNPC_U2: - em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1); - em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); - em28xx_write_regs(dev, 0x0d, "\x42", 1); - em28xx_write_regs(dev, 0x08, "\xfd", 1); - msleep(10); - em28xx_write_regs(dev, 0x08, "\xff", 1); - msleep(10); - em28xx_write_regs(dev, 0x08, "\x7f", 1); - msleep(10); - em28xx_write_regs(dev, 0x08, "\x6b", 1); - - break; - case EM2860_BOARD_EASYCAP: - em28xx_write_regs(dev, 0x08, "\xf8", 1); - break; - - case EM2820_BOARD_IODATA_GVMVP_SZ: - em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff); - msleep(70); - em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7); - msleep(10); - em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); - msleep(70); - em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); - msleep(70); - break; } em28xx_gpio_set(dev, dev->board.tuner_gpio); @@ -1731,7 +1610,7 @@ static int em28xx_hint_board(struct em28xx *dev) em28xx_errdev("If the board were missdetected, " "please email this log to:\n"); em28xx_errdev("\tV4L Mailing List " - " \n"); + " \n"); em28xx_errdev("Board detected as %s\n", em28xx_boards[dev->model].name); @@ -1763,7 +1642,7 @@ static int em28xx_hint_board(struct em28xx *dev) em28xx_errdev("If the board were missdetected, " "please email this log to:\n"); em28xx_errdev("\tV4L Mailing List " - " \n"); + " \n"); em28xx_errdev("Board detected as %s\n", em28xx_boards[dev->model].name); @@ -1776,7 +1655,7 @@ static int em28xx_hint_board(struct em28xx *dev) em28xx_errdev("You may try to use card= insmod option to " "workaround that.\n"); em28xx_errdev("Please send an email with this log to:\n"); - em28xx_errdev("\tV4L Mailing List \n"); + em28xx_errdev("\tV4L Mailing List \n"); em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash); em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash); @@ -1921,8 +1800,6 @@ void em28xx_card_setup(struct em28xx *dev) request_module("tvp5150"); if (dev->board.tuner_type != TUNER_ABSENT) request_module("tuner"); - if (dev->board.adecoder == EM28XX_TVAUDIO) - request_module("tvaudio"); #endif em28xx_config_tuner(dev); diff --git a/trunk/drivers/media/video/em28xx/em28xx-core.c b/trunk/drivers/media/video/em28xx/em28xx-core.c index 8f1999ca4803..94fb1b639a2e 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-core.c +++ b/trunk/drivers/media/video/em28xx/em28xx-core.c @@ -33,8 +33,8 @@ /* #define ENABLE_DEBUG_ISOC_FRAMES */ static unsigned int core_debug; -module_param(core_debug, int, 0644); -MODULE_PARM_DESC(core_debug, "enable debug messages [core]"); +module_param(core_debug,int,0644); +MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); #define em28xx_coredbg(fmt, arg...) do {\ if (core_debug) \ @@ -42,8 +42,8 @@ MODULE_PARM_DESC(core_debug, "enable debug messages [core]"); dev->name, __func__ , ##arg); } while (0) static unsigned int reg_debug; -module_param(reg_debug, int, 0644); -MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]"); +module_param(reg_debug,int,0644); +MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); #define em28xx_regdbg(fmt, arg...) do {\ if (reg_debug) \ @@ -77,7 +77,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, return -EINVAL; if (reg_debug) { - printk(KERN_DEBUG "(pipe 0x%08x): " + printk( KERN_DEBUG "(pipe 0x%08x): " "IN: %02x %02x %02x %02x %02x %02x %02x %02x ", pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, @@ -154,7 +154,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, if (reg_debug) { int byte; - printk(KERN_DEBUG "(pipe 0x%08x): " + printk( KERN_DEBUG "(pipe 0x%08x): " "OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>", pipe, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, @@ -378,11 +378,6 @@ static int em28xx_set_audio_source(struct em28xx *dev) } } - if (dev->board.mute_gpio && dev->mute) - em28xx_gpio_set(dev, dev->board.mute_gpio); - else - em28xx_gpio_set(dev, INPUT(dev->ctl_input)->gpio); - ret = em28xx_write_reg_bits(dev, EM28XX_R0E_AUDIOSRC, input, 0xc0); if (ret < 0) return ret; @@ -429,7 +424,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) xclk = dev->board.xclk & 0x7f; if (!dev->mute) - xclk |= EM28XX_XCLK_AUDIO_UNMUTE; + xclk |= 0x80; ret = em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk); if (ret < 0) @@ -467,8 +462,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) { int sel = ac97_return_record_select(dev->ctl_aoutput); - /* Use the same input for both left and right - channels */ + /* Use the same input for both left and right channels */ sel |= (sel << 8); em28xx_write_ac97(dev, AC97_RECORD_SELECT, sel); @@ -704,7 +698,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2); /* it seems that both H and V scalers must be active to work correctly */ - mode = (h || v) ? 0x30 : 0x00; + mode = (h || v)? 0x30: 0x00; } return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30); } @@ -833,19 +827,6 @@ static void em28xx_irq_callback(struct urb *urb) struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); int rc, i; - switch (urb->status) { - case 0: /* success */ - case -ETIMEDOUT: /* NAK */ - break; - case -ECONNRESET: /* kill */ - case -ENOENT: - case -ESHUTDOWN: - return; - default: /* error */ - em28xx_isocdbg("urb completition error %d.\n", urb->status); - break; - } - /* Copy data from URB */ spin_lock(&dev->slock); rc = dev->isoc_ctl.isoc_copy(dev, urb); @@ -964,7 +945,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, em28xx_err("unable to allocate %i bytes for transfer" " buffer %i%s\n", sb_size, i, - in_interrupt() ? " while in int" : ""); + in_interrupt()?" while in int":""); em28xx_uninit_isoc(dev); return -ENOMEM; } @@ -982,7 +963,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, em28xx_irq_callback, dma_q, 1); urb->number_of_packets = max_packets; - urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; + urb->transfer_flags = URB_ISO_ASAP; k = 0; for (j = 0; j < max_packets; j++) { diff --git a/trunk/drivers/media/video/em28xx/em28xx-dvb.c b/trunk/drivers/media/video/em28xx/em28xx-dvb.c index fcd25511209b..9ad8527b3fda 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-dvb.c +++ b/trunk/drivers/media/video/em28xx/em28xx-dvb.c @@ -29,6 +29,9 @@ #include "lgdt330x.h" #include "zl10353.h" #include "s5h1409.h" +#ifdef EM28XX_DRX397XD_SUPPORT +#include "drx397xD.h" +#endif MODULE_DESCRIPTION("driver for em28xx based DVB cards"); MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/trunk/drivers/media/video/em28xx/em28xx-i2c.c b/trunk/drivers/media/video/em28xx/em28xx-i2c.c index 02c12fe6361b..d69f0efcc9aa 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-i2c.c +++ b/trunk/drivers/media/video/em28xx/em28xx-i2c.c @@ -402,12 +402,10 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) dev->name); break; case 2: - printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n", - dev->name); + printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n", dev->name); break; case 3: - printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n", - dev->name); + printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n", dev->name); break; } @@ -510,17 +508,12 @@ static int attach_inform(struct i2c_client *client) dprintk1(1, "attach_inform: tvp5150 detected.\n"); break; - case 0xb0: - dprintk1(1, "attach_inform: tda9874 detected\n"); - break; - default: if (!dev->tuner_addr) dev->tuner_addr = client->addr; dprintk1(1, "attach inform: detected I2C address %x\n", client->addr << 1); - dprintk1(1, "driver id %d\n", client->driver->id); } @@ -559,7 +552,6 @@ static char *i2c_devs[128] = { [0x80 >> 1] = "msp34xx", [0x88 >> 1] = "msp34xx", [0xa0 >> 1] = "eeprom", - [0xb0 >> 1] = "tda9874", [0xb8 >> 1] = "tvp5150a", [0xba >> 1] = "tvp5150a", [0xc0 >> 1] = "tuner (analog)", diff --git a/trunk/drivers/media/video/em28xx/em28xx-input.c b/trunk/drivers/media/video/em28xx/em28xx-input.c index a5abfd7a19f5..0443afe09ff8 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-input.c +++ b/trunk/drivers/media/video/em28xx/em28xx-input.c @@ -68,7 +68,8 @@ struct em28xx_IR { /* poll external decoder */ int polling; - struct delayed_work work; + struct work_struct work; + struct timer_list timer; unsigned int last_toggle:1; unsigned int last_readcount; unsigned int repeat_interval; @@ -291,23 +292,32 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir) return; } +static void ir_timer(unsigned long data) +{ + struct em28xx_IR *ir = (struct em28xx_IR *)data; + + schedule_work(&ir->work); +} + static void em28xx_ir_work(struct work_struct *work) { - struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work.work); + struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work); em28xx_ir_handle_key(ir); - schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); + mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); } static void em28xx_ir_start(struct em28xx_IR *ir) { - INIT_DELAYED_WORK(&ir->work, em28xx_ir_work); - schedule_delayed_work(&ir->work, 0); + setup_timer(&ir->timer, ir_timer, (unsigned long)ir); + INIT_WORK(&ir->work, em28xx_ir_work); + schedule_work(&ir->work); } static void em28xx_ir_stop(struct em28xx_IR *ir) { - cancel_delayed_work_sync(&ir->work); + del_timer_sync(&ir->timer); + flush_scheduled_work(); } int em28xx_ir_init(struct em28xx *dev) diff --git a/trunk/drivers/media/video/em28xx/em28xx-video.c b/trunk/drivers/media/video/em28xx/em28xx-video.c index 575472f1e702..8e61b2ca9167 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-video.c +++ b/trunk/drivers/media/video/em28xx/em28xx-video.c @@ -186,8 +186,7 @@ static void em28xx_copy_video(struct em28xx *dev, em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n", ((char *)startwrite + lencopy) - ((char *)outp + buf->vb.size)); - remain = (char *)outp + buf->vb.size - (char *)startwrite; - lencopy = remain; + lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite; } if (lencopy <= 0) return; @@ -203,8 +202,7 @@ static void em28xx_copy_video(struct em28xx *dev, else lencopy = bytesperline; - if ((char *)startwrite + lencopy > (char *)outp + - buf->vb.size) { + if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) { em28xx_isocdbg("Overflow of %zi bytes past buffer end (2)\n", ((char *)startwrite + lencopy) - ((char *)outp + buf->vb.size)); @@ -349,7 +347,7 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb) } if (p[0] == 0x22 && p[1] == 0x5a) { em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2], - len, (p[2] & 1) ? "odd" : "even"); + len, (p[2] & 1)? "odd" : "even"); if (!(p[2] & 1)) { if (buf != NULL) @@ -478,9 +476,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) { - struct em28xx_buffer *buf = container_of(vb, - struct em28xx_buffer, - vb); + struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); struct em28xx_fh *fh = vq->priv_data; struct em28xx *dev = fh->dev; struct em28xx_dmaqueue *vidq = &dev->vidq; @@ -493,9 +489,7 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb) { - struct em28xx_buffer *buf = container_of(vb, - struct em28xx_buffer, - vb); + struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); struct em28xx_fh *fh = vq->priv_data; struct em28xx *dev = (struct em28xx *)fh->dev; @@ -540,13 +534,6 @@ static void video_mux(struct em28xx *dev, int index) &route); } - if (dev->board.adecoder != EM28XX_NOADECODER) { - route.input = dev->ctl_ainput; - route.output = dev->ctl_aoutput; - em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, - &route); - } - em28xx_audio_analog_set(dev); } @@ -570,7 +557,7 @@ static int res_get(struct em28xx_fh *fh) static int res_check(struct em28xx_fh *fh) { - return fh->stream_on; + return (fh->stream_on); } static void res_free(struct em28xx_fh *fh) @@ -804,7 +791,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, return rc; } -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm) { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; @@ -1021,13 +1008,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, if (dev->board.has_msp34xx) em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl); - else { + else rc = em28xx_get_ctrl(dev, ctrl); - if (rc < 0) { - em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl); - rc = 0; - } - } mutex_unlock(&dev->lock); return rc; @@ -1363,7 +1345,7 @@ static int vidioc_querycap(struct file *file, void *priv, strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); - usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); + strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); cap->version = EM28XX_VERSION_CODE; @@ -1449,7 +1431,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, if (rc < 0) return rc; - return videobuf_reqbufs(&fh->vb_vidq, rb); + return (videobuf_reqbufs(&fh->vb_vidq, rb)); } static int vidioc_querybuf(struct file *file, void *priv, @@ -1463,7 +1445,7 @@ static int vidioc_querybuf(struct file *file, void *priv, if (rc < 0) return rc; - return videobuf_querybuf(&fh->vb_vidq, b); + return (videobuf_querybuf(&fh->vb_vidq, b)); } static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) @@ -1476,7 +1458,7 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) if (rc < 0) return rc; - return videobuf_qbuf(&fh->vb_vidq, b); + return (videobuf_qbuf(&fh->vb_vidq, b)); } static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) @@ -1489,7 +1471,8 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) if (rc < 0) return rc; - return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); + return (videobuf_dqbuf(&fh->vb_vidq, b, + file->f_flags & O_NONBLOCK)); } #ifdef CONFIG_VIDEO_V4L1_COMPAT @@ -1513,7 +1496,7 @@ static int radio_querycap(struct file *file, void *priv, strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); - usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); + strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); cap->version = EM28XX_VERSION_CODE; cap->capabilities = V4L2_CAP_TUNER; @@ -1798,7 +1781,7 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count, * em28xx_v4l2_poll() * will allocate buffers when called for the first time */ -static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait) +static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait) { struct em28xx_fh *fh = filp->private_data; struct em28xx *dev = fh->dev; @@ -1951,8 +1934,8 @@ static struct video_device em28xx_radio_template = { static struct video_device *em28xx_vdev_init(struct em28xx *dev, - const struct video_device *template, - const char *type_name) + const struct video_device *template, + const char *type_name) { struct video_device *vfd; @@ -2001,9 +1984,8 @@ int em28xx_register_analog_devices(struct em28xx *dev) /* enable vbi capturing */ /* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */ - val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK); - em28xx_write_reg(dev, EM28XX_R0F_XCLK, - (EM28XX_XCLK_AUDIO_UNMUTE | val)); + val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK); + em28xx_write_reg(dev, EM28XX_R0F_XCLK, (EM28XX_XCLK_AUDIO_UNMUTE | val)); em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51); em28xx_set_outfmt(dev); @@ -2038,8 +2020,7 @@ int em28xx_register_analog_devices(struct em28xx *dev) } if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { - dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, - "radio"); + dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio"); if (!dev->radio_dev) { em28xx_errdev("cannot allocate video_device.\n"); return -ENODEV; diff --git a/trunk/drivers/media/video/em28xx/em28xx.h b/trunk/drivers/media/video/em28xx/em28xx.h index a33a58da016e..dd2cd36fb1bb 100644 --- a/trunk/drivers/media/video/em28xx/em28xx.h +++ b/trunk/drivers/media/video/em28xx/em28xx.h @@ -70,6 +70,7 @@ #define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30 #define EM2821_BOARD_USBGEAR_VD204 31 #define EM2821_BOARD_SUPERCOMP_USB_2 32 +#define EM2821_BOARD_PROLINK_PLAYTV_USB2 33 #define EM2860_BOARD_TERRATEC_HYBRID_XS 34 #define EM2860_BOARD_TYPHOON_DVD_MAKER 35 #define EM2860_BOARD_NETGMBH_CAM 36 @@ -97,10 +98,6 @@ #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58 #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60 #define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61 -#define EM2820_BOARD_GADMEI_TVR200 62 -#define EM2860_BOARD_KAIOMY_TVNPC_U2 63 -#define EM2860_BOARD_EASYCAP 64 -#define EM2820_BOARD_IODATA_GVMVP_SZ 65 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 @@ -113,10 +110,6 @@ #define EM28XX_BOARD_NOT_VALIDATED 1 #define EM28XX_BOARD_VALIDATED 0 -/* Params for em28xx_cmd() audio */ -#define EM28XX_START_AUDIO 1 -#define EM28XX_STOP_AUDIO 0 - /* maximum number of em28xx boards */ #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ @@ -161,8 +154,7 @@ */ /* time to wait when stopping the isoc transfer */ -#define EM28XX_URB_TIMEOUT \ - msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS) +#define EM28XX_URB_TIMEOUT msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS) /* time in msecs to wait for i2c writes to finish */ #define EM2800_I2C_WRITE_TIMEOUT 20 @@ -356,11 +348,6 @@ enum em28xx_decoder { EM28XX_SAA711X, }; -enum em28xx_adecoder { - EM28XX_NOADECODER = 0, - EM28XX_TVAUDIO, -}; - struct em28xx_board { char *name; int vchannels; @@ -374,7 +361,6 @@ struct em28xx_board { struct em28xx_reg_seq *dvb_gpio; struct em28xx_reg_seq *suspend_gpio; struct em28xx_reg_seq *tuner_gpio; - struct em28xx_reg_seq *mute_gpio; unsigned int is_em2800:1; unsigned int has_msp34xx:1; @@ -387,7 +373,6 @@ struct em28xx_board { unsigned char xclk, i2c_speed; enum em28xx_decoder decoder; - enum em28xx_adecoder adecoder; struct em28xx_input input[MAX_EM28XX_INPUT]; struct em28xx_input radio; @@ -435,7 +420,7 @@ struct em28xx_audio { unsigned int hwptr_done_capture; struct snd_card *sndcard; - int users; + int users, shutdown; enum em28xx_stream_state capture_stream; spinlock_t slock; }; @@ -538,8 +523,7 @@ struct em28xx { int num_alt; /* Number of alternative settings */ unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */ - char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc - transfer */ + char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */ char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */ /* helper funcs that call usb_control_msg */ diff --git a/trunk/drivers/media/video/gspca/Kconfig b/trunk/drivers/media/video/gspca/Kconfig index 578dc4ffc965..ee6a691dff22 100644 --- a/trunk/drivers/media/video/gspca/Kconfig +++ b/trunk/drivers/media/video/gspca/Kconfig @@ -56,15 +56,6 @@ config USB_GSPCA_MARS To compile this driver as a module, choose M here: the module will be called gspca_mars. -config USB_GSPCA_MR97310A - tristate "Mars-Semi MR97310A USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the MR97310A chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_mr97310a. - config USB_GSPCA_OV519 tristate "OV519 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA @@ -176,24 +167,6 @@ config USB_GSPCA_SPCA561 To compile this driver as a module, choose M here: the module will be called gspca_spca561. -config USB_GSPCA_SQ905 - tristate "SQ Technologies SQ905 based USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SQ905 chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_sq905. - -config USB_GSPCA_SQ905C - tristate "SQ Technologies SQ905C based USB Camera Driver" - depends on VIDEO_V4L2 && USB_GSPCA - help - Say Y here if you want support for cameras based on the SQ905C chip. - - To compile this driver as a module, choose M here: the - module will be called gspca_sq905c. - config USB_GSPCA_STK014 tristate "Syntek DV4000 (STK014) USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA diff --git a/trunk/drivers/media/video/gspca/Makefile b/trunk/drivers/media/video/gspca/Makefile index 8a6643e8eb96..bd8d9ee40504 100644 --- a/trunk/drivers/media/video/gspca/Makefile +++ b/trunk/drivers/media/video/gspca/Makefile @@ -1,56 +1,50 @@ -obj-$(CONFIG_USB_GSPCA) += gspca_main.o -obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o -obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o -obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o -obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o -obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o -obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o -obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o -obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o -obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o -obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o -obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o -obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o -obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o -obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o -obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o -obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o -obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o -obj-$(CONFIG_USB_GSPCA_SQ905) += gspca_sq905.o -obj-$(CONFIG_USB_GSPCA_SQ905C) += gspca_sq905c.o -obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o -obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o -obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o -obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o -obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o -obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o +obj-$(CONFIG_USB_GSPCA) += gspca_main.o +obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o +obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o +obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o +obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o +obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o +obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o +obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o +obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o +obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o +obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o +obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o +obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o +obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o +obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o +obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o +obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o +obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o +obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o +obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o +obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o +obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o +obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o -gspca_main-objs := gspca.o -gspca_conex-objs := conex.o -gspca_etoms-objs := etoms.o -gspca_finepix-objs := finepix.o -gspca_mars-objs := mars.o -gspca_mr97310a-objs := mr97310a.o -gspca_ov519-objs := ov519.o -gspca_ov534-objs := ov534.o -gspca_pac207-objs := pac207.o -gspca_pac7311-objs := pac7311.o -gspca_sonixb-objs := sonixb.o -gspca_sonixj-objs := sonixj.o -gspca_spca500-objs := spca500.o -gspca_spca501-objs := spca501.o -gspca_spca505-objs := spca505.o -gspca_spca506-objs := spca506.o -gspca_spca508-objs := spca508.o -gspca_spca561-objs := spca561.o -gspca_sq905-objs := sq905.o -gspca_sq905c-objs := sq905c.o -gspca_stk014-objs := stk014.o -gspca_sunplus-objs := sunplus.o -gspca_t613-objs := t613.o -gspca_tv8532-objs := tv8532.o -gspca_vc032x-objs := vc032x.o -gspca_zc3xx-objs := zc3xx.o +gspca_main-objs := gspca.o +gspca_conex-objs := conex.o +gspca_etoms-objs := etoms.o +gspca_finepix-objs := finepix.o +gspca_mars-objs := mars.o +gspca_ov519-objs := ov519.o +gspca_ov534-objs := ov534.o +gspca_pac207-objs := pac207.o +gspca_pac7311-objs := pac7311.o +gspca_sonixb-objs := sonixb.o +gspca_sonixj-objs := sonixj.o +gspca_spca500-objs := spca500.o +gspca_spca501-objs := spca501.o +gspca_spca505-objs := spca505.o +gspca_spca506-objs := spca506.o +gspca_spca508-objs := spca508.o +gspca_spca561-objs := spca561.o +gspca_stk014-objs := stk014.o +gspca_sunplus-objs := sunplus.o +gspca_t613-objs := t613.o +gspca_tv8532-objs := tv8532.o +gspca_vc032x-objs := vc032x.o +gspca_zc3xx-objs := zc3xx.o -obj-$(CONFIG_USB_M5602) += m5602/ -obj-$(CONFIG_USB_STV06XX) += stv06xx/ +obj-$(CONFIG_USB_M5602) += m5602/ +obj-$(CONFIG_USB_STV06XX) += stv06xx/ diff --git a/trunk/drivers/media/video/gspca/conex.c b/trunk/drivers/media/video/gspca/conex.c index 219cfa6fb877..1753f5bb3544 100644 --- a/trunk/drivers/media/video/gspca/conex.c +++ b/trunk/drivers/media/video/gspca/conex.c @@ -36,12 +36,8 @@ struct sd { unsigned char brightness; unsigned char contrast; unsigned char colors; - u8 quality; -#define QUALITY_MIN 30 -#define QUALITY_MAX 60 -#define QUALITY_DEF 40 - u8 *jpeg_hdr; + unsigned char qindex; }; /* V4L2 controls supported by the driver */ @@ -819,13 +815,14 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; + cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + sd->qindex = 0; /* set the quantization */ sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; - sd->quality = QUALITY_DEF; return 0; } @@ -842,14 +839,6 @@ static int sd_init(struct gspca_dev *gspca_dev) static int sd_start(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; - - /* create the JPEG header */ - sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x22); /* JPEG 411 */ - jpeg_set_qual(sd->jpeg_hdr, sd->quality); - cx11646_initsize(gspca_dev); cx11646_fw(gspca_dev); cx_sensor(gspca_dev); @@ -860,11 +849,8 @@ static int sd_start(struct gspca_dev *gspca_dev) /* called on streamoff with alt 0 and on disconnect */ static void sd_stop0(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; int retry = 50; - kfree(sd->jpeg_hdr); - if (!gspca_dev->present) return; reg_w_val(gspca_dev, 0x0000, 0x00); @@ -890,8 +876,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, __u8 *data, /* isoc packet */ int len) /* iso packet length */ { - struct sd *sd = (struct sd *) gspca_dev; - if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */ @@ -899,8 +883,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, data, 0); /* put the JPEG header in the new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - sd->jpeg_hdr, JPEG_HDR_SZ); + jpeg_put_header(gspca_dev, frame, + ((struct sd *) gspca_dev)->qindex, + 0x22); data += 2; len -= 2; } @@ -1003,34 +988,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -static int sd_set_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (jcomp->quality < QUALITY_MIN) - sd->quality = QUALITY_MIN; - else if (jcomp->quality > QUALITY_MAX) - sd->quality = QUALITY_MAX; - else - sd->quality = jcomp->quality; - if (gspca_dev->streaming) - jpeg_set_qual(sd->jpeg_hdr, sd->quality); - return 0; -} - -static int sd_get_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - memset(jcomp, 0, sizeof *jcomp); - jcomp->quality = sd->quality; - jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT - | V4L2_JPEG_MARKER_DQT; - return 0; -} - /* sub-driver description */ static struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -1041,8 +998,6 @@ static struct sd_desc sd_desc = { .start = sd_start, .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan, - .get_jcomp = sd_get_jcomp, - .set_jcomp = sd_set_jcomp, }; /* -- module initialisation -- */ @@ -1074,10 +1029,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/etoms.c b/trunk/drivers/media/video/gspca/etoms.c index 2c20d06a03e8..f3cd8ff5cc92 100644 --- a/trunk/drivers/media/video/gspca/etoms.c +++ b/trunk/drivers/media/video/gspca/etoms.c @@ -472,6 +472,19 @@ static void setbrightness(struct gspca_dev *gspca_dev) reg_w_val(gspca_dev, ET_O_RED + i, brightness); } +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i; + int brightness = 0; + + for (i = 0; i < 4; i++) { + reg_r(gspca_dev, ET_O_RED + i, 1); + brightness += gspca_dev->usb_buf[0]; + } + sd->brightness = brightness >> 3; +} + static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -482,6 +495,19 @@ static void setcontrast(struct gspca_dev *gspca_dev) reg_w(gspca_dev, ET_G_RED, RGBG, 6); } +static void getcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i; + int contrast = 0; + + for (i = 0; i < 4; i++) { + reg_r(gspca_dev, ET_G_RED + i, 1); + contrast += gspca_dev->usb_buf[0]; + } + sd->contrast = contrast >> 2; +} + static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -632,6 +658,7 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; + cam->epaddr = 1; sd->sensor = id->driver_info; if (sd->sensor == SENSOR_PAS106) { cam->cam_mode = sif_mode; @@ -794,6 +821,7 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getbrightness(gspca_dev); *val = sd->brightness; return 0; } @@ -812,6 +840,7 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getcontrast(gspca_dev); *val = sd->contrast; return 0; } @@ -830,6 +859,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getcolors(gspca_dev); *val = sd->colors; return 0; } @@ -898,10 +928,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/finepix.c b/trunk/drivers/media/video/gspca/finepix.c index 00e6863ed666..afc8b2dd307b 100644 --- a/trunk/drivers/media/video/gspca/finepix.c +++ b/trunk/drivers/media/video/gspca/finepix.c @@ -27,7 +27,7 @@ MODULE_DESCRIPTION("Fujifilm FinePix USB V4L2 driver"); MODULE_LICENSE("GPL"); /* Default timeout, in ms */ -#define FPIX_TIMEOUT 250 +#define FPIX_TIMEOUT (HZ / 10) /* Maximum transfer size to use. The windows driver reads by chunks of * 0x2000 bytes, so do the same. Note: reading more seems to work @@ -38,15 +38,38 @@ MODULE_LICENSE("GPL"); struct usb_fpix { struct gspca_dev gspca_dev; /* !! must be the first item */ - struct work_struct work_struct; - struct workqueue_struct *work_thread; + /* + * USB stuff + */ + struct usb_ctrlrequest ctrlreq; + struct urb *control_urb; + struct timer_list bulk_timer; + + enum { + FPIX_NOP, /* inactive, else streaming */ + FPIX_RESET, /* must reset */ + FPIX_REQ_FRAME, /* requesting a frame */ + FPIX_READ_FRAME, /* reading frame */ + } state; + + /* + * Driver stuff + */ + struct delayed_work wqe; + struct completion can_close; + int streaming; }; /* Delay after which claim the next frame. If the delay is too small, * the camera will return old frames. On the 4800Z, 20ms is bad, 25ms - * will fail every 4 or 5 frames, but 30ms is perfect. On the A210, - * 30ms is bad while 35ms is perfect. */ -#define NEXT_FRAME_DELAY 35 + * will fail every 4 or 5 frames, but 30ms is perfect. */ +#define NEXT_FRAME_DELAY (((HZ * 30) + 999) / 1000) + +#define dev_new_state(new_state) { \ + PDEBUG(D_STREAM, "new state from %d to %d at %s:%d", \ + dev->state, new_state, __func__, __LINE__); \ + dev->state = new_state; \ +} /* These cameras only support 320x200. */ static const struct v4l2_pix_format fpix_mode[1] = { @@ -57,183 +80,316 @@ static const struct v4l2_pix_format fpix_mode[1] = { .priv = 0} }; -/* send a command to the webcam */ -static int command(struct gspca_dev *gspca_dev, - int order) /* 0: reset, 1: frame request */ +/* Reads part of a frame */ +static void read_frame_part(struct usb_fpix *dev) { - static u8 order_values[2][12] = { - {0xc6, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0}, /* reset */ - {0xd3, 0, 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0}, /* fr req */ - }; + int ret; - memcpy(gspca_dev->usb_buf, order_values[order], 12); - return usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_GET_STATUS, - USB_DIR_OUT | USB_TYPE_CLASS | - USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf, - 12, FPIX_TIMEOUT); + PDEBUG(D_STREAM, "read_frame_part"); + + /* Reads part of a frame */ + ret = usb_submit_urb(dev->gspca_dev.urb[0], GFP_ATOMIC); + if (ret) { + dev_new_state(FPIX_RESET); + schedule_delayed_work(&dev->wqe, 1); + PDEBUG(D_STREAM, "usb_submit_urb failed with %d", + ret); + } else { + /* Sometimes we never get a callback, so use a timer. + * Is this masking a bug somewhere else? */ + dev->bulk_timer.expires = jiffies + msecs_to_jiffies(150); + add_timer(&dev->bulk_timer); + } } -/* workqueue */ -static void dostream(struct work_struct *work) +/* Callback for URBs. */ +static void urb_callback(struct urb *urb) { - struct usb_fpix *dev = container_of(work, struct usb_fpix, work_struct); - struct gspca_dev *gspca_dev = &dev->gspca_dev; - struct urb *urb = gspca_dev->urb[0]; - u8 *data = urb->transfer_buffer; - struct gspca_frame *frame; - int ret = 0; - int len; - - /* synchronize with the main driver */ - mutex_lock(&gspca_dev->usb_lock); - mutex_unlock(&gspca_dev->usb_lock); - PDEBUG(D_STREAM, "dostream started"); - - /* loop reading a frame */ -again: - while (gspca_dev->present && gspca_dev->streaming) { - - /* request a frame */ - mutex_lock(&gspca_dev->usb_lock); - ret = command(gspca_dev, 1); - mutex_unlock(&gspca_dev->usb_lock); - if (ret < 0) - break; - if (!gspca_dev->present || !gspca_dev->streaming) - break; - - /* the frame comes in parts */ - for (;;) { - ret = usb_bulk_msg(gspca_dev->dev, - urb->pipe, - data, - FPIX_MAX_TRANSFER, - &len, FPIX_TIMEOUT); - if (ret < 0) { - /* Most of the time we get a timeout - * error. Just restart. */ - goto again; - } - if (!gspca_dev->present || !gspca_dev->streaming) - goto out; - frame = gspca_get_i_frame(&dev->gspca_dev); - if (frame == NULL) - gspca_dev->last_packet_type = DISCARD_PACKET; - - if (len < FPIX_MAX_TRANSFER || - (data[len - 2] == 0xff && - data[len - 1] == 0xd9)) { - - /* If the result is less than what was asked - * for, then it's the end of the - * frame. Sometimes the jpeg is not complete, - * but there's nothing we can do. We also end - * here if the the jpeg ends right at the end - * of the frame. */ - if (frame) - frame = gspca_frame_add(gspca_dev, - LAST_PACKET, - frame, - data, len); - break; - } + struct gspca_dev *gspca_dev = urb->context; + struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; + + PDEBUG(D_PACK, + "enter urb_callback - status=%d, length=%d", + urb->status, urb->actual_length); + + if (dev->state == FPIX_READ_FRAME) + del_timer(&dev->bulk_timer); + + if (urb->status != 0) { + /* We kill a stuck urb every 50 frames on average, so don't + * display a log message for that. */ + if (urb->status != -ECONNRESET) + PDEBUG(D_STREAM, "bad URB status %d", urb->status); + dev_new_state(FPIX_RESET); + schedule_delayed_work(&dev->wqe, 1); + } + + switch (dev->state) { + case FPIX_REQ_FRAME: + dev_new_state(FPIX_READ_FRAME); + read_frame_part(dev); + break; + + case FPIX_READ_FRAME: { + unsigned char *data = urb->transfer_buffer; + struct gspca_frame *frame; + + frame = gspca_get_i_frame(&dev->gspca_dev); + if (frame == NULL) + gspca_dev->last_packet_type = DISCARD_PACKET; + if (urb->actual_length < FPIX_MAX_TRANSFER || + (data[urb->actual_length-2] == 0xff && + data[urb->actual_length-1] == 0xd9)) { + + /* If the result is less than what was asked + * for, then it's the end of the + * frame. Sometime the jpeg is not complete, + * but there's nothing we can do. We also end + * here if the the jpeg ends right at the end + * of the frame. */ + if (frame) + gspca_frame_add(gspca_dev, LAST_PACKET, + frame, + data, urb->actual_length); + dev_new_state(FPIX_REQ_FRAME); + schedule_delayed_work(&dev->wqe, NEXT_FRAME_DELAY); + } else { /* got a partial image */ if (frame) gspca_frame_add(gspca_dev, gspca_dev->last_packet_type - == LAST_PACKET + == LAST_PACKET ? FIRST_PACKET : INTER_PACKET, - frame, data, len); + frame, + data, urb->actual_length); + read_frame_part(dev); } + break; + } + + case FPIX_NOP: + case FPIX_RESET: + PDEBUG(D_STREAM, "invalid state %d", dev->state); + break; + } +} - /* We must wait before trying reading the next - * frame. If we don't, or if the delay is too short, - * the camera will disconnect. */ - msleep(NEXT_FRAME_DELAY); +/* Request a new frame */ +static void request_frame(struct usb_fpix *dev) +{ + int ret; + struct gspca_dev *gspca_dev = &dev->gspca_dev; + + /* Setup command packet */ + memset(gspca_dev->usb_buf, 0, 12); + gspca_dev->usb_buf[0] = 0xd3; + gspca_dev->usb_buf[7] = 0x01; + + /* Request a frame */ + dev->ctrlreq.bRequestType = + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; + dev->ctrlreq.bRequest = USB_REQ_GET_STATUS; + dev->ctrlreq.wValue = 0; + dev->ctrlreq.wIndex = 0; + dev->ctrlreq.wLength = cpu_to_le16(12); + + usb_fill_control_urb(dev->control_urb, + gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + (unsigned char *) &dev->ctrlreq, + gspca_dev->usb_buf, + 12, urb_callback, gspca_dev); + + ret = usb_submit_urb(dev->control_urb, GFP_ATOMIC); + if (ret) { + dev_new_state(FPIX_RESET); + schedule_delayed_work(&dev->wqe, 1); + PDEBUG(D_STREAM, "usb_submit_urb failed with %d", ret); + } +} + +/*--------------------------------------------------------------------------*/ + +/* State machine. */ +static void fpix_sm(struct work_struct *work) +{ + struct usb_fpix *dev = container_of(work, struct usb_fpix, wqe.work); + + PDEBUG(D_STREAM, "fpix_sm state %d", dev->state); + + /* verify that the device wasn't unplugged */ + if (!dev->gspca_dev.present) { + PDEBUG(D_STREAM, "device is gone"); + dev_new_state(FPIX_NOP); + complete(&dev->can_close); + return; + } + + if (!dev->streaming) { + PDEBUG(D_STREAM, "stopping state machine"); + dev_new_state(FPIX_NOP); + complete(&dev->can_close); + return; } -out: - PDEBUG(D_STREAM, "dostream stopped"); + switch (dev->state) { + case FPIX_RESET: + dev_new_state(FPIX_REQ_FRAME); + schedule_delayed_work(&dev->wqe, HZ / 10); + break; + + case FPIX_REQ_FRAME: + /* get an image */ + request_frame(dev); + break; + + case FPIX_NOP: + case FPIX_READ_FRAME: + PDEBUG(D_STREAM, "invalid state %d", dev->state); + break; + } } /* this function is called at probe time */ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) { - struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; struct cam *cam = &gspca_dev->cam; cam->cam_mode = fpix_mode; cam->nmodes = 1; + cam->epaddr = 0x01; /* todo: correct for all cams? */ cam->bulk_size = FPIX_MAX_TRANSFER; - INIT_WORK(&dev->work_struct, dostream); - +/* gspca_dev->nbalt = 1; * use bulk transfer */ return 0; } +/* Stop streaming and free the ressources allocated by sd_start. */ +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; + + dev->streaming = 0; + + /* Stop the state machine */ + if (dev->state != FPIX_NOP) + wait_for_completion(&dev->can_close); +} + +/* called on streamoff with alt 0 and disconnect */ +static void sd_stop0(struct gspca_dev *gspca_dev) +{ + struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; + + usb_free_urb(dev->control_urb); + dev->control_urb = NULL; +} + +/* Kill an URB that hasn't completed. */ +static void timeout_kill(unsigned long data) +{ + struct urb *urb = (struct urb *) data; + + usb_unlink_urb(urb); +} + /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { + struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; + + INIT_DELAYED_WORK(&dev->wqe, fpix_sm); + + init_timer(&dev->bulk_timer); + dev->bulk_timer.function = timeout_kill; + return 0; } -/* start the camera */ static int sd_start(struct gspca_dev *gspca_dev) { struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; - int ret, len; + int ret; + int size_ret; /* Init the device */ - ret = command(gspca_dev, 0); - if (ret < 0) { - PDEBUG(D_STREAM, "init failed %d", ret); - return ret; + memset(gspca_dev->usb_buf, 0, 12); + gspca_dev->usb_buf[0] = 0xc6; + gspca_dev->usb_buf[8] = 0x20; + + ret = usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + USB_REQ_GET_STATUS, + USB_DIR_OUT | USB_TYPE_CLASS | + USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf, + 12, FPIX_TIMEOUT); + + if (ret != 12) { + PDEBUG(D_STREAM, "usb_control_msg failed (%d)", ret); + ret = -EIO; + goto error; } /* Read the result of the command. Ignore the result, for it * varies with the device. */ ret = usb_bulk_msg(gspca_dev->dev, - gspca_dev->urb[0]->pipe, - gspca_dev->urb[0]->transfer_buffer, - FPIX_MAX_TRANSFER, &len, + usb_rcvbulkpipe(gspca_dev->dev, + gspca_dev->cam.epaddr), + gspca_dev->usb_buf, FPIX_MAX_TRANSFER, &size_ret, FPIX_TIMEOUT); - if (ret < 0) { - PDEBUG(D_STREAM, "usb_bulk_msg failed %d", ret); - return ret; + if (ret != 0) { + PDEBUG(D_STREAM, "usb_bulk_msg failed (%d)", ret); + ret = -EIO; + goto error; } /* Request a frame, but don't read it */ - ret = command(gspca_dev, 1); - if (ret < 0) { - PDEBUG(D_STREAM, "frame request failed %d", ret); - return ret; + memset(gspca_dev->usb_buf, 0, 12); + gspca_dev->usb_buf[0] = 0xd3; + gspca_dev->usb_buf[7] = 0x01; + + ret = usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + USB_REQ_GET_STATUS, + USB_DIR_OUT | USB_TYPE_CLASS | + USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf, + 12, FPIX_TIMEOUT); + if (ret != 12) { + PDEBUG(D_STREAM, "usb_control_msg failed (%d)", ret); + ret = -EIO; + goto error; } /* Again, reset bulk in endpoint */ - usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe); + usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr); + + /* Allocate a control URB */ + dev->control_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!dev->control_urb) { + PDEBUG(D_STREAM, "No free urbs available"); + ret = -EIO; + goto error; + } - /* Start the workqueue function to do the streaming */ - dev->work_thread = create_singlethread_workqueue(MODULE_NAME); - queue_work(dev->work_thread, &dev->work_struct); + /* Various initializations. */ + init_completion(&dev->can_close); + dev->bulk_timer.data = (unsigned long)dev->gspca_dev.urb[0]; + dev->gspca_dev.urb[0]->complete = urb_callback; + dev->streaming = 1; - return 0; -} + /* Schedule a frame request. */ + dev_new_state(FPIX_REQ_FRAME); + schedule_delayed_work(&dev->wqe, 1); -/* called on streamoff with alt==0 and on disconnect */ -/* the usb_lock is held at entry - restore on exit */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; + return 0; - /* wait for the work queue to terminate */ - mutex_unlock(&gspca_dev->usb_lock); - destroy_workqueue(dev->work_thread); - mutex_lock(&gspca_dev->usb_lock); - dev->work_thread = NULL; +error: + /* Free the ressources */ + sd_stopN(gspca_dev); + sd_stop0(gspca_dev); + return ret; } /* Table of supported USB devices */ @@ -268,11 +424,12 @@ MODULE_DEVICE_TABLE(usb, device_table); /* sub-driver description */ static const struct sd_desc sd_desc = { - .name = MODULE_NAME, + .name = MODULE_NAME, .config = sd_config, - .init = sd_init, - .start = sd_start, - .stop0 = sd_stop0, + .init = sd_init, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, }; /* -- device connect -- */ @@ -286,28 +443,24 @@ static int sd_probe(struct usb_interface *intf, } static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, .disconnect = gspca_disconnect, #ifdef CONFIG_PM .suspend = gspca_suspend, - .resume = gspca_resume, + .resume = gspca_resume, #endif }; /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } - static void __exit sd_mod_exit(void) { usb_deregister(&sd_driver); diff --git a/trunk/drivers/media/video/gspca/gspca.c b/trunk/drivers/media/video/gspca/gspca.c index a75c1ca2db41..65e4901f4db7 100644 --- a/trunk/drivers/media/video/gspca/gspca.c +++ b/trunk/drivers/media/video/gspca/gspca.c @@ -38,16 +38,15 @@ #include "gspca.h" /* global values */ -#define DEF_NURBS 3 /* default number of URBs */ -#if DEF_NURBS > MAX_NURBS -#error "DEF_NURBS too big" -#endif +#define DEF_NURBS 2 /* default number of URBs */ MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 5, 0) +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 4, 0) + +static int video_nr = -1; #ifdef GSPCA_DEBUG int gspca_debug = D_ERR | D_PROBE; @@ -127,18 +126,16 @@ static void fill_frame(struct gspca_dev *gspca_dev, struct urb *urb) { struct gspca_frame *frame; - u8 *data; /* address of data in the iso message */ + __u8 *data; /* address of data in the iso message */ int i, len, st; cam_pkt_op pkt_scan; if (urb->status != 0) { - if (urb->status == -ESHUTDOWN) - return; /* disconnection */ #ifdef CONFIG_PM if (!gspca_dev->frozen) #endif PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); - return; + return; /* disconnection ? */ } pkt_scan = gspca_dev->sd_desc->pkt_scan; for (i = 0; i < urb->number_of_packets; i++) { @@ -169,7 +166,7 @@ static void fill_frame(struct gspca_dev *gspca_dev, /* let the packet be analyzed by the subdriver */ PDEBUG(D_PACK, "packet [%d] o:%d l:%d", i, urb->iso_frame_desc[i].offset, len); - data = (u8 *) urb->transfer_buffer + data = (__u8 *) urb->transfer_buffer + urb->iso_frame_desc[i].offset; pkt_scan(gspca_dev, frame, data, len); } @@ -185,7 +182,8 @@ static void fill_frame(struct gspca_dev *gspca_dev, * * Analyse each packet and call the subdriver for copy to the frame buffer. */ -static void isoc_irq(struct urb *urb) +static void isoc_irq(struct urb *urb +) { struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; @@ -198,7 +196,8 @@ static void isoc_irq(struct urb *urb) /* * bulk message interrupt from the USB device */ -static void bulk_irq(struct urb *urb) +static void bulk_irq(struct urb *urb +) { struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; struct gspca_frame *frame; @@ -210,8 +209,6 @@ static void bulk_irq(struct urb *urb) switch (urb->status) { case 0: break; - case -ESHUTDOWN: - return; /* disconnection */ case -ECONNRESET: urb->status = 0; break; @@ -220,7 +217,7 @@ static void bulk_irq(struct urb *urb) if (!gspca_dev->frozen) #endif PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); - return; + return; /* disconnection ? */ } /* check the availability of the frame buffer */ @@ -325,7 +322,6 @@ static int gspca_is_compressed(__u32 format) case V4L2_PIX_FMT_JPEG: case V4L2_PIX_FMT_SPCA561: case V4L2_PIX_FMT_PAC207: - case V4L2_PIX_FMT_MR97310A: return 1; } return 0; @@ -426,8 +422,10 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) if (urb == NULL) break; + BUG_ON(!gspca_dev->dev); gspca_dev->urb[i] = NULL; - usb_kill_urb(urb); + if (!gspca_dev->present) + usb_kill_urb(urb); if (urb->transfer_buffer != NULL) usb_buffer_free(gspca_dev->dev, urb->transfer_buffer_length, @@ -441,16 +439,22 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) * look for an input transfer endpoint in an alternate setting */ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt, + __u8 epaddr, __u8 xfer) { struct usb_host_endpoint *ep; int i, attr; + epaddr |= USB_DIR_IN; for (i = 0; i < alt->desc.bNumEndpoints; i++) { ep = &alt->endpoint[i]; - attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; - if (attr == xfer) - return ep; + if (ep->desc.bEndpointAddress == epaddr) { + attr = ep->desc.bmAttributes + & USB_ENDPOINT_XFERTYPE_MASK; + if (attr == xfer) + return ep; + break; + } } return NULL; } @@ -474,23 +478,23 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev) i = gspca_dev->alt; /* previous alt setting */ /* try isoc */ - while (--i >= 0) { + while (--i > 0) { /* alt 0 is unusable */ ep = alt_xfer(&intf->altsetting[i], + gspca_dev->cam.epaddr, USB_ENDPOINT_XFER_ISOC); if (ep) break; } - /* if no isoc, try bulk (alt 0 only) */ + /* if no isoc, try bulk */ if (ep == NULL) { ep = alt_xfer(&intf->altsetting[0], + gspca_dev->cam.epaddr, USB_ENDPOINT_XFER_BULK); if (ep == NULL) { err("no transfer endpoint found"); return NULL; } - i = 0; - gspca_dev->bulk = 1; } PDEBUG(D_STREAM, "use alt %d ep 0x%02x", i, ep->desc.bEndpointAddress); @@ -517,7 +521,7 @@ static int create_urbs(struct gspca_dev *gspca_dev, /* calculate the packet size and the number of packets */ psize = le16_to_cpu(ep->desc.wMaxPacketSize); - if (!gspca_dev->bulk) { /* isoc */ + if (gspca_dev->alt != 0) { /* isoc */ /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); @@ -597,11 +601,6 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - if (!gspca_dev->present) { - ret = -ENODEV; - goto out; - } - /* set the higher alternate setting and * loop until urb submit succeeds */ gspca_dev->alt = gspca_dev->nbalt; @@ -617,9 +616,10 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) goto out; /* clear the bulk endpoint */ - if (gspca_dev->bulk) + if (gspca_dev->alt == 0) /* if bulk transfer */ usb_clear_halt(gspca_dev->dev, - gspca_dev->urb[0]->pipe); + usb_rcvintpipe(gspca_dev->dev, + gspca_dev->cam.epaddr)); /* start the cam */ ret = gspca_dev->sd_desc->start(gspca_dev); @@ -630,7 +630,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) gspca_dev->streaming = 1; /* some bulk transfers are started by the subdriver */ - if (gspca_dev->bulk && gspca_dev->cam.bulk_nurbs == 0) + if (gspca_dev->alt == 0 && gspca_dev->cam.bulk_nurbs == 0) break; /* submit the URBs */ @@ -671,14 +671,11 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev) static void gspca_stream_off(struct gspca_dev *gspca_dev) { gspca_dev->streaming = 0; - if (gspca_dev->present) { - if (gspca_dev->sd_desc->stopN) - gspca_dev->sd_desc->stopN(gspca_dev); - destroy_urbs(gspca_dev); - gspca_set_alt0(gspca_dev); - } - - /* always call stop0 to free the subdriver's resources */ + if (gspca_dev->present + && gspca_dev->sd_desc->stopN) + gspca_dev->sd_desc->stopN(gspca_dev); + destroy_urbs(gspca_dev); + gspca_set_alt0(gspca_dev); if (gspca_dev->sd_desc->stop0) gspca_dev->sd_desc->stop0(gspca_dev); PDEBUG(D_STREAM, "stream off OK"); @@ -765,6 +762,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, fmtdesc->pixelformat = fmt_tb[index]; if (gspca_is_compressed(fmt_tb[index])) fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; + fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmtdesc->description[0] = fmtdesc->pixelformat & 0xff; fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff; fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff; @@ -959,15 +957,8 @@ static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { struct gspca_dev *gspca_dev = priv; - int ret; - /* protect the access to the usb device */ - if (mutex_lock_interruptible(&gspca_dev->usb_lock)) - return -ERESTARTSYS; - if (!gspca_dev->present) { - ret = -ENODEV; - goto out; - } + memset(cap, 0, sizeof *cap); strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver); if (gspca_dev->dev->product != NULL) { strncpy(cap->card, gspca_dev->dev->product, @@ -978,15 +969,13 @@ static int vidioc_querycap(struct file *file, void *priv, le16_to_cpu(gspca_dev->dev->descriptor.idVendor), le16_to_cpu(gspca_dev->dev->descriptor.idProduct)); } - usb_make_path(gspca_dev->dev, cap->bus_info, sizeof(cap->bus_info)); + strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name, + sizeof cap->bus_info); cap->version = DRIVER_VERSION_NUMBER; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; - ret = 0; -out: - mutex_unlock(&gspca_dev->usb_lock); - return ret; + return 0; } static int vidioc_queryctrl(struct file *file, void *priv, @@ -1049,10 +1038,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - if (gspca_dev->present) - ret = ctrls->set(gspca_dev, ctrl->value); - else - ret = -ENODEV; + ret = ctrls->set(gspca_dev, ctrl->value); mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1076,10 +1062,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - if (gspca_dev->present) - ret = ctrls->get(gspca_dev, &ctrl->value); - else - ret = -ENODEV; + ret = ctrls->get(gspca_dev, &ctrl->value); mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1098,6 +1081,7 @@ static int vidioc_s_audio(struct file *file, void *priv, static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *audio) { + memset(audio, 0, sizeof *audio); strcpy(audio->name, "Microphone"); return 0; } @@ -1131,6 +1115,7 @@ static int vidioc_enum_input(struct file *file, void *priv, if (input->index != 0) return -EINVAL; + memset(input, 0, sizeof *input); input->type = V4L2_INPUT_TYPE_CAMERA; strncpy(input->name, gspca_dev->sd_desc->name, sizeof input->name); @@ -1239,7 +1224,10 @@ static int vidioc_streamon(struct file *file, void *priv, return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; - + if (!gspca_dev->present) { + ret = -ENODEV; + goto out; + } if (gspca_dev->nframes == 0 || !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) { ret = -EINVAL; @@ -1307,10 +1295,7 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv, return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - if (gspca_dev->present) - ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); - else - ret = -ENODEV; + ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1325,10 +1310,7 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - if (gspca_dev->present) - ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); - else - ret = -ENODEV; + ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1338,6 +1320,8 @@ static int vidioc_g_parm(struct file *filp, void *priv, { struct gspca_dev *gspca_dev = priv; + memset(parm, 0, sizeof *parm); + parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; parm->parm.capture.readbuffers = gspca_dev->nbufread; if (gspca_dev->sd_desc->get_streamparm) { @@ -1345,11 +1329,7 @@ static int vidioc_g_parm(struct file *filp, void *priv, if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - if (gspca_dev->present) - ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, - parm); - else - ret = -ENODEV; + ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, parm); mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1374,11 +1354,7 @@ static int vidioc_s_parm(struct file *filp, void *priv, if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - if (gspca_dev->present) - ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, - parm); - else - ret = -ENODEV; + ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, parm); mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1406,6 +1382,7 @@ static int vidiocgmbuf(struct file *file, void *priv, { struct v4l2_format fmt; + memset(&fmt, 0, sizeof fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; i = gspca_dev->cam.nmodes - 1; /* highest mode */ fmt.fmt.pix.width = gspca_dev->cam.cam_mode[i].width; @@ -1551,8 +1528,7 @@ static int frame_wait(struct gspca_dev *gspca_dev, if (gspca_dev->sd_desc->dq_callback) { mutex_lock(&gspca_dev->usb_lock); - if (gspca_dev->present) - gspca_dev->sd_desc->dq_callback(gspca_dev); + gspca_dev->sd_desc->dq_callback(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); } return j; @@ -1574,9 +1550,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, if (v4l2_buf->memory != gspca_dev->memory) return -EINVAL; - if (!gspca_dev->present) - return -ENODEV; - /* if not streaming, be sure the application will not loop forever */ if (!(file->f_flags & O_NONBLOCK) && !gspca_dev->streaming && gspca_dev->users == 1) @@ -1727,6 +1700,8 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) PDEBUG(D_FRAM, "poll"); poll_wait(file, &gspca_dev->wq, wait); + if (!gspca_dev->present) + return POLLERR; /* if reqbufs is not done, the user would use read() */ if (gspca_dev->nframes == 0) { @@ -1739,6 +1714,10 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) return POLLERR; + if (!gspca_dev->present) { + ret = POLLERR; + goto out; + } /* check the next incoming buffer */ i = gspca_dev->fr_o; @@ -1747,9 +1726,8 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) ret = POLLIN | POLLRDNORM; /* something to read */ else ret = 0; +out: mutex_unlock(&gspca_dev->queue_lock); - if (!gspca_dev->present) - return POLLHUP; return ret; } @@ -1947,7 +1925,7 @@ int gspca_dev_probe(struct usb_interface *intf, gspca_dev->present = 1; ret = video_register_device(&gspca_dev->vdev, VFL_TYPE_GRABBER, - -1); + video_nr); if (ret < 0) { err("video_register_device err %d", ret); goto out; @@ -1975,16 +1953,10 @@ void gspca_disconnect(struct usb_interface *intf) mutex_lock(&gspca_dev->usb_lock); gspca_dev->present = 0; - - if (gspca_dev->streaming) { - destroy_urbs(gspca_dev); - wake_up_interruptible(&gspca_dev->wq); - } - - /* the device is freed at exit of this function */ - gspca_dev->dev = NULL; mutex_unlock(&gspca_dev->usb_lock); + destroy_urbs(gspca_dev); + gspca_dev->dev = NULL; usb_set_intfdata(intf, NULL); /* release the device */ diff --git a/trunk/drivers/media/video/gspca/gspca.h b/trunk/drivers/media/video/gspca/gspca.h index e4d4cf6ce05a..c90af9cb1e07 100644 --- a/trunk/drivers/media/video/gspca/gspca.h +++ b/trunk/drivers/media/video/gspca/gspca.h @@ -33,13 +33,19 @@ extern int gspca_debug; #endif #undef err #define err(fmt, args...) \ - printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args) + do {\ + printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args); \ + } while (0) #undef info #define info(fmt, args...) \ - printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args) + do {\ + printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \ + } while (0) #undef warn #define warn(fmt, args...) \ - printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args) + do {\ + printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args); \ + } while (0) #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ /* image transfers */ @@ -56,6 +62,7 @@ struct cam { * - cannot be > MAX_NURBS * - when 0 and bulk_size != 0 means * 1 URB and submit done by subdriver */ + __u8 epaddr; }; struct gspca_dev; @@ -167,7 +174,6 @@ struct gspca_dev { __u8 iface; /* USB interface number */ __u8 alt; /* USB alternate setting */ __u8 nbalt; /* number of USB alternate settings */ - u8 bulk; /* image transfer by 0:isoc / 1:bulk */ }; int gspca_dev_probe(struct usb_interface *intf, diff --git a/trunk/drivers/media/video/gspca/jpeg.h b/trunk/drivers/media/video/gspca/jpeg.h index de63c36806c0..d823b47bd4e6 100644 --- a/trunk/drivers/media/video/gspca/jpeg.h +++ b/trunk/drivers/media/video/gspca/jpeg.h @@ -24,39 +24,171 @@ * */ -/* - * generation options - * CONEX_CAM Conexant if present - */ - -/* JPEG header */ -static const u8 jpeg_head[] = { +/* start of jpeg frame + quantization table */ +static const unsigned char quant[][0x88] = { +/* index 0 - Q40*/ + { 0xff, 0xd8, /* jpeg */ - -/* quantization table quality 50% */ + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, /* quantization table part 1 */ + 20, 14, 15, 18, 15, 13, 20, 18, 16, 18, 23, 21, 20, 24, 30, 50, + 33, 30, 28, 28, 30, 61, 44, 46, 36, 50, 73, 64, 76, 75, 71, 64, + 70, 69, 80, 90, 115, 98, 80, 85, 109, 86, 69, 70, 100, 136, 101, + 109, + 119, 123, 129, 130, 129, 78, 96, 141, 151, 140, 125, 150, 115, + 126, 129, 124, +1, /* quantization table part 2 */ + 21, 23, 23, 30, 26, 30, 59, 33, 33, 59, 124, 83, 70, 83, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124}, +/* index 1 - Q50 */ + { + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40, + 26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61, 60, 57, 51, + 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80, 109, 81, 87, + 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101, + 103, 99, +1, + 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}, +/* index 2 Q60 */ + { + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 13, 9, 10, 11, 10, 8, 13, 11, 10, 11, 14, 14, 13, 15, 19, 32, + 21, 19, 18, 18, 19, 39, 28, 30, 23, 32, 46, 41, 49, 48, 46, 41, + 45, 44, 51, 58, 74, 62, 51, 54, 70, 55, 44, 45, 64, 87, 65, 70, + 76, 78, 82, 83, 82, 50, 62, 90, 97, 90, 80, 96, 74, 81, 82, 79, +1, + 14, 14, 14, 19, 17, 19, 38, 21, 21, 38, 79, 53, 45, 53, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79}, +/* index 3 - Q70 */ + { + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 10, 7, 7, 8, 7, 6, 10, 8, 8, 8, 11, 10, 10, 11, 14, 24, + 16, 14, 13, 13, 14, 29, 21, 22, 17, 24, 35, 31, 37, 36, 34, 31, + 34, 33, 38, 43, 55, 47, 38, 41, 52, 41, 33, 34, 48, 65, 49, 52, + 57, 59, 62, 62, 62, 37, 46, 68, 73, 67, 60, 72, 55, 61, 62, 59, +1, + 10, 11, 11, 14, 13, 14, 28, 16, 16, 28, 59, 40, 34, 40, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59}, +/* index 4 - Q80 */ + { + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 6, 4, 5, 6, 5, 4, 6, 6, 5, 6, 7, 7, 6, 8, 10, 16, + 10, 10, 9, 9, 10, 20, 14, 15, 12, 16, 23, 20, 24, 24, 23, 20, + 22, 22, 26, 29, 37, 31, 26, 27, 35, 28, 22, 22, 32, 44, 32, 35, + 38, 39, 41, 42, 41, 25, 31, 45, 48, 45, 40, 48, 37, 40, 41, 40, +1, + 7, 7, 7, 10, 8, 10, 19, 10, 10, 19, 40, 26, 22, 26, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}, +/* index 5 - Q85 */ + { + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 5, 3, 4, 4, 4, 3, 5, 4, 4, 4, 5, 5, 5, 6, 7, 12, + 8, 7, 7, 7, 7, 15, 11, 11, 9, 12, 17, 15, 18, 18, 17, 15, + 17, 17, 19, 22, 28, 23, 19, 20, 26, 21, 17, 17, 24, 33, 24, 26, + 29, 29, 31, 31, 31, 19, 23, 34, 36, 34, 30, 36, 28, 30, 31, 30, +1, + 5, 5, 5, 7, 6, 7, 14, 8, 8, 14, 30, 20, 17, 20, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, +/* index 6 - 86 */ +{ + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 0x04, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x04, + 0x04, 0x04, 0x05, 0x05, 0x04, 0x05, 0x07, 0x0B, + 0x07, 0x07, 0x06, 0x06, 0x07, 0x0E, 0x0A, 0x0A, + 0x08, 0x0B, 0x10, 0x0E, 0x11, 0x11, 0x10, 0x0E, + 0x10, 0x0F, 0x12, 0x14, 0x1A, 0x16, 0x12, 0x13, + 0x18, 0x13, 0x0F, 0x10, 0x16, 0x1F, 0x17, 0x18, + 0x1B, 0x1B, 0x1D, 0x1D, 0x1D, 0x11, 0x16, 0x20, + 0x22, 0x1F, 0x1C, 0x22, 0x1A, 0x1C, 0x1D, 0x1C, +1, + 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0D, 0x07, + 0x07, 0x0D, 0x1C, 0x12, 0x10, 0x12, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + }, +/* index 7 - 88 */ +{ + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, /* DQT */ 0, -#define JPEG_QT0_OFFSET 7 - 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, - 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, - 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, - 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, - 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44, - 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, - 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, - 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63, + 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x04, 0x03, + 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x06, 0x0A, + 0x06, 0x06, 0x05, 0x05, 0x06, 0x0C, 0x08, 0x09, + 0x07, 0x0A, 0x0E, 0x0C, 0x0F, 0x0E, 0x0E, 0x0C, + 0x0D, 0x0D, 0x0F, 0x11, 0x16, 0x13, 0x0F, 0x10, + 0x15, 0x11, 0x0D, 0x0D, 0x13, 0x1A, 0x13, 0x15, + 0x17, 0x18, 0x19, 0x19, 0x19, 0x0F, 0x12, 0x1B, + 0x1D, 0x1B, 0x18, 0x1D, 0x16, 0x18, 0x19, 0x18, 1, -#define JPEG_QT1_OFFSET 72 - 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x04, 0x04, 0x04, 0x06, 0x05, 0x06, 0x0B, 0x06, + 0x06, 0x0B, 0x18, 0x10, 0x0D, 0x10, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +}, +/* index 8 - ?? */ +{ + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x05, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x05, + 0x04, 0x05, 0x07, 0x06, 0x08, 0x08, 0x07, 0x06, + 0x07, 0x07, 0x08, 0x09, 0x0C, 0x0A, 0x08, 0x09, + 0x0B, 0x09, 0x07, 0x07, 0x0A, 0x0E, 0x0A, 0x0B, + 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x08, 0x0A, 0x0E, + 0x0F, 0x0E, 0x0D, 0x0F, 0x0C, 0x0D, 0x0D, 0x0C, +1, + 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x06, 0x03, + 0x03, 0x06, 0x0C, 0x08, 0x07, 0x08, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C +} +}; -/* huffman table */ +/* huffman table + start of SOF0 */ +static unsigned char huffman[] = { 0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -112,57 +244,58 @@ static const u8 jpeg_head[] = { 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, #ifdef CONEX_CAM /* the Conexant frames start with SOF0 */ -#define JPEG_HDR_SZ 556 #else 0xff, 0xc0, 0x00, 0x11, /* SOF0 (start of frame 0 */ 0x08, /* data precision */ -#define JPEG_HEIGHT_OFFSET 561 - 0x01, 0xe0, /* height */ - 0x02, 0x80, /* width */ - 0x03, /* component number */ - 0x01, - 0x21, /* samples Y */ +#endif +}; + +#ifndef CONEX_CAM +/* variable part: + * 0x01, 0xe0, height + * 0x02, 0x80, width + * 0x03, component number + * 0x01, + * 0x21, samples Y + */ + +/* end of header */ +static unsigned char eoh[] = { 0x00, /* quant Y */ 0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */ 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan) */ 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 -#define JPEG_HDR_SZ 589 -#endif }; +#endif -/* define the JPEG header */ -static void jpeg_define(u8 *jpeg_hdr, - int height, - int width, - int samplesY) +/* -- output the JPEG header -- */ +static void jpeg_put_header(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, + int qindex, + int samplesY) { - memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head); #ifndef CONEX_CAM - jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8; - jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height & 0xff; - jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8; - jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width & 0xff; - jpeg_hdr[JPEG_HEIGHT_OFFSET + 6] = samplesY; + unsigned char tmpbuf[8]; #endif -} - -/* set the JPEG quality */ -static void jpeg_set_qual(u8 *jpeg_hdr, - int quality) -{ - int i, sc; - if (quality < 50) - sc = 5000 / quality; - else - sc = 200 - quality * 2; - for (i = 0; i < 64; i++) { - jpeg_hdr[JPEG_QT0_OFFSET + i] = - (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100; - jpeg_hdr[JPEG_QT1_OFFSET + i] = - (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100; - } + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + (unsigned char *) quant[qindex], sizeof quant[0]); + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + (unsigned char *) huffman, sizeof huffman); +#ifndef CONEX_CAM + tmpbuf[0] = gspca_dev->height >> 8; + tmpbuf[1] = gspca_dev->height & 0xff; + tmpbuf[2] = gspca_dev->width >> 8; + tmpbuf[3] = gspca_dev->width & 0xff; + tmpbuf[4] = 0x03; /* component number */ + tmpbuf[5] = 0x01; /* first component */ + tmpbuf[6] = samplesY; + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + tmpbuf, 7); + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + eoh, sizeof eoh); +#endif } #endif diff --git a/trunk/drivers/media/video/gspca/m5602/m5602_core.c b/trunk/drivers/media/video/gspca/m5602/m5602_core.c index b35e4838a6e5..ed906fe31287 100644 --- a/trunk/drivers/media/video/gspca/m5602/m5602_core.c +++ b/trunk/drivers/media/video/gspca/m5602/m5602_core.c @@ -332,6 +332,7 @@ static int m5602_configure(struct gspca_dev *gspca_dev, int err; cam = &gspca_dev->cam; + cam->epaddr = M5602_ISOC_ENDPOINT_ADDR; sd->desc = &sd_desc; if (dump_bridge) @@ -373,10 +374,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init mod_m5602_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/mars.c b/trunk/drivers/media/video/gspca/mars.c index 75e8d14e4ac7..3d2090e67a63 100644 --- a/trunk/drivers/media/video/gspca/mars.c +++ b/trunk/drivers/media/video/gspca/mars.c @@ -32,91 +32,17 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - u8 brightness; - u8 colors; - u8 gamma; - u8 sharpness; - u8 quality; -#define QUALITY_MIN 40 -#define QUALITY_MAX 70 -#define QUALITY_DEF 50 - - u8 *jpeg_hdr; + char qindex; }; /* V4L2 controls supported by the driver */ -static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); - static struct ctrl sd_ctrls[] = { - { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 30, - .step = 1, -#define BRIGHTNESS_DEF 15 - .default_value = BRIGHTNESS_DEF, - }, - .set = sd_setbrightness, - .get = sd_getbrightness, - }, - { - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Color", - .minimum = 1, - .maximum = 255, - .step = 1, -#define COLOR_DEF 200 - .default_value = COLOR_DEF, - }, - .set = sd_setcolors, - .get = sd_getcolors, - }, - { - { - .id = V4L2_CID_GAMMA, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gamma", - .minimum = 0, - .maximum = 3, - .step = 1, -#define GAMMA_DEF 1 - .default_value = GAMMA_DEF, - }, - .set = sd_setgamma, - .get = sd_getgamma, - }, - { - { - .id = V4L2_CID_SHARPNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Sharpness", - .minimum = 0, - .maximum = 2, - .step = 1, -#define SHARPNESS_DEF 1 - .default_value = SHARPNESS_DEF, - }, - .set = sd_setsharpness, - .get = sd_getsharpness, - }, }; static const struct v4l2_pix_format vga_mode[] = { {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, + .sizeimage = 320 * 240 * 3 / 8 + 589, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 2}, {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, @@ -126,45 +52,65 @@ static const struct v4l2_pix_format vga_mode[] = { .priv = 1}, }; -static const __u8 mi_data[0x20] = { -/* 01 02 03 04 05 06 07 08 */ - 0x48, 0x22, 0x01, 0x47, 0x10, 0x00, 0x00, 0x00, -/* 09 0a 0b 0c 0d 0e 0f 10 */ - 0x00, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, -/* 11 12 13 14 15 16 17 18 */ - 0x30, 0x00, 0x04, 0x00, 0x06, 0x01, 0xe2, 0x02, -/* 19 1a 1b 1c 1d 1e 1f 20 */ - 0x82, 0x00, 0x20, 0x17, 0x80, 0x08, 0x0c, 0x00 +/* MI Register table //elvis */ +enum { + REG_HW_MI_0, + REG_HW_MI_1, + REG_HW_MI_2, + REG_HW_MI_3, + REG_HW_MI_4, + REG_HW_MI_5, + REG_HW_MI_6, + REG_HW_MI_7, + REG_HW_MI_9 = 0x09, + REG_HW_MI_B = 0x0B, + REG_HW_MI_C, + REG_HW_MI_D, + REG_HW_MI_1E = 0x1E, + REG_HW_MI_20 = 0x20, + REG_HW_MI_2B = 0x2B, + REG_HW_MI_2C, + REG_HW_MI_2D, + REG_HW_MI_2E, + REG_HW_MI_35 = 0x35, + REG_HW_MI_5F = 0x5f, + REG_HW_MI_60, + REG_HW_MI_61, + REG_HW_MI_62, + REG_HW_MI_63, + REG_HW_MI_64, + REG_HW_MI_F1 = 0xf1, + ATTR_TOTAL_MI_REG = 0xf2 }; -/* write bytes from gspca_dev->usb_buf */ +/* the bytes to write are in gspca_dev->usb_buf */ static int reg_w(struct gspca_dev *gspca_dev, - int len) + __u16 index, int len) { - int alen, ret; - - ret = usb_bulk_msg(gspca_dev->dev, - usb_sndbulkpipe(gspca_dev->dev, 4), - gspca_dev->usb_buf, - len, - &alen, - 500); /* timeout in milliseconds */ - if (ret < 0) - PDEBUG(D_ERR, "reg write [%02x] error %d", - gspca_dev->usb_buf[0], ret); - return ret; + int rc; + + rc = usb_control_msg(gspca_dev->dev, + usb_sndbulkpipe(gspca_dev->dev, 4), + 0x12, + 0xc8, /* ?? */ + 0, /* value */ + index, gspca_dev->usb_buf, len, 500); + if (rc < 0) + PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc); + return rc; } -static void mi_w(struct gspca_dev *gspca_dev, - u8 addr, - u8 value) +static void bulk_w(struct gspca_dev *gspca_dev, + __u16 *pch, + __u16 Address) { gspca_dev->usb_buf[0] = 0x1f; gspca_dev->usb_buf[1] = 0; /* control byte */ - gspca_dev->usb_buf[2] = addr; - gspca_dev->usb_buf[3] = value; + gspca_dev->usb_buf[2] = Address; + gspca_dev->usb_buf[3] = *pch >> 8; /* high byte */ + gspca_dev->usb_buf[4] = *pch; /* low byte */ - reg_w(gspca_dev, 4); + reg_w(gspca_dev, Address, 5); } /* this function is called at probe time */ @@ -175,14 +121,10 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; + cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); - sd->brightness = BRIGHTNESS_DEF; - sd->colors = COLOR_DEF; - sd->gamma = GAMMA_DEF; - sd->sharpness = SHARPNESS_DEF; - sd->quality = QUALITY_DEF; - gspca_dev->nbalt = 9; /* use the altsetting 08 */ + sd->qindex = 1; /* set the quantization table */ return 0; } @@ -194,22 +136,24 @@ static int sd_init(struct gspca_dev *gspca_dev) static int sd_start(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; int err_code; - u8 *data; - int i; - - /* create the JPEG header */ - sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x21); /* JPEG 422 */ - jpeg_set_qual(sd->jpeg_hdr, sd->quality); + __u8 *data; + __u16 *MI_buf; + int h_size, v_size; + int intpipe; + + PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface); + err_code = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8); + if (err_code < 0) { + PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error"); + return err_code; + } data = gspca_dev->usb_buf; - data[0] = 0x01; /* address */ data[1] = 0x01; - err_code = reg_w(gspca_dev, 2); + + err_code = reg_w(gspca_dev, data[0], 2); if (err_code < 0) return err_code; @@ -219,28 +163,30 @@ static int sd_start(struct gspca_dev *gspca_dev) data[0] = 0x00; /* address */ data[1] = 0x0c | 0x01; /* reg 0 */ data[2] = 0x01; /* reg 1 */ - data[3] = gspca_dev->width / 8; /* h_size , reg 2 */ - data[4] = gspca_dev->height / 8; /* v_size , reg 3 */ + h_size = gspca_dev->width; + v_size = gspca_dev->height; + data[3] = h_size / 8; /* h_size , reg 2 */ + data[4] = v_size / 8; /* v_size , reg 3 */ data[5] = 0x30; /* reg 4, MI, PAS5101 : * 0x30 for 24mhz , 0x28 for 12mhz */ - data[6] = 0x02; /* reg 5, H start - was 0x04 */ - data[7] = sd->gamma * 0x40; /* reg 0x06: gamma */ - data[8] = 0x01; /* reg 7, V start - was 0x03 */ + data[6] = 4; /* reg 5, H start */ + data[7] = 0xc0; /* reg 6, gamma 1.5 */ + data[8] = 3; /* reg 7, V start */ /* if (h_size == 320 ) */ /* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ /* else */ data[9] = 0x52; /* reg 8, 24MHz, no scale down */ -/*jfm: from win trace*/ - data[10] = 0x18; + data[10] = 0x5d; /* reg 9, I2C device address + * [for PAS5101 (0x40)] [for MI (0x5d)] */ - err_code = reg_w(gspca_dev, 11); + err_code = reg_w(gspca_dev, data[0], 11); if (err_code < 0) return err_code; data[0] = 0x23; /* address */ data[1] = 0x09; /* reg 35, append frame header */ - err_code = reg_w(gspca_dev, 2); + err_code = reg_w(gspca_dev, data[0], 2); if (err_code < 0) return err_code; @@ -251,57 +197,137 @@ static int sd_start(struct gspca_dev *gspca_dev) /* else */ data[1] = 50; /* 50 reg 60, pc-cam frame size * (unit: 4KB) 200KB */ - err_code = reg_w(gspca_dev, 2); + err_code = reg_w(gspca_dev, data[0], 2); if (err_code < 0) return err_code; + if (0) { /* fixed dark-gain */ + data[1] = 0; /* reg 94, Y Gain (1.75) */ + data[2] = 0; /* reg 95, UV Gain (1.75) */ + data[3] = 0x3f; /* reg 96, Y Gain/UV Gain/disable + * auto dark-gain */ + data[4] = 0; /* reg 97, set fixed dark level */ + data[5] = 0; /* reg 98, don't care */ + } else { /* auto dark-gain */ + data[1] = 0; /* reg 94, Y Gain (auto) */ + data[2] = 0; /* reg 95, UV Gain (1.75) */ + data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable + * auto dark-gain */ + switch (gspca_dev->width) { +/* case 1280: */ +/* data[4] = 154; + * reg 97, %3 shadow point (unit: 256 pixel) */ +/* data[5] = 51; + * reg 98, %1 highlight point + * (uint: 256 pixel) */ +/* break; */ + default: +/* case 640: */ + data[4] = 36; /* reg 97, %3 shadow point + * (unit: 256 pixel) */ + data[5] = 12; /* reg 98, %1 highlight point + * (uint: 256 pixel) */ + break; + case 320: + data[4] = 9; /* reg 97, %3 shadow point + * (unit: 256 pixel) */ + data[5] = 3; /* reg 98, %1 highlight point + * (uint: 256 pixel) */ + break; + } + } /* auto dark-gain */ data[0] = 0x5e; /* address */ - data[1] = 0; /* reg 94, Y Gain (auto) */ -/*jfm: from win trace*/ - /* reg 0x5f/0x60 (LE) = saturation */ - /* h (60): xxxx x100 - * l (5f): xxxx x000 */ - data[2] = sd->colors << 3; - data[3] = ((sd->colors >> 2) & 0xf8) | 0x04; - data[4] = sd->brightness; /* reg 0x61 = brightness */ - data[5] = 0x00; - - err_code = reg_w(gspca_dev, 6); - if (err_code < 0) - return err_code; - data[0] = 0x67; -/*jfm: from win trace*/ - data[1] = sd->sharpness * 4 + 3; - data[2] = 0x14; - err_code = reg_w(gspca_dev, 3); + err_code = reg_w(gspca_dev, data[0], 6); if (err_code < 0) return err_code; - data[0] = 0x69; - data[1] = 0x2f; - data[2] = 0x28; - data[3] = 0x42; - err_code = reg_w(gspca_dev, 4); - if (err_code < 0) - return err_code; - - data[0] = 0x63; - data[1] = 0x07; - err_code = reg_w(gspca_dev, 2); -/*jfm: win trace - many writes here to reg 0x64*/ + data[0] = 0x67; + data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */ + err_code = reg_w(gspca_dev, data[0], 2); if (err_code < 0) return err_code; - /* initialize the MI sensor */ - for (i = 0; i < sizeof mi_data; i++) - mi_w(gspca_dev, i + 1, mi_data[i]); + /* + * initialize the value of MI sensor... + */ + MI_buf = kzalloc(ATTR_TOTAL_MI_REG * sizeof *MI_buf, GFP_KERNEL); + MI_buf[REG_HW_MI_1] = 0x000a; + MI_buf[REG_HW_MI_2] = 0x000c; + MI_buf[REG_HW_MI_3] = 0x0405; + MI_buf[REG_HW_MI_4] = 0x0507; + /* mi_Attr_Reg_[REG_HW_MI_5] = 0x01ff;//13 */ + MI_buf[REG_HW_MI_5] = 0x0013; /* 13 */ + MI_buf[REG_HW_MI_6] = 0x001f; /* vertical blanking */ + /* mi_Attr_Reg_[REG_HW_MI_6] = 0x0400; // vertical blanking */ + MI_buf[REG_HW_MI_7] = 0x0002; + /* mi_Attr_Reg_[REG_HW_MI_9] = 0x015f; */ + /* mi_Attr_Reg_[REG_HW_MI_9] = 0x030f; */ + MI_buf[REG_HW_MI_9] = 0x0374; + MI_buf[REG_HW_MI_B] = 0x0000; + MI_buf[REG_HW_MI_C] = 0x0000; + MI_buf[REG_HW_MI_D] = 0x0000; + MI_buf[REG_HW_MI_1E] = 0x8000; +/* mi_Attr_Reg_[REG_HW_MI_20] = 0x1104; */ + MI_buf[REG_HW_MI_20] = 0x1104; /* 0x111c; */ + MI_buf[REG_HW_MI_2B] = 0x0008; +/* mi_Attr_Reg_[REG_HW_MI_2C] = 0x000f; */ + MI_buf[REG_HW_MI_2C] = 0x001f; /* lita suggest */ + MI_buf[REG_HW_MI_2D] = 0x0008; + MI_buf[REG_HW_MI_2E] = 0x0008; + MI_buf[REG_HW_MI_35] = 0x0051; + MI_buf[REG_HW_MI_5F] = 0x0904; /* fail to write */ + MI_buf[REG_HW_MI_60] = 0x0000; + MI_buf[REG_HW_MI_61] = 0x0000; + MI_buf[REG_HW_MI_62] = 0x0498; + MI_buf[REG_HW_MI_63] = 0x0000; + MI_buf[REG_HW_MI_64] = 0x0000; + MI_buf[REG_HW_MI_F1] = 0x0001; + /* changing while setting up the different value of dx/dy */ + + if (gspca_dev->width != 1280) { + MI_buf[0x01] = 0x010a; + MI_buf[0x02] = 0x014c; + MI_buf[0x03] = 0x01e5; + MI_buf[0x04] = 0x0287; + } + MI_buf[0x20] = 0x1104; + + bulk_w(gspca_dev, MI_buf + 1, 1); + bulk_w(gspca_dev, MI_buf + 2, 2); + bulk_w(gspca_dev, MI_buf + 3, 3); + bulk_w(gspca_dev, MI_buf + 4, 4); + bulk_w(gspca_dev, MI_buf + 5, 5); + bulk_w(gspca_dev, MI_buf + 6, 6); + bulk_w(gspca_dev, MI_buf + 7, 7); + bulk_w(gspca_dev, MI_buf + 9, 9); + bulk_w(gspca_dev, MI_buf + 0x0b, 0x0b); + bulk_w(gspca_dev, MI_buf + 0x0c, 0x0c); + bulk_w(gspca_dev, MI_buf + 0x0d, 0x0d); + bulk_w(gspca_dev, MI_buf + 0x1e, 0x1e); + bulk_w(gspca_dev, MI_buf + 0x20, 0x20); + bulk_w(gspca_dev, MI_buf + 0x2b, 0x2b); + bulk_w(gspca_dev, MI_buf + 0x2c, 0x2c); + bulk_w(gspca_dev, MI_buf + 0x2d, 0x2d); + bulk_w(gspca_dev, MI_buf + 0x2e, 0x2e); + bulk_w(gspca_dev, MI_buf + 0x35, 0x35); + bulk_w(gspca_dev, MI_buf + 0x5f, 0x5f); + bulk_w(gspca_dev, MI_buf + 0x60, 0x60); + bulk_w(gspca_dev, MI_buf + 0x61, 0x61); + bulk_w(gspca_dev, MI_buf + 0x62, 0x62); + bulk_w(gspca_dev, MI_buf + 0x63, 0x63); + bulk_w(gspca_dev, MI_buf + 0x64, 0x64); + bulk_w(gspca_dev, MI_buf + 0xf1, 0xf1); + kfree(MI_buf); + + intpipe = usb_sndintpipe(gspca_dev->dev, 0); + err_code = usb_clear_halt(gspca_dev->dev, intpipe); data[0] = 0x00; data[1] = 0x4d; /* ISOC transfering enable... */ - reg_w(gspca_dev, 2); - return 0; + reg_w(gspca_dev, data[0], 2); + return err_code; } static void sd_stopN(struct gspca_dev *gspca_dev) @@ -310,18 +336,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev) gspca_dev->usb_buf[0] = 1; gspca_dev->usb_buf[1] = 0; - result = reg_w(gspca_dev, 2); + result = reg_w(gspca_dev, gspca_dev->usb_buf[0], 2); if (result < 0) PDEBUG(D_ERR, "Camera Stop failed"); } -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - kfree(sd->jpeg_hdr); -} - static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ @@ -344,16 +363,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, || data[5 + p] == 0x65 || data[5 + p] == 0x66 || data[5 + p] == 0x67) { - PDEBUG(D_PACK, "sof offset: %d len: %d", + PDEBUG(D_PACK, "sof offset: %d leng: %d", p, len); frame = gspca_frame_add(gspca_dev, LAST_PACKET, - frame, data, p); + frame, data, 0); /* put the JPEG header */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - sd->jpeg_hdr, JPEG_HDR_SZ); - data += p + 16; - len -= p + 16; + jpeg_put_header(gspca_dev, frame, + sd->qindex, 0x21); + data += 16; + len -= 16; break; } } @@ -361,121 +380,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } -static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->brightness = val; - if (gspca_dev->streaming) { - gspca_dev->usb_buf[0] = 0x61; - gspca_dev->usb_buf[1] = val; - reg_w(gspca_dev, 2); - } - return 0; -} - -static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->brightness; - return 0; -} - -static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->colors = val; - if (gspca_dev->streaming) { - - /* see sd_start */ - gspca_dev->usb_buf[0] = 0x5f; - gspca_dev->usb_buf[1] = sd->colors << 3; - gspca_dev->usb_buf[2] = ((sd->colors >> 2) & 0xf8) | 0x04; - reg_w(gspca_dev, 3); - } - return 0; -} - -static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->colors; - return 0; -} - -static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->gamma = val; - if (gspca_dev->streaming) { - gspca_dev->usb_buf[0] = 0x06; - gspca_dev->usb_buf[1] = val * 0x40; - reg_w(gspca_dev, 2); - } - return 0; -} - -static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->gamma; - return 0; -} - -static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->sharpness = val; - if (gspca_dev->streaming) { - gspca_dev->usb_buf[0] = 0x67; - gspca_dev->usb_buf[1] = val * 4 + 3; - reg_w(gspca_dev, 2); - } - return 0; -} - -static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->sharpness; - return 0; -} - -static int sd_set_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (jcomp->quality < QUALITY_MIN) - sd->quality = QUALITY_MIN; - else if (jcomp->quality > QUALITY_MAX) - sd->quality = QUALITY_MAX; - else - sd->quality = jcomp->quality; - if (gspca_dev->streaming) - jpeg_set_qual(sd->jpeg_hdr, sd->quality); - return 0; -} - -static int sd_get_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - memset(jcomp, 0, sizeof *jcomp); - jcomp->quality = sd->quality; - jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT - | V4L2_JPEG_MARKER_DQT; - return 0; -} - /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -485,10 +389,7 @@ static const struct sd_desc sd_desc = { .init = sd_init, .start = sd_start, .stopN = sd_stopN, - .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan, - .get_jcomp = sd_get_jcomp, - .set_jcomp = sd_set_jcomp, }; /* -- module initialisation -- */ @@ -520,11 +421,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/mr97310a.c b/trunk/drivers/media/video/gspca/mr97310a.c deleted file mode 100644 index 2a901a4a6f00..000000000000 --- a/trunk/drivers/media/video/gspca/mr97310a.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Mars MR97310A library - * - * Copyright (C) 2009 Kyle Guinn - * - * 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 - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define MODULE_NAME "mr97310a" - -#include "gspca.h" - -MODULE_AUTHOR("Kyle Guinn "); -MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* specific webcam descriptor */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - u8 sof_read; -}; - -/* V4L2 controls supported by the driver */ -static struct ctrl sd_ctrls[] = { -}; - -static const struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 4}, - {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 176 * 144, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 3}, - {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2}, - {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, -}; - -/* the bytes to write are in gspca_dev->usb_buf */ -static int reg_w(struct gspca_dev *gspca_dev, int len) -{ - int rc; - - rc = usb_bulk_msg(gspca_dev->dev, - usb_sndbulkpipe(gspca_dev->dev, 4), - gspca_dev->usb_buf, len, NULL, 500); - if (rc < 0) - PDEBUG(D_ERR, "reg write [%02x] error %d", - gspca_dev->usb_buf[0], rc); - return rc; -} - -/* this function is called at probe time */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam; - - cam = &gspca_dev->cam; - cam->cam_mode = vga_mode; - cam->nmodes = ARRAY_SIZE(vga_mode); - return 0; -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - return 0; -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - __u8 *data = gspca_dev->usb_buf; - int err_code; - - sd->sof_read = 0; - - /* Note: register descriptions guessed from MR97113A driver */ - - data[0] = 0x01; - data[1] = 0x01; - err_code = reg_w(gspca_dev, 2); - if (err_code < 0) - return err_code; - - data[0] = 0x00; - data[1] = 0x0d; - data[2] = 0x01; - data[5] = 0x2b; - data[7] = 0x00; - data[9] = 0x50; /* reg 8, no scale down */ - data[10] = 0xc0; - - switch (gspca_dev->width) { - case 160: - data[9] |= 0x0c; /* reg 8, 4:1 scale down */ - /* fall thru */ - case 320: - data[9] |= 0x04; /* reg 8, 2:1 scale down */ - /* fall thru */ - case 640: - default: - data[3] = 0x50; /* reg 2, H size */ - data[4] = 0x78; /* reg 3, V size */ - data[6] = 0x04; /* reg 5, H start */ - data[8] = 0x03; /* reg 7, V start */ - break; - - case 176: - data[9] |= 0x04; /* reg 8, 2:1 scale down */ - /* fall thru */ - case 352: - data[3] = 0x2c; /* reg 2, H size */ - data[4] = 0x48; /* reg 3, V size */ - data[6] = 0x94; /* reg 5, H start */ - data[8] = 0x63; /* reg 7, V start */ - break; - } - - err_code = reg_w(gspca_dev, 11); - if (err_code < 0) - return err_code; - - data[0] = 0x0a; - data[1] = 0x80; - err_code = reg_w(gspca_dev, 2); - if (err_code < 0) - return err_code; - - data[0] = 0x14; - data[1] = 0x0a; - err_code = reg_w(gspca_dev, 2); - if (err_code < 0) - return err_code; - - data[0] = 0x1b; - data[1] = 0x00; - err_code = reg_w(gspca_dev, 2); - if (err_code < 0) - return err_code; - - data[0] = 0x15; - data[1] = 0x16; - err_code = reg_w(gspca_dev, 2); - if (err_code < 0) - return err_code; - - data[0] = 0x16; - data[1] = 0x10; - err_code = reg_w(gspca_dev, 2); - if (err_code < 0) - return err_code; - - data[0] = 0x17; - data[1] = 0x3a; - err_code = reg_w(gspca_dev, 2); - if (err_code < 0) - return err_code; - - data[0] = 0x18; - data[1] = 0x68; - err_code = reg_w(gspca_dev, 2); - if (err_code < 0) - return err_code; - - data[0] = 0x1f; - data[1] = 0x00; - data[2] = 0x02; - data[3] = 0x06; - data[4] = 0x59; - data[5] = 0x0c; - data[6] = 0x16; - data[7] = 0x00; - data[8] = 0x07; - data[9] = 0x00; - data[10] = 0x01; - err_code = reg_w(gspca_dev, 11); - if (err_code < 0) - return err_code; - - data[0] = 0x1f; - data[1] = 0x04; - data[2] = 0x11; - data[3] = 0x01; - err_code = reg_w(gspca_dev, 4); - if (err_code < 0) - return err_code; - - data[0] = 0x1f; - data[1] = 0x00; - data[2] = 0x0a; - data[3] = 0x00; - data[4] = 0x01; - data[5] = 0x00; - data[6] = 0x00; - data[7] = 0x01; - data[8] = 0x00; - data[9] = 0x0a; - err_code = reg_w(gspca_dev, 10); - if (err_code < 0) - return err_code; - - data[0] = 0x1f; - data[1] = 0x04; - data[2] = 0x11; - data[3] = 0x01; - err_code = reg_w(gspca_dev, 4); - if (err_code < 0) - return err_code; - - data[0] = 0x1f; - data[1] = 0x00; - data[2] = 0x12; - data[3] = 0x00; - data[4] = 0x63; - data[5] = 0x00; - data[6] = 0x70; - data[7] = 0x00; - data[8] = 0x00; - err_code = reg_w(gspca_dev, 9); - if (err_code < 0) - return err_code; - - data[0] = 0x1f; - data[1] = 0x04; - data[2] = 0x11; - data[3] = 0x01; - err_code = reg_w(gspca_dev, 4); - if (err_code < 0) - return err_code; - - data[0] = 0x00; - data[1] = 0x4d; /* ISOC transfering enable... */ - err_code = reg_w(gspca_dev, 2); - return err_code; -} - -static void sd_stopN(struct gspca_dev *gspca_dev) -{ - int result; - - gspca_dev->usb_buf[0] = 1; - gspca_dev->usb_buf[1] = 0; - result = reg_w(gspca_dev, 2); - if (result < 0) - PDEBUG(D_ERR, "Camera Stop failed"); -} - -/* Include pac common sof detection functions */ -#include "pac_common.h" - -static void sd_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *data, /* isoc packet */ - int len) /* iso packet length */ -{ - unsigned char *sof; - - sof = pac_find_sof(gspca_dev, data, len); - if (sof) { - int n; - - /* finish decoding current frame */ - n = sof - data; - if (n > sizeof pac_sof_marker) - n -= sizeof pac_sof_marker; - else - n = 0; - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - data, n); - /* Start next frame. */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - pac_sof_marker, sizeof pac_sof_marker); - len -= sof - data; - data = sof; - } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); -} - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .ctrls = sd_ctrls, - .nctrls = ARRAY_SIZE(sd_ctrls), - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stopN = sd_stopN, - .pkt_scan = sd_pkt_scan, -}; - -/* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x08ca, 0x0111)}, - {} -}; -MODULE_DEVICE_TABLE(usb, device_table); - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, -#endif -}; - -/* -- module insert / remove -- */ -static int __init sd_mod_init(void) -{ - if (usb_register(&sd_driver) < 0) - return -1; - PDEBUG(D_PROBE, "registered"); - return 0; -} -static void __exit sd_mod_exit(void) -{ - usb_deregister(&sd_driver); - PDEBUG(D_PROBE, "deregistered"); -} - -module_init(sd_mod_init); -module_exit(sd_mod_exit); diff --git a/trunk/drivers/media/video/gspca/ov519.c b/trunk/drivers/media/video/gspca/ov519.c index 1fff37b79891..ee232956c812 100644 --- a/trunk/drivers/media/video/gspca/ov519.c +++ b/trunk/drivers/media/video/gspca/ov519.c @@ -1360,6 +1360,7 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; + cam->epaddr = OV511_ENDPOINT_ADDRESS; if (!sd->sif) { cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); @@ -2176,10 +2177,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/ov534.c b/trunk/drivers/media/video/gspca/ov534.c index 19e0bc60de14..3bf15e401693 100644 --- a/trunk/drivers/media/video/gspca/ov534.c +++ b/trunk/drivers/media/video/gspca/ov534.c @@ -1,8 +1,7 @@ /* - * ov534 gspca driver + * ov534/ov772x gspca driver * Copyright (C) 2008 Antonio Ospite * Copyright (C) 2008 Jim Paris - * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr * * Based on a prototype written by Mark Ferrell * USB protocol reverse engineered by Jim Paris @@ -27,7 +26,7 @@ #include "gspca.h" -#define OV534_REG_ADDRESS 0xf1 /* sensor address */ +#define OV534_REG_ADDRESS 0xf1 /* ? */ #define OV534_REG_SUBADDR 0xf2 #define OV534_REG_WRITE 0xf3 #define OV534_REG_READ 0xf4 @@ -47,13 +46,9 @@ MODULE_LICENSE("GPL"); /* specific webcam descriptor */ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ + __u32 last_fid; __u32 last_pts; - u16 last_fid; - u8 frame_rate; - - u8 sensor; -#define SENSOR_OV772X 0 -#define SENSOR_OV965X 1 + int frame_rate; }; /* V4L2 controls supported by the driver */ @@ -68,7 +63,114 @@ static const struct v4l2_pix_format vga_mode[] = { .priv = 0}, }; -static const u8 bridge_init_ov722x[][2] = { +static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) +{ + struct usb_device *udev = gspca_dev->dev; + int ret; + + PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val); + gspca_dev->usb_buf[0] = val; + ret = usb_control_msg(udev, + usb_sndctrlpipe(udev, 0), + 0x1, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); + if (ret < 0) + PDEBUG(D_ERR, "write failed"); +} + +static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg) +{ + struct usb_device *udev = gspca_dev->dev; + int ret; + + ret = usb_control_msg(udev, + usb_rcvctrlpipe(udev, 0), + 0x1, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); + PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]); + if (ret < 0) + PDEBUG(D_ERR, "read failed"); + return gspca_dev->usb_buf[0]; +} + +/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7. + * (direction and output)? */ +static void ov534_set_led(struct gspca_dev *gspca_dev, int status) +{ + u8 data; + + PDEBUG(D_CONF, "led status: %d", status); + + data = ov534_reg_read(gspca_dev, 0x21); + data |= 0x80; + ov534_reg_write(gspca_dev, 0x21, data); + + data = ov534_reg_read(gspca_dev, 0x23); + if (status) + data |= 0x80; + else + data &= ~(0x80); + + ov534_reg_write(gspca_dev, 0x23, data); +} + +static int sccb_check_status(struct gspca_dev *gspca_dev) +{ + u8 data; + int i; + + for (i = 0; i < 5; i++) { + data = ov534_reg_read(gspca_dev, OV534_REG_STATUS); + + switch (data) { + case 0x00: + return 1; + case 0x04: + return 0; + case 0x03: + break; + default: + PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5", + data, i + 1); + } + } + return 0; +} + +static void sccb_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) +{ + PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%02x", reg, val); + ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg); + ov534_reg_write(gspca_dev, OV534_REG_WRITE, val); + ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3); + + if (!sccb_check_status(gspca_dev)) + PDEBUG(D_ERR, "sccb_reg_write failed"); +} + +#ifdef GSPCA_DEBUG +static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg) +{ + ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg); + ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2); + if (!sccb_check_status(gspca_dev)) + PDEBUG(D_ERR, "sccb_reg_read failed 1"); + + ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2); + if (!sccb_check_status(gspca_dev)) + PDEBUG(D_ERR, "sccb_reg_read failed 2"); + + return ov534_reg_read(gspca_dev, OV534_REG_READ); +} +#endif + +static const __u8 ov534_reg_initdata[][2] = { + { 0xe7, 0x3a }, + + { OV534_REG_ADDRESS, 0x42 }, /* select OV772x sensor */ + { 0xc2, 0x0c }, { 0x88, 0xf8 }, { 0xc3, 0x69 }, @@ -126,7 +228,7 @@ static const u8 bridge_init_ov722x[][2] = { { 0xc2, 0x0c }, }; -static const u8 sensor_init_ov722x[][2] = { +static const __u8 ov772x_reg_initdata[][2] = { { 0x12, 0x80 }, { 0x11, 0x01 }, @@ -209,456 +311,6 @@ static const u8 sensor_init_ov722x[][2] = { { 0x0c, 0xd0 } }; -static const u8 bridge_init_ov965x[][2] = { - {0x88, 0xf8}, - {0x89, 0xff}, - {0x76, 0x03}, - {0x92, 0x03}, - {0x95, 0x10}, - {0xe2, 0x00}, - {0xe7, 0x3e}, - {0x8d, 0x1c}, - {0x8e, 0x00}, - {0x8f, 0x00}, - {0x1f, 0x00}, - {0xc3, 0xf9}, - {0x89, 0xff}, - {0x88, 0xf8}, - {0x76, 0x03}, - {0x92, 0x01}, - {0x93, 0x18}, - {0x1c, 0x0a}, - {0x1d, 0x48}, - {0xc0, 0x50}, - {0xc1, 0x3c}, - {0x34, 0x05}, - {0xc2, 0x0c}, - {0xc3, 0xf9}, - {0x34, 0x05}, - {0xe7, 0x2e}, - {0x31, 0xf9}, - {0x35, 0x02}, - {0xd9, 0x10}, - {0x25, 0x42}, - {0x94, 0x11}, -}; - -static const u8 sensor_init_ov965x[][2] = { - {0x12, 0x80}, /* com7 - reset */ - {0x00, 0x00}, /* gain */ - {0x01, 0x80}, /* blue */ - {0x02, 0x80}, /* red */ - {0x03, 0x1b}, /* vref */ - {0x04, 0x03}, /* com1 - exposure low bits */ - {0x0b, 0x57}, /* ver */ - {0x0e, 0x61}, /* com5 */ - {0x0f, 0x42}, /* com6 */ - {0x11, 0x00}, /* clkrc */ - {0x12, 0x02}, /* com7 */ - {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ - {0x14, 0x28}, /* com9 */ - {0x16, 0x24}, /* rsvd16 */ - {0x17, 0x1d}, /* hstart*/ - {0x18, 0xbd}, /* hstop */ - {0x19, 0x01}, /* vstrt */ - {0x1a, 0x81}, /* vstop*/ - {0x1e, 0x04}, /* mvfp */ - {0x24, 0x3c}, /* aew */ - {0x25, 0x36}, /* aeb */ - {0x26, 0x71}, /* vpt */ - {0x27, 0x08}, /* bbias */ - {0x28, 0x08}, /* gbbias */ - {0x29, 0x15}, /* gr com */ - {0x2a, 0x00}, - {0x2b, 0x00}, - {0x2c, 0x08}, /* rbias */ - {0x32, 0xff}, /* href */ - {0x33, 0x00}, /* chlf */ - {0x34, 0x3f}, /* arblm */ - {0x35, 0x00}, /* rsvd35 */ - {0x36, 0xf8}, /* rsvd36 */ - {0x38, 0x72}, /* acom38 */ - {0x39, 0x57}, /* ofon */ - {0x3a, 0x80}, /* tslb */ - {0x3b, 0xc4}, - {0x3d, 0x99}, /* com13 */ - {0x3f, 0xc1}, - {0x40, 0xc0}, /* com15 */ - {0x41, 0x40}, /* com16 */ - {0x42, 0xc0}, - {0x43, 0x0a}, - {0x44, 0xf0}, - {0x45, 0x46}, - {0x46, 0x62}, - {0x47, 0x2a}, - {0x48, 0x3c}, - {0x4a, 0xfc}, - {0x4b, 0xfc}, - {0x4c, 0x7f}, - {0x4d, 0x7f}, - {0x4e, 0x7f}, - {0x4f, 0x98}, - {0x50, 0x98}, - {0x51, 0x00}, - {0x52, 0x28}, - {0x53, 0x70}, - {0x54, 0x98}, - {0x58, 0x1a}, - {0x59, 0x85}, - {0x5a, 0xa9}, - {0x5b, 0x64}, - {0x5c, 0x84}, - {0x5d, 0x53}, - {0x5e, 0x0e}, - {0x5f, 0xf0}, - {0x60, 0xf0}, - {0x61, 0xf0}, - {0x62, 0x00}, /* lcc1 */ - {0x63, 0x00}, /* lcc2 */ - {0x64, 0x02}, /* lcc3 */ - {0x65, 0x16}, /* lcc4 */ - {0x66, 0x01}, /* lcc5 */ - {0x69, 0x02}, /* hv */ - {0x6b, 0x5a}, /* dbvl */ - {0x6c, 0x04}, - {0x6d, 0x55}, - {0x6e, 0x00}, - {0x6f, 0x9d}, - {0x70, 0x21}, - {0x71, 0x78}, - {0x72, 0x00}, - {0x73, 0x01}, - {0x74, 0x3a}, - {0x75, 0x35}, - {0x76, 0x01}, - {0x77, 0x02}, - {0x7a, 0x12}, - {0x7b, 0x08}, - {0x7c, 0x16}, - {0x7d, 0x30}, - {0x7e, 0x5e}, - {0x7f, 0x72}, - {0x80, 0x82}, - {0x81, 0x8e}, - {0x82, 0x9a}, - {0x83, 0xa4}, - {0x84, 0xac}, - {0x85, 0xb8}, - {0x86, 0xc3}, - {0x87, 0xd6}, - {0x88, 0xe6}, - {0x89, 0xf2}, - {0x8a, 0x03}, - {0x8c, 0x89}, - {0x14, 0x28}, /* com9 */ - {0x90, 0x7d}, - {0x91, 0x7b}, - {0x9d, 0x03}, - {0x9e, 0x04}, - {0x9f, 0x7a}, - {0xa0, 0x79}, - {0xa1, 0x40}, /* aechm */ - {0xa4, 0x50}, - {0xa5, 0x68}, /* com26 */ - {0xa6, 0x4a}, - {0xa8, 0xc1}, /* acoma8 */ - {0xa9, 0xef}, /* acoma9 */ - {0xaa, 0x92}, - {0xab, 0x04}, - {0xac, 0x80}, - {0xad, 0x80}, - {0xae, 0x80}, - {0xaf, 0x80}, - {0xb2, 0xf2}, - {0xb3, 0x20}, - {0xb4, 0x20}, - {0xb5, 0x00}, - {0xb6, 0xaf}, - {0xbb, 0xae}, - {0xbc, 0x7f}, - {0xdb, 0x7f}, - {0xbe, 0x7f}, - {0xbf, 0x7f}, - {0xc0, 0xe2}, - {0xc1, 0xc0}, - {0xc2, 0x01}, - {0xc3, 0x4e}, - {0xc6, 0x85}, - {0xc7, 0x80}, - {0xc9, 0xe0}, - {0xca, 0xe8}, - {0xcb, 0xf0}, - {0xcc, 0xd8}, - {0xcd, 0xf1}, - {0x4f, 0x98}, - {0x50, 0x98}, - {0x51, 0x00}, - {0x52, 0x28}, - {0x53, 0x70}, - {0x54, 0x98}, - {0x58, 0x1a}, - {0xff, 0x41}, /* read 41, write ff 00 */ - {0x41, 0x40}, /* com16 */ - {0xc5, 0x03}, - {0x6a, 0x02}, - - {0x12, 0x62}, /* com7 - VGA + CIF */ - {0x36, 0xfa}, /* rsvd36 */ - {0x69, 0x0a}, /* hv */ - {0x8c, 0x89}, /* com22 */ - {0x14, 0x28}, /* com9 */ - {0x3e, 0x0c}, - {0x41, 0x40}, /* com16 */ - {0x72, 0x00}, - {0x73, 0x00}, - {0x74, 0x3a}, - {0x75, 0x35}, - {0x76, 0x01}, - {0xc7, 0x80}, - {0x03, 0x12}, /* vref */ - {0x17, 0x16}, /* hstart */ - {0x18, 0x02}, /* hstop */ - {0x19, 0x01}, /* vstrt */ - {0x1a, 0x3d}, /* vstop */ - {0x32, 0xff}, /* href */ - {0xc0, 0xaa}, -}; - -static const u8 bridge_init_ov965x_2[][2] = { - {0x94, 0xaa}, - {0xf1, 0x60}, - {0xe5, 0x04}, - {0xc0, 0x50}, - {0xc1, 0x3c}, - {0x8c, 0x00}, - {0x8d, 0x1c}, - {0x34, 0x05}, - - {0xc2, 0x0c}, - {0xc3, 0xf9}, - {0xda, 0x01}, - {0x50, 0x00}, - {0x51, 0xa0}, - {0x52, 0x3c}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x00}, - {0x57, 0x00}, - {0x5c, 0x00}, - {0x5a, 0xa0}, - {0x5b, 0x78}, - {0x35, 0x02}, - {0xd9, 0x10}, - {0x94, 0x11}, -}; - -static const u8 sensor_init_ov965x_2[][2] = { - {0x3b, 0xc4}, - {0x1e, 0x04}, /* mvfp */ - {0x13, 0xe0}, /* com8 */ - {0x00, 0x00}, /* gain */ - {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ - {0x11, 0x03}, /* clkrc */ - {0x6b, 0x5a}, /* dblv */ - {0x6a, 0x05}, - {0xc5, 0x07}, - {0xa2, 0x4b}, - {0xa3, 0x3e}, - {0x2d, 0x00}, - {0xff, 0x42}, /* read 42, write ff 00 */ - {0x42, 0xc0}, - {0x2d, 0x00}, - {0xff, 0x42}, /* read 42, write ff 00 */ - {0x42, 0xc1}, - {0x3f, 0x01}, - {0xff, 0x42}, /* read 42, write ff 00 */ - {0x42, 0xc1}, - {0x4f, 0x98}, - {0x50, 0x98}, - {0x51, 0x00}, - {0x52, 0x28}, - {0x53, 0x70}, - {0x54, 0x98}, - {0x58, 0x1a}, - {0xff, 0x41}, /* read 41, write ff 00 */ - {0x41, 0x40}, /* com16 */ - {0x56, 0x40}, - {0x55, 0x8f}, - {0x10, 0x25}, /* aech - exposure high bits */ - {0xff, 0x13}, /* read 13, write ff 00 */ - {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ -}; - -static const u8 bridge_start_ov965x[][2] = { - {0xc2, 0x4c}, - {0xc3, 0xf9}, - {0x50, 0x00}, - {0x51, 0xa0}, - {0x52, 0x78}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x00}, - {0x57, 0x00}, - {0x5c, 0x00}, - {0x5a, 0x28}, - {0x5b, 0x1e}, - {0x35, 0x00}, - {0xd9, 0x21}, - {0x94, 0x11}, -}; - -static const u8 sensor_start_ov965x[][2] = { - {0x3b, 0xe4}, - {0x1e, 0x04}, /* mvfp */ - {0x13, 0xe0}, /* com8 */ - {0x00, 0x00}, - {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ - {0x11, 0x01}, /* clkrc */ - {0x6b, 0x5a}, /* dblv */ - {0x6a, 0x02}, - {0xc5, 0x03}, - {0xa2, 0x96}, - {0xa3, 0x7d}, - {0xff, 0x13}, /* read 13, write ff 00 */ - {0x13, 0xe7}, - {0x3a, 0x80}, - {0xff, 0x42}, /* read 42, write ff 00 */ - {0x42, 0xc1}, -}; - - -static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) -{ - struct usb_device *udev = gspca_dev->dev; - int ret; - - PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val); - gspca_dev->usb_buf[0] = val; - ret = usb_control_msg(udev, - usb_sndctrlpipe(udev, 0), - 0x01, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); - if (ret < 0) - PDEBUG(D_ERR, "write failed"); -} - -static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg) -{ - struct usb_device *udev = gspca_dev->dev; - int ret; - - ret = usb_control_msg(udev, - usb_rcvctrlpipe(udev, 0), - 0x01, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); - PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]); - if (ret < 0) - PDEBUG(D_ERR, "read failed"); - return gspca_dev->usb_buf[0]; -} - -/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7. - * (direction and output)? */ -static void ov534_set_led(struct gspca_dev *gspca_dev, int status) -{ - u8 data; - - PDEBUG(D_CONF, "led status: %d", status); - - data = ov534_reg_read(gspca_dev, 0x21); - data |= 0x80; - ov534_reg_write(gspca_dev, 0x21, data); - - data = ov534_reg_read(gspca_dev, 0x23); - if (status) - data |= 0x80; - else - data &= ~0x80; - - ov534_reg_write(gspca_dev, 0x23, data); - - if (!status) { - data = ov534_reg_read(gspca_dev, 0x21); - data &= ~0x80; - ov534_reg_write(gspca_dev, 0x21, data); - } -} - -static int sccb_check_status(struct gspca_dev *gspca_dev) -{ - u8 data; - int i; - - for (i = 0; i < 5; i++) { - data = ov534_reg_read(gspca_dev, OV534_REG_STATUS); - - switch (data) { - case 0x00: - return 1; - case 0x04: - return 0; - case 0x03: - break; - default: - PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5", - data, i + 1); - } - } - return 0; -} - -static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val) -{ - PDEBUG(D_USBO, "reg: 0x%02x, val: 0x%02x", reg, val); - ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg); - ov534_reg_write(gspca_dev, OV534_REG_WRITE, val); - ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3); - - if (!sccb_check_status(gspca_dev)) - PDEBUG(D_ERR, "sccb_reg_write failed"); -} - -static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg) -{ - ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg); - ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2); - if (!sccb_check_status(gspca_dev)) - PDEBUG(D_ERR, "sccb_reg_read failed 1"); - - ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2); - if (!sccb_check_status(gspca_dev)) - PDEBUG(D_ERR, "sccb_reg_read failed 2"); - - return ov534_reg_read(gspca_dev, OV534_REG_READ); -} - -/* output a bridge sequence (reg - val) */ -static void reg_w_array(struct gspca_dev *gspca_dev, - const u8 (*data)[2], int len) -{ - while (--len >= 0) { - ov534_reg_write(gspca_dev, (*data)[0], (*data)[1]); - data++; - } -} - -/* output a sensor sequence (reg - val) */ -static void sccb_w_array(struct gspca_dev *gspca_dev, - const u8 (*data)[2], int len) -{ - while (--len >= 0) { - if ((*data)[0] != 0xff) { - sccb_reg_write(gspca_dev, (*data)[0], (*data)[1]); - } else { - sccb_reg_read(gspca_dev, (*data)[1]); - sccb_reg_write(gspca_dev, 0xff, 0x00); - } - data++; - } -} - /* set framerate */ static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) { @@ -694,17 +346,40 @@ static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) PDEBUG(D_PROBE, "frame_rate: %d", fr); } +/* setup method */ +static void ov534_setup(struct gspca_dev *gspca_dev) +{ + int i; + + /* Initialize bridge chip */ + for (i = 0; i < ARRAY_SIZE(ov534_reg_initdata); i++) + ov534_reg_write(gspca_dev, ov534_reg_initdata[i][0], + ov534_reg_initdata[i][1]); + + PDEBUG(D_PROBE, "sensor is ov%02x%02x", + sccb_reg_read(gspca_dev, 0x0a), + sccb_reg_read(gspca_dev, 0x0b)); + + ov534_set_led(gspca_dev, 1); + + /* Initialize sensor */ + for (i = 0; i < ARRAY_SIZE(ov772x_reg_initdata); i++) + sccb_reg_write(gspca_dev, ov772x_reg_initdata[i][0], + ov772x_reg_initdata[i][1]); + + ov534_reg_write(gspca_dev, 0xe0, 0x09); + ov534_set_led(gspca_dev, 0); +} + /* this function is called at probe time */ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) { - struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - sd->sensor = id->driver_info; - cam = &gspca_dev->cam; + cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); @@ -717,102 +392,26 @@ static int sd_config(struct gspca_dev *gspca_dev, /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; - u16 sensor_id; - static const u8 sensor_addr[2] = { - 0x42, /* 0 SENSOR_OV772X */ - 0x60, /* 1 SENSOR_OV965X */ - }; - - /* reset bridge */ - ov534_reg_write(gspca_dev, 0xe7, 0x3a); - ov534_reg_write(gspca_dev, 0xe0, 0x08); - msleep(100); - - /* initialize the sensor address */ - ov534_reg_write(gspca_dev, OV534_REG_ADDRESS, - sensor_addr[sd->sensor]); - - /* reset sensor */ - sccb_reg_write(gspca_dev, 0x12, 0x80); - msleep(10); - - /* probe the sensor */ - sccb_reg_read(gspca_dev, 0x0a); - sensor_id = sccb_reg_read(gspca_dev, 0x0a) << 8; - sccb_reg_read(gspca_dev, 0x0b); - sensor_id |= sccb_reg_read(gspca_dev, 0x0b); - PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id); - - /* initialize */ - switch (sd->sensor) { - case SENSOR_OV772X: - reg_w_array(gspca_dev, bridge_init_ov722x, - ARRAY_SIZE(bridge_init_ov722x)); - ov534_set_led(gspca_dev, 1); - sccb_w_array(gspca_dev, sensor_init_ov722x, - ARRAY_SIZE(sensor_init_ov722x)); - ov534_reg_write(gspca_dev, 0xe0, 0x09); - ov534_set_led(gspca_dev, 0); - ov534_set_frame_rate(gspca_dev); - break; - default: -/* case SENSOR_OV965X: */ - reg_w_array(gspca_dev, bridge_init_ov965x, - ARRAY_SIZE(bridge_init_ov965x)); - sccb_w_array(gspca_dev, sensor_init_ov965x, - ARRAY_SIZE(sensor_init_ov965x)); - reg_w_array(gspca_dev, bridge_init_ov965x_2, - ARRAY_SIZE(bridge_init_ov965x_2)); - sccb_w_array(gspca_dev, sensor_init_ov965x_2, - ARRAY_SIZE(sensor_init_ov965x_2)); - ov534_reg_write(gspca_dev, 0xe0, 0x00); - ov534_reg_write(gspca_dev, 0xe0, 0x01); - ov534_set_led(gspca_dev, 0); - ov534_reg_write(gspca_dev, 0xe0, 0x00); - } + ov534_setup(gspca_dev); + ov534_set_frame_rate(gspca_dev); return 0; } static int sd_start(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; + /* start streaming data */ + ov534_set_led(gspca_dev, 1); + ov534_reg_write(gspca_dev, 0xe0, 0x00); - switch (sd->sensor) { - case SENSOR_OV772X: - ov534_set_led(gspca_dev, 1); - ov534_reg_write(gspca_dev, 0xe0, 0x00); - break; - default: -/* case SENSOR_OV965X: */ - reg_w_array(gspca_dev, bridge_start_ov965x, - ARRAY_SIZE(bridge_start_ov965x)); - sccb_w_array(gspca_dev, sensor_start_ov965x, - ARRAY_SIZE(sensor_start_ov965x)); - ov534_reg_write(gspca_dev, 0xe0, 0x00); - ov534_set_led(gspca_dev, 1); -/*fixme: other sensor start omitted*/ - } return 0; } static void sd_stopN(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->sensor) { - case SENSOR_OV772X: - ov534_reg_write(gspca_dev, 0xe0, 0x09); - ov534_set_led(gspca_dev, 0); - break; - default: -/* case SENSOR_OV965X: */ - ov534_reg_write(gspca_dev, 0xe0, 0x01); - ov534_set_led(gspca_dev, 0); - ov534_reg_write(gspca_dev, 0xe0, 0x00); - break; - } + /* stop streaming data */ + ov534_reg_write(gspca_dev, 0xe0, 0x09); + ov534_set_led(gspca_dev, 0); } /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ @@ -830,75 +429,75 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, { struct sd *sd = (struct sd *) gspca_dev; __u32 this_pts; - u16 this_fid; + int this_fid; int remaining_len = len; + __u8 *next_data = data; - do { - len = min(remaining_len, 2040); /*fixme: was 2048*/ +scan_next: + if (remaining_len <= 0) + return; + + data = next_data; + len = min(remaining_len, 2048); + remaining_len -= len; + next_data += len; + + /* Payloads are prefixed with a UVC-style header. We + consider a frame to start when the FID toggles, or the PTS + changes. A frame ends when EOF is set, and we've received + the correct number of bytes. */ + + /* Verify UVC header. Header length is always 12 */ + if (data[0] != 12 || len < 12) { + PDEBUG(D_PACK, "bad header"); + goto discard; + } - /* Payloads are prefixed with a UVC-style header. We - consider a frame to start when the FID toggles, or the PTS - changes. A frame ends when EOF is set, and we've received - the correct number of bytes. */ + /* Check errors */ + if (data[1] & UVC_STREAM_ERR) { + PDEBUG(D_PACK, "payload error"); + goto discard; + } - /* Verify UVC header. Header length is always 12 */ - if (data[0] != 12 || len < 12) { - PDEBUG(D_PACK, "bad header"); - goto discard; - } + /* Extract PTS and FID */ + if (!(data[1] & UVC_STREAM_PTS)) { + PDEBUG(D_PACK, "PTS not present"); + goto discard; + } + this_pts = (data[5] << 24) | (data[4] << 16) | (data[3] << 8) | data[2]; + this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0; + + /* If PTS or FID has changed, start a new frame. */ + if (this_pts != sd->last_pts || this_fid != sd->last_fid) { + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); + sd->last_pts = this_pts; + sd->last_fid = this_fid; + } - /* Check errors */ - if (data[1] & UVC_STREAM_ERR) { - PDEBUG(D_PACK, "payload error"); - goto discard; - } + /* Add the data from this payload */ + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + data + 12, len - 12); + + /* If this packet is marked as EOF, end the frame */ + if (data[1] & UVC_STREAM_EOF) { + sd->last_pts = 0; - /* Extract PTS and FID */ - if (!(data[1] & UVC_STREAM_PTS)) { - PDEBUG(D_PACK, "PTS not present"); + if ((frame->data_end - frame->data) != + (gspca_dev->width * gspca_dev->height * 2)) { + PDEBUG(D_PACK, "short frame"); goto discard; } - this_pts = (data[5] << 24) | (data[4] << 16) - | (data[3] << 8) | data[2]; - this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0; - - /* If PTS or FID has changed, start a new frame. */ - if (this_pts != sd->last_pts || this_fid != sd->last_fid) { - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - NULL, 0); - sd->last_pts = this_pts; - sd->last_fid = this_fid; - } - - /* Add the data from this payload */ - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - data + 12, len - 12); - /* If this packet is marked as EOF, end the frame */ - if (data[1] & UVC_STREAM_EOF) { - sd->last_pts = 0; - - if (frame->data_end - frame->data != - gspca_dev->width * gspca_dev->height * 2) { - PDEBUG(D_PACK, "short frame"); - goto discard; - } - - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, - NULL, 0); - } + gspca_frame_add(gspca_dev, LAST_PACKET, frame, NULL, 0); + } - /* Done this payload */ - goto scan_next; + /* Done this payload */ + goto scan_next; discard: - /* Discard data until a new frame starts. */ - gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0); - -scan_next: - remaining_len -= len; - data += len; - } while (remaining_len > 0); + /* Discard data until a new frame starts. */ + gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0); + goto scan_next; } /* get stream parameters (framerate) */ @@ -957,8 +556,9 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X}, - {USB_DEVICE(0x1415, 0x2000), .driver_info = SENSOR_OV772X}, + {USB_DEVICE(0x06f8, 0x3002)}, /* Hercules Blog Webcam */ + {USB_DEVICE(0x06f8, 0x3003)}, /* Hercules Dualpix HD Weblog */ + {USB_DEVICE(0x1415, 0x2000)}, /* Sony HD Eye for PS3 (SLEH 00201) */ {} }; @@ -985,10 +585,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/pac207.c b/trunk/drivers/media/video/gspca/pac207.c index 95a97ab684cd..c90ac852bac0 100644 --- a/trunk/drivers/media/video/gspca/pac207.c +++ b/trunk/drivers/media/video/gspca/pac207.c @@ -256,6 +256,7 @@ static int sd_config(struct gspca_dev *gspca_dev, " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); cam = &gspca_dev->cam; + cam->epaddr = 0x05; cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); sd->brightness = PAC207_BRIGHTNESS_DEFAULT; @@ -535,7 +536,6 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x093a, 0x2470)}, {USB_DEVICE(0x093a, 0x2471)}, {USB_DEVICE(0x093a, 0x2472)}, - {USB_DEVICE(0x093a, 0x2474)}, {USB_DEVICE(0x093a, 0x2476)}, {USB_DEVICE(0x145f, 0x013a)}, {USB_DEVICE(0x2001, 0xf115)}, @@ -565,10 +565,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/pac7311.c b/trunk/drivers/media/video/gspca/pac7311.c index e1e3a3a50484..a9c95cba710e 100644 --- a/trunk/drivers/media/video/gspca/pac7311.c +++ b/trunk/drivers/media/video/gspca/pac7311.c @@ -498,6 +498,7 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; + cam->epaddr = 0x05; sd->sensor = id->driver_info; if (sd->sensor == SENSOR_PAC7302) { @@ -1096,10 +1097,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/sonixb.c b/trunk/drivers/media/video/gspca/sonixb.c index 153d0a91d4b5..b3e4e0677b68 100644 --- a/trunk/drivers/media/video/gspca/sonixb.c +++ b/trunk/drivers/media/video/gspca/sonixb.c @@ -870,6 +870,7 @@ static int sd_config(struct gspca_dev *gspca_dev, gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis; cam = &gspca_dev->cam; + cam->epaddr = 0x01; if (!(sensor_data[sd->sensor].flags & F_SIF)) { cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); @@ -1271,10 +1272,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/sonixj.c b/trunk/drivers/media/video/gspca/sonixj.c index c72e19d3ac37..3373b8d9d2a8 100644 --- a/trunk/drivers/media/video/gspca/sonixj.c +++ b/trunk/drivers/media/video/gspca/sonixj.c @@ -35,47 +35,36 @@ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ atomic_t avg_lum; - u32 exposure; - - u16 brightness; - u8 contrast; - u8 colors; - u8 autogain; - u8 blue; - u8 red; - u8 gamma; - u8 vflip; /* ov7630/ov7648 only */ - u8 infrared; /* mt9v111 only */ - u8 quality; /* image quality */ -#define QUALITY_MIN 60 -#define QUALITY_MAX 95 -#define QUALITY_DEF 80 - u8 jpegqual; /* webcam quality */ - - u8 reg18; - - s8 ag_cnt; + unsigned int exposure; + + __u16 brightness; + __u8 contrast; + __u8 colors; + __u8 autogain; + __u8 blue; + __u8 red; + __u8 vflip; /* ov7630 only */ + __u8 infrared; /* mi0360 only */ + + __s8 ag_cnt; #define AG_CNT_START 13 - u8 bridge; + __u8 qindex; + __u8 bridge; #define BRIDGE_SN9C102P 0 #define BRIDGE_SN9C105 1 #define BRIDGE_SN9C110 2 #define BRIDGE_SN9C120 3 #define BRIDGE_SN9C325 4 - u8 sensor; /* Type of image sensor chip */ + __u8 sensor; /* Type of image sensor chip */ #define SENSOR_HV7131R 0 #define SENSOR_MI0360 1 #define SENSOR_MO4000 2 -#define SENSOR_MT9V111 3 -#define SENSOR_OM6802 4 -#define SENSOR_OV7630 5 -#define SENSOR_OV7648 6 -#define SENSOR_OV7660 7 -#define SENSOR_SP80708 8 - u8 i2c_base; - - u8 *jpeg_hdr; +#define SENSOR_OM6802 3 +#define SENSOR_OV7630 4 +#define SENSOR_OV7648 5 +#define SENSOR_OV7660 6 + __u8 i2c_base; }; /* V4L2 controls supported by the driver */ @@ -89,8 +78,6 @@ static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val); static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val); static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); @@ -171,20 +158,6 @@ static struct ctrl sd_ctrls[] = { .set = sd_setred_balance, .get = sd_getred_balance, }, - { - { - .id = V4L2_CID_GAMMA, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gamma", - .minimum = 0, - .maximum = 40, - .step = 1, -#define GAMMA_DEF 20 - .default_value = GAMMA_DEF, - }, - .set = sd_setgamma, - .get = sd_getgamma, - }, #define AUTOGAIN_IDX 5 { { @@ -200,7 +173,7 @@ static struct ctrl sd_ctrls[] = { .set = sd_setautogain, .get = sd_getautogain, }, -/* ov7630/ov7648 only */ +/* ov7630 only */ #define VFLIP_IDX 6 { { @@ -210,13 +183,13 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, -#define VFLIP_DEF 0 /* vflip def = 1 for ov7630 */ +#define VFLIP_DEF 1 .default_value = VFLIP_DEF, }, .set = sd_setvflip, .get = sd_getvflip, }, -/* mt9v111 only */ +/* mi0360 only */ #define INFRARED_IDX 7 { { @@ -238,22 +211,18 @@ static struct ctrl sd_ctrls[] = { static __u32 ctrl_dis[] = { (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_HV7131R 0 */ - (1 << INFRARED_IDX) | (1 << VFLIP_IDX), + (1 << VFLIP_IDX), /* SENSOR_MI0360 1 */ (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_MO4000 2 */ - (1 << VFLIP_IDX), - /* SENSOR_MT9V111 3 */ (1 << INFRARED_IDX) | (1 << VFLIP_IDX), - /* SENSOR_OM6802 4 */ + /* SENSOR_OM6802 3 */ (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX), - /* SENSOR_OV7630 5 */ - (1 << INFRARED_IDX), - /* SENSOR_OV7648 6 */ + /* SENSOR_OV7630 4 */ (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), - /* SENSOR_OV7660 7 */ + /* SENSOR_OV7648 5 */ (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), - /* SENSOR_SP80708 8 */ + /* SENSOR_OV7660 6 */ }; static const struct v4l2_pix_format vga_mode[] = { @@ -274,228 +243,196 @@ static const struct v4l2_pix_format vga_mode[] = { .priv = 0}, }; -/*Data from sn9c102p+hv7131r */ -static const u8 sn_hv7131[0x1c] = { +/*Data from sn9c102p+hv71331r */ +static const __u8 sn_hv7131[] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20, /* reg8 reg9 rega regb regc regd rege regf */ 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, -/* reg18 reg19 reg1a reg1b */ - 0x0a, 0x00, 0x00, 0x00 +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static const u8 sn_mi0360[0x1c] = { +static const __u8 sn_mi0360[] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, /* reg8 reg9 rega regb regc regd rege regf */ 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, -/* reg18 reg19 reg1a reg1b */ - 0x06, 0x00, 0x00, 0x00 +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static const u8 sn_mo4000[0x1c] = { +static const __u8 sn_mo4000[] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18, + 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18, /* reg8 reg9 rega regb regc regd rege regf */ 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, -/* reg18 reg19 reg1a reg1b */ - 0x08, 0x00, 0x00, 0x00 +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static const u8 sn_mt9v111[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40, -/* reg18 reg19 reg1a reg1b */ - 0x06, 0x00, 0x00, 0x00 -}; - -static const u8 sn_om6802[0x1c] = { +static const __u8 sn_om6802[] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20, /* reg8 reg9 rega regb regc regd rege regf */ 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40, -/* reg18 reg19 reg1a reg1b */ - 0x05, 0x00, 0x00, 0x00 +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf, + 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef, + 0xf7 }; -static const u8 sn_ov7630[0x1c] = { +static const __u8 sn_ov7630[] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20, /* reg8 reg9 rega regb regc regd rege regf */ 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2, -/* reg18 reg19 reg1a reg1b */ - 0x0b, 0x00, 0x00, 0x00 +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static const u8 sn_ov7648[0x1c] = { +static const __u8 sn_ov7648[] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, /* reg8 reg9 rega regb regc regd rege regf */ 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00, -/* reg18 reg19 reg1a reg1b */ - 0x0b, 0x00, 0x00, 0x00 +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static const u8 sn_ov7660[0x1c] = { +static const __u8 sn_ov7660[] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, /* reg8 reg9 rega regb regc regd rege regf */ 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, -/* reg18 reg19 reg1a reg1b */ - 0x07, 0x00, 0x00, 0x00 -}; - -static const u8 sn_sp80708[0x1c] = { -/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20, -/* reg8 reg9 rega regb regc regd rege regf */ - 0x81, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, -/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ - 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00, -/* reg18 reg19 reg1a reg1b */ - 0x07, 0x00, 0x00, 0x00 +/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; /* sequence specific to the sensors - !! index = SENSOR_xxx */ -static const u8 *sn_tb[] = { +static const __u8 *sn_tb[] = { sn_hv7131, sn_mi0360, sn_mo4000, - sn_mt9v111, sn_om6802, sn_ov7630, sn_ov7648, - sn_ov7660, - sn_sp80708 + sn_ov7660 }; -/* default gamma table */ -static const u8 gamma_def[17] = { +static const __u8 gamma_def[] = { 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff }; -/* gamma for sensors HV7131R and MT9V111 */ -static const u8 gamma_spec_1[17] = { - 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d, - 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5 -}; -/* gamma for sensor SP80708 */ -static const u8 gamma_spec_2[17] = { - 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab, - 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6 -}; /* color matrix and offsets */ -static const u8 reg84[] = { +static const __u8 reg84[] = { 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */ 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */ 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */ 0x00, 0x00, 0x00 /* YUV offsets */ }; -static const u8 hv7131r_sensor_init[][8] = { - {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, - {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10}, - {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10}, -/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */ - {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10}, -/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */ - - {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, - {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10}, - {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10}, - {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10}, - {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10}, - {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */ - {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */ - - {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10}, - - {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10}, +static const __u8 hv7131r_sensor_init[][8] = { + {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, + {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10}, + {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10}, + {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10}, + {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, + + {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, + {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10}, + {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10}, + {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10}, + {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10}, + {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */ + {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */ + + {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10}, + + {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10}, {} }; -static const u8 mi0360_sensor_init[][8] = { - {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10}, - {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10}, - {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10}, - {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10}, - {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10}, - {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10}, - {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10}, - {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10}, - {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10}, - {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10}, - - {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, - {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10}, - {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10}, - - {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */ - {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, - {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */ - - {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10}, - {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */ -/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */ -/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */ - {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */ - {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */ +static const __u8 mi0360_sensor_init[][8] = { + {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, + {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10}, + {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10}, + {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10}, + {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10}, + {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10}, + {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10}, + {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10}, + {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10}, + {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10}, + {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10}, + {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10}, + + {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, + {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10}, + {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10}, + {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10}, + + {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */ + {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10}, + {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10}, + {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */ + + {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10}, + {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */ +/* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */ +/* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */ + {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */ + {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */ {} }; -static const u8 mo4000_sensor_init[][8] = { +static const __u8 mo4000_sensor_init[][8] = { {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, @@ -518,49 +455,7 @@ static const u8 mo4000_sensor_init[][8] = { {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, {} }; -static const u8 mt9v111_sensor_init[][8] = { - {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */ - /* delay 20 ms */ - {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */ - {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */ - {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */ - {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */ - {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */ - {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */ - {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */ - {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */ - {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */ - {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */ - {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */ - {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */ - {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */ - {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */ - {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, - /*******/ - {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10}, - {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */ - {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */ - /*******/ - {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */ - {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */ - {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */ - {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */ - {} -}; -static const u8 om6802_sensor_init[][8] = { +static __u8 om6802_sensor_init[][8] = { {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10}, {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10}, {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10}, @@ -594,7 +489,7 @@ static const u8 om6802_sensor_init[][8] = { /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */ {} }; -static const u8 ov7630_sensor_init[][8] = { +static const __u8 ov7630_sensor_init[][8] = { {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, /* win: delay 20ms */ @@ -648,7 +543,7 @@ static const u8 ov7630_sensor_init[][8] = { {} }; -static const u8 ov7648_sensor_init[][8] = { +static const __u8 ov7648_sensor_init[][8] = { {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */ {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, @@ -677,8 +572,7 @@ static const u8 ov7648_sensor_init[][8] = { {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, /*...*/ /* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */ -/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN - * set by setvflip */ +/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */ {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10}, /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */ @@ -695,7 +589,7 @@ static const u8 ov7648_sensor_init[][8] = { {} }; -static const u8 ov7660_sensor_init[][8] = { +static const __u8 ov7660_sensor_init[][8] = { {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ /* (delay 20ms) */ {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, @@ -784,92 +678,28 @@ static const u8 ov7660_sensor_init[][8] = { {} }; -static const u8 sp80708_sensor_init[][8] = { - {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10}, - /********/ - {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10}, - {} +static const __u8 qtable4[] = { + 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06, + 0x06, 0x08, 0x0A, 0x11, + 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15, + 0x19, 0x19, 0x17, 0x15, + 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17, + 0x21, 0x2E, 0x21, 0x23, + 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32, + 0x25, 0x29, 0x2C, 0x29, + 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B, + 0x17, 0x1B, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29 }; /* read bytes to gspca_dev->usb_buf */ static void reg_r(struct gspca_dev *gspca_dev, - u16 value, int len) + __u16 value, int len) { #ifdef GSPCA_DEBUG if (len > USB_BUF_SZ) { @@ -888,10 +718,10 @@ static void reg_r(struct gspca_dev *gspca_dev, } static void reg_w1(struct gspca_dev *gspca_dev, - u16 value, - u8 data) + __u16 value, + __u8 data) { - PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data); + PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data); gspca_dev->usb_buf[0] = data; usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), @@ -903,11 +733,11 @@ static void reg_w1(struct gspca_dev *gspca_dev, 500); } static void reg_w(struct gspca_dev *gspca_dev, - u16 value, - const u8 *buffer, + __u16 value, + const __u8 *buffer, int len) { - PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..", + PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..", value, buffer[0], buffer[1]); #ifdef GSPCA_DEBUG if (len > USB_BUF_SZ) { @@ -926,7 +756,7 @@ static void reg_w(struct gspca_dev *gspca_dev, } /* I2C write 1 byte */ -static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) +static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -951,7 +781,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) /* I2C write 8 bytes */ static void i2c_w8(struct gspca_dev *gspca_dev, - const u8 *buffer) + const __u8 *buffer) { memcpy(gspca_dev->usb_buf, buffer, 8); usb_control_msg(gspca_dev->dev, @@ -965,10 +795,10 @@ static void i2c_w8(struct gspca_dev *gspca_dev, } /* read 5 bytes in gspca_dev->usb_buf */ -static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) +static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg) { struct sd *sd = (struct sd *) gspca_dev; - u8 mode[8]; + __u8 mode[8]; mode[0] = 0x81 | 0x10; mode[1] = sd->i2c_base; @@ -987,7 +817,7 @@ static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg) reg_r(gspca_dev, 0x0a, 5); } -static int hv7131r_probe(struct gspca_dev *gspca_dev) +static int probesensor(struct gspca_dev *gspca_dev) { i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ msleep(10); @@ -1009,66 +839,16 @@ static int hv7131r_probe(struct gspca_dev *gspca_dev) return -ENODEV; } -static void mi0360_probe(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, j; - u16 val = 0; - static const u8 probe_tb[][4][8] = { - { /* mi0360 */ - {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, - {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10} - }, - { /* mt9v111 */ - {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, - {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, - {} - }, - }; - - for (i = 0; i < ARRAY_SIZE(probe_tb); i++) { - reg_w1(gspca_dev, 0x17, 0x62); - reg_w1(gspca_dev, 0x01, 0x08); - for (j = 0; j < 3; j++) - i2c_w8(gspca_dev, probe_tb[i][j]); - msleep(2); - reg_r(gspca_dev, 0x0a, 5); - val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; - if (probe_tb[i][3][0] != 0) - i2c_w8(gspca_dev, probe_tb[i][3]); - reg_w1(gspca_dev, 0x01, 0x29); - reg_w1(gspca_dev, 0x17, 0x42); - if (val != 0xffff) - break; - } - switch (val) { - case 0x823a: - PDEBUG(D_PROBE, "Sensor mt9v111"); - sd->sensor = SENSOR_MT9V111; - sd->i2c_base = 0x5c; - break; - case 0x8243: - PDEBUG(D_PROBE, "Sensor mi0360"); - break; - default: - PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val); - break; - } -} - static int configure_gpio(struct gspca_dev *gspca_dev, - const u8 *sn9c1xx) + const __u8 *sn9c1xx) { struct sd *sd = (struct sd *) gspca_dev; - const u8 *reg9a; - static const u8 reg9a_def[] = + const __u8 *reg9a; + static const __u8 reg9a_def[] = {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; - static const u8 reg9a_sn9c325[] = + static const __u8 reg9a_sn9c325[] = {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; - static const u8 regd4[] = {0x60, 0x00, 0x00}; + static const __u8 regd4[] = {0x60, 0x00, 0x00}; reg_w1(gspca_dev, 0xf1, 0x00); reg_w1(gspca_dev, 0x01, sn9c1xx[1]); @@ -1092,12 +872,6 @@ static int configure_gpio(struct gspca_dev *gspca_dev, reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); switch (sd->sensor) { - case SENSOR_MT9V111: - reg_w1(gspca_dev, 0x01, 0x61); - reg_w1(gspca_dev, 0x17, 0x61); - reg_w1(gspca_dev, 0x01, 0x60); - reg_w1(gspca_dev, 0x01, 0x40); - break; case SENSOR_OM6802: reg_w1(gspca_dev, 0x02, 0x71); reg_w1(gspca_dev, 0x01, 0x42); @@ -1126,20 +900,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev, break; } /* fall thru */ - case SENSOR_SP80708: - reg_w1(gspca_dev, 0x01, 0x63); - reg_w1(gspca_dev, 0x17, 0x20); - reg_w1(gspca_dev, 0x01, 0x62); - reg_w1(gspca_dev, 0x01, 0x42); - mdelay(100); - reg_w1(gspca_dev, 0x02, 0x62); - break; default: reg_w1(gspca_dev, 0x01, 0x43); reg_w1(gspca_dev, 0x17, 0x61); reg_w1(gspca_dev, 0x01, 0x42); if (sd->sensor == SENSOR_HV7131R) { - if (hv7131r_probe(gspca_dev) < 0) + if (probesensor(gspca_dev) < 0) return -ENODEV; } break; @@ -1150,7 +916,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev, static void hv7131R_InitSensor(struct gspca_dev *gspca_dev) { int i = 0; - static const u8 SetSensorClk[] = /* 0x08 Mclk */ + static const __u8 SetSensorClk[] = /* 0x08 Mclk */ { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 }; while (hv7131r_sensor_init[i][0]) { @@ -1180,19 +946,6 @@ static void mo4000_InitSensor(struct gspca_dev *gspca_dev) } } -static void mt9v111_InitSensor(struct gspca_dev *gspca_dev) -{ - int i = 0; - - i2c_w8(gspca_dev, mt9v111_sensor_init[i]); - i++; - msleep(20); - while (mt9v111_sensor_init[i][0]) { - i2c_w8(gspca_dev, mt9v111_sensor_init[i]); - i++; - } -} - static void om6802_InitSensor(struct gspca_dev *gspca_dev) { int i = 0; @@ -1257,19 +1010,6 @@ static void ov7660_InitSensor(struct gspca_dev *gspca_dev) } } -static void sp80708_InitSensor(struct gspca_dev *gspca_dev) -{ - int i = 0; - - i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */ - i++; - msleep(20); - while (sp80708_sensor_init[i][0]) { - i2c_w8(gspca_dev, sp80708_sensor_init[i]); - i++; - } -} - /* this function is called at probe time */ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) @@ -1278,6 +1018,7 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; + cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); @@ -1285,21 +1026,16 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->sensor = id->driver_info >> 8; sd->i2c_base = id->driver_info; + sd->qindex = 4; /* set the quantization table */ sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; sd->blue = BLUE_BALANCE_DEF; sd->red = RED_BALANCE_DEF; - sd->gamma = GAMMA_DEF; sd->autogain = AUTOGAIN_DEF; sd->ag_cnt = -1; - if (sd->sensor != SENSOR_OV7630) - sd->vflip = 0; - else - sd->vflip = 1; + sd->vflip = VFLIP_DEF; sd->infrared = INFRARED_DEF; - sd->quality = QUALITY_DEF; - sd->jpegqual = 80; gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; return 0; @@ -1309,8 +1045,8 @@ static int sd_config(struct gspca_dev *gspca_dev, static int sd_init(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - u8 regGpio[] = { 0x29, 0x74 }; - u8 regF1; + __u8 regGpio[] = { 0x29, 0x74 }; + __u8 regF1; /* setup a selector by bridge */ reg_w1(gspca_dev, 0xf1, 0x01); @@ -1328,15 +1064,11 @@ static int sd_init(struct gspca_dev *gspca_dev) case BRIDGE_SN9C105: if (regF1 != 0x11) return -ENODEV; - if (sd->sensor == SENSOR_MI0360) - mi0360_probe(gspca_dev); reg_w(gspca_dev, 0x01, regGpio, 2); break; case BRIDGE_SN9C120: if (regF1 != 0x12) return -ENODEV; - if (sd->sensor == SENSOR_MI0360) - mi0360_probe(gspca_dev); regGpio[1] = 0x70; reg_w(gspca_dev, 0x01, regGpio, 2); break; @@ -1354,14 +1086,20 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static u32 setexposure(struct gspca_dev *gspca_dev, - u32 expo) +static unsigned int setexposure(struct gspca_dev *gspca_dev, + unsigned int expo) { struct sd *sd = (struct sd *) gspca_dev; + static const __u8 doit[] = /* update sensor */ + { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; + static const __u8 sensorgo[] = /* sensor on */ + { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 }; + static const __u8 gainMo[] = + { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d }; switch (sd->sensor) { case SENSOR_HV7131R: { - u8 Expodoit[] = + __u8 Expodoit[] = { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 }; Expodoit[3] = expo >> 16; @@ -1371,12 +1109,8 @@ static u32 setexposure(struct gspca_dev *gspca_dev, break; } case SENSOR_MI0360: { - u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ + __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 }; - static const u8 doit[] = /* update sensor */ - { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; - static const u8 sensorgo[] = /* sensor on */ - { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 }; if (expo > 0x0635) expo = 0x0635; @@ -1390,12 +1124,10 @@ static u32 setexposure(struct gspca_dev *gspca_dev, break; } case SENSOR_MO4000: { - u8 expoMof[] = + __u8 expoMof[] = { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 }; - u8 expoMo10[] = + __u8 expoMo10[] = { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 }; - static const u8 gainMo[] = - { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d }; if (expo > 0x1fff) expo = 0x1fff; @@ -1407,27 +1139,14 @@ static u32 setexposure(struct gspca_dev *gspca_dev, | ((expo & 0x0003) << 4); i2c_w8(gspca_dev, expoMo10); i2c_w8(gspca_dev, gainMo); - PDEBUG(D_FRAM, "set exposure %d", + PDEBUG(D_CONF, "set exposure %d", ((expoMo10[3] & 0x07) << 10) | (expoMof[3] << 2) | ((expoMo10[3] & 0x30) >> 4)); break; } - case SENSOR_MT9V111: { - u8 expo_c1[] = - { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 }; - - if (expo > 0x0280) - expo = 0x0280; - else if (expo < 0x0040) - expo = 0x0040; - expo_c1[3] = expo >> 8; - expo_c1[4] = expo; - i2c_w8(gspca_dev, expo_c1); - break; - } case SENSOR_OM6802: { - u8 gainOm[] = + __u8 gainOm[] = { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 }; if (expo > 0x03ff) @@ -1437,7 +1156,7 @@ static u32 setexposure(struct gspca_dev *gspca_dev, gainOm[3] = expo >> 2; i2c_w8(gspca_dev, gainOm); reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f); - PDEBUG(D_FRAM, "set exposure %d", gainOm[3]); + PDEBUG(D_CONF, "set exposure %d", gainOm[3]); break; } } @@ -1448,7 +1167,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; unsigned int expo; - u8 k2; + __u8 k2; k2 = ((int) sd->brightness - 0x8000) >> 10; switch (sd->sensor) { @@ -1465,10 +1184,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) expo = sd->brightness >> 4; sd->exposure = setexposure(gspca_dev, expo); break; - case SENSOR_MT9V111: - expo = sd->brightness >> 8; - sd->exposure = setexposure(gspca_dev, expo); - break; case SENSOR_OM6802: expo = sd->brightness >> 6; sd->exposure = setexposure(gspca_dev, expo); @@ -1476,15 +1191,14 @@ static void setbrightness(struct gspca_dev *gspca_dev) break; } - if (sd->sensor != SENSOR_MT9V111) - reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */ + reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */ } static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - u8 k2; - u8 contrast[6]; + __u8 k2; + __u8 contrast[6]; k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */ contrast[0] = (k2 + 1) / 2; /* red */ @@ -1500,8 +1214,8 @@ static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i, v; - u8 reg8a[12]; /* U & V gains */ - static s16 uv[6] = { /* same as reg84 in signed decimal */ + __u8 reg8a[12]; /* U & V gains */ + static __s16 uv[6] = { /* same as reg84 in signed decimal */ -24, -38, 64, /* UR UG UB */ 62, -51, -9 /* VR VG VB */ }; @@ -1522,75 +1236,22 @@ static void setredblue(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x06, sd->blue); } -static void setgamma(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i; - u8 gamma[17]; - const u8 *gamma_base; - static const u8 delta[17] = { - 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a, - 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00 - }; - - switch (sd->sensor) { - case SENSOR_HV7131R: - case SENSOR_MT9V111: - gamma_base = gamma_spec_1; - break; - case SENSOR_SP80708: - gamma_base = gamma_spec_2; - break; - default: - gamma_base = gamma_def; - break; - } - - for (i = 0; i < sizeof gamma; i++) - gamma[i] = gamma_base[i] - + delta[i] * (sd->gamma - GAMMA_DEF) / 32; - reg_w(gspca_dev, 0x20, gamma, sizeof gamma); -} - static void setautogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX)) return; - switch (sd->sensor) { - case SENSOR_OV7630: - case SENSOR_OV7648: { - u8 comb; - - if (sd->sensor == SENSOR_OV7630) - comb = 0xc0; - else - comb = 0xa0; - if (sd->autogain) - comb |= 0x02; - i2c_w1(&sd->gspca_dev, 0x13, comb); - return; - } - } if (sd->autogain) sd->ag_cnt = AG_CNT_START; else sd->ag_cnt = -1; } -/* ov7630/ov7648 only */ static void setvflip(struct sd *sd) { - u8 comn; - - if (sd->sensor == SENSOR_OV7630) - comn = 0x02; - else - comn = 0x06; - if (sd->vflip) - comn |= 0x80; - i2c_w1(&sd->gspca_dev, 0x75, comn); + i2c_w1(&sd->gspca_dev, 0x75, /* COMN */ + sd->vflip ? 0x82 : 0x02); } static void setinfrared(struct sd *sd) @@ -1601,63 +1262,20 @@ static void setinfrared(struct sd *sd) sd->infrared ? 0x66 : 0x64); } -static void setjpegqual(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int i, sc; - - if (sd->jpegqual < 50) - sc = 5000 / sd->jpegqual; - else - sc = 200 - sd->jpegqual * 2; -#if USB_BUF_SZ < 64 -#error "No room enough in usb_buf for quantization table" -#endif - for (i = 0; i < 64; i++) - gspca_dev->usb_buf[i] = - (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100; - usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x08, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0x0100, 0, - gspca_dev->usb_buf, 64, - 500); - for (i = 0; i < 64; i++) - gspca_dev->usb_buf[i] = - (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100; - usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0x08, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0x0140, 0, - gspca_dev->usb_buf, 64, - 500); - - sd->reg18 ^= 0x40; - reg_w1(gspca_dev, 0x18, sd->reg18); -} - /* -- start the camera -- */ static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i; - u8 reg1, reg17; - const u8 *sn9c1xx; + __u8 reg1, reg17, reg18; + const __u8 *sn9c1xx; int mode; - static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; - static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; - static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ - static const u8 CE_ov76xx[] = + static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; + static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; + static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ + static const __u8 CE_ov76xx[] = { 0x32, 0xdd, 0x32, 0xdd }; - /* create the JPEG header */ - sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x21); /* JPEG 422 */ - jpeg_set_qual(sd->jpeg_hdr, sd->quality); - sn9c1xx = sn_tb[(int) sd->sensor]; configure_gpio(gspca_dev, sn9c1xx); @@ -1674,9 +1292,6 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0xc9, 0x3c); reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); switch (sd->sensor) { - case SENSOR_MT9V111: - reg17 = 0xe0; - break; case SENSOR_OV7630: reg17 = 0xe2; break; @@ -1700,24 +1315,14 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */ reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */ reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); - - setgamma(gspca_dev); - + reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def); for (i = 0; i < 8; i++) reg_w(gspca_dev, 0x84, reg84, sizeof reg84); switch (sd->sensor) { - case SENSOR_MT9V111: - reg_w1(gspca_dev, 0x9a, 0x07); - reg_w1(gspca_dev, 0x99, 0x59); - break; case SENSOR_OV7648: reg_w1(gspca_dev, 0x9a, 0x0a); reg_w1(gspca_dev, 0x99, 0x60); break; - case SENSOR_SP80708: - reg_w1(gspca_dev, 0x9a, 0x05); - reg_w1(gspca_dev, 0x99, 0x59); - break; case SENSOR_OV7660: if (sd->bridge == BRIDGE_SN9C120) { reg_w1(gspca_dev, 0x9a, 0x05); @@ -1753,15 +1358,6 @@ static int sd_start(struct gspca_dev *gspca_dev) /* reg1 = 0x06; * 640 clk 24Mz (done) */ } break; - case SENSOR_MT9V111: - mt9v111_InitSensor(gspca_dev); - if (mode) { - reg1 = 0x04; /* 320 clk 48Mhz */ - } else { -/* reg1 = 0x06; * 640 clk 24Mz (done) */ - reg17 = 0xc2; - } - break; case SENSOR_OM6802: om6802_InitSensor(gspca_dev); reg17 = 0x64; /* 640 MCKSIZE */ @@ -1777,7 +1373,8 @@ static int sd_start(struct gspca_dev *gspca_dev) reg17 = 0x21; /* reg1 = 0x42; * 42 - 46? */ break; - case SENSOR_OV7660: + default: +/* case SENSOR_OV7660: */ ov7660_InitSensor(gspca_dev); if (sd->bridge == BRIDGE_SN9C120) { if (mode) { /* 320x240 - 160x120 */ @@ -1790,16 +1387,6 @@ static int sd_start(struct gspca_dev *gspca_dev) * inverse power down */ } break; - default: -/* case SENSOR_SP80708: */ - sp80708_InitSensor(gspca_dev); - if (mode) { -/*?? reg1 = 0x04; * 320 clk 48Mhz */ - } else { - reg1 = 0x46; /* 640 clk 48Mz */ - reg17 = 0xa2; - } - break; } reg_w(gspca_dev, 0xc0, C0, 6); reg_w(gspca_dev, 0xca, CA, 4); @@ -1816,13 +1403,20 @@ static int sd_start(struct gspca_dev *gspca_dev) } /* here change size mode 0 -> VGA; 1 -> CIF */ - sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40; - reg_w1(gspca_dev, 0x18, sd->reg18); - setjpegqual(gspca_dev); + reg18 = sn9c1xx[0x18] | (mode << 4); + reg_w1(gspca_dev, 0x18, reg18 | 0x40); + + reg_w(gspca_dev, 0x100, qtable4, 0x40); + reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); + + reg_w1(gspca_dev, 0x18, reg18); reg_w1(gspca_dev, 0x17, reg17); reg_w1(gspca_dev, 0x01, reg1); switch (sd->sensor) { + case SENSOR_MI0360: + setinfrared(sd); + break; case SENSOR_OV7630: setvflip(sd); break; @@ -1836,14 +1430,14 @@ static int sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - static const u8 stophv7131[] = + static const __u8 stophv7131[] = { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 }; - static const u8 stopmi0360[] = + static const __u8 stopmi0360[] = { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; - static const u8 stopov7648[] = + static const __u8 stopov7648[] = { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 }; - u8 data; - const u8 *sn9c1xx; + __u8 data; + const __u8 *sn9c1xx; data = 0x0b; switch (sd->sensor) { @@ -1858,7 +1452,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev) case SENSOR_OV7648: i2c_w8(gspca_dev, stopov7648); /* fall thru */ - case SENSOR_MT9V111: case SENSOR_OV7630: data = 0x29; break; @@ -1875,20 +1468,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0xf1, 0x00); } -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - kfree(sd->jpeg_hdr); -} - static void do_autogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int delta; int expotimes; - u8 luma_mean = 130; - u8 luma_delta = 20; + __u8 luma_mean = 130; + __u8 luma_delta = 20; /* Thanks S., without your advice, autobright should not work :) */ if (sd->ag_cnt < 0) @@ -1913,7 +1499,6 @@ static void do_autogain(struct gspca_dev *gspca_dev) default: /* case SENSOR_MO4000: */ /* case SENSOR_MI0360: */ -/* case SENSOR_MT9V111: */ /* case SENSOR_OM6802: */ expotimes = sd->exposure; expotimes += (luma_mean - delta) >> 6; @@ -1931,7 +1516,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) /* This function is run at interrupt level. */ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - u8 *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -1965,8 +1550,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, if (gspca_dev->last_packet_type == LAST_PACKET) { /* put the JPEG 422 header */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - sd->jpeg_hdr, JPEG_HDR_SZ); + jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21); } gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } @@ -2061,24 +1645,6 @@ static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->gamma = val; - if (gspca_dev->streaming) - setgamma(gspca_dev); - return 0; -} - -static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->gamma; - return 0; -} - static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -2133,34 +1699,6 @@ static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -static int sd_set_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (jcomp->quality < QUALITY_MIN) - sd->quality = QUALITY_MIN; - else if (jcomp->quality > QUALITY_MAX) - sd->quality = QUALITY_MAX; - else - sd->quality = jcomp->quality; - if (gspca_dev->streaming) - jpeg_set_qual(sd->jpeg_hdr, sd->quality); - return 0; -} - -static int sd_get_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - memset(jcomp, 0, sizeof *jcomp); - jcomp->quality = sd->quality; - jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT - | V4L2_JPEG_MARKER_DQT; - return 0; -} - /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -2170,11 +1708,8 @@ static const struct sd_desc sd_desc = { .init = sd_init, .start = sd_start, .stopN = sd_stopN, - .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan, .dq_callback = do_autogain, - .get_jcomp = sd_get_jcomp, - .set_jcomp = sd_set_jcomp, }; /* -- module initialisation -- */ @@ -2189,7 +1724,9 @@ static const __devinitdata struct usb_device_id device_table[] = { #endif {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, +#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)}, +#endif {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)}, {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)}, @@ -2227,10 +1764,10 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)}, #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)}, -#endif {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */ - {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)}, +#endif + {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); @@ -2257,10 +1794,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; info("registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/spca500.c b/trunk/drivers/media/video/gspca/spca500.c index 6f38fa6d86b6..942f04cd44dd 100644 --- a/trunk/drivers/media/video/gspca/spca500.c +++ b/trunk/drivers/media/video/gspca/spca500.c @@ -38,11 +38,8 @@ struct sd { unsigned char brightness; unsigned char contrast; unsigned char colors; - u8 quality; -#define QUALITY_MIN 70 -#define QUALITY_MAX 95 -#define QUALITY_DEF 85 + char qindex; char subtype; #define AgfaCl20 0 #define AiptekPocketDV 1 @@ -59,8 +56,6 @@ struct sd { #define Optimedia 12 #define PalmPixDC85 13 #define ToptroIndus 14 - - u8 *jpeg_hdr; }; /* V4L2 controls supported by the driver */ @@ -634,6 +629,7 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; + cam->epaddr = 0x01; sd->subtype = id->driver_info; if (sd->subtype != LogitechClickSmart310) { cam->cam_mode = vga_mode; @@ -642,10 +638,10 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); } + sd->qindex = 5; sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; - sd->quality = QUALITY_DEF; return 0; } @@ -671,12 +667,6 @@ static int sd_start(struct gspca_dev *gspca_dev) __u8 Data; __u8 xmult, ymult; - /* create the JPEG header */ - sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x22); /* JPEG 411 */ - jpeg_set_qual(sd->jpeg_hdr, sd->quality); - if (sd->subtype == LogitechClickSmart310) { xmult = 0x16; ymult = 0x12; @@ -723,8 +713,7 @@ static int sd_start(struct gspca_dev *gspca_dev) write_vector(gspca_dev, spca500_visual_defaults); spca500_setmode(gspca_dev, xmult, ymult); /* enable drop packet */ - err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001); - if (err < 0) + reg_w(gspca_dev, 0x00, 0x850a, 0x0001); PDEBUG(D_ERR, "failed to enable drop packet"); reg_w(gspca_dev, 0x00, 0x8880, 3); err = spca50x_setup_qtable(gspca_dev, @@ -892,13 +881,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev) gspca_dev->usb_buf[0]); } -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - kfree(sd->jpeg_hdr); -} - static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ @@ -919,8 +901,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, ffd9, 2); /* put the JPEG header in the new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - sd->jpeg_hdr, JPEG_HDR_SZ); + jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22); data += SPCA500_OFFSET_DATA; len -= SPCA500_OFFSET_DATA; @@ -956,6 +937,16 @@ static void setbrightness(struct gspca_dev *gspca_dev) (__u8) (sd->brightness - 128)); } +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int ret; + + ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1); + if (ret >= 0) + sd->brightness = ret + 128; +} + static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -963,6 +954,16 @@ static void setcontrast(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x00, 0x8168, sd->contrast); } +static void getcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int ret; + + ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1); + if (ret >= 0) + sd->contrast = ret; +} + static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -970,6 +971,16 @@ static void setcolors(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x00, 0x8169, sd->colors); } +static void getcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int ret; + + ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1); + if (ret >= 0) + sd->colors = ret; +} + static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -984,6 +995,7 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getbrightness(gspca_dev); *val = sd->brightness; return 0; } @@ -1002,6 +1014,7 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getcontrast(gspca_dev); *val = sd->contrast; return 0; } @@ -1020,38 +1033,11 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getcolors(gspca_dev); *val = sd->colors; return 0; } -static int sd_set_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (jcomp->quality < QUALITY_MIN) - sd->quality = QUALITY_MIN; - else if (jcomp->quality > QUALITY_MAX) - sd->quality = QUALITY_MAX; - else - sd->quality = jcomp->quality; - if (gspca_dev->streaming) - jpeg_set_qual(sd->jpeg_hdr, sd->quality); - return 0; -} - -static int sd_get_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - memset(jcomp, 0, sizeof *jcomp); - jcomp->quality = sd->quality; - jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT - | V4L2_JPEG_MARKER_DQT; - return 0; -} - /* sub-driver description */ static struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -1061,10 +1047,7 @@ static struct sd_desc sd_desc = { .init = sd_init, .start = sd_start, .stopN = sd_stopN, - .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan, - .get_jcomp = sd_get_jcomp, - .set_jcomp = sd_set_jcomp, }; /* -- module initialisation -- */ @@ -1110,10 +1093,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/spca501.c b/trunk/drivers/media/video/gspca/spca501.c index d48b27c648ca..82e3e3e2ada1 100644 --- a/trunk/drivers/media/video/gspca/spca501.c +++ b/trunk/drivers/media/video/gspca/spca501.c @@ -1883,6 +1883,10 @@ static void setbrightness(struct gspca_dev *gspca_dev) reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness); } +static void getbrightness(struct gspca_dev *gspca_dev) +{ +} + static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1893,6 +1897,10 @@ static void setcontrast(struct gspca_dev *gspca_dev) sd->contrast & 0xff); } +static void getcontrast(struct gspca_dev *gspca_dev) +{ +} + static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1900,6 +1908,10 @@ static void setcolors(struct gspca_dev *gspca_dev) reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, sd->colors); } +static void getcolors(struct gspca_dev *gspca_dev) +{ +} + static void setblue_balance(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1922,6 +1934,7 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; + cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; sd->subtype = id->driver_info; @@ -2071,6 +2084,7 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getbrightness(gspca_dev); *val = sd->brightness; return 0; } @@ -2089,6 +2103,7 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getcontrast(gspca_dev); *val = sd->contrast; return 0; } @@ -2107,6 +2122,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getcolors(gspca_dev); *val = sd->colors; return 0; } @@ -2195,10 +2211,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/spca505.c b/trunk/drivers/media/video/gspca/spca505.c index 2acec58b1b97..2a33a29010ee 100644 --- a/trunk/drivers/media/video/gspca/spca505.c +++ b/trunk/drivers/media/video/gspca/spca505.c @@ -31,9 +31,9 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - u8 brightness; + unsigned char brightness; - u8 subtype; + char subtype; #define IntelPCCameraPro 0 #define Nxultra 1 }; @@ -43,6 +43,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, @@ -51,8 +52,7 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 255, .step = 1, -#define BRIGHTNESS_DEF 127 - .default_value = BRIGHTNESS_DEF, + .default_value = 127, }, .set = sd_setbrightness, .get = sd_getbrightness, @@ -64,12 +64,12 @@ static const struct v4l2_pix_format vga_mode[] = { .bytesperline = 160, .sizeimage = 160 * 120 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 4}, + .priv = 5}, {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, .bytesperline = 176, .sizeimage = 176 * 144 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 3}, + .priv = 4}, {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, .bytesperline = 320, .sizeimage = 320 * 240 * 3 / 2, @@ -93,7 +93,6 @@ static const struct v4l2_pix_format vga_mode[] = { #define SPCA50X_USB_CTRL 0x00 /* spca505 */ #define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */ - #define SPCA50X_REG_GLOBAL 0x03 /* spca505 */ #define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */ #define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */ @@ -102,230 +101,230 @@ static const struct v4l2_pix_format vga_mode[] = { #define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */ #define SPCA50X_GMISC3_SAA7113RST 0x20 /* Not sure about this one spca505 */ -/* Image format and compression control */ -#define SPCA50X_REG_COMPRESS 0x04 - /* * Data to initialize a SPCA505. Common to the CCD and external modes */ -static const u8 spca505_init_data[][3] = { - /* bmRequest,value,index */ +static const __u16 spca505_init_data[][3] = { + /* line bmRequest,value,index */ + /* 1819 */ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3}, /* Sensor reset */ - {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3}, - {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1}, + /* 1822 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3}, + /* 1825 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1}, /* Block USB reset */ - {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, SPCA50X_GLOBAL_MISC0}, + /* 1828 */ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, + SPCA50X_GLOBAL_MISC0}, - {0x05, 0x01, 0x10}, + /* 1831 */ {0x5, 0x01, 0x10}, /* Maybe power down some stuff */ - {0x05, 0x0f, 0x11}, + /* 1834 */ {0x5, 0x0f, 0x11}, /* Setup internal CCD ? */ - {0x06, 0x10, 0x08}, - {0x06, 0x00, 0x09}, - {0x06, 0x00, 0x0a}, - {0x06, 0x00, 0x0b}, - {0x06, 0x10, 0x0c}, - {0x06, 0x00, 0x0d}, - {0x06, 0x00, 0x0e}, - {0x06, 0x00, 0x0f}, - {0x06, 0x10, 0x10}, - {0x06, 0x02, 0x11}, - {0x06, 0x00, 0x12}, - {0x06, 0x04, 0x13}, - {0x06, 0x02, 0x14}, - {0x06, 0x8a, 0x51}, - {0x06, 0x40, 0x52}, - {0x06, 0xb6, 0x53}, - {0x06, 0x3d, 0x54}, + /* 1837 */ {0x6, 0x10, 0x08}, + /* 1840 */ {0x6, 0x00, 0x09}, + /* 1843 */ {0x6, 0x00, 0x0a}, + /* 1846 */ {0x6, 0x00, 0x0b}, + /* 1849 */ {0x6, 0x10, 0x0c}, + /* 1852 */ {0x6, 0x00, 0x0d}, + /* 1855 */ {0x6, 0x00, 0x0e}, + /* 1858 */ {0x6, 0x00, 0x0f}, + /* 1861 */ {0x6, 0x10, 0x10}, + /* 1864 */ {0x6, 0x02, 0x11}, + /* 1867 */ {0x6, 0x00, 0x12}, + /* 1870 */ {0x6, 0x04, 0x13}, + /* 1873 */ {0x6, 0x02, 0x14}, + /* 1876 */ {0x6, 0x8a, 0x51}, + /* 1879 */ {0x6, 0x40, 0x52}, + /* 1882 */ {0x6, 0xb6, 0x53}, + /* 1885 */ {0x6, 0x3d, 0x54}, {} }; /* * Data to initialize the camera using the internal CCD */ -static const u8 spca505_open_data_ccd[][3] = { - /* bmRequest,value,index */ +static const __u16 spca505_open_data_ccd[][3] = { + /* line bmRequest,value,index */ /* Internal CCD data set */ - {0x03, 0x04, 0x01}, + /* 1891 */ {0x3, 0x04, 0x01}, /* This could be a reset */ - {0x03, 0x00, 0x01}, + /* 1894 */ {0x3, 0x00, 0x01}, /* Setup compression and image registers. 0x6 and 0x7 seem to be related to H&V hold, and are resolution mode specific */ - {0x04, 0x10, 0x01}, + /* 1897 */ {0x4, 0x10, 0x01}, /* DIFF(0x50), was (0x10) */ - {0x04, 0x00, 0x04}, - {0x04, 0x00, 0x05}, - {0x04, 0x20, 0x06}, - {0x04, 0x20, 0x07}, + /* 1900 */ {0x4, 0x00, 0x04}, + /* 1903 */ {0x4, 0x00, 0x05}, + /* 1906 */ {0x4, 0x20, 0x06}, + /* 1909 */ {0x4, 0x20, 0x07}, - {0x08, 0x0a, 0x00}, + /* 1912 */ {0x8, 0x0a, 0x00}, /* DIFF (0x4a), was (0xa) */ - {0x05, 0x00, 0x10}, - {0x05, 0x00, 0x11}, - {0x05, 0x00, 0x00}, + /* 1915 */ {0x5, 0x00, 0x10}, + /* 1918 */ {0x5, 0x00, 0x11}, + /* 1921 */ {0x5, 0x00, 0x00}, /* DIFF not written */ - {0x05, 0x00, 0x01}, + /* 1924 */ {0x5, 0x00, 0x01}, /* DIFF not written */ - {0x05, 0x00, 0x02}, + /* 1927 */ {0x5, 0x00, 0x02}, /* DIFF not written */ - {0x05, 0x00, 0x03}, + /* 1930 */ {0x5, 0x00, 0x03}, /* DIFF not written */ - {0x05, 0x00, 0x04}, + /* 1933 */ {0x5, 0x00, 0x04}, /* DIFF not written */ - {0x05, 0x80, 0x05}, + /* 1936 */ {0x5, 0x80, 0x05}, /* DIFF not written */ - {0x05, 0xe0, 0x06}, + /* 1939 */ {0x5, 0xe0, 0x06}, /* DIFF not written */ - {0x05, 0x20, 0x07}, + /* 1942 */ {0x5, 0x20, 0x07}, /* DIFF not written */ - {0x05, 0xa0, 0x08}, + /* 1945 */ {0x5, 0xa0, 0x08}, /* DIFF not written */ - {0x05, 0x0, 0x12}, + /* 1948 */ {0x5, 0x0, 0x12}, /* DIFF not written */ - {0x05, 0x02, 0x0f}, + /* 1951 */ {0x5, 0x02, 0x0f}, /* DIFF not written */ - {0x05, 0x10, 0x46}, + /* 1954 */ {0x5, 0x10, 0x46}, /* DIFF not written */ - {0x05, 0x8, 0x4a}, + /* 1957 */ {0x5, 0x8, 0x4a}, /* DIFF not written */ - {0x03, 0x08, 0x03}, + /* 1960 */ {0x3, 0x08, 0x03}, /* DIFF (0x3,0x28,0x3) */ - {0x03, 0x08, 0x01}, - {0x03, 0x0c, 0x03}, + /* 1963 */ {0x3, 0x08, 0x01}, + /* 1966 */ {0x3, 0x0c, 0x03}, /* DIFF not written */ - {0x03, 0x21, 0x00}, + /* 1969 */ {0x3, 0x21, 0x00}, /* DIFF (0x39) */ /* Extra block copied from init to hopefully ensure CCD is in a sane state */ - {0x06, 0x10, 0x08}, - {0x06, 0x00, 0x09}, - {0x06, 0x00, 0x0a}, - {0x06, 0x00, 0x0b}, - {0x06, 0x10, 0x0c}, - {0x06, 0x00, 0x0d}, - {0x06, 0x00, 0x0e}, - {0x06, 0x00, 0x0f}, - {0x06, 0x10, 0x10}, - {0x06, 0x02, 0x11}, - {0x06, 0x00, 0x12}, - {0x06, 0x04, 0x13}, - {0x06, 0x02, 0x14}, - {0x06, 0x8a, 0x51}, - {0x06, 0x40, 0x52}, - {0x06, 0xb6, 0x53}, - {0x06, 0x3d, 0x54}, + /* 1837 */ {0x6, 0x10, 0x08}, + /* 1840 */ {0x6, 0x00, 0x09}, + /* 1843 */ {0x6, 0x00, 0x0a}, + /* 1846 */ {0x6, 0x00, 0x0b}, + /* 1849 */ {0x6, 0x10, 0x0c}, + /* 1852 */ {0x6, 0x00, 0x0d}, + /* 1855 */ {0x6, 0x00, 0x0e}, + /* 1858 */ {0x6, 0x00, 0x0f}, + /* 1861 */ {0x6, 0x10, 0x10}, + /* 1864 */ {0x6, 0x02, 0x11}, + /* 1867 */ {0x6, 0x00, 0x12}, + /* 1870 */ {0x6, 0x04, 0x13}, + /* 1873 */ {0x6, 0x02, 0x14}, + /* 1876 */ {0x6, 0x8a, 0x51}, + /* 1879 */ {0x6, 0x40, 0x52}, + /* 1882 */ {0x6, 0xb6, 0x53}, + /* 1885 */ {0x6, 0x3d, 0x54}, /* End of extra block */ - {0x06, 0x3f, 0x1}, + /* 1972 */ {0x6, 0x3f, 0x1}, /* Block skipped */ - {0x06, 0x10, 0x02}, - {0x06, 0x64, 0x07}, - {0x06, 0x10, 0x08}, - {0x06, 0x00, 0x09}, - {0x06, 0x00, 0x0a}, - {0x06, 0x00, 0x0b}, - {0x06, 0x10, 0x0c}, - {0x06, 0x00, 0x0d}, - {0x06, 0x00, 0x0e}, - {0x06, 0x00, 0x0f}, - {0x06, 0x10, 0x10}, - {0x06, 0x02, 0x11}, - {0x06, 0x00, 0x12}, - {0x06, 0x04, 0x13}, - {0x06, 0x02, 0x14}, - {0x06, 0x8a, 0x51}, - {0x06, 0x40, 0x52}, - {0x06, 0xb6, 0x53}, - {0x06, 0x3d, 0x54}, - {0x06, 0x60, 0x57}, - {0x06, 0x20, 0x58}, - {0x06, 0x15, 0x59}, - {0x06, 0x05, 0x5a}, - - {0x05, 0x01, 0xc0}, - {0x05, 0x10, 0xcb}, - {0x05, 0x80, 0xc1}, + /* 1975 */ {0x6, 0x10, 0x02}, + /* 1978 */ {0x6, 0x64, 0x07}, + /* 1981 */ {0x6, 0x10, 0x08}, + /* 1984 */ {0x6, 0x00, 0x09}, + /* 1987 */ {0x6, 0x00, 0x0a}, + /* 1990 */ {0x6, 0x00, 0x0b}, + /* 1993 */ {0x6, 0x10, 0x0c}, + /* 1996 */ {0x6, 0x00, 0x0d}, + /* 1999 */ {0x6, 0x00, 0x0e}, + /* 2002 */ {0x6, 0x00, 0x0f}, + /* 2005 */ {0x6, 0x10, 0x10}, + /* 2008 */ {0x6, 0x02, 0x11}, + /* 2011 */ {0x6, 0x00, 0x12}, + /* 2014 */ {0x6, 0x04, 0x13}, + /* 2017 */ {0x6, 0x02, 0x14}, + /* 2020 */ {0x6, 0x8a, 0x51}, + /* 2023 */ {0x6, 0x40, 0x52}, + /* 2026 */ {0x6, 0xb6, 0x53}, + /* 2029 */ {0x6, 0x3d, 0x54}, + /* 2032 */ {0x6, 0x60, 0x57}, + /* 2035 */ {0x6, 0x20, 0x58}, + /* 2038 */ {0x6, 0x15, 0x59}, + /* 2041 */ {0x6, 0x05, 0x5a}, + + /* 2044 */ {0x5, 0x01, 0xc0}, + /* 2047 */ {0x5, 0x10, 0xcb}, + /* 2050 */ {0x5, 0x80, 0xc1}, /* */ - {0x05, 0x0, 0xc2}, + /* 2053 */ {0x5, 0x0, 0xc2}, /* 4 was 0 */ - {0x05, 0x00, 0xca}, - {0x05, 0x80, 0xc1}, + /* 2056 */ {0x5, 0x00, 0xca}, + /* 2059 */ {0x5, 0x80, 0xc1}, /* */ - {0x05, 0x04, 0xc2}, - {0x05, 0x00, 0xca}, - {0x05, 0x0, 0xc1}, + /* 2062 */ {0x5, 0x04, 0xc2}, + /* 2065 */ {0x5, 0x00, 0xca}, + /* 2068 */ {0x5, 0x0, 0xc1}, /* */ - {0x05, 0x00, 0xc2}, - {0x05, 0x00, 0xca}, - {0x05, 0x40, 0xc1}, + /* 2071 */ {0x5, 0x00, 0xc2}, + /* 2074 */ {0x5, 0x00, 0xca}, + /* 2077 */ {0x5, 0x40, 0xc1}, /* */ - {0x05, 0x17, 0xc2}, - {0x05, 0x00, 0xca}, - {0x05, 0x80, 0xc1}, + /* 2080 */ {0x5, 0x17, 0xc2}, + /* 2083 */ {0x5, 0x00, 0xca}, + /* 2086 */ {0x5, 0x80, 0xc1}, /* */ - {0x05, 0x06, 0xc2}, - {0x05, 0x00, 0xca}, - {0x05, 0x80, 0xc1}, + /* 2089 */ {0x5, 0x06, 0xc2}, + /* 2092 */ {0x5, 0x00, 0xca}, + /* 2095 */ {0x5, 0x80, 0xc1}, /* */ - {0x05, 0x04, 0xc2}, - {0x05, 0x00, 0xca}, + /* 2098 */ {0x5, 0x04, 0xc2}, + /* 2101 */ {0x5, 0x00, 0xca}, - {0x03, 0x4c, 0x3}, - {0x03, 0x18, 0x1}, + /* 2104 */ {0x3, 0x4c, 0x3}, + /* 2107 */ {0x3, 0x18, 0x1}, - {0x06, 0x70, 0x51}, - {0x06, 0xbe, 0x53}, - {0x06, 0x71, 0x57}, - {0x06, 0x20, 0x58}, - {0x06, 0x05, 0x59}, - {0x06, 0x15, 0x5a}, + /* 2110 */ {0x6, 0x70, 0x51}, + /* 2113 */ {0x6, 0xbe, 0x53}, + /* 2116 */ {0x6, 0x71, 0x57}, + /* 2119 */ {0x6, 0x20, 0x58}, + /* 2122 */ {0x6, 0x05, 0x59}, + /* 2125 */ {0x6, 0x15, 0x5a}, - {0x04, 0x00, 0x08}, + /* 2128 */ {0x4, 0x00, 0x08}, /* Compress = OFF (0x1 to turn on) */ - {0x04, 0x12, 0x09}, - {0x04, 0x21, 0x0a}, - {0x04, 0x10, 0x0b}, - {0x04, 0x21, 0x0c}, - {0x04, 0x05, 0x00}, + /* 2131 */ {0x4, 0x12, 0x09}, + /* 2134 */ {0x4, 0x21, 0x0a}, + /* 2137 */ {0x4, 0x10, 0x0b}, + /* 2140 */ {0x4, 0x21, 0x0c}, + /* 2143 */ {0x4, 0x05, 0x00}, /* was 5 (Image Type ? ) */ - {0x04, 0x00, 0x01}, - - {0x06, 0x3f, 0x01}, - - {0x04, 0x00, 0x04}, - {0x04, 0x00, 0x05}, - {0x04, 0x40, 0x06}, - {0x04, 0x40, 0x07}, - - {0x06, 0x1c, 0x17}, - {0x06, 0xe2, 0x19}, - {0x06, 0x1c, 0x1b}, - {0x06, 0xe2, 0x1d}, - {0x06, 0xaa, 0x1f}, - {0x06, 0x70, 0x20}, - - {0x05, 0x01, 0x10}, - {0x05, 0x00, 0x11}, - {0x05, 0x01, 0x00}, - {0x05, 0x05, 0x01}, - {0x05, 0x00, 0xc1}, + /* 2146 */ {0x4, 0x00, 0x01}, + + /* 2149 */ {0x6, 0x3f, 0x01}, + + /* 2152 */ {0x4, 0x00, 0x04}, + /* 2155 */ {0x4, 0x00, 0x05}, + /* 2158 */ {0x4, 0x40, 0x06}, + /* 2161 */ {0x4, 0x40, 0x07}, + + /* 2164 */ {0x6, 0x1c, 0x17}, + /* 2167 */ {0x6, 0xe2, 0x19}, + /* 2170 */ {0x6, 0x1c, 0x1b}, + /* 2173 */ {0x6, 0xe2, 0x1d}, + /* 2176 */ {0x6, 0xaa, 0x1f}, + /* 2179 */ {0x6, 0x70, 0x20}, + + /* 2182 */ {0x5, 0x01, 0x10}, + /* 2185 */ {0x5, 0x00, 0x11}, + /* 2188 */ {0x5, 0x01, 0x00}, + /* 2191 */ {0x5, 0x05, 0x01}, + /* 2194 */ {0x5, 0x00, 0xc1}, /* */ - {0x05, 0x00, 0xc2}, - {0x05, 0x00, 0xca}, + /* 2197 */ {0x5, 0x00, 0xc2}, + /* 2200 */ {0x5, 0x00, 0xca}, - {0x06, 0x70, 0x51}, - {0x06, 0xbe, 0x53}, + /* 2203 */ {0x6, 0x70, 0x51}, + /* 2206 */ {0x6, 0xbe, 0x53}, {} }; /* - * Made by Tomasz Zablocki (skalamandra@poczta.onet.pl) + Made by Tomasz Zablocki (skalamandra@poczta.onet.pl) * SPCA505b chip based cameras initialization data + * */ /* jfm */ #define initial_brightness 0x7f /* 0x0(white)-0xff(black) */ @@ -333,7 +332,7 @@ static const u8 spca505_open_data_ccd[][3] = { /* * Data to initialize a SPCA505. Common to the CCD and external modes */ -static const u8 spca505b_init_data[][3] = { +static const __u16 spca505b_init_data[][3] = { /* start */ {0x02, 0x00, 0x00}, /* init */ {0x02, 0x00, 0x01}, @@ -397,7 +396,7 @@ static const u8 spca505b_init_data[][3] = { /* * Data to initialize the camera using the internal CCD */ -static const u8 spca505b_open_data_ccd[][3] = { +static const __u16 spca505b_open_data_ccd[][3] = { /* {0x02,0x00,0x00}, */ {0x03, 0x04, 0x01}, /* rst */ @@ -427,7 +426,7 @@ static const u8 spca505b_open_data_ccd[][3] = { {0x05, 0x00, 0x12}, {0x05, 0x6f, 0x00}, {0x05, initial_brightness >> 6, 0x00}, - {0x05, (initial_brightness << 2) & 0xff, 0x01}, + {0x05, initial_brightness << 2, 0x01}, {0x05, 0x00, 0x02}, {0x05, 0x01, 0x03}, {0x05, 0x00, 0x04}, @@ -437,7 +436,7 @@ static const u8 spca505b_open_data_ccd[][3] = { {0x05, 0xa0, 0x08}, {0x05, 0x00, 0x12}, {0x05, 0x02, 0x0f}, - {0x05, 0x80, 0x14}, /* max exposure off (0=on) */ + {0x05, 128, 0x14}, /* max exposure off (0=on) */ {0x05, 0x01, 0xb0}, {0x05, 0x01, 0xbf}, {0x03, 0x02, 0x06}, @@ -561,26 +560,26 @@ static const u8 spca505b_open_data_ccd[][3] = { {0x06, 0x32, 0x20}, {0x05, initial_brightness >> 6, 0x00}, - {0x05, (initial_brightness << 2) & 0xff, 0x01}, + {0x05, initial_brightness << 2, 0x01}, {0x05, 0x06, 0xc1}, {0x05, 0x58, 0xc2}, - {0x05, 0x00, 0xca}, - {0x05, 0x00, 0x11}, + {0x05, 0x0, 0xca}, + {0x05, 0x0, 0x11}, {} }; static int reg_write(struct usb_device *dev, - u16 req, u16 index, u16 value) + __u16 reg, __u16 index, __u16 value) { int ret; ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - req, + reg, USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, NULL, 0, 500); - PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d", - req, index, value, ret); + PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x", + reg, index, value, ret); if (ret < 0) PDEBUG(D_ERR, "reg write: error %d", ret); return ret; @@ -588,34 +587,42 @@ static int reg_write(struct usb_device *dev, /* returns: negative is error, pos or zero is data */ static int reg_read(struct gspca_dev *gspca_dev, - u16 req, /* bRequest */ - u16 index) /* wIndex */ + __u16 reg, /* bRequest */ + __u16 index, /* wIndex */ + __u16 length) /* wLength (1 or 2 only) */ { int ret; + gspca_dev->usb_buf[1] = 0; ret = usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0), - req, + reg, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, /* value */ - index, - gspca_dev->usb_buf, 2, + (__u16) 0, /* value */ + (__u16) index, + gspca_dev->usb_buf, length, 500); /* timeout */ - if (ret < 0) - return ret; + if (ret < 0) { + PDEBUG(D_ERR, "reg_read err %d", ret); + return -1; + } return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; } static int write_vector(struct gspca_dev *gspca_dev, - const u8 data[][3]) + const __u16 data[][3]) { struct usb_device *dev = gspca_dev->dev; int ret, i = 0; - while (data[i][0] != 0) { + while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); - if (ret < 0) + if (ret < 0) { + PDEBUG(D_ERR, + "Register write failed for 0x%x,0x%x,0x%x", + data[i][0], data[i][1], data[i][2]); return ret; + } i++; } return 0; @@ -629,13 +636,14 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; + cam->epaddr = 0x01; cam->cam_mode = vga_mode; sd->subtype = id->driver_info; if (sd->subtype != IntelPCCameraPro) - cam->nmodes = ARRAY_SIZE(vga_mode); + cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; else /* no 640x480 for IntelPCCameraPro */ - cam->nmodes = ARRAY_SIZE(vga_mode) - 1; - sd->brightness = BRIGHTNESS_DEF; + cam->nmodes = sizeof vga_mode / sizeof vga_mode[0] - 1; + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; if (sd->subtype == Nxultra) { if (write_vector(gspca_dev, spca505b_init_data)) @@ -649,72 +657,82 @@ static int sd_config(struct gspca_dev *gspca_dev, /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) -{ - return 0; -} - -static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - u8 brightness = sd->brightness; - - reg_write(gspca_dev->dev, 0x05, 0x00, (255 - brightness) >> 6); - reg_write(gspca_dev->dev, 0x05, 0x01, (255 - brightness) << 2); -} - -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; - int ret, mode; - static u8 mode_tb[][3] = { - /* r00 r06 r07 */ - {0x00, 0x10, 0x10}, /* 640x480 */ - {0x01, 0x1a, 0x1a}, /* 352x288 */ - {0x02, 0x1c, 0x1d}, /* 320x240 */ - {0x04, 0x34, 0x34}, /* 176x144 */ - {0x05, 0x40, 0x40} /* 160x120 */ - }; + int ret; + PDEBUG(D_STREAM, "Initializing SPCA505"); if (sd->subtype == Nxultra) write_vector(gspca_dev, spca505b_open_data_ccd); else write_vector(gspca_dev, spca505_open_data_ccd); - ret = reg_read(gspca_dev, 0x06, 0x16); + ret = reg_read(gspca_dev, 6, 0x16, 2); if (ret < 0) { - PDEBUG(D_ERR|D_CONF, - "register read failed err: %d", + PDEBUG(D_ERR|D_STREAM, + "register read failed for after vector read err = %d", ret); - return ret; + return -EIO; } - if (ret != 0x0101) { - PDEBUG(D_ERR|D_CONF, - "After vector read returns 0x%04x should be 0x0101", - ret); + PDEBUG(D_STREAM, + "After vector read returns : 0x%x should be 0x0101", + ret & 0xffff); + + ret = reg_write(gspca_dev->dev, 6, 0x16, 0x0a); + if (ret < 0) { + PDEBUG(D_ERR, "register write failed for (6,0xa,0x16) err=%d", + ret); + return -EIO; } + reg_write(gspca_dev->dev, 5, 0xc2, 18); + return 0; +} - ret = reg_write(gspca_dev->dev, 0x06, 0x16, 0x0a); - if (ret < 0) - return ret; - reg_write(gspca_dev->dev, 0x05, 0xc2, 0x12); +static int sd_start(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + int ret; /* necessary because without it we can see stream * only once after loading module */ /* stopping usb registers Tomasz change */ - reg_write(dev, 0x02, 0x00, 0x00); - - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; - reg_write(dev, SPCA50X_REG_COMPRESS, 0x00, mode_tb[mode][0]); - reg_write(dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]); - reg_write(dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]); - + reg_write(dev, 0x02, 0x0, 0x0); + switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { + case 0: + reg_write(dev, 0x04, 0x00, 0x00); + reg_write(dev, 0x04, 0x06, 0x10); + reg_write(dev, 0x04, 0x07, 0x10); + break; + case 1: + reg_write(dev, 0x04, 0x00, 0x01); + reg_write(dev, 0x04, 0x06, 0x1a); + reg_write(dev, 0x04, 0x07, 0x1a); + break; + case 2: + reg_write(dev, 0x04, 0x00, 0x02); + reg_write(dev, 0x04, 0x06, 0x1c); + reg_write(dev, 0x04, 0x07, 0x1d); + break; + case 4: + reg_write(dev, 0x04, 0x00, 0x04); + reg_write(dev, 0x04, 0x06, 0x34); + reg_write(dev, 0x04, 0x07, 0x34); + break; + default: +/* case 5: */ + reg_write(dev, 0x04, 0x00, 0x05); + reg_write(dev, 0x04, 0x06, 0x40); + reg_write(dev, 0x04, 0x07, 0x40); + break; + } +/* Enable ISO packet machine - should we do this here or in ISOC init ? */ ret = reg_write(dev, SPCA50X_REG_USB, SPCA50X_USB_CTRL, SPCA50X_CUSB_ENABLE); - setbrightness(gspca_dev); - +/* reg_write(dev, 0x5, 0x0, 0x0); */ +/* reg_write(dev, 0x5, 0x0, 0x1); */ +/* reg_write(dev, 0x5, 0x11, 0x2); */ return ret; } @@ -732,15 +750,15 @@ static void sd_stop0(struct gspca_dev *gspca_dev) /* This maybe reset or power control */ reg_write(gspca_dev->dev, 0x03, 0x03, 0x20); - reg_write(gspca_dev->dev, 0x03, 0x01, 0x00); - reg_write(gspca_dev->dev, 0x03, 0x00, 0x01); - reg_write(gspca_dev->dev, 0x05, 0x10, 0x01); - reg_write(gspca_dev->dev, 0x05, 0x11, 0x0f); + reg_write(gspca_dev->dev, 0x03, 0x01, 0x0); + reg_write(gspca_dev->dev, 0x03, 0x00, 0x1); + reg_write(gspca_dev->dev, 0x05, 0x10, 0x1); + reg_write(gspca_dev->dev, 0x05, 0x11, 0xf); } static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - u8 *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { switch (data[0]) { @@ -753,6 +771,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, data, len); break; case 0xff: /* drop */ +/* gspca_dev->last_packet_type = DISCARD_PACKET; */ break; default: data += 1; @@ -763,6 +782,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } } +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + __u8 brightness = sd->brightness; + reg_write(gspca_dev->dev, 5, 0x00, (255 - brightness) >> 6); + reg_write(gspca_dev->dev, 5, 0x01, (255 - brightness) << 2); + +} +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = 255 + - ((reg_read(gspca_dev, 5, 0x01, 1) >> 2) + + (reg_read(gspca_dev, 5, 0x0, 1) << 6)); +} + static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -777,6 +814,7 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getbrightness(gspca_dev); *val = sd->brightness; return 0; } @@ -825,11 +863,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/spca506.c b/trunk/drivers/media/video/gspca/spca506.c index 3a0c893f942d..96e2512e0621 100644 --- a/trunk/drivers/media/video/gspca/spca506.c +++ b/trunk/drivers/media/video/gspca/spca506.c @@ -193,6 +193,24 @@ static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur, } } +static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg) +{ + int retry = 60; + + reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004); + reg_w(gspca_dev->dev, 0x07, reg, 0x0001); + reg_w(gspca_dev->dev, 0x07, 0x01, 0x0002); + while (--retry) { + reg_r(gspca_dev, 0x07, 0x0003, 2); + if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00) + break; + } + if (retry == 0) + return -1; + reg_r(gspca_dev, 0x07, 0x0000, 1); + return gspca_dev->usb_buf[0]; +} + static void spca506_SetNormeInput(struct gspca_dev *gspca_dev, __u16 norme, __u16 channel) @@ -285,6 +303,7 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; + cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; @@ -577,6 +596,13 @@ static void setbrightness(struct gspca_dev *gspca_dev) spca506_WriteI2c(gspca_dev, 0x01, 0x09); } +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = spca506_ReadI2c(gspca_dev, SAA7113_bright); +} + static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -586,6 +612,13 @@ static void setcontrast(struct gspca_dev *gspca_dev) spca506_WriteI2c(gspca_dev, 0x01, 0x09); } +static void getcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = spca506_ReadI2c(gspca_dev, SAA7113_contrast); +} + static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -595,6 +628,13 @@ static void setcolors(struct gspca_dev *gspca_dev) spca506_WriteI2c(gspca_dev, 0x01, 0x09); } +static void getcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = spca506_ReadI2c(gspca_dev, SAA7113_saturation); +} + static void sethue(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -604,6 +644,13 @@ static void sethue(struct gspca_dev *gspca_dev) spca506_WriteI2c(gspca_dev, 0x01, 0x09); } +static void gethue(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->hue = spca506_ReadI2c(gspca_dev, SAA7113_hue); +} + static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -618,6 +665,7 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getbrightness(gspca_dev); *val = sd->brightness; return 0; } @@ -636,6 +684,7 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getcontrast(gspca_dev); *val = sd->contrast; return 0; } @@ -654,6 +703,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getcolors(gspca_dev); *val = sd->colors; return 0; } @@ -672,6 +722,7 @@ static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + gethue(gspca_dev); *val = sd->hue; return 0; } @@ -721,10 +772,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/spca508.c b/trunk/drivers/media/video/gspca/spca508.c index adacf8437661..be5d740a315d 100644 --- a/trunk/drivers/media/video/gspca/spca508.c +++ b/trunk/drivers/media/video/gspca/spca508.c @@ -101,7 +101,8 @@ static const struct v4l2_pix_format sif_mode[] = { * Initialization data: this is the first set-up data written to the * device (before the open data). */ -static const u16 spca508_init_data[][2] = +static const __u16 spca508_init_data[][3] = +#define IGN(x) /* nothing */ { /* line URB value, index */ /* 44274 1804 */ {0x0000, 0x870b}, @@ -588,10 +589,11 @@ static const u16 spca508_init_data[][2] = {} }; + /* * Initialization data for Intel EasyPC Camera CS110 */ -static const u16 spca508cs110_init_data[][2] = { +static const __u16 spca508cs110_init_data[][3] = { {0x0000, 0x870b}, /* Reset CTL3 */ {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ {0x0000, 0x8111}, /* Normal operation on reset */ @@ -675,7 +677,7 @@ static const u16 spca508cs110_init_data[][2] = { {} }; -static const u16 spca508_sightcam_init_data[][2] = { +static const __u16 spca508_sightcam_init_data[][3] = { /* This line seems to setup the frame/canvas */ /*368 */ {0x000f, 0x8402}, @@ -758,7 +760,7 @@ static const u16 spca508_sightcam_init_data[][2] = { {} }; -static const u16 spca508_sightcam2_init_data[][2] = { +static const __u16 spca508_sightcam2_init_data[][3] = { /* 35 */ {0x0020, 0x8112}, /* 36 */ {0x000f, 0x8402}, @@ -1105,7 +1107,7 @@ static const u16 spca508_sightcam2_init_data[][2] = { /* * Initialization data for Creative Webcam Vista */ -static const u16 spca508_vista_init_data[][2] = { +static const __u16 spca508_vista_init_data[][3] = { {0x0008, 0x8200}, /* Clear register */ {0x0000, 0x870b}, /* Reset CTL3 */ {0x0020, 0x8112}, /* Video Drop packet enable */ @@ -1307,18 +1309,18 @@ static const u16 spca508_vista_init_data[][2] = { {0x0050, 0x8703}, {0x0002, 0x8704}, /* External input CKIx1 */ - {0x0001, 0x870c}, /* Select CKOx2 output */ - {0x009a, 0x8600}, /* Line memory Read Counter (L) */ + {0x0001, 0x870C}, /* Select CKOx2 output */ + {0x009A, 0x8600}, /* Line memory Read Counter (L) */ {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ {0x0023, 0x8601}, {0x0010, 0x8602}, - {0x000a, 0x8603}, + {0x000A, 0x8603}, {0x009A, 0x8600}, - {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ - {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */ - {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */ - {0x0048, 0x865e}, /* Vertical valid lines window (L) */ - {0x0000, 0x865f}, + {0x0001, 0x865B}, /* 1 Horizontal Offset for Valid Pixel(L) */ + {0x0003, 0x865C}, /* Vertical offset for valid lines (L) */ + {0x0058, 0x865D}, /* Horizontal valid pixels window (L) */ + {0x0048, 0x865E}, /* Vertical valid lines window (L) */ + {0x0000, 0x865F}, {0x0006, 0x8660}, /* Enable nibble data input, select nibble input order */ @@ -1326,63 +1328,63 @@ static const u16 spca508_vista_init_data[][2] = { {0x0013, 0x8608}, /* A11 Coeficients for color correction */ {0x0028, 0x8609}, /* Note: these values are confirmed at the end of array */ - {0x0005, 0x860a}, /* ... */ - {0x0025, 0x860b}, - {0x00e1, 0x860c}, - {0x00fa, 0x860D}, - {0x00f4, 0x860e}, - {0x00e8, 0x860f}, + {0x0005, 0x860A}, /* ... */ + {0x0025, 0x860B}, + {0x00E1, 0x860C}, + {0x00FA, 0x860D}, + {0x00F4, 0x860E}, + {0x00E8, 0x860F}, {0x0025, 0x8610}, /* A33 Coef. */ - {0x00fc, 0x8611}, /* White balance offset: R */ + {0x00FC, 0x8611}, /* White balance offset: R */ {0x0001, 0x8612}, /* White balance offset: Gr */ - {0x00fe, 0x8613}, /* White balance offset: B */ + {0x00FE, 0x8613}, /* White balance offset: B */ {0x0000, 0x8614}, /* White balance offset: Gb */ {0x0064, 0x8651}, /* R gain for white balance (L) */ {0x0040, 0x8652}, /* Gr gain for white balance (L) */ {0x0066, 0x8653}, /* B gain for white balance (L) */ {0x0040, 0x8654}, /* Gb gain for white balance (L) */ - {0x0001, 0x863f}, /* Enable fixed gamma correction */ + {0x0001, 0x863F}, /* Enable fixed gamma correction */ - {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */ + {0x00A1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */ /* UV division: UV no change, Enable New edge enhancement */ {0x0018, 0x8657}, /* Edge gain high threshold */ {0x0020, 0x8658}, /* Edge gain low threshold */ {0x000A, 0x8659}, /* Edge bandwidth high threshold */ - {0x0005, 0x865a}, /* Edge bandwidth low threshold */ + {0x0005, 0x865A}, /* Edge bandwidth low threshold */ {0x0064, 0x8607}, /* UV filter enable */ {0x0016, 0x8660}, - {0x0000, 0x86b0}, /* Bad pixels compensation address */ - {0x00dc, 0x86b1}, /* X coord for bad pixels compensation (L) */ - {0x0000, 0x86b2}, - {0x0009, 0x86b3}, /* Y coord for bad pixels compensation (L) */ - {0x0000, 0x86b4}, - - {0x0001, 0x86b0}, - {0x00f5, 0x86b1}, - {0x0000, 0x86b2}, - {0x00c6, 0x86b3}, - {0x0000, 0x86b4}, - - {0x0002, 0x86b0}, - {0x001c, 0x86b1}, - {0x0001, 0x86b2}, - {0x00d7, 0x86b3}, - {0x0000, 0x86b4}, - - {0x0003, 0x86b0}, - {0x001c, 0x86b1}, - {0x0001, 0x86b2}, - {0x00d8, 0x86b3}, - {0x0000, 0x86b4}, - - {0x0004, 0x86b0}, - {0x001d, 0x86b1}, - {0x0001, 0x86b2}, - {0x00d8, 0x86b3}, - {0x0000, 0x86b4}, - {0x001e, 0x8660}, + {0x0000, 0x86B0}, /* Bad pixels compensation address */ + {0x00DC, 0x86B1}, /* X coord for bad pixels compensation (L) */ + {0x0000, 0x86B2}, + {0x0009, 0x86B3}, /* Y coord for bad pixels compensation (L) */ + {0x0000, 0x86B4}, + + {0x0001, 0x86B0}, + {0x00F5, 0x86B1}, + {0x0000, 0x86B2}, + {0x00C6, 0x86B3}, + {0x0000, 0x86B4}, + + {0x0002, 0x86B0}, + {0x001C, 0x86B1}, + {0x0001, 0x86B2}, + {0x00D7, 0x86B3}, + {0x0000, 0x86B4}, + + {0x0003, 0x86B0}, + {0x001C, 0x86B1}, + {0x0001, 0x86B2}, + {0x00D8, 0x86B3}, + {0x0000, 0x86B4}, + + {0x0004, 0x86B0}, + {0x001D, 0x86B1}, + {0x0001, 0x86B2}, + {0x00D8, 0x86B3}, + {0x0000, 0x86B4}, + {0x001E, 0x8660}, /* READ { 0, 0x0000, 0x8608 } -> 0000: 13 */ @@ -1447,7 +1449,7 @@ static int reg_read(struct gspca_dev *gspca_dev, } static int write_vector(struct gspca_dev *gspca_dev, - const u16 data[][2]) + const __u16 data[][3]) { struct usb_device *dev = gspca_dev->dev; int ret, i = 0; @@ -1485,6 +1487,7 @@ static int sd_config(struct gspca_dev *gspca_dev, PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1); cam = &gspca_dev->cam; + cam->epaddr = 0x01; cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); @@ -1590,6 +1593,13 @@ static void setbrightness(struct gspca_dev *gspca_dev) reg_write(gspca_dev->dev, 0x8654, brightness); } +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = reg_read(gspca_dev, 0x8651); +} + static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -1604,6 +1614,7 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getbrightness(gspca_dev); *val = sd->brightness; return 0; } @@ -1655,11 +1666,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/spca561.c b/trunk/drivers/media/video/gspca/spca561.c index c99c5e34e211..3c9288019e96 100644 --- a/trunk/drivers/media/video/gspca/spca561.c +++ b/trunk/drivers/media/video/gspca/spca561.c @@ -141,38 +141,38 @@ static const struct v4l2_pix_format sif_072a_mode[] = { #define SPCA561_OFFSET_WIN1GBAVE 14 #define SPCA561_OFFSET_FREQ 15 #define SPCA561_OFFSET_VSYNC 16 +#define SPCA561_OFFSET_DATA 1 #define SPCA561_INDEX_I2C_BASE 0x8800 #define SPCA561_SNAPBIT 0x20 #define SPCA561_SNAPCTRL 0x40 -static const u16 rev72a_reset[][2] = { +static const __u16 rev72a_init_data1[][2] = { {0x0000, 0x8114}, /* Software GPIO output data */ {0x0001, 0x8114}, /* Software GPIO output data */ {0x0000, 0x8112}, /* Some kind of reset */ - {} -}; -static const __u16 rev72a_init_data1[][2] = { {0x0003, 0x8701}, /* PCLK clock delay adjustment */ {0x0001, 0x8703}, /* HSYNC from cmos inverted */ {0x0011, 0x8118}, /* Enable and conf sensor */ {0x0001, 0x8118}, /* Conf sensor */ {0x0092, 0x8804}, /* I know nothing about these */ {0x0010, 0x8802}, /* 0x88xx registers, so I won't */ + {0x000d, 0x8805}, /* sensor default setting */ {} }; -static const u16 rev72a_init_sensor1[][2] = { - {0x0001, 0x000d}, - {0x0002, 0x0018}, - {0x0004, 0x0165}, - {0x0005, 0x0021}, - {0x0007, 0x00aa}, - {0x0020, 0x1504}, - {0x0039, 0x0002}, - {0x0035, 0x0010}, - {0x0009, 0x1049}, - {0x0028, 0x000b}, - {0x003b, 0x000f}, - {0x003c, 0x0000}, +static const __u16 rev72a_init_sensor1[][2] = { + /* ms-win values */ + {0x0001, 0x0018}, /* 0x01 <- 0x0d */ + {0x0002, 0x0065}, /* 0x02 <- 0x18 */ + {0x0004, 0x0121}, /* 0x04 <- 0x0165 */ + {0x0005, 0x00aa}, /* 0x05 <- 0x21 */ + {0x0007, 0x0004}, /* 0x07 <- 0xaa */ + {0x0020, 0x1502}, /* 0x20 <- 0x1504 */ + {0x0039, 0x0010}, /* 0x39 <- 0x02 */ + {0x0035, 0x0049}, /* 0x35 <- 0x10 */ + {0x0009, 0x100b}, /* 0x09 <- 0x1049 */ + {0x0028, 0x000f}, /* 0x28 <- 0x0b */ + {0x003b, 0x003c}, /* 0x3b <- 0x0f */ + {0x003c, 0x0000}, /* 0x3c <- 0x00 */ {} }; static const __u16 rev72a_init_data2[][2] = { @@ -190,10 +190,15 @@ static const __u16 rev72a_init_data2[][2] = { {0x0002, 0x8201}, /* Output address for r/w serial EEPROM */ {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ {0x0001, 0x8200}, /* OprMode to be executed by hardware */ -/* from ms-win */ - {0x0000, 0x8611}, /* R offset for white balance */ - {0x00fd, 0x8612}, /* Gr offset for white balance */ - {0x0003, 0x8613}, /* B offset for white balance */ + {0x0007, 0x8201}, /* Output address for r/w serial EEPROM */ + {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ + {0x0001, 0x8200}, /* OprMode to be executed by hardware */ + {0x0010, 0x8660}, /* Compensation memory stuff */ + {0x0018, 0x8660}, /* Compensation memory stuff */ + + {0x0004, 0x8611}, /* R offset for white balance */ + {0x0004, 0x8612}, /* Gr offset for white balance */ + {0x0007, 0x8613}, /* B offset for white balance */ {0x0000, 0x8614}, /* Gb offset for white balance */ /* from ms-win */ {0x0035, 0x8651}, /* R gain for white balance */ @@ -201,8 +206,8 @@ static const __u16 rev72a_init_data2[][2] = { {0x005f, 0x8653}, /* B gain for white balance */ {0x0040, 0x8654}, /* Gb gain for white balance */ {0x0002, 0x8502}, /* Maximum average bit rate stuff */ - {0x0011, 0x8802}, + {0x0011, 0x8802}, {0x0087, 0x8700}, /* Set master clock (96Mhz????) */ {0x0081, 0x8702}, /* Master clock output enable */ @@ -213,15 +218,104 @@ static const __u16 rev72a_init_data2[][2] = { {0x0003, 0x865c}, /* Vertical offset for valid lines */ {} }; -static const u16 rev72a_init_sensor2[][2] = { - {0x0003, 0x0121}, - {0x0004, 0x0165}, - {0x0005, 0x002f}, /* blanking control column */ - {0x0006, 0x0000}, /* blanking mode row*/ - {0x000a, 0x0002}, - {0x0009, 0x1061}, /* setexposure times && pixel clock +static const __u16 rev72a_init_sensor2[][2] = { + /* ms-win values */ + {0x0003, 0x0121}, /* 0x03 <- 0x01 0x21 //289 */ + {0x0004, 0x0165}, /* 0x04 <- 0x01 0x65 //357 */ + {0x0005, 0x002f}, /* 0x05 <- 0x2f */ + {0x0006, 0x0000}, /* 0x06 <- 0 */ + {0x000a, 0x0002}, /* 0x0a <- 2 */ + {0x0009, 0x1061}, /* 0x09 <- 0x1061 */ + {0x0035, 0x0014}, /* 0x35 <- 0x14 */ + {} +}; +static const __u16 rev72a_init_data3[][2] = { + {0x0030, 0x8112}, /* ISO and drop packet enable */ +/*fixme: should stop here*/ + {0x0000, 0x8112}, /* Some kind of reset ???? */ + {0x0009, 0x8118}, /* Enable sensor and set standby */ + {0x0000, 0x8114}, /* Software GPIO output data */ + {0x0000, 0x8114}, /* Software GPIO output data */ + {0x0001, 0x8114}, /* Software GPIO output data */ + {0x0000, 0x8112}, /* Some kind of reset ??? */ + {0x0003, 0x8701}, + {0x0001, 0x8703}, + {0x0011, 0x8118}, + {0x0001, 0x8118}, + /***************/ + {0x0092, 0x8804}, + {0x0010, 0x8802}, + {0x000d, 0x8805}, + {0x0001, 0x8801}, + {0x0000, 0x8800}, + {0x0018, 0x8805}, + {0x0002, 0x8801}, + {0x0000, 0x8800}, + {0x0065, 0x8805}, + {0x0004, 0x8801}, + {0x0001, 0x8800}, + {0x0021, 0x8805}, + {0x0005, 0x8801}, + {0x0000, 0x8800}, + {0x00aa, 0x8805}, + {0x0007, 0x8801}, /* mode 0xaa */ + {0x0000, 0x8800}, + {0x0004, 0x8805}, + {0x0020, 0x8801}, + {0x0015, 0x8800}, /* mode 0x0415 */ + {0x0002, 0x8805}, + {0x0039, 0x8801}, + {0x0000, 0x8800}, + {0x0010, 0x8805}, + {0x0035, 0x8801}, + {0x0000, 0x8800}, + {0x0049, 0x8805}, + {0x0009, 0x8801}, + {0x0010, 0x8800}, + {0x000b, 0x8805}, + {0x0028, 0x8801}, + {0x0000, 0x8800}, + {0x000f, 0x8805}, + {0x003b, 0x8801}, + {0x0000, 0x8800}, + {0x0000, 0x8805}, + {0x003c, 0x8801}, + {0x0000, 0x8800}, + {0x0002, 0x8502}, + {0x0039, 0x8801}, + {0x0000, 0x8805}, + {0x0000, 0x8800}, + + {0x0087, 0x8700}, /* overwrite by start */ + {0x0081, 0x8702}, + {0x0000, 0x8500}, +/* {0x0010, 0x8500}, -- Previous line was this */ + {0x0002, 0x865b}, + {0x0003, 0x865c}, + /***************/ + {0x0003, 0x8801}, /* 0x121-> 289 */ + {0x0021, 0x8805}, + {0x0001, 0x8800}, + {0x0004, 0x8801}, /* 0x165 -> 357 */ + {0x0065, 0x8805}, + {0x0001, 0x8800}, + {0x0005, 0x8801}, /* 0x2f //blanking control colonne */ + {0x002f, 0x8805}, + {0x0000, 0x8800}, + {0x0006, 0x8801}, /* 0x00 //blanking mode row */ + {0x0000, 0x8805}, + {0x0000, 0x8800}, + {0x000a, 0x8801}, /* 0x01 //0x02 */ + {0x0001, 0x8805}, + {0x0000, 0x8800}, + {0x0009, 0x8801}, /* 0x1061 - setexposure times && pixel clock * 0001 0 | 000 0110 0001 */ - {0x0035, 0x0014}, + {0x0061, 0x8805}, /* 61 31 */ + {0x0008, 0x8800}, /* 08 */ + {0x0035, 0x8801}, /* 0x14 - set gain general */ + {0x001f, 0x8805}, /* 0x14 */ + {0x0000, 0x8800}, + {0x000e, 0x8112}, /* white balance - was 30 */ {} }; @@ -366,7 +460,6 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg) reg_r(gspca_dev, 0x8803, 1); if (!gspca_dev->usb_buf[0]) return; - msleep(10); } while (--retry); } @@ -386,7 +479,6 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode) reg_r(gspca_dev, 0x8805, 1); return ((int) value << 8) | gspca_dev->usb_buf[0]; } - msleep(10); } while (--retry); return -1; } @@ -449,6 +541,7 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; + cam->epaddr = 0x01; gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ sd->chip_revision = id->driver_info; @@ -479,13 +572,11 @@ static int sd_init_12a(struct gspca_dev *gspca_dev) static int sd_init_72a(struct gspca_dev *gspca_dev) { PDEBUG(D_STREAM, "Chip revision: 072a"); - write_vector(gspca_dev, rev72a_reset); - msleep(200); write_vector(gspca_dev, rev72a_init_data1); write_sensor_72a(gspca_dev, rev72a_init_sensor1); write_vector(gspca_dev, rev72a_init_data2); write_sensor_72a(gspca_dev, rev72a_init_sensor2); - reg_w_val(gspca_dev->dev, 0x8112, 0x30); + write_vector(gspca_dev, rev72a_init_data3); return 0; } @@ -640,18 +731,11 @@ static int sd_start_72a(struct gspca_dev *gspca_dev) int Clck; int mode; - write_vector(gspca_dev, rev72a_reset); - msleep(200); - write_vector(gspca_dev, rev72a_init_data1); - write_sensor_72a(gspca_dev, rev72a_init_sensor1); - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; switch (mode) { default: - case 0: - Clck = 0x27; /* ms-win 0x87 */ - break; - case 1: +/* case 0: + case 1: */ Clck = 0x25; break; case 2: @@ -661,14 +745,13 @@ static int sd_start_72a(struct gspca_dev *gspca_dev) Clck = 0x21; break; } - reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ - reg_w_val(dev, 0x8702, 0x81); reg_w_val(dev, 0x8500, mode); /* mode */ - write_sensor_72a(gspca_dev, rev72a_init_sensor2); + reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ + reg_w_val(dev, 0x8112, 0x10 | 0x20); setcontrast(gspca_dev); /* setbrightness(gspca_dev); * fixme: bad values */ + setwhite(gspca_dev); setautogain(gspca_dev); - reg_w_val(dev, 0x8112, 0x10 | 0x20); return 0; } @@ -784,11 +867,12 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; - len--; - switch (*data++) { /* sequence number */ + switch (data[0]) { /* sequence number */ case 0: /* start of frame */ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); + data += SPCA561_OFFSET_DATA; + len -= SPCA561_OFFSET_DATA; if (data[1] & 0x10) { /* compressed bayer */ gspca_frame_add(gspca_dev, FIRST_PACKET, @@ -809,6 +893,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, case 0xff: /* drop (empty mpackets) */ return; } + data++; + len--; gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } @@ -1111,10 +1197,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/sq905.c b/trunk/drivers/media/video/gspca/sq905.c deleted file mode 100644 index 04e3ae57a2e3..000000000000 --- a/trunk/drivers/media/video/gspca/sq905.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * SQ905 subdriver - * - * Copyright (C) 2008, 2009 Adam Baker and Theodore Kilgore - * - * 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 - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * History and Acknowledgments - * - * The original Linux driver for SQ905 based cameras was written by - * Marcell Lengyel and furter developed by many other contributers - * and is available from http://sourceforge.net/projects/sqcam/ - * - * This driver takes advantage of the reverse engineering work done for - * that driver and for libgphoto2 but shares no code with them. - * - * This driver has used as a base the finepix driver and other gspca - * based drivers and may still contain code fragments taken from those - * drivers. - */ - -#define MODULE_NAME "sq905" - -#include -#include "gspca.h" - -MODULE_AUTHOR("Adam Baker , " - "Theodore Kilgore "); -MODULE_DESCRIPTION("GSPCA/SQ905 USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* Default timeouts, in ms */ -#define SQ905_CMD_TIMEOUT 500 -#define SQ905_DATA_TIMEOUT 1000 - -/* Maximum transfer size to use. */ -#define SQ905_MAX_TRANSFER 0x8000 -#define FRAME_HEADER_LEN 64 - -/* The known modes, or registers. These go in the "value" slot. */ - -/* 00 is "none" obviously */ - -#define SQ905_BULK_READ 0x03 /* precedes any bulk read */ -#define SQ905_COMMAND 0x06 /* precedes the command codes below */ -#define SQ905_PING 0x07 /* when reading an "idling" command */ -#define SQ905_READ_DONE 0xc0 /* ack bulk read completed */ - -/* Any non-zero value in the bottom 2 bits of the 2nd byte of - * the ID appears to indicate the camera can do 640*480. If the - * LSB of that byte is set the image is just upside down, otherwise - * it is rotated 180 degrees. */ -#define SQ905_HIRES_MASK 0x00000300 -#define SQ905_ORIENTATION_MASK 0x00000100 - -/* Some command codes. These go in the "index" slot. */ - -#define SQ905_ID 0xf0 /* asks for model string */ -#define SQ905_CONFIG 0x20 /* gets photo alloc. table, not used here */ -#define SQ905_DATA 0x30 /* accesses photo data, not used here */ -#define SQ905_CLEAR 0xa0 /* clear everything */ -#define SQ905_CAPTURE_LOW 0x60 /* Starts capture at 160x120 */ -#define SQ905_CAPTURE_MED 0x61 /* Starts capture at 320x240 */ -#define SQ905_CAPTURE_HIGH 0x62 /* Starts capture at 640x480 (some cams only) */ -/* note that the capture command also controls the output dimensions */ - -/* Structure to hold all of our device specific stuff */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - - /* - * Driver stuff - */ - struct work_struct work_struct; - struct workqueue_struct *work_thread; -}; - -static struct v4l2_pix_format sq905_mode[] = { - { 160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, - { 320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, - { 640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0} -}; - -/* - * Send a command to the camera. - */ -static int sq905_command(struct gspca_dev *gspca_dev, u16 index) -{ - int ret; - - gspca_dev->usb_buf[0] = '\0'; - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_SYNCH_FRAME, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - SQ905_COMMAND, index, gspca_dev->usb_buf, 1, - SQ905_CMD_TIMEOUT); - if (ret < 0) { - PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", - __func__, ret); - return ret; - } - - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_SYNCH_FRAME, /* request */ - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - SQ905_PING, 0, gspca_dev->usb_buf, 1, - SQ905_CMD_TIMEOUT); - if (ret < 0) { - PDEBUG(D_ERR, "%s: usb_control_msg failed 2 (%d)", - __func__, ret); - return ret; - } - - return 0; -} - -/* - * Acknowledge the end of a frame - see warning on sq905_command. - */ -static int sq905_ack_frame(struct gspca_dev *gspca_dev) -{ - int ret; - - gspca_dev->usb_buf[0] = '\0'; - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_SYNCH_FRAME, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - SQ905_READ_DONE, 0, gspca_dev->usb_buf, 1, - SQ905_CMD_TIMEOUT); - if (ret < 0) { - PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret); - return ret; - } - - return 0; -} - -/* - * request and read a block of data - see warning on sq905_command. - */ -static int -sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size) -{ - int ret; - int act_len; - - gspca_dev->usb_buf[0] = '\0'; - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_SYNCH_FRAME, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - SQ905_BULK_READ, size, gspca_dev->usb_buf, - 1, SQ905_CMD_TIMEOUT); - if (ret < 0) { - PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret); - return ret; - } - ret = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 0x81), - data, size, &act_len, SQ905_DATA_TIMEOUT); - - /* successful, it returns 0, otherwise negative */ - if (ret < 0 || act_len != size) { - PDEBUG(D_ERR, "bulk read fail (%d) len %d/%d", - ret, act_len, size); - return -EIO; - } - return 0; -} - -/* This function is called as a workqueue function and runs whenever the camera - * is streaming data. Because it is a workqueue function it is allowed to sleep - * so we can use synchronous USB calls. To avoid possible collisions with other - * threads attempting to use the camera's USB interface we take the gspca - * usb_lock when performing USB operations. In practice the only thing we need - * to protect against is the usb_set_interface call that gspca makes during - * stream_off as the camera doesn't provide any controls that the user could try - * to change. - */ -static void sq905_dostream(struct work_struct *work) -{ - struct sd *dev = container_of(work, struct sd, work_struct); - struct gspca_dev *gspca_dev = &dev->gspca_dev; - struct gspca_frame *frame; - int bytes_left; /* bytes remaining in current frame. */ - int data_len; /* size to use for the next read. */ - int header_read; /* true if we have already read the frame header. */ - int discarding; /* true if we failed to get space for frame. */ - int packet_type; - int frame_sz; - int ret; - u8 *data; - u8 *buffer; - - buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); - mutex_lock(&gspca_dev->usb_lock); - if (!buffer) { - PDEBUG(D_ERR, "Couldn't allocate USB buffer"); - goto quit_stream; - } - - frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage - + FRAME_HEADER_LEN; - - while (gspca_dev->present && gspca_dev->streaming) { - /* Need a short delay to ensure streaming flag was set by - * gspca and to make sure gspca can grab the mutex. */ - mutex_unlock(&gspca_dev->usb_lock); - msleep(1); - - /* request some data and then read it until we have - * a complete frame. */ - bytes_left = frame_sz; - header_read = 0; - discarding = 0; - - while (bytes_left > 0) { - data_len = bytes_left > SQ905_MAX_TRANSFER ? - SQ905_MAX_TRANSFER : bytes_left; - mutex_lock(&gspca_dev->usb_lock); - if (!gspca_dev->present) - goto quit_stream; - ret = sq905_read_data(gspca_dev, buffer, data_len); - if (ret < 0) - goto quit_stream; - mutex_unlock(&gspca_dev->usb_lock); - PDEBUG(D_STREAM, - "Got %d bytes out of %d for frame", - data_len, bytes_left); - bytes_left -= data_len; - data = buffer; - if (!header_read) { - packet_type = FIRST_PACKET; - /* The first 64 bytes of each frame are - * a header full of FF 00 bytes */ - data += FRAME_HEADER_LEN; - data_len -= FRAME_HEADER_LEN; - header_read = 1; - } else if (bytes_left == 0) { - packet_type = LAST_PACKET; - } else { - packet_type = INTER_PACKET; - } - frame = gspca_get_i_frame(gspca_dev); - if (frame && !discarding) { - frame = gspca_frame_add(gspca_dev, packet_type, - frame, data, data_len); - /* If entire frame fits in one packet we still - need to add a LAST_PACKET */ - if (packet_type == FIRST_PACKET && - bytes_left == 0) - frame = gspca_frame_add(gspca_dev, - LAST_PACKET, - frame, data, 0); - } else { - discarding = 1; - } - } - /* acknowledge the frame */ - mutex_lock(&gspca_dev->usb_lock); - if (!gspca_dev->present) - goto quit_stream; - ret = sq905_ack_frame(gspca_dev); - if (ret < 0) - goto quit_stream; - } -quit_stream: - /* the usb_lock is already acquired */ - if (gspca_dev->present) - sq905_command(gspca_dev, SQ905_CLEAR); - mutex_unlock(&gspca_dev->usb_lock); - kfree(buffer); -} - -/* This function is called at probe time just before sd_init */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam = &gspca_dev->cam; - struct sd *dev = (struct sd *) gspca_dev; - - /* We don't use the buffer gspca allocates so make it small. */ - cam->bulk_size = 64; - - INIT_WORK(&dev->work_struct, sq905_dostream); - - return 0; -} - -/* called on streamoff with alt==0 and on disconnect */ -/* the usb_lock is held at entry - restore on exit */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *dev = (struct sd *) gspca_dev; - - /* wait for the work queue to terminate */ - mutex_unlock(&gspca_dev->usb_lock); - /* This waits for sq905_dostream to finish */ - destroy_workqueue(dev->work_thread); - dev->work_thread = NULL; - mutex_lock(&gspca_dev->usb_lock); -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - u32 ident; - int ret; - - /* connect to the camera and read - * the model ID and process that and put it away. - */ - ret = sq905_command(gspca_dev, SQ905_CLEAR); - if (ret < 0) - return ret; - ret = sq905_command(gspca_dev, SQ905_ID); - if (ret < 0) - return ret; - ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4); - if (ret < 0) - return ret; - /* usb_buf is allocated with kmalloc so is aligned. - * Camera model number is the right way round if we assume this - * reverse engineered ID is supposed to be big endian. */ - ident = be32_to_cpup((__be32 *)gspca_dev->usb_buf); - ret = sq905_command(gspca_dev, SQ905_CLEAR); - if (ret < 0) - return ret; - PDEBUG(D_CONF, "SQ905 camera ID %08x detected", ident); - gspca_dev->cam.cam_mode = sq905_mode; - gspca_dev->cam.nmodes = ARRAY_SIZE(sq905_mode); - if (!(ident & SQ905_HIRES_MASK)) - gspca_dev->cam.nmodes--; - return 0; -} - -/* Set up for getting frames. */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *dev = (struct sd *) gspca_dev; - int ret; - - /* "Open the shutter" and set size, to start capture */ - switch (gspca_dev->curr_mode) { - default: -/* case 2: */ - PDEBUG(D_STREAM, "Start streaming at high resolution"); - ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_HIGH); - break; - case 1: - PDEBUG(D_STREAM, "Start streaming at medium resolution"); - ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_MED); - break; - case 0: - PDEBUG(D_STREAM, "Start streaming at low resolution"); - ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_LOW); - } - - if (ret < 0) { - PDEBUG(D_ERR, "Start streaming command failed"); - return ret; - } - /* Start the workqueue function to do the streaming */ - dev->work_thread = create_singlethread_workqueue(MODULE_NAME); - queue_work(dev->work_thread, &dev->work_struct); - - return 0; -} - -/* Table of supported USB devices */ -static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x2770, 0x9120)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stop0 = sd_stop0, -}; - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, - &sd_desc, - sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, -#endif -}; - -/* -- module insert / remove -- */ -static int __init sd_mod_init(void) -{ - int ret; - - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; - PDEBUG(D_PROBE, "registered"); - return 0; -} - -static void __exit sd_mod_exit(void) -{ - usb_deregister(&sd_driver); - PDEBUG(D_PROBE, "deregistered"); -} - -module_init(sd_mod_init); -module_exit(sd_mod_exit); diff --git a/trunk/drivers/media/video/gspca/sq905c.c b/trunk/drivers/media/video/gspca/sq905c.c deleted file mode 100644 index 0bcb74a1b143..000000000000 --- a/trunk/drivers/media/video/gspca/sq905c.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * SQ905C subdriver - * - * Copyright (C) 2009 Theodore Kilgore - * - * 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 - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * - * This driver uses work done in - * libgphoto2/camlibs/digigr8, Copyright (C) Theodore Kilgore. - * - * This driver has also used as a base the sq905c driver - * and may contain code fragments from it. - */ - -#define MODULE_NAME "sq905c" - -#include -#include "gspca.h" - -MODULE_AUTHOR("Theodore Kilgore "); -MODULE_DESCRIPTION("GSPCA/SQ905C USB Camera Driver"); -MODULE_LICENSE("GPL"); - -/* Default timeouts, in ms */ -#define SQ905C_CMD_TIMEOUT 500 -#define SQ905C_DATA_TIMEOUT 1000 - -/* Maximum transfer size to use. */ -#define SQ905C_MAX_TRANSFER 0x8000 - -#define FRAME_HEADER_LEN 0x50 - -/* Commands. These go in the "value" slot. */ -#define SQ905C_CLEAR 0xa0 /* clear everything */ -#define SQ905C_CAPTURE_LOW 0xa040 /* Starts capture at 160x120 */ -#define SQ905C_CAPTURE_MED 0x1440 /* Starts capture at 320x240 */ -#define SQ905C_CAPTURE_HI 0x2840 /* Starts capture at 320x240 */ - -/* For capture, this must go in the "index" slot. */ -#define SQ905C_CAPTURE_INDEX 0x110f - -/* Structure to hold all of our device specific stuff */ -struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ - const struct v4l2_pix_format *cap_mode; - /* Driver stuff */ - struct work_struct work_struct; - struct workqueue_struct *work_thread; -}; - -/* - * Most of these cameras will do 640x480 and 320x240. 160x120 works - * in theory but gives very poor output. Therefore, not supported. - * The 0x2770:0x9050 cameras have max resolution of 320x240. - */ -static struct v4l2_pix_format sq905c_mode[] = { - { 320, 240, V4L2_PIX_FMT_SQ905C, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, - { 640, 480, V4L2_PIX_FMT_SQ905C, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0} -}; - -/* Send a command to the camera. */ -static int sq905c_command(struct gspca_dev *gspca_dev, u16 command, u16 index) -{ - int ret; - - ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - USB_REQ_SYNCH_FRAME, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - command, index, NULL, 0, - SQ905C_CMD_TIMEOUT); - if (ret < 0) { - PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", - __func__, ret); - return ret; - } - - return 0; -} - -/* This function is called as a workqueue function and runs whenever the camera - * is streaming data. Because it is a workqueue function it is allowed to sleep - * so we can use synchronous USB calls. To avoid possible collisions with other - * threads attempting to use the camera's USB interface the gspca usb_lock is - * used when performing the one USB control operation inside the workqueue, - * which tells the camera to close the stream. In practice the only thing - * which needs to be protected against is the usb_set_interface call that - * gspca makes during stream_off. Otherwise the camera doesn't provide any - * controls that the user could try to change. - */ -static void sq905c_dostream(struct work_struct *work) -{ - struct sd *dev = container_of(work, struct sd, work_struct); - struct gspca_dev *gspca_dev = &dev->gspca_dev; - struct gspca_frame *frame; - int bytes_left; /* bytes remaining in current frame. */ - int data_len; /* size to use for the next read. */ - int act_len; - int discarding = 0; /* true if we failed to get space for frame. */ - int packet_type; - int ret; - u8 *buffer; - - buffer = kmalloc(SQ905C_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); - if (!buffer) { - PDEBUG(D_ERR, "Couldn't allocate USB buffer"); - goto quit_stream; - } - - while (gspca_dev->present && gspca_dev->streaming) { - if (!gspca_dev->present) - goto quit_stream; - /* Request the header, which tells the size to download */ - ret = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 0x81), - buffer, FRAME_HEADER_LEN, &act_len, - SQ905C_DATA_TIMEOUT); - PDEBUG(D_STREAM, - "Got %d bytes out of %d for header", - act_len, FRAME_HEADER_LEN); - if (ret < 0 || act_len < FRAME_HEADER_LEN) - goto quit_stream; - /* size is read from 4 bytes starting 0x40, little endian */ - bytes_left = buffer[0x40]|(buffer[0x41]<<8)|(buffer[0x42]<<16) - |(buffer[0x43]<<24); - PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left); - /* We keep the header. It has other information, too. */ - packet_type = FIRST_PACKET; - frame = gspca_get_i_frame(gspca_dev); - if (frame && !discarding) { - gspca_frame_add(gspca_dev, packet_type, - frame, buffer, FRAME_HEADER_LEN); - } else - discarding = 1; - while (bytes_left > 0) { - data_len = bytes_left > SQ905C_MAX_TRANSFER ? - SQ905C_MAX_TRANSFER : bytes_left; - if (!gspca_dev->present) - goto quit_stream; - ret = usb_bulk_msg(gspca_dev->dev, - usb_rcvbulkpipe(gspca_dev->dev, 0x81), - buffer, data_len, &act_len, - SQ905C_DATA_TIMEOUT); - if (ret < 0 || act_len < data_len) - goto quit_stream; - PDEBUG(D_STREAM, - "Got %d bytes out of %d for frame", - data_len, bytes_left); - bytes_left -= data_len; - if (bytes_left == 0) - packet_type = LAST_PACKET; - else - packet_type = INTER_PACKET; - frame = gspca_get_i_frame(gspca_dev); - if (frame && !discarding) - gspca_frame_add(gspca_dev, packet_type, - frame, buffer, data_len); - else - discarding = 1; - } - } -quit_stream: - mutex_lock(&gspca_dev->usb_lock); - if (gspca_dev->present) - sq905c_command(gspca_dev, SQ905C_CLEAR, 0); - mutex_unlock(&gspca_dev->usb_lock); - kfree(buffer); -} - -/* This function is called at probe time just before sd_init */ -static int sd_config(struct gspca_dev *gspca_dev, - const struct usb_device_id *id) -{ - struct cam *cam = &gspca_dev->cam; - struct sd *dev = (struct sd *) gspca_dev; - - PDEBUG(D_PROBE, - "SQ9050 camera detected" - " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); - cam->cam_mode = sq905c_mode; - cam->nmodes = 2; - if (id->idProduct == 0x9050) - cam->nmodes = 1; - /* We don't use the buffer gspca allocates so make it small. */ - cam->bulk_size = 32; - INIT_WORK(&dev->work_struct, sq905c_dostream); - return 0; -} - -/* called on streamoff with alt==0 and on disconnect */ -/* the usb_lock is held at entry - restore on exit */ -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *dev = (struct sd *) gspca_dev; - - /* wait for the work queue to terminate */ - mutex_unlock(&gspca_dev->usb_lock); - /* This waits for sq905c_dostream to finish */ - destroy_workqueue(dev->work_thread); - dev->work_thread = NULL; - mutex_lock(&gspca_dev->usb_lock); -} - -/* this function is called at probe and resume time */ -static int sd_init(struct gspca_dev *gspca_dev) -{ - int ret; - - /* connect to the camera and reset it. */ - ret = sq905c_command(gspca_dev, SQ905C_CLEAR, 0); - return ret; -} - -/* Set up for getting frames. */ -static int sd_start(struct gspca_dev *gspca_dev) -{ - struct sd *dev = (struct sd *) gspca_dev; - int ret; - - dev->cap_mode = gspca_dev->cam.cam_mode; - /* "Open the shutter" and set size, to start capture */ - switch (gspca_dev->width) { - case 640: - PDEBUG(D_STREAM, "Start streaming at high resolution"); - dev->cap_mode++; - ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_HI, - SQ905C_CAPTURE_INDEX); - break; - default: /* 320 */ - PDEBUG(D_STREAM, "Start streaming at medium resolution"); - ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_MED, - SQ905C_CAPTURE_INDEX); - } - - if (ret < 0) { - PDEBUG(D_ERR, "Start streaming command failed"); - return ret; - } - /* Start the workqueue function to do the streaming */ - dev->work_thread = create_singlethread_workqueue(MODULE_NAME); - queue_work(dev->work_thread, &dev->work_struct); - - return 0; -} - -/* Table of supported USB devices */ -static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x2770, 0x905c)}, - {USB_DEVICE(0x2770, 0x9050)}, - {USB_DEVICE(0x2770, 0x913d)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, device_table); - -/* sub-driver description */ -static const struct sd_desc sd_desc = { - .name = MODULE_NAME, - .config = sd_config, - .init = sd_init, - .start = sd_start, - .stop0 = sd_stop0, -}; - -/* -- device connect -- */ -static int sd_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return gspca_dev_probe(intf, id, - &sd_desc, - sizeof(struct sd), - THIS_MODULE); -} - -static struct usb_driver sd_driver = { - .name = MODULE_NAME, - .id_table = device_table, - .probe = sd_probe, - .disconnect = gspca_disconnect, -#ifdef CONFIG_PM - .suspend = gspca_suspend, - .resume = gspca_resume, -#endif -}; - -/* -- module insert / remove -- */ -static int __init sd_mod_init(void) -{ - int ret; - - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; - PDEBUG(D_PROBE, "registered"); - return 0; -} - -static void __exit sd_mod_exit(void) -{ - usb_deregister(&sd_driver); - PDEBUG(D_PROBE, "deregistered"); -} - -module_init(sd_mod_init); -module_exit(sd_mod_exit); diff --git a/trunk/drivers/media/video/gspca/stk014.c b/trunk/drivers/media/video/gspca/stk014.c index f25be20cf1a6..60de9af87fbb 100644 --- a/trunk/drivers/media/video/gspca/stk014.c +++ b/trunk/drivers/media/video/gspca/stk014.c @@ -35,14 +35,11 @@ struct sd { unsigned char contrast; unsigned char colors; unsigned char lightfreq; - u8 quality; -#define QUALITY_MIN 60 -#define QUALITY_MAX 95 -#define QUALITY_DEF 80 - - u8 *jpeg_hdr; }; +/* global parameters */ +static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */ + /* V4L2 controls supported by the driver */ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); @@ -183,7 +180,7 @@ static int rcv_val(struct gspca_dev *gspca_dev, reg_w(gspca_dev, 0x63b, 0); reg_w(gspca_dev, 0x630, 5); ret = usb_bulk_msg(dev, - usb_rcvbulkpipe(dev, 0x05), + usb_rcvbulkpipe(dev, 5), gspca_dev->usb_buf, 4, /* length */ &alen, @@ -297,14 +294,15 @@ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) { struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam = &gspca_dev->cam; + cam->epaddr = 0x02; gspca_dev->cam.cam_mode = vga_mode; gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; sd->lightfreq = FREQ_DEF; - sd->quality = QUALITY_DEF; return 0; } @@ -328,15 +326,8 @@ static int sd_init(struct gspca_dev *gspca_dev) /* -- start the camera -- */ static int sd_start(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; int ret, value; - /* create the JPEG header */ - sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x22); /* JPEG 411 */ - jpeg_set_qual(sd->jpeg_hdr, sd->quality); - /* work on alternate 1 */ usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); @@ -408,19 +399,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev) PDEBUG(D_STREAM, "camera stopped"); } -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - kfree(sd->jpeg_hdr); -} - static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ int len) /* iso packet length */ { - struct sd *sd = (struct sd *) gspca_dev; static unsigned char ffd9[] = {0xff, 0xd9}; /* a frame starts with: @@ -437,8 +420,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, ffd9, 2); /* put the JPEG 411 header */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - sd->jpeg_hdr, JPEG_HDR_SZ); + jpeg_put_header(gspca_dev, frame, sd_quant, 0x22); /* beginning of the frame */ #define STKHDRSZ 12 @@ -538,34 +520,6 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, return -EINVAL; } -static int sd_set_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (jcomp->quality < QUALITY_MIN) - sd->quality = QUALITY_MIN; - else if (jcomp->quality > QUALITY_MAX) - sd->quality = QUALITY_MAX; - else - sd->quality = jcomp->quality; - if (gspca_dev->streaming) - jpeg_set_qual(sd->jpeg_hdr, sd->quality); - return 0; -} - -static int sd_get_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - memset(jcomp, 0, sizeof *jcomp); - jcomp->quality = sd->quality; - jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT - | V4L2_JPEG_MARKER_DQT; - return 0; -} - /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -575,11 +529,8 @@ static const struct sd_desc sd_desc = { .init = sd_init, .start = sd_start, .stopN = sd_stopN, - .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan, .querymenu = sd_querymenu, - .get_jcomp = sd_get_jcomp, - .set_jcomp = sd_set_jcomp, }; /* -- module initialisation -- */ @@ -611,10 +562,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; info("registered"); return 0; } @@ -626,3 +575,6 @@ static void __exit sd_mod_exit(void) module_init(sd_mod_init); module_exit(sd_mod_exit); + +module_param_named(quant, sd_quant, int, 0644); +MODULE_PARM_DESC(quant, "Quantization index (0..8)"); diff --git a/trunk/drivers/media/video/gspca/stv06xx/stv06xx.c b/trunk/drivers/media/video/gspca/stv06xx/stv06xx.c index 9dff2e65b116..13a021e3cbb7 100644 --- a/trunk/drivers/media/video/gspca/stv06xx/stv06xx.c +++ b/trunk/drivers/media/video/gspca/stv06xx/stv06xx.c @@ -429,6 +429,7 @@ static int stv06xx_config(struct gspca_dev *gspca_dev, PDEBUG(D_PROBE, "Configuring camera"); cam = &gspca_dev->cam; + cam->epaddr = STV_ISOC_ENDPOINT_ADDR; sd->desc = sd_desc; gspca_dev->sd_desc = &sd->desc; @@ -500,10 +501,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c index b16903814203..14335a9e4bb5 100644 --- a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c +++ b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c @@ -30,66 +30,6 @@ #include "stv06xx_hdcs.h" -static const struct ctrl hdcs1x00_ctrl[] = { - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .minimum = 0x00, - .maximum = 0xffff, - .step = 0x1, - .default_value = HDCS_DEFAULT_EXPOSURE, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = hdcs_set_exposure, - .get = hdcs_get_exposure - }, { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "gain", - .minimum = 0x00, - .maximum = 0xff, - .step = 0x1, - .default_value = HDCS_DEFAULT_GAIN, - .flags = V4L2_CTRL_FLAG_SLIDER - }, - .set = hdcs_set_gain, - .get = hdcs_get_gain - } -}; - -static struct v4l2_pix_format hdcs1x00_mode[] = { - { - HDCS_1X00_DEF_WIDTH, - HDCS_1X00_DEF_HEIGHT, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT, - .bytesperline = HDCS_1X00_DEF_WIDTH, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - } -}; - -static const struct ctrl hdcs1020_ctrl[] = {}; - -static struct v4l2_pix_format hdcs1020_mode[] = { - { - HDCS_1020_DEF_WIDTH, - HDCS_1020_DEF_HEIGHT, - V4L2_PIX_FMT_SBGGR8, - V4L2_FIELD_NONE, - .sizeimage = - HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT, - .bytesperline = HDCS_1020_DEF_WIDTH, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - } -}; - enum hdcs_power_state { HDCS_STATE_SLEEP, HDCS_STATE_IDLE, @@ -413,10 +353,10 @@ static int hdcs_probe_1x00(struct sd *sd) info("HDCS-1000/1100 sensor detected"); - sd->gspca_dev.cam.cam_mode = hdcs1x00_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode); - sd->desc.ctrls = hdcs1x00_ctrl; - sd->desc.nctrls = ARRAY_SIZE(hdcs1x00_ctrl); + sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1x00.modes; + sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1x00.nmodes; + sd->desc.ctrls = stv06xx_sensor_hdcs1x00.ctrls; + sd->desc.nctrls = stv06xx_sensor_hdcs1x00.nctrls; hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); if (!hdcs) @@ -472,10 +412,10 @@ static int hdcs_probe_1020(struct sd *sd) info("HDCS-1020 sensor detected"); - sd->gspca_dev.cam.cam_mode = hdcs1020_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode); - sd->desc.ctrls = hdcs1020_ctrl; - sd->desc.nctrls = ARRAY_SIZE(hdcs1020_ctrl); + sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1020.modes; + sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1020.nmodes; + sd->desc.ctrls = stv06xx_sensor_hdcs1020.ctrls; + sd->desc.nctrls = stv06xx_sensor_hdcs1020.nctrls; hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); if (!hdcs) diff --git a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h index 412f06cf3d5c..9c7279a4cd88 100644 --- a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h +++ b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h @@ -152,6 +152,53 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = { .stop = hdcs_stop, .disconnect = hdcs_disconnect, .dump = hdcs_dump, + + .nctrls = 2, + .ctrls = { + { + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "exposure", + .minimum = 0x00, + .maximum = 0xffff, + .step = 0x1, + .default_value = HDCS_DEFAULT_EXPOSURE, + .flags = V4L2_CTRL_FLAG_SLIDER + }, + .set = hdcs_set_exposure, + .get = hdcs_get_exposure + }, + { + { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "gain", + .minimum = 0x00, + .maximum = 0xff, + .step = 0x1, + .default_value = HDCS_DEFAULT_GAIN, + .flags = V4L2_CTRL_FLAG_SLIDER + }, + .set = hdcs_set_gain, + .get = hdcs_get_gain + } + }, + + .nmodes = 1, + .modes = { + { + HDCS_1X00_DEF_WIDTH, + HDCS_1X00_DEF_HEIGHT, + V4L2_PIX_FMT_SBGGR8, + V4L2_FIELD_NONE, + .sizeimage = + HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT, + .bytesperline = HDCS_1X00_DEF_WIDTH, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1 + } + } }; const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = { @@ -160,11 +207,29 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = { .i2c_addr = (0x55 << 1), .i2c_len = 1, + .nctrls = 0, + .ctrls = {}, + .init = hdcs_init, .probe = hdcs_probe_1020, .start = hdcs_start, .stop = hdcs_stop, .dump = hdcs_dump, + + .nmodes = 1, + .modes = { + { + HDCS_1020_DEF_WIDTH, + HDCS_1020_DEF_HEIGHT, + V4L2_PIX_FMT_SBGGR8, + V4L2_FIELD_NONE, + .sizeimage = + HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT, + .bytesperline = HDCS_1020_DEF_WIDTH, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1 + } + } }; static const u16 stv_bridge_init[][2] = { diff --git a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c index 285221e6b390..d0a0f8596454 100644 --- a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c +++ b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c @@ -46,132 +46,6 @@ #include "stv06xx_pb0100.h" -static const struct ctrl pb0100_ctrl[] = { -#define GAIN_IDX 0 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gain", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 128 - }, - .set = pb0100_set_gain, - .get = pb0100_get_gain - }, -#define RED_BALANCE_IDX 1 - { - { - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Red Balance", - .minimum = -255, - .maximum = 255, - .step = 1, - .default_value = 0 - }, - .set = pb0100_set_red_balance, - .get = pb0100_get_red_balance - }, -#define BLUE_BALANCE_IDX 2 - { - { - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Blue Balance", - .minimum = -255, - .maximum = 255, - .step = 1, - .default_value = 0 - }, - .set = pb0100_set_blue_balance, - .get = pb0100_get_blue_balance - }, -#define EXPOSURE_IDX 3 - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure", - .minimum = 0, - .maximum = 511, - .step = 1, - .default_value = 12 - }, - .set = pb0100_set_exposure, - .get = pb0100_get_exposure - }, -#define AUTOGAIN_IDX 4 - { - { - .id = V4L2_CID_AUTOGAIN, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Automatic Gain and Exposure", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = pb0100_set_autogain, - .get = pb0100_get_autogain - }, -#define AUTOGAIN_TARGET_IDX 5 - { - { - .id = V4L2_CTRL_CLASS_USER + 0x1000, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Automatic Gain Target", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 128 - }, - .set = pb0100_set_autogain_target, - .get = pb0100_get_autogain_target - }, -#define NATURAL_IDX 6 - { - { - .id = V4L2_CTRL_CLASS_USER + 0x1001, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Natural Light Source", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1 - }, - .set = pb0100_set_natural, - .get = pb0100_get_natural - } -}; - -static struct v4l2_pix_format pb0100_mode[] = { -/* low res / subsample modes disabled as they are only half res horizontal, - halving the vertical resolution does not seem to work */ - { - 320, - 240, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 320 * 240, - .bytesperline = 320, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = PB0100_CROP_TO_VGA - }, - { - 352, - 288, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 352 * 288, - .bytesperline = 352, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - } -}; - static int pb0100_probe(struct sd *sd) { u16 sensor; @@ -185,19 +59,20 @@ static int pb0100_probe(struct sd *sd) if ((sensor >> 8) == 0x64) { sensor_settings = kmalloc( - ARRAY_SIZE(pb0100_ctrl) * sizeof(s32), + stv06xx_sensor_pb0100.nctrls * sizeof(s32), GFP_KERNEL); if (!sensor_settings) return -ENOMEM; info("Photobit pb0100 sensor detected"); - sd->gspca_dev.cam.cam_mode = pb0100_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode); - sd->desc.ctrls = pb0100_ctrl; - sd->desc.nctrls = ARRAY_SIZE(pb0100_ctrl); - for (i = 0; i < sd->desc.nctrls; i++) - sensor_settings[i] = pb0100_ctrl[i].qctrl.default_value; + sd->gspca_dev.cam.cam_mode = stv06xx_sensor_pb0100.modes; + sd->gspca_dev.cam.nmodes = stv06xx_sensor_pb0100.nmodes; + sd->desc.ctrls = stv06xx_sensor_pb0100.ctrls; + sd->desc.nctrls = stv06xx_sensor_pb0100.nctrls; + for (i = 0; i < stv06xx_sensor_pb0100.nctrls; i++) + sensor_settings[i] = stv06xx_sensor_pb0100. + ctrls[i].qctrl.default_value; sd->sensor_priv = sensor_settings; return 0; @@ -268,12 +143,6 @@ static int pb0100_stop(struct sd *sd) return (err < 0) ? err : 0; } -static void pb0100_disconnect(struct sd *sd) -{ - sd->sensor = NULL; - kfree(sd->sensor_priv); -} - /* FIXME: Sort the init commands out and put them into tables, this is only for getting the camera to work */ /* FIXME: No error handling for now, diff --git a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h index 4de4fa5ebc57..5ea21a1154c4 100644 --- a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h +++ b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h @@ -114,7 +114,6 @@ static int pb0100_start(struct sd *sd); static int pb0100_init(struct sd *sd); static int pb0100_stop(struct sd *sd); static int pb0100_dump(struct sd *sd); -static void pb0100_disconnect(struct sd *sd); /* V4L2 controls supported by the driver */ static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val); @@ -138,12 +137,139 @@ const struct stv06xx_sensor stv06xx_sensor_pb0100 = { .i2c_addr = 0xba, .i2c_len = 2, + .nctrls = 7, + .ctrls = { +#define GAIN_IDX 0 + { + { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gain", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 128 + }, + .set = pb0100_set_gain, + .get = pb0100_get_gain + }, +#define RED_BALANCE_IDX 1 + { + { + .id = V4L2_CID_RED_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Red Balance", + .minimum = -255, + .maximum = 255, + .step = 1, + .default_value = 0 + }, + .set = pb0100_set_red_balance, + .get = pb0100_get_red_balance + }, +#define BLUE_BALANCE_IDX 2 + { + { + .id = V4L2_CID_BLUE_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Blue Balance", + .minimum = -255, + .maximum = 255, + .step = 1, + .default_value = 0 + }, + .set = pb0100_set_blue_balance, + .get = pb0100_get_blue_balance + }, +#define EXPOSURE_IDX 3 + { + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure", + .minimum = 0, + .maximum = 511, + .step = 1, + .default_value = 12 + }, + .set = pb0100_set_exposure, + .get = pb0100_get_exposure + }, +#define AUTOGAIN_IDX 4 + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Automatic Gain and Exposure", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1 + }, + .set = pb0100_set_autogain, + .get = pb0100_get_autogain + }, +#define AUTOGAIN_TARGET_IDX 5 + { + { + .id = V4L2_CTRL_CLASS_USER + 0x1000, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Automatic Gain Target", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 128 + }, + .set = pb0100_set_autogain_target, + .get = pb0100_get_autogain_target + }, +#define NATURAL_IDX 6 + { + { + .id = V4L2_CTRL_CLASS_USER + 0x1001, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Natural Light Source", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1 + }, + .set = pb0100_set_natural, + .get = pb0100_get_natural + }, + }, + .init = pb0100_init, .probe = pb0100_probe, .start = pb0100_start, .stop = pb0100_stop, .dump = pb0100_dump, - .disconnect = pb0100_disconnect, + + .nmodes = 2, + .modes = { +/* low res / subsample modes disabled as they are only half res horizontal, + halving the vertical resolution does not seem to work */ + { + 320, + 240, + V4L2_PIX_FMT_SGRBG8, + V4L2_FIELD_NONE, + .sizeimage = 320 * 240, + .bytesperline = 320, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = PB0100_CROP_TO_VGA + }, + { + 352, + 288, + V4L2_PIX_FMT_SGRBG8, + V4L2_FIELD_NONE, + .sizeimage = 352 * 288, + .bytesperline = 352, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0 + }, + } }; #endif diff --git a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h index e88c42f7d2f8..c726dacefa1f 100644 --- a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h +++ b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h @@ -41,6 +41,8 @@ extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00; extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020; extern const struct stv06xx_sensor stv06xx_sensor_pb0100; +#define STV06XX_MAX_CTRLS (V4L2_CID_LASTP1 - V4L2_CID_BASE + 10) + struct stv06xx_sensor { /* Defines the name of a sensor */ char name[32]; @@ -79,6 +81,12 @@ struct stv06xx_sensor { /* Instructs the sensor to dump all its contents */ int (*dump)(struct sd *sd); + + int nctrls; + struct ctrl ctrls[STV06XX_MAX_CTRLS]; + + char nmodes; + struct v4l2_pix_format modes[]; }; #endif diff --git a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c index 69c77c932fc0..1ca91f2a6dee 100644 --- a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c +++ b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c @@ -29,92 +29,26 @@ #include "stv06xx_vv6410.h" -static struct v4l2_pix_format vv6410_mode[] = { - { - 356, - 292, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 356 * 292, - .bytesperline = 356, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - } -}; - -static const struct ctrl vv6410_ctrl[] = { -#define HFLIP_IDX 0 - { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "horizontal flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = vv6410_set_hflip, - .get = vv6410_get_hflip - }, -#define VFLIP_IDX 1 - { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "vertical flip", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0 - }, - .set = vv6410_set_vflip, - .get = vv6410_get_vflip - }, -#define GAIN_IDX 2 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "analog gain", - .minimum = 0, - .maximum = 15, - .step = 1, - .default_value = 0 - }, - .set = vv6410_set_analog_gain, - .get = vv6410_get_analog_gain - } -}; - static int vv6410_probe(struct sd *sd) { u16 data; - int err, i; - s32 *sensor_settings; + int err; err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data); + if (err < 0) return -ENODEV; if (data == 0x19) { info("vv6410 sensor detected"); - sensor_settings = kmalloc(ARRAY_SIZE(vv6410_ctrl) * sizeof(s32), - GFP_KERNEL); - if (!sensor_settings) - return -ENOMEM; - - sd->gspca_dev.cam.cam_mode = vv6410_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode); - sd->desc.ctrls = vv6410_ctrl; - sd->desc.nctrls = ARRAY_SIZE(vv6410_ctrl); - - for (i = 0; i < sd->desc.nctrls; i++) - sensor_settings[i] = vv6410_ctrl[i].qctrl.default_value; - sd->sensor_priv = sensor_settings; + sd->gspca_dev.cam.cam_mode = stv06xx_sensor_vv6410.modes; + sd->gspca_dev.cam.nmodes = stv06xx_sensor_vv6410.nmodes; + sd->desc.ctrls = stv06xx_sensor_vv6410.ctrls; + sd->desc.nctrls = stv06xx_sensor_vv6410.nctrls; return 0; } + return -ENODEV; } @@ -146,12 +80,6 @@ static int vv6410_init(struct sd *sd) return (err < 0) ? err : 0; } -static void vv6410_disconnect(struct sd *sd) -{ - sd->sensor = NULL; - kfree(sd->sensor_priv); -} - static int vv6410_start(struct sd *sd) { int err; @@ -228,13 +156,17 @@ static int vv6410_dump(struct sd *sd) static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) { + int err; + u16 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - *val = sensor_settings[HFLIP_IDX]; + err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); + + *val = (i2c_data & VV6410_HFLIP) ? 1 : 0; + PDEBUG(D_V4L2, "Read horizontal flip %d", *val); - return 0; + return (err < 0) ? err : 0; } static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) @@ -242,9 +174,6 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) int err; u16 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - sensor_settings[HFLIP_IDX] = val; err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); if (err < 0) return err; @@ -262,13 +191,17 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) { + int err; + u16 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - *val = sensor_settings[VFLIP_IDX]; + err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); + + *val = (i2c_data & VV6410_VFLIP) ? 1 : 0; + PDEBUG(D_V4L2, "Read vertical flip %d", *val); - return 0; + return (err < 0) ? err : 0; } static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) @@ -276,9 +209,6 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) int err; u16 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - sensor_settings[VFLIP_IDX] = val; err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); if (err < 0) return err; @@ -296,23 +226,24 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val) { + int err; + u16 i2c_data; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - *val = sensor_settings[GAIN_IDX]; + err = stv06xx_read_sensor(sd, VV6410_ANALOGGAIN, &i2c_data); + + *val = i2c_data & 0xf; PDEBUG(D_V4L2, "Read analog gain %d", *val); - return 0; + return (err < 0) ? err : 0; } static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val) { int err; struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - sensor_settings[GAIN_IDX] = val; PDEBUG(D_V4L2, "Set analog gain to %d", val); err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf)); diff --git a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h index 95ac55891bd4..3ff8c4ea3362 100644 --- a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h +++ b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h @@ -178,7 +178,6 @@ static int vv6410_start(struct sd *sd); static int vv6410_init(struct sd *sd); static int vv6410_stop(struct sd *sd); static int vv6410_dump(struct sd *sd); -static void vv6410_disconnect(struct sd *sd); /* V4L2 controls supported by the driver */ static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); @@ -198,7 +197,62 @@ const struct stv06xx_sensor stv06xx_sensor_vv6410 = { .start = vv6410_start, .stop = vv6410_stop, .dump = vv6410_dump, - .disconnect = vv6410_disconnect, + + .nctrls = 3, + .ctrls = { + { + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "horizontal flip", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0 + }, + .set = vv6410_set_hflip, + .get = vv6410_get_hflip + }, { + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "vertical flip", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0 + }, + .set = vv6410_set_vflip, + .get = vv6410_get_vflip + }, { + { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "analog gain", + .minimum = 0, + .maximum = 15, + .step = 1, + .default_value = 0 + }, + .set = vv6410_set_analog_gain, + .get = vv6410_get_analog_gain + } + }, + + .nmodes = 1, + .modes = { + { + 356, + 292, + V4L2_PIX_FMT_SGRBG8, + V4L2_FIELD_NONE, + .sizeimage = + 356 * 292, + .bytesperline = 356, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0 + } + } }; /* If NULL, only single value to write, stored in len */ diff --git a/trunk/drivers/media/video/gspca/sunplus.c b/trunk/drivers/media/video/gspca/sunplus.c index c2b8c10c075a..6d904d5e4c74 100644 --- a/trunk/drivers/media/video/gspca/sunplus.c +++ b/trunk/drivers/media/video/gspca/sunplus.c @@ -39,11 +39,8 @@ struct sd { unsigned char contrast; unsigned char colors; unsigned char autogain; - u8 quality; -#define QUALITY_MIN 70 -#define QUALITY_MAX 95 -#define QUALITY_DEF 85 + char qindex; char bridge; #define BRIDGE_SPCA504 0 #define BRIDGE_SPCA504B 1 @@ -55,8 +52,6 @@ struct sd { #define LogitechClickSmart420 2 #define LogitechClickSmart820 3 #define MegapixV4 4 - - u8 *jpeg_hdr; }; /* V4L2 controls supported by the driver */ @@ -817,6 +812,7 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; + cam->epaddr = 0x01; sd->bridge = id->driver_info >> 8; sd->subtype = id->driver_info; @@ -854,10 +850,10 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0]; break; } + sd->qindex = 5; /* set the quantization table */ sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; - sd->quality = QUALITY_DEF; return 0; } @@ -974,12 +970,6 @@ static int sd_start(struct gspca_dev *gspca_dev) __u8 i; __u8 info[6]; - /* create the JPEG header */ - sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x22); /* JPEG 411 */ - jpeg_set_qual(sd->jpeg_hdr, sd->quality); - if (sd->bridge == BRIDGE_SPCA504B) spca504B_setQtable(gspca_dev); spca504B_SetSizeType(gspca_dev); @@ -1089,13 +1079,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev) } } -static void sd_stop0(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - kfree(sd->jpeg_hdr); -} - static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ @@ -1172,8 +1155,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, ffd9, 2); /* put the JPEG header in the new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - sd->jpeg_hdr, JPEG_HDR_SZ); + jpeg_put_header(gspca_dev, frame, + ((struct sd *) gspca_dev)->qindex, + 0x22); } /* add 0x00 after 0xff */ @@ -1214,6 +1198,26 @@ static void setbrightness(struct gspca_dev *gspca_dev) } } +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u16 brightness = 0; + + switch (sd->bridge) { + default: +/* case BRIDGE_SPCA533: */ +/* case BRIDGE_SPCA504B: */ +/* case BRIDGE_SPCA504: */ +/* case BRIDGE_SPCA504C: */ + brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2); + break; + case BRIDGE_SPCA536: + brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2); + break; + } + sd->brightness = ((brightness & 0xff) - 128) % 255; +} + static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1233,6 +1237,24 @@ static void setcontrast(struct gspca_dev *gspca_dev) } } +static void getcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + switch (sd->bridge) { + default: +/* case BRIDGE_SPCA533: */ +/* case BRIDGE_SPCA504B: */ +/* case BRIDGE_SPCA504: */ +/* case BRIDGE_SPCA504C: */ + sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2); + break; + case BRIDGE_SPCA536: + sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2); + break; + } +} + static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1252,6 +1274,24 @@ static void setcolors(struct gspca_dev *gspca_dev) } } +static void getcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + switch (sd->bridge) { + default: +/* case BRIDGE_SPCA533: */ +/* case BRIDGE_SPCA504B: */ +/* case BRIDGE_SPCA504: */ +/* case BRIDGE_SPCA504C: */ + sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1; + break; + case BRIDGE_SPCA536: + sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1; + break; + } +} + static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -1266,6 +1306,7 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getbrightness(gspca_dev); *val = sd->brightness; return 0; } @@ -1284,6 +1325,7 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getcontrast(gspca_dev); *val = sd->contrast; return 0; } @@ -1302,6 +1344,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + getcolors(gspca_dev); *val = sd->colors; return 0; } @@ -1322,34 +1365,6 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -static int sd_set_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (jcomp->quality < QUALITY_MIN) - sd->quality = QUALITY_MIN; - else if (jcomp->quality > QUALITY_MAX) - sd->quality = QUALITY_MAX; - else - sd->quality = jcomp->quality; - if (gspca_dev->streaming) - jpeg_set_qual(sd->jpeg_hdr, sd->quality); - return 0; -} - -static int sd_get_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - memset(jcomp, 0, sizeof *jcomp); - jcomp->quality = sd->quality; - jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT - | V4L2_JPEG_MARKER_DQT; - return 0; -} - /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -1359,10 +1374,7 @@ static const struct sd_desc sd_desc = { .init = sd_init, .start = sd_start, .stopN = sd_stopN, - .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan, - .get_jcomp = sd_get_jcomp, - .set_jcomp = sd_set_jcomp, }; /* -- module initialisation -- */ @@ -1453,10 +1465,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/t613.c b/trunk/drivers/media/video/gspca/t613.c index f63e37e2e4fd..6ee111a3cbd1 100644 --- a/trunk/drivers/media/video/gspca/t613.c +++ b/trunk/drivers/media/video/gspca/t613.c @@ -37,21 +37,20 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - u8 brightness; - u8 contrast; - u8 colors; - u8 autogain; - u8 gamma; - u8 sharpness; - u8 freq; - u8 whitebalance; - u8 mirror; - u8 effect; - - u8 sensor; -#define SENSOR_OM6802 0 -#define SENSOR_OTHER 1 -#define SENSOR_TAS5130A 2 + unsigned char brightness; + unsigned char contrast; + unsigned char colors; + unsigned char autogain; + unsigned char gamma; + unsigned char sharpness; + unsigned char freq; + unsigned char whitebalance; + unsigned char mirror; + unsigned char effect; + + __u8 sensor; +#define SENSOR_TAS5130A 0 +#define SENSOR_OM6802 1 }; /* V4L2 controls supported by the driver */ @@ -79,6 +78,7 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, struct v4l2_querymenu *menu); static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, @@ -87,12 +87,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 14, .step = 1, -#define BRIGHTNESS_DEF 8 - .default_value = BRIGHTNESS_DEF, + .default_value = 8, }, .set = sd_setbrightness, .get = sd_getbrightness, }, +#define SD_CONTRAST 1 { { .id = V4L2_CID_CONTRAST, @@ -101,12 +101,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 0x0d, .step = 1, -#define CONTRAST_DEF 0x07 - .default_value = CONTRAST_DEF, + .default_value = 0x07, }, .set = sd_setcontrast, .get = sd_getcontrast, }, +#define SD_COLOR 2 { { .id = V4L2_CID_SATURATION, @@ -115,8 +115,7 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 0x0f, .step = 1, -#define COLORS_DEF 0x05 - .default_value = COLORS_DEF, + .default_value = 0x05, }, .set = sd_setcolors, .get = sd_getcolors, @@ -136,6 +135,7 @@ static struct ctrl sd_ctrls[] = { .set = sd_setgamma, .get = sd_getgamma, }, +#define SD_AUTOGAIN 4 { { .id = V4L2_CID_GAIN, /* here, i activate only the lowlight, @@ -146,12 +146,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, -#define AUTOGAIN_DEF 0x01 - .default_value = AUTOGAIN_DEF, + .default_value = 0x01, }, .set = sd_setlowlight, .get = sd_getlowlight, }, +#define SD_MIRROR 5 { { .id = V4L2_CID_HFLIP, @@ -160,12 +160,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, -#define MIRROR_DEF 0 - .default_value = MIRROR_DEF, + .default_value = 0, }, .set = sd_setflip, .get = sd_getflip }, +#define SD_LIGHTFREQ 6 { { .id = V4L2_CID_POWER_LINE_FREQUENCY, @@ -174,12 +174,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 1, /* 1 -> 0x50, 2->0x60 */ .maximum = 2, .step = 1, -#define FREQ_DEF 1 - .default_value = FREQ_DEF, + .default_value = 1, }, .set = sd_setfreq, .get = sd_getfreq}, +#define SD_WHITE_BALANCE 7 { { .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, @@ -188,12 +188,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, -#define WHITE_BALANCE_DEF 0 - .default_value = WHITE_BALANCE_DEF, + .default_value = 0, }, .set = sd_setwhitebalance, .get = sd_getwhitebalance }, +#define SD_SHARPNESS 8 /* (aka definition on win) */ { { .id = V4L2_CID_SHARPNESS, @@ -202,12 +202,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 15, .step = 1, -#define SHARPNESS_DEF 0x06 - .default_value = SHARPNESS_DEF, + .default_value = 0x06, }, .set = sd_setsharpness, .get = sd_getsharpness, }, +#define SD_EFFECTS 9 { { .id = V4L2_CID_EFFECTS, @@ -216,8 +216,7 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 4, .step = 1, -#define EFFECTS_DEF 0 - .default_value = EFFECTS_DEF, + .default_value = 0, }, .set = sd_seteffect, .get = sd_geteffect @@ -264,50 +263,28 @@ static const struct v4l2_pix_format vga_mode_t16[] = { /* sensor specific data */ struct additional_sensor_data { - const u8 data1[10]; - const u8 data2[9]; - const u8 data3[9]; - const u8 data4[4]; - const u8 data5[6]; - const u8 stream[4]; + const __u8 data1[20]; + const __u8 data2[18]; + const __u8 data3[18]; + const __u8 data4[4]; + const __u8 data5[6]; + const __u8 stream[4]; }; -static const struct additional_sensor_data sensor_data[] = { - { /* OM6802 */ - .data1 = - {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06, - 0xb3, 0xfc}, - .data2 = - {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff, - 0xff}, - .data4 = /*Freq (50/60Hz). Splitted for test purpose */ - {0x66, 0xca, 0xa8, 0xf0}, - .data5 = /* this could be removed later */ - {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23}, - .stream = - {0x0b, 0x04, 0x0a, 0x78}, - }, - { /* OTHER */ - .data1 = - {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a, - 0xe8, 0xfc}, - .data2 = - {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96, - 0xd9}, - .data4 = - {0x66, 0x00, 0xa8, 0xa8}, - .data5 = - {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69}, - .stream = - {0x0b, 0x04, 0x0a, 0x00}, - }, +const static struct additional_sensor_data sensor_data[] = { { /* TAS5130A */ .data1 = - {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27, - 0xc8, 0xfc}, + {0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, + 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27, + 0xd8, 0xc8, 0xd9, 0xfc}, .data2 = - {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8, - 0xe0}, + {0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, + 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8, + 0xe8, 0xe0}, + .data3 = + {0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, + 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8, + 0xcf, 0xe0}, .data4 = /* Freq (50/60Hz). Splitted for test purpose */ {0x66, 0x00, 0xa8, 0xe8}, .data5 = @@ -315,12 +292,32 @@ static const struct additional_sensor_data sensor_data[] = { .stream = {0x0b, 0x04, 0x0a, 0x40}, }, + { /* OM6802 */ + .data1 = + {0xd0, 0xc2, 0xd1, 0x28, 0xd2, 0x0f, 0xd3, 0x22, + 0xd4, 0xcd, 0xd5, 0x27, 0xd6, 0x2c, 0xd7, 0x06, + 0xd8, 0xb3, 0xd9, 0xfc}, + .data2 = + {0xe0, 0x80, 0xe1, 0xff, 0xe2, 0xff, 0xe3, 0x80, + 0xe4, 0xff, 0xe5, 0xff, 0xe6, 0x80, 0xe7, 0xff, + 0xe8, 0xff}, + .data3 = + {0xc7, 0x80, 0xc8, 0xff, 0xc9, 0xff, 0xca, 0x80, + 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0x80, 0xce, 0xff, + 0xcf, 0xff}, + .data4 = /*Freq (50/60Hz). Splitted for test purpose */ + {0x66, 0xca, 0xa8, 0xf0 }, + .data5 = /* this could be removed later */ + {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23}, + .stream = + {0x0b, 0x04, 0x0a, 0x78}, + } }; #define MAX_EFFECTS 7 /* easily done by soft, this table could be removed, * i keep it here just in case */ -static const u8 effects_table[MAX_EFFECTS][6] = { +static const __u8 effects_table[MAX_EFFECTS][6] = { {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */ {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */ {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */ @@ -330,58 +327,90 @@ static const u8 effects_table[MAX_EFFECTS][6] = { {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */ }; -static const u8 gamma_table[GAMMA_MAX][17] = { - {0x00, 0x3e, 0x69, 0x85, 0x95, 0xa1, 0xae, 0xb9, /* 0 */ - 0xc2, 0xcb, 0xd4, 0xdb, 0xe3, 0xea, 0xf1, 0xf8, - 0xff}, - {0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad, /* 1 */ - 0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7, - 0xff}, - {0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6, /* 2 */ - 0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6, - 0xff}, - {0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e, /* 3 */ - 0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5, - 0xff}, - {0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95, /* 4 */ - 0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4, - 0xff}, - {0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87, /* 5 */ - 0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3, - 0xff}, - {0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67, /* 6 */ - 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, - 0xff}, - {0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70, /* 7 */ - 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, - 0xff}, - {0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79, /* 8 */ - 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0, - 0xff}, - {0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84, /* 9 */ - 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0, - 0xff}, - {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */ - 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0, - 0xff}, - {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8D, 0x9B, /* 11 */ - 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5, - 0xff}, - {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */ - 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6, - 0xff}, - {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */ - 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9, - 0xff}, - {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */ - 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa, - 0xff}, - {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */ - 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc, - 0xff} +static const __u8 gamma_table[GAMMA_MAX][34] = { + {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, /* 0 */ + 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9, + 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb, + 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x33, 0x92, 0x5a, 0x93, 0x75, /* 1 */ + 0x94, 0x85, 0x95, 0x93, 0x96, 0xa1, 0x97, 0xad, + 0x98, 0xb7, 0x99, 0xc2, 0x9a, 0xcb, 0x9b, 0xd4, + 0x9c, 0xde, 0x9D, 0xe7, 0x9e, 0xf0, 0x9f, 0xf7, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x2f, 0x92, 0x51, 0x93, 0x6b, /* 2 */ + 0x94, 0x7c, 0x95, 0x8a, 0x96, 0x99, 0x97, 0xa6, + 0x98, 0xb1, 0x99, 0xbc, 0x9a, 0xc6, 0x9b, 0xd0, + 0x9c, 0xdb, 0x9d, 0xe4, 0x9e, 0xed, 0x9f, 0xf6, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, /* 3 */ + 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9e, + 0x98, 0xaa, 0x99, 0xb5, 0x9a, 0xbf, 0x9b, 0xcb, + 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x23, 0x92, 0x3f, 0x93, 0x55, /* 4 */ + 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95, + 0x98, 0xa2, 0x99, 0xad, 0x9a, 0xb9, 0x9b, 0xc6, + 0x9c, 0xd2, 0x9d, 0xde, 0x9e, 0xe9, 0x9f, 0xf4, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x1b, 0x92, 0x33, 0x93, 0x48, /* 5 */ + 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87, + 0x98, 0x96, 0x99, 0xa3, 0x9a, 0xb1, 0x9b, 0xbe, + 0x9c, 0xcc, 0x9d, 0xda, 0x9e, 0xe7, 0x9f, 0xf3, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, /* 6 */ + 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67, + 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa, + 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, /* 7 */ + 0x94, 0x38, 0x95, 0x4a, 0x96, 0x60, 0x97, 0x70, + 0x98, 0x80, 0x99, 0x90, 0x9a, 0xa0, 0x9b, 0xb0, + 0x9c, 0xc0, 0x9D, 0xd0, 0x9e, 0xe0, 0x9f, 0xf0, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, /* 8 */ + 0x94, 0x47, 0x95, 0x5a, 0x96, 0x69, 0x97, 0x79, + 0x98, 0x88, 0x99, 0x97, 0x9a, 0xa7, 0x9b, 0xb6, + 0x9c, 0xc4, 0x9d, 0xd3, 0x9e, 0xe0, 0x9f, 0xf0, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, /* 9 */ + 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84, + 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, + 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x18, 0x92, 0x2b, 0x93, 0x44, /* 10 */ + 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8e, + 0x98, 0x9c, 0x99, 0xaa, 0x9a, 0xb7, 0x9b, 0xc4, + 0x9c, 0xd0, 0x9d, 0xd8, 0x9e, 0xe2, 0x9f, 0xf0, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x1a, 0x92, 0x34, 0x93, 0x52, /* 11 */ + 0x94, 0x66, 0x95, 0x7e, 0x96, 0x8D, 0x97, 0x9B, + 0x98, 0xa8, 0x99, 0xb4, 0x9a, 0xc0, 0x9b, 0xcb, + 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x3f, 0x92, 0x5a, 0x93, 0x6e, /* 12 */ + 0x94, 0x7f, 0x95, 0x8e, 0x96, 0x9c, 0x97, 0xa8, + 0x98, 0xb4, 0x99, 0xbf, 0x9a, 0xc9, 0x9b, 0xd3, + 0x9c, 0xdc, 0x9d, 0xe5, 0x9e, 0xee, 0x9f, 0xf6, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x54, 0x92, 0x6f, 0x93, 0x83, /* 13 */ + 0x94, 0x93, 0x95, 0xa0, 0x96, 0xad, 0x97, 0xb7, + 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdc, + 0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a, /* 14 */ + 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6, + 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3, + 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7, /* 15 */ + 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8, + 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed, + 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc, + 0xa0, 0xff} }; -static const u8 tas5130a_sensor_init[][8] = { +static const __u8 tas5130a_sensor_init[][8] = { {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09}, {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09}, {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}, @@ -389,11 +418,11 @@ static const u8 tas5130a_sensor_init[][8] = { {}, }; -static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07}; +static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07}; /* read 1 byte */ -static u8 reg_r(struct gspca_dev *gspca_dev, - u16 index) +static int reg_r(struct gspca_dev *gspca_dev, + __u16 index) { usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0), @@ -406,7 +435,7 @@ static u8 reg_r(struct gspca_dev *gspca_dev, } static void reg_w(struct gspca_dev *gspca_dev, - u16 index) + __u16 index) { usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), @@ -417,7 +446,7 @@ static void reg_w(struct gspca_dev *gspca_dev, } static void reg_w_buf(struct gspca_dev *gspca_dev, - const u8 *buffer, u16 len) + const __u8 *buffer, __u16 len) { if (len <= USB_BUF_SZ) { memcpy(gspca_dev->usb_buf, buffer, len); @@ -428,7 +457,7 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, 0x01, 0, gspca_dev->usb_buf, len, 500); } else { - u8 *tmpbuf; + __u8 *tmpbuf; tmpbuf = kmalloc(len, GFP_KERNEL); memcpy(tmpbuf, buffer, len); @@ -442,41 +471,14 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, } } -/* write values to consecutive registers */ -static void reg_w_ixbuf(struct gspca_dev *gspca_dev, - u8 reg, - const u8 *buffer, u16 len) -{ - int i; - u8 *p, *tmpbuf; - - if (len * 2 <= USB_BUF_SZ) - p = tmpbuf = gspca_dev->usb_buf; - else - p = tmpbuf = kmalloc(len * 2, GFP_KERNEL); - i = len; - while (--i >= 0) { - *p++ = reg++; - *p++ = *buffer++; - } - usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), - 0, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x01, 0, - tmpbuf, len * 2, 500); - if (len * 2 > USB_BUF_SZ) - kfree(tmpbuf); -} - /* Reported as OM6802*/ static void om6802_sensor_init(struct gspca_dev *gspca_dev) { int i; - const u8 *p; - u8 byte; - u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05}; - static const u8 sensor_init[] = { + const __u8 *p; + __u8 byte; + __u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05}; + static const __u8 sensor_init[] = { 0xdf, 0x6d, 0xdd, 0x18, 0x5a, 0xe0, @@ -495,7 +497,7 @@ static void om6802_sensor_init(struct gspca_dev *gspca_dev) }; reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); - msleep(100); + msleep(5); i = 4; while (--i > 0) { byte = reg_r(gspca_dev, 0x0060); @@ -536,20 +538,20 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; + cam->epaddr = 0x01; cam->cam_mode = vga_mode_t16; cam->nmodes = ARRAY_SIZE(vga_mode_t16); - sd->brightness = BRIGHTNESS_DEF; - sd->contrast = CONTRAST_DEF; - sd->colors = COLORS_DEF; + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; sd->gamma = GAMMA_DEF; - sd->autogain = AUTOGAIN_DEF; - sd->mirror = MIRROR_DEF; - sd->freq = FREQ_DEF; - sd->whitebalance = WHITE_BALANCE_DEF; - sd->sharpness = SHARPNESS_DEF; - sd->effect = EFFECTS_DEF; + sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value; + sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value; + sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value; + sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value; + sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value; return 0; } @@ -557,7 +559,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; unsigned int brightness; - u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 }; + __u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 }; brightness = sd->brightness; if (brightness < 7) { @@ -574,7 +576,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; unsigned int contrast = sd->contrast; - u16 reg_to_write; + __u16 reg_to_write; if (contrast < 7) reg_to_write = 0x8ea9 - contrast * 0x200; @@ -587,7 +589,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - u16 reg_to_write; + __u16 reg_to_write; reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */ reg_w(gspca_dev, reg_to_write); @@ -598,15 +600,14 @@ static void setgamma(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; PDEBUG(D_CONF, "Gamma: %d", sd->gamma); - reg_w_ixbuf(gspca_dev, 0x90, - gamma_table[sd->gamma], sizeof gamma_table[0]); + reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]); } static void setwhitebalance(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - u8 white_balance[8] = + __u8 white_balance[8] = {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38}; if (sd->whitebalance) @@ -618,7 +619,7 @@ static void setwhitebalance(struct gspca_dev *gspca_dev) static void setsharpness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - u16 reg_to_write; + __u16 reg_to_write; reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; @@ -634,22 +635,18 @@ static int sd_init(struct gspca_dev *gspca_dev) * to see the initial parameters.*/ struct sd *sd = (struct sd *) gspca_dev; int i; - u16 sensor_id; - u8 test_byte = 0; - u16 reg80, reg8e; - - static const u8 read_indexs[] = - { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, - 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 }; - static const u8 n1[] = + __u8 byte, test_byte; + + static const __u8 read_indexs[] = + { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, + 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 }; + static const __u8 n1[] = {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; - static const u8 n2[] = + static const __u8 n2[] = {0x08, 0x00}; - static const u8 n3[6] = + static const __u8 n3[] = {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; - static const u8 n3_other[6] = - {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00}; - static const u8 n4[] = + static const __u8 n4[] = {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c, 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68, 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1, @@ -659,61 +656,40 @@ static int sd_init(struct gspca_dev *gspca_dev) 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; - static const u8 n4_other[] = - {0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69, - 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68, - 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8, - 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8, - 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56, - 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5, - 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0, - 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00}; - static const u8 nset8[6] = - { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 }; - static const u8 nset8_other[6] = - { 0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00 }; - static const u8 nset9[4] = + static const __u8 nset9[4] = { 0x0b, 0x04, 0x0a, 0x78 }; - static const u8 nset9_other[4] = - { 0x0b, 0x04, 0x0a, 0x00 }; - - sensor_id = (reg_r(gspca_dev, 0x06) << 8) - | reg_r(gspca_dev, 0x07); - switch (sensor_id & 0xff0f) { - case 0x0801: - PDEBUG(D_PROBE, "sensor tas5130a"); - sd->sensor = SENSOR_TAS5130A; - break; - case 0x0803: - PDEBUG(D_PROBE, "sensor 'other'"); - sd->sensor = SENSOR_OTHER; - break; - case 0x0807: - PDEBUG(D_PROBE, "sensor om6802"); + static const __u8 nset8[6] = + { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 }; + + byte = reg_r(gspca_dev, 0x06); + test_byte = reg_r(gspca_dev, 0x07); + if (byte == 0x08 && test_byte == 0x07) { + PDEBUG(D_CONF, "sensor om6802"); sd->sensor = SENSOR_OM6802; - break; - default: - PDEBUG(D_ERR|D_PROBE, "unknown sensor %04x", sensor_id); - return -EINVAL; + } else if (byte == 0x08 && test_byte == 0x01) { + PDEBUG(D_CONF, "sensor tas5130a"); + sd->sensor = SENSOR_TAS5130A; + } else { + PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte); + sd->sensor = SENSOR_TAS5130A; } - if (sd->sensor != SENSOR_OTHER) { - reg_w_buf(gspca_dev, n1, sizeof n1); - i = 5; - while (--i >= 0) { - reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); - test_byte = reg_r(gspca_dev, 0x0063); - msleep(100); - if (test_byte == 0x17) - break; /* OK */ - } - if (i < 0) { - err("Bad sensor reset %02x", test_byte); -/* return -EIO; */ + reg_w_buf(gspca_dev, n1, sizeof n1); + test_byte = 0; + i = 5; + while (--i >= 0) { + reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); + test_byte = reg_r(gspca_dev, 0x0063); + msleep(100); + if (test_byte == 0x17) + break; /* OK */ + } + if (i < 0) { + err("Bad sensor reset %02x", test_byte); +/* return -EIO; */ /*fixme: test - continue */ - } - reg_w_buf(gspca_dev, n2, sizeof n2); } + reg_w_buf(gspca_dev, n2, sizeof n2); i = 0; while (read_indexs[i] != 0x00) { @@ -723,31 +699,21 @@ static int sd_init(struct gspca_dev *gspca_dev) i++; } - if (sd->sensor != SENSOR_OTHER) { - reg_w_buf(gspca_dev, n3, sizeof n3); - reg_w_buf(gspca_dev, n4, sizeof n4); - reg_r(gspca_dev, 0x0080); - reg_w(gspca_dev, 0x2c80); - reg80 = 0x3880; - reg8e = 0x338e; - } else { - reg_w_buf(gspca_dev, n3_other, sizeof n3_other); - reg_w_buf(gspca_dev, n4_other, sizeof n4_other); - sd->gamma = 5; - reg80 = 0xac80; - reg8e = 0xb88e; - } + reg_w_buf(gspca_dev, n3, sizeof n3); + reg_w_buf(gspca_dev, n4, sizeof n4); + reg_r(gspca_dev, 0x0080); + reg_w(gspca_dev, 0x2c80); - reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1, + reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1, sizeof sensor_data[sd->sensor].data1); - reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2, - sizeof sensor_data[sd->sensor].data2); - reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2, + reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3, + sizeof sensor_data[sd->sensor].data3); + reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2, sizeof sensor_data[sd->sensor].data2); - reg_w(gspca_dev, reg80); - reg_w(gspca_dev, reg80); - reg_w(gspca_dev, reg8e); + reg_w(gspca_dev, 0x3880); + reg_w(gspca_dev, 0x3880); + reg_w(gspca_dev, 0x338e); setbrightness(gspca_dev); setcontrast(gspca_dev); @@ -764,20 +730,16 @@ static int sd_init(struct gspca_dev *gspca_dev) sizeof sensor_data[sd->sensor].data4); reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5, sizeof sensor_data[sd->sensor].data5); - if (sd->sensor != SENSOR_OTHER) { - reg_w_buf(gspca_dev, nset8, sizeof nset8); - reg_w_buf(gspca_dev, nset9, sizeof nset9); - reg_w(gspca_dev, 0x2880); - } else { - reg_w_buf(gspca_dev, nset8_other, sizeof nset8_other); - reg_w_buf(gspca_dev, nset9_other, sizeof nset9_other); - } + reg_w_buf(gspca_dev, nset8, sizeof nset8); + reg_w_buf(gspca_dev, nset9, sizeof nset9); - reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1, + reg_w(gspca_dev, 0x2880); + + reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1, sizeof sensor_data[sd->sensor].data1); - reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2, - sizeof sensor_data[sd->sensor].data2); - reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2, + reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3, + sizeof sensor_data[sd->sensor].data3); + reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2, sizeof sensor_data[sd->sensor].data2); return 0; @@ -786,7 +748,7 @@ static int sd_init(struct gspca_dev *gspca_dev) static void setflip(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - u8 flipcmd[8] = + __u8 flipcmd[8] = {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}; if (sd->mirror) @@ -816,7 +778,7 @@ static void seteffect(struct gspca_dev *gspca_dev) static void setlightfreq(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 }; + __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 }; if (sd->freq == 2) /* 60hz */ freq[1] = 0x00; @@ -829,22 +791,22 @@ static void setlightfreq(struct gspca_dev *gspca_dev) static void poll_sensor(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - static const u8 poll1[] = + static const __u8 poll1[] = {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82, 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34, 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01, 0x60, 0x14}; - static const u8 poll2[] = + static const __u8 poll2[] = {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9, 0x73, 0x02, 0x73, 0x02, 0x60, 0x14}; - static const u8 poll3[] = + static const __u8 poll3[] = {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d}; - static const u8 poll4[] = + static const __u8 poll4[] = {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f, 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c, 0xc2, 0x80, 0xc3, 0x10}; - if (sd->sensor == SENSOR_OM6802) { + if (sd->sensor != SENSOR_TAS5130A) { PDEBUG(D_STREAM, "[Sensor requires polling]"); reg_w_buf(gspca_dev, poll1, sizeof poll1); reg_w_buf(gspca_dev, poll2, sizeof poll2); @@ -857,14 +819,13 @@ static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i, mode; - u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; - static const u8 t3[] = - { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 }; + __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; + static const __u8 t3[] = + { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06, + 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 }; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv; switch (mode) { - case 0: /* 640x480 (0x00) */ - break; case 1: /* 352x288 */ t2[1] = 0x40; break; @@ -874,20 +835,14 @@ static int sd_start(struct gspca_dev *gspca_dev) case 3: /* 176x144 */ t2[1] = 0x50; break; - default: -/* case 4: * 160x120 */ + case 4: /* 160x120 */ t2[1] = 0x20; break; + default: /* 640x480 (0x00) */ + break; } - switch (sd->sensor) { - case SENSOR_OM6802: - om6802_sensor_init(gspca_dev); - break; - case SENSOR_OTHER: - break; - default: -/* case SENSOR_TAS5130A: */ + if (sd->sensor == SENSOR_TAS5130A) { i = 0; while (tas5130a_sensor_init[i][0] != 0) { reg_w_buf(gspca_dev, tas5130a_sensor_init[i], @@ -899,13 +854,14 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w_buf(gspca_dev, tas5130a_sensor_init[3], sizeof tas5130a_sensor_init[0]); reg_w(gspca_dev, 0x3c80); - break; + } else { + om6802_sensor_init(gspca_dev); } reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4, sizeof sensor_data[sd->sensor].data4); reg_r(gspca_dev, 0x0012); reg_w_buf(gspca_dev, t2, sizeof t2); - reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3); + reg_w_buf(gspca_dev, t3, sizeof t3); reg_w(gspca_dev, 0x0013); msleep(15); reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, @@ -929,18 +885,16 @@ static void sd_stopN(struct gspca_dev *gspca_dev) msleep(20); reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, sizeof sensor_data[sd->sensor].stream); - if (sd->sensor != SENSOR_OTHER) { - msleep(20); - reg_w(gspca_dev, 0x0309); - } + msleep(20); + reg_w(gspca_dev, 0x0309); } static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - u8 *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { - static u8 ffd9[] = { 0xff, 0xd9 }; + static __u8 ffd9[] = { 0xff, 0xd9 }; if (data[0] == 0x5a) { /* Control Packet, after this came the header again, @@ -1218,10 +1172,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/tv8532.c b/trunk/drivers/media/video/gspca/tv8532.c index 9f243d7e3110..94163cceb28a 100644 --- a/trunk/drivers/media/video/gspca/tv8532.c +++ b/trunk/drivers/media/video/gspca/tv8532.c @@ -31,6 +31,7 @@ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ __u16 brightness; + __u16 contrast; __u8 packet; }; @@ -38,22 +39,38 @@ struct sd { /* V4L2 controls supported by the driver */ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", .minimum = 1, - .maximum = 0x15f, /* = 352 - 1 */ + .maximum = 0x2ff, .step = 1, -#define BRIGHTNESS_DEF 0x14c - .default_value = BRIGHTNESS_DEF, + .default_value = 0x18f, }, .set = sd_setbrightness, .get = sd_getbrightness, }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 0xffff, + .step = 1, + .default_value = 0x7fff, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, }; static const struct v4l2_pix_format sif_mode[] = { @@ -69,64 +86,78 @@ static const struct v4l2_pix_format sif_mode[] = { .priv = 0}, }; -/* TV-8532A (ICM532A) registers (LE) */ -#define R00_PART_CONTROL 0x00 -#define LATENT_CHANGE 0x80 -#define EXPO_CHANGE 0x04 -#define R01_TIMING_CONTROL_LOW 0x01 -#define CMD_EEprom_Open 0x30 -#define CMD_EEprom_Close 0x29 -#define R03_TABLE_ADDR 0x03 -#define R04_WTRAM_DATA_L 0x04 -#define R05_WTRAM_DATA_M 0x05 -#define R06_WTRAM_DATA_H 0x06 -#define R07_TABLE_LEN 0x07 -#define R08_RAM_WRITE_ACTION 0x08 -#define R0C_AD_WIDTHL 0x0c -#define R0D_AD_WIDTHH 0x0d -#define R0E_AD_HEIGHTL 0x0e -#define R0F_AD_HEIGHTH 0x0f -#define R10_AD_COL_BEGINL 0x10 -#define R11_AD_COL_BEGINH 0x11 -#define MIRROR 0x04 /* [10] */ -#define R14_AD_ROW_BEGINL 0x14 -#define R15_AD_ROWBEGINH 0x15 -#define R1C_AD_EXPOSE_TIMEL 0x1c -#define R28_QUANT 0x28 -#define R29_LINE 0x29 -#define R2C_POLARITY 0x2c -#define R2D_POINT 0x2d -#define R2E_POINTH 0x2e -#define R2F_POINTB 0x2f -#define R30_POINTBH 0x30 -#define R31_UPD 0x31 -#define R2A_HIGH_BUDGET 0x2a -#define R2B_LOW_BUDGET 0x2b -#define R34_VID 0x34 -#define R35_VIDH 0x35 -#define R36_PID 0x36 -#define R37_PIDH 0x37 -#define R39_Test1 0x39 /* GPIO */ -#define R3B_Test3 0x3B /* GPIO */ -#define R83_AD_IDH 0x83 -#define R91_AD_SLOPEREG 0x91 -#define R94_AD_BITCONTROL 0x94 - -static const u8 eeprom_data[][3] = { -/* dataH dataM dataL */ - {0x01, 0x00, 0x01}, - {0x01, 0x80, 0x11}, - {0x05, 0x00, 0x14}, - {0x05, 0x00, 0x1c}, - {0x0d, 0x00, 0x1e}, - {0x05, 0x00, 0x1f}, - {0x05, 0x05, 0x19}, - {0x05, 0x01, 0x1b}, - {0x05, 0x09, 0x1e}, - {0x0d, 0x89, 0x2e}, - {0x05, 0x89, 0x2f}, - {0x05, 0x0d, 0xd9}, - {0x05, 0x09, 0xf1}, +/* + * Initialization data: this is the first set-up data written to the + * device (before the open data). + */ +#define TESTCLK 0x10 /* reg 0x2c -> 0x12 //10 */ +#define TESTCOMP 0x90 /* reg 0x28 -> 0x80 */ +#define TESTLINE 0x81 /* reg 0x29 -> 0x81 */ +#define QCIFLINE 0x41 /* reg 0x29 -> 0x81 */ +#define TESTPTL 0x14 /* reg 0x2D -> 0x14 */ +#define TESTPTH 0x01 /* reg 0x2E -> 0x01 */ +#define TESTPTBL 0x12 /* reg 0x2F -> 0x0a */ +#define TESTPTBH 0x01 /* reg 0x30 -> 0x01 */ +#define ADWIDTHL 0xe8 /* reg 0x0c -> 0xe8 */ +#define ADWIDTHH 0x03 /* reg 0x0d -> 0x03 */ +#define ADHEIGHL 0x90 /* reg 0x0e -> 0x91 //93 */ +#define ADHEIGHH 0x01 /* reg 0x0f -> 0x01 */ +#define EXPOL 0x8f /* reg 0x1c -> 0x8f */ +#define EXPOH 0x01 /* reg 0x1d -> 0x01 */ +#define ADCBEGINL 0x44 /* reg 0x10 -> 0x46 //47 */ +#define ADCBEGINH 0x00 /* reg 0x11 -> 0x00 */ +#define ADRBEGINL 0x0a /* reg 0x14 -> 0x0b //0x0c */ +#define ADRBEGINH 0x00 /* reg 0x15 -> 0x00 */ +#define TV8532_CMD_UPDATE 0x84 + +#define TV8532_EEprom_Add 0x03 +#define TV8532_EEprom_DataL 0x04 +#define TV8532_EEprom_DataM 0x05 +#define TV8532_EEprom_DataH 0x06 +#define TV8532_EEprom_TableLength 0x07 +#define TV8532_EEprom_Write 0x08 +#define TV8532_PART_CTRL 0x00 +#define TV8532_CTRL 0x01 +#define TV8532_CMD_EEprom_Open 0x30 +#define TV8532_CMD_EEprom_Close 0x29 +#define TV8532_UDP_UPDATE 0x31 +#define TV8532_GPIO 0x39 +#define TV8532_GPIO_OE 0x3B +#define TV8532_REQ_RegWrite 0x02 +#define TV8532_REQ_RegRead 0x03 + +#define TV8532_ADWIDTH_L 0x0C +#define TV8532_ADWIDTH_H 0x0D +#define TV8532_ADHEIGHT_L 0x0E +#define TV8532_ADHEIGHT_H 0x0F +#define TV8532_EXPOSURE 0x1C +#define TV8532_QUANT_COMP 0x28 +#define TV8532_MODE_PACKET 0x29 +#define TV8532_SETCLK 0x2C +#define TV8532_POINT_L 0x2D +#define TV8532_POINT_H 0x2E +#define TV8532_POINTB_L 0x2F +#define TV8532_POINTB_H 0x30 +#define TV8532_BUDGET_L 0x2A +#define TV8532_BUDGET_H 0x2B +#define TV8532_VID_L 0x34 +#define TV8532_VID_H 0x35 +#define TV8532_PID_L 0x36 +#define TV8532_PID_H 0x37 +#define TV8532_DeviceID 0x83 +#define TV8532_AD_SLOPE 0x91 +#define TV8532_AD_BITCTRL 0x94 +#define TV8532_AD_COLBEGIN_L 0x10 +#define TV8532_AD_COLBEGIN_H 0x11 +#define TV8532_AD_ROWBEGIN_L 0x14 +#define TV8532_AD_ROWBEGIN_H 0x15 + +static const __u32 tv_8532_eeprom_data[] = { +/* add dataL dataM dataH */ + 0x00010001, 0x01018011, 0x02050014, 0x0305001c, + 0x040d001e, 0x0505001f, 0x06050519, 0x0705011b, + 0x0805091e, 0x090d892e, 0x0a05892f, 0x0b050dd9, + 0x0c0509f1, 0 }; static int reg_r(struct gspca_dev *gspca_dev, @@ -134,7 +165,7 @@ static int reg_r(struct gspca_dev *gspca_dev, { usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0), - 0x03, + TV8532_REQ_RegRead, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, gspca_dev->usb_buf, 1, @@ -143,27 +174,27 @@ static int reg_r(struct gspca_dev *gspca_dev, } /* write 1 byte */ -static void reg_w1(struct gspca_dev *gspca_dev, +static void reg_w_1(struct gspca_dev *gspca_dev, __u16 index, __u8 value) { gspca_dev->usb_buf[0] = value; usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), - 0x02, + TV8532_REQ_RegWrite, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, gspca_dev->usb_buf, 1, 500); } /* write 2 bytes */ -static void reg_w2(struct gspca_dev *gspca_dev, - u16 index, u16 value) +static void reg_w_2(struct gspca_dev *gspca_dev, + __u16 index, __u8 val1, __u8 val2) { - gspca_dev->usb_buf[0] = value; - gspca_dev->usb_buf[1] = value >> 8; + gspca_dev->usb_buf[0] = val1; + gspca_dev->usb_buf[1] = val2; usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), - 0x02, + TV8532_REQ_RegWrite, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, gspca_dev->usb_buf, 2, 500); @@ -171,18 +202,32 @@ static void reg_w2(struct gspca_dev *gspca_dev, static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev) { - int i; - - reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Open); - for (i = 0; i < ARRAY_SIZE(eeprom_data); i++) { - reg_w1(gspca_dev, R03_TABLE_ADDR, i); - reg_w1(gspca_dev, R04_WTRAM_DATA_L, eeprom_data[i][2]); - reg_w1(gspca_dev, R05_WTRAM_DATA_M, eeprom_data[i][1]); - reg_w1(gspca_dev, R06_WTRAM_DATA_H, eeprom_data[i][0]); - reg_w1(gspca_dev, R08_RAM_WRITE_ACTION, 0); + int i = 0; + __u8 reg, data0, data1, data2; + + reg_w_1(gspca_dev, TV8532_GPIO, 0xb0); + reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Open); +/* msleep(1); */ + while (tv_8532_eeprom_data[i]) { + reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24; + reg_w_1(gspca_dev, TV8532_EEprom_Add, reg); + /* msleep(1); */ + data0 = (tv_8532_eeprom_data[i] & 0x000000ff); + reg_w_1(gspca_dev, TV8532_EEprom_DataL, data0); + /* msleep(1); */ + data1 = (tv_8532_eeprom_data[i] & 0x0000ff00) >> 8; + reg_w_1(gspca_dev, TV8532_EEprom_DataM, data1); + /* msleep(1); */ + data2 = (tv_8532_eeprom_data[i] & 0x00ff0000) >> 16; + reg_w_1(gspca_dev, TV8532_EEprom_DataH, data2); + /* msleep(1); */ + reg_w_1(gspca_dev, TV8532_EEprom_Write, 0); + /* msleep(10); */ + i++; } - reg_w1(gspca_dev, R07_TABLE_LEN, i); - reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close); + reg_w_1(gspca_dev, TV8532_EEprom_TableLength, i); +/* msleep(1); */ + reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Close); msleep(10); } @@ -193,76 +238,79 @@ static int sd_config(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; + tv_8532WriteEEprom(gspca_dev); + cam = &gspca_dev->cam; + cam->epaddr = 1; cam->cam_mode = sif_mode; - cam->nmodes = ARRAY_SIZE(sif_mode); + cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; - sd->brightness = BRIGHTNESS_DEF; + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; return 0; } static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev) { - int i; - static u8 reg_tb[] = { - R0C_AD_WIDTHL, - R0D_AD_WIDTHH, - R28_QUANT, - R29_LINE, - R2C_POLARITY, - R2D_POINT, - R2E_POINTH, - R2F_POINTB, - R30_POINTBH, - R2A_HIGH_BUDGET, - R2B_LOW_BUDGET, - R34_VID, - R35_VIDH, - R36_PID, - R37_PIDH, - R83_AD_IDH, - R10_AD_COL_BEGINL, - R11_AD_COL_BEGINH, - R14_AD_ROW_BEGINL, - R15_AD_ROWBEGINH, - 0 - }; - - i = 0; - do { - reg_r(gspca_dev, reg_tb[i]); - i++; - } while (reg_tb[i] != 0); + __u8 data; + + data = reg_r(gspca_dev, 0x0001); + PDEBUG(D_USBI, "register 0x01-> %x", data); + data = reg_r(gspca_dev, 0x0002); + PDEBUG(D_USBI, "register 0x02-> %x", data); + reg_r(gspca_dev, TV8532_ADWIDTH_L); + reg_r(gspca_dev, TV8532_ADWIDTH_H); + reg_r(gspca_dev, TV8532_QUANT_COMP); + reg_r(gspca_dev, TV8532_MODE_PACKET); + reg_r(gspca_dev, TV8532_SETCLK); + reg_r(gspca_dev, TV8532_POINT_L); + reg_r(gspca_dev, TV8532_POINT_H); + reg_r(gspca_dev, TV8532_POINTB_L); + reg_r(gspca_dev, TV8532_POINTB_H); + reg_r(gspca_dev, TV8532_BUDGET_L); + reg_r(gspca_dev, TV8532_BUDGET_H); + reg_r(gspca_dev, TV8532_VID_L); + reg_r(gspca_dev, TV8532_VID_H); + reg_r(gspca_dev, TV8532_PID_L); + reg_r(gspca_dev, TV8532_PID_H); + reg_r(gspca_dev, TV8532_DeviceID); + reg_r(gspca_dev, TV8532_AD_COLBEGIN_L); + reg_r(gspca_dev, TV8532_AD_COLBEGIN_H); + reg_r(gspca_dev, TV8532_AD_ROWBEGIN_L); + reg_r(gspca_dev, TV8532_AD_ROWBEGIN_H); } static void tv_8532_setReg(struct gspca_dev *gspca_dev) { - reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44); - /* begin active line */ - reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00); - /* mirror and digital gain */ - reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE); - /* = 0x84 */ - - reg_w1(gspca_dev, R3B_Test3, 0x0a); /* Test0Sel = 10 */ + reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L, + ADCBEGINL); /* 0x10 */ + reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H, + ADCBEGINH); /* also digital gain */ + reg_w_1(gspca_dev, TV8532_PART_CTRL, + TV8532_CMD_UPDATE); /* 0x00<-0x84 */ + + reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0a); /******************************************************/ - reg_w1(gspca_dev, R0E_AD_HEIGHTL, 0x90); - reg_w1(gspca_dev, R0F_AD_HEIGHTH, 0x01); - reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f); - reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44); - /* begin active line */ - reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00); - /* mirror and digital gain */ - reg_w1(gspca_dev, R14_AD_ROW_BEGINL, 0x0a); - - reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00); - reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x02); - - reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close); - - reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00); - reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE); - /* = 0x84 */ + reg_w_1(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL); /* 0e */ + reg_w_1(gspca_dev, TV8532_ADHEIGHT_H, ADHEIGHH); /* 0f */ + reg_w_2(gspca_dev, TV8532_EXPOSURE, + EXPOL, EXPOH); /* 350d 0x014c; 1c */ + reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L, + ADCBEGINL); /* 0x10 */ + reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H, + ADCBEGINH); /* also digital gain */ + reg_w_1(gspca_dev, TV8532_AD_ROWBEGIN_L, + ADRBEGINL); /* 0x14 */ + + reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */ + reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x02); /* 0x94 */ + + reg_w_1(gspca_dev, TV8532_CTRL, + TV8532_CMD_EEprom_Close); /* 0x01 */ + + reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */ + reg_w_1(gspca_dev, TV8532_PART_CTRL, + TV8532_CMD_UPDATE); /* 0x00<-0x84 */ } static void tv_8532_PollReg(struct gspca_dev *gspca_dev) @@ -271,55 +319,54 @@ static void tv_8532_PollReg(struct gspca_dev *gspca_dev) /* strange polling from tgc */ for (i = 0; i < 10; i++) { - reg_w1(gspca_dev, R2C_POLARITY, 0x10); - reg_w1(gspca_dev, R00_PART_CONTROL, - LATENT_CHANGE | EXPO_CHANGE); - reg_w1(gspca_dev, R31_UPD, 0x01); + reg_w_1(gspca_dev, TV8532_SETCLK, + TESTCLK); /* 0x48; //0x08; 0x2c */ + reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE); + reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ } } /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { - tv_8532WriteEEprom(gspca_dev); - - reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32); /* slope begin 1,7V, - * slope rate 2 */ - reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00); + reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); + reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); tv_8532ReadRegisters(gspca_dev); - reg_w1(gspca_dev, R3B_Test3, 0x0b); - reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190); - reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f); - reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8); - reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03); + reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); + reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL, + ADHEIGHH); /* 401d 0x0169; 0e */ + reg_w_2(gspca_dev, TV8532_EXPOSURE, EXPOL, + EXPOH); /* 350d 0x014c; 1c */ + reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */ + reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */ /*******************************************************************/ - reg_w1(gspca_dev, R28_QUANT, 0x90); - /* no compress - fixed Q - quant 0 */ - reg_w1(gspca_dev, R29_LINE, 0x81); - /* 0x84; // CIF | 4 packet 0x29 */ + reg_w_1(gspca_dev, TV8532_QUANT_COMP, + TESTCOMP); /* 0x72 compressed mode 0x28 */ + reg_w_1(gspca_dev, TV8532_MODE_PACKET, + TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */ /************************************************/ - reg_w1(gspca_dev, R2C_POLARITY, 0x10); - /* 0x48; //0x08; 0x2c */ - reg_w1(gspca_dev, R2D_POINT, 0x14); - /* 0x38; 0x2d */ - reg_w1(gspca_dev, R2E_POINTH, 0x01); - /* 0x04; 0x2e */ - reg_w1(gspca_dev, R2F_POINTB, 0x12); - /* 0x04; 0x2f */ - reg_w1(gspca_dev, R30_POINTBH, 0x01); - /* 0x04; 0x30 */ - reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE); - /* 0x00<-0x84 */ + reg_w_1(gspca_dev, TV8532_SETCLK, + TESTCLK); /* 0x48; //0x08; 0x2c */ + reg_w_1(gspca_dev, TV8532_POINT_L, + TESTPTL); /* 0x38; 0x2d */ + reg_w_1(gspca_dev, TV8532_POINT_H, + TESTPTH); /* 0x04; 0x2e */ + reg_w_1(gspca_dev, TV8532_POINTB_L, + TESTPTBL); /* 0x04; 0x2f */ + reg_w_1(gspca_dev, TV8532_POINTB_H, + TESTPTBH); /* 0x04; 0x30 */ + reg_w_1(gspca_dev, TV8532_PART_CTRL, + TV8532_CMD_UPDATE); /* 0x00<-0x84 */ /*************************************************/ - reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */ + reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ msleep(200); - reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */ + reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ /*************************************************/ tv_8532_setReg(gspca_dev); /*************************************************/ - reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */ + reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); /*************************************************/ tv_8532_setReg(gspca_dev); /*************************************************/ @@ -330,10 +377,11 @@ static int sd_init(struct gspca_dev *gspca_dev) static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + int brightness = sd->brightness; - reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, sd->brightness); - reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE); - /* 0x84 */ + reg_w_2(gspca_dev, TV8532_EXPOSURE, + brightness >> 8, brightness); /* 1c */ + reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE); } /* -- start the camera -- */ @@ -341,50 +389,57 @@ static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32); /* slope begin 1,7V, - * slope rate 2 */ - reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00); + reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); + reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); tv_8532ReadRegisters(gspca_dev); - reg_w1(gspca_dev, R3B_Test3, 0x0b); - - reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190); + reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); + reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, + ADHEIGHL, ADHEIGHH); /* 401d 0x0169; 0e */ +/* reg_w_2(gspca_dev, TV8532_EXPOSURE, + EXPOL, EXPOH); * 350d 0x014c; 1c */ setbrightness(gspca_dev); - reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8); /* 0x20; 0x0c */ - reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03); + reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */ + reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */ /************************************************/ - reg_w1(gspca_dev, R28_QUANT, 0x90); - /* 0x72 compressed mode 0x28 */ + reg_w_1(gspca_dev, TV8532_QUANT_COMP, + TESTCOMP); /* 0x72 compressed mode 0x28 */ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { /* 176x144 */ - reg_w1(gspca_dev, R29_LINE, 0x41); - /* CIF - 2 lines/packet */ + reg_w_1(gspca_dev, TV8532_MODE_PACKET, + QCIFLINE); /* 0x84; // CIF | 4 packet 0x29 */ } else { /* 352x288 */ - reg_w1(gspca_dev, R29_LINE, 0x81); - /* CIF - 2 lines/packet */ + reg_w_1(gspca_dev, TV8532_MODE_PACKET, + TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */ } /************************************************/ - reg_w1(gspca_dev, R2C_POLARITY, 0x10); /* slow clock */ - reg_w1(gspca_dev, R2D_POINT, 0x14); - reg_w1(gspca_dev, R2E_POINTH, 0x01); - reg_w1(gspca_dev, R2F_POINTB, 0x12); - reg_w1(gspca_dev, R30_POINTBH, 0x01); - reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE); + reg_w_1(gspca_dev, TV8532_SETCLK, + TESTCLK); /* 0x48; //0x08; 0x2c */ + reg_w_1(gspca_dev, TV8532_POINT_L, + TESTPTL); /* 0x38; 0x2d */ + reg_w_1(gspca_dev, TV8532_POINT_H, + TESTPTH); /* 0x04; 0x2e */ + reg_w_1(gspca_dev, TV8532_POINTB_L, + TESTPTBL); /* 0x04; 0x2f */ + reg_w_1(gspca_dev, TV8532_POINTB_H, + TESTPTBH); /* 0x04; 0x30 */ + reg_w_1(gspca_dev, TV8532_PART_CTRL, + TV8532_CMD_UPDATE); /* 0x00<-0x84 */ /************************************************/ - reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */ + reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ msleep(200); - reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */ + reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ /************************************************/ tv_8532_setReg(gspca_dev); /************************************************/ - reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */ + reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); /************************************************/ tv_8532_setReg(gspca_dev); /************************************************/ tv_8532_PollReg(gspca_dev); - reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */ + reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ gspca_dev->empty_packet = 0; /* check the empty packets */ sd->packet = 0; /* ignore the first packets */ @@ -394,7 +449,7 @@ static int sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { - reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */ + reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); } static void sd_pkt_scan(struct gspca_dev *gspca_dev, @@ -418,9 +473,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, /* each packet contains: * - header 2 bytes - * - RGRG line + * - RG line * - 4 bytes - * - GBGB line + * - GB line * - 4 bytes */ gspca_frame_add(gspca_dev, packet_type0, @@ -429,6 +484,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, frame, data + gspca_dev->width + 6, gspca_dev->width); } +static void setcontrast(struct gspca_dev *gspca_dev) +{ +} + static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -447,6 +506,24 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->contrast; + return 0; +} + /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -493,10 +570,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/vc032x.c b/trunk/drivers/media/video/gspca/vc032x.c index 4c802fb12cd6..0525ea51a6de 100644 --- a/trunk/drivers/media/video/gspca/vc032x.c +++ b/trunk/drivers/media/video/gspca/vc032x.c @@ -37,21 +37,18 @@ struct sd { __u8 lightfreq; __u8 sharpness; - u8 image_offset; - char bridge; #define BRIDGE_VC0321 0 #define BRIDGE_VC0323 1 char sensor; #define SENSOR_HV7131R 0 #define SENSOR_MI0360 1 -#define SENSOR_MI1310_SOC 2 -#define SENSOR_MI1320 3 -#define SENSOR_MI1320_SOC 4 -#define SENSOR_OV7660 5 -#define SENSOR_OV7670 6 -#define SENSOR_PO1200 7 -#define SENSOR_PO3130NC 8 +#define SENSOR_MI1320 2 +#define SENSOR_MI1310_SOC 3 +#define SENSOR_OV7660 4 +#define SENSOR_OV7670 5 +#define SENSOR_PO1200 6 +#define SENSOR_PO3130NC 7 }; /* V4L2 controls supported by the driver */ @@ -152,50 +149,8 @@ static const struct v4l2_pix_format vc0323_mode[] = { .sizeimage = 640 * 480 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 0}, - {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, /* mi13x0_soc only */ - .bytesperline = 1280, - .sizeimage = 1280 * 1024 * 1 / 4 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, -}; -static const struct v4l2_pix_format bi_mode[] = { -/*fixme: jeg does not work - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 5}, -*/ - {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 4}, -/* - {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 3}, -*/ - {640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 2}, -/* - {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 1280, - .sizeimage = 1280 * 1024 * 1 / 4 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, -*/ - {1280, 1024, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, - .bytesperline = 1280, - .sizeimage = 1280 * 1024 * 2, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0}, }; + static const struct v4l2_pix_format svga_mode[] = { {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 800, @@ -445,208 +400,92 @@ static const __u8 mi0360_initQVGA_JPG[][4] = { static const __u8 mi1310_socinitVGA_JPG[][4] = { {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc}, - {0xb3, 0x00, 0x24, 0xcc}, - {0xb3, 0x00, 0x25, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x03, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, + {0xb3, 0x00, 0x64, 0xcc}, + {0xb3, 0x00, 0x65, 0xcc}, + {0xb3, 0x05, 0x00, 0xcc}, + {0xb3, 0x06, 0x00, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc}, + {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x0d, 0xcc}, + {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, + {0xb3, 0x22, 0x03, 0xcc}, + {0xb3, 0x23, 0xc0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb8, 0x01, 0x7d, 0xcc}, - {0xb8, 0x81, 0x09, 0xcc}, - {0xb8, 0x27, 0x20, 0xcc}, - {0xb8, 0x26, 0x80, 0xcc}, - {0xb3, 0x00, 0x25, 0xcc}, - {0xb8, 0x00, 0x13, 0xcc}, - {0xbc, 0x00, 0x71, 0xcc}, - {0xb8, 0x81, 0x01, 0xcc}, - {0xb8, 0x2c, 0x5a, 0xcc}, - {0xb8, 0x2d, 0xff, 0xcc}, - {0xb8, 0x2e, 0xee, 0xcc}, - {0xb8, 0x2f, 0xfb, 0xcc}, - {0xb8, 0x30, 0x52, 0xcc}, - {0xb8, 0x31, 0xf8, 0xcc}, - {0xb8, 0x32, 0xf1, 0xcc}, - {0xb8, 0x33, 0xff, 0xcc}, - {0xb8, 0x34, 0x54, 0xcc}, - {0xb8, 0x35, 0x00, 0xcc}, - {0xb8, 0x36, 0x00, 0xcc}, - {0xb8, 0x37, 0x00, 0xcc}, + {0xb3, 0x16, 0x04, 0xcc}, + {0xb3, 0x17, 0xff, 0xcc}, + {0xb3, 0x00, 0x65, 0xcc}, + {0xb8, 0x00, 0x00, 0xcc}, + {0xbc, 0x00, 0xd0, 0xcc}, + {0xbc, 0x01, 0x01, 0xcc}, + {0xf0, 0x00, 0x02, 0xbb}, + {0xc8, 0x9f, 0x0b, 0xbb}, + {0x5b, 0x00, 0x01, 0xbb}, + {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x01, 0x00, 0xdd}, - {0x0d, 0x00, 0x09, 0xbb}, - {0x0d, 0x00, 0x08, 0xbb}, + {0x20, 0x03, 0x02, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, - {0x00, 0x01, 0x00, 0xdd}, - {0x06, 0x00, 0x14, 0xbb}, - {0x3a, 0x10, 0x00, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0x9b, 0x10, 0x00, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, + {0x05, 0x00, 0x07, 0xbb}, + {0x34, 0x00, 0x00, 0xbb}, + {0x35, 0xff, 0x00, 0xbb}, + {0xdc, 0x07, 0x02, 0xbb}, + {0xdd, 0x3c, 0x18, 0xbb}, + {0xde, 0x92, 0x6d, 0xbb}, + {0xdf, 0xcd, 0xb1, 0xbb}, + {0xe0, 0xff, 0xe7, 0xbb}, + {0x06, 0xf0, 0x0d, 0xbb}, + {0x06, 0x70, 0x0e, 0xbb}, + {0x4c, 0x00, 0x01, 0xbb}, + {0x4d, 0x00, 0x01, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, + {0x2e, 0x0c, 0x55, 0xbb}, + {0x21, 0xb6, 0x6e, 0xbb}, + {0x36, 0x30, 0x10, 0xbb}, + {0x37, 0x00, 0xc1, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x01, 0x00, 0xdd}, - {0x2b, 0x00, 0x28, 0xbb}, - {0x2c, 0x00, 0x30, 0xbb}, - {0x2d, 0x00, 0x30, 0xbb}, - {0x2e, 0x00, 0x28, 0xbb}, - {0x41, 0x00, 0xd7, 0xbb}, - {0x09, 0x02, 0x3a, 0xbb}, - {0x0c, 0x00, 0x00, 0xbb}, - {0x20, 0x00, 0x00, 0xbb}, - {0x05, 0x00, 0x8c, 0xbb}, - {0x06, 0x00, 0x32, 0xbb}, - {0x07, 0x00, 0xc6, 0xbb}, - {0x08, 0x00, 0x19, 0xbb}, - {0x24, 0x80, 0x6f, 0xbb}, - {0xc8, 0x00, 0x0f, 0xbb}, - {0x20, 0x00, 0x0f, 0xbb}, + {0x07, 0x00, 0x84, 0xbb}, + {0x08, 0x02, 0x4a, 0xbb}, + {0x05, 0x01, 0x10, 0xbb}, + {0x06, 0x00, 0x39, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, + {0x58, 0x02, 0x67, 0xbb}, + {0x57, 0x02, 0x00, 0xbb}, + {0x5a, 0x02, 0x67, 0xbb}, + {0x59, 0x02, 0x00, 0xbb}, + {0x5c, 0x12, 0x0d, 0xbb}, + {0x5d, 0x16, 0x11, 0xbb}, + {0x39, 0x06, 0x18, 0xbb}, + {0x3a, 0x06, 0x18, 0xbb}, + {0x3b, 0x06, 0x18, 0xbb}, + {0x3c, 0x06, 0x18, 0xbb}, + {0x64, 0x7b, 0x5b, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, + {0x36, 0x30, 0x10, 0xbb}, + {0x37, 0x00, 0xc0, 0xbb}, + {0xbc, 0x0e, 0x00, 0xcc}, + {0xbc, 0x0f, 0x05, 0xcc}, + {0xbc, 0x10, 0xc0, 0xcc}, + {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc}, {0xb6, 0x03, 0x02, 0xcc}, {0xb6, 0x02, 0x80, 0xcc}, {0xb6, 0x05, 0x01, 0xcc}, {0xb6, 0x04, 0xe0, 0xcc}, - {0xb6, 0x12, 0x78, 0xcc}, + {0xb6, 0x12, 0xf8, 0xcc}, + {0xb6, 0x13, 0x25, 0xcc}, {0xb6, 0x18, 0x02, 0xcc}, {0xb6, 0x17, 0x58, 0xcc}, {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, {0xb6, 0x23, 0x0b, 0xcc}, - {0xb3, 0x02, 0x02, 0xcc}, - {0xbf, 0xc0, 0x39, 0xcc}, - {0xbf, 0xc1, 0x04, 0xcc}, - {0xbf, 0xcc, 0x10, 0xcc}, - {0xb9, 0x12, 0x00, 0xcc}, - {0xb9, 0x13, 0x0a, 0xcc}, - {0xb9, 0x14, 0x0a, 0xcc}, - {0xb9, 0x15, 0x0a, 0xcc}, - {0xb9, 0x16, 0x0a, 0xcc}, - {0xb9, 0x18, 0x00, 0xcc}, - {0xb9, 0x19, 0x0f, 0xcc}, - {0xb9, 0x1a, 0x0f, 0xcc}, - {0xb9, 0x1b, 0x0f, 0xcc}, - {0xb9, 0x1c, 0x0f, 0xcc}, - {0xb8, 0x8e, 0x00, 0xcc}, - {0xb8, 0x8f, 0xff, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0x03, 0x03, 0xc0, 0xbb}, - {0x06, 0x00, 0x10, 0xbb}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb8, 0x0c, 0x20, 0xcc}, - {0xb8, 0x0d, 0x70, 0xcc}, - {0xb6, 0x13, 0x13, 0xcc}, - {0x2f, 0x00, 0xC0, 0xbb}, - {0xb8, 0xa0, 0x12, 0xcc}, - {}, -}; -static const __u8 mi1310_socinitQVGA_JPG[][4] = { - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0xb3, 0x00, 0x24, 0xcc}, - {0xb3, 0x00, 0x25, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x03, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xdd, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x0d, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb8, 0x01, 0x7d, 0xcc}, - {0xb8, 0x81, 0x09, 0xcc}, - {0xb8, 0x27, 0x20, 0xcc}, - {0xb8, 0x26, 0x80, 0xcc}, - {0xb3, 0x00, 0x25, 0xcc}, - {0xb8, 0x00, 0x13, 0xcc}, - {0xbc, 0x00, 0xd1, 0xcc}, - {0xb8, 0x81, 0x01, 0xcc}, - {0xb8, 0x2c, 0x5a, 0xcc}, - {0xb8, 0x2d, 0xff, 0xcc}, - {0xb8, 0x2e, 0xee, 0xcc}, - {0xb8, 0x2f, 0xfb, 0xcc}, - {0xb8, 0x30, 0x52, 0xcc}, - {0xb8, 0x31, 0xf8, 0xcc}, - {0xb8, 0x32, 0xf1, 0xcc}, - {0xb8, 0x33, 0xff, 0xcc}, - {0xb8, 0x34, 0x54, 0xcc}, - {0xb8, 0x35, 0x00, 0xcc}, - {0xb8, 0x36, 0x00, 0xcc}, - {0xb8, 0x37, 0x00, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x01, 0x00, 0xdd}, - {0x0d, 0x00, 0x09, 0xbb}, - {0x0d, 0x00, 0x08, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x00, 0x01, 0x00, 0xdd}, - {0x06, 0x00, 0x14, 0xbb}, - {0x3a, 0x10, 0x00, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0x9b, 0x10, 0x00, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x01, 0x00, 0xdd}, - {0x2b, 0x00, 0x28, 0xbb}, - {0x2c, 0x00, 0x30, 0xbb}, - {0x2d, 0x00, 0x30, 0xbb}, - {0x2e, 0x00, 0x28, 0xbb}, - {0x41, 0x00, 0xd7, 0xbb}, - {0x09, 0x02, 0x3a, 0xbb}, - {0x0c, 0x00, 0x00, 0xbb}, - {0x20, 0x00, 0x00, 0xbb}, - {0x05, 0x00, 0x8c, 0xbb}, - {0x06, 0x00, 0x32, 0xbb}, - {0x07, 0x00, 0xc6, 0xbb}, - {0x08, 0x00, 0x19, 0xbb}, - {0x24, 0x80, 0x6f, 0xbb}, - {0xc8, 0x00, 0x0f, 0xbb}, - {0x20, 0x00, 0x0f, 0xbb}, - {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x01, 0xcc}, - {0xb6, 0x02, 0x40, 0xcc}, - {0xb6, 0x05, 0x00, 0xcc}, - {0xb6, 0x04, 0xf0, 0xcc}, - {0xb6, 0x12, 0x78, 0xcc}, - {0xb6, 0x18, 0x00, 0xcc}, - {0xb6, 0x17, 0x96, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, - {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, - {0xb3, 0x02, 0x02, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, {0xbf, 0xc1, 0x04, 0xcc}, - {0xbf, 0xcc, 0x10, 0xcc}, - {0xb9, 0x12, 0x00, 0xcc}, - {0xb9, 0x13, 0x0a, 0xcc}, - {0xb9, 0x14, 0x0a, 0xcc}, - {0xb9, 0x15, 0x0a, 0xcc}, - {0xb9, 0x16, 0x0a, 0xcc}, - {0xb9, 0x18, 0x00, 0xcc}, - {0xb9, 0x19, 0x0f, 0xcc}, - {0xb9, 0x1a, 0x0f, 0xcc}, - {0xb9, 0x1b, 0x0f, 0xcc}, - {0xb9, 0x1c, 0x0f, 0xcc}, - {0xb8, 0x8e, 0x00, 0xcc}, - {0xb8, 0x8f, 0xff, 0xcc}, + {0xbf, 0xcc, 0x00, 0xcc}, {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, {0xbc, 0x04, 0x18, 0xcc}, @@ -657,996 +496,288 @@ static const __u8 mi1310_socinitQVGA_JPG[][4] = { {0xbc, 0x0a, 0x10, 0xcc}, {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0x03, 0x03, 0xc0, 0xbb}, - {0x06, 0x00, 0x10, 0xbb}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb8, 0x0c, 0x20, 0xcc}, - {0xb8, 0x0d, 0x70, 0xcc}, - {0xb6, 0x13, 0x13, 0xcc}, - {0x2f, 0x00, 0xC0, 0xbb}, - {0xb8, 0xa0, 0x12, 0xcc}, - {}, -}; -static const u8 mi1310_soc_InitSXGA_JPG[][4] = { - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0xb3, 0x00, 0x24, 0xcc}, - {0xb3, 0x00, 0x25, 0xcc}, - {0xb3, 0x05, 0x00, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xdd, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x0d, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x04, 0xcc}, - {0xb3, 0x23, 0x00, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x04, 0xcc}, - {0xb3, 0x17, 0xff, 0xcc}, - {0xb8, 0x01, 0x7d, 0xcc}, - {0xb8, 0x81, 0x09, 0xcc}, - {0xb8, 0x27, 0x20, 0xcc}, - {0xb8, 0x26, 0x80, 0xcc}, - {0xb8, 0x06, 0x00, 0xcc}, - {0xb8, 0x07, 0x05, 0xcc}, - {0xb8, 0x08, 0x00, 0xcc}, - {0xb8, 0x09, 0x04, 0xcc}, - {0xb3, 0x00, 0x25, 0xcc}, - {0xb8, 0x00, 0x11, 0xcc}, - {0xbc, 0x00, 0x71, 0xcc}, - {0xb8, 0x81, 0x01, 0xcc}, - {0xb8, 0x2c, 0x5a, 0xcc}, - {0xb8, 0x2d, 0xff, 0xcc}, - {0xb8, 0x2e, 0xee, 0xcc}, - {0xb8, 0x2f, 0xfb, 0xcc}, - {0xb8, 0x30, 0x52, 0xcc}, - {0xb8, 0x31, 0xf8, 0xcc}, - {0xb8, 0x32, 0xf1, 0xcc}, - {0xb8, 0x33, 0xff, 0xcc}, - {0xb8, 0x34, 0x54, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x01, 0x00, 0xdd}, - {0x0d, 0x00, 0x09, 0xbb}, - {0x0d, 0x00, 0x08, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x00, 0x01, 0x00, 0xdd}, - {0x06, 0x00, 0x14, 0xbb}, - {0x3a, 0x10, 0x00, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0x9b, 0x10, 0x00, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x01, 0x00, 0xdd}, - {0x2b, 0x00, 0x28, 0xbb}, - {0x2c, 0x00, 0x30, 0xbb}, - {0x2d, 0x00, 0x30, 0xbb}, - {0x2e, 0x00, 0x28, 0xbb}, - {0x41, 0x00, 0xd7, 0xbb}, - {0x09, 0x02, 0x3a, 0xbb}, - {0x0c, 0x00, 0x00, 0xbb}, - {0x20, 0x00, 0x00, 0xbb}, - {0x05, 0x00, 0x8c, 0xbb}, - {0x06, 0x00, 0x32, 0xbb}, - {0x07, 0x00, 0xc6, 0xbb}, - {0x08, 0x00, 0x19, 0xbb}, - {0x24, 0x80, 0x6f, 0xbb}, - {0xc8, 0x00, 0x0f, 0xbb}, - {0x20, 0x00, 0x03, 0xbb}, - {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x05, 0xcc}, - {0xb6, 0x02, 0x00, 0xcc}, - {0xb6, 0x05, 0x04, 0xcc}, - {0xb6, 0x04, 0x00, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb6, 0x18, 0x0a, 0xcc}, - {0xb6, 0x17, 0x00, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, - {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, - {0xb3, 0x02, 0x02, 0xcc}, - {0xbf, 0xc0, 0x39, 0xcc}, - {0xbf, 0xc1, 0x04, 0xcc}, - {0xbf, 0xcc, 0x10, 0xcc}, - {0xb9, 0x12, 0x00, 0xcc}, - {0xb9, 0x13, 0x14, 0xcc}, - {0xb9, 0x14, 0x14, 0xcc}, - {0xb9, 0x15, 0x14, 0xcc}, - {0xb9, 0x16, 0x14, 0xcc}, - {0xb9, 0x18, 0x00, 0xcc}, - {0xb9, 0x19, 0x1e, 0xcc}, - {0xb9, 0x1a, 0x1e, 0xcc}, - {0xb9, 0x1b, 0x1e, 0xcc}, - {0xb9, 0x1c, 0x1e, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xb8, 0x8e, 0x00, 0xcc}, - {0xb8, 0x8f, 0xff, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb8, 0x0c, 0x20, 0xcc}, - {0xb8, 0x0d, 0x70, 0xcc}, - {0xb6, 0x13, 0x13, 0xcc}, - {0x2f, 0x00, 0xC0, 0xbb}, - {0xb8, 0xa0, 0x12, 0xcc}, - {} -}; - -static const __u8 mi1320_gamma[17] = { - 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, - 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff -}; -static const __u8 mi1320_matrix[9] = { - 0x54, 0xda, 0x06, 0xf1, 0x50, 0xf4, 0xf7, 0xea, 0x52 -}; -static const __u8 mi1320_initVGA_data[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, - {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, - {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, - {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, - {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, - {0xb3, 0x06, 0x00, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x03, 0xcc}, {0xb3, 0x23, 0xc0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x04, 0xcc}, {0xb3, 0x17, 0xff, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, {0xbc, 0x00, 0xd0, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x00, 0xbb}, - {0x0d, 0x00, 0x09, 0xbb}, {0x00, 0x01, 0x00, 0xdd}, - {0x0d, 0x00, 0x08, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, - {0xa1, 0x05, 0x00, 0xbb}, {0xa4, 0x03, 0xc0, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, - {0xc8, 0x9f, 0x0b, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, - {0xf0, 0x00, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, - {0x20, 0x01, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, - {0xf0, 0x00, 0x01, 0xbb}, {0x9d, 0x3c, 0xa0, 0xbb}, - {0x47, 0x30, 0x30, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, - {0x0a, 0x80, 0x11, 0xbb}, {0x35, 0x00, 0x22, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x9d, 0xc5, 0x05, 0xbb}, - {0xdc, 0x0f, 0xfc, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, - {0x06, 0x74, 0x0e, 0xbb}, {0x80, 0x00, 0x06, 0xbb}, - {0x81, 0x04, 0x00, 0xbb}, {0x82, 0x01, 0x02, 0xbb}, - {0x83, 0x03, 0x02, 0xbb}, {0x84, 0x05, 0x00, 0xbb}, - {0x85, 0x01, 0x00, 0xbb}, {0x86, 0x03, 0x02, 0xbb}, - {0x87, 0x05, 0x00, 0xbb}, {0x88, 0x01, 0x00, 0xbb}, - {0x89, 0x02, 0x02, 0xbb}, {0x8a, 0xfd, 0x04, 0xbb}, - {0x8b, 0xfc, 0xfd, 0xbb}, {0x8c, 0xff, 0xfd, 0xbb}, - {0x8d, 0x00, 0x00, 0xbb}, {0x8e, 0xfe, 0x05, 0xbb}, - {0x8f, 0xfc, 0xfd, 0xbb}, {0x90, 0xfe, 0xfd, 0xbb}, - {0x91, 0x00, 0x00, 0xbb}, {0x92, 0xfe, 0x03, 0xbb}, - {0x93, 0xfd, 0xfe, 0xbb}, {0x94, 0xff, 0xfd, 0xbb}, - {0x95, 0x00, 0x00, 0xbb}, {0xb6, 0x07, 0x05, 0xbb}, - {0xb7, 0x13, 0x06, 0xbb}, {0xb8, 0x08, 0x06, 0xbb}, - {0xb9, 0x14, 0x08, 0xbb}, {0xba, 0x06, 0x05, 0xbb}, - {0xbb, 0x13, 0x06, 0xbb}, {0xbc, 0x03, 0x01, 0xbb}, - {0xbd, 0x03, 0x04, 0xbb}, {0xbe, 0x00, 0x02, 0xbb}, - {0xbf, 0x03, 0x01, 0xbb}, {0xc0, 0x02, 0x04, 0xbb}, - {0xc1, 0x00, 0x04, 0xbb}, {0xc2, 0x02, 0x01, 0xbb}, - {0xc3, 0x01, 0x03, 0xbb}, {0xc4, 0x00, 0x04, 0xbb}, - {0xf0, 0x00, 0x00, 0xbb}, {0x05, 0x01, 0x13, 0xbb}, - {0x06, 0x00, 0x11, 0xbb}, {0x07, 0x00, 0x85, 0xbb}, - {0x08, 0x00, 0x27, 0xbb}, {0x20, 0x01, 0x03, 0xbb}, - {0x21, 0x80, 0x00, 0xbb}, {0x22, 0x0d, 0x0f, 0xbb}, - {0x24, 0x80, 0x00, 0xbb}, {0x59, 0x00, 0xff, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x39, 0x03, 0x0d, 0xbb}, - {0x3a, 0x06, 0x1b, 0xbb}, {0x3b, 0x00, 0x95, 0xbb}, - {0x3c, 0x04, 0xdb, 0xbb}, {0x57, 0x02, 0x00, 0xbb}, - {0x58, 0x02, 0x66, 0xbb}, {0x59, 0x00, 0xff, 0xbb}, - {0x5a, 0x01, 0x33, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb}, - {0x5d, 0x16, 0x11, 0xbb}, {0x64, 0x5e, 0x1c, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb}, - {0x5b, 0x00, 0x01, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, - {0x36, 0x68, 0x10, 0xbb}, {0x00, 0x00, 0x30, 0xdd}, - {0x37, 0x82, 0x00, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc}, - {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc}, - {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x05, 0xcc}, {0xb6, 0x02, 0x00, 0xcc}, - {0xb6, 0x05, 0x04, 0xcc}, {0xb6, 0x04, 0x00, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x29, 0xcc}, - {0xb6, 0x18, 0x0a, 0xcc}, {0xb6, 0x17, 0x00, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x26, 0xcc}, - {0xbf, 0xc1, 0x02, 0xcc}, {0xbf, 0xcc, 0x04, 0xcc}, - {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, - {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, - {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, - {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, - {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, - {} -}; -static const __u8 mi1320_initQVGA_data[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, - {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, - {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, - {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, - {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, {0xb3, 0x23, 0xe0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x00, 0x65, 0xcc}, {0xb8, 0x00, 0x00, 0xcc}, - {0xbc, 0x00, 0xd0, 0xcc}, {0xbc, 0x01, 0x01, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, {0x0d, 0x00, 0x09, 0xbb}, - {0x00, 0x01, 0x00, 0xdd}, {0x0d, 0x00, 0x08, 0xbb}, - {0xf0, 0x00, 0x00, 0xbb}, {0x02, 0x00, 0x64, 0xbb}, - {0x05, 0x01, 0x78, 0xbb}, {0x06, 0x00, 0x11, 0xbb}, - {0x07, 0x01, 0x42, 0xbb}, {0x08, 0x00, 0x11, 0xbb}, - {0x20, 0x01, 0x00, 0xbb}, {0x21, 0x80, 0x00, 0xbb}, - {0x22, 0x0d, 0x0f, 0xbb}, {0x24, 0x80, 0x00, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, - {0x9d, 0x3c, 0xa0, 0xbb}, {0x47, 0x30, 0x30, 0xbb}, - {0xf0, 0x00, 0x00, 0xbb}, {0x0a, 0x80, 0x11, 0xbb}, - {0x35, 0x00, 0x22, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, - {0x9d, 0xc5, 0x05, 0xbb}, {0xdc, 0x0f, 0xfc, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0x74, 0x0e, 0xbb}, - {0x80, 0x00, 0x06, 0xbb}, {0x81, 0x04, 0x00, 0xbb}, - {0x82, 0x01, 0x02, 0xbb}, {0x83, 0x03, 0x02, 0xbb}, - {0x84, 0x05, 0x00, 0xbb}, {0x85, 0x01, 0x00, 0xbb}, - {0x86, 0x03, 0x02, 0xbb}, {0x87, 0x05, 0x00, 0xbb}, - {0x88, 0x01, 0x00, 0xbb}, {0x89, 0x02, 0x02, 0xbb}, - {0x8a, 0xfd, 0x04, 0xbb}, {0x8b, 0xfc, 0xfd, 0xbb}, - {0x8c, 0xff, 0xfd, 0xbb}, {0x8d, 0x00, 0x00, 0xbb}, - {0x8e, 0xfe, 0x05, 0xbb}, {0x8f, 0xfc, 0xfd, 0xbb}, - {0x90, 0xfe, 0xfd, 0xbb}, {0x91, 0x00, 0x00, 0xbb}, - {0x92, 0xfe, 0x03, 0xbb}, {0x93, 0xfd, 0xfe, 0xbb}, - {0x94, 0xff, 0xfd, 0xbb}, {0x95, 0x00, 0x00, 0xbb}, - {0xb6, 0x07, 0x05, 0xbb}, {0xb7, 0x13, 0x06, 0xbb}, - {0xb8, 0x08, 0x06, 0xbb}, {0xb9, 0x14, 0x08, 0xbb}, - {0xba, 0x06, 0x05, 0xbb}, {0xbb, 0x13, 0x06, 0xbb}, - {0xbc, 0x03, 0x01, 0xbb}, {0xbd, 0x03, 0x04, 0xbb}, - {0xbe, 0x00, 0x02, 0xbb}, {0xbf, 0x03, 0x01, 0xbb}, - {0xc0, 0x02, 0x04, 0xbb}, {0xc1, 0x00, 0x04, 0xbb}, - {0xc2, 0x02, 0x01, 0xbb}, {0xc3, 0x01, 0x03, 0xbb}, - {0xc4, 0x00, 0x04, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, - {0xc8, 0x00, 0x00, 0xbb}, {0x2e, 0x00, 0x00, 0xbb}, - {0x2e, 0x0c, 0x5b, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb}, - {0x39, 0x03, 0xca, 0xbb}, {0x3a, 0x06, 0x80, 0xbb}, - {0x3b, 0x01, 0x52, 0xbb}, {0x3c, 0x05, 0x40, 0xbb}, - {0x57, 0x01, 0x9c, 0xbb}, {0x58, 0x01, 0xee, 0xbb}, - {0x59, 0x00, 0xf0, 0xbb}, {0x5a, 0x01, 0x20, 0xbb}, - {0x5c, 0x1d, 0x17, 0xbb}, {0x5d, 0x22, 0x1c, 0xbb}, - {0x64, 0x1e, 0x1c, 0xbb}, {0x5b, 0x00, 0x01, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x68, 0x10, 0xbb}, - {0x00, 0x00, 0x30, 0xdd}, {0x37, 0x81, 0x00, 0xbb}, - {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, - {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, - {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, - {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, - {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, - {0xbf, 0xc0, 0x26, 0xcc}, {0xbf, 0xc1, 0x02, 0xcc}, - {0xbf, 0xcc, 0x04, 0xcc}, {0xb3, 0x5c, 0x01, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {} -}; - -static const u8 mi1320_soc_InitVGA[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0x00, 0x00, 0x30, 0xdd}, - {0xb3, 0x00, 0x64, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xc8, 0xcc}, - {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb8, 0x00, 0x00, 0xcc}, - {0xbc, 0x00, 0x71, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0xc8, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x30, 0xdd}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0x07, 0x00, 0xe0, 0xbb}, - {0x08, 0x00, 0x0b, 0xbb}, - {0x21, 0x00, 0x0c, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, - {0xbf, 0xc0, 0x26, 0xcc}, - {0xbf, 0xc1, 0x02, 0xcc}, - {0xbf, 0xcc, 0x04, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x05, 0x01, 0x78, 0xbb}, - {0x06, 0x00, 0x11, 0xbb}, - {0x07, 0x01, 0x42, 0xbb}, - {0x08, 0x00, 0x11, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, - {0x21, 0x80, 0x00, 0xbb}, - {0x22, 0x0d, 0x0f, 0xbb}, - {0x24, 0x80, 0x00, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x39, 0x03, 0xca, 0xbb}, - {0x3a, 0x06, 0x80, 0xbb}, - {0x3b, 0x01, 0x52, 0xbb}, - {0x3c, 0x05, 0x40, 0xbb}, - {0x57, 0x01, 0x9c, 0xbb}, - {0x58, 0x01, 0xee, 0xbb}, - {0x59, 0x00, 0xf0, 0xbb}, - {0x5a, 0x01, 0x20, 0xbb}, - {0x5c, 0x1d, 0x17, 0xbb}, - {0x5d, 0x22, 0x1c, 0xbb}, - {0x64, 0x1e, 0x1c, 0xbb}, - {0x5b, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x22, 0xa0, 0x78, 0xbb}, - {0x23, 0xa0, 0x78, 0xbb}, - {0x24, 0x7f, 0x00, 0xbb}, - {0x28, 0xea, 0x02, 0xbb}, - {0x29, 0x86, 0x7a, 0xbb}, - {0x5e, 0x52, 0x4c, 0xbb}, - {0x5f, 0x20, 0x24, 0xbb}, - {0x60, 0x00, 0x02, 0xbb}, - {0x02, 0x00, 0xee, 0xbb}, - {0x03, 0x39, 0x23, 0xbb}, - {0x04, 0x07, 0x24, 0xbb}, - {0x09, 0x00, 0xc0, 0xbb}, - {0x0a, 0x00, 0x79, 0xbb}, - {0x0b, 0x00, 0x04, 0xbb}, - {0x0c, 0x00, 0x5c, 0xbb}, - {0x0d, 0x00, 0xd9, 0xbb}, - {0x0e, 0x00, 0x53, 0xbb}, - {0x0f, 0x00, 0x21, 0xbb}, - {0x10, 0x00, 0xa4, 0xbb}, - {0x11, 0x00, 0xe5, 0xbb}, - {0x15, 0x00, 0x00, 0xbb}, - {0x16, 0x00, 0x00, 0xbb}, - {0x17, 0x00, 0x00, 0xbb}, - {0x18, 0x00, 0x00, 0xbb}, - {0x19, 0x00, 0x00, 0xbb}, - {0x1a, 0x00, 0x00, 0xbb}, - {0x1b, 0x00, 0x00, 0xbb}, - {0x1c, 0x00, 0x00, 0xbb}, - {0x1d, 0x00, 0x00, 0xbb}, - {0x1e, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x06, 0xe0, 0x0e, 0xbb}, - {0x06, 0x60, 0x0e, 0xbb}, - {0xb3, 0x5c, 0x01, 0xcc}, - {} -}; -static const u8 mi1320_soc_InitVGA_JPG[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0x00, 0x00, 0x30, 0xdd}, - {0xb3, 0x00, 0x64, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xc8, 0xcc}, - {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb8, 0x00, 0x00, 0xcc}, - {0xbc, 0x00, 0x71, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0xc8, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x30, 0xdd}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0x07, 0x00, 0xe0, 0xbb}, - {0x08, 0x00, 0x0b, 0xbb}, - {0x21, 0x00, 0x0c, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, - {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x02, 0xcc}, - {0xb6, 0x02, 0x80, 0xcc}, - {0xb6, 0x05, 0x01, 0xcc}, - {0xb6, 0x04, 0xe0, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb6, 0x13, 0x05, 0xcc}, - {0xb6, 0x18, 0x02, 0xcc}, - {0xb6, 0x17, 0x58, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, - {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, - {0xbf, 0xc0, 0x39, 0xcc}, - {0xbf, 0xc1, 0x04, 0xcc}, - {0xbf, 0xcc, 0x00, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x05, 0x01, 0x78, 0xbb}, - {0x06, 0x00, 0x11, 0xbb}, - {0x07, 0x01, 0x42, 0xbb}, - {0x08, 0x00, 0x11, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, - {0x21, 0x80, 0x00, 0xbb}, - {0x22, 0x0d, 0x0f, 0xbb}, - {0x24, 0x80, 0x00, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x39, 0x03, 0xca, 0xbb}, - {0x3a, 0x06, 0x80, 0xbb}, - {0x3b, 0x01, 0x52, 0xbb}, - {0x3c, 0x05, 0x40, 0xbb}, - {0x57, 0x01, 0x9c, 0xbb}, - {0x58, 0x01, 0xee, 0xbb}, - {0x59, 0x00, 0xf0, 0xbb}, - {0x5a, 0x01, 0x20, 0xbb}, - {0x5c, 0x1d, 0x17, 0xbb}, - {0x5d, 0x22, 0x1c, 0xbb}, - {0x64, 0x1e, 0x1c, 0xbb}, - {0x5b, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x22, 0xa0, 0x78, 0xbb}, - {0x23, 0xa0, 0x78, 0xbb}, - {0x24, 0x7f, 0x00, 0xbb}, - {0x28, 0xea, 0x02, 0xbb}, - {0x29, 0x86, 0x7a, 0xbb}, - {0x5e, 0x52, 0x4c, 0xbb}, - {0x5f, 0x20, 0x24, 0xbb}, - {0x60, 0x00, 0x02, 0xbb}, - {0x02, 0x00, 0xee, 0xbb}, - {0x03, 0x39, 0x23, 0xbb}, - {0x04, 0x07, 0x24, 0xbb}, - {0x09, 0x00, 0xc0, 0xbb}, - {0x0a, 0x00, 0x79, 0xbb}, - {0x0b, 0x00, 0x04, 0xbb}, - {0x0c, 0x00, 0x5c, 0xbb}, - {0x0d, 0x00, 0xd9, 0xbb}, - {0x0e, 0x00, 0x53, 0xbb}, - {0x0f, 0x00, 0x21, 0xbb}, - {0x10, 0x00, 0xa4, 0xbb}, - {0x11, 0x00, 0xe5, 0xbb}, - {0x15, 0x00, 0x00, 0xbb}, - {0x16, 0x00, 0x00, 0xbb}, - {0x17, 0x00, 0x00, 0xbb}, - {0x18, 0x00, 0x00, 0xbb}, - {0x19, 0x00, 0x00, 0xbb}, - {0x1a, 0x00, 0x00, 0xbb}, - {0x1b, 0x00, 0x00, 0xbb}, - {0x1c, 0x00, 0x00, 0xbb}, - {0x1d, 0x00, 0x00, 0xbb}, - {0x1e, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x06, 0xe0, 0x0e, 0xbb}, - {0x06, 0x60, 0x0e, 0xbb}, - {0xb3, 0x5c, 0x01, 0xcc}, - {} -}; -static const u8 mi1320_soc_InitQVGA[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0x00, 0x00, 0x30, 0xdd}, - {0xb3, 0x00, 0x64, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xc8, 0xcc}, - {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb8, 0x00, 0x00, 0xcc}, - {0xbc, 0x00, 0xd1, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0xc8, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x30, 0xdd}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0x07, 0x00, 0xe0, 0xbb}, - {0x08, 0x00, 0x0b, 0xbb}, - {0x21, 0x00, 0x0c, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, - {0xbf, 0xc0, 0x26, 0xcc}, - {0xbf, 0xc1, 0x02, 0xcc}, - {0xbf, 0xcc, 0x04, 0xcc}, - {0xbc, 0x02, 0x18, 0xcc}, - {0xbc, 0x03, 0x50, 0xcc}, - {0xbc, 0x04, 0x18, 0xcc}, - {0xbc, 0x05, 0x00, 0xcc}, - {0xbc, 0x06, 0x00, 0xcc}, - {0xbc, 0x08, 0x30, 0xcc}, - {0xbc, 0x09, 0x40, 0xcc}, - {0xbc, 0x0a, 0x10, 0xcc}, - {0xbc, 0x0b, 0x00, 0xcc}, - {0xbc, 0x0c, 0x00, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x05, 0x01, 0x78, 0xbb}, - {0x06, 0x00, 0x11, 0xbb}, - {0x07, 0x01, 0x42, 0xbb}, - {0x08, 0x00, 0x11, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, - {0x21, 0x80, 0x00, 0xbb}, - {0x22, 0x0d, 0x0f, 0xbb}, - {0x24, 0x80, 0x00, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x39, 0x03, 0xca, 0xbb}, - {0x3a, 0x06, 0x80, 0xbb}, - {0x3b, 0x01, 0x52, 0xbb}, - {0x3c, 0x05, 0x40, 0xbb}, - {0x57, 0x01, 0x9c, 0xbb}, - {0x58, 0x01, 0xee, 0xbb}, - {0x59, 0x00, 0xf0, 0xbb}, - {0x5a, 0x01, 0x20, 0xbb}, - {0x5c, 0x1d, 0x17, 0xbb}, - {0x5d, 0x22, 0x1c, 0xbb}, - {0x64, 0x1e, 0x1c, 0xbb}, - {0x5b, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x22, 0xa0, 0x78, 0xbb}, - {0x23, 0xa0, 0x78, 0xbb}, - {0x24, 0x7f, 0x00, 0xbb}, - {0x28, 0xea, 0x02, 0xbb}, - {0x29, 0x86, 0x7a, 0xbb}, - {0x5e, 0x52, 0x4c, 0xbb}, - {0x5f, 0x20, 0x24, 0xbb}, - {0x60, 0x00, 0x02, 0xbb}, - {0x02, 0x00, 0xee, 0xbb}, - {0x03, 0x39, 0x23, 0xbb}, - {0x04, 0x07, 0x24, 0xbb}, - {0x09, 0x00, 0xc0, 0xbb}, - {0x0a, 0x00, 0x79, 0xbb}, - {0x0b, 0x00, 0x04, 0xbb}, - {0x0c, 0x00, 0x5c, 0xbb}, - {0x0d, 0x00, 0xd9, 0xbb}, - {0x0e, 0x00, 0x53, 0xbb}, - {0x0f, 0x00, 0x21, 0xbb}, - {0x10, 0x00, 0xa4, 0xbb}, - {0x11, 0x00, 0xe5, 0xbb}, - {0x15, 0x00, 0x00, 0xbb}, - {0x16, 0x00, 0x00, 0xbb}, - {0x17, 0x00, 0x00, 0xbb}, - {0x18, 0x00, 0x00, 0xbb}, - {0x19, 0x00, 0x00, 0xbb}, - {0x1a, 0x00, 0x00, 0xbb}, - {0x1b, 0x00, 0x00, 0xbb}, - {0x1c, 0x00, 0x00, 0xbb}, - {0x1d, 0x00, 0x00, 0xbb}, - {0x1e, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x06, 0xe0, 0x0e, 0xbb}, - {0x06, 0x60, 0x0e, 0xbb}, - {0xb3, 0x5c, 0x01, 0xcc}, - {} -}; -static const u8 mi1320_soc_InitQVGA_JPG[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0x00, 0x00, 0x30, 0xdd}, - {0xb3, 0x00, 0x64, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xc8, 0xcc}, - {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x01, 0xcc}, - {0xb3, 0x23, 0xe0, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x02, 0xcc}, - {0xb3, 0x17, 0x7f, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb8, 0x00, 0x00, 0xcc}, - {0xbc, 0x00, 0xd1, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0xc8, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x30, 0xdd}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x10, 0xdd}, - {0x07, 0x00, 0xe0, 0xbb}, - {0x08, 0x00, 0x0b, 0xbb}, - {0x21, 0x00, 0x0c, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, - {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x01, 0xcc}, - {0xb6, 0x02, 0x40, 0xcc}, - {0xb6, 0x05, 0x00, 0xcc}, - {0xb6, 0x04, 0xf0, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb6, 0x13, 0x05, 0xcc}, - {0xb6, 0x18, 0x00, 0xcc}, - {0xb6, 0x17, 0x96, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, - {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, - {0xbf, 0xc0, 0x39, 0xcc}, - {0xbf, 0xc1, 0x04, 0xcc}, - {0xbf, 0xcc, 0x00, 0xcc}, - {0xbc, 0x02, 0x18, 0xcc}, - {0xbc, 0x03, 0x50, 0xcc}, - {0xbc, 0x04, 0x18, 0xcc}, - {0xbc, 0x05, 0x00, 0xcc}, - {0xbc, 0x06, 0x00, 0xcc}, - {0xbc, 0x08, 0x30, 0xcc}, - {0xbc, 0x09, 0x40, 0xcc}, - {0xbc, 0x0a, 0x10, 0xcc}, - {0xbc, 0x0b, 0x00, 0xcc}, - {0xbc, 0x0c, 0x00, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x05, 0x01, 0x78, 0xbb}, - {0x06, 0x00, 0x11, 0xbb}, - {0x07, 0x01, 0x42, 0xbb}, - {0x08, 0x00, 0x11, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, - {0x21, 0x80, 0x00, 0xbb}, - {0x22, 0x0d, 0x0f, 0xbb}, - {0x24, 0x80, 0x00, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x39, 0x03, 0xca, 0xbb}, - {0x3a, 0x06, 0x80, 0xbb}, - {0x3b, 0x01, 0x52, 0xbb}, - {0x3c, 0x05, 0x40, 0xbb}, - {0x57, 0x01, 0x9c, 0xbb}, - {0x58, 0x01, 0xee, 0xbb}, - {0x59, 0x00, 0xf0, 0xbb}, - {0x5a, 0x01, 0x20, 0xbb}, - {0x5c, 0x1d, 0x17, 0xbb}, - {0x5d, 0x22, 0x1c, 0xbb}, - {0x64, 0x1e, 0x1c, 0xbb}, - {0x5b, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x22, 0xa0, 0x78, 0xbb}, - {0x23, 0xa0, 0x78, 0xbb}, - {0x24, 0x7f, 0x00, 0xbb}, - {0x28, 0xea, 0x02, 0xbb}, - {0x29, 0x86, 0x7a, 0xbb}, - {0x5e, 0x52, 0x4c, 0xbb}, - {0x5f, 0x20, 0x24, 0xbb}, - {0x60, 0x00, 0x02, 0xbb}, - {0x02, 0x00, 0xee, 0xbb}, - {0x03, 0x39, 0x23, 0xbb}, - {0x04, 0x07, 0x24, 0xbb}, - {0x09, 0x00, 0xc0, 0xbb}, - {0x0a, 0x00, 0x79, 0xbb}, - {0x0b, 0x00, 0x04, 0xbb}, - {0x0c, 0x00, 0x5c, 0xbb}, - {0x0d, 0x00, 0xd9, 0xbb}, - {0x0e, 0x00, 0x53, 0xbb}, - {0x0f, 0x00, 0x21, 0xbb}, - {0x10, 0x00, 0xa4, 0xbb}, - {0x11, 0x00, 0xe5, 0xbb}, - {0x15, 0x00, 0x00, 0xbb}, - {0x16, 0x00, 0x00, 0xbb}, - {0x17, 0x00, 0x00, 0xbb}, - {0x18, 0x00, 0x00, 0xbb}, - {0x19, 0x00, 0x00, 0xbb}, - {0x1a, 0x00, 0x00, 0xbb}, - {0x1b, 0x00, 0x00, 0xbb}, - {0x1c, 0x00, 0x00, 0xbb}, - {0x1d, 0x00, 0x00, 0xbb}, - {0x1e, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x06, 0xe0, 0x0e, 0xbb}, - {0x06, 0x60, 0x0e, 0xbb}, - {0xb3, 0x5c, 0x01, 0xcc}, - {} -}; -static const u8 mi1320_soc_InitSXGA_JPG[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, - {0xb0, 0x03, 0x19, 0xcc}, - {0xb0, 0x04, 0x02, 0xcc}, - {0x00, 0x00, 0x33, 0xdd}, - {0xb3, 0x00, 0x64, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb3, 0x05, 0x00, 0xcc}, - {0xb3, 0x06, 0x00, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xc8, 0xcc}, - {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x04, 0xcc}, - {0xb3, 0x23, 0x00, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x04, 0xcc}, - {0xb3, 0x17, 0xff, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xbc, 0x00, 0x71, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x00, 0x00, 0x30, 0xdd}, - {0xc8, 0x9f, 0x0b, 0xbb}, - {0x00, 0x00, 0x20, 0xdd}, - {0x5b, 0x00, 0x01, 0xbb}, - {0x00, 0x00, 0x20, 0xdd}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x30, 0xdd}, - {0x20, 0x01, 0x03, 0xbb}, - {0x00, 0x00, 0x20, 0xdd}, - {0xb6, 0x00, 0x00, 0xcc}, - {0xb6, 0x03, 0x05, 0xcc}, - {0xb6, 0x02, 0x00, 0xcc}, - {0xb6, 0x05, 0x04, 0xcc}, - {0xb6, 0x04, 0x00, 0xcc}, - {0xb6, 0x12, 0xf8, 0xcc}, - {0xb6, 0x13, 0x29, 0xcc}, - {0xb6, 0x18, 0x0a, 0xcc}, - {0xb6, 0x17, 0x00, 0xcc}, - {0xb6, 0x16, 0x00, 0xcc}, - {0xb6, 0x22, 0x12, 0xcc}, - {0xb6, 0x23, 0x0b, 0xcc}, - {0xbf, 0xc0, 0x39, 0xcc}, - {0xbf, 0xc1, 0x04, 0xcc}, - {0xbf, 0xcc, 0x00, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x05, 0x01, 0x78, 0xbb}, - {0x06, 0x00, 0x11, 0xbb}, - {0x07, 0x01, 0x42, 0xbb}, - {0x08, 0x00, 0x11, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, - {0x21, 0x80, 0x00, 0xbb}, - {0x22, 0x0d, 0x0f, 0xbb}, - {0x24, 0x80, 0x00, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x39, 0x03, 0xca, 0xbb}, - {0x3a, 0x06, 0x80, 0xbb}, - {0x3b, 0x01, 0x52, 0xbb}, - {0x3c, 0x05, 0x40, 0xbb}, - {0x57, 0x01, 0x9c, 0xbb}, - {0x58, 0x01, 0xee, 0xbb}, - {0x59, 0x00, 0xf0, 0xbb}, - {0x5a, 0x01, 0x20, 0xbb}, - {0x5c, 0x1d, 0x17, 0xbb}, - {0x5d, 0x22, 0x1c, 0xbb}, - {0x64, 0x1e, 0x1c, 0xbb}, - {0x5b, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x22, 0xa0, 0x78, 0xbb}, - {0x23, 0xa0, 0x78, 0xbb}, - {0x24, 0x7f, 0x00, 0xbb}, - {0x28, 0xea, 0x02, 0xbb}, - {0x29, 0x86, 0x7a, 0xbb}, - {0x5e, 0x52, 0x4c, 0xbb}, - {0x5f, 0x20, 0x24, 0xbb}, - {0x60, 0x00, 0x02, 0xbb}, - {0x02, 0x00, 0xee, 0xbb}, - {0x03, 0x39, 0x23, 0xbb}, - {0x04, 0x07, 0x24, 0xbb}, - {0x09, 0x00, 0xc0, 0xbb}, - {0x0a, 0x00, 0x79, 0xbb}, - {0x0b, 0x00, 0x04, 0xbb}, - {0x0c, 0x00, 0x5c, 0xbb}, - {0x0d, 0x00, 0xd9, 0xbb}, - {0x0e, 0x00, 0x53, 0xbb}, - {0x0f, 0x00, 0x21, 0xbb}, - {0x10, 0x00, 0xa4, 0xbb}, - {0x11, 0x00, 0xe5, 0xbb}, - {0x15, 0x00, 0x00, 0xbb}, - {0x16, 0x00, 0x00, 0xbb}, - {0x17, 0x00, 0x00, 0xbb}, - {0x18, 0x00, 0x00, 0xbb}, - {0x19, 0x00, 0x00, 0xbb}, - {0x1a, 0x00, 0x00, 0xbb}, - {0x1b, 0x00, 0x00, 0xbb}, - {0x1c, 0x00, 0x00, 0xbb}, - {0x1d, 0x00, 0x00, 0xbb}, - {0x1e, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x06, 0xe0, 0x0e, 0xbb}, - {0x06, 0x60, 0x0e, 0xbb}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x05, 0x01, 0x13, 0xbb}, - {0x06, 0x00, 0x11, 0xbb}, - {0x07, 0x00, 0x85, 0xbb}, - {0x08, 0x00, 0x27, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, - {0x21, 0x80, 0x00, 0xbb}, - {0x22, 0x0d, 0x0f, 0xbb}, - {0x24, 0x80, 0x00, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x39, 0x03, 0x0d, 0xbb}, - {0x3a, 0x06, 0x1b, 0xbb}, - {0x3b, 0x00, 0x95, 0xbb}, - {0x3c, 0x04, 0xdb, 0xbb}, - {0x57, 0x02, 0x00, 0xbb}, - {0x58, 0x02, 0x66, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, - {0x5a, 0x01, 0x33, 0xbb}, - {0x5c, 0x12, 0x0d, 0xbb}, - {0x5d, 0x16, 0x11, 0xbb}, - {0x64, 0x5e, 0x1c, 0xbb}, - {0x2f, 0x90, 0x00, 0xbb}, - {} -}; -static const u8 mi1320_soc_InitSXGA[][4] = { - {0xb3, 0x01, 0x01, 0xcc}, - {0xb0, 0x03, 0x19, 0xcc}, - {0x00, 0x00, 0x30, 0xdd}, - {0xb3, 0x00, 0x64, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xb3, 0x05, 0x01, 0xcc}, - {0xb3, 0x06, 0x01, 0xcc}, - {0xb3, 0x08, 0x01, 0xcc}, - {0xb3, 0x09, 0x0c, 0xcc}, - {0xb3, 0x34, 0x02, 0xcc}, - {0xb3, 0x35, 0xc8, 0xcc}, - {0xb3, 0x02, 0x00, 0xcc}, - {0xb3, 0x03, 0x0a, 0xcc}, - {0xb3, 0x04, 0x05, 0xcc}, - {0xb3, 0x20, 0x00, 0xcc}, - {0xb3, 0x21, 0x00, 0xcc}, - {0xb3, 0x22, 0x04, 0xcc}, - {0xb3, 0x23, 0x00, 0xcc}, - {0xb3, 0x14, 0x00, 0xcc}, - {0xb3, 0x15, 0x00, 0xcc}, - {0xb3, 0x16, 0x04, 0xcc}, - {0xb3, 0x17, 0xff, 0xcc}, - {0xb3, 0x00, 0x67, 0xcc}, - {0xbc, 0x00, 0x71, 0xcc}, - {0xbc, 0x01, 0x01, 0xcc}, - {0xb3, 0x5c, 0x01, 0xcc}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x00, 0x00, 0x30, 0xdd}, - {0xc8, 0x9f, 0x0b, 0xbb}, - {0x00, 0x00, 0x20, 0xdd}, - {0x5b, 0x00, 0x01, 0xbb}, - {0x00, 0x00, 0x20, 0xdd}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x00, 0x00, 0x30, 0xdd}, - {0x20, 0x01, 0x03, 0xbb}, - {0x00, 0x00, 0x20, 0xdd}, - {0xbf, 0xc0, 0x26, 0xcc}, - {0xbf, 0xc1, 0x02, 0xcc}, - {0xbf, 0xcc, 0x04, 0xcc}, - {0xb3, 0x01, 0x41, 0xcc}, - {0xf0, 0x00, 0x00, 0xbb}, - {0x05, 0x01, 0x78, 0xbb}, - {0x06, 0x00, 0x11, 0xbb}, - {0x07, 0x01, 0x42, 0xbb}, - {0x08, 0x00, 0x11, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, - {0x21, 0x80, 0x00, 0xbb}, - {0x22, 0x0d, 0x0f, 0xbb}, - {0x24, 0x80, 0x00, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, + {0xb3, 0x5c, 0x01, 0xcc}, + {0xf0, 0x00, 0x01, 0xbb}, + {0x80, 0x00, 0x03, 0xbb}, + {0x81, 0xc7, 0x14, 0xbb}, + {0x82, 0xeb, 0xe8, 0xbb}, + {0x83, 0xfe, 0xf4, 0xbb}, + {0x84, 0xcd, 0x10, 0xbb}, + {0x85, 0xf3, 0xee, 0xbb}, + {0x86, 0xff, 0xf1, 0xbb}, + {0x87, 0xcd, 0x10, 0xbb}, + {0x88, 0xf3, 0xee, 0xbb}, + {0x89, 0x01, 0xf1, 0xbb}, + {0x8a, 0xe5, 0x17, 0xbb}, + {0x8b, 0xe8, 0xe2, 0xbb}, + {0x8c, 0xf7, 0xed, 0xbb}, + {0x8d, 0x00, 0xff, 0xbb}, + {0x8e, 0xec, 0x10, 0xbb}, + {0x8f, 0xf0, 0xed, 0xbb}, + {0x90, 0xf9, 0xf2, 0xbb}, + {0x91, 0x00, 0x00, 0xbb}, + {0x92, 0xe9, 0x0d, 0xbb}, + {0x93, 0xf4, 0xf2, 0xbb}, + {0x94, 0xfb, 0xf5, 0xbb}, + {0x95, 0x00, 0xff, 0xbb}, + {0xb6, 0x0f, 0x08, 0xbb}, + {0xb7, 0x3d, 0x16, 0xbb}, + {0xb8, 0x0c, 0x04, 0xbb}, + {0xb9, 0x1c, 0x07, 0xbb}, + {0xba, 0x0a, 0x03, 0xbb}, + {0xbb, 0x1b, 0x09, 0xbb}, + {0xbc, 0x17, 0x0d, 0xbb}, + {0xbd, 0x23, 0x1d, 0xbb}, + {0xbe, 0x00, 0x28, 0xbb}, + {0xbf, 0x11, 0x09, 0xbb}, + {0xc0, 0x16, 0x15, 0xbb}, + {0xc1, 0x00, 0x1b, 0xbb}, + {0xc2, 0x0e, 0x07, 0xbb}, + {0xc3, 0x14, 0x10, 0xbb}, + {0xc4, 0x00, 0x17, 0xbb}, + {0x06, 0x74, 0x8e, 0xbb}, + {0xf0, 0x00, 0x01, 0xbb}, + {0x06, 0xf4, 0x8e, 0xbb}, + {0x00, 0x00, 0x50, 0xdd}, + {0x06, 0x74, 0x8e, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, - {0x39, 0x03, 0xca, 0xbb}, - {0x3a, 0x06, 0x80, 0xbb}, - {0x3b, 0x01, 0x52, 0xbb}, - {0x3c, 0x05, 0x40, 0xbb}, - {0x57, 0x01, 0x9c, 0xbb}, - {0x58, 0x01, 0xee, 0xbb}, - {0x59, 0x00, 0xf0, 0xbb}, - {0x5a, 0x01, 0x20, 0xbb}, - {0x5c, 0x1d, 0x17, 0xbb}, - {0x5d, 0x22, 0x1c, 0xbb}, - {0x64, 0x1e, 0x1c, 0xbb}, - {0x5b, 0x00, 0x00, 0xbb}, + {0x24, 0x50, 0x20, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, - {0x22, 0xa0, 0x78, 0xbb}, - {0x23, 0xa0, 0x78, 0xbb}, - {0x24, 0x7f, 0x00, 0xbb}, - {0x28, 0xea, 0x02, 0xbb}, - {0x29, 0x86, 0x7a, 0xbb}, - {0x5e, 0x52, 0x4c, 0xbb}, - {0x5f, 0x20, 0x24, 0xbb}, - {0x60, 0x00, 0x02, 0xbb}, - {0x02, 0x00, 0xee, 0xbb}, - {0x03, 0x39, 0x23, 0xbb}, - {0x04, 0x07, 0x24, 0xbb}, - {0x09, 0x00, 0xc0, 0xbb}, - {0x0a, 0x00, 0x79, 0xbb}, - {0x0b, 0x00, 0x04, 0xbb}, - {0x0c, 0x00, 0x5c, 0xbb}, - {0x0d, 0x00, 0xd9, 0xbb}, - {0x0e, 0x00, 0x53, 0xbb}, - {0x0f, 0x00, 0x21, 0xbb}, - {0x10, 0x00, 0xa4, 0xbb}, - {0x11, 0x00, 0xe5, 0xbb}, - {0x15, 0x00, 0x00, 0xbb}, - {0x16, 0x00, 0x00, 0xbb}, - {0x17, 0x00, 0x00, 0xbb}, - {0x18, 0x00, 0x00, 0xbb}, - {0x19, 0x00, 0x00, 0xbb}, - {0x1a, 0x00, 0x00, 0xbb}, - {0x1b, 0x00, 0x00, 0xbb}, - {0x1c, 0x00, 0x00, 0xbb}, - {0x1d, 0x00, 0x00, 0xbb}, - {0x1e, 0x00, 0x00, 0xbb}, - {0xf0, 0x00, 0x01, 0xbb}, - {0x06, 0xe0, 0x0e, 0xbb}, - {0x06, 0x60, 0x0e, 0xbb}, - {0xb3, 0x5c, 0x01, 0xcc}, + {0x34, 0x0c, 0x50, 0xbb}, + {0xb3, 0x01, 0x41, 0xcc}, {0xf0, 0x00, 0x00, 0xbb}, - {0x05, 0x01, 0x13, 0xbb}, - {0x06, 0x00, 0x11, 0xbb}, - {0x07, 0x00, 0x85, 0xbb}, - {0x08, 0x00, 0x27, 0xbb}, - {0x20, 0x01, 0x03, 0xbb}, - {0x21, 0x80, 0x00, 0xbb}, - {0x22, 0x0d, 0x0f, 0xbb}, - {0x24, 0x80, 0x00, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, - {0xf0, 0x00, 0x02, 0xbb}, - {0x39, 0x03, 0x0d, 0xbb}, - {0x3a, 0x06, 0x1b, 0xbb}, - {0x3b, 0x00, 0x95, 0xbb}, - {0x3c, 0x04, 0xdb, 0xbb}, - {0x57, 0x02, 0x00, 0xbb}, - {0x58, 0x02, 0x66, 0xbb}, - {0x59, 0x00, 0xff, 0xbb}, - {0x5a, 0x01, 0x33, 0xbb}, - {0x5c, 0x12, 0x0d, 0xbb}, - {0x5d, 0x16, 0x11, 0xbb}, - {0x64, 0x5e, 0x1c, 0xbb}, + {0x03, 0x03, 0xc0, 0xbb}, + {}, +}; +static const __u8 mi1310_socinitQVGA_JPG[][4] = { + {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc}, + {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, + {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x00, 0xcc}, + {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, + {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc}, + {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc}, + {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, + {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x03, 0xcc}, + {0xb3, 0x23, 0xc0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc}, + {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x04, 0xcc}, + {0xb3, 0x17, 0xff, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, + {0xb8, 0x00, 0x00, 0xcc}, {0xbc, 0x00, 0xf0, 0xcc}, + {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb}, + {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb}, + {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, + {0x20, 0x03, 0x02, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, + {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb}, + {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb}, + {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb}, + {0xdf, 0xcd, 0xb1, 0xbb}, {0xe0, 0xff, 0xe7, 0xbb}, + {0x06, 0xf0, 0x0d, 0xbb}, {0x06, 0x70, 0x0e, 0xbb}, + {0x4c, 0x00, 0x01, 0xbb}, {0x4d, 0x00, 0x01, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x2e, 0x0c, 0x55, 0xbb}, + {0x21, 0xb6, 0x6e, 0xbb}, {0x36, 0x30, 0x10, 0xbb}, + {0x37, 0x00, 0xc1, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, + {0x07, 0x00, 0x84, 0xbb}, {0x08, 0x02, 0x4a, 0xbb}, + {0x05, 0x01, 0x10, 0xbb}, {0x06, 0x00, 0x39, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x58, 0x02, 0x67, 0xbb}, + {0x57, 0x02, 0x00, 0xbb}, {0x5a, 0x02, 0x67, 0xbb}, + {0x59, 0x02, 0x00, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb}, + {0x5d, 0x16, 0x11, 0xbb}, {0x39, 0x06, 0x18, 0xbb}, + {0x3a, 0x06, 0x18, 0xbb}, {0x3b, 0x06, 0x18, 0xbb}, + {0x3c, 0x06, 0x18, 0xbb}, {0x64, 0x7b, 0x5b, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x30, 0x10, 0xbb}, + {0x37, 0x00, 0xc0, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc}, + {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc}, + {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc}, + {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc}, + {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc}, + {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x25, 0xcc}, + {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc}, + {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, + {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, + {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc}, + {0xb3, 0x5c, 0x01, 0xcc}, {0xf0, 0x00, 0x01, 0xbb}, + {0x80, 0x00, 0x03, 0xbb}, {0x81, 0xc7, 0x14, 0xbb}, + {0x82, 0xeb, 0xe8, 0xbb}, {0x83, 0xfe, 0xf4, 0xbb}, + {0x84, 0xcd, 0x10, 0xbb}, {0x85, 0xf3, 0xee, 0xbb}, + {0x86, 0xff, 0xf1, 0xbb}, {0x87, 0xcd, 0x10, 0xbb}, + {0x88, 0xf3, 0xee, 0xbb}, {0x89, 0x01, 0xf1, 0xbb}, + {0x8a, 0xe5, 0x17, 0xbb}, {0x8b, 0xe8, 0xe2, 0xbb}, + {0x8c, 0xf7, 0xed, 0xbb}, {0x8d, 0x00, 0xff, 0xbb}, + {0x8e, 0xec, 0x10, 0xbb}, {0x8f, 0xf0, 0xed, 0xbb}, + {0x90, 0xf9, 0xf2, 0xbb}, {0x91, 0x00, 0x00, 0xbb}, + {0x92, 0xe9, 0x0d, 0xbb}, {0x93, 0xf4, 0xf2, 0xbb}, + {0x94, 0xfb, 0xf5, 0xbb}, {0x95, 0x00, 0xff, 0xbb}, + {0xb6, 0x0f, 0x08, 0xbb}, {0xb7, 0x3d, 0x16, 0xbb}, + {0xb8, 0x0c, 0x04, 0xbb}, {0xb9, 0x1c, 0x07, 0xbb}, + {0xba, 0x0a, 0x03, 0xbb}, {0xbb, 0x1b, 0x09, 0xbb}, + {0xbc, 0x17, 0x0d, 0xbb}, {0xbd, 0x23, 0x1d, 0xbb}, + {0xbe, 0x00, 0x28, 0xbb}, {0xbf, 0x11, 0x09, 0xbb}, + {0xc0, 0x16, 0x15, 0xbb}, {0xc1, 0x00, 0x1b, 0xbb}, + {0xc2, 0x0e, 0x07, 0xbb}, {0xc3, 0x14, 0x10, 0xbb}, + {0xc4, 0x00, 0x17, 0xbb}, {0x06, 0x74, 0x8e, 0xbb}, + {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0xf4, 0x8e, 0xbb}, + {0x00, 0x00, 0x50, 0xdd}, {0x06, 0x74, 0x8e, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x24, 0x50, 0x20, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x34, 0x0c, 0x50, 0xbb}, + {0xb3, 0x01, 0x41, 0xcc}, {0xf0, 0x00, 0x00, 0xbb}, + {0x03, 0x03, 0xc0, 0xbb}, + {}, +}; + +static const __u8 mi1320_gamma[17] = { + 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, + 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff +}; +static const __u8 mi1320_matrix[9] = { + 0x54, 0xda, 0x06, 0xf1, 0x50, 0xf4, 0xf7, 0xea, 0x52 +}; +static const __u8 mi1320_initVGA_data[][4] = { + {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, + {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, + {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, + {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, + {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, + {0xb3, 0x06, 0x00, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, + {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, + {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc}, + {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, + {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, + {0xb3, 0x22, 0x03, 0xcc}, {0xb3, 0x23, 0xc0, 0xcc}, + {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, + {0xb3, 0x16, 0x04, 0xcc}, {0xb3, 0x17, 0xff, 0xcc}, + {0xb3, 0x00, 0x67, 0xcc}, {0xbc, 0x00, 0xd0, 0xcc}, + {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x00, 0xbb}, + {0x0d, 0x00, 0x09, 0xbb}, {0x00, 0x01, 0x00, 0xdd}, + {0x0d, 0x00, 0x08, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, + {0xa1, 0x05, 0x00, 0xbb}, {0xa4, 0x03, 0xc0, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, + {0xc8, 0x9f, 0x0b, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, + {0xf0, 0x00, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, + {0x20, 0x01, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, + {0xf0, 0x00, 0x01, 0xbb}, {0x9d, 0x3c, 0xa0, 0xbb}, + {0x47, 0x30, 0x30, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, + {0x0a, 0x80, 0x11, 0xbb}, {0x35, 0x00, 0x22, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x9d, 0xc5, 0x05, 0xbb}, + {0xdc, 0x0f, 0xfc, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, + {0x06, 0x74, 0x0e, 0xbb}, {0x80, 0x00, 0x06, 0xbb}, + {0x81, 0x04, 0x00, 0xbb}, {0x82, 0x01, 0x02, 0xbb}, + {0x83, 0x03, 0x02, 0xbb}, {0x84, 0x05, 0x00, 0xbb}, + {0x85, 0x01, 0x00, 0xbb}, {0x86, 0x03, 0x02, 0xbb}, + {0x87, 0x05, 0x00, 0xbb}, {0x88, 0x01, 0x00, 0xbb}, + {0x89, 0x02, 0x02, 0xbb}, {0x8a, 0xfd, 0x04, 0xbb}, + {0x8b, 0xfc, 0xfd, 0xbb}, {0x8c, 0xff, 0xfd, 0xbb}, + {0x8d, 0x00, 0x00, 0xbb}, {0x8e, 0xfe, 0x05, 0xbb}, + {0x8f, 0xfc, 0xfd, 0xbb}, {0x90, 0xfe, 0xfd, 0xbb}, + {0x91, 0x00, 0x00, 0xbb}, {0x92, 0xfe, 0x03, 0xbb}, + {0x93, 0xfd, 0xfe, 0xbb}, {0x94, 0xff, 0xfd, 0xbb}, + {0x95, 0x00, 0x00, 0xbb}, {0xb6, 0x07, 0x05, 0xbb}, + {0xb7, 0x13, 0x06, 0xbb}, {0xb8, 0x08, 0x06, 0xbb}, + {0xb9, 0x14, 0x08, 0xbb}, {0xba, 0x06, 0x05, 0xbb}, + {0xbb, 0x13, 0x06, 0xbb}, {0xbc, 0x03, 0x01, 0xbb}, + {0xbd, 0x03, 0x04, 0xbb}, {0xbe, 0x00, 0x02, 0xbb}, + {0xbf, 0x03, 0x01, 0xbb}, {0xc0, 0x02, 0x04, 0xbb}, + {0xc1, 0x00, 0x04, 0xbb}, {0xc2, 0x02, 0x01, 0xbb}, + {0xc3, 0x01, 0x03, 0xbb}, {0xc4, 0x00, 0x04, 0xbb}, + {0xf0, 0x00, 0x00, 0xbb}, {0x05, 0x01, 0x13, 0xbb}, + {0x06, 0x00, 0x11, 0xbb}, {0x07, 0x00, 0x85, 0xbb}, + {0x08, 0x00, 0x27, 0xbb}, {0x20, 0x01, 0x03, 0xbb}, + {0x21, 0x80, 0x00, 0xbb}, {0x22, 0x0d, 0x0f, 0xbb}, + {0x24, 0x80, 0x00, 0xbb}, {0x59, 0x00, 0xff, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x39, 0x03, 0x0d, 0xbb}, + {0x3a, 0x06, 0x1b, 0xbb}, {0x3b, 0x00, 0x95, 0xbb}, + {0x3c, 0x04, 0xdb, 0xbb}, {0x57, 0x02, 0x00, 0xbb}, + {0x58, 0x02, 0x66, 0xbb}, {0x59, 0x00, 0xff, 0xbb}, + {0x5a, 0x01, 0x33, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb}, + {0x5d, 0x16, 0x11, 0xbb}, {0x64, 0x5e, 0x1c, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb}, + {0x5b, 0x00, 0x01, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, + {0x36, 0x68, 0x10, 0xbb}, {0x00, 0x00, 0x30, 0xdd}, + {0x37, 0x82, 0x00, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc}, + {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc}, + {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc}, + {0xb6, 0x03, 0x05, 0xcc}, {0xb6, 0x02, 0x00, 0xcc}, + {0xb6, 0x05, 0x04, 0xcc}, {0xb6, 0x04, 0x00, 0xcc}, + {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x29, 0xcc}, + {0xb6, 0x18, 0x0a, 0xcc}, {0xb6, 0x17, 0x00, 0xcc}, + {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, + {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x26, 0xcc}, + {0xbf, 0xc1, 0x02, 0xcc}, {0xbf, 0xcc, 0x04, 0xcc}, + {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, + {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, + {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, + {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, + {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, + {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, + {} +}; +static const __u8 mi1320_initQVGA_data[][4] = { + {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, + {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, + {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, + {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, + {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x01, 0xcc}, + {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, + {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, + {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc}, + {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, + {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, + {0xb3, 0x22, 0x01, 0xcc}, {0xb3, 0x23, 0xe0, 0xcc}, + {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, + {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, + {0xb3, 0x00, 0x65, 0xcc}, {0xb8, 0x00, 0x00, 0xcc}, + {0xbc, 0x00, 0xd0, 0xcc}, {0xbc, 0x01, 0x01, 0xcc}, + {0xf0, 0x00, 0x00, 0xbb}, {0x0d, 0x00, 0x09, 0xbb}, + {0x00, 0x01, 0x00, 0xdd}, {0x0d, 0x00, 0x08, 0xbb}, + {0xf0, 0x00, 0x00, 0xbb}, {0x02, 0x00, 0x64, 0xbb}, + {0x05, 0x01, 0x78, 0xbb}, {0x06, 0x00, 0x11, 0xbb}, + {0x07, 0x01, 0x42, 0xbb}, {0x08, 0x00, 0x11, 0xbb}, + {0x20, 0x01, 0x00, 0xbb}, {0x21, 0x80, 0x00, 0xbb}, + {0x22, 0x0d, 0x0f, 0xbb}, {0x24, 0x80, 0x00, 0xbb}, + {0x59, 0x00, 0xff, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, + {0x9d, 0x3c, 0xa0, 0xbb}, {0x47, 0x30, 0x30, 0xbb}, + {0xf0, 0x00, 0x00, 0xbb}, {0x0a, 0x80, 0x11, 0xbb}, + {0x35, 0x00, 0x22, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, + {0x9d, 0xc5, 0x05, 0xbb}, {0xdc, 0x0f, 0xfc, 0xbb}, + {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0x74, 0x0e, 0xbb}, + {0x80, 0x00, 0x06, 0xbb}, {0x81, 0x04, 0x00, 0xbb}, + {0x82, 0x01, 0x02, 0xbb}, {0x83, 0x03, 0x02, 0xbb}, + {0x84, 0x05, 0x00, 0xbb}, {0x85, 0x01, 0x00, 0xbb}, + {0x86, 0x03, 0x02, 0xbb}, {0x87, 0x05, 0x00, 0xbb}, + {0x88, 0x01, 0x00, 0xbb}, {0x89, 0x02, 0x02, 0xbb}, + {0x8a, 0xfd, 0x04, 0xbb}, {0x8b, 0xfc, 0xfd, 0xbb}, + {0x8c, 0xff, 0xfd, 0xbb}, {0x8d, 0x00, 0x00, 0xbb}, + {0x8e, 0xfe, 0x05, 0xbb}, {0x8f, 0xfc, 0xfd, 0xbb}, + {0x90, 0xfe, 0xfd, 0xbb}, {0x91, 0x00, 0x00, 0xbb}, + {0x92, 0xfe, 0x03, 0xbb}, {0x93, 0xfd, 0xfe, 0xbb}, + {0x94, 0xff, 0xfd, 0xbb}, {0x95, 0x00, 0x00, 0xbb}, + {0xb6, 0x07, 0x05, 0xbb}, {0xb7, 0x13, 0x06, 0xbb}, + {0xb8, 0x08, 0x06, 0xbb}, {0xb9, 0x14, 0x08, 0xbb}, + {0xba, 0x06, 0x05, 0xbb}, {0xbb, 0x13, 0x06, 0xbb}, + {0xbc, 0x03, 0x01, 0xbb}, {0xbd, 0x03, 0x04, 0xbb}, + {0xbe, 0x00, 0x02, 0xbb}, {0xbf, 0x03, 0x01, 0xbb}, + {0xc0, 0x02, 0x04, 0xbb}, {0xc1, 0x00, 0x04, 0xbb}, + {0xc2, 0x02, 0x01, 0xbb}, {0xc3, 0x01, 0x03, 0xbb}, + {0xc4, 0x00, 0x04, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, + {0xc8, 0x00, 0x00, 0xbb}, {0x2e, 0x00, 0x00, 0xbb}, + {0x2e, 0x0c, 0x5b, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb}, + {0x39, 0x03, 0xca, 0xbb}, {0x3a, 0x06, 0x80, 0xbb}, + {0x3b, 0x01, 0x52, 0xbb}, {0x3c, 0x05, 0x40, 0xbb}, + {0x57, 0x01, 0x9c, 0xbb}, {0x58, 0x01, 0xee, 0xbb}, + {0x59, 0x00, 0xf0, 0xbb}, {0x5a, 0x01, 0x20, 0xbb}, + {0x5c, 0x1d, 0x17, 0xbb}, {0x5d, 0x22, 0x1c, 0xbb}, + {0x64, 0x1e, 0x1c, 0xbb}, {0x5b, 0x00, 0x01, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x68, 0x10, 0xbb}, + {0x00, 0x00, 0x30, 0xdd}, {0x37, 0x81, 0x00, 0xbb}, + {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, + {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, + {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, + {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, + {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, + {0xbf, 0xc0, 0x26, 0xcc}, {0xbf, 0xc1, 0x02, 0xcc}, + {0xbf, 0xcc, 0x04, 0xcc}, {0xb3, 0x5c, 0x01, 0xcc}, + {0xb3, 0x01, 0x41, 0xcc}, {} }; + static const __u8 po3130_gamma[17] = { 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff @@ -2633,43 +1764,26 @@ static const __u8 po1200_initVGA_data[][4] = { }; struct sensor_info { - s8 sensorId; - u8 I2cAdd; - u8 IdAdd; - u16 VpId; - u8 m1; - u8 m2; - u8 op; -}; + int sensorId; + __u8 I2cAdd; + __u8 IdAdd; + __u16 VpId; + __u8 m1; + __u8 m2; + __u8 op; + }; static const struct sensor_info sensor_info_data[] = { /* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */ - {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05}, - {-1, 0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01}, -/* (tested in vc032x_probe_sensor) */ -/* {-1, 0x80 | 0x20, 0x83, 0x0000, 0x24, 0x25, 0x01}, */ + {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01}, + {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05}, {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, + {SENSOR_MI1320, 0x80 | 0xc8, 0x00, 0x148c, 0x64, 0x65, 0x01}, + {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05}, {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01}, /* (tested in vc032x_probe_sensor) */ /* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */ - {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01}, - {-1, 0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05}, - {-1, 0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05}, - {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05}, -/* {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01}, */ - {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01}, -/* {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01}, */ -/* {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05}, */ - {-1, 0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01}, {SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01}, - {-1, 0x80 | 0x2d, 0x00, 0x0000, 0x65, 0x67, 0x01}, - {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01}, - {-1, 0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01}, - {SENSOR_MI1320_SOC, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x67, 0x01}, -/*fixme: previously detected?*/ - {SENSOR_MI1320, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x65, 0x01}, -/*fixme: not in the ms-win probe - may be found before?*/ - {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05}, }; /* read 'len' bytes in gspca_dev->usb_buf */ @@ -2700,49 +1814,51 @@ static void reg_w(struct usb_device *dev, 500); } -static u16 read_sensor_register(struct gspca_dev *gspca_dev, - u16 address) +static void read_sensor_register(struct gspca_dev *gspca_dev, + __u16 address, __u16 *value) { struct usb_device *dev = gspca_dev->dev; - u8 ldata, mdata, hdata; + __u8 ldata, mdata, hdata; int retry = 50; + *value = 0; + reg_r(gspca_dev, 0xa1, 0xb33f, 1); + /*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */ if (!(gspca_dev->usb_buf[0] & 0x02)) { - PDEBUG(D_ERR, "I2c Bus Busy Wait %02x", - gspca_dev->usb_buf[0]); - return 0; + PDEBUG(D_ERR, "I2c Bus Busy Wait %d", + gspca_dev->usb_buf[0] & 0x02); + return; } reg_w(dev, 0xa0, address, 0xb33a); reg_w(dev, 0xa0, 0x02, 0xb339); - do { + reg_r(gspca_dev, 0xa1, 0xb33b, 1); + while (retry-- && gspca_dev->usb_buf[0]) { reg_r(gspca_dev, 0xa1, 0xb33b, 1); - if (gspca_dev->usb_buf[0] == 0x00) - break; - msleep(40); - } while (--retry >= 0); - +/* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */ + msleep(1); + } reg_r(gspca_dev, 0xa1, 0xb33e, 1); ldata = gspca_dev->usb_buf[0]; reg_r(gspca_dev, 0xa1, 0xb33d, 1); mdata = gspca_dev->usb_buf[0]; reg_r(gspca_dev, 0xa1, 0xb33c, 1); hdata = gspca_dev->usb_buf[0]; - if (hdata != 0 && mdata != 0 && ldata != 0) - PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x", - hdata, mdata, ldata); + PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x", + hdata, mdata, ldata); reg_r(gspca_dev, 0xa1, 0xb334, 1); if (gspca_dev->usb_buf[0] == 0x02) - return (hdata << 8) + mdata; - return hdata; + *value = (hdata << 8) + mdata; + else + *value = hdata; } static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; int i; - u16 value; + __u16 value; const struct sensor_info *ptsensor_info; reg_r(gspca_dev, 0xa1, 0xbfcf, 1); @@ -2756,51 +1872,48 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) reg_w(dev, 0xa0, 0x0c, 0xb309); reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335); reg_w(dev, 0xa0, ptsensor_info->op, 0xb301); - value = read_sensor_register(gspca_dev, ptsensor_info->IdAdd); - if (value == 0 && ptsensor_info->IdAdd == 0x82) - value = read_sensor_register(gspca_dev, 0x83); - if (value != 0) { - PDEBUG(D_ERR|D_PROBE, "Sensor ID %04x (%d)", - value, i); - if (value == ptsensor_info->VpId) - return ptsensor_info->sensorId; - - switch (value) { - case 0x7673: - return SENSOR_OV7670; - case 0x8243: - return SENSOR_MI0360; - } -/*fixme: should return here*/ - } + read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value); + if (value == ptsensor_info->VpId) + return ptsensor_info->sensorId; + + /* special case for MI0360 */ + if (ptsensor_info->sensorId == SENSOR_MI1310_SOC + && value == 0x8243) + return SENSOR_MI0360; } return -1; } -static void i2c_write(struct gspca_dev *gspca_dev, - u8 reg, const u8 *val, - u8 size) /* 1 or 2 */ +static __u8 i2c_write(struct gspca_dev *gspca_dev, + __u8 reg, const __u8 *val, __u8 size) { struct usb_device *dev = gspca_dev->dev; - int retry; + if (size > 3 || size < 1) + return -EINVAL; reg_r(gspca_dev, 0xa1, 0xb33f, 1); -/*fixme:should check if (!(gspca_dev->usb_buf[0] & 0x02)) error*/ reg_w(dev, 0xa0, size, 0xb334); reg_w(dev, 0xa0, reg, 0xb33a); - reg_w(dev, 0xa0, val[0], 0xb336); - if (size > 1) + switch (size) { + case 1: + reg_w(dev, 0xa0, val[0], 0xb336); + break; + case 2: + reg_w(dev, 0xa0, val[0], 0xb336); reg_w(dev, 0xa0, val[1], 0xb337); + break; + case 3: + reg_w(dev, 0xa0, val[0], 0xb336); + reg_w(dev, 0xa0, val[1], 0xb337); + reg_w(dev, 0xa0, val[2], 0xb338); + break; + default: + reg_w(dev, 0xa0, 0x01, 0xb334); + return -EINVAL; + } reg_w(dev, 0xa0, 0x01, 0xb339); - retry = 4; - do { - reg_r(gspca_dev, 0xa1, 0xb33b, 1); - if (gspca_dev->usb_buf[0] == 0) - break; - msleep(20); - } while (--retry > 0); - if (retry <= 0) - PDEBUG(D_ERR, "i2c_write failed"); + reg_r(gspca_dev, 0xa1, 0xb33b, 1); + return gspca_dev->usb_buf[0] == 0; } static void put_tab_to_reg(struct gspca_dev *gspca_dev, @@ -2825,7 +1938,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev, return; case 0xcc: /* normal write */ reg_w(dev, 0xa0, data[i][2], - (data[i][0]) << 8 | data[i][1]); + ((data[i][0])<<8) | data[i][1]); break; case 0xaa: /* i2c op */ i2c_write(gspca_dev, data[i][1], &data[i][2], 1); @@ -2842,6 +1955,19 @@ static void usb_exchange(struct gspca_dev *gspca_dev, /*not reached*/ } +/* + "GammaT"=hex:04,17,31,4f,6a,83,99,ad,bf,ce,da,e5,ee,f5,fb,ff,ff + "MatrixT"=hex:60,f9,e5,e7,50,05,f3,e6,66 + */ + +static void vc0321_reset(struct gspca_dev *gspca_dev) +{ + reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb04d); + reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb301); + msleep(100); + reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb003); + msleep(100); +} /* this function is called at probe time */ static int sd_config(struct gspca_dev *gspca_dev, @@ -2853,7 +1979,10 @@ static int sd_config(struct gspca_dev *gspca_dev, int sensor; cam = &gspca_dev->cam; + cam->epaddr = 0x02; sd->bridge = id->driver_info; + + vc0321_reset(gspca_dev); sensor = vc032x_probe_sensor(gspca_dev); switch (sensor) { case -1: @@ -2872,9 +2001,6 @@ static int sd_config(struct gspca_dev *gspca_dev, case SENSOR_MI1320: PDEBUG(D_PROBE, "Find Sensor MI1320"); break; - case SENSOR_MI1320_SOC: - PDEBUG(D_PROBE, "Find Sensor MI1320_SOC"); - break; case SENSOR_OV7660: PDEBUG(D_PROBE, "Find Sensor OV7660"); break; @@ -2894,23 +2020,12 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = vc0321_mode; cam->nmodes = ARRAY_SIZE(vc0321_mode); } else { - switch (sensor) { - case SENSOR_PO1200: - cam->cam_mode = svga_mode; - cam->nmodes = ARRAY_SIZE(svga_mode); - break; - case SENSOR_MI1310_SOC: + if (sensor != SENSOR_PO1200) { cam->cam_mode = vc0323_mode; cam->nmodes = ARRAY_SIZE(vc0323_mode); - break; - case SENSOR_MI1320_SOC: - cam->cam_mode = bi_mode; - cam->nmodes = ARRAY_SIZE(bi_mode); - break; - default: - cam->cam_mode = vc0323_mode; - cam->nmodes = ARRAY_SIZE(vc0323_mode) - 1; - break; + } else { + cam->cam_mode = svga_mode; + cam->nmodes = ARRAY_SIZE(svga_mode); } } @@ -2946,7 +2061,7 @@ static int sd_config(struct gspca_dev *gspca_dev, return 0; } -/* this function is called at probe and resume time */ +/* this function is called at probe and time */ static int sd_init(struct gspca_dev *gspca_dev) { return 0; @@ -3009,18 +2124,9 @@ static void setsharpness(struct gspca_dev *gspca_dev) static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - const __u8 (*init)[4]; const __u8 *GammaT = NULL; const __u8 *MatrixT = NULL; int mode; - static const u8 (*mi1320_soc_init[])[4] = { - mi1320_soc_InitSXGA, - mi1320_soc_InitSXGA_JPG, - mi1320_soc_InitVGA, - mi1320_soc_InitVGA_JPG, - mi1320_soc_InitQVGA, - mi1320_soc_InitQVGA_JPG - }; /* Assume start use the good resolution from gspca_dev->mode */ if (sd->bridge == BRIDGE_VC0321) { @@ -3028,13 +2134,6 @@ static int sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfed); reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfee); reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfef); - sd->image_offset = 46; - } else { - if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].pixelformat - == V4L2_PIX_FMT_JPEG) - sd->image_offset = 0; - else - sd->image_offset = 32; } mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; @@ -3042,87 +2141,115 @@ static int sd_start(struct gspca_dev *gspca_dev) case SENSOR_HV7131R: GammaT = hv7131r_gamma; MatrixT = hv7131r_matrix; - if (mode) - init = hv7131r_initQVGA_data; /* 320x240 */ - else - init = hv7131r_initVGA_data; /* 640x480 */ + if (mode) { + /* 320x240 */ + usb_exchange(gspca_dev, hv7131r_initQVGA_data); + } else { + /* 640x480 */ + usb_exchange(gspca_dev, hv7131r_initVGA_data); + } break; case SENSOR_OV7660: GammaT = ov7660_gamma; MatrixT = ov7660_matrix; - if (mode) - init = ov7660_initQVGA_data; /* 320x240 */ - else - init = ov7660_initVGA_data; /* 640x480 */ + if (mode) { + /* 320x240 */ + usb_exchange(gspca_dev, ov7660_initQVGA_data); + } else { + /* 640x480 */ + usb_exchange(gspca_dev, ov7660_initVGA_data); + } break; case SENSOR_OV7670: /*GammaT = ov7660_gamma; */ /*MatrixT = ov7660_matrix; */ - if (mode) - init = ov7670_initQVGA_JPG; /* 320x240 */ - else - init = ov7670_initVGA_JPG; /* 640x480 */ + if (mode) { + /* 320x240 */ + usb_exchange(gspca_dev, ov7670_initQVGA_JPG); + } else { + /* 640x480 */ + usb_exchange(gspca_dev, ov7670_initVGA_JPG); + } break; case SENSOR_MI0360: GammaT = mi1320_gamma; MatrixT = mi0360_matrix; - if (mode) - init = mi0360_initQVGA_JPG; /* 320x240 */ - else - init = mi0360_initVGA_JPG; /* 640x480 */ + if (mode) { + /* 320x240 */ + usb_exchange(gspca_dev, mi0360_initQVGA_JPG); + } else { + /* 640x480 */ + usb_exchange(gspca_dev, mi0360_initVGA_JPG); + } break; case SENSOR_MI1310_SOC: - GammaT = mi1320_gamma; - MatrixT = mi1320_matrix; - switch (mode) { - case 1: - init = mi1310_socinitQVGA_JPG; /* 320x240 */ - break; - case 0: - init = mi1310_socinitVGA_JPG; /* 640x480 */ - break; - default: - init = mi1310_soc_InitSXGA_JPG; /* 1280x1024 */ - break; + if (mode) { + /* 320x240 */ + usb_exchange(gspca_dev, mi1310_socinitQVGA_JPG); + } else { + /* 640x480 */ + usb_exchange(gspca_dev, mi1310_socinitVGA_JPG); } break; case SENSOR_MI1320: GammaT = mi1320_gamma; MatrixT = mi1320_matrix; - if (mode) - init = mi1320_initQVGA_data; /* 320x240 */ - else - init = mi1320_initVGA_data; /* 640x480 */ - break; - case SENSOR_MI1320_SOC: - GammaT = mi1320_gamma; - MatrixT = mi1320_matrix; - init = mi1320_soc_init[mode]; + if (mode) { + /* 320x240 */ + usb_exchange(gspca_dev, mi1320_initQVGA_data); + } else { + /* 640x480 */ + usb_exchange(gspca_dev, mi1320_initVGA_data); + } break; case SENSOR_PO3130NC: GammaT = po3130_gamma; MatrixT = po3130_matrix; - if (mode) - init = po3130_initQVGA_data; /* 320x240 */ - else - init = po3130_initVGA_data; /* 640x480 */ - usb_exchange(gspca_dev, init); - init = po3130_rundata; + if (mode) { + /* 320x240 */ + usb_exchange(gspca_dev, po3130_initQVGA_data); + } else { + /* 640x480 */ + usb_exchange(gspca_dev, po3130_initVGA_data); + } + usb_exchange(gspca_dev, po3130_rundata); break; - default: -/* case SENSOR_PO1200: */ + case SENSOR_PO1200: GammaT = po1200_gamma; MatrixT = po1200_matrix; - init = po1200_initVGA_data; + usb_exchange(gspca_dev, po1200_initVGA_data); break; + default: + PDEBUG(D_PROBE, "Damned !! no sensor found Bye"); + return -EMEDIUMTYPE; } - usb_exchange(gspca_dev, init); if (GammaT && MatrixT) { put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a); put_tab_to_reg(gspca_dev, GammaT, 17, 0xb85b); put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c); put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c); + /* Seem SHARPNESS */ + /* + reg_w(gspca_dev->dev, 0xa0, 0x80, 0xb80a); + reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80b); + reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80e); + */ + /* all 0x40 ??? do nothing + reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb822); + reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb823); + reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824); + */ + /* Only works for HV7131R ?? + reg_r (gspca_dev, 0xa1, 0xb881, 1); + reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881); + reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801); + */ + /* only hv7131r et ov7660 + reg_w(gspca_dev->dev, 0xa0, 0x20, 0xb827); + reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb826); * ISP_GAIN 80 + reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS + */ /* set the led on 0x0892 0x0896 */ if (sd->sensor != SENSOR_PO1200) { reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff); @@ -3169,8 +2296,12 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, "vc032x header packet found len %d", len); frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); - data += sd->image_offset; - len -= sd->image_offset; + if (sd->bridge == BRIDGE_VC0321) { +#define VCHDRSZ 46 + data += VCHDRSZ; + len -= VCHDRSZ; +#undef VCHDRSZ + } gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); return; @@ -3268,8 +2399,7 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ strcpy((char *) menu->name, "50 Hz"); return 0; - default: -/* case 2: * V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ + case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ strcpy((char *) menu->name, "60 Hz"); return 0; } @@ -3294,7 +2424,6 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x405b), .driver_info = BRIDGE_VC0323}, {USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321}, {USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321}, {USB_DEVICE(0x046d, 0x0897), .driver_info = BRIDGE_VC0321}, @@ -3303,7 +2432,6 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321}, {USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321}, {USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321}, - {USB_DEVICE(0x15b8, 0x6001), .driver_info = BRIDGE_VC0323}, {USB_DEVICE(0x15b8, 0x6002), .driver_info = BRIDGE_VC0323}, {USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323}, {} @@ -3332,11 +2460,8 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - int ret; - - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/gspca/zc3xx.c b/trunk/drivers/media/video/gspca/zc3xx.c index 4fe01d8b6c87..ec2a53d53fe2 100644 --- a/trunk/drivers/media/video/gspca/zc3xx.c +++ b/trunk/drivers/media/video/gspca/zc3xx.c @@ -23,7 +23,6 @@ #define MODULE_NAME "zc3xx" #include "gspca.h" -#include "jpeg.h" MODULE_AUTHOR("Michel Xhaard , " "Serge A. Suchkov "); @@ -32,7 +31,7 @@ MODULE_LICENSE("GPL"); static int force_sensor = -1; -#define QUANT_VAL 1 /* quantization table */ +#include "jpeg.h" #include "zc3xx-reg.h" /* specific webcam descriptor */ @@ -45,36 +44,30 @@ struct sd { __u8 autogain; __u8 lightfreq; __u8 sharpness; - u8 quality; /* image quality */ -#define QUALITY_MIN 40 -#define QUALITY_MAX 60 -#define QUALITY_DEF 50 + char qindex; signed char sensor; /* Type of image sensor chip */ /* !! values used in different tables */ -#define SENSOR_ADCM2700 0 -#define SENSOR_CS2102 1 -#define SENSOR_CS2102K 2 -#define SENSOR_GC0305 3 -#define SENSOR_HDCS2020b 4 -#define SENSOR_HV7131B 5 -#define SENSOR_HV7131C 6 -#define SENSOR_ICM105A 7 -#define SENSOR_MC501CB 8 -#define SENSOR_OV7620 9 -/*#define SENSOR_OV7648 9 - same values */ -#define SENSOR_OV7630C 10 -#define SENSOR_PAS106 11 -#define SENSOR_PAS202B 12 -#define SENSOR_PB0330 13 -#define SENSOR_PO2030 14 -#define SENSOR_TAS5130CK 15 -#define SENSOR_TAS5130CXX 16 -#define SENSOR_TAS5130C_VF0250 17 -#define SENSOR_MAX 18 +#define SENSOR_CS2102 0 +#define SENSOR_CS2102K 1 +#define SENSOR_GC0305 2 +#define SENSOR_HDCS2020b 3 +#define SENSOR_HV7131B 4 +#define SENSOR_HV7131C 5 +#define SENSOR_ICM105A 6 +#define SENSOR_MC501CB 7 +#define SENSOR_OV7620 8 +/*#define SENSOR_OV7648 8 - same values */ +#define SENSOR_OV7630C 9 +#define SENSOR_PAS106 10 +#define SENSOR_PAS202B 11 +#define SENSOR_PB0330 12 +#define SENSOR_PO2030 13 +#define SENSOR_TAS5130CK 14 +#define SENSOR_TAS5130CXX 15 +#define SENSOR_TAS5130C_VF0250 16 +#define SENSOR_MAX 17 unsigned short chip_revision; - - u8 *jpeg_hdr; }; /* V4L2 controls supported by the driver */ @@ -213,213 +206,6 @@ struct usb_action { __u16 idx; }; -static const struct usb_action adcm2700_Initial[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ - {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */ - {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */ - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ - {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ - {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */ - {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ - {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */ - {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ - {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */ - {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */ - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ - {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */ - {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */ - {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */ - {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */ - {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */ - {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */ - {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */ - {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */ - {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */ - {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */ - {0xbb, 0x86, 0x0002}, /* 00,86,02,bb */ - {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */ - {0xbb, 0x86, 0x0802}, /* 08,86,02,bb */ - {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */ -/*mswin+*/ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, - {0xaa, 0xfe, 0x0002}, - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, - {0xaa, 0xb4, 0xcd37}, - {0xaa, 0xa4, 0x0004}, - {0xaa, 0xa8, 0x0007}, - {0xaa, 0xac, 0x0004}, -/*mswin-*/ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */ - {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ - {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */ - {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ - {} -}; -static const struct usb_action adcm2700_InitialScale[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ - {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ - {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */ - {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ - {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ - {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ - {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ - {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ - {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ - {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ - {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */ - {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ - {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */ - {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ - {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */ - {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */ - {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ - {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */ - {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */ - {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */ - {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */ - {0xdd, 0x00, 0x0050}, /* 00,00,50,dd */ - {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */ - {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */ - {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */ - {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */ - {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */ - {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */ - {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */ - {0xbb, 0x86, 0x0002}, /* 00,88,02,bb */ - {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */ - {0xbb, 0x86, 0x0802}, /* 08,88,02,bb */ - {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */ - /*******/ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */ - {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */ - {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ - {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */ - {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ - {} -}; -static const struct usb_action adcm2700_50HZ[] = { - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xbb, 0x05, 0x8400}, /* 84,05,00,bb */ - {0xbb, 0xd0, 0xb007}, /* b0,d0,07,bb */ - {0xbb, 0xa0, 0xb80f}, /* b8,a0,0f,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ - {0xaa, 0x26, 0x00d0}, /* 00,26,d0,aa */ - {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */ - {} -}; -static const struct usb_action adcm2700_60HZ[] = { - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */ - {0xbb, 0x82, 0xb006}, /* b0,82,06,bb */ - {0xbb, 0x04, 0xb80d}, /* b8,04,0d,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ - {0xaa, 0x26, 0x0057}, /* 00,26,57,aa */ - {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */ - {} -}; -static const struct usb_action adcm2700_NoFliker[] = { - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */ - {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */ - {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */ - {0xbb, 0x05, 0xb000}, /* b0,05,00,bb */ - {0xbb, 0xa0, 0xb801}, /* b8,a0,01,bb */ - {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ - {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */ - {} -}; static const struct usb_action cs2102_Initial[] = { {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0008}, @@ -1091,7 +877,7 @@ static const struct usb_action cs2102K_Initial[] = { }; static const struct usb_action cs2102K_InitialScale[] = { - {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, @@ -1108,7 +894,6 @@ static const struct usb_action cs2102K_InitialScale[] = { {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, -/*fixme: next sequence = i2c exchanges*/ {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR}, {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, @@ -1292,6 +1077,207 @@ static const struct usb_action cs2102K_InitialScale[] = { {0xa0, 0x60, ZC3XX_R116_RGAIN}, {0xa0, 0x40, ZC3XX_R117_GGAIN}, {0xa0, 0x4c, ZC3XX_R118_BGAIN}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, + {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0A, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0B, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0C, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0D, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0xA3, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0E, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x0C, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x78, ZC3XX_R18D_YTARGET}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0x01, 0x01b1}, + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x60, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x4c, ZC3XX_R118_BGAIN}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ + {0xa0, 0x38, ZC3XX_R121_GAMMA01}, + {0xa0, 0x59, ZC3XX_R122_GAMMA02}, + {0xa0, 0x79, ZC3XX_R123_GAMMA03}, + {0xa0, 0x92, ZC3XX_R124_GAMMA04}, + {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, + {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, + {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, + {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, + {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, + {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x26, ZC3XX_R130_GAMMA10}, + {0xa0, 0x22, ZC3XX_R131_GAMMA11}, + {0xa0, 0x20, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, + {0xa0, 0x16, ZC3XX_R134_GAMMA14}, + {0xa0, 0x13, ZC3XX_R135_GAMMA15}, + {0xa0, 0x10, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, + {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf4, ZC3XX_R10B_RGB01}, + {0xa0, 0xf4, ZC3XX_R10C_RGB02}, + {0xa0, 0xf4, ZC3XX_R10D_RGB10}, + {0xa0, 0x58, ZC3XX_R10E_RGB11}, + {0xa0, 0xf4, ZC3XX_R10F_RGB12}, + {0xa0, 0xf4, ZC3XX_R110_RGB20}, + {0xa0, 0xf4, ZC3XX_R111_RGB21}, + {0xa0, 0x58, ZC3XX_R112_RGB22}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, + {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0x19, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0x1f, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x60, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x4c, ZC3XX_R118_BGAIN}, {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, @@ -1348,7 +1334,6 @@ static const struct usb_action cs2102K_InitialScale[] = { {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, -/*fixme:what does the next sequence?*/ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, @@ -6252,7 +6237,7 @@ static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = { {} }; -static u8 reg_r_i(struct gspca_dev *gspca_dev, +static int reg_r_i(struct gspca_dev *gspca_dev, __u16 index) { usb_control_msg(gspca_dev->dev, @@ -6265,10 +6250,10 @@ static u8 reg_r_i(struct gspca_dev *gspca_dev, return gspca_dev->usb_buf[0]; } -static u8 reg_r(struct gspca_dev *gspca_dev, +static int reg_r(struct gspca_dev *gspca_dev, __u16 index) { - u8 ret; + int ret; ret = reg_r_i(gspca_dev, index); PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret); @@ -6301,8 +6286,8 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev, __u8 retbyte; __u16 retval; - reg_w_i(gspca_dev->dev, reg, 0x0092); - reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */ + reg_w_i(gspca_dev->dev, reg, 0x92); + reg_w_i(gspca_dev->dev, 0x02, 0x90); /* <- read command */ msleep(25); retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ @@ -6347,12 +6332,6 @@ static void usb_exchange(struct gspca_dev *gspca_dev, action->idx & 0xff, /* valL */ action->idx >> 8); /* valH */ break; - case 0xbb: - i2c_write(gspca_dev, - action->idx >> 8, /* reg */ - action->idx & 0xff, /* valL */ - action->val); /* valH */ - break; default: /* case 0xdd: * delay */ msleep(action->val / 64 + 10); @@ -6368,10 +6347,6 @@ static void setmatrix(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int i; const __u8 *matrix; - static const u8 adcm2700_matrix[9] = -/* {0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; */ -/*ms-win*/ - {0x74, 0xed, 0xed, 0xed, 0x74, 0xed, 0xed, 0xed, 0x74}; static const __u8 gc0305_matrix[9] = {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50}; static const __u8 ov7620_matrix[9] = @@ -6383,24 +6358,23 @@ static void setmatrix(struct gspca_dev *gspca_dev) static const __u8 vf0250_matrix[9] = {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; static const __u8 *matrix_tb[SENSOR_MAX] = { - adcm2700_matrix, /* SENSOR_ADCM2700 0 */ - NULL, /* SENSOR_CS2102 1 */ - NULL, /* SENSOR_CS2102K 2 */ - gc0305_matrix, /* SENSOR_GC0305 3 */ - NULL, /* SENSOR_HDCS2020b 4 */ - NULL, /* SENSOR_HV7131B 5 */ - NULL, /* SENSOR_HV7131C 6 */ - NULL, /* SENSOR_ICM105A 7 */ - NULL, /* SENSOR_MC501CB 8 */ - ov7620_matrix, /* SENSOR_OV7620 9 */ - NULL, /* SENSOR_OV7630C 10 */ - NULL, /* SENSOR_PAS106 11 */ - pas202b_matrix, /* SENSOR_PAS202B 12 */ - NULL, /* SENSOR_PB0330 13 */ - po2030_matrix, /* SENSOR_PO2030 14 */ - NULL, /* SENSOR_TAS5130CK 15 */ - NULL, /* SENSOR_TAS5130CXX 16 */ - vf0250_matrix, /* SENSOR_TAS5130C_VF0250 17 */ + NULL, /* SENSOR_CS2102 0 */ + NULL, /* SENSOR_CS2102K 1 */ + gc0305_matrix, /* SENSOR_GC0305 2 */ + NULL, /* SENSOR_HDCS2020b 3 */ + NULL, /* SENSOR_HV7131B 4 */ + NULL, /* SENSOR_HV7131C 5 */ + NULL, /* SENSOR_ICM105A 6 */ + NULL, /* SENSOR_MC501CB 7 */ + ov7620_matrix, /* SENSOR_OV7620 8 */ + NULL, /* SENSOR_OV7630C 9 */ + NULL, /* SENSOR_PAS106 10 */ + pas202b_matrix, /* SENSOR_PAS202B 11 */ + NULL, /* SENSOR_PB0330 12 */ + po2030_matrix, /* SENSOR_PO2030 13 */ + NULL, /* SENSOR_TAS5130CK 14 */ + NULL, /* SENSOR_TAS5130CXX 15 */ + vf0250_matrix, /* SENSOR_TAS5130C_VF0250 16 */ }; matrix = matrix_tb[sd->sensor]; @@ -6424,11 +6398,8 @@ static void setbrightness(struct gspca_dev *gspca_dev) /*fixme: is it really write to 011d and 018d for all other sensors? */ brightness = sd->brightness; reg_w(gspca_dev->dev, brightness, 0x011d); - switch (sd->sensor) { - case SENSOR_ADCM2700: - case SENSOR_HV7131B: + if (sd->sensor == SENSOR_HV7131B) return; - } if (brightness < 0x70) brightness += 0x10; else @@ -6565,10 +6536,10 @@ static void setquality(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; + __u8 quality; __u8 frxt; switch (sd->sensor) { - case SENSOR_ADCM2700: case SENSOR_GC0305: case SENSOR_HV7131B: case SENSOR_OV7620: @@ -6576,18 +6547,26 @@ static void setquality(struct gspca_dev *gspca_dev) return; } /*fixme: is it really 0008 0007 0018 for all other sensors? */ - reg_w(dev, QUANT_VAL, 0x0008); + quality = sd->qindex; + reg_w(dev, quality, 0x0008); frxt = 0x30; reg_w(dev, frxt, 0x0007); -#if QUANT_VAL == 0 || QUANT_VAL == 1 || QUANT_VAL == 2 - frxt = 0xff; -#elif QUANT_VAL == 3 - frxt = 0xf0; -#elif QUANT_VAL == 4 - frxt = 0xe0; -#else - frxt = 0x20; -#endif + switch (quality) { + case 0: + case 1: + case 2: + frxt = 0xff; + break; + case 3: + frxt = 0xf0; + break; + case 4: + frxt = 0xe0; + break; + case 5: + frxt = 0x20; + break; + } reg_w(dev, frxt, 0x0018); } @@ -6604,75 +6583,71 @@ static int setlightfreq(struct gspca_dev *gspca_dev) int i, mode; const struct usb_action *zc3_freq; static const struct usb_action *freq_tb[SENSOR_MAX][6] = { -/* SENSOR_ADCM2700 0 */ - {adcm2700_NoFliker, adcm2700_NoFliker, - adcm2700_50HZ, adcm2700_50HZ, - adcm2700_60HZ, adcm2700_60HZ}, -/* SENSOR_CS2102 1 */ +/* SENSOR_CS2102 0 */ {cs2102_NoFliker, cs2102_NoFlikerScale, cs2102_50HZ, cs2102_50HZScale, cs2102_60HZ, cs2102_60HZScale}, -/* SENSOR_CS2102K 2 */ +/* SENSOR_CS2102K 1 */ {cs2102_NoFliker, cs2102_NoFlikerScale, NULL, NULL, /* currently disabled */ NULL, NULL}, -/* SENSOR_GC0305 3 */ +/* SENSOR_GC0305 2 */ {gc0305_NoFliker, gc0305_NoFliker, gc0305_50HZ, gc0305_50HZ, gc0305_60HZ, gc0305_60HZ}, -/* SENSOR_HDCS2020b 4 */ +/* SENSOR_HDCS2020b 3 */ {hdcs2020b_NoFliker, hdcs2020b_NoFliker, hdcs2020b_50HZ, hdcs2020b_50HZ, hdcs2020b_60HZ, hdcs2020b_60HZ}, -/* SENSOR_HV7131B 5 */ +/* SENSOR_HV7131B 4 */ {hv7131b_NoFlikerScale, hv7131b_NoFliker, hv7131b_50HZScale, hv7131b_50HZ, hv7131b_60HZScale, hv7131b_60HZ}, -/* SENSOR_HV7131C 6 */ +/* SENSOR_HV7131C 5 */ {NULL, NULL, NULL, NULL, NULL, NULL}, -/* SENSOR_ICM105A 7 */ +/* SENSOR_ICM105A 6 */ {icm105a_NoFliker, icm105a_NoFlikerScale, icm105a_50HZ, icm105a_50HZScale, icm105a_60HZ, icm105a_60HZScale}, -/* SENSOR_MC501CB 8 */ +/* SENSOR_MC501CB 7 */ {MC501CB_NoFliker, MC501CB_NoFlikerScale, MC501CB_50HZ, MC501CB_50HZScale, MC501CB_60HZ, MC501CB_60HZScale}, -/* SENSOR_OV7620 9 */ +/* SENSOR_OV7620 8 */ {OV7620_NoFliker, OV7620_NoFliker, OV7620_50HZ, OV7620_50HZ, OV7620_60HZ, OV7620_60HZ}, -/* SENSOR_OV7630C 10 */ +/* SENSOR_OV7630C 9 */ {NULL, NULL, NULL, NULL, NULL, NULL}, -/* SENSOR_PAS106 11 */ +/* SENSOR_PAS106 10 */ {pas106b_NoFliker, pas106b_NoFliker, pas106b_50HZ, pas106b_50HZ, pas106b_60HZ, pas106b_60HZ}, -/* SENSOR_PAS202B 12 */ +/* SENSOR_PAS202B 11 */ {pas202b_NoFlikerScale, pas202b_NoFliker, pas202b_50HZScale, pas202b_50HZ, pas202b_60HZScale, pas202b_60HZ}, -/* SENSOR_PB0330 13 */ +/* SENSOR_PB0330 12 */ {pb0330_NoFliker, pb0330_NoFlikerScale, pb0330_50HZ, pb0330_50HZScale, pb0330_60HZ, pb0330_60HZScale}, -/* SENSOR_PO2030 14 */ +/* SENSOR_PO2030 13 */ {PO2030_NoFliker, PO2030_NoFliker, PO2030_50HZ, PO2030_50HZ, PO2030_60HZ, PO2030_60HZ}, -/* SENSOR_TAS5130CK 15 */ +/* SENSOR_TAS5130CK 14 */ {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, tas5130cxx_50HZ, tas5130cxx_50HZScale, tas5130cxx_60HZ, tas5130cxx_60HZScale}, -/* SENSOR_TAS5130CXX 16 */ +/* SENSOR_TAS5130CXX 15 */ {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, tas5130cxx_50HZ, tas5130cxx_50HZScale, tas5130cxx_60HZ, tas5130cxx_60HZScale}, -/* SENSOR_TAS5130C_VF0250 17 */ +/* SENSOR_TAS5130C_VF0250 16 */ {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale, tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale}, @@ -6726,7 +6701,6 @@ static void send_unknown(struct usb_device *dev, int sensor) reg_w(dev, 0x0c, 0x003b); reg_w(dev, 0x08, 0x0038); break; - case SENSOR_ADCM2700: case SENSOR_GC0305: case SENSOR_OV7620: case SENSOR_PB0330: @@ -6769,25 +6743,26 @@ static int sif_probe(struct gspca_dev *gspca_dev) static int vga_2wr_probe(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - u16 retword; + __u8 retbyte; + __u16 checkword; start_2wr_probe(dev, 0x00); /* HV7131B */ i2c_write(gspca_dev, 0x01, 0xaa, 0x00); - retword = i2c_read(gspca_dev, 0x01); - if (retword != 0) + retbyte = i2c_read(gspca_dev, 0x01); + if (retbyte != 0) return 0x00; /* HV7131B */ start_2wr_probe(dev, 0x04); /* CS2102 */ i2c_write(gspca_dev, 0x01, 0xaa, 0x00); - retword = i2c_read(gspca_dev, 0x01); - if (retword != 0) + retbyte = i2c_read(gspca_dev, 0x01); + if (retbyte != 0) return 0x04; /* CS2102 */ start_2wr_probe(dev, 0x06); /* OmniVision */ reg_w(dev, 0x08, 0x008d); i2c_write(gspca_dev, 0x11, 0xaa, 0x00); - retword = i2c_read(gspca_dev, 0x11); - if (retword != 0) { + retbyte = i2c_read(gspca_dev, 0x11); + if (retbyte != 0) { /* (should have returned 0xaa) --> Omnivision? */ /* reg_r 0x10 -> 0x06 --> */ goto ov_check; @@ -6795,40 +6770,40 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev) start_2wr_probe(dev, 0x08); /* HDCS2020 */ i2c_write(gspca_dev, 0x15, 0xaa, 0x00); - retword = i2c_read(gspca_dev, 0x15); - if (retword != 0) + retbyte = i2c_read(gspca_dev, 0x15); + if (retbyte != 0) return 0x08; /* HDCS2020 */ start_2wr_probe(dev, 0x0a); /* PB0330 */ i2c_write(gspca_dev, 0x07, 0xaa, 0xaa); - retword = i2c_read(gspca_dev, 0x07); - if (retword != 0) + retbyte = i2c_read(gspca_dev, 0x07); + if (retbyte != 0) return 0x0a; /* PB0330 */ - retword = i2c_read(gspca_dev, 0x03); - if (retword != 0) + retbyte = i2c_read(gspca_dev, 0x03); + if (retbyte != 0) return 0x0a; /* PB0330 ?? */ - retword = i2c_read(gspca_dev, 0x04); - if (retword != 0) + retbyte = i2c_read(gspca_dev, 0x04); + if (retbyte != 0) return 0x0a; /* PB0330 ?? */ start_2wr_probe(dev, 0x0c); /* ICM105A */ i2c_write(gspca_dev, 0x01, 0x11, 0x00); - retword = i2c_read(gspca_dev, 0x01); - if (retword != 0) + retbyte = i2c_read(gspca_dev, 0x01); + if (retbyte != 0) return 0x0c; /* ICM105A */ start_2wr_probe(dev, 0x0e); /* PAS202BCB */ reg_w(dev, 0x08, 0x008d); i2c_write(gspca_dev, 0x03, 0xaa, 0x00); msleep(500); - retword = i2c_read(gspca_dev, 0x03); - if (retword != 0) + retbyte = i2c_read(gspca_dev, 0x03); + if (retbyte != 0) return 0x0e; /* PAS202BCB */ start_2wr_probe(dev, 0x02); /* ?? */ i2c_write(gspca_dev, 0x01, 0xaa, 0x00); - retword = i2c_read(gspca_dev, 0x01); - if (retword != 0) + retbyte = i2c_read(gspca_dev, 0x01); + if (retbyte != 0) return 0x02; /* ?? */ ov_check: reg_r(gspca_dev, 0x0010); /* ?? */ @@ -6842,10 +6817,12 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev) msleep(500); reg_w(dev, 0x01, 0x0012); i2c_write(gspca_dev, 0x12, 0x80, 0x00); /* sensor reset */ - retword = i2c_read(gspca_dev, 0x0a) << 8; - retword |= i2c_read(gspca_dev, 0x0b); - PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", retword); - switch (retword) { + retbyte = i2c_read(gspca_dev, 0x0a); + checkword = retbyte << 8; + retbyte = i2c_read(gspca_dev, 0x0b); + checkword |= retbyte; + PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", checkword); + switch (checkword) { case 0x7631: /* OV7630C */ reg_w(dev, 0x06, 0x0010); break; @@ -6855,7 +6832,7 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev) default: return -1; /* not OmniVision */ } - return retword; + return checkword; } struct sensor_by_chipset_revision { @@ -6868,7 +6845,6 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { {0x8001, 0x13}, {0x8000, 0x14}, /* CS2102K */ {0x8400, 0x15}, /* TAS5130K */ - {0x4001, 0x16}, /* ADCM2700 */ }; static int vga_3wr_probe(struct gspca_dev *gspca_dev) @@ -6877,7 +6853,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) struct usb_device *dev = gspca_dev->dev; int i; __u8 retbyte; - u16 retword; + __u16 checkword; /*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ reg_w(dev, 0x02, 0x0010); @@ -6889,25 +6865,27 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x03, 0x0012); reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x05, 0x0012); - retword = i2c_read(gspca_dev, 0x14); - if (retword != 0) + retbyte = i2c_read(gspca_dev, 0x14); + if (retbyte != 0) return 0x11; /* HV7131R */ - retword = i2c_read(gspca_dev, 0x15); - if (retword != 0) + retbyte = i2c_read(gspca_dev, 0x15); + if (retbyte != 0) return 0x11; /* HV7131R */ - retword = i2c_read(gspca_dev, 0x16); - if (retword != 0) + retbyte = i2c_read(gspca_dev, 0x16); + if (retbyte != 0) return 0x11; /* HV7131R */ reg_w(dev, 0x02, 0x0010); - retword = reg_r(gspca_dev, 0x000b) << 8; - retword |= reg_r(gspca_dev, 0x000a); - PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword); + retbyte = reg_r(gspca_dev, 0x000b); + checkword = retbyte << 8; + retbyte = reg_r(gspca_dev, 0x000a); + checkword |= retbyte; + PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword); reg_r(gspca_dev, 0x0010); /* this is tested only once anyway */ for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { - if (chipset_revision_sensor[i].revision == retword) { - sd->chip_revision = retword; + if (chipset_revision_sensor[i].revision == checkword) { + sd->chip_revision = checkword; send_unknown(dev, SENSOR_PB0330); return chipset_revision_sensor[i].internal_sensor_id; } @@ -6919,8 +6897,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x0a, 0x0010); reg_w(dev, 0x03, 0x0012); reg_w(dev, 0x01, 0x0012); - retword = i2c_read(gspca_dev, 0x00); - if (retword != 0) { + retbyte = i2c_read(gspca_dev, 0x00); + if (retbyte != 0) { PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); return 0x0a; /* ?? */ } @@ -6932,14 +6910,14 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x03, 0x0012); msleep(2); reg_w(dev, 0x01, 0x0012); - retword = i2c_read(gspca_dev, 0x00); - if (retword != 0) { - PDEBUG(D_PROBE, "probe 3wr vga type %02x", retword); - if (retword == 0x0011) /* VF0250 */ + retbyte = i2c_read(gspca_dev, 0x00); + if (retbyte != 0) { + PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte); + if (retbyte == 0x11) /* VF0250 */ return 0x0250; - if (retword == 0x0029) /* gc0305 */ + if (retbyte == 0x29) /* gc0305 */ send_unknown(dev, SENSOR_GC0305); - return retword; + return retbyte; } reg_w(dev, 0x01, 0x0000); /* check OmniVision */ @@ -6949,8 +6927,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x06, 0x0010); reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x05, 0x0012); - if (i2c_read(gspca_dev, 0x1c) == 0x007f /* OV7610 - manufacturer ID */ - && i2c_read(gspca_dev, 0x1d) == 0x00a2) { + if (i2c_read(gspca_dev, 0x1c) == 0x7f /* OV7610 - manufacturer ID */ + && i2c_read(gspca_dev, 0x1d) == 0xa2) { send_unknown(dev, SENSOR_OV7620); return 0x06; /* OmniVision confirm ? */ } @@ -6964,14 +6942,16 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) /* msleep(150); */ reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x05, 0x0012); - retword = i2c_read(gspca_dev, 0x00) << 8; /* ID 0 */ - retword |= i2c_read(gspca_dev, 0x01); /* ID 1 */ - PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword); - if (retword == 0x2030) { + retbyte = i2c_read(gspca_dev, 0x0000); /* ID 0 */ + checkword = retbyte << 8; + retbyte = i2c_read(gspca_dev, 0x0001); /* ID 1 */ + checkword |= retbyte; + PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword); + if (checkword == 0x2030) { retbyte = i2c_read(gspca_dev, 0x02); /* revision number */ PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte); send_unknown(dev, SENSOR_PO2030); - return retword; + return checkword; } reg_w(dev, 0x01, 0x0000); @@ -6982,10 +6962,10 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x05, 0x0001); reg_w(dev, 0xd3, 0x008b); - retword = i2c_read(gspca_dev, 0x01); - if (retword != 0) { - PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword); - return retword; + retbyte = i2c_read(gspca_dev, 0x01); + if (retbyte != 0) { + PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); + return 0x0a; /* ?? */ } return -1; } @@ -6993,7 +6973,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) static int zcxx_probeSensor(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - int sensor; + int sensor, sensor2; switch (sd->sensor) { case SENSOR_MC501CB: @@ -7008,9 +6988,16 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev) break; } sensor = vga_2wr_probe(gspca_dev); - if (sensor >= 0) + if (sensor >= 0) { + if (sensor < 0x7600) + return sensor; + /* next probe is needed for OmniVision ? */ + } + sensor2 = vga_3wr_probe(gspca_dev); + if (sensor2 >= 0 + && sensor >= 0) return sensor; - return vga_3wr_probe(gspca_dev); + return sensor2; } /* this function is called at probe time */ @@ -7022,24 +7009,23 @@ static int sd_config(struct gspca_dev *gspca_dev, int sensor; int vga = 1; /* 1: vga, 0: sif */ static const __u8 gamma[SENSOR_MAX] = { - 4, /* SENSOR_ADCM2700 0 */ - 5, /* SENSOR_CS2102 1 */ - 5, /* SENSOR_CS2102K 2 */ - 4, /* SENSOR_GC0305 3 */ - 4, /* SENSOR_HDCS2020b 4 */ - 4, /* SENSOR_HV7131B 5 */ - 4, /* SENSOR_HV7131C 6 */ - 4, /* SENSOR_ICM105A 7 */ - 4, /* SENSOR_MC501CB 8 */ - 3, /* SENSOR_OV7620 9 */ - 4, /* SENSOR_OV7630C 10 */ - 4, /* SENSOR_PAS106 11 */ - 4, /* SENSOR_PAS202B 12 */ - 4, /* SENSOR_PB0330 13 */ - 4, /* SENSOR_PO2030 14 */ - 4, /* SENSOR_TAS5130CK 15 */ - 4, /* SENSOR_TAS5130CXX 16 */ - 3, /* SENSOR_TAS5130C_VF0250 17 */ + 5, /* SENSOR_CS2102 0 */ + 5, /* SENSOR_CS2102K 1 */ + 4, /* SENSOR_GC0305 2 */ + 4, /* SENSOR_HDCS2020b 3 */ + 4, /* SENSOR_HV7131B 4 */ + 4, /* SENSOR_HV7131C 5 */ + 4, /* SENSOR_ICM105A 6 */ + 4, /* SENSOR_MC501CB 7 */ + 3, /* SENSOR_OV7620 8 */ + 4, /* SENSOR_OV7630C 9 */ + 4, /* SENSOR_PAS106 10 */ + 4, /* SENSOR_PAS202B 11 */ + 4, /* SENSOR_PB0330 12 */ + 4, /* SENSOR_PO2030 13 */ + 4, /* SENSOR_TAS5130CK 14 */ + 4, /* SENSOR_TAS5130CXX 15 */ + 3, /* SENSOR_TAS5130C_VF0250 16 */ }; /* define some sensors from the vendor/product */ @@ -7047,7 +7033,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->sensor = id->driver_info; sensor = zcxx_probeSensor(gspca_dev); if (sensor >= 0) - PDEBUG(D_PROBE, "probe sensor -> %04x", sensor); + PDEBUG(D_PROBE, "probe sensor -> %02x", sensor); if ((unsigned) force_sensor < SENSOR_MAX) { sd->sensor = force_sensor; PDEBUG(D_PROBE, "sensor forced to %d", force_sensor); @@ -7126,10 +7112,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->chip_revision); sd->sensor = SENSOR_TAS5130CK; break; - case 0x16: - PDEBUG(D_PROBE, "Find Sensor ADCM2700"); - sd->sensor = SENSOR_ADCM2700; - break; case 0x29: PDEBUG(D_PROBE, "Find Sensor GC0305"); sd->sensor = SENSOR_GC0305; @@ -7147,16 +7129,12 @@ static int sd_config(struct gspca_dev *gspca_dev, PDEBUG(D_PROBE, "Find Sensor OV7620"); sd->sensor = SENSOR_OV7620; break; - case 0x7631: - PDEBUG(D_PROBE, "Find Sensor OV7630C"); - sd->sensor = SENSOR_OV7630C; - break; case 0x7648: PDEBUG(D_PROBE, "Find Sensor OV7648"); sd->sensor = SENSOR_OV7620; /* same sensor (?) */ break; default: - PDEBUG(D_ERR|D_PROBE, "Unknown sensor %04x", sensor); + PDEBUG(D_ERR|D_PROBE, "Unknown sensor %02x", sensor); return -EINVAL; } } @@ -7169,6 +7147,7 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; + cam->epaddr = 0x01; /*fixme:test*/ gspca_dev->nbalt--; if (vga) { @@ -7178,12 +7157,12 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); } + sd->qindex = 1; sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; sd->gamma = gamma[(int) sd->sensor]; sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value; - sd->quality = QUALITY_DEF; switch (sd->sensor) { case SENSOR_GC0305: @@ -7217,34 +7196,27 @@ static int sd_start(struct gspca_dev *gspca_dev) const struct usb_action *zc3_init; int mode; static const struct usb_action *init_tb[SENSOR_MAX][2] = { - {adcm2700_Initial, adcm2700_InitialScale}, /* 0 */ - {cs2102_InitialScale, cs2102_Initial}, /* 1 */ - {cs2102K_InitialScale, cs2102K_Initial}, /* 2 */ - {gc0305_Initial, gc0305_InitialScale}, /* 3 */ - {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 4 */ - {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 5 */ - {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */ - {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */ - {MC501CB_InitialScale, MC501CB_Initial}, /* 8 */ - {OV7620_mode0, OV7620_mode1}, /* 9 */ - {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */ - {pas106b_InitialScale, pas106b_Initial}, /* 11 */ - {pas202b_Initial, pas202b_InitialScale}, /* 12 */ - {pb0330xx_InitialScale, pb0330xx_Initial}, /* 13 */ + {cs2102_InitialScale, cs2102_Initial}, /* 0 */ + {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */ + {gc0305_Initial, gc0305_InitialScale}, /* 2 */ + {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 3 */ + {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 4 */ + {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 5 */ + {icm105axx_InitialScale, icm105axx_Initial}, /* 6 */ + {MC501CB_InitialScale, MC501CB_Initial}, /* 7 */ + {OV7620_mode0, OV7620_mode1}, /* 8 */ + {ov7630c_InitialScale, ov7630c_Initial}, /* 9 */ + {pas106b_InitialScale, pas106b_Initial}, /* 10 */ + {pas202b_Initial, pas202b_InitialScale}, /* 11 */ + {pb0330xx_InitialScale, pb0330xx_Initial}, /* 12 */ /* or {pb03303x_InitialScale, pb03303x_Initial}, */ - {PO2030_mode0, PO2030_mode1}, /* 14 */ - {tas5130CK_InitialScale, tas5130CK_Initial}, /* 15 */ - {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 16 */ + {PO2030_mode0, PO2030_mode1}, /* 13 */ + {tas5130CK_InitialScale, tas5130CK_Initial}, /* 14 */ + {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 15 */ {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial}, - /* 17 */ + /* 16 */ }; - /* create the JPEG header */ - sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); - jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, - 0x21); /* JPEG 422 */ - jpeg_set_qual(sd->jpeg_hdr, sd->quality); - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; zc3_init = init_tb[(int) sd->sensor][mode]; switch (sd->sensor) { @@ -7271,12 +7243,11 @@ static int sd_start(struct gspca_dev *gspca_dev) usb_exchange(gspca_dev, zc3_init); switch (sd->sensor) { - case SENSOR_ADCM2700: case SENSOR_GC0305: case SENSOR_OV7620: case SENSOR_PO2030: case SENSOR_TAS5130C_VF0250: -/* msleep(100); * ?? */ + msleep(100); /* ?? */ reg_r(gspca_dev, 0x0002); /* --> 0x40 */ reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ reg_w(dev, 0x15, 0x01ae); @@ -7289,7 +7260,6 @@ static int sd_start(struct gspca_dev *gspca_dev) setmatrix(gspca_dev); setbrightness(gspca_dev); switch (sd->sensor) { - case SENSOR_ADCM2700: case SENSOR_OV7620: reg_r(gspca_dev, 0x0008); reg_w(dev, 0x00, 0x0008); @@ -7331,13 +7301,6 @@ static int sd_start(struct gspca_dev *gspca_dev) setlightfreq(gspca_dev); switch (sd->sensor) { - case SENSOR_ADCM2700: - reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ - reg_w(dev, 0x15, 0x01ae); - reg_w(dev, 0x02, 0x0180); - /* ms-win + */ - reg_w(dev, 0x40, 0x0117); - break; case SENSOR_GC0305: reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ reg_w(dev, 0x15, 0x01ae); @@ -7360,16 +7323,19 @@ static int sd_start(struct gspca_dev *gspca_dev) setautogain(gspca_dev); switch (sd->sensor) { + case SENSOR_PAS202B: + reg_w(dev, 0x00, 0x0007); /* (from win traces) */ + break; case SENSOR_PO2030: msleep(500); reg_r(gspca_dev, 0x0008); reg_r(gspca_dev, 0x0007); - /*fall thru*/ - case SENSOR_PAS202B: reg_w(dev, 0x00, 0x0007); /* (from win traces) */ - reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING); + reg_w(dev, 0x02, 0x0008); break; } + if (sd->sensor == SENSOR_PAS202B) + reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING); return 0; } @@ -7378,7 +7344,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - kfree(sd->jpeg_hdr); if (!gspca_dev->present) return; send_unknown(gspca_dev->dev, sd->sensor); @@ -7389,15 +7354,14 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, __u8 *data, int len) { - struct sd *sd = (struct sd *) gspca_dev; if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); /* put the JPEG header in the new frame */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - sd->jpeg_hdr, JPEG_HDR_SZ); - + jpeg_put_header(gspca_dev, frame, + ((struct sd *) gspca_dev)->qindex, + 0x21); /* remove the webcam's header: * ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp * - 'ss ss' is the frame sequence number (BE) @@ -7539,34 +7503,6 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, return -EINVAL; } -static int sd_set_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (jcomp->quality < QUALITY_MIN) - sd->quality = QUALITY_MIN; - else if (jcomp->quality > QUALITY_MAX) - sd->quality = QUALITY_MAX; - else - sd->quality = jcomp->quality; - if (gspca_dev->streaming) - jpeg_set_qual(sd->jpeg_hdr, sd->quality); - return 0; -} - -static int sd_get_jcomp(struct gspca_dev *gspca_dev, - struct v4l2_jpegcompression *jcomp) -{ - struct sd *sd = (struct sd *) gspca_dev; - - memset(jcomp, 0, sizeof *jcomp); - jcomp->quality = sd->quality; - jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT - | V4L2_JPEG_MARKER_DQT; - return 0; -} - static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, @@ -7577,8 +7513,6 @@ static const struct sd_desc sd_desc = { .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan, .querymenu = sd_querymenu, - .get_jcomp = sd_get_jcomp, - .set_jcomp = sd_set_jcomp, }; static const __devinitdata struct usb_device_id device_table[] = { @@ -7629,9 +7563,11 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x055f, 0xd004)}, {USB_DEVICE(0x0698, 0x2003)}, {USB_DEVICE(0x0ac8, 0x0301), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x0ac8, 0x0302), .driver_info = SENSOR_PAS106}, + {USB_DEVICE(0x0ac8, 0x0302)}, {USB_DEVICE(0x0ac8, 0x301b)}, +#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE {USB_DEVICE(0x0ac8, 0x303b)}, +#endif {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250}, {USB_DEVICE(0x0ac8, 0x307b)}, {USB_DEVICE(0x10fd, 0x0128)}, @@ -7664,10 +7600,8 @@ static struct usb_driver sd_driver = { static int __init sd_mod_init(void) { - int ret; - ret = usb_register(&sd_driver); - if (ret < 0) - return ret; + if (usb_register(&sd_driver) < 0) + return -1; PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/trunk/drivers/media/video/hdpvr/Kconfig b/trunk/drivers/media/video/hdpvr/Kconfig deleted file mode 100644 index de247f3c7d05..000000000000 --- a/trunk/drivers/media/video/hdpvr/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ - -config VIDEO_HDPVR - tristate "Hauppauge HD PVR support" - depends on VIDEO_DEV - ---help--- - This is a video4linux driver for Hauppauge's HD PVR USB device. - - To compile this driver as a module, choose M here: the - module will be called hdpvr - diff --git a/trunk/drivers/media/video/hdpvr/Makefile b/trunk/drivers/media/video/hdpvr/Makefile deleted file mode 100644 index e0230fcb2e36..000000000000 --- a/trunk/drivers/media/video/hdpvr/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -hdpvr-objs := hdpvr-control.o hdpvr-core.o hdpvr-video.o - -hdpvr-$(CONFIG_I2C) += hdpvr-i2c.o - -obj-$(CONFIG_VIDEO_HDPVR) += hdpvr.o - -EXTRA_CFLAGS += -Idrivers/media/video - -EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) diff --git a/trunk/drivers/media/video/hdpvr/hdpvr-control.c b/trunk/drivers/media/video/hdpvr/hdpvr-control.c deleted file mode 100644 index 06791749d1a0..000000000000 --- a/trunk/drivers/media/video/hdpvr/hdpvr-control.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Hauppauge HD PVR USB driver - video 4 linux 2 interface - * - * Copyright (C) 2008 Janne Grunau (j@jannau.net) - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "hdpvr.h" - - -int hdpvr_config_call(struct hdpvr_device *dev, uint value, u8 valbuf) -{ - int ret; - char request_type = 0x38, snd_request = 0x01; - - msleep(10); - - mutex_lock(&dev->usbc_mutex); - dev->usbc_buf[0] = valbuf; - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - snd_request, 0x00 | request_type, - value, CTRL_DEFAULT_INDEX, - dev->usbc_buf, 1, 10000); - - mutex_unlock(&dev->usbc_mutex); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "config call request for value 0x%x returned %d\n", value, - ret); - - return ret < 0 ? ret : 0; -} - -struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev) -{ - struct hdpvr_video_info *vidinf = NULL; -#ifdef HDPVR_DEBUG - char print_buf[15]; -#endif - int ret; - - vidinf = kzalloc(sizeof(struct hdpvr_video_info), GFP_KERNEL); - if (!vidinf) { - v4l2_err(&dev->v4l2_dev, "out of memory\n"); - goto err; - } - - mutex_lock(&dev->usbc_mutex); - ret = usb_control_msg(dev->udev, - usb_rcvctrlpipe(dev->udev, 0), - 0x81, 0x80 | 0x38, - 0x1400, 0x0003, - dev->usbc_buf, 5, - 1000); - if (ret == 5) { - vidinf->width = dev->usbc_buf[1] << 8 | dev->usbc_buf[0]; - vidinf->height = dev->usbc_buf[3] << 8 | dev->usbc_buf[2]; - vidinf->fps = dev->usbc_buf[4]; - } - -#ifdef HDPVR_DEBUG - if (hdpvr_debug & MSG_INFO) { - hex_dump_to_buffer(dev->usbc_buf, 5, 16, 1, print_buf, - sizeof(print_buf), 0); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "get video info returned: %d, %s\n", ret, print_buf); - } -#endif - mutex_unlock(&dev->usbc_mutex); - - if (!vidinf->width || !vidinf->height || !vidinf->fps) { - kfree(vidinf); - vidinf = NULL; - } -err: - return vidinf; -} - -int get_input_lines_info(struct hdpvr_device *dev) -{ -#ifdef HDPVR_DEBUG - char print_buf[9]; -#endif - int ret, lines; - - mutex_lock(&dev->usbc_mutex); - ret = usb_control_msg(dev->udev, - usb_rcvctrlpipe(dev->udev, 0), - 0x81, 0x80 | 0x38, - 0x1800, 0x0003, - dev->usbc_buf, 3, - 1000); - -#ifdef HDPVR_DEBUG - if (hdpvr_debug & MSG_INFO) { - hex_dump_to_buffer(dev->usbc_buf, 3, 16, 1, print_buf, - sizeof(print_buf), 0); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "get input lines info returned: %d, %s\n", ret, - print_buf); - } -#endif - lines = dev->usbc_buf[1] << 8 | dev->usbc_buf[0]; - mutex_unlock(&dev->usbc_mutex); - return lines; -} - - -int hdpvr_set_bitrate(struct hdpvr_device *dev) -{ - int ret; - - mutex_lock(&dev->usbc_mutex); - memset(dev->usbc_buf, 0, 4); - dev->usbc_buf[0] = dev->options.bitrate; - dev->usbc_buf[2] = dev->options.peak_bitrate; - - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - 0x01, 0x38, CTRL_BITRATE_VALUE, - CTRL_DEFAULT_INDEX, dev->usbc_buf, 4, 1000); - mutex_unlock(&dev->usbc_mutex); - - return ret; -} - -int hdpvr_set_audio(struct hdpvr_device *dev, u8 input, - enum v4l2_mpeg_audio_encoding codec) -{ - int ret = 0; - - if (dev->flags & HDPVR_FLAG_AC3_CAP) { - mutex_lock(&dev->usbc_mutex); - memset(dev->usbc_buf, 0, 2); - dev->usbc_buf[0] = input; - if (codec == V4L2_MPEG_AUDIO_ENCODING_AAC) - dev->usbc_buf[1] = 0; - else if (codec == V4L2_MPEG_AUDIO_ENCODING_AC3) - dev->usbc_buf[1] = 1; - else { - mutex_unlock(&dev->usbc_mutex); - v4l2_err(&dev->v4l2_dev, "invalid audio codec %d\n", - codec); - ret = -EINVAL; - goto error; - } - - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - 0x01, 0x38, CTRL_AUDIO_INPUT_VALUE, - CTRL_DEFAULT_INDEX, dev->usbc_buf, 2, - 1000); - mutex_unlock(&dev->usbc_mutex); - if (ret == 2) - ret = 0; - } else - ret = hdpvr_config_call(dev, CTRL_AUDIO_INPUT_VALUE, - dev->options.audio_input+1); -error: - return ret; -} - -int hdpvr_set_options(struct hdpvr_device *dev) -{ - hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, dev->options.video_std); - - hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, - dev->options.video_input+1); - - hdpvr_set_audio(dev, dev->options.audio_input+1, - dev->options.audio_codec); - - hdpvr_set_bitrate(dev); - hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE, - dev->options.bitrate_mode); - hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, dev->options.gop_mode); - - hdpvr_config_call(dev, CTRL_BRIGHTNESS, dev->options.brightness); - hdpvr_config_call(dev, CTRL_CONTRAST, dev->options.contrast); - hdpvr_config_call(dev, CTRL_HUE, dev->options.hue); - hdpvr_config_call(dev, CTRL_SATURATION, dev->options.saturation); - hdpvr_config_call(dev, CTRL_SHARPNESS, dev->options.sharpness); - - return 0; -} diff --git a/trunk/drivers/media/video/hdpvr/hdpvr-core.c b/trunk/drivers/media/video/hdpvr/hdpvr-core.c deleted file mode 100644 index 188bd5aea258..000000000000 --- a/trunk/drivers/media/video/hdpvr/hdpvr-core.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * Hauppauge HD PVR USB driver - * - * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2008 Janne Grunau (j@jannau.net) - * Copyright (C) 2008 John Poet - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "hdpvr.h" - -static int video_nr[HDPVR_MAX] = {[0 ... (HDPVR_MAX - 1)] = UNSET}; -module_param_array(video_nr, int, NULL, 0); -MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)"); - -/* holds the number of currently registered devices */ -static atomic_t dev_nr = ATOMIC_INIT(-1); - -int hdpvr_debug; -module_param(hdpvr_debug, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(hdpvr_debug, "enable debugging output"); - -uint default_video_input = HDPVR_VIDEO_INPUTS; -module_param(default_video_input, uint, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / " - "1=S-Video / 2=Composite"); - -uint default_audio_input = HDPVR_AUDIO_INPUTS; -module_param(default_audio_input, uint, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / " - "1=RCA front / 2=S/PDIF"); - -static int boost_audio; -module_param(boost_audio, bool, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(boost_audio, "boost the audio signal"); - - -/* table of devices that work with this driver */ -static struct usb_device_id hdpvr_table[] = { - { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID) }, - { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) }, - { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, hdpvr_table); - - -void hdpvr_delete(struct hdpvr_device *dev) -{ - hdpvr_free_buffers(dev); - - if (dev->video_dev) - video_device_release(dev->video_dev); - - usb_put_dev(dev->udev); -} - -static void challenge(u8 *bytes) -{ - u64 *i64P, tmp64; - uint i, idx; - - for (idx = 0; idx < 32; ++idx) { - - if (idx & 0x3) - bytes[(idx >> 3) + 3] = bytes[(idx >> 2) & 0x3]; - - switch (idx & 0x3) { - case 0x3: - bytes[2] += bytes[3] * 4 + bytes[4] + bytes[5]; - bytes[4] += bytes[(idx & 0x1) * 2] * 9 + 9; - break; - case 0x1: - bytes[0] *= 8; - bytes[0] += 7*idx + 4; - bytes[6] += bytes[3] * 3; - break; - case 0x0: - bytes[3 - (idx >> 3)] = bytes[idx >> 2]; - bytes[5] += bytes[6] * 3; - for (i = 0; i < 3; i++) - bytes[3] *= bytes[3] + 1; - break; - case 0x2: - for (i = 0; i < 3; i++) - bytes[1] *= bytes[6] + 1; - for (i = 0; i < 3; i++) { - i64P = (u64 *)bytes; - tmp64 = le64_to_cpup(i64P); - tmp64 <<= bytes[7] & 0x0f; - *i64P += cpu_to_le64(tmp64); - } - break; - } - } -} - -/* try to init the device like the windows driver */ -static int device_authorization(struct hdpvr_device *dev) -{ - - int ret, retval = -ENOMEM; - char request_type = 0x38, rcv_request = 0x81; - char *response; -#ifdef HDPVR_DEBUG - size_t buf_size = 46; - char *print_buf = kzalloc(5*buf_size+1, GFP_KERNEL); - if (!print_buf) { - v4l2_err(&dev->v4l2_dev, "Out of memory\n"); - goto error; - } -#endif - - mutex_lock(&dev->usbc_mutex); - ret = usb_control_msg(dev->udev, - usb_rcvctrlpipe(dev->udev, 0), - rcv_request, 0x80 | request_type, - 0x0400, 0x0003, - dev->usbc_buf, 46, - 10000); - if (ret != 46) { - v4l2_err(&dev->v4l2_dev, - "unexpected answer of status request, len %d\n", ret); - goto error; - } -#ifdef HDPVR_DEBUG - else { - hex_dump_to_buffer(dev->usbc_buf, 46, 16, 1, print_buf, - sizeof(print_buf), 0); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "Status request returned, len %d: %s\n", - ret, print_buf); - } -#endif - if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION) { - dev->flags &= ~HDPVR_FLAG_AC3_CAP; - } else if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION_AC3) { - dev->flags |= HDPVR_FLAG_AC3_CAP; - } else if (dev->usbc_buf[1] > HDPVR_FIRMWARE_VERSION_AC3) { - v4l2_info(&dev->v4l2_dev, "untested firmware version 0x%x, " - "the driver might not work\n", dev->usbc_buf[1]); - dev->flags |= HDPVR_FLAG_AC3_CAP; - } else { - v4l2_err(&dev->v4l2_dev, "unknown firmware version 0x%x\n", - dev->usbc_buf[1]); - ret = -EINVAL; - goto error; - } - - response = dev->usbc_buf+38; -#ifdef HDPVR_DEBUG - hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, "challenge: %s\n", - print_buf); -#endif - challenge(response); -#ifdef HDPVR_DEBUG - hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n", - print_buf); -#endif - - msleep(100); - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - 0xd1, 0x00 | request_type, - 0x0000, 0x0000, - response, 8, - 10000); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "magic request returned %d\n", ret); - mutex_unlock(&dev->usbc_mutex); - - retval = ret != 8; -error: - return retval; -} - -static int hdpvr_device_init(struct hdpvr_device *dev) -{ - int ret; - u8 *buf; - struct hdpvr_video_info *vidinf; - - if (device_authorization(dev)) - return -EACCES; - - /* default options for init */ - hdpvr_set_options(dev); - - /* set filter options */ - mutex_lock(&dev->usbc_mutex); - buf = dev->usbc_buf; - buf[0] = 0x03; buf[1] = 0x03; buf[2] = 0x00; buf[3] = 0x00; - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - 0x01, 0x38, - CTRL_LOW_PASS_FILTER_VALUE, CTRL_DEFAULT_INDEX, - buf, 4, - 1000); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "control request returned %d\n", ret); - mutex_unlock(&dev->usbc_mutex); - - vidinf = get_video_info(dev); - if (!vidinf) - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "no valid video signal or device init failed\n"); - else - kfree(vidinf); - - /* enable fan and bling leds */ - mutex_lock(&dev->usbc_mutex); - buf[0] = 0x1; - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - 0xd4, 0x38, 0, 0, buf, 1, - 1000); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "control request returned %d\n", ret); - - /* boost analog audio */ - buf[0] = boost_audio; - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - 0xd5, 0x38, 0, 0, buf, 1, - 1000); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "control request returned %d\n", ret); - mutex_unlock(&dev->usbc_mutex); - - dev->status = STATUS_IDLE; - return 0; -} - -static const struct hdpvr_options hdpvr_default_options = { - .video_std = HDPVR_60HZ, - .video_input = HDPVR_COMPONENT, - .audio_input = HDPVR_RCA_BACK, - .bitrate = 65, /* 6 mbps */ - .peak_bitrate = 90, /* 9 mbps */ - .bitrate_mode = HDPVR_CONSTANT, - .gop_mode = HDPVR_SIMPLE_IDR_GOP, - .audio_codec = V4L2_MPEG_AUDIO_ENCODING_AAC, - .brightness = 0x86, - .contrast = 0x80, - .hue = 0x80, - .saturation = 0x80, - .sharpness = 0x80, -}; - -static int hdpvr_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - struct hdpvr_device *dev; - struct usb_host_interface *iface_desc; - struct usb_endpoint_descriptor *endpoint; - size_t buffer_size; - int i; - int retval = -ENOMEM; - - /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - err("Out of memory"); - goto error; - } - - /* register v4l2_device early so it can be used for printks */ - if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) { - err("v4l2_device_register failed"); - goto error; - } - - mutex_init(&dev->io_mutex); - mutex_init(&dev->i2c_mutex); - mutex_init(&dev->usbc_mutex); - dev->usbc_buf = kmalloc(64, GFP_KERNEL); - if (!dev->usbc_buf) { - v4l2_err(&dev->v4l2_dev, "Out of memory\n"); - goto error; - } - - init_waitqueue_head(&dev->wait_buffer); - init_waitqueue_head(&dev->wait_data); - - dev->workqueue = create_singlethread_workqueue("hdpvr_buffer"); - if (!dev->workqueue) - goto error; - - /* init video transfer queues */ - INIT_LIST_HEAD(&dev->free_buff_list); - INIT_LIST_HEAD(&dev->rec_buff_list); - - dev->options = hdpvr_default_options; - - if (default_video_input < HDPVR_VIDEO_INPUTS) - dev->options.video_input = default_video_input; - - if (default_audio_input < HDPVR_AUDIO_INPUTS) - dev->options.audio_input = default_audio_input; - - dev->udev = usb_get_dev(interface_to_usbdev(interface)); - - /* set up the endpoint information */ - /* use only the first bulk-in and bulk-out endpoints */ - iface_desc = interface->cur_altsetting; - for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { - endpoint = &iface_desc->endpoint[i].desc; - - if (!dev->bulk_in_endpointAddr && - usb_endpoint_is_bulk_in(endpoint)) { - /* USB interface description is buggy, reported max - * packet size is 512 bytes, windows driver uses 8192 */ - buffer_size = 8192; - dev->bulk_in_size = buffer_size; - dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; - } - - } - if (!dev->bulk_in_endpointAddr) { - v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n"); - goto error; - } - - /* init the device */ - if (hdpvr_device_init(dev)) { - v4l2_err(&dev->v4l2_dev, "device init failed\n"); - goto error; - } - - mutex_lock(&dev->io_mutex); - if (hdpvr_alloc_buffers(dev, NUM_BUFFERS)) { - v4l2_err(&dev->v4l2_dev, - "allocating transfer buffers failed\n"); - goto error; - } - mutex_unlock(&dev->io_mutex); - - if (hdpvr_register_videodev(dev, &interface->dev, - video_nr[atomic_inc_return(&dev_nr)])) { - v4l2_err(&dev->v4l2_dev, "registering videodev failed\n"); - goto error; - } - -#ifdef CONFIG_I2C - /* until i2c is working properly */ - retval = 0; /* hdpvr_register_i2c_adapter(dev); */ - if (retval < 0) { - v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n"); - goto error; - } -#endif /* CONFIG_I2C */ - - /* save our data pointer in this interface device */ - usb_set_intfdata(interface, dev); - - /* let the user know what node this device is now attached to */ - v4l2_info(&dev->v4l2_dev, "device now attached to /dev/video%d\n", - dev->video_dev->minor); - return 0; - -error: - if (dev) { - mutex_unlock(&dev->io_mutex); - /* this frees allocated memory */ - hdpvr_delete(dev); - } - return retval; -} - -static void hdpvr_disconnect(struct usb_interface *interface) -{ - struct hdpvr_device *dev; - int minor; - - dev = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); - - minor = dev->video_dev->minor; - - /* prevent more I/O from starting and stop any ongoing */ - mutex_lock(&dev->io_mutex); - dev->status = STATUS_DISCONNECTED; - v4l2_device_disconnect(&dev->v4l2_dev); - video_unregister_device(dev->video_dev); - wake_up_interruptible(&dev->wait_data); - wake_up_interruptible(&dev->wait_buffer); - mutex_unlock(&dev->io_mutex); - msleep(100); - flush_workqueue(dev->workqueue); - mutex_lock(&dev->io_mutex); - hdpvr_cancel_queue(dev); - destroy_workqueue(dev->workqueue); - mutex_unlock(&dev->io_mutex); - - /* deregister I2C adapter */ -#ifdef CONFIG_I2C - mutex_lock(&dev->i2c_mutex); - if (dev->i2c_adapter) - i2c_del_adapter(dev->i2c_adapter); - kfree(dev->i2c_adapter); - dev->i2c_adapter = NULL; - mutex_unlock(&dev->i2c_mutex); -#endif /* CONFIG_I2C */ - - atomic_dec(&dev_nr); - - v4l2_info(&dev->v4l2_dev, "device /dev/video%d disconnected\n", minor); - - v4l2_device_unregister(&dev->v4l2_dev); - kfree(dev->usbc_buf); - kfree(dev); -} - - -static struct usb_driver hdpvr_usb_driver = { - .name = "hdpvr", - .probe = hdpvr_probe, - .disconnect = hdpvr_disconnect, - .id_table = hdpvr_table, -}; - -static int __init hdpvr_init(void) -{ - int result; - - /* register this driver with the USB subsystem */ - result = usb_register(&hdpvr_usb_driver); - if (result) - err("usb_register failed. Error number %d", result); - - return result; -} - -static void __exit hdpvr_exit(void) -{ - /* deregister this driver with the USB subsystem */ - usb_deregister(&hdpvr_usb_driver); -} - -module_init(hdpvr_init); -module_exit(hdpvr_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Janne Grunau"); -MODULE_DESCRIPTION("Hauppauge HD PVR driver"); diff --git a/trunk/drivers/media/video/hdpvr/hdpvr-i2c.c b/trunk/drivers/media/video/hdpvr/hdpvr-i2c.c deleted file mode 100644 index c4b5d1515c10..000000000000 --- a/trunk/drivers/media/video/hdpvr/hdpvr-i2c.c +++ /dev/null @@ -1,145 +0,0 @@ - -/* - * Hauppauge HD PVR USB driver - * - * Copyright (C) 2008 Janne Grunau (j@jannau.net) - * - * 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. - * - */ - -#include - -#include "hdpvr.h" - -#define CTRL_READ_REQUEST 0xb8 -#define CTRL_WRITE_REQUEST 0x38 - -#define REQTYPE_I2C_READ 0xb1 -#define REQTYPE_I2C_WRITE 0xb0 -#define REQTYPE_I2C_WRITE_STATT 0xd0 - -static int hdpvr_i2c_read(struct hdpvr_device *dev, unsigned char addr, - char *data, int len) -{ - int ret; - char *buf = kmalloc(len, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - ret = usb_control_msg(dev->udev, - usb_rcvctrlpipe(dev->udev, 0), - REQTYPE_I2C_READ, CTRL_READ_REQUEST, - 0x100|addr, 0, buf, len, 1000); - - if (ret == len) { - memcpy(data, buf, len); - ret = 0; - } else if (ret >= 0) - ret = -EIO; - - kfree(buf); - - return ret; -} - -static int hdpvr_i2c_write(struct hdpvr_device *dev, unsigned char addr, - char *data, int len) -{ - int ret; - char *buf = kmalloc(len, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - memcpy(buf, data, len); - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST, - 0x100|addr, 0, buf, len, 1000); - - if (ret < 0) - goto error; - - ret = usb_control_msg(dev->udev, - usb_rcvctrlpipe(dev->udev, 0), - REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST, - 0, 0, buf, 2, 1000); - - if (ret == 2) - ret = 0; - else if (ret >= 0) - ret = -EIO; - -error: - kfree(buf); - return ret; -} - -static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs, - int num) -{ - struct hdpvr_device *dev = i2c_get_adapdata(i2c_adapter); - int retval = 0, i, addr; - - if (num <= 0) - return 0; - - mutex_lock(&dev->i2c_mutex); - - for (i = 0; i < num && !retval; i++) { - addr = msgs[i].addr << 1; - - if (msgs[i].flags & I2C_M_RD) - retval = hdpvr_i2c_read(dev, addr, msgs[i].buf, - msgs[i].len); - else - retval = hdpvr_i2c_write(dev, addr, msgs[i].buf, - msgs[i].len); - } - - mutex_unlock(&dev->i2c_mutex); - - return retval ? retval : num; -} - -static u32 hdpvr_functionality(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -} - -static struct i2c_algorithm hdpvr_algo = { - .master_xfer = hdpvr_transfer, - .functionality = hdpvr_functionality, -}; - -int hdpvr_register_i2c_adapter(struct hdpvr_device *dev) -{ - struct i2c_adapter *i2c_adap; - int retval = -ENOMEM; - - i2c_adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); - if (i2c_adap == NULL) - goto error; - - strlcpy(i2c_adap->name, "Hauppauge HD PVR I2C", - sizeof(i2c_adap->name)); - i2c_adap->algo = &hdpvr_algo; - i2c_adap->class = I2C_CLASS_TV_ANALOG; - i2c_adap->id = I2C_HW_B_HDPVR; - i2c_adap->owner = THIS_MODULE; - i2c_adap->dev.parent = &dev->udev->dev; - - i2c_set_adapdata(i2c_adap, dev); - - retval = i2c_add_adapter(i2c_adap); - - if (!retval) - dev->i2c_adapter = i2c_adap; - else - kfree(i2c_adap); - -error: - return retval; -} diff --git a/trunk/drivers/media/video/hdpvr/hdpvr-video.c b/trunk/drivers/media/video/hdpvr/hdpvr-video.c deleted file mode 100644 index 3e6ffee8dfed..000000000000 --- a/trunk/drivers/media/video/hdpvr/hdpvr-video.c +++ /dev/null @@ -1,1248 +0,0 @@ -/* - * Hauppauge HD PVR USB driver - video 4 linux 2 interface - * - * Copyright (C) 2008 Janne Grunau (j@jannau.net) - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "hdpvr.h" - -#define BULK_URB_TIMEOUT 1250 /* 1.25 seconds */ - -#define print_buffer_status() { \ - v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, \ - "%s:%d buffer stat: %d free, %d proc\n", \ - __func__, __LINE__, \ - list_size(&dev->free_buff_list), \ - list_size(&dev->rec_buff_list)); } - -struct hdpvr_fh { - struct hdpvr_device *dev; -}; - -static uint list_size(struct list_head *list) -{ - struct list_head *tmp; - uint count = 0; - - list_for_each(tmp, list) { - count++; - } - - return count; -} - -/*=========================================================================*/ -/* urb callback */ -static void hdpvr_read_bulk_callback(struct urb *urb) -{ - struct hdpvr_buffer *buf = (struct hdpvr_buffer *)urb->context; - struct hdpvr_device *dev = buf->dev; - - /* marking buffer as received and wake waiting */ - buf->status = BUFSTAT_READY; - wake_up_interruptible(&dev->wait_data); -} - -/*=========================================================================*/ -/* bufffer bits */ - -/* function expects dev->io_mutex to be hold by caller */ -int hdpvr_cancel_queue(struct hdpvr_device *dev) -{ - struct hdpvr_buffer *buf; - - list_for_each_entry(buf, &dev->rec_buff_list, buff_list) { - usb_kill_urb(buf->urb); - buf->status = BUFSTAT_AVAILABLE; - } - - list_splice_init(&dev->rec_buff_list, dev->free_buff_list.prev); - - return 0; -} - -static int hdpvr_free_queue(struct list_head *q) -{ - struct list_head *tmp; - struct list_head *p; - struct hdpvr_buffer *buf; - struct urb *urb; - - for (p = q->next; p != q;) { - buf = list_entry(p, struct hdpvr_buffer, buff_list); - - urb = buf->urb; - usb_buffer_free(urb->dev, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma); - usb_free_urb(urb); - tmp = p->next; - list_del(p); - kfree(buf); - p = tmp; - } - - return 0; -} - -/* function expects dev->io_mutex to be hold by caller */ -int hdpvr_free_buffers(struct hdpvr_device *dev) -{ - hdpvr_cancel_queue(dev); - - hdpvr_free_queue(&dev->free_buff_list); - hdpvr_free_queue(&dev->rec_buff_list); - - return 0; -} - -/* function expects dev->io_mutex to be hold by caller */ -int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count) -{ - uint i; - int retval = -ENOMEM; - u8 *mem; - struct hdpvr_buffer *buf; - struct urb *urb; - - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "allocating %u buffers\n", count); - - for (i = 0; i < count; i++) { - - buf = kzalloc(sizeof(struct hdpvr_buffer), GFP_KERNEL); - if (!buf) { - v4l2_err(&dev->v4l2_dev, "cannot allocate buffer\n"); - goto exit; - } - buf->dev = dev; - - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n"); - goto exit; - } - buf->urb = urb; - - mem = usb_buffer_alloc(dev->udev, dev->bulk_in_size, GFP_KERNEL, - &urb->transfer_dma); - if (!mem) { - v4l2_err(&dev->v4l2_dev, - "cannot allocate usb transfer buffer\n"); - goto exit; - } - - usb_fill_bulk_urb(buf->urb, dev->udev, - usb_rcvbulkpipe(dev->udev, - dev->bulk_in_endpointAddr), - mem, dev->bulk_in_size, - hdpvr_read_bulk_callback, buf); - - buf->status = BUFSTAT_AVAILABLE; - list_add_tail(&buf->buff_list, &dev->free_buff_list); - } - return 0; -exit: - hdpvr_free_buffers(dev); - return retval; -} - -static int hdpvr_submit_buffers(struct hdpvr_device *dev) -{ - struct hdpvr_buffer *buf; - struct urb *urb; - int ret = 0, err_count = 0; - - mutex_lock(&dev->io_mutex); - - while (dev->status == STATUS_STREAMING && - !list_empty(&dev->free_buff_list)) { - - buf = list_entry(dev->free_buff_list.next, struct hdpvr_buffer, - buff_list); - if (buf->status != BUFSTAT_AVAILABLE) { - v4l2_err(&dev->v4l2_dev, - "buffer not marked as availbale\n"); - ret = -EFAULT; - goto err; - } - - urb = buf->urb; - urb->status = 0; - urb->actual_length = 0; - ret = usb_submit_urb(urb, GFP_KERNEL); - if (ret) { - v4l2_err(&dev->v4l2_dev, - "usb_submit_urb in %s returned %d\n", - __func__, ret); - if (++err_count > 2) - break; - continue; - } - buf->status = BUFSTAT_INPROGRESS; - list_move_tail(&buf->buff_list, &dev->rec_buff_list); - } -err: - print_buffer_status(); - mutex_unlock(&dev->io_mutex); - return ret; -} - -static struct hdpvr_buffer *hdpvr_get_next_buffer(struct hdpvr_device *dev) -{ - struct hdpvr_buffer *buf; - - mutex_lock(&dev->io_mutex); - - if (list_empty(&dev->rec_buff_list)) { - mutex_unlock(&dev->io_mutex); - return NULL; - } - - buf = list_entry(dev->rec_buff_list.next, struct hdpvr_buffer, - buff_list); - mutex_unlock(&dev->io_mutex); - - return buf; -} - -static void hdpvr_transmit_buffers(struct work_struct *work) -{ - struct hdpvr_device *dev = container_of(work, struct hdpvr_device, - worker); - - while (dev->status == STATUS_STREAMING) { - - if (hdpvr_submit_buffers(dev)) { - v4l2_err(&dev->v4l2_dev, "couldn't submit buffers\n"); - goto error; - } - if (wait_event_interruptible(dev->wait_buffer, - !list_empty(&dev->free_buff_list) || - dev->status != STATUS_STREAMING)) - goto error; - } - - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "transmit worker exited\n"); - return; -error: - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "transmit buffers errored\n"); - dev->status = STATUS_ERROR; -} - -/* function expects dev->io_mutex to be hold by caller */ -static int hdpvr_start_streaming(struct hdpvr_device *dev) -{ - int ret; - struct hdpvr_video_info *vidinf; - - if (dev->status == STATUS_STREAMING) - return 0; - else if (dev->status != STATUS_IDLE) - return -EAGAIN; - - vidinf = get_video_info(dev); - - if (vidinf) { - v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, - "video signal: %dx%d@%dhz\n", vidinf->width, - vidinf->height, vidinf->fps); - kfree(vidinf); - - /* start streaming 2 request */ - ret = usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - 0xb8, 0x38, 0x1, 0, NULL, 0, 8000); - v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, - "encoder start control request returned %d\n", ret); - - hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00); - - INIT_WORK(&dev->worker, hdpvr_transmit_buffers); - queue_work(dev->workqueue, &dev->worker); - - v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, - "streaming started\n"); - dev->status = STATUS_STREAMING; - - return 0; - } - msleep(250); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "no video signal at input %d\n", dev->options.video_input); - return -EAGAIN; -} - - -/* function expects dev->io_mutex to be hold by caller */ -static int hdpvr_stop_streaming(struct hdpvr_device *dev) -{ - uint actual_length, c = 0; - u8 *buf; - - if (dev->status == STATUS_IDLE) - return 0; - else if (dev->status != STATUS_STREAMING) - return -EAGAIN; - - buf = kmalloc(dev->bulk_in_size, GFP_KERNEL); - if (!buf) - v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer " - "for emptying the internal device buffer. " - "Next capture start will be slow\n"); - - dev->status = STATUS_SHUTTING_DOWN; - hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00); - mutex_unlock(&dev->io_mutex); - - wake_up_interruptible(&dev->wait_buffer); - msleep(50); - - flush_workqueue(dev->workqueue); - - mutex_lock(&dev->io_mutex); - /* kill the still outstanding urbs */ - hdpvr_cancel_queue(dev); - - /* emptying the device buffer beforeshutting it down */ - while (buf && ++c < 500 && - !usb_bulk_msg(dev->udev, - usb_rcvbulkpipe(dev->udev, - dev->bulk_in_endpointAddr), - buf, dev->bulk_in_size, &actual_length, - BULK_URB_TIMEOUT)) { - /* wait */ - msleep(5); - v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, - "%2d: got %d bytes\n", c, actual_length); - } - kfree(buf); - v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, - "used %d urbs to empty device buffers\n", c-1); - msleep(10); - - dev->status = STATUS_IDLE; - - return 0; -} - - -/*=======================================================================*/ -/* - * video 4 linux 2 file operations - */ - -static int hdpvr_open(struct file *file) -{ - struct hdpvr_device *dev; - struct hdpvr_fh *fh; - int retval = -ENOMEM; - - dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file)); - if (!dev) { - v4l2_err(&dev->v4l2_dev, "open failing with with ENODEV\n"); - retval = -ENODEV; - goto err; - } - - fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL); - if (!fh) { - v4l2_err(&dev->v4l2_dev, "Out of memory\n"); - goto err; - } - /* lock the device to allow correctly handling errors - * in resumption */ - mutex_lock(&dev->io_mutex); - dev->open_count++; - - fh->dev = dev; - - /* save our object in the file's private structure */ - file->private_data = fh; - - retval = 0; -err: - mutex_unlock(&dev->io_mutex); - return retval; -} - -static int hdpvr_release(struct file *file) -{ - struct hdpvr_fh *fh = (struct hdpvr_fh *)file->private_data; - struct hdpvr_device *dev = fh->dev; - - if (!dev) - return -ENODEV; - - mutex_lock(&dev->io_mutex); - if (!(--dev->open_count) && dev->status == STATUS_STREAMING) - hdpvr_stop_streaming(dev); - - mutex_unlock(&dev->io_mutex); - - return 0; -} - -/* - * hdpvr_v4l2_read() - * will allocate buffers when called for the first time - */ -static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count, - loff_t *pos) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - struct hdpvr_buffer *buf = NULL; - struct urb *urb; - unsigned int ret = 0; - int rem, cnt; - - if (*pos) - return -ESPIPE; - - if (!dev) - return -ENODEV; - - mutex_lock(&dev->io_mutex); - if (dev->status == STATUS_IDLE) { - if (hdpvr_start_streaming(dev)) { - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "start_streaming failed\n"); - ret = -EIO; - msleep(200); - dev->status = STATUS_IDLE; - mutex_unlock(&dev->io_mutex); - goto err; - } - print_buffer_status(); - } - mutex_unlock(&dev->io_mutex); - - /* wait for the first buffer */ - if (!(file->f_flags & O_NONBLOCK)) { - if (wait_event_interruptible(dev->wait_data, - hdpvr_get_next_buffer(dev))) - return -ERESTARTSYS; - } - - buf = hdpvr_get_next_buffer(dev); - - while (count > 0 && buf) { - - if (buf->status != BUFSTAT_READY && - dev->status != STATUS_DISCONNECTED) { - /* return nonblocking */ - if (file->f_flags & O_NONBLOCK) { - if (!ret) - ret = -EAGAIN; - goto err; - } - - if (wait_event_interruptible(dev->wait_data, - buf->status == BUFSTAT_READY)) { - ret = -ERESTARTSYS; - goto err; - } - } - - if (buf->status != BUFSTAT_READY) - break; - - /* set remaining bytes to copy */ - urb = buf->urb; - rem = urb->actual_length - buf->pos; - cnt = rem > count ? count : rem; - - if (copy_to_user(buffer, urb->transfer_buffer + buf->pos, - cnt)) { - v4l2_err(&dev->v4l2_dev, "read: copy_to_user failed\n"); - if (!ret) - ret = -EFAULT; - goto err; - } - - buf->pos += cnt; - count -= cnt; - buffer += cnt; - ret += cnt; - - /* finished, take next buffer */ - if (buf->pos == urb->actual_length) { - mutex_lock(&dev->io_mutex); - buf->pos = 0; - buf->status = BUFSTAT_AVAILABLE; - - list_move_tail(&buf->buff_list, &dev->free_buff_list); - - print_buffer_status(); - - mutex_unlock(&dev->io_mutex); - - wake_up_interruptible(&dev->wait_buffer); - - buf = hdpvr_get_next_buffer(dev); - } - } -err: - if (!ret && !buf) - ret = -EAGAIN; - return ret; -} - -static unsigned int hdpvr_poll(struct file *filp, poll_table *wait) -{ - struct hdpvr_buffer *buf = NULL; - struct hdpvr_fh *fh = (struct hdpvr_fh *)filp->private_data; - struct hdpvr_device *dev = fh->dev; - unsigned int mask = 0; - - mutex_lock(&dev->io_mutex); - - if (video_is_unregistered(dev->video_dev)) - return -EIO; - - if (dev->status == STATUS_IDLE) { - if (hdpvr_start_streaming(dev)) { - v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, - "start_streaming failed\n"); - dev->status = STATUS_IDLE; - } - - print_buffer_status(); - } - mutex_unlock(&dev->io_mutex); - - buf = hdpvr_get_next_buffer(dev); - /* only wait if no data is available */ - if (!buf || buf->status != BUFSTAT_READY) { - poll_wait(filp, &dev->wait_data, wait); - buf = hdpvr_get_next_buffer(dev); - } - if (buf && buf->status == BUFSTAT_READY) - mask |= POLLIN | POLLRDNORM; - - return mask; -} - - -static const struct v4l2_file_operations hdpvr_fops = { - .owner = THIS_MODULE, - .open = hdpvr_open, - .release = hdpvr_release, - .read = hdpvr_read, - .poll = hdpvr_poll, - .unlocked_ioctl = video_ioctl2, -}; - -/*=======================================================================*/ -/* - * V4L2 ioctl handling - */ - -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct hdpvr_device *dev = video_drvdata(file); - - strcpy(cap->driver, "hdpvr"); - strcpy(cap->card, "Haupauge HD PVR"); - usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); - cap->version = HDPVR_VERSION; - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_AUDIO | - V4L2_CAP_READWRITE; - return 0; -} - -static int vidioc_s_std(struct file *file, void *private_data, - v4l2_std_id *std) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - u8 std_type = 1; - - if (*std & (V4L2_STD_NTSC | V4L2_STD_PAL_60)) - std_type = 0; - - return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type); -} - -static const char *iname[] = { - [HDPVR_COMPONENT] = "Component", - [HDPVR_SVIDEO] = "S-Video", - [HDPVR_COMPOSITE] = "Composite", -}; - -static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - unsigned int n; - - n = i->index; - if (n >= HDPVR_VIDEO_INPUTS) - return -EINVAL; - - i->type = V4L2_INPUT_TYPE_CAMERA; - - strncpy(i->name, iname[n], sizeof(i->name) - 1); - i->name[sizeof(i->name) - 1] = '\0'; - - i->audioset = 1<std = dev->video_dev->tvnorms; - - return 0; -} - -static int vidioc_s_input(struct file *file, void *private_data, - unsigned int index) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - int retval; - - if (index >= HDPVR_VIDEO_INPUTS) - return -EINVAL; - - if (dev->status != STATUS_IDLE) - return -EAGAIN; - - retval = hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, index+1); - if (!retval) - dev->options.video_input = index; - - return retval; -} - -static int vidioc_g_input(struct file *file, void *private_data, - unsigned int *index) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - - *index = dev->options.video_input; - return 0; -} - - -static const char *audio_iname[] = { - [HDPVR_RCA_FRONT] = "RCA front", - [HDPVR_RCA_BACK] = "RCA back", - [HDPVR_SPDIF] = "SPDIF", -}; - -static int vidioc_enumaudio(struct file *file, void *priv, - struct v4l2_audio *audio) -{ - unsigned int n; - - n = audio->index; - if (n >= HDPVR_AUDIO_INPUTS) - return -EINVAL; - - audio->capability = V4L2_AUDCAP_STEREO; - - strncpy(audio->name, audio_iname[n], sizeof(audio->name) - 1); - audio->name[sizeof(audio->name) - 1] = '\0'; - - return 0; -} - -static int vidioc_s_audio(struct file *file, void *private_data, - struct v4l2_audio *audio) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - int retval; - - if (audio->index >= HDPVR_AUDIO_INPUTS) - return -EINVAL; - - if (dev->status != STATUS_IDLE) - return -EAGAIN; - - retval = hdpvr_set_audio(dev, audio->index+1, dev->options.audio_codec); - if (!retval) - dev->options.audio_input = audio->index; - - return retval; -} - -static int vidioc_g_audio(struct file *file, void *private_data, - struct v4l2_audio *audio) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - - audio->index = dev->options.audio_input; - audio->capability = V4L2_AUDCAP_STEREO; - strncpy(audio->name, audio_iname[audio->index], sizeof(audio->name)); - audio->name[sizeof(audio->name) - 1] = '\0'; - return 0; -} - -static const s32 supported_v4l2_ctrls[] = { - V4L2_CID_BRIGHTNESS, - V4L2_CID_CONTRAST, - V4L2_CID_SATURATION, - V4L2_CID_HUE, - V4L2_CID_SHARPNESS, - V4L2_CID_MPEG_AUDIO_ENCODING, - V4L2_CID_MPEG_VIDEO_ENCODING, - V4L2_CID_MPEG_VIDEO_BITRATE_MODE, - V4L2_CID_MPEG_VIDEO_BITRATE, - V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, -}; - -static int fill_queryctrl(struct hdpvr_options *opt, struct v4l2_queryctrl *qc, - int ac3) -{ - int err; - - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86); - case V4L2_CID_CONTRAST: - return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); - case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); - case V4L2_CID_SHARPNESS: - return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80); - case V4L2_CID_MPEG_AUDIO_ENCODING: - return v4l2_ctrl_query_fill( - qc, V4L2_MPEG_AUDIO_ENCODING_AAC, - ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 - : V4L2_MPEG_AUDIO_ENCODING_AAC, - 1, V4L2_MPEG_AUDIO_ENCODING_AAC); - case V4L2_CID_MPEG_VIDEO_ENCODING: - return v4l2_ctrl_query_fill( - qc, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, - V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1, - V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC); - -/* case V4L2_CID_MPEG_VIDEO_? maybe keyframe interval: */ -/* return v4l2_ctrl_query_fill(qc, 0, 128, 128, 0); */ - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - return v4l2_ctrl_query_fill( - qc, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1, - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR); - - case V4L2_CID_MPEG_VIDEO_BITRATE: - return v4l2_ctrl_query_fill(qc, 1000000, 13500000, 100000, - 6500000); - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - err = v4l2_ctrl_query_fill(qc, 1100000, 20200000, 100000, - 9000000); - if (!err && opt->bitrate_mode == HDPVR_CONSTANT) - qc->flags |= V4L2_CTRL_FLAG_INACTIVE; - return err; - default: - return -EINVAL; - } -} - -static int vidioc_queryctrl(struct file *file, void *private_data, - struct v4l2_queryctrl *qc) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - int i, next; - u32 id = qc->id; - - memset(qc, 0, sizeof(*qc)); - - next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL); - qc->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL; - - for (i = 0; i < ARRAY_SIZE(supported_v4l2_ctrls); i++) { - if (next) { - if (qc->id < supported_v4l2_ctrls[i]) - qc->id = supported_v4l2_ctrls[i]; - else - continue; - } - - if (qc->id == supported_v4l2_ctrls[i]) - return fill_queryctrl(&dev->options, qc, - dev->flags & HDPVR_FLAG_AC3_CAP); - - if (qc->id < supported_v4l2_ctrls[i]) - break; - } - - return -EINVAL; -} - -static int vidioc_g_ctrl(struct file *file, void *private_data, - struct v4l2_control *ctrl) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = dev->options.brightness; - break; - case V4L2_CID_CONTRAST: - ctrl->value = dev->options.contrast; - break; - case V4L2_CID_SATURATION: - ctrl->value = dev->options.saturation; - break; - case V4L2_CID_HUE: - ctrl->value = dev->options.hue; - break; - case V4L2_CID_SHARPNESS: - ctrl->value = dev->options.sharpness; - break; - default: - return -EINVAL; - } - return 0; -} - -static int vidioc_s_ctrl(struct file *file, void *private_data, - struct v4l2_control *ctrl) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - int retval; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - retval = hdpvr_config_call(dev, CTRL_BRIGHTNESS, ctrl->value); - if (!retval) - dev->options.brightness = ctrl->value; - break; - case V4L2_CID_CONTRAST: - retval = hdpvr_config_call(dev, CTRL_CONTRAST, ctrl->value); - if (!retval) - dev->options.contrast = ctrl->value; - break; - case V4L2_CID_SATURATION: - retval = hdpvr_config_call(dev, CTRL_SATURATION, ctrl->value); - if (!retval) - dev->options.saturation = ctrl->value; - break; - case V4L2_CID_HUE: - retval = hdpvr_config_call(dev, CTRL_HUE, ctrl->value); - if (!retval) - dev->options.hue = ctrl->value; - break; - case V4L2_CID_SHARPNESS: - retval = hdpvr_config_call(dev, CTRL_SHARPNESS, ctrl->value); - if (!retval) - dev->options.sharpness = ctrl->value; - break; - default: - return -EINVAL; - } - - return retval; -} - - -static int hdpvr_get_ctrl(struct hdpvr_options *opt, - struct v4l2_ext_control *ctrl) -{ - switch (ctrl->id) { - case V4L2_CID_MPEG_AUDIO_ENCODING: - ctrl->value = opt->audio_codec; - break; - case V4L2_CID_MPEG_VIDEO_ENCODING: - ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC; - break; -/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */ -/* ctrl->value = (opt->gop_mode & 0x2) ? 0 : 128; */ -/* break; */ - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - ctrl->value = opt->bitrate_mode == HDPVR_CONSTANT - ? V4L2_MPEG_VIDEO_BITRATE_MODE_CBR - : V4L2_MPEG_VIDEO_BITRATE_MODE_VBR; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE: - ctrl->value = opt->bitrate * 100000; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - ctrl->value = opt->peak_bitrate * 100000; - break; - case V4L2_CID_MPEG_STREAM_TYPE: - ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS; - break; - default: - return -EINVAL; - } - return 0; -} - -static int vidioc_g_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = hdpvr_get_ctrl(&dev->options, ctrl); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - - } - - return -EINVAL; -} - - -static int hdpvr_try_ctrl(struct v4l2_ext_control *ctrl, int ac3) -{ - int ret = -EINVAL; - - switch (ctrl->id) { - case V4L2_CID_MPEG_AUDIO_ENCODING: - if (ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AAC || - (ac3 && ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AC3)) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_ENCODING: - if (ctrl->value == V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC) - ret = 0; - break; -/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */ -/* if (ctrl->value == 0 || ctrl->value == 128) */ -/* ret = 0; */ -/* break; */ - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR || - ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) - ret = 0; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE: - { - uint bitrate = ctrl->value / 100000; - if (bitrate >= 10 && bitrate <= 135) - ret = 0; - break; - } - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - { - uint peak_bitrate = ctrl->value / 100000; - if (peak_bitrate >= 10 && peak_bitrate <= 202) - ret = 0; - break; - } - case V4L2_CID_MPEG_STREAM_TYPE: - if (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) - ret = 0; - break; - default: - return -EINVAL; - } - return 0; -} - -static int vidioc_try_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = hdpvr_try_ctrl(ctrl, - dev->flags & HDPVR_FLAG_AC3_CAP); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - } - - return -EINVAL; -} - - -static int hdpvr_set_ctrl(struct hdpvr_device *dev, - struct v4l2_ext_control *ctrl) -{ - struct hdpvr_options *opt = &dev->options; - int ret = 0; - - switch (ctrl->id) { - case V4L2_CID_MPEG_AUDIO_ENCODING: - if (dev->flags & HDPVR_FLAG_AC3_CAP) { - opt->audio_codec = ctrl->value; - ret = hdpvr_set_audio(dev, opt->audio_input, - opt->audio_codec); - } - break; - case V4L2_CID_MPEG_VIDEO_ENCODING: - break; -/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */ -/* if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */ -/* opt->gop_mode |= 0x2; */ -/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */ -/* opt->gop_mode); */ -/* } */ -/* if (ctrl->value == 128 && opt->gop_mode & 0x2) { */ -/* opt->gop_mode &= ~0x2; */ -/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */ -/* opt->gop_mode); */ -/* } */ -/* break; */ - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR && - opt->bitrate_mode != HDPVR_CONSTANT) { - opt->bitrate_mode = HDPVR_CONSTANT; - hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE, - opt->bitrate_mode); - } - if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && - opt->bitrate_mode == HDPVR_CONSTANT) { - opt->bitrate_mode = HDPVR_VARIABLE_AVERAGE; - hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE, - opt->bitrate_mode); - } - break; - case V4L2_CID_MPEG_VIDEO_BITRATE: { - uint bitrate = ctrl->value / 100000; - - opt->bitrate = bitrate; - if (bitrate >= opt->peak_bitrate) - opt->peak_bitrate = bitrate+1; - - hdpvr_set_bitrate(dev); - break; - } - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: { - uint peak_bitrate = ctrl->value / 100000; - - if (opt->bitrate_mode == HDPVR_CONSTANT) - break; - - if (opt->bitrate < peak_bitrate) { - opt->peak_bitrate = peak_bitrate; - hdpvr_set_bitrate(dev); - } else - ret = -EINVAL; - break; - } - case V4L2_CID_MPEG_STREAM_TYPE: - break; - default: - return -EINVAL; - } - return ret; -} - -static int vidioc_s_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - int i, err = 0; - - if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = ctrls->controls + i; - - err = hdpvr_try_ctrl(ctrl, - dev->flags & HDPVR_FLAG_AC3_CAP); - if (err) { - ctrls->error_idx = i; - break; - } - err = hdpvr_set_ctrl(dev, ctrl); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; - - } - - return -EINVAL; -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data, - struct v4l2_fmtdesc *f) -{ - - if (f->index != 0 || f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - f->flags = V4L2_FMT_FLAG_COMPRESSED; - strncpy(f->description, "MPEG2-TS with AVC/AAC streams", 32); - f->pixelformat = V4L2_PIX_FMT_MPEG; - - return 0; -} - -static int vidioc_g_fmt_vid_cap(struct file *file, void *private_data, - struct v4l2_format *f) -{ - struct hdpvr_fh *fh = file->private_data; - struct hdpvr_device *dev = fh->dev; - struct hdpvr_video_info *vid_info; - - if (!dev) - return -ENODEV; - - vid_info = get_video_info(dev); - if (!vid_info) - return -EFAULT; - - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.width = vid_info->width; - f->fmt.pix.height = vid_info->height; - f->fmt.pix.sizeimage = dev->bulk_in_size; - f->fmt.pix.colorspace = 0; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.field = V4L2_FIELD_ANY; - - kfree(vid_info); - return 0; -} - -static int vidioc_encoder_cmd(struct file *filp, void *priv, - struct v4l2_encoder_cmd *a) -{ - struct hdpvr_fh *fh = filp->private_data; - struct hdpvr_device *dev = fh->dev; - int res; - - mutex_lock(&dev->io_mutex); - - memset(&a->raw, 0, sizeof(a->raw)); - switch (a->cmd) { - case V4L2_ENC_CMD_START: - a->flags = 0; - res = hdpvr_start_streaming(dev); - break; - case V4L2_ENC_CMD_STOP: - res = hdpvr_stop_streaming(dev); - break; - default: - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "Unsupported encoder cmd %d\n", a->cmd); - res = -EINVAL; - } - mutex_unlock(&dev->io_mutex); - return res; -} - -static int vidioc_try_encoder_cmd(struct file *filp, void *priv, - struct v4l2_encoder_cmd *a) -{ - switch (a->cmd) { - case V4L2_ENC_CMD_START: - case V4L2_ENC_CMD_STOP: - return 0; - default: - return -EINVAL; - } -} - -static const struct v4l2_ioctl_ops hdpvr_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_s_std = vidioc_s_std, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_enumaudio = vidioc_enumaudio, - .vidioc_g_audio = vidioc_g_audio, - .vidioc_s_audio = vidioc_s_audio, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, - .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, - .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_encoder_cmd = vidioc_encoder_cmd, - .vidioc_try_encoder_cmd = vidioc_try_encoder_cmd, -}; - -static void hdpvr_device_release(struct video_device *vdev) -{ - struct hdpvr_device *dev = video_get_drvdata(vdev); - - hdpvr_delete(dev); -} - -static const struct video_device hdpvr_video_template = { -/* .type = VFL_TYPE_GRABBER, */ -/* .type2 = VID_TYPE_CAPTURE | VID_TYPE_MPEG_ENCODER, */ - .fops = &hdpvr_fops, - .release = hdpvr_device_release, - .ioctl_ops = &hdpvr_ioctl_ops, - .tvnorms = - V4L2_STD_NTSC | V4L2_STD_SECAM | V4L2_STD_PAL_B | - V4L2_STD_PAL_G | V4L2_STD_PAL_H | V4L2_STD_PAL_I | - V4L2_STD_PAL_D | V4L2_STD_PAL_M | V4L2_STD_PAL_N | - V4L2_STD_PAL_60, -}; - -int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent, - int devnum) -{ - /* setup and register video device */ - dev->video_dev = video_device_alloc(); - if (!dev->video_dev) { - v4l2_err(&dev->v4l2_dev, "video_device_alloc() failed\n"); - goto error; - } - - *(dev->video_dev) = hdpvr_video_template; - strcpy(dev->video_dev->name, "Hauppauge HD PVR"); - dev->video_dev->parent = parent; - video_set_drvdata(dev->video_dev, dev); - - if (video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum)) { - v4l2_err(&dev->v4l2_dev, "video_device registration failed\n"); - goto error; - } - - return 0; -error: - return -ENOMEM; -} diff --git a/trunk/drivers/media/video/hdpvr/hdpvr.h b/trunk/drivers/media/video/hdpvr/hdpvr.h deleted file mode 100644 index 1edd8759121e..000000000000 --- a/trunk/drivers/media/video/hdpvr/hdpvr.h +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Hauppauge HD PVR USB driver - * - * Copyright (C) 2008 Janne Grunau (j@jannau.net) - * - * 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. - * - */ - -#include -#include -#include -#include -#include - -#include - -#define HDPVR_MAJOR_VERSION 0 -#define HDPVR_MINOR_VERSION 2 -#define HDPVR_RELEASE 0 -#define HDPVR_VERSION \ - KERNEL_VERSION(HDPVR_MAJOR_VERSION, HDPVR_MINOR_VERSION, HDPVR_RELEASE) - -#define HDPVR_MAX 8 - -/* Define these values to match your devices */ -#define HD_PVR_VENDOR_ID 0x2040 -#define HD_PVR_PRODUCT_ID 0x4900 -#define HD_PVR_PRODUCT_ID1 0x4901 -#define HD_PVR_PRODUCT_ID2 0x4902 - -#define UNSET (-1U) - -#define NUM_BUFFERS 64 - -#define HDPVR_FIRMWARE_VERSION 0x8 -#define HDPVR_FIRMWARE_VERSION_AC3 0xd - -/* #define HDPVR_DEBUG */ - -extern int hdpvr_debug; - -#define MSG_INFO 1 -#define MSG_BUFFER 2 - -struct hdpvr_options { - u8 video_std; - u8 video_input; - u8 audio_input; - u8 bitrate; /* in 100kbps */ - u8 peak_bitrate; /* in 100kbps */ - u8 bitrate_mode; - u8 gop_mode; - enum v4l2_mpeg_audio_encoding audio_codec; - u8 brightness; - u8 contrast; - u8 hue; - u8 saturation; - u8 sharpness; -}; - -/* Structure to hold all of our device specific stuff */ -struct hdpvr_device { - /* the v4l device for this device */ - struct video_device *video_dev; - /* the usb device for this device */ - struct usb_device *udev; - /* v4l2-device unused */ - struct v4l2_device v4l2_dev; - - /* the max packet size of the bulk endpoint */ - size_t bulk_in_size; - /* the address of the bulk in endpoint */ - __u8 bulk_in_endpointAddr; - - /* holds the current device status */ - __u8 status; - /* count the number of openers */ - uint open_count; - - /* holds the cureent set options */ - struct hdpvr_options options; - - uint flags; - - /* synchronize I/O */ - struct mutex io_mutex; - /* available buffers */ - struct list_head free_buff_list; - /* in progress buffers */ - struct list_head rec_buff_list; - /* waitqueue for buffers */ - wait_queue_head_t wait_buffer; - /* waitqueue for data */ - wait_queue_head_t wait_data; - /**/ - struct workqueue_struct *workqueue; - /**/ - struct work_struct worker; - - /* I2C adapter */ - struct i2c_adapter *i2c_adapter; - /* I2C lock */ - struct mutex i2c_mutex; - - /* usb control transfer buffer and lock */ - struct mutex usbc_mutex; - u8 *usbc_buf; -}; - - -/* buffer one bulk urb of data */ -struct hdpvr_buffer { - struct list_head buff_list; - - struct urb *urb; - - struct hdpvr_device *dev; - - uint pos; - - __u8 status; -}; - -/* */ - -struct hdpvr_video_info { - u16 width; - u16 height; - u8 fps; -}; - -enum { - STATUS_UNINITIALIZED = 0, - STATUS_IDLE, - STATUS_STARTING, - STATUS_SHUTTING_DOWN, - STATUS_STREAMING, - STATUS_ERROR, - STATUS_DISCONNECTED, -}; - -enum { - HDPVR_FLAG_AC3_CAP = 1, -}; - -enum { - BUFSTAT_UNINITIALIZED = 0, - BUFSTAT_AVAILABLE, - BUFSTAT_INPROGRESS, - BUFSTAT_READY, -}; - -#define CTRL_START_STREAMING_VALUE 0x0700 -#define CTRL_STOP_STREAMING_VALUE 0x0800 -#define CTRL_BITRATE_VALUE 0x1000 -#define CTRL_BITRATE_MODE_VALUE 0x1200 -#define CTRL_GOP_MODE_VALUE 0x1300 -#define CTRL_VIDEO_INPUT_VALUE 0x1500 -#define CTRL_VIDEO_STD_TYPE 0x1700 -#define CTRL_AUDIO_INPUT_VALUE 0x2500 -#define CTRL_BRIGHTNESS 0x2900 -#define CTRL_CONTRAST 0x2a00 -#define CTRL_HUE 0x2b00 -#define CTRL_SATURATION 0x2c00 -#define CTRL_SHARPNESS 0x2d00 -#define CTRL_LOW_PASS_FILTER_VALUE 0x3100 - -#define CTRL_DEFAULT_INDEX 0x0003 - - - /* :0 s 38 01 1000 0003 0004 4 = 0a00ca00 - * BITRATE SETTING - * 1st and 2nd byte (little endian): average bitrate in 100 000 bit/s - * min: 1 mbit/s, max: 13.5 mbit/s - * 3rd and 4th byte (little endian): peak bitrate in 100 000 bit/s - * min: average + 100kbit/s, - * max: 20.2 mbit/s - */ - - /* :0 s 38 01 1200 0003 0001 1 = 02 - * BIT RATE MODE - * constant = 1, variable (peak) = 2, variable (average) = 3 - */ - - /* :0 s 38 01 1300 0003 0001 1 = 03 - * GOP MODE (2 bit) - * low bit 0/1: advanced/simple GOP - * high bit 0/1: IDR(4/32/128) / no IDR (4/32/0) - */ - - /* :0 s 38 01 1700 0003 0001 1 = 00 - * VIDEO STANDARD or FREQUNCY 0 = 60hz, 1 = 50hz - */ - - /* :0 s 38 01 3100 0003 0004 4 = 03030000 - * FILTER CONTROL - * 1st byte luma low pass filter strength, - * 2nd byte chroma low pass filter strength, - * 3rd byte MF enable chroma, min=0, max=1 - * 4th byte n - */ - - - /* :0 s 38 b9 0001 0000 0000 0 */ - - - -/* :0 s 38 d3 0000 0000 0001 1 = 00 */ -/* ret = usb_control_msg(dev->udev, */ -/* usb_sndctrlpipe(dev->udev, 0), */ -/* 0xd3, 0x38, */ -/* 0, 0, */ -/* "\0", 1, */ -/* 1000); */ - -/* info("control request returned %d", ret); */ -/* msleep(5000); */ - - - /* :0 s b8 81 1400 0003 0005 5 < - * :0 0 5 = d0024002 19 - * QUERY FRAME SIZE AND RATE - * 1st and 2nd byte (little endian): horizontal resolution - * 3rd and 4th byte (little endian): vertical resolution - * 5th byte: frame rate - */ - - /* :0 s b8 81 1800 0003 0003 3 < - * :0 0 3 = 030104 - * QUERY SIGNAL AND DETECTED LINES, maybe INPUT - */ - -enum hdpvr_video_std { - HDPVR_60HZ = 0, - HDPVR_50HZ, -}; - -enum hdpvr_video_input { - HDPVR_COMPONENT = 0, - HDPVR_SVIDEO, - HDPVR_COMPOSITE, - HDPVR_VIDEO_INPUTS -}; - -enum hdpvr_audio_inputs { - HDPVR_RCA_BACK = 0, - HDPVR_RCA_FRONT, - HDPVR_SPDIF, - HDPVR_AUDIO_INPUTS -}; - -enum hdpvr_bitrate_mode { - HDPVR_CONSTANT = 1, - HDPVR_VARIABLE_PEAK, - HDPVR_VARIABLE_AVERAGE, -}; - -enum hdpvr_gop_mode { - HDPVR_ADVANCED_IDR_GOP = 0, - HDPVR_SIMPLE_IDR_GOP, - HDPVR_ADVANCED_NOIDR_GOP, - HDPVR_SIMPLE_NOIDR_GOP, -}; - -void hdpvr_delete(struct hdpvr_device *dev); - -/*========================================================================*/ -/* hardware control functions */ -int hdpvr_set_options(struct hdpvr_device *dev); - -int hdpvr_set_bitrate(struct hdpvr_device *dev); - -int hdpvr_set_audio(struct hdpvr_device *dev, u8 input, - enum v4l2_mpeg_audio_encoding codec); - -int hdpvr_config_call(struct hdpvr_device *dev, uint value, - unsigned char valbuf); - -struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev); - -/* :0 s b8 81 1800 0003 0003 3 < */ -/* :0 0 3 = 0301ff */ -int get_input_lines_info(struct hdpvr_device *dev); - - -/*========================================================================*/ -/* v4l2 registration */ -int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent, - int devnumber); - -int hdpvr_cancel_queue(struct hdpvr_device *dev); - -/*========================================================================*/ -/* i2c adapter registration */ -int hdpvr_register_i2c_adapter(struct hdpvr_device *dev); - -/*========================================================================*/ -/* buffer management */ -int hdpvr_free_buffers(struct hdpvr_device *dev); -int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count); diff --git a/trunk/drivers/media/video/hexium_gemini.c b/trunk/drivers/media/video/hexium_gemini.c index 8e1463ee1b64..79393d1772e4 100644 --- a/trunk/drivers/media/video/hexium_gemini.c +++ b/trunk/drivers/media/video/hexium_gemini.c @@ -56,6 +56,17 @@ struct hexium_data u8 byte; }; +static struct saa7146_extension_ioctls ioctls[] = { + { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_QUERYCTRL, SAA7146_BEFORE }, + { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_S_STD, SAA7146_AFTER }, + { VIDIOC_G_CTRL, SAA7146_BEFORE }, + { VIDIOC_S_CTRL, SAA7146_BEFORE }, + { 0, 0 } +}; + #define HEXIUM_CONTROLS 1 static struct v4l2_queryctrl hexium_controls[] = { { V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 }, @@ -220,132 +231,6 @@ static int hexium_set_standard(struct hexium *hexium, struct hexium_data *vdec) return 0; } -static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) -{ - DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); - - if (i->index < 0 || i->index >= HEXIUM_INPUTS) - return -EINVAL; - - memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); - - DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index)); - return 0; -} - -static int vidioc_g_input(struct file *file, void *fh, unsigned int *input) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct hexium *hexium = (struct hexium *) dev->ext_priv; - - *input = hexium->cur_input; - - DEB_D(("VIDIOC_G_INPUT: %d\n", *input)); - return 0; -} - -static int vidioc_s_input(struct file *file, void *fh, unsigned int input) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct hexium *hexium = (struct hexium *) dev->ext_priv; - - DEB_EE(("VIDIOC_S_INPUT %d.\n", input)); - - if (input < 0 || input >= HEXIUM_INPUTS) - return -EINVAL; - - hexium->cur_input = input; - hexium_set_input(hexium, input); - return 0; -} - -/* the saa7146 provides some controls (brightness, contrast, saturation) - which gets registered *after* this function. because of this we have - to return with a value != 0 even if the function succeded.. */ -static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - int i; - - for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) { - if (hexium_controls[i].id == qc->id) { - *qc = hexium_controls[i]; - DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id)); - return 0; - } - } - return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc); -} - -static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct hexium *hexium = (struct hexium *) dev->ext_priv; - int i; - - for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) { - if (hexium_controls[i].id == vc->id) - break; - } - - if (i < 0) - return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc); - - if (vc->id == V4L2_CID_PRIVATE_BASE) { - vc->value = hexium->cur_bw; - DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value)); - return 0; - } - return -EINVAL; -} - -static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct hexium *hexium = (struct hexium *) dev->ext_priv; - int i = 0; - - for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) { - if (hexium_controls[i].id == vc->id) - break; - } - - if (i < 0) - return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc); - - if (vc->id == V4L2_CID_PRIVATE_BASE) - hexium->cur_bw = vc->value; - - DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw)); - - if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) { - hexium_set_standard(hexium, hexium_pal); - return 0; - } - if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) { - hexium_set_standard(hexium, hexium_ntsc); - return 0; - } - if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) { - hexium_set_standard(hexium, hexium_secam); - return 0; - } - if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) { - hexium_set_standard(hexium, hexium_pal_bw); - return 0; - } - if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) { - hexium_set_standard(hexium, hexium_ntsc_bw); - return 0; - } - if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) - /* fixme: is there no bw secam mode? */ - return -EINVAL; - - return -EINVAL; -} - - static struct saa7146_ext_vv vv_data; /* this function only gets called when the probing was successful */ @@ -394,12 +279,6 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d hexium->cur_input = 0; saa7146_vv_init(dev, &vv_data); - vv_data.ops.vidioc_queryctrl = vidioc_queryctrl; - vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl; - vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl; - vv_data.ops.vidioc_enum_input = vidioc_enum_input; - vv_data.ops.vidioc_g_input = vidioc_g_input; - vv_data.ops.vidioc_s_input = vidioc_s_input; if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) { printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n"); return -1; @@ -427,6 +306,153 @@ static int hexium_detach(struct saa7146_dev *dev) return 0; } +static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) +{ + struct saa7146_dev *dev = fh->dev; + struct hexium *hexium = (struct hexium *) dev->ext_priv; +/* + struct saa7146_vv *vv = dev->vv_data; +*/ + switch (cmd) { + case VIDIOC_ENUMINPUT: + { + struct v4l2_input *i = arg; + DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); + + if (i->index < 0 || i->index >= HEXIUM_INPUTS) { + return -EINVAL; + } + + memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); + + DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index)); + return 0; + } + case VIDIOC_G_INPUT: + { + int *input = (int *) arg; + *input = hexium->cur_input; + + DEB_D(("VIDIOC_G_INPUT: %d\n", *input)); + return 0; + } + case VIDIOC_S_INPUT: + { + int input = *(int *) arg; + + DEB_EE(("VIDIOC_S_INPUT %d.\n", input)); + + if (input < 0 || input >= HEXIUM_INPUTS) { + return -EINVAL; + } + + hexium->cur_input = input; + hexium_set_input(hexium, input); + + return 0; + } + /* the saa7146 provides some controls (brightness, contrast, saturation) + which gets registered *after* this function. because of this we have + to return with a value != 0 even if the function succeded.. */ + case VIDIOC_QUERYCTRL: + { + struct v4l2_queryctrl *qc = arg; + int i; + + for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) { + if (hexium_controls[i].id == qc->id) { + *qc = hexium_controls[i]; + DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id)); + return 0; + } + } + return -EAGAIN; + } + case VIDIOC_G_CTRL: + { + struct v4l2_control *vc = arg; + int i; + + for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) { + if (hexium_controls[i].id == vc->id) { + break; + } + } + + if (i < 0) { + return -EAGAIN; + } + + switch (vc->id) { + case V4L2_CID_PRIVATE_BASE:{ + vc->value = hexium->cur_bw; + DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value)); + return 0; + } + } + return -EINVAL; + } + + case VIDIOC_S_CTRL: + { + struct v4l2_control *vc = arg; + int i = 0; + + for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) { + if (hexium_controls[i].id == vc->id) { + break; + } + } + + if (i < 0) { + return -EAGAIN; + } + + switch (vc->id) { + case V4L2_CID_PRIVATE_BASE:{ + hexium->cur_bw = vc->value; + break; + } + } + + DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw)); + + if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) { + hexium_set_standard(hexium, hexium_pal); + return 0; + } + if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) { + hexium_set_standard(hexium, hexium_ntsc); + return 0; + } + if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) { + hexium_set_standard(hexium, hexium_secam); + return 0; + } + if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) { + hexium_set_standard(hexium, hexium_pal_bw); + return 0; + } + if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) { + hexium_set_standard(hexium, hexium_ntsc_bw); + return 0; + } + if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) { + /* fixme: is there no bw secam mode? */ + return -EINVAL; + } + + return -EINVAL; + } + default: +/* + DEB_D(("hexium_ioctl() does not handle this ioctl.\n")); +*/ + return -ENOIOCTLCMD; + } + return 0; +} + static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std) { struct hexium *hexium = (struct hexium *) dev->ext_priv; @@ -488,6 +514,8 @@ static struct saa7146_ext_vv vv_data = { .stds = &hexium_standards[0], .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard), .std_callback = &std_callback, + .ioctls = &ioctls[0], + .ioctl = hexium_ioctl, }; static struct saa7146_extension hexium_extension = { diff --git a/trunk/drivers/media/video/hexium_orion.c b/trunk/drivers/media/video/hexium_orion.c index 2bc39f628455..074bec711fe0 100644 --- a/trunk/drivers/media/video/hexium_orion.c +++ b/trunk/drivers/media/video/hexium_orion.c @@ -57,6 +57,14 @@ struct hexium_data u8 byte; }; +static struct saa7146_extension_ioctls ioctls[] = { + { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_S_STD, SAA7146_AFTER }, + { 0, 0 } +}; + struct hexium { int type; @@ -321,44 +329,6 @@ static int hexium_set_input(struct hexium *hexium, int input) return 0; } -static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) -{ - DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); - - if (i->index < 0 || i->index >= HEXIUM_INPUTS) - return -EINVAL; - - memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); - - DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index)); - return 0; -} - -static int vidioc_g_input(struct file *file, void *fh, unsigned int *input) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct hexium *hexium = (struct hexium *) dev->ext_priv; - - *input = hexium->cur_input; - - DEB_D(("VIDIOC_G_INPUT: %d\n", *input)); - return 0; -} - -static int vidioc_s_input(struct file *file, void *fh, unsigned int input) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct hexium *hexium = (struct hexium *) dev->ext_priv; - - if (input < 0 || input >= HEXIUM_INPUTS) - return -EINVAL; - - hexium->cur_input = input; - hexium_set_input(hexium, input); - - return 0; -} - static struct saa7146_ext_vv vv_data; /* this function only gets called when the probing was successful */ @@ -369,9 +339,6 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d DEB_EE((".\n")); saa7146_vv_init(dev, &vv_data); - vv_data.ops.vidioc_enum_input = vidioc_enum_input; - vv_data.ops.vidioc_g_input = vidioc_g_input; - vv_data.ops.vidioc_s_input = vidioc_s_input; if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) { printk("hexium_orion: cannot register capture v4l2 device. skipping.\n"); return -1; @@ -403,6 +370,58 @@ static int hexium_detach(struct saa7146_dev *dev) return 0; } +static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) +{ + struct saa7146_dev *dev = fh->dev; + struct hexium *hexium = (struct hexium *) dev->ext_priv; +/* + struct saa7146_vv *vv = dev->vv_data; +*/ + switch (cmd) { + case VIDIOC_ENUMINPUT: + { + struct v4l2_input *i = arg; + DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); + + if (i->index < 0 || i->index >= HEXIUM_INPUTS) { + return -EINVAL; + } + + memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); + + DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index)); + return 0; + } + case VIDIOC_G_INPUT: + { + int *input = (int *) arg; + *input = hexium->cur_input; + + DEB_D(("VIDIOC_G_INPUT: %d\n", *input)); + return 0; + } + case VIDIOC_S_INPUT: + { + int input = *(int *) arg; + + if (input < 0 || input >= HEXIUM_INPUTS) { + return -EINVAL; + } + + hexium->cur_input = input; + hexium_set_input(hexium, input); + + return 0; + } + default: +/* + DEB_D(("hexium_ioctl() does not handle this ioctl.\n")); +*/ + return -ENOIOCTLCMD; + } + return 0; +} + static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std) { return 0; @@ -460,6 +479,8 @@ static struct saa7146_ext_vv vv_data = { .stds = &hexium_standards[0], .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard), .std_callback = &std_callback, + .ioctls = &ioctls[0], + .ioctl = hexium_ioctl, }; static struct saa7146_extension extension = { diff --git a/trunk/drivers/media/video/indycam.c b/trunk/drivers/media/video/indycam.c index 3d6940163b12..84b9e4f2b3b3 100644 --- a/trunk/drivers/media/video/indycam.c +++ b/trunk/drivers/media/video/indycam.c @@ -19,12 +19,10 @@ #include #include +#include /* IndyCam decodes stream of photons into digital image representation ;-) */ -#include +#include #include -#include -#include -#include #include "indycam.h" @@ -35,7 +33,6 @@ MODULE_VERSION(INDYCAM_MODULE_VERSION); MODULE_AUTHOR("Mikael Nousiainen "); MODULE_LICENSE("GPL"); - // #define INDYCAM_DEBUG #ifdef INDYCAM_DEBUG @@ -47,14 +44,11 @@ MODULE_LICENSE("GPL"); #endif struct indycam { - struct v4l2_subdev sd; + struct i2c_client *client; u8 version; }; -static inline struct indycam *to_indycam(struct v4l2_subdev *sd) -{ - return container_of(sd, struct indycam, sd); -} +static struct i2c_driver i2c_driver_indycam; static const u8 initseq[] = { INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */ @@ -69,9 +63,8 @@ static const u8 initseq[] = { /* IndyCam register handling */ -static int indycam_read_reg(struct v4l2_subdev *sd, u8 reg, u8 *value) +static int indycam_read_reg(struct i2c_client *client, u8 reg, u8 *value) { - struct i2c_client *client = v4l2_get_subdevdata(sd); int ret; if (reg == INDYCAM_REG_RESET) { @@ -94,12 +87,12 @@ static int indycam_read_reg(struct v4l2_subdev *sd, u8 reg, u8 *value) return 0; } -static int indycam_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value) +static int indycam_write_reg(struct i2c_client *client, u8 reg, u8 value) { - struct i2c_client *client = v4l2_get_subdevdata(sd); int err; - if (reg == INDYCAM_REG_BRIGHTNESS || reg == INDYCAM_REG_VERSION) { + if ((reg == INDYCAM_REG_BRIGHTNESS) + || (reg == INDYCAM_REG_VERSION)) { dprintk("indycam_write_reg(): " "skipping read-only register %d\n", reg); return 0; @@ -115,13 +108,13 @@ static int indycam_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value) return err; } -static int indycam_write_block(struct v4l2_subdev *sd, u8 reg, +static int indycam_write_block(struct i2c_client *client, u8 reg, u8 length, u8 *data) { int i, err; for (i = 0; i < length; i++) { - err = indycam_write_reg(sd, reg + i, data[i]); + err = indycam_write_reg(client, reg + i, data[i]); if (err) return err; } @@ -132,78 +125,79 @@ static int indycam_write_block(struct v4l2_subdev *sd, u8 reg, /* Helper functions */ #ifdef INDYCAM_DEBUG -static void indycam_regdump_debug(struct v4l2_subdev *sd) +static void indycam_regdump_debug(struct i2c_client *client) { int i; u8 val; for (i = 0; i < 9; i++) { - indycam_read_reg(sd, i, &val); + indycam_read_reg(client, i, &val); dprintk("Reg %d = 0x%02x\n", i, val); } } #endif -static int indycam_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static int indycam_get_control(struct i2c_client *client, + struct indycam_control *ctrl) { - struct indycam *camera = to_indycam(sd); + struct indycam *camera = i2c_get_clientdata(client); u8 reg; int ret = 0; - switch (ctrl->id) { - case V4L2_CID_AUTOGAIN: - case V4L2_CID_AUTO_WHITE_BALANCE: - ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, ®); + switch (ctrl->type) { + case INDYCAM_CONTROL_AGC: + case INDYCAM_CONTROL_AWB: + ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, ®); if (ret) return -EIO; - if (ctrl->id == V4L2_CID_AUTOGAIN) + if (ctrl->type == INDYCAM_CONTROL_AGC) ctrl->value = (reg & INDYCAM_CONTROL_AGCENA) ? 1 : 0; else ctrl->value = (reg & INDYCAM_CONTROL_AWBCTL) ? 1 : 0; break; - case V4L2_CID_EXPOSURE: - ret = indycam_read_reg(sd, INDYCAM_REG_SHUTTER, ®); + case INDYCAM_CONTROL_SHUTTER: + ret = indycam_read_reg(client, INDYCAM_REG_SHUTTER, ®); if (ret) return -EIO; ctrl->value = ((s32)reg == 0x00) ? 0xff : ((s32)reg - 1); break; - case V4L2_CID_GAIN: - ret = indycam_read_reg(sd, INDYCAM_REG_GAIN, ®); + case INDYCAM_CONTROL_GAIN: + ret = indycam_read_reg(client, INDYCAM_REG_GAIN, ®); if (ret) return -EIO; ctrl->value = (s32)reg; break; - case V4L2_CID_RED_BALANCE: - ret = indycam_read_reg(sd, INDYCAM_REG_RED_BALANCE, ®); + case INDYCAM_CONTROL_RED_BALANCE: + ret = indycam_read_reg(client, INDYCAM_REG_RED_BALANCE, ®); if (ret) return -EIO; ctrl->value = (s32)reg; break; - case V4L2_CID_BLUE_BALANCE: - ret = indycam_read_reg(sd, INDYCAM_REG_BLUE_BALANCE, ®); + case INDYCAM_CONTROL_BLUE_BALANCE: + ret = indycam_read_reg(client, INDYCAM_REG_BLUE_BALANCE, ®); if (ret) return -EIO; ctrl->value = (s32)reg; break; case INDYCAM_CONTROL_RED_SATURATION: - ret = indycam_read_reg(sd, + ret = indycam_read_reg(client, INDYCAM_REG_RED_SATURATION, ®); if (ret) return -EIO; ctrl->value = (s32)reg; break; case INDYCAM_CONTROL_BLUE_SATURATION: - ret = indycam_read_reg(sd, + ret = indycam_read_reg(client, INDYCAM_REG_BLUE_SATURATION, ®); if (ret) return -EIO; ctrl->value = (s32)reg; break; - case V4L2_CID_GAMMA: + case INDYCAM_CONTROL_GAMMA: if (camera->version == CAMERA_VERSION_MOOSE) { - ret = indycam_read_reg(sd, + ret = indycam_read_reg(client, INDYCAM_REG_GAMMA, ®); if (ret) return -EIO; @@ -219,20 +213,21 @@ static int indycam_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) return ret; } -static int indycam_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static int indycam_set_control(struct i2c_client *client, + struct indycam_control *ctrl) { - struct indycam *camera = to_indycam(sd); + struct indycam *camera = i2c_get_clientdata(client); u8 reg; int ret = 0; - switch (ctrl->id) { - case V4L2_CID_AUTOGAIN: - case V4L2_CID_AUTO_WHITE_BALANCE: - ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, ®); + switch (ctrl->type) { + case INDYCAM_CONTROL_AGC: + case INDYCAM_CONTROL_AWB: + ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, ®); if (ret) break; - if (ctrl->id == V4L2_CID_AUTOGAIN) { + if (ctrl->type == INDYCAM_CONTROL_AGC) { if (ctrl->value) reg |= INDYCAM_CONTROL_AGCENA; else @@ -244,34 +239,34 @@ static int indycam_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) reg &= ~INDYCAM_CONTROL_AWBCTL; } - ret = indycam_write_reg(sd, INDYCAM_REG_CONTROL, reg); + ret = indycam_write_reg(client, INDYCAM_REG_CONTROL, reg); break; - case V4L2_CID_EXPOSURE: + case INDYCAM_CONTROL_SHUTTER: reg = (ctrl->value == 0xff) ? 0x00 : (ctrl->value + 1); - ret = indycam_write_reg(sd, INDYCAM_REG_SHUTTER, reg); + ret = indycam_write_reg(client, INDYCAM_REG_SHUTTER, reg); break; - case V4L2_CID_GAIN: - ret = indycam_write_reg(sd, INDYCAM_REG_GAIN, ctrl->value); + case INDYCAM_CONTROL_GAIN: + ret = indycam_write_reg(client, INDYCAM_REG_GAIN, ctrl->value); break; - case V4L2_CID_RED_BALANCE: - ret = indycam_write_reg(sd, INDYCAM_REG_RED_BALANCE, + case INDYCAM_CONTROL_RED_BALANCE: + ret = indycam_write_reg(client, INDYCAM_REG_RED_BALANCE, ctrl->value); break; - case V4L2_CID_BLUE_BALANCE: - ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_BALANCE, + case INDYCAM_CONTROL_BLUE_BALANCE: + ret = indycam_write_reg(client, INDYCAM_REG_BLUE_BALANCE, ctrl->value); break; case INDYCAM_CONTROL_RED_SATURATION: - ret = indycam_write_reg(sd, INDYCAM_REG_RED_SATURATION, + ret = indycam_write_reg(client, INDYCAM_REG_RED_SATURATION, ctrl->value); break; case INDYCAM_CONTROL_BLUE_SATURATION: - ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_SATURATION, + ret = indycam_write_reg(client, INDYCAM_REG_BLUE_SATURATION, ctrl->value); break; - case V4L2_CID_GAMMA: + case INDYCAM_CONTROL_GAMMA: if (camera->version == CAMERA_VERSION_MOOSE) { - ret = indycam_write_reg(sd, INDYCAM_REG_GAMMA, + ret = indycam_write_reg(client, INDYCAM_REG_GAMMA, ctrl->value); } break; @@ -284,103 +279,192 @@ static int indycam_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) /* I2C-interface */ -static int indycam_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *chip) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct indycam *camera = to_indycam(sd); - - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_INDYCAM, - camera->version); -} - -/* ----------------------------------------------------------------------- */ - -static const struct v4l2_subdev_core_ops indycam_core_ops = { - .g_chip_ident = indycam_g_chip_ident, - .g_ctrl = indycam_g_ctrl, - .s_ctrl = indycam_s_ctrl, -}; - -static const struct v4l2_subdev_ops indycam_ops = { - .core = &indycam_core_ops, -}; - -static int indycam_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int indycam_attach(struct i2c_adapter *adap, int addr, int kind) { int err = 0; struct indycam *camera; - struct v4l2_subdev *sd; + struct i2c_client *client; - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); + printk(KERN_INFO "SGI IndyCam driver version %s\n", + INDYCAM_MODULE_VERSION); - camera = kzalloc(sizeof(struct indycam), GFP_KERNEL); - if (!camera) + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) return -ENOMEM; + camera = kzalloc(sizeof(struct indycam), GFP_KERNEL); + if (!camera) { + err = -ENOMEM; + goto out_free_client; + } + + client->addr = addr; + client->adapter = adap; + client->driver = &i2c_driver_indycam; + client->flags = 0; + strcpy(client->name, "IndyCam client"); + i2c_set_clientdata(client, camera); - sd = &camera->sd; - v4l2_i2c_subdev_init(sd, client, &indycam_ops); + camera->client = client; + + err = i2c_attach_client(client); + if (err) + goto out_free_camera; camera->version = i2c_smbus_read_byte_data(client, INDYCAM_REG_VERSION); if (camera->version != CAMERA_VERSION_INDY && camera->version != CAMERA_VERSION_MOOSE) { - kfree(camera); - return -ENODEV; + err = -ENODEV; + goto out_detach_client; } - printk(KERN_INFO "IndyCam v%d.%d detected\n", INDYCAM_VERSION_MAJOR(camera->version), INDYCAM_VERSION_MINOR(camera->version)); - indycam_regdump(sd); + indycam_regdump(client); // initialize - err = indycam_write_block(sd, 0, sizeof(initseq), (u8 *)&initseq); + err = indycam_write_block(client, 0, sizeof(initseq), (u8 *)&initseq); if (err) { printk(KERN_ERR "IndyCam initialization failed\n"); - kfree(camera); - return -EIO; + err = -EIO; + goto out_detach_client; } - indycam_regdump(sd); + indycam_regdump(client); // white balance - err = indycam_write_reg(sd, INDYCAM_REG_CONTROL, + err = indycam_write_reg(client, INDYCAM_REG_CONTROL, INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL); if (err) { printk(KERN_ERR "IndyCam: White balancing camera failed\n"); - kfree(camera); - return -EIO; + err = -EIO; + goto out_detach_client; } - indycam_regdump(sd); + indycam_regdump(client); printk(KERN_INFO "IndyCam initialized\n"); return 0; + +out_detach_client: + i2c_detach_client(client); +out_free_camera: + kfree(camera); +out_free_client: + kfree(client); + return err; } -static int indycam_remove(struct i2c_client *client) +static int indycam_probe(struct i2c_adapter *adap) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); + /* Indy specific crap */ + if (adap->id == I2C_HW_SGI_VINO) + return indycam_attach(adap, INDYCAM_ADDR, 0); + /* Feel free to add probe here :-) */ + return -ENODEV; +} + +static int indycam_detach(struct i2c_client *client) +{ + struct indycam *camera = i2c_get_clientdata(client); - v4l2_device_unregister_subdev(sd); - kfree(to_indycam(sd)); + i2c_detach_client(client); + kfree(camera); + kfree(client); return 0; } -static const struct i2c_device_id indycam_id[] = { - { "indycam", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, indycam_id); +static int indycam_command(struct i2c_client *client, unsigned int cmd, + void *arg) +{ + // struct indycam *camera = i2c_get_clientdata(client); + + /* The old video_decoder interface just isn't enough, + * so we'll use some custom commands. */ + switch (cmd) { + case DECODER_GET_CAPABILITIES: { + struct video_decoder_capability *cap = arg; -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "indycam", - .probe = indycam_probe, - .remove = indycam_remove, - .id_table = indycam_id, + cap->flags = VIDEO_DECODER_NTSC; + cap->inputs = 1; + cap->outputs = 1; + break; + } + case DECODER_GET_STATUS: { + int *iarg = arg; + + *iarg = DECODER_STATUS_GOOD | DECODER_STATUS_NTSC | + DECODER_STATUS_COLOR; + break; + } + case DECODER_SET_NORM: { + int *iarg = arg; + + switch (*iarg) { + case VIDEO_MODE_NTSC: + break; + default: + return -EINVAL; + } + break; + } + case DECODER_SET_INPUT: { + int *iarg = arg; + + if (*iarg != 0) + return -EINVAL; + break; + } + case DECODER_SET_OUTPUT: { + int *iarg = arg; + + if (*iarg != 0) + return -EINVAL; + break; + } + case DECODER_ENABLE_OUTPUT: { + /* Always enabled */ + break; + } + case DECODER_SET_PICTURE: { + // struct video_picture *pic = arg; + /* TODO: convert values for indycam_set_controls() */ + break; + } + case DECODER_INDYCAM_GET_CONTROL: { + return indycam_get_control(client, arg); + } + case DECODER_INDYCAM_SET_CONTROL: { + return indycam_set_control(client, arg); + } + default: + return -EINVAL; + } + + return 0; +} + +static struct i2c_driver i2c_driver_indycam = { + .driver = { + .name = "indycam", + }, + .id = I2C_DRIVERID_INDYCAM, + .attach_adapter = indycam_probe, + .detach_client = indycam_detach, + .command = indycam_command, }; + +static int __init indycam_init(void) +{ + return i2c_add_driver(&i2c_driver_indycam); +} + +static void __exit indycam_exit(void) +{ + i2c_del_driver(&i2c_driver_indycam); +} + +module_init(indycam_init); +module_exit(indycam_exit); diff --git a/trunk/drivers/media/video/indycam.h b/trunk/drivers/media/video/indycam.h index 881f21c474c4..e6ee82063ed8 100644 --- a/trunk/drivers/media/video/indycam.h +++ b/trunk/drivers/media/video/indycam.h @@ -87,7 +87,22 @@ /* Driver interface definitions */ -#define INDYCAM_CONTROL_RED_SATURATION (V4L2_CID_PRIVATE_BASE + 0) -#define INDYCAM_CONTROL_BLUE_SATURATION (V4L2_CID_PRIVATE_BASE + 1) +#define INDYCAM_CONTROL_AGC 0 /* boolean */ +#define INDYCAM_CONTROL_AWB 1 /* boolean */ +#define INDYCAM_CONTROL_SHUTTER 2 +#define INDYCAM_CONTROL_GAIN 3 +#define INDYCAM_CONTROL_RED_BALANCE 4 +#define INDYCAM_CONTROL_BLUE_BALANCE 5 +#define INDYCAM_CONTROL_RED_SATURATION 6 +#define INDYCAM_CONTROL_BLUE_SATURATION 7 +#define INDYCAM_CONTROL_GAMMA 8 + +struct indycam_control { + u8 type; + s32 value; +}; + +#define DECODER_INDYCAM_GET_CONTROL _IOR('d', 193, struct indycam_control) +#define DECODER_INDYCAM_SET_CONTROL _IOW('d', 194, struct indycam_control) #endif diff --git a/trunk/drivers/media/video/ir-kbd-i2c.c b/trunk/drivers/media/video/ir-kbd-i2c.c index 092c7da0f37a..d4658c56eddc 100644 --- a/trunk/drivers/media/video/ir-kbd-i2c.c +++ b/trunk/drivers/media/video/ir-kbd-i2c.c @@ -16,8 +16,6 @@ * Henry Wong * Mark Schultz * Brian Rogers - * modified for AVerMedia Cardbus by - * Oldrich Jedlicka * * 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 @@ -218,46 +216,6 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) return 1; } -static int get_key_avermedia_cardbus(struct IR_i2c *ir, - u32 *ir_key, u32 *ir_raw) -{ - unsigned char subaddr, key, keygroup; - struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0, - .buf = &subaddr, .len = 1}, - { .addr = ir->c.addr, .flags = I2C_M_RD, - .buf = &key, .len = 1} }; - subaddr = 0x0d; - if (2 != i2c_transfer(ir->c.adapter, msg, 2)) { - dprintk(1, "read error\n"); - return -EIO; - } - - if (key == 0xff) - return 0; - - subaddr = 0x0b; - msg[1].buf = &keygroup; - if (2 != i2c_transfer(ir->c.adapter, msg, 2)) { - dprintk(1, "read error\n"); - return -EIO; - } - - if (keygroup == 0xff) - return 0; - - dprintk(1, "read key 0x%02x/0x%02x\n", key, keygroup); - if (keygroup < 2 || keygroup > 3) { - /* Only a warning */ - dprintk(1, "warning: invalid key group 0x%02x for key 0x%02x\n", - keygroup, key); - } - key |= (keygroup & 1) << 6; - - *ir_key = key; - *ir_raw = key; - return 1; -} - /* ----------------------------------------------------------------------- */ static void ir_key_poll(struct IR_i2c *ir) @@ -279,9 +237,15 @@ static void ir_key_poll(struct IR_i2c *ir) } } +static void ir_timer(unsigned long data) +{ + struct IR_i2c *ir = (struct IR_i2c*)data; + schedule_work(&ir->work); +} + static void ir_work(struct work_struct *work) { - struct IR_i2c *ir = container_of(work, struct IR_i2c, work.work); + struct IR_i2c *ir = container_of(work, struct IR_i2c, work); int polling_interval = 100; /* MSI TV@nywhere Plus requires more frequent polling @@ -290,7 +254,7 @@ static void ir_work(struct work_struct *work) polling_interval = 50; ir_key_poll(ir); - schedule_delayed_work(&ir->work, msecs_to_jiffies(polling_interval)); + mod_timer(&ir->timer, jiffies + msecs_to_jiffies(polling_interval)); } /* ----------------------------------------------------------------------- */ @@ -396,12 +360,6 @@ static int ir_attach(struct i2c_adapter *adap, int addr, ir_type = IR_TYPE_OTHER; } break; - case 0x40: - name = "AVerMedia Cardbus remote"; - ir->get_key = get_key_avermedia_cardbus; - ir_type = IR_TYPE_OTHER; - ir_codes = ir_codes_avermedia_cardbus; - break; default: /* shouldn't happen */ printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr); @@ -446,8 +404,11 @@ static int ir_attach(struct i2c_adapter *adap, int addr, ir->input->name, ir->input->phys, adap->name); /* start polling via eventd */ - INIT_DELAYED_WORK(&ir->work, ir_work); - schedule_delayed_work(&ir->work, 0); + INIT_WORK(&ir->work, ir_work); + init_timer(&ir->timer); + ir->timer.function = ir_timer; + ir->timer.data = (unsigned long)ir; + schedule_work(&ir->work); return 0; @@ -464,7 +425,8 @@ static int ir_detach(struct i2c_client *client) struct IR_i2c *ir = i2c_get_clientdata(client); /* kill outstanding polls */ - cancel_delayed_work_sync(&ir->work); + del_timer_sync(&ir->timer); + flush_scheduled_work(); /* unregister devices */ input_unregister_device(ir->input); @@ -562,22 +524,6 @@ static int ir_probe(struct i2c_adapter *adap) ir_attach(adap, msg.addr, 0, 0); } - /* Special case for AVerMedia Cardbus remote */ - if (adap->id == I2C_HW_SAA7134) { - unsigned char subaddr, data; - struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0, - .buf = &subaddr, .len = 1}, - { .addr = 0x40, .flags = I2C_M_RD, - .buf = &data, .len = 1} }; - subaddr = 0x0d; - rc = i2c_transfer(adap, msg, 2); - dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n", - msg[0].addr, subaddr, adap->name, - (2 == rc) ? "yes" : "no"); - if (2 == rc) - ir_attach(adap, msg[0].addr, 0, 0); - } - return 0; } diff --git a/trunk/drivers/media/video/ivtv/ivtv-controls.c b/trunk/drivers/media/video/ivtv/ivtv-controls.c index 84995bcf4a75..62aa06f5d168 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-controls.c +++ b/trunk/drivers/media/video/ivtv/ivtv-controls.c @@ -26,7 +26,6 @@ #include "ivtv-mailbox.h" #include "ivtv-controls.h" -/* Must be sorted from low to high control ID! */ static const u32 user_ctrls[] = { V4L2_CID_USER_CLASS, V4L2_CID_BRIGHTNESS, diff --git a/trunk/drivers/media/video/ivtv/ivtv-driver.c b/trunk/drivers/media/video/ivtv/ivtv-driver.c index eca8bf92a225..c46c990987f9 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-driver.c +++ b/trunk/drivers/media/video/ivtv/ivtv-driver.c @@ -357,7 +357,7 @@ void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv) static void ivtv_process_eeprom(struct ivtv *itv) { struct tveeprom tv; - int pci_slot = PCI_SLOT(itv->pdev->devfn); + int pci_slot = PCI_SLOT(itv->dev->devfn); ivtv_read_eeprom(itv, &tv); @@ -604,7 +604,7 @@ static void ivtv_process_options(struct ivtv *itv) itv->std = ivtv_parse_std(itv); if (itv->std == 0 && tunertype >= 0) itv->std = tunertype ? V4L2_STD_MN : (V4L2_STD_ALL & ~V4L2_STD_MN); - itv->has_cx23415 = (itv->pdev->device == PCI_DEVICE_ID_IVTV15); + itv->has_cx23415 = (itv->dev->device == PCI_DEVICE_ID_IVTV15); chipname = itv->has_cx23415 ? "cx23415" : "cx23416"; if (itv->options.cardtype == -1) { IVTV_INFO("Ignore card (detected %s based chip)\n", chipname); @@ -617,9 +617,9 @@ static void ivtv_process_options(struct ivtv *itv) IVTV_ERR("Unknown user specified type, trying to autodetect card\n"); } if (itv->card == NULL) { - if (itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE || - itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 || - itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) { + if (itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE || + itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 || + itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) { itv->card = ivtv_get_card(itv->has_cx23415 ? IVTV_CARD_PVR_350 : IVTV_CARD_PVR_150); IVTV_INFO("Autodetected Hauppauge card (%s based)\n", chipname); @@ -630,13 +630,13 @@ static void ivtv_process_options(struct ivtv *itv) if (itv->card->pci_list == NULL) continue; for (j = 0; itv->card->pci_list[j].device; j++) { - if (itv->pdev->device != + if (itv->dev->device != itv->card->pci_list[j].device) continue; - if (itv->pdev->subsystem_vendor != + if (itv->dev->subsystem_vendor != itv->card->pci_list[j].subsystem_vendor) continue; - if (itv->pdev->subsystem_device != + if (itv->dev->subsystem_device != itv->card->pci_list[j].subsystem_device) continue; IVTV_INFO("Autodetected %s card (%s based)\n", @@ -650,9 +650,9 @@ static void ivtv_process_options(struct ivtv *itv) if (itv->card == NULL) { itv->card = ivtv_get_card(IVTV_CARD_PVR_150); IVTV_ERR("Unknown card: vendor/device: [%04x:%04x]\n", - itv->pdev->vendor, itv->pdev->device); + itv->dev->vendor, itv->dev->device); IVTV_ERR(" subsystem vendor/device: [%04x:%04x]\n", - itv->pdev->subsystem_vendor, itv->pdev->subsystem_device); + itv->dev->subsystem_vendor, itv->dev->subsystem_device); IVTV_ERR(" %s based\n", chipname); IVTV_ERR("Defaulting to %s card\n", itv->card->name); IVTV_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n"); @@ -671,7 +671,7 @@ static void ivtv_process_options(struct ivtv *itv) */ static int __devinit ivtv_init_struct1(struct ivtv *itv) { - itv->base_addr = pci_resource_start(itv->pdev, 0); + itv->base_addr = pci_resource_start(itv->dev, 0); itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */ itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */ @@ -682,7 +682,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) spin_lock_init(&itv->lock); spin_lock_init(&itv->dma_reg_lock); - itv->irq_work_queues = create_singlethread_workqueue(itv->v4l2_dev.name); + itv->irq_work_queues = create_singlethread_workqueue(itv->device.name); if (itv->irq_work_queues == NULL) { IVTV_ERR("Could not create ivtv workqueue\n"); return -1; @@ -766,7 +766,7 @@ static void __devinit ivtv_init_struct2(struct ivtv *itv) itv->audio_input = itv->card->video_inputs[i].audio_index; } -static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev, +static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev, const struct pci_device_id *pci_id) { u16 cmd; @@ -775,11 +775,11 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev, IVTV_DEBUG_INFO("Enabling pci device\n"); - if (pci_enable_device(pdev)) { + if (pci_enable_device(dev)) { IVTV_ERR("Can't enable device!\n"); return -EIO; } - if (pci_set_dma_mask(pdev, 0xffffffff)) { + if (pci_set_dma_mask(dev, 0xffffffff)) { IVTV_ERR("No suitable DMA available.\n"); return -EIO; } @@ -805,11 +805,11 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev, } /* Check for bus mastering */ - pci_read_config_word(pdev, PCI_COMMAND, &cmd); + pci_read_config_word(dev, PCI_COMMAND, &cmd); if (!(cmd & PCI_COMMAND_MASTER)) { IVTV_DEBUG_INFO("Attempting to enable Bus Mastering\n"); - pci_set_master(pdev); - pci_read_config_word(pdev, PCI_COMMAND, &cmd); + pci_set_master(dev); + pci_read_config_word(dev, PCI_COMMAND, &cmd); if (!(cmd & PCI_COMMAND_MASTER)) { IVTV_ERR("Bus Mastering is not enabled\n"); return -ENXIO; @@ -817,26 +817,26 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev, } IVTV_DEBUG_INFO("Bus Mastering Enabled.\n"); - pci_read_config_byte(pdev, PCI_CLASS_REVISION, &card_rev); - pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency); + pci_read_config_byte(dev, PCI_CLASS_REVISION, &card_rev); + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); if (pci_latency < 64 && ivtv_pci_latency) { IVTV_INFO("Unreasonably low latency timer, " "setting to 64 (was %d)\n", pci_latency); - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); - pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); } /* This config space value relates to DMA latencies. The default value 0x8080 is too low however and will lead to DMA errors. 0xffff is the max value which solves these problems. */ - pci_write_config_dword(pdev, 0x40, 0xffff); + pci_write_config_dword(dev, 0x40, 0xffff); IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, " "irq: %d, latency: %d, memory: 0x%lx\n", - pdev->device, card_rev, pdev->bus->number, - PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), - pdev->irq, pci_latency, (unsigned long)itv->base_addr); + itv->dev->device, card_rev, dev->bus->number, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), + itv->dev->irq, pci_latency, (unsigned long)itv->base_addr); return 0; } @@ -935,7 +935,7 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) } } -static int __devinit ivtv_probe(struct pci_dev *pdev, +static int __devinit ivtv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) { int retval = 0; @@ -945,17 +945,17 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, itv = kzalloc(sizeof(struct ivtv), GFP_ATOMIC); if (itv == NULL) return -ENOMEM; - itv->pdev = pdev; + itv->dev = dev; itv->instance = atomic_inc_return(&ivtv_instance) - 1; - retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev); + retval = v4l2_device_register(&dev->dev, &itv->device); if (retval) { kfree(itv); return retval; } /* "ivtv + PCI ID" is a bit of a mouthful, so use "ivtv + instance" instead. */ - snprintf(itv->v4l2_dev.name, sizeof(itv->v4l2_dev.name), + snprintf(itv->device.name, sizeof(itv->device.name), "ivtv%d", itv->instance); IVTV_INFO("Initializing card %d\n", itv->instance); @@ -972,11 +972,12 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr); /* PCI Device Setup */ - retval = ivtv_setup_pci(itv, pdev, pci_id); - if (retval == -EIO) - goto free_workqueue; - if (retval == -ENXIO) - goto free_mem; + if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) { + if (retval == -EIO) + goto free_workqueue; + else if (retval == -ENXIO) + goto free_mem; + } /* map io memory */ IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", @@ -1153,8 +1154,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, ivtv_set_irq_mask(itv, 0xffffffff); /* Register IRQ */ - retval = request_irq(itv->pdev->irq, ivtv_irq_handler, - IRQF_SHARED | IRQF_DISABLED, itv->v4l2_dev.name, (void *)itv); + retval = request_irq(itv->dev->irq, ivtv_irq_handler, + IRQF_SHARED | IRQF_DISABLED, itv->device.name, (void *)itv); if (retval) { IVTV_ERR("Failed to register irq %d\n", retval); goto free_i2c; @@ -1176,7 +1177,7 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, free_streams: ivtv_streams_cleanup(itv, 1); free_irq: - free_irq(itv->pdev->irq, (void *)itv); + free_irq(itv->dev->irq, (void *)itv); free_i2c: exit_ivtv_i2c(itv); free_io: @@ -1193,7 +1194,7 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, retval = -ENODEV; IVTV_ERR("Error %d on initialization\n", retval); - v4l2_device_unregister(&itv->v4l2_dev); + v4l2_device_unregister(&itv->device); kfree(itv); return retval; } @@ -1291,10 +1292,10 @@ int ivtv_init_on_first_open(struct ivtv *itv) return 0; } -static void ivtv_remove(struct pci_dev *pdev) +static void ivtv_remove(struct pci_dev *pci_dev) { - struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); - struct ivtv *itv = to_ivtv(v4l2_dev); + struct v4l2_device *dev = dev_get_drvdata(&pci_dev->dev); + struct ivtv *itv = to_ivtv(dev); int i; IVTV_DEBUG_INFO("Removing card\n"); @@ -1335,9 +1336,11 @@ static void ivtv_remove(struct pci_dev *pdev) ivtv_streams_cleanup(itv, 1); ivtv_udma_free(itv); + v4l2_device_unregister(&itv->device); + exit_ivtv_i2c(itv); - free_irq(itv->pdev->irq, (void *)itv); + free_irq(itv->dev->irq, (void *)itv); ivtv_iounmap(itv); release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); @@ -1345,13 +1348,11 @@ static void ivtv_remove(struct pci_dev *pdev) if (itv->has_cx23415) release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); - pci_disable_device(itv->pdev); + pci_disable_device(itv->dev); for (i = 0; i < IVTV_VBI_FRAMES; i++) kfree(itv->vbi.sliced_mpeg_data[i]); printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name); - - v4l2_device_unregister(&itv->v4l2_dev); kfree(itv); } diff --git a/trunk/drivers/media/video/ivtv/ivtv-driver.h b/trunk/drivers/media/video/ivtv/ivtv-driver.h index 440f7328a7ed..ce8d9b74357e 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-driver.h +++ b/trunk/drivers/media/video/ivtv/ivtv-driver.h @@ -133,7 +133,7 @@ extern int ivtv_debug; #define IVTV_DEBUG(x, type, fmt, args...) \ do { \ if ((x) & ivtv_debug) \ - v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \ + v4l2_info(&itv->device, " " type ": " fmt , ##args); \ } while (0) #define IVTV_DEBUG_WARN(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_WARN, "warn", fmt , ## args) #define IVTV_DEBUG_INFO(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_INFO, "info", fmt , ## args) @@ -149,7 +149,7 @@ extern int ivtv_debug; #define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \ do { \ if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \ - v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \ + v4l2_info(&itv->device, " " type ": " fmt , ##args); \ } while (0) #define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warn", fmt , ## args) #define IVTV_DEBUG_HI_INFO(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info", fmt , ## args) @@ -163,9 +163,9 @@ extern int ivtv_debug; #define IVTV_DEBUG_HI_YUV(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args) /* Standard kernel messages */ -#define IVTV_ERR(fmt, args...) v4l2_err(&itv->v4l2_dev, fmt , ## args) -#define IVTV_WARN(fmt, args...) v4l2_warn(&itv->v4l2_dev, fmt , ## args) -#define IVTV_INFO(fmt, args...) v4l2_info(&itv->v4l2_dev, fmt , ## args) +#define IVTV_ERR(fmt, args...) v4l2_err(&itv->device, fmt , ## args) +#define IVTV_WARN(fmt, args...) v4l2_warn(&itv->device, fmt , ## args) +#define IVTV_INFO(fmt, args...) v4l2_info(&itv->device, fmt , ## args) /* output modes (cx23415 only) */ #define OUT_NONE 0 @@ -315,7 +315,7 @@ struct ivtv; /* forward reference */ struct ivtv_stream { /* These first four fields are always set, even if the stream is not actually created. */ - struct video_device *vdev; /* NULL when stream not created */ + struct video_device *v4l2dev; /* NULL when stream not created */ struct ivtv *itv; /* for ease of use */ const char *name; /* name of the stream */ int type; /* stream type */ @@ -592,7 +592,7 @@ struct ivtv_card; /* Struct to hold info about ivtv cards */ struct ivtv { /* General fixed card data */ - struct pci_dev *pdev; /* PCI device */ + struct pci_dev *dev; /* PCI device */ const struct ivtv_card *card; /* card information */ const char *card_name; /* full name of the card */ const struct ivtv_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */ @@ -612,7 +612,7 @@ struct ivtv { volatile void __iomem *reg_mem; /* pointer to mapped registers */ struct ivtv_options options; /* user options */ - struct v4l2_device v4l2_dev; + struct v4l2_device device; struct v4l2_subdev sd_gpio; /* GPIO sub-device */ u16 instance; @@ -696,7 +696,7 @@ struct ivtv { u64 vbi_data_inserted; /* number of VBI bytes inserted into the MPEG stream */ u32 last_dec_timing[3]; /* cache last retrieved pts/scr/frame values */ unsigned long dualwatch_jiffies;/* jiffies value of the previous dualwatch check */ - u32 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */ + u16 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */ /* VBI state info */ @@ -719,9 +719,9 @@ struct ivtv { struct osd_info *osd_info; /* ivtvfb private OSD info */ }; -static inline struct ivtv *to_ivtv(struct v4l2_device *v4l2_dev) +static inline struct ivtv *to_ivtv(struct v4l2_device *dev) { - return container_of(v4l2_dev, struct ivtv, v4l2_dev); + return container_of(dev, struct ivtv, device); } /* Globals */ @@ -788,7 +788,7 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv) /* Call the specified callback for all subdevs matching hw (if 0, then match them all). Ignore any errors. */ #define ivtv_call_hw(itv, hw, o, f, args...) \ - __v4l2_device_call_subdevs(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args) + __v4l2_device_call_subdevs(&(itv)->device, !(hw) || (sd->grp_id & (hw)), o, f , ##args) #define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args) @@ -796,7 +796,7 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv) match them all). If the callback returns an error other than 0 or -ENOIOCTLCMD, then return with that error code. */ #define ivtv_call_hw_err(itv, hw, o, f, args...) \ - __v4l2_device_call_subdevs_until_err(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args) + __v4l2_device_call_subdevs_until_err(&(itv)->device, !(hw) || (sd->grp_id & (hw)), o, f , ##args) #define ivtv_call_all_err(itv, o, f, args...) ivtv_call_hw_err(itv, 0, o, f , ##args) diff --git a/trunk/drivers/media/video/ivtv/ivtv-fileops.c b/trunk/drivers/media/video/ivtv/ivtv-fileops.c index cfaacf6096d0..d594bc29f07f 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-fileops.c +++ b/trunk/drivers/media/video/ivtv/ivtv-fileops.c @@ -148,10 +148,10 @@ void ivtv_release_stream(struct ivtv_stream *s) static void ivtv_dualwatch(struct ivtv *itv) { struct v4l2_tuner vt; - u32 new_bitmap; - u32 new_stereo_mode; - const u32 stereo_mask = 0x0300; - const u32 dual = 0x0200; + u16 new_bitmap; + u16 new_stereo_mode; + const u16 stereo_mask = 0x0300; + const u16 dual = 0x0200; new_stereo_mode = itv->params.audio_properties & stereo_mask; memset(&vt, 0, sizeof(vt)); @@ -991,7 +991,7 @@ int ivtv_v4l2_open(struct file *filp) mutex_lock(&itv->serialize_lock); if (ivtv_init_on_first_open(itv)) { IVTV_ERR("Failed to initialize on minor %d\n", - vdev->minor); + s->v4l2dev->minor); mutex_unlock(&itv->serialize_lock); return -ENXIO; } diff --git a/trunk/drivers/media/video/ivtv/ivtv-firmware.c b/trunk/drivers/media/video/ivtv/ivtv-firmware.c index c1b7ec475c27..6dba55b7e25a 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-firmware.c +++ b/trunk/drivers/media/video/ivtv/ivtv-firmware.c @@ -52,7 +52,7 @@ static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv int retries = 3; retry: - if (retries && request_firmware(&fw, fn, &itv->pdev->dev) == 0) { + if (retries && request_firmware(&fw, fn, &itv->dev->dev) == 0) { int i; volatile u32 __iomem *dst = (volatile u32 __iomem *)mem; const u32 *src = (const u32 *)fw->data; diff --git a/trunk/drivers/media/video/ivtv/ivtv-gpio.c b/trunk/drivers/media/video/ivtv/ivtv-gpio.c index 3321983d89e5..dc2850e87a7e 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-gpio.c +++ b/trunk/drivers/media/video/ivtv/ivtv-gpio.c @@ -384,7 +384,7 @@ int ivtv_gpio_init(struct ivtv *itv) write_reg(itv->card->gpio_init.initial_value | pin, IVTV_REG_GPIO_OUT); write_reg(itv->card->gpio_init.direction | pin, IVTV_REG_GPIO_DIR); v4l2_subdev_init(&itv->sd_gpio, &subdev_ops); - snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->v4l2_dev.name); + snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->device.name); itv->sd_gpio.grp_id = IVTV_HW_GPIO; - return v4l2_device_register_subdev(&itv->v4l2_dev, &itv->sd_gpio); + return v4l2_device_register_subdev(&itv->device, &itv->sd_gpio); } diff --git a/trunk/drivers/media/video/ivtv/ivtv-i2c.c b/trunk/drivers/media/video/ivtv/ivtv-i2c.c index e73a196ecc7a..ca1d9557945e 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-i2c.c +++ b/trunk/drivers/media/video/ivtv/ivtv-i2c.c @@ -194,14 +194,14 @@ struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw) struct v4l2_subdev *result = NULL; struct v4l2_subdev *sd; - spin_lock(&itv->v4l2_dev.lock); - v4l2_device_for_each_subdev(sd, &itv->v4l2_dev) { + spin_lock(&itv->device.lock); + v4l2_device_for_each_subdev(sd, &itv->device) { if (sd->grp_id == hw) { result = sd; break; } } - spin_unlock(&itv->v4l2_dev.lock); + spin_unlock(&itv->device.lock); return result; } @@ -472,8 +472,8 @@ static int ivtv_read(struct ivtv *itv, unsigned char addr, unsigned char *data, intervening stop condition */ static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { - struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap); - struct ivtv *itv = to_ivtv(v4l2_dev); + struct v4l2_device *drv = i2c_get_adapdata(i2c_adap); + struct ivtv *itv = to_ivtv(drv); int retval; int i; @@ -604,12 +604,12 @@ int init_ivtv_i2c(struct ivtv *itv) sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d", itv->instance); - i2c_set_adapdata(&itv->i2c_adap, &itv->v4l2_dev); + i2c_set_adapdata(&itv->i2c_adap, &itv->device); memcpy(&itv->i2c_client, &ivtv_i2c_client_template, sizeof(struct i2c_client)); itv->i2c_client.adapter = &itv->i2c_adap; - itv->i2c_adap.dev.parent = &itv->pdev->dev; + itv->i2c_adap.dev.parent = &itv->dev->dev; IVTV_DEBUG_I2C("setting scl and sda to 1\n"); ivtv_setscl(itv, 1); diff --git a/trunk/drivers/media/video/ivtv/ivtv-ioctl.c b/trunk/drivers/media/video/ivtv/ivtv-ioctl.c index 9a0424298af1..c13bd2aa0bea 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/trunk/drivers/media/video/ivtv/ivtv-ioctl.c @@ -345,8 +345,10 @@ static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f pixfmt->priv = 0; if (id->type == IVTV_ENC_STREAM_TYPE_YUV) { pixfmt->pixelformat = V4L2_PIX_FMT_HM12; - /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */ - pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2; + /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ + pixfmt->sizeimage = + pixfmt->height * pixfmt->width + + pixfmt->height * (pixfmt->width / 2); pixfmt->bytesperline = 720; } else { pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; @@ -467,17 +469,11 @@ static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format struct ivtv *itv = id->itv; int w = fmt->fmt.pix.width; int h = fmt->fmt.pix.height; - int min_h = 2; w = min(w, 720); w = max(w, 2); - if (id->type == IVTV_ENC_STREAM_TYPE_YUV) { - /* YUV height must be a multiple of 32 */ - h &= ~0x1f; - min_h = 32; - } h = min(h, itv->is_50hz ? 576 : 480); - h = max(h, min_h); + h = max(h, 2); ivtv_g_fmt_vid_cap(file, fh, fmt); fmt->fmt.pix.width = w; fmt->fmt.pix.height = h; @@ -770,7 +766,7 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); - snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev)); + snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->dev)); vcap->version = IVTV_DRIVER_VERSION; /* version */ vcap->capabilities = itv->v4l2_cap; /* capabilities */ return 0; @@ -1517,12 +1513,12 @@ static int ivtv_log_status(struct file *file, void *fh) } IVTV_INFO("Tuner: %s\n", test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); - cx2341x_log_status(&itv->params, itv->v4l2_dev.name); + cx2341x_log_status(&itv->params, itv->device.name); IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags); for (i = 0; i < IVTV_MAX_STREAMS; i++) { struct ivtv_stream *s = &itv->streams[i]; - if (s->vdev == NULL || s->buffers == 0) + if (s->v4l2dev == NULL || s->buffers == 0) continue; IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, (s->buffers - s->q_free.buffers) * 100 / s->buffers, diff --git a/trunk/drivers/media/video/ivtv/ivtv-irq.c b/trunk/drivers/media/video/ivtv/ivtv-irq.c index 01c14d2b381a..f5d00ec5da73 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-irq.c +++ b/trunk/drivers/media/video/ivtv/ivtv-irq.c @@ -46,7 +46,7 @@ static void ivtv_pio_work_handler(struct ivtv *itv) IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n"); if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS || - s->vdev == NULL || !ivtv_use_pio(s)) { + s->v4l2dev == NULL || !ivtv_use_pio(s)) { itv->cur_pio_stream = -1; /* trigger PIO complete user interrupt */ write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); @@ -109,7 +109,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA int rc; /* sanity checks */ - if (s->vdev == NULL) { + if (s->v4l2dev == NULL) { IVTV_DEBUG_WARN("Stream %s not started\n", s->name); return -1; } diff --git a/trunk/drivers/media/video/ivtv/ivtv-queue.c b/trunk/drivers/media/video/ivtv/ivtv-queue.c index ff7b7deded4f..71bd13e22e2e 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-queue.c +++ b/trunk/drivers/media/video/ivtv/ivtv-queue.c @@ -230,7 +230,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s) return -ENOMEM; } if (ivtv_might_use_dma(s)) { - s->sg_handle = pci_map_single(itv->pdev, s->sg_dma, sizeof(struct ivtv_sg_element), s->dma); + s->sg_handle = pci_map_single(itv->dev, s->sg_dma, sizeof(struct ivtv_sg_element), s->dma); ivtv_stream_sync_for_cpu(s); } @@ -248,7 +248,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s) } INIT_LIST_HEAD(&buf->list); if (ivtv_might_use_dma(s)) { - buf->dma_handle = pci_map_single(s->itv->pdev, + buf->dma_handle = pci_map_single(s->itv->dev, buf->buf, s->buf_size + 256, s->dma); ivtv_buf_sync_for_cpu(s, buf); } @@ -271,7 +271,7 @@ void ivtv_stream_free(struct ivtv_stream *s) /* empty q_free */ while ((buf = ivtv_dequeue(s, &s->q_free))) { if (ivtv_might_use_dma(s)) - pci_unmap_single(s->itv->pdev, buf->dma_handle, + pci_unmap_single(s->itv->dev, buf->dma_handle, s->buf_size + 256, s->dma); kfree(buf->buf); kfree(buf); @@ -280,7 +280,7 @@ void ivtv_stream_free(struct ivtv_stream *s) /* Free SG Array/Lists */ if (s->sg_dma != NULL) { if (s->sg_handle != IVTV_DMA_UNMAPPED) { - pci_unmap_single(s->itv->pdev, s->sg_handle, + pci_unmap_single(s->itv->dev, s->sg_handle, sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); s->sg_handle = IVTV_DMA_UNMAPPED; } diff --git a/trunk/drivers/media/video/ivtv/ivtv-queue.h b/trunk/drivers/media/video/ivtv/ivtv-queue.h index 91233839a26c..476556afd39a 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-queue.h +++ b/trunk/drivers/media/video/ivtv/ivtv-queue.h @@ -53,14 +53,14 @@ static inline int ivtv_use_dma(struct ivtv_stream *s) static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf) { if (ivtv_use_dma(s)) - pci_dma_sync_single_for_cpu(s->itv->pdev, buf->dma_handle, + pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle, s->buf_size + 256, s->dma); } static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf) { if (ivtv_use_dma(s)) - pci_dma_sync_single_for_device(s->itv->pdev, buf->dma_handle, + pci_dma_sync_single_for_device(s->itv->dev, buf->dma_handle, s->buf_size + 256, s->dma); } @@ -82,14 +82,14 @@ void ivtv_stream_free(struct ivtv_stream *s); static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s) { if (ivtv_use_dma(s)) - pci_dma_sync_single_for_cpu(s->itv->pdev, s->sg_handle, + pci_dma_sync_single_for_cpu(s->itv->dev, s->sg_handle, sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); } static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s) { if (ivtv_use_dma(s)) - pci_dma_sync_single_for_device(s->itv->pdev, s->sg_handle, + pci_dma_sync_single_for_device(s->itv->dev, s->sg_handle, sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); } diff --git a/trunk/drivers/media/video/ivtv/ivtv-streams.c b/trunk/drivers/media/video/ivtv/ivtv-streams.c index 15da01710efc..854a950af78c 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-streams.c +++ b/trunk/drivers/media/video/ivtv/ivtv-streams.c @@ -137,11 +137,11 @@ static struct { static void ivtv_stream_init(struct ivtv *itv, int type) { struct ivtv_stream *s = &itv->streams[type]; - struct video_device *vdev = s->vdev; + struct video_device *dev = s->v4l2dev; - /* we need to keep vdev, so restore it afterwards */ + /* we need to keep v4l2dev, so restore it afterwards */ memset(s, 0, sizeof(*s)); - s->vdev = vdev; + s->v4l2dev = dev; /* initialize ivtv_stream fields */ s->itv = itv; @@ -172,10 +172,10 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) int num_offset = ivtv_stream_info[type].num_offset; int num = itv->instance + ivtv_first_minor + num_offset; - /* These four fields are always initialized. If vdev == NULL, then + /* These four fields are always initialized. If v4l2dev == NULL, then this stream is not in use. In that case no other fields but these four can be used. */ - s->vdev = NULL; + s->v4l2dev = NULL; s->itv = itv; s->type = type; s->name = ivtv_stream_info[type].name; @@ -197,21 +197,21 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) ivtv_stream_init(itv, type); /* allocate and initialize the v4l2 video device structure */ - s->vdev = video_device_alloc(); - if (s->vdev == NULL) { + s->v4l2dev = video_device_alloc(); + if (s->v4l2dev == NULL) { IVTV_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name); return -ENOMEM; } - snprintf(s->vdev->name, sizeof(s->vdev->name), "%s %s", - itv->v4l2_dev.name, s->name); + snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "%s %s", + itv->device.name, s->name); - s->vdev->num = num; - s->vdev->v4l2_dev = &itv->v4l2_dev; - s->vdev->fops = ivtv_stream_info[type].fops; - s->vdev->release = video_device_release; - s->vdev->tvnorms = V4L2_STD_ALL; - ivtv_set_funcs(s->vdev); + s->v4l2dev->num = num; + s->v4l2dev->v4l2_dev = &itv->device; + s->v4l2dev->fops = ivtv_stream_info[type].fops; + s->v4l2dev->release = video_device_release; + s->v4l2dev->tvnorms = V4L2_STD_ALL; + ivtv_set_funcs(s->v4l2dev); return 0; } @@ -226,7 +226,7 @@ int ivtv_streams_setup(struct ivtv *itv) if (ivtv_prep_dev(itv, type)) break; - if (itv->streams[type].vdev == NULL) + if (itv->streams[type].v4l2dev == NULL) continue; /* Allocate Stream */ @@ -247,28 +247,28 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) int vfl_type = ivtv_stream_info[type].vfl_type; int num; - if (s->vdev == NULL) + if (s->v4l2dev == NULL) return 0; - num = s->vdev->num; + num = s->v4l2dev->num; /* card number + user defined offset + device offset */ if (type != IVTV_ENC_STREAM_TYPE_MPG) { struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG]; - if (s_mpg->vdev) - num = s_mpg->vdev->num + ivtv_stream_info[type].num_offset; + if (s_mpg->v4l2dev) + num = s_mpg->v4l2dev->num + ivtv_stream_info[type].num_offset; } - video_set_drvdata(s->vdev, s); + video_set_drvdata(s->v4l2dev, s); /* Register device. First try the desired minor, then any free one. */ - if (video_register_device(s->vdev, vfl_type, num)) { + if (video_register_device(s->v4l2dev, vfl_type, num)) { IVTV_ERR("Couldn't register v4l2 device for %s kernel number %d\n", s->name, num); - video_device_release(s->vdev); - s->vdev = NULL; + video_device_release(s->v4l2dev); + s->v4l2dev = NULL; return -ENOMEM; } - num = s->vdev->num; + num = s->v4l2dev->num; switch (vfl_type) { case VFL_TYPE_GRABBER: @@ -316,9 +316,9 @@ void ivtv_streams_cleanup(struct ivtv *itv, int unregister) /* Teardown all streams */ for (type = 0; type < IVTV_MAX_STREAMS; type++) { - struct video_device *vdev = itv->streams[type].vdev; + struct video_device *vdev = itv->streams[type].v4l2dev; - itv->streams[type].vdev = NULL; + itv->streams[type].v4l2dev = NULL; if (vdev == NULL) continue; @@ -449,7 +449,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) int captype = 0, subtype = 0; int enable_passthrough = 0; - if (s->vdev == NULL) + if (s->v4l2dev == NULL) return -EINVAL; IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name); @@ -611,7 +611,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) struct cx2341x_mpeg_params *p = &itv->params; int datatype; - if (s->vdev == NULL) + if (s->v4l2dev == NULL) return -EINVAL; IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); @@ -657,7 +657,7 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset) { struct ivtv *itv = s->itv; - if (s->vdev == NULL) + if (s->v4l2dev == NULL) return -EINVAL; if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) @@ -705,7 +705,7 @@ void ivtv_stop_all_captures(struct ivtv *itv) for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) { struct ivtv_stream *s = &itv->streams[i]; - if (s->vdev == NULL) + if (s->v4l2dev == NULL) continue; if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { ivtv_stop_v4l2_encode_stream(s, 0); @@ -720,7 +720,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) int cap_type; int stopmode; - if (s->vdev == NULL) + if (s->v4l2dev == NULL) return -EINVAL; /* This function assumes that you are allowed to stop the capture @@ -834,7 +834,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) { struct ivtv *itv = s->itv; - if (s->vdev == NULL) + if (s->v4l2dev == NULL) return -EINVAL; if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG) @@ -895,7 +895,7 @@ int ivtv_passthrough_mode(struct ivtv *itv, int enable) struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV]; struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV]; - if (yuv_stream->vdev == NULL || dec_stream->vdev == NULL) + if (yuv_stream->v4l2dev == NULL || dec_stream->v4l2dev == NULL) return -EINVAL; IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n"); diff --git a/trunk/drivers/media/video/ivtv/ivtv-udma.c b/trunk/drivers/media/video/ivtv/ivtv-udma.c index d07ad6c39024..460db03b0ba0 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-udma.c +++ b/trunk/drivers/media/video/ivtv/ivtv-udma.c @@ -93,7 +93,7 @@ void ivtv_udma_alloc(struct ivtv *itv) { if (itv->udma.SG_handle == 0) { /* Map DMA Page Array Buffer */ - itv->udma.SG_handle = pci_map_single(itv->pdev, itv->udma.SGarray, + itv->udma.SG_handle = pci_map_single(itv->dev, itv->udma.SGarray, sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); ivtv_udma_sync_for_cpu(itv); } @@ -147,7 +147,7 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr, } /* Map SG List */ - dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); + dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); /* Fill SG Array with new values */ ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1); @@ -172,7 +172,7 @@ void ivtv_udma_unmap(struct ivtv *itv) /* Unmap Scatterlist */ if (dma->SG_length) { - pci_unmap_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); + pci_unmap_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); dma->SG_length = 0; } /* sync DMA */ @@ -191,13 +191,13 @@ void ivtv_udma_free(struct ivtv *itv) /* Unmap SG Array */ if (itv->udma.SG_handle) { - pci_unmap_single(itv->pdev, itv->udma.SG_handle, + pci_unmap_single(itv->dev, itv->udma.SG_handle, sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); } /* Unmap Scatterlist */ if (itv->udma.SG_length) { - pci_unmap_sg(itv->pdev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE); + pci_unmap_sg(itv->dev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE); } for (i = 0; i < IVTV_DMA_SG_OSD_ENT; i++) { diff --git a/trunk/drivers/media/video/ivtv/ivtv-udma.h b/trunk/drivers/media/video/ivtv/ivtv-udma.h index ee3c9efb5b72..df727e23be0a 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-udma.h +++ b/trunk/drivers/media/video/ivtv/ivtv-udma.h @@ -35,13 +35,13 @@ void ivtv_udma_start(struct ivtv *itv); static inline void ivtv_udma_sync_for_device(struct ivtv *itv) { - pci_dma_sync_single_for_device(itv->pdev, itv->udma.SG_handle, + pci_dma_sync_single_for_device((struct pci_dev *)itv->dev, itv->udma.SG_handle, sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); } static inline void ivtv_udma_sync_for_cpu(struct ivtv *itv) { - pci_dma_sync_single_for_cpu(itv->pdev, itv->udma.SG_handle, + pci_dma_sync_single_for_cpu((struct pci_dev *)itv->dev, itv->udma.SG_handle, sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE); } diff --git a/trunk/drivers/media/video/ivtv/ivtv-vbi.c b/trunk/drivers/media/video/ivtv/ivtv-vbi.c index f420d31b937d..5c5d1c462fef 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-vbi.c +++ b/trunk/drivers/media/video/ivtv/ivtv-vbi.c @@ -185,8 +185,6 @@ static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp) size = 4 + ((43 * line + 3) & ~3); } else { memcpy(dst + sd, "itv0", 4); - cpu_to_le32s(&linemask[0]); - cpu_to_le32s(&linemask[1]); memcpy(dst + sd + 4, &linemask[0], 8); size = 12 + ((43 * line + 3) & ~3); } diff --git a/trunk/drivers/media/video/ivtv/ivtv-version.h b/trunk/drivers/media/video/ivtv/ivtv-version.h index b530dec399d3..8cd753d30bf7 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-version.h +++ b/trunk/drivers/media/video/ivtv/ivtv-version.h @@ -23,7 +23,7 @@ #define IVTV_DRIVER_NAME "ivtv" #define IVTV_DRIVER_VERSION_MAJOR 1 #define IVTV_DRIVER_VERSION_MINOR 4 -#define IVTV_DRIVER_VERSION_PATCHLEVEL 1 +#define IVTV_DRIVER_VERSION_PATCHLEVEL 0 #define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL) #define IVTV_DRIVER_VERSION KERNEL_VERSION(IVTV_DRIVER_VERSION_MAJOR,IVTV_DRIVER_VERSION_MINOR,IVTV_DRIVER_VERSION_PATCHLEVEL) diff --git a/trunk/drivers/media/video/ivtv/ivtv-yuv.c b/trunk/drivers/media/video/ivtv/ivtv-yuv.c index 7912ed6b72ee..ee91107376c7 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-yuv.c +++ b/trunk/drivers/media/video/ivtv/ivtv-yuv.c @@ -103,7 +103,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, dma->page_count = 0; return -ENOMEM; } - dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); + dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); /* Fill SG Array with new values */ ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size); @@ -910,7 +910,7 @@ static void ivtv_yuv_init(struct ivtv *itv) /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */ yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN); if (yi->blanking_ptr) { - yi->blanking_dmaptr = pci_map_single(itv->pdev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE); + yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE); } else { yi->blanking_dmaptr = 0; IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n"); @@ -1237,7 +1237,7 @@ void ivtv_yuv_close(struct ivtv *itv) if (yi->blanking_ptr) { kfree(yi->blanking_ptr); yi->blanking_ptr = NULL; - pci_unmap_single(itv->pdev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE); + pci_unmap_single(itv->dev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE); } /* Invalidate the old dimension information */ diff --git a/trunk/drivers/media/video/ivtv/ivtvfb.c b/trunk/drivers/media/video/ivtv/ivtvfb.c index 66e6eb513076..36abd2aef6f1 100644 --- a/trunk/drivers/media/video/ivtv/ivtvfb.c +++ b/trunk/drivers/media/video/ivtv/ivtvfb.c @@ -1192,12 +1192,12 @@ static int ivtvfb_init_card(struct ivtv *itv) static int __init ivtvfb_callback_init(struct device *dev, void *p) { struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); - struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev); + struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device); if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { if (ivtvfb_init_card(itv) == 0) { IVTVFB_INFO("Framebuffer registered on %s\n", - itv->v4l2_dev.name); + itv->device.name); (*(int *)p)++; } } @@ -1207,7 +1207,7 @@ static int __init ivtvfb_callback_init(struct device *dev, void *p) static int ivtvfb_callback_cleanup(struct device *dev, void *p) { struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); - struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev); + struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device); if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) { diff --git a/trunk/drivers/media/video/ks0127.c b/trunk/drivers/media/video/ks0127.c index 841024b6bcdf..bae2d2beb709 100644 --- a/trunk/drivers/media/video/ks0127.c +++ b/trunk/drivers/media/video/ks0127.c @@ -39,20 +39,19 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include #include "ks0127.h" MODULE_DESCRIPTION("KS0127 video decoder driver"); MODULE_AUTHOR("Ryan Drake"); MODULE_LICENSE("GPL"); -/* Addresses */ -#define I2C_KS0127_ADDON 0xD8 -#define I2C_KS0127_ONBOARD 0xDA - +#define KS_TYPE_UNKNOWN 0 +#define KS_TYPE_0122S 1 +#define KS_TYPE_0127 2 +#define KS_TYPE_0127B 3 /* ks0127 control registers */ #define KS_STAT 0x00 @@ -198,17 +197,15 @@ struct adjust { }; struct ks0127 { - struct v4l2_subdev sd; - v4l2_std_id norm; - int ident; + int format_width; + int format_height; + int cap_width; + int cap_height; + int norm; + int ks_type; u8 regs[256]; }; -static inline struct ks0127 *to_ks0127(struct v4l2_subdev *sd) -{ - return container_of(sd, struct ks0127, sd); -} - static int debug; /* insmod parameter */ @@ -314,45 +311,43 @@ static void init_reg_defaults(void) */ -static u8 ks0127_read(struct v4l2_subdev *sd, u8 reg) +static u8 ks0127_read(struct i2c_client *c, u8 reg) { - struct i2c_client *client = v4l2_get_subdevdata(sd); char val = 0; struct i2c_msg msgs[] = { - { client->addr, 0, sizeof(reg), ® }, - { client->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val } + { c->addr, 0, sizeof(reg), ® }, + { c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val } }; int ret; - ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs)); if (ret != ARRAY_SIZE(msgs)) - v4l2_dbg(1, debug, sd, "read error\n"); + v4l_dbg(1, debug, c, "read error\n"); return val; } -static void ks0127_write(struct v4l2_subdev *sd, u8 reg, u8 val) +static void ks0127_write(struct i2c_client *c, u8 reg, u8 val) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ks0127 *ks = to_ks0127(sd); + struct ks0127 *ks = i2c_get_clientdata(c); char msg[] = { reg, val }; - if (i2c_master_send(client, msg, sizeof(msg)) != sizeof(msg)) - v4l2_dbg(1, debug, sd, "write error\n"); + if (i2c_master_send(c, msg, sizeof(msg)) != sizeof(msg)) + v4l_dbg(1, debug, c, "write error\n"); ks->regs[reg] = val; } /* generic bit-twiddling */ -static void ks0127_and_or(struct v4l2_subdev *sd, u8 reg, u8 and_v, u8 or_v) +static void ks0127_and_or(struct i2c_client *client, u8 reg, u8 and_v, u8 or_v) { - struct ks0127 *ks = to_ks0127(sd); + struct ks0127 *ks = i2c_get_clientdata(client); u8 val = ks->regs[reg]; val = (val & and_v) | or_v; - ks0127_write(sd, reg, val); + ks0127_write(client, reg, val); } @@ -360,363 +355,439 @@ static void ks0127_and_or(struct v4l2_subdev *sd, u8 reg, u8 and_v, u8 or_v) /**************************************************************************** * ks0127 private api ****************************************************************************/ -static void ks0127_init(struct v4l2_subdev *sd) +static void ks0127_reset(struct i2c_client *c) { - struct ks0127 *ks = to_ks0127(sd); + struct ks0127 *ks = i2c_get_clientdata(c); u8 *table = reg_defaults; int i; - ks->ident = V4L2_IDENT_KS0127; + ks->ks_type = KS_TYPE_UNKNOWN; - v4l2_dbg(1, debug, sd, "reset\n"); + v4l_dbg(1, debug, c, "reset\n"); msleep(1); /* initialize all registers to known values */ /* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */ for (i = 1; i < 33; i++) - ks0127_write(sd, i, table[i]); + ks0127_write(c, i, table[i]); for (i = 35; i < 40; i++) - ks0127_write(sd, i, table[i]); + ks0127_write(c, i, table[i]); for (i = 41; i < 56; i++) - ks0127_write(sd, i, table[i]); + ks0127_write(c, i, table[i]); for (i = 58; i < 64; i++) - ks0127_write(sd, i, table[i]); + ks0127_write(c, i, table[i]); - if ((ks0127_read(sd, KS_STAT) & 0x80) == 0) { - ks->ident = V4L2_IDENT_KS0122S; - v4l2_dbg(1, debug, sd, "ks0122s found\n"); + if ((ks0127_read(c, KS_STAT) & 0x80) == 0) { + ks->ks_type = KS_TYPE_0122S; + v4l_dbg(1, debug, c, "ks0122s found\n"); return; } - switch (ks0127_read(sd, KS_CMDE) & 0x0f) { + switch (ks0127_read(c, KS_CMDE) & 0x0f) { case 0: - v4l2_dbg(1, debug, sd, "ks0127 found\n"); + ks->ks_type = KS_TYPE_0127; + v4l_dbg(1, debug, c, "ks0127 found\n"); break; case 9: - ks->ident = V4L2_IDENT_KS0127B; - v4l2_dbg(1, debug, sd, "ks0127B Revision A found\n"); + ks->ks_type = KS_TYPE_0127B; + v4l_dbg(1, debug, c, "ks0127B Revision A found\n"); break; default: - v4l2_dbg(1, debug, sd, "unknown revision\n"); + v4l_dbg(1, debug, c, "unknown revision\n"); break; } } -static int ks0127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) +static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) { - struct ks0127 *ks = to_ks0127(sd); - - switch (route->input) { - case KS_INPUT_COMPOSITE_1: - case KS_INPUT_COMPOSITE_2: - case KS_INPUT_COMPOSITE_3: - case KS_INPUT_COMPOSITE_4: - case KS_INPUT_COMPOSITE_5: - case KS_INPUT_COMPOSITE_6: - v4l2_dbg(1, debug, sd, - "s_routing %d: Composite\n", route->input); - /* autodetect 50/60 Hz */ - ks0127_and_or(sd, KS_CMDA, 0xfc, 0x00); - /* VSE=0 */ - ks0127_and_or(sd, KS_CMDA, ~0x40, 0x00); - /* set input line */ - ks0127_and_or(sd, KS_CMDB, 0xb0, route->input); - /* non-freerunning mode */ - ks0127_and_or(sd, KS_CMDC, 0x70, 0x0a); - /* analog input */ - ks0127_and_or(sd, KS_CMDD, 0x03, 0x00); - /* enable chroma demodulation */ - ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x00); - /* chroma trap, HYBWR=1 */ - ks0127_and_or(sd, KS_LUMA, 0x00, - (reg_defaults[KS_LUMA])|0x0c); - /* scaler fullbw, luma comb off */ - ks0127_and_or(sd, KS_VERTIA, 0x08, 0x81); - /* manual chroma comb .25 .5 .25 */ - ks0127_and_or(sd, KS_VERTIC, 0x0f, 0x90); - - /* chroma path delay */ - ks0127_and_or(sd, KS_CHROMB, 0x0f, 0x90); - - ks0127_write(sd, KS_UGAIN, reg_defaults[KS_UGAIN]); - ks0127_write(sd, KS_VGAIN, reg_defaults[KS_VGAIN]); - ks0127_write(sd, KS_UVOFFH, reg_defaults[KS_UVOFFH]); - ks0127_write(sd, KS_UVOFFL, reg_defaults[KS_UVOFFL]); - break; + struct ks0127 *ks = i2c_get_clientdata(c); + int *iarg = (int *)arg; + int status; - case KS_INPUT_SVIDEO_1: - case KS_INPUT_SVIDEO_2: - case KS_INPUT_SVIDEO_3: - v4l2_dbg(1, debug, sd, - "s_routing %d: S-Video\n", route->input); - /* autodetect 50/60 Hz */ - ks0127_and_or(sd, KS_CMDA, 0xfc, 0x00); - /* VSE=0 */ - ks0127_and_or(sd, KS_CMDA, ~0x40, 0x00); - /* set input line */ - ks0127_and_or(sd, KS_CMDB, 0xb0, route->input); - /* non-freerunning mode */ - ks0127_and_or(sd, KS_CMDC, 0x70, 0x0a); - /* analog input */ - ks0127_and_or(sd, KS_CMDD, 0x03, 0x00); - /* enable chroma demodulation */ - ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x00); - ks0127_and_or(sd, KS_LUMA, 0x00, - reg_defaults[KS_LUMA]); - /* disable luma comb */ - ks0127_and_or(sd, KS_VERTIA, 0x08, - (reg_defaults[KS_VERTIA]&0xf0)|0x01); - ks0127_and_or(sd, KS_VERTIC, 0x0f, - reg_defaults[KS_VERTIC]&0xf0); - - ks0127_and_or(sd, KS_CHROMB, 0x0f, - reg_defaults[KS_CHROMB]&0xf0); - - ks0127_write(sd, KS_UGAIN, reg_defaults[KS_UGAIN]); - ks0127_write(sd, KS_VGAIN, reg_defaults[KS_VGAIN]); - ks0127_write(sd, KS_UVOFFH, reg_defaults[KS_UVOFFH]); - ks0127_write(sd, KS_UVOFFL, reg_defaults[KS_UVOFFL]); + if (!ks) + return -ENODEV; + + switch (cmd) { + case DECODER_INIT: + v4l_dbg(1, debug, c, "DECODER_INIT\n"); + ks0127_reset(c); break; - case KS_INPUT_YUV656: - v4l2_dbg(1, debug, sd, "s_routing 15: YUV656\n"); - if (ks->norm & V4L2_STD_525_60) - /* force 60 Hz */ - ks0127_and_or(sd, KS_CMDA, 0xfc, 0x03); - else - /* force 50 Hz */ - ks0127_and_or(sd, KS_CMDA, 0xfc, 0x02); - - ks0127_and_or(sd, KS_CMDA, 0xff, 0x40); /* VSE=1 */ - /* set input line and VALIGN */ - ks0127_and_or(sd, KS_CMDB, 0xb0, (route->input | 0x40)); - /* freerunning mode, */ - /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/ - ks0127_and_or(sd, KS_CMDC, 0x70, 0x87); - /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */ - ks0127_and_or(sd, KS_CMDD, 0x03, 0x08); - /* disable chroma demodulation */ - ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x30); - /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */ - ks0127_and_or(sd, KS_LUMA, 0x00, 0x71); - ks0127_and_or(sd, KS_VERTIC, 0x0f, - reg_defaults[KS_VERTIC]&0xf0); - - /* scaler fullbw, luma comb off */ - ks0127_and_or(sd, KS_VERTIA, 0x08, 0x81); - - ks0127_and_or(sd, KS_CHROMB, 0x0f, - reg_defaults[KS_CHROMB]&0xf0); - - ks0127_and_or(sd, KS_CON, 0x00, 0x00); - ks0127_and_or(sd, KS_BRT, 0x00, 32); /* spec: 34 */ - /* spec: 229 (e5) */ - ks0127_and_or(sd, KS_SAT, 0x00, 0xe8); - ks0127_and_or(sd, KS_HUE, 0x00, 0); - - ks0127_and_or(sd, KS_UGAIN, 0x00, 238); - ks0127_and_or(sd, KS_VGAIN, 0x00, 0x00); - - /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */ - ks0127_and_or(sd, KS_UVOFFH, 0x00, 0x4f); - ks0127_and_or(sd, KS_UVOFFL, 0x00, 0x00); + case DECODER_SET_INPUT: + switch(*iarg) { + case KS_INPUT_COMPOSITE_1: + case KS_INPUT_COMPOSITE_2: + case KS_INPUT_COMPOSITE_3: + case KS_INPUT_COMPOSITE_4: + case KS_INPUT_COMPOSITE_5: + case KS_INPUT_COMPOSITE_6: + v4l_dbg(1, debug, c, + "DECODER_SET_INPUT %d: Composite\n", *iarg); + /* autodetect 50/60 Hz */ + ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); + /* VSE=0 */ + ks0127_and_or(c, KS_CMDA, ~0x40, 0x00); + /* set input line */ + ks0127_and_or(c, KS_CMDB, 0xb0, *iarg); + /* non-freerunning mode */ + ks0127_and_or(c, KS_CMDC, 0x70, 0x0a); + /* analog input */ + ks0127_and_or(c, KS_CMDD, 0x03, 0x00); + /* enable chroma demodulation */ + ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00); + /* chroma trap, HYBWR=1 */ + ks0127_and_or(c, KS_LUMA, 0x00, + (reg_defaults[KS_LUMA])|0x0c); + /* scaler fullbw, luma comb off */ + ks0127_and_or(c, KS_VERTIA, 0x08, 0x81); + /* manual chroma comb .25 .5 .25 */ + ks0127_and_or(c, KS_VERTIC, 0x0f, 0x90); + + /* chroma path delay */ + ks0127_and_or(c, KS_CHROMB, 0x0f, 0x90); + + ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]); + ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]); + ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]); + ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]); + break; + + case KS_INPUT_SVIDEO_1: + case KS_INPUT_SVIDEO_2: + case KS_INPUT_SVIDEO_3: + v4l_dbg(1, debug, c, + "DECODER_SET_INPUT %d: S-Video\n", *iarg); + /* autodetect 50/60 Hz */ + ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); + /* VSE=0 */ + ks0127_and_or(c, KS_CMDA, ~0x40, 0x00); + /* set input line */ + ks0127_and_or(c, KS_CMDB, 0xb0, *iarg); + /* non-freerunning mode */ + ks0127_and_or(c, KS_CMDC, 0x70, 0x0a); + /* analog input */ + ks0127_and_or(c, KS_CMDD, 0x03, 0x00); + /* enable chroma demodulation */ + ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00); + ks0127_and_or(c, KS_LUMA, 0x00, + reg_defaults[KS_LUMA]); + /* disable luma comb */ + ks0127_and_or(c, KS_VERTIA, 0x08, + (reg_defaults[KS_VERTIA]&0xf0)|0x01); + ks0127_and_or(c, KS_VERTIC, 0x0f, + reg_defaults[KS_VERTIC]&0xf0); + + ks0127_and_or(c, KS_CHROMB, 0x0f, + reg_defaults[KS_CHROMB]&0xf0); + + ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]); + ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]); + ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]); + ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]); + break; + + case KS_INPUT_YUV656: + v4l_dbg(1, debug, c, + "DECODER_SET_INPUT 15: YUV656\n"); + if (ks->norm == VIDEO_MODE_NTSC || + ks->norm == KS_STD_PAL_M) + /* force 60 Hz */ + ks0127_and_or(c, KS_CMDA, 0xfc, 0x03); + else + /* force 50 Hz */ + ks0127_and_or(c, KS_CMDA, 0xfc, 0x02); + + ks0127_and_or(c, KS_CMDA, 0xff, 0x40); /* VSE=1 */ + /* set input line and VALIGN */ + ks0127_and_or(c, KS_CMDB, 0xb0, (*iarg | 0x40)); + /* freerunning mode, */ + /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/ + ks0127_and_or(c, KS_CMDC, 0x70, 0x87); + /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */ + ks0127_and_or(c, KS_CMDD, 0x03, 0x08); + /* disable chroma demodulation */ + ks0127_and_or(c, KS_CTRACK, 0xcf, 0x30); + /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */ + ks0127_and_or(c, KS_LUMA, 0x00, 0x71); + ks0127_and_or(c, KS_VERTIC, 0x0f, + reg_defaults[KS_VERTIC]&0xf0); + + /* scaler fullbw, luma comb off */ + ks0127_and_or(c, KS_VERTIA, 0x08, 0x81); + + ks0127_and_or(c, KS_CHROMB, 0x0f, + reg_defaults[KS_CHROMB]&0xf0); + + ks0127_and_or(c, KS_CON, 0x00, 0x00); + ks0127_and_or(c, KS_BRT, 0x00, 32); /* spec: 34 */ + /* spec: 229 (e5) */ + ks0127_and_or(c, KS_SAT, 0x00, 0xe8); + ks0127_and_or(c, KS_HUE, 0x00, 0); + + ks0127_and_or(c, KS_UGAIN, 0x00, 238); + ks0127_and_or(c, KS_VGAIN, 0x00, 0x00); + + /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */ + ks0127_and_or(c, KS_UVOFFH, 0x00, 0x4f); + ks0127_and_or(c, KS_UVOFFL, 0x00, 0x00); + break; + + default: + v4l_dbg(1, debug, c, + "DECODER_SET_INPUT: Unknown input %d\n", *iarg); + break; + } + + /* hack: CDMLPF sometimes spontaneously switches on; */ + /* force back off */ + ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]); break; - default: - v4l2_dbg(1, debug, sd, - "s_routing: Unknown input %d\n", route->input); + case DECODER_SET_OUTPUT: + switch(*iarg) { + case KS_OUTPUT_YUV656E: + v4l_dbg(1, debug, c, + "DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n"); + return -EINVAL; + + case KS_OUTPUT_EXV: + v4l_dbg(1, debug, c, + "DECODER_SET_OUTPUT: OUTPUT_EXV\n"); + ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09); + break; + } break; - } - /* hack: CDMLPF sometimes spontaneously switches on; */ - /* force back off */ - ks0127_write(sd, KS_DEMOD, reg_defaults[KS_DEMOD]); - return 0; -} + case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */ + /* Set to automatic SECAM/Fsc mode */ + ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00); + + ks->norm = *iarg; + switch (*iarg) { + /* this is untested !! */ + /* It just detects PAL_N/NTSC_M (no special frequencies) */ + /* And you have to set the standard a second time afterwards */ + case VIDEO_MODE_AUTO: + v4l_dbg(1, debug, c, + "DECODER_SET_NORM: AUTO\n"); + + /* The chip determines the format */ + /* based on the current field rate */ + ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); + ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); + /* This is wrong for PAL ! As I said, */ + /* you need to set the standard once again !! */ + ks->format_height = 240; + ks->format_width = 704; + break; + + case VIDEO_MODE_NTSC: + v4l_dbg(1, debug, c, + "DECODER_SET_NORM: NTSC_M\n"); + ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); + ks->format_height = 240; + ks->format_width = 704; + break; + + case KS_STD_NTSC_N: + v4l_dbg(1, debug, c, + "KS0127_SET_NORM: NTSC_N (fixme)\n"); + ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); + ks->format_height = 240; + ks->format_width = 704; + break; + + case VIDEO_MODE_PAL: + v4l_dbg(1, debug, c, + "DECODER_SET_NORM: PAL_N\n"); + ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); + ks->format_height = 290; + ks->format_width = 704; + break; + + case KS_STD_PAL_M: + v4l_dbg(1, debug, c, + "KS0127_SET_NORM: PAL_M (fixme)\n"); + ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); + ks->format_height = 290; + ks->format_width = 704; + break; + + case VIDEO_MODE_SECAM: + v4l_dbg(1, debug, c, + "KS0127_SET_NORM: SECAM\n"); + ks->format_height = 290; + ks->format_width = 704; + + /* set to secam autodetection */ + ks0127_and_or(c, KS_CHROMA, 0xdf, 0x20); + ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00); + schedule_timeout_interruptible(HZ/10+1); + + /* did it autodetect? */ + if (ks0127_read(c, KS_DEMOD) & 0x40) + break; -static int ks0127_s_std(struct v4l2_subdev *sd, v4l2_std_id std) -{ - struct ks0127 *ks = to_ks0127(sd); - - /* Set to automatic SECAM/Fsc mode */ - ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x00); - - ks->norm = std; - if (std & V4L2_STD_NTSC) { - v4l2_dbg(1, debug, sd, - "s_std: NTSC_M\n"); - ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x20); - } else if (std & V4L2_STD_PAL_N) { - v4l2_dbg(1, debug, sd, - "s_std: NTSC_N (fixme)\n"); - ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x40); - } else if (std & V4L2_STD_PAL) { - v4l2_dbg(1, debug, sd, - "s_std: PAL_N\n"); - ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x20); - } else if (std & V4L2_STD_PAL_M) { - v4l2_dbg(1, debug, sd, - "s_std: PAL_M (fixme)\n"); - ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x40); - } else if (std & V4L2_STD_SECAM) { - v4l2_dbg(1, debug, sd, - "s_std: SECAM\n"); - - /* set to secam autodetection */ - ks0127_and_or(sd, KS_CHROMA, 0xdf, 0x20); - ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x00); - schedule_timeout_interruptible(HZ/10+1); - - /* did it autodetect? */ - if (!(ks0127_read(sd, KS_DEMOD) & 0x40)) /* force to secam mode */ - ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x0f); - } else { - v4l2_dbg(1, debug, sd, "s_std: Unknown norm %llx\n", - (unsigned long long)std); - } - return 0; -} + ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f); + break; + + default: + v4l_dbg(1, debug, c, + "DECODER_SET_NORM: Unknown norm %d\n", *iarg); + break; + } + break; -static int ks0127_s_stream(struct v4l2_subdev *sd, int enable) -{ - v4l2_dbg(1, debug, sd, "s_stream(%d)\n", enable); - if (enable) { - /* All output pins on */ - ks0127_and_or(sd, KS_OFMTA, 0xcf, 0x30); - /* Obey the OEN pin */ - ks0127_and_or(sd, KS_CDEM, 0x7f, 0x00); - } else { - /* Video output pins off */ - ks0127_and_or(sd, KS_OFMTA, 0xcf, 0x00); - /* Ignore the OEN pin */ - ks0127_and_or(sd, KS_CDEM, 0x7f, 0x80); + case DECODER_SET_PICTURE: + v4l_dbg(1, debug, c, + "DECODER_SET_PICTURE: not yet supported\n"); + return -EINVAL; + + /* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */ + /* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */ + /* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */ + /* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */ + /* sam todo: KS0127_SET_AGC_MODE: */ + /* sam todo: KS0127_SET_AGC: */ + /* sam todo: KS0127_SET_CHROMA_MODE: */ + /* sam todo: KS0127_SET_PIXCLK_MODE: */ + /* sam todo: KS0127_SET_GAMMA_MODE: */ + /* sam todo: KS0127_SET_UGAIN: */ + /* sam todo: KS0127_SET_VGAIN: */ + /* sam todo: KS0127_SET_INVALY: */ + /* sam todo: KS0127_SET_INVALU: */ + /* sam todo: KS0127_SET_INVALV: */ + /* sam todo: KS0127_SET_UNUSEY: */ + /* sam todo: KS0127_SET_UNUSEU: */ + /* sam todo: KS0127_SET_UNUSEV: */ + /* sam todo: KS0127_SET_VSALIGN_MODE: */ + + case DECODER_ENABLE_OUTPUT: + { + int enable; + + iarg = arg; + enable = (*iarg != 0); + if (enable) { + v4l_dbg(1, debug, c, + "DECODER_ENABLE_OUTPUT on\n"); + /* All output pins on */ + ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30); + /* Obey the OEN pin */ + ks0127_and_or(c, KS_CDEM, 0x7f, 0x00); + } else { + v4l_dbg(1, debug, c, + "DECODER_ENABLE_OUTPUT off\n"); + /* Video output pins off */ + ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00); + /* Ignore the OEN pin */ + ks0127_and_or(c, KS_CDEM, 0x7f, 0x80); + } + break; } - return 0; -} - -static int ks0127_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd) -{ - int stat = V4L2_IN_ST_NO_SIGNAL; - u8 status; - v4l2_std_id std = V4L2_STD_ALL; - - status = ks0127_read(sd, KS_STAT); - if (!(status & 0x20)) /* NOVID not set */ - stat = 0; - if (!(status & 0x01)) /* CLOCK set */ - stat |= V4L2_IN_ST_NO_COLOR; - if ((status & 0x08)) /* PALDET set */ - std = V4L2_STD_PAL; - else - std = V4L2_STD_NTSC; - if (pstd) - *pstd = std; - if (pstatus) - *pstatus = stat; - return 0; -} -static int ks0127_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) -{ - v4l2_dbg(1, debug, sd, "querystd\n"); - return ks0127_status(sd, NULL, std); -} - -static int ks0127_g_input_status(struct v4l2_subdev *sd, u32 *status) -{ - v4l2_dbg(1, debug, sd, "g_input_status\n"); - return ks0127_status(sd, status, NULL); -} - -static int ks0127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ks0127 *ks = to_ks0127(sd); + /* sam todo: KS0127_SET_OUTPUT_MODE: */ + /* sam todo: KS0127_SET_WIDTH: */ + /* sam todo: KS0127_SET_HEIGHT: */ + /* sam todo: KS0127_SET_HSCALE: */ + + case DECODER_GET_STATUS: + v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n"); + *iarg = 0; + status = ks0127_read(c, KS_STAT); + if (!(status & 0x20)) /* NOVID not set */ + *iarg = (*iarg | DECODER_STATUS_GOOD); + if ((status & 0x01)) /* CLOCK set */ + *iarg = (*iarg | DECODER_STATUS_COLOR); + if ((status & 0x08)) /* PALDET set */ + *iarg = (*iarg | DECODER_STATUS_PAL); + else + *iarg = (*iarg | DECODER_STATUS_NTSC); + break; - return v4l2_chip_ident_i2c_client(client, chip, ks->ident, 0); + /* Catch any unknown command */ + default: + v4l_dbg(1, debug, c, "unknown: 0x%08x\n", cmd); + return -EINVAL; + } + return 0; } -/* ----------------------------------------------------------------------- */ - -static const struct v4l2_subdev_core_ops ks0127_core_ops = { - .g_chip_ident = ks0127_g_chip_ident, -}; - -static const struct v4l2_subdev_tuner_ops ks0127_tuner_ops = { - .s_std = ks0127_s_std, -}; -static const struct v4l2_subdev_video_ops ks0127_video_ops = { - .s_routing = ks0127_s_routing, - .s_stream = ks0127_s_stream, - .querystd = ks0127_querystd, - .g_input_status = ks0127_g_input_status, -}; +/* Addresses to scan */ +#define I2C_KS0127_ADDON 0xD8 +#define I2C_KS0127_ONBOARD 0xDA -static const struct v4l2_subdev_ops ks0127_ops = { - .core = &ks0127_core_ops, - .tuner = &ks0127_tuner_ops, - .video = &ks0127_video_ops, +static unsigned short normal_i2c[] = { + I2C_KS0127_ADDON >> 1, + I2C_KS0127_ONBOARD >> 1, + I2C_CLIENT_END }; -/* ----------------------------------------------------------------------- */ - +I2C_CLIENT_INSMOD; -static int ks0127_probe(struct i2c_client *client, const struct i2c_device_id *id) +static int ks0127_probe(struct i2c_client *c, const struct i2c_device_id *id) { struct ks0127 *ks; - struct v4l2_subdev *sd; - v4l_info(client, "%s chip found @ 0x%x (%s)\n", - client->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board", - client->addr << 1, client->adapter->name); + v4l_info(c, "%s chip found @ 0x%x (%s)\n", + c->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board", + c->addr << 1, c->adapter->name); ks = kzalloc(sizeof(*ks), GFP_KERNEL); if (ks == NULL) return -ENOMEM; - sd = &ks->sd; - v4l2_i2c_subdev_init(sd, client, &ks0127_ops); + + i2c_set_clientdata(c, ks); + + ks->ks_type = KS_TYPE_UNKNOWN; /* power up */ init_reg_defaults(); - ks0127_write(sd, KS_CMDA, 0x2c); + ks0127_write(c, KS_CMDA, 0x2c); mdelay(10); /* reset the device */ - ks0127_init(sd); + ks0127_reset(c); return 0; } -static int ks0127_remove(struct i2c_client *client) +static int ks0127_remove(struct i2c_client *c) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ks0127 *ks = i2c_get_clientdata(c); + + ks0127_write(c, KS_OFMTA, 0x20); /* tristate */ + ks0127_write(c, KS_CMDA, 0x2c | 0x80); /* power down */ - v4l2_device_unregister_subdev(sd); - ks0127_write(sd, KS_OFMTA, 0x20); /* tristate */ - ks0127_write(sd, KS_CMDA, 0x2c | 0x80); /* power down */ - kfree(to_ks0127(sd)); + kfree(ks); return 0; } +static int ks0127_legacy_probe(struct i2c_adapter *adapter) +{ + return adapter->id == I2C_HW_B_ZR36067; +} + static const struct i2c_device_id ks0127_id[] = { { "ks0127", 0 }, - { "ks0127b", 0 }, - { "ks0122s", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, ks0127_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "ks0127", + .driverid = I2C_DRIVERID_KS0127, + .command = ks0127_command, .probe = ks0127_probe, .remove = ks0127_remove, + .legacy_probe = ks0127_legacy_probe, .id_table = ks0127_id, }; diff --git a/trunk/drivers/media/video/ks0127.h b/trunk/drivers/media/video/ks0127.h index cb8abd5403b3..1ec578833aea 100644 --- a/trunk/drivers/media/video/ks0127.h +++ b/trunk/drivers/media/video/ks0127.h @@ -24,6 +24,8 @@ #ifndef KS0127_H #define KS0127_H +#include + /* input channels */ #define KS_INPUT_COMPOSITE_1 0 #define KS_INPUT_COMPOSITE_2 1 diff --git a/trunk/drivers/media/video/m52790.c b/trunk/drivers/media/video/m52790.c index 1f340fefc49d..de397ef57b44 100644 --- a/trunk/drivers/media/video/m52790.c +++ b/trunk/drivers/media/video/m52790.c @@ -132,6 +132,11 @@ static int m52790_log_status(struct v4l2_subdev *sd) return 0; } +static int m52790_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops m52790_core_ops = { @@ -205,6 +210,8 @@ MODULE_DEVICE_TABLE(i2c, m52790_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "m52790", + .driverid = I2C_DRIVERID_M52790, + .command = m52790_command, .probe = m52790_probe, .remove = m52790_remove, .id_table = m52790_id, diff --git a/trunk/drivers/media/video/meye.c b/trunk/drivers/media/video/meye.c index 2ad11f0999c6..b76e33d5c867 100644 --- a/trunk/drivers/media/video/meye.c +++ b/trunk/drivers/media/video/meye.c @@ -1017,6 +1017,7 @@ static int meyeioc_stilljcapt(int *len) static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { + memset(cap, 0, sizeof(*cap)); strcpy(cap->driver, "meye"); strcpy(cap->card, "meye"); sprintf(cap->bus_info, "PCI:%s", pci_name(meye.mchip_dev)); @@ -1035,6 +1036,8 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) if (i->index != 0) return -EINVAL; + memset(i, 0, sizeof(*i)); + i->index = 0; strcpy(i->name, "Camera"); i->type = V4L2_INPUT_TYPE_CAMERA; @@ -1256,13 +1259,22 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, if (f->index > 1) return -EINVAL; + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (f->index == 0) { /* standard YUV 422 capture */ + memset(f, 0, sizeof(*f)); + f->index = 0; + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->flags = 0; strcpy(f->description, "YUV422"); f->pixelformat = V4L2_PIX_FMT_YUYV; } else { /* compressed MJPEG capture */ + memset(f, 0, sizeof(*f)); + f->index = 1; + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->flags = V4L2_FMT_FLAG_COMPRESSED; strcpy(f->description, "MJPEG"); f->pixelformat = V4L2_PIX_FMT_MJPEG; @@ -1274,6 +1286,9 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV && f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) return -EINVAL; @@ -1304,6 +1319,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format)); + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + switch (meye.mchip_mode) { case MCHIP_HIC_MODE_CONT_OUT: default: @@ -1320,6 +1341,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, f->fmt.pix.bytesperline = f->fmt.pix.width * 2; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; + f->fmt.pix.colorspace = 0; + f->fmt.pix.priv = 0; return 0; } @@ -1327,6 +1350,9 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, static int vidioc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV && f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) return -EINVAL; @@ -1372,6 +1398,9 @@ static int vidioc_reqbufs(struct file *file, void *fh, { int i; + if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (req->memory != V4L2_MEMORY_MMAP) return -EINVAL; @@ -1412,11 +1441,15 @@ static int vidioc_reqbufs(struct file *file, void *fh, static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) { - unsigned int index = buf->index; + int index = buf->index; - if (index >= gbuffers) + if (index < 0 || index >= gbuffers) return -EINVAL; + memset(buf, 0, sizeof(*buf)); + + buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf->index = index; buf->bytesused = meye.grab_buffer[index].size; buf->flags = V4L2_BUF_FLAG_MAPPED; @@ -1438,10 +1471,13 @@ static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (buf->memory != V4L2_MEMORY_MMAP) return -EINVAL; - if (buf->index >= gbuffers) + if (buf->index < 0 || buf->index >= gbuffers) return -EINVAL; if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED) @@ -1461,6 +1497,9 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { int reqnr; + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (buf->memory != V4L2_MEMORY_MMAP) return -EINVAL; diff --git a/trunk/drivers/media/video/msp3400-driver.c b/trunk/drivers/media/video/msp3400-driver.c index 9e8e06cfe5c6..4d7a91852117 100644 --- a/trunk/drivers/media/video/msp3400-driver.c +++ b/trunk/drivers/media/video/msp3400-driver.c @@ -366,6 +366,29 @@ int msp_sleep(struct msp_state *state, int timeout) } /* ------------------------------------------------------------------------ */ +#ifdef CONFIG_VIDEO_ALLOW_V4L1 +static int msp_mode_v4l2_to_v4l1(int rxsubchans, int audmode) +{ + if (rxsubchans == V4L2_TUNER_SUB_MONO) + return VIDEO_SOUND_MONO; + if (rxsubchans == V4L2_TUNER_SUB_STEREO) + return VIDEO_SOUND_STEREO; + if (audmode == V4L2_TUNER_MODE_LANG2) + return VIDEO_SOUND_LANG2; + return VIDEO_SOUND_LANG1; +} + +static int msp_mode_v4l1_to_v4l2(int mode) +{ + if (mode & VIDEO_SOUND_STEREO) + return V4L2_TUNER_MODE_STEREO; + if (mode & VIDEO_SOUND_LANG2) + return V4L2_TUNER_MODE_LANG2; + if (mode & VIDEO_SOUND_LANG1) + return V4L2_TUNER_MODE_LANG1; + return V4L2_TUNER_MODE_MONO; +} +#endif static int msp_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { @@ -459,6 +482,96 @@ static int msp_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) return 0; } +#ifdef CONFIG_VIDEO_ALLOW_V4L1 +static long msp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct msp_state *state = to_state(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); + + switch (cmd) { + /* --- v4l ioctls --- */ + /* take care: bttv does userspace copying, we'll get a + kernel pointer here... */ + case VIDIOCGAUDIO: + { + struct video_audio *va = arg; + + va->flags |= VIDEO_AUDIO_VOLUME | VIDEO_AUDIO_MUTABLE; + if (state->has_sound_processing) + va->flags |= VIDEO_AUDIO_BALANCE | + VIDEO_AUDIO_BASS | + VIDEO_AUDIO_TREBLE; + if (state->muted) + va->flags |= VIDEO_AUDIO_MUTE; + va->volume = state->volume; + va->balance = state->volume ? state->balance : 32768; + va->bass = state->bass; + va->treble = state->treble; + + if (state->radio) + break; + if (state->opmode == OPMODE_AUTOSELECT) + msp_detect_stereo(client); + va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans, state->audmode); + break; + } + + case VIDIOCSAUDIO: + { + struct video_audio *va = arg; + + state->muted = (va->flags & VIDEO_AUDIO_MUTE); + state->volume = va->volume; + state->balance = va->balance; + state->bass = va->bass; + state->treble = va->treble; + msp_set_audio(client); + + if (va->mode != 0 && state->radio == 0 && + state->audmode != msp_mode_v4l1_to_v4l2(va->mode)) { + state->audmode = msp_mode_v4l1_to_v4l2(va->mode); + msp_set_audmode(client); + } + break; + } + + case VIDIOCSCHAN: + { + struct video_channel *vc = arg; + int update = 0; + v4l2_std_id std; + + if (state->radio) + update = 1; + state->radio = 0; + if (vc->norm == VIDEO_MODE_PAL) + std = V4L2_STD_PAL; + else if (vc->norm == VIDEO_MODE_SECAM) + std = V4L2_STD_SECAM; + else + std = V4L2_STD_NTSC; + if (std != state->v4l2_std) { + state->v4l2_std = std; + update = 1; + } + if (update) + msp_wake_thread(client); + break; + } + + case VIDIOCSFREQ: + { + /* new channel -- kick audio carrier scan */ + msp_wake_thread(client); + break; + } + default: + return -ENOIOCTLCMD; + } + return 0; +} +#endif + /* --- v4l2 ioctls --- */ static int msp_s_radio(struct v4l2_subdev *sd) { @@ -600,24 +713,22 @@ static int msp_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) struct msp_state *state = to_state(sd); switch (qc->id) { - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880); - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); - default: - break; + case V4L2_CID_AUDIO_VOLUME: + case V4L2_CID_AUDIO_MUTE: + return v4l2_ctrl_query_fill_std(qc); + default: + break; } if (!state->has_sound_processing) return -EINVAL; switch (qc->id) { - case V4L2_CID_AUDIO_LOUDNESS: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768); - default: - return -EINVAL; + case V4L2_CID_AUDIO_LOUDNESS: + case V4L2_CID_AUDIO_BALANCE: + case V4L2_CID_AUDIO_BASS: + case V4L2_CID_AUDIO_TREBLE: + return v4l2_ctrl_query_fill_std(qc); + default: + return -EINVAL; } return 0; } @@ -709,6 +820,9 @@ static const struct v4l2_subdev_core_ops msp_core_ops = { .g_ctrl = msp_g_ctrl, .s_ctrl = msp_s_ctrl, .queryctrl = msp_queryctrl, +#ifdef CONFIG_VIDEO_ALLOW_V4L1 + .ioctl = msp_ioctl, +#endif }; static const struct v4l2_subdev_tuner_ops msp_tuner_ops = { diff --git a/trunk/drivers/media/video/mt9m001.c b/trunk/drivers/media/video/mt9m001.c index fa7e5093edeb..c1bf75ef2741 100644 --- a/trunk/drivers/media/video/mt9m001.c +++ b/trunk/drivers/media/video/mt9m001.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -72,7 +73,9 @@ struct mt9m001 { struct i2c_client *client; struct soc_camera_device icd; int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ + int switch_gpio; unsigned char autoexposure; + unsigned char datawidth; }; static int reg_read(struct soc_camera_device *icd, const u8 reg) @@ -178,28 +181,92 @@ static int mt9m001_stop_capture(struct soc_camera_device *icd) return 0; } +static int bus_switch_request(struct mt9m001 *mt9m001, + struct soc_camera_link *icl) +{ +#ifdef CONFIG_MT9M001_PCA9536_SWITCH + int ret; + unsigned int gpio = icl->gpio; + + if (gpio_is_valid(gpio)) { + /* We have a data bus switch. */ + ret = gpio_request(gpio, "mt9m001"); + if (ret < 0) { + dev_err(&mt9m001->client->dev, "Cannot get GPIO %u\n", + gpio); + return ret; + } + + ret = gpio_direction_output(gpio, 0); + if (ret < 0) { + dev_err(&mt9m001->client->dev, + "Cannot set GPIO %u to output\n", gpio); + gpio_free(gpio); + return ret; + } + } + + mt9m001->switch_gpio = gpio; +#else + mt9m001->switch_gpio = -EINVAL; +#endif + return 0; +} + +static void bus_switch_release(struct mt9m001 *mt9m001) +{ +#ifdef CONFIG_MT9M001_PCA9536_SWITCH + if (gpio_is_valid(mt9m001->switch_gpio)) + gpio_free(mt9m001->switch_gpio); +#endif +} + +static int bus_switch_act(struct mt9m001 *mt9m001, int go8bit) +{ +#ifdef CONFIG_MT9M001_PCA9536_SWITCH + if (!gpio_is_valid(mt9m001->switch_gpio)) + return -ENODEV; + + gpio_set_value_cansleep(mt9m001->switch_gpio, go8bit); + return 0; +#else + return -ENODEV; +#endif +} + +static int bus_switch_possible(struct mt9m001 *mt9m001) +{ +#ifdef CONFIG_MT9M001_PCA9536_SWITCH + return gpio_is_valid(mt9m001->switch_gpio); +#else + return 0; +#endif +} + static int mt9m001_set_bus_param(struct soc_camera_device *icd, unsigned long flags) { struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); - struct soc_camera_link *icl = mt9m001->client->dev.platform_data; - unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK; + unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; + int ret; - /* Only one width bit may be set */ - if (!is_power_of_2(width_flag)) - return -EINVAL; + /* Flags validity verified in test_bus_param */ - if (icl->set_bus_param) - return icl->set_bus_param(icl, width_flag); + if ((mt9m001->datawidth != 10 && (width_flag == SOCAM_DATAWIDTH_10)) || + (mt9m001->datawidth != 9 && (width_flag == SOCAM_DATAWIDTH_9)) || + (mt9m001->datawidth != 8 && (width_flag == SOCAM_DATAWIDTH_8))) { + /* Well, we actually only can do 10 or 8 bits... */ + if (width_flag == SOCAM_DATAWIDTH_9) + return -EINVAL; + ret = bus_switch_act(mt9m001, + width_flag == SOCAM_DATAWIDTH_8); + if (ret < 0) + return ret; - /* - * Without board specific bus width settings we only support the - * sensors native bus width - */ - if (width_flag == SOCAM_DATAWIDTH_10) - return 0; + mt9m001->datawidth = width_flag == SOCAM_DATAWIDTH_8 ? 8 : 10; + } - return -EINVAL; + return 0; } static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) @@ -207,20 +274,18 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); struct soc_camera_link *icl = mt9m001->client->dev.platform_data; /* MT9M001 has all capture_format parameters fixed */ - unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | + unsigned long flags = SOCAM_DATAWIDTH_10 | SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | - SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER; + SOCAM_MASTER; - if (icl->query_bus_param) - flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK; - else - flags |= SOCAM_DATAWIDTH_10; + if (bus_switch_possible(mt9m001)) + flags |= SOCAM_DATAWIDTH_8; return soc_camera_apply_sensor_flags(icl, flags); } -static int mt9m001_set_crop(struct soc_camera_device *icd, - struct v4l2_rect *rect) +static int mt9m001_set_fmt(struct soc_camera_device *icd, + __u32 pixfmt, struct v4l2_rect *rect) { struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); int ret; @@ -259,20 +324,6 @@ static int mt9m001_set_crop(struct soc_camera_device *icd, return ret; } -static int mt9m001_set_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) -{ - struct v4l2_rect rect = { - .left = icd->x_current, - .top = icd->y_current, - .width = f->fmt.pix.width, - .height = f->fmt.pix.height, - }; - - /* No support for scaling so far, just crop. TODO: use skipping */ - return mt9m001_set_crop(icd, &rect); -} - static int mt9m001_try_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { @@ -398,7 +449,6 @@ static struct soc_camera_ops mt9m001_ops = { .release = mt9m001_release, .start_capture = mt9m001_start_capture, .stop_capture = mt9m001_stop_capture, - .set_crop = mt9m001_set_crop, .set_fmt = mt9m001_set_fmt, .try_fmt = mt9m001_try_fmt, .set_bus_param = mt9m001_set_bus_param, @@ -533,7 +583,6 @@ static int mt9m001_video_probe(struct soc_camera_device *icd) struct soc_camera_link *icl = mt9m001->client->dev.platform_data; s32 data; int ret; - unsigned long flags; /* We must have a parent by now. And it cannot be a wrong one. * So this entire test is completely redundant. */ @@ -554,10 +603,18 @@ static int mt9m001_video_probe(struct soc_camera_device *icd) case 0x8421: mt9m001->model = V4L2_IDENT_MT9M001C12ST; icd->formats = mt9m001_colour_formats; + if (gpio_is_valid(icl->gpio)) + icd->num_formats = ARRAY_SIZE(mt9m001_colour_formats); + else + icd->num_formats = 1; break; case 0x8431: mt9m001->model = V4L2_IDENT_MT9M001C12STM; icd->formats = mt9m001_monochrome_formats; + if (gpio_is_valid(icl->gpio)) + icd->num_formats = ARRAY_SIZE(mt9m001_monochrome_formats); + else + icd->num_formats = 1; break; default: ret = -ENODEV; @@ -566,26 +623,6 @@ static int mt9m001_video_probe(struct soc_camera_device *icd) goto ei2c; } - icd->num_formats = 0; - - /* - * This is a 10bit sensor, so by default we only allow 10bit. - * The platform may support different bus widths due to - * different routing of the data lines. - */ - if (icl->query_bus_param) - flags = icl->query_bus_param(icl); - else - flags = SOCAM_DATAWIDTH_10; - - if (flags & SOCAM_DATAWIDTH_10) - icd->num_formats++; - else - icd->formats++; - - if (flags & SOCAM_DATAWIDTH_8) - icd->num_formats++; - dev_info(&icd->dev, "Detected a MT9M001 chip ID %x (%s)\n", data, data == 0x8431 ? "C12STM" : "C12ST"); @@ -651,10 +688,18 @@ static int mt9m001_probe(struct i2c_client *client, icd->height_max = 1024; icd->y_skip_top = 1; icd->iface = icl->bus_id; + /* Default datawidth - this is the only width this camera (normally) + * supports. It is only with extra logic that it can support + * other widths. Therefore it seems to be a sensible default. */ + mt9m001->datawidth = 10; /* Simulated autoexposure. If enabled, we calculate shutter width * ourselves in the driver based on vertical blanking and frame width */ mt9m001->autoexposure = 1; + ret = bus_switch_request(mt9m001, icl); + if (ret) + goto eswinit; + ret = soc_camera_device_register(icd); if (ret) goto eisdr; @@ -662,6 +707,8 @@ static int mt9m001_probe(struct i2c_client *client, return 0; eisdr: + bus_switch_release(mt9m001); +eswinit: kfree(mt9m001); return ret; } @@ -671,6 +718,7 @@ static int mt9m001_remove(struct i2c_client *client) struct mt9m001 *mt9m001 = i2c_get_clientdata(client); soc_camera_device_unregister(&mt9m001->icd); + bus_switch_release(mt9m001); kfree(mt9m001); return 0; diff --git a/trunk/drivers/media/video/mt9m111.c b/trunk/drivers/media/video/mt9m111.c index cdd1ddb51388..5b8e20979cce 100644 --- a/trunk/drivers/media/video/mt9m111.c +++ b/trunk/drivers/media/video/mt9m111.c @@ -152,7 +152,7 @@ struct mt9m111 { struct soc_camera_device icd; int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */ enum mt9m111_context context; - struct v4l2_rect rect; + unsigned int left, top, width, height; u32 pixfmt; unsigned char autoexposure; unsigned char datawidth; @@ -249,13 +249,12 @@ static int mt9m111_set_context(struct soc_camera_device *icd, return reg_write(CONTEXT_CONTROL, valA); } -static int mt9m111_setup_rect(struct soc_camera_device *icd, - struct v4l2_rect *rect) +static int mt9m111_setup_rect(struct soc_camera_device *icd) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); int ret, is_raw_format; - int width = rect->width; - int height = rect->height; + int width = mt9m111->width; + int height = mt9m111->height; if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8) || (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)) @@ -263,9 +262,9 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd, else is_raw_format = 0; - ret = reg_write(COLUMN_START, rect->left); + ret = reg_write(COLUMN_START, mt9m111->left); if (!ret) - ret = reg_write(ROW_START, rect->top); + ret = reg_write(ROW_START, mt9m111->top); if (is_raw_format) { if (!ret) @@ -394,8 +393,6 @@ static int mt9m111_disable(struct soc_camera_device *icd) static int mt9m111_reset(struct soc_camera_device *icd) { - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - struct soc_camera_link *icl = mt9m111->client->dev.platform_data; int ret; ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); @@ -404,10 +401,6 @@ static int mt9m111_reset(struct soc_camera_device *icd) if (!ret) ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE | MT9M111_RESET_RESET_SOC); - - if (icl->reset) - icl->reset(&mt9m111->client->dev); - return ret; } @@ -427,7 +420,7 @@ static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd) struct soc_camera_link *icl = mt9m111->client->dev.platform_data; unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8; + SOCAM_DATAWIDTH_8; return soc_camera_apply_sensor_flags(icl, flags); } @@ -437,22 +430,6 @@ static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f) return 0; } -static int mt9m111_set_crop(struct soc_camera_device *icd, - struct v4l2_rect *rect) -{ - struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret; - - dev_dbg(&icd->dev, "%s left=%d, top=%d, width=%d, height=%d\n", - __func__, rect->left, rect->top, rect->width, - rect->height); - - ret = mt9m111_setup_rect(icd, rect); - if (!ret) - mt9m111->rect = *rect; - return ret; -} - static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); @@ -503,27 +480,23 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) } static int mt9m111_set_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) + __u32 pixfmt, struct v4l2_rect *rect) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_rect rect = { - .left = mt9m111->rect.left, - .top = mt9m111->rect.top, - .width = pix->width, - .height = pix->height, - }; int ret; + mt9m111->left = rect->left; + mt9m111->top = rect->top; + mt9m111->width = rect->width; + mt9m111->height = rect->height; + dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", - __func__, pix->pixelformat, rect.left, rect.top, rect.width, - rect.height); + __func__, pixfmt, mt9m111->left, mt9m111->top, mt9m111->width, + mt9m111->height); - ret = mt9m111_setup_rect(icd, &rect); - if (!ret) - ret = mt9m111_set_pixfmt(icd, pix->pixelformat); + ret = mt9m111_setup_rect(icd); if (!ret) - mt9m111->rect = rect; + ret = mt9m111_set_pixfmt(icd, pixfmt); return ret; } @@ -654,7 +627,6 @@ static struct soc_camera_ops mt9m111_ops = { .release = mt9m111_release, .start_capture = mt9m111_start_capture, .stop_capture = mt9m111_stop_capture, - .set_crop = mt9m111_set_crop, .set_fmt = mt9m111_set_fmt, .try_fmt = mt9m111_try_fmt, .query_bus_param = mt9m111_query_bus_param, @@ -839,7 +811,7 @@ static int mt9m111_restore_state(struct soc_camera_device *icd) mt9m111_set_context(icd, mt9m111->context); mt9m111_set_pixfmt(icd, mt9m111->pixfmt); - mt9m111_setup_rect(icd, &mt9m111->rect); + mt9m111_setup_rect(icd); mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); mt9m111_set_global_gain(icd, icd->gain); diff --git a/trunk/drivers/media/video/mt9t031.c b/trunk/drivers/media/video/mt9t031.c index 23f9ce9d67ef..349d8e365530 100644 --- a/trunk/drivers/media/video/mt9t031.c +++ b/trunk/drivers/media/video/mt9t031.c @@ -144,11 +144,13 @@ static int mt9t031_init(struct soc_camera_device *icd) int ret; /* Disable chip output, synchronous option update */ + dev_dbg(icd->vdev->parent, "%s\n", __func__); + ret = reg_write(icd, MT9T031_RESET, 1); if (ret >= 0) ret = reg_write(icd, MT9T031_RESET, 0); if (ret >= 0) - ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2); + ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3); return ret >= 0 ? 0 : -EIO; } @@ -156,14 +158,14 @@ static int mt9t031_init(struct soc_camera_device *icd) static int mt9t031_release(struct soc_camera_device *icd) { /* Disable the chip */ - reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2); + reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3); return 0; } static int mt9t031_start_capture(struct soc_camera_device *icd) { /* Switch to master "normal" mode */ - if (reg_set(icd, MT9T031_OUTPUT_CONTROL, 2) < 0) + if (reg_set(icd, MT9T031_OUTPUT_CONTROL, 3) < 0) return -EIO; return 0; } @@ -171,7 +173,7 @@ static int mt9t031_start_capture(struct soc_camera_device *icd) static int mt9t031_stop_capture(struct soc_camera_device *icd) { /* Stop sensor readout */ - if (reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2) < 0) + if (reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3) < 0) return -EIO; return 0; } @@ -184,9 +186,9 @@ static int mt9t031_set_bus_param(struct soc_camera_device *icd, return -EINVAL; if (flags & SOCAM_PCLK_SAMPLE_FALLING) - reg_clear(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); - else reg_set(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); + else + reg_clear(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); return 0; } @@ -199,73 +201,67 @@ static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM); } -/* Round up minima and round down maxima */ -static void recalculate_limits(struct soc_camera_device *icd, - u16 xskip, u16 yskip) -{ - icd->x_min = (MT9T031_COLUMN_SKIP + xskip - 1) / xskip; - icd->y_min = (MT9T031_ROW_SKIP + yskip - 1) / yskip; - icd->width_min = (MT9T031_MIN_WIDTH + xskip - 1) / xskip; - icd->height_min = (MT9T031_MIN_HEIGHT + yskip - 1) / yskip; - icd->width_max = MT9T031_MAX_WIDTH / xskip; - icd->height_max = MT9T031_MAX_HEIGHT / yskip; -} - -static int mt9t031_set_params(struct soc_camera_device *icd, - struct v4l2_rect *rect, u16 xskip, u16 yskip) +static int mt9t031_set_fmt(struct soc_camera_device *icd, + __u32 pixfmt, struct v4l2_rect *rect) { struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); int ret; - u16 xbin, ybin, width, height, left, top; const u16 hblank = MT9T031_HORIZONTAL_BLANK, vblank = MT9T031_VERTICAL_BLANK; + u16 xbin, xskip = mt9t031->xskip, ybin, yskip = mt9t031->yskip, + width = rect->width * xskip, height = rect->height * yskip; - /* Make sure we don't exceed sensor limits */ - if (rect->left + rect->width > icd->width_max) - rect->left = (icd->width_max - rect->width) / 2 + icd->x_min; + if (pixfmt) { + /* S_FMT - use binning and skipping for scaling, recalculate */ + /* Is this more optimal than just a division? */ + for (xskip = 8; xskip > 1; xskip--) + if (rect->width * xskip <= icd->width_max) + break; - if (rect->top + rect->height > icd->height_max) - rect->top = (icd->height_max - rect->height) / 2 + icd->y_min; + for (yskip = 8; yskip > 1; yskip--) + if (rect->height * yskip <= icd->height_max) + break; - width = rect->width * xskip; - height = rect->height * yskip; - left = rect->left * xskip; - top = rect->top * yskip; + width = rect->width * xskip; + height = rect->height * yskip; + + dev_dbg(&icd->dev, "xskip %u, width %u, yskip %u, height %u\n", + xskip, width, yskip, height); + } xbin = min(xskip, (u16)3); ybin = min(yskip, (u16)3); - dev_dbg(&icd->dev, "xskip %u, width %u/%u, yskip %u, height %u/%u\n", - xskip, width, rect->width, yskip, height, rect->height); + /* Make sure we don't exceed frame limits */ + if (rect->left + width > icd->width_max) + rect->left = (icd->width_max - width) / 2; + + if (rect->top + height > icd->height_max) + rect->top = (icd->height_max - height) / 2; - /* Could just do roundup(rect->left, [xy]bin * 2); but this is cheaper */ + /* Could just do roundup(rect->left, [xy]bin); but this is cheaper */ switch (xbin) { case 2: - left = (left + 3) & ~3; + rect->left = (rect->left + 1) & ~1; break; case 3: - left = roundup(left, 6); + rect->left = roundup(rect->left, 3); } switch (ybin) { case 2: - top = (top + 3) & ~3; + rect->top = (rect->top + 1) & ~1; break; case 3: - top = roundup(top, 6); + rect->top = roundup(rect->top, 3); } - /* Disable register update, reconfigure atomically */ - ret = reg_set(icd, MT9T031_OUTPUT_CONTROL, 1); - if (ret < 0) - return ret; - /* Blanking and start values - default... */ ret = reg_write(icd, MT9T031_HORIZONTAL_BLANKING, hblank); if (ret >= 0) ret = reg_write(icd, MT9T031_VERTICAL_BLANKING, vblank); - if (yskip != mt9t031->yskip || xskip != mt9t031->xskip) { + if (pixfmt) { /* Binning, skipping */ if (ret >= 0) ret = reg_write(icd, MT9T031_COLUMN_ADDRESS_MODE, @@ -274,14 +270,14 @@ static int mt9t031_set_params(struct soc_camera_device *icd, ret = reg_write(icd, MT9T031_ROW_ADDRESS_MODE, ((ybin - 1) << 4) | (yskip - 1)); } - dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top); + dev_dbg(&icd->dev, "new left %u, top %u\n", rect->left, rect->top); /* The caller provides a supported format, as guaranteed by * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */ if (ret >= 0) - ret = reg_write(icd, MT9T031_COLUMN_START, left); + ret = reg_write(icd, MT9T031_COLUMN_START, rect->left); if (ret >= 0) - ret = reg_write(icd, MT9T031_ROW_START, top); + ret = reg_write(icd, MT9T031_ROW_START, rect->top); if (ret >= 0) ret = reg_write(icd, MT9T031_WINDOW_WIDTH, width - 1); if (ret >= 0) @@ -301,58 +297,12 @@ static int mt9t031_set_params(struct soc_camera_device *icd, } } - /* Re-enable register update, commit all changes */ - if (ret >= 0) - ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 1); - - return ret < 0 ? ret : 0; -} - -static int mt9t031_set_crop(struct soc_camera_device *icd, - struct v4l2_rect *rect) -{ - struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); - - /* CROP - no change in scaling, or in limits */ - return mt9t031_set_params(icd, rect, mt9t031->xskip, mt9t031->yskip); -} - -static int mt9t031_set_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) -{ - struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); - int ret; - u16 xskip, yskip; - struct v4l2_rect rect = { - .left = icd->x_current, - .top = icd->y_current, - .width = f->fmt.pix.width, - .height = f->fmt.pix.height, - }; - - /* - * try_fmt has put rectangle within limits. - * S_FMT - use binning and skipping for scaling, recalculate - * limits, used for cropping - */ - /* Is this more optimal than just a division? */ - for (xskip = 8; xskip > 1; xskip--) - if (rect.width * xskip <= MT9T031_MAX_WIDTH) - break; - - for (yskip = 8; yskip > 1; yskip--) - if (rect.height * yskip <= MT9T031_MAX_HEIGHT) - break; - - recalculate_limits(icd, xskip, yskip); - - ret = mt9t031_set_params(icd, &rect, xskip, yskip); - if (!ret) { + if (!ret && pixfmt) { mt9t031->xskip = xskip; mt9t031->yskip = yskip; } - return ret; + return ret < 0 ? ret : 0; } static int mt9t031_try_fmt(struct soc_camera_device *icd, @@ -360,14 +310,14 @@ static int mt9t031_try_fmt(struct soc_camera_device *icd, { struct v4l2_pix_format *pix = &f->fmt.pix; - if (pix->height < MT9T031_MIN_HEIGHT) - pix->height = MT9T031_MIN_HEIGHT; - if (pix->height > MT9T031_MAX_HEIGHT) - pix->height = MT9T031_MAX_HEIGHT; - if (pix->width < MT9T031_MIN_WIDTH) - pix->width = MT9T031_MIN_WIDTH; - if (pix->width > MT9T031_MAX_WIDTH) - pix->width = MT9T031_MAX_WIDTH; + if (pix->height < icd->height_min) + pix->height = icd->height_min; + if (pix->height > icd->height_max) + pix->height = icd->height_max; + if (pix->width < icd->width_min) + pix->width = icd->width_min; + if (pix->width > icd->width_max) + pix->width = icd->width_max; pix->width &= ~0x01; /* has to be even */ pix->height &= ~0x01; /* has to be even */ @@ -439,14 +389,6 @@ static const struct v4l2_queryctrl mt9t031_controls[] = { .maximum = 1, .step = 1, .default_value = 0, - }, { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Horizontally", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, }, { .id = V4L2_CID_GAIN, .type = V4L2_CTRL_TYPE_INTEGER, @@ -489,7 +431,6 @@ static struct soc_camera_ops mt9t031_ops = { .release = mt9t031_release, .start_capture = mt9t031_start_capture, .stop_capture = mt9t031_stop_capture, - .set_crop = mt9t031_set_crop, .set_fmt = mt9t031_set_fmt, .try_fmt = mt9t031_try_fmt, .set_bus_param = mt9t031_set_bus_param, @@ -572,23 +513,21 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro if (data < 0) return -EIO; } else { - /* Pack it into 1.125..128 variable step, register values 9..0x7860 */ + /* Pack it into 1.125..15 variable step, register values 9..67 */ /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */ unsigned long range = qctrl->maximum - qctrl->default_value - 1; - /* calculated gain: map 65..127 to 9..1024 step 0.125 */ unsigned long gain = ((ctrl->value - qctrl->default_value - 1) * - 1015 + range / 2) / range + 9; + 111 + range / 2) / range + 9; - if (gain <= 32) /* calculated gain 9..32 -> 9..32 */ + if (gain <= 32) data = gain; - else if (gain <= 64) /* calculated gain 33..64 -> 0x51..0x60 */ + else if (gain <= 64) data = ((gain - 32) * 16 + 16) / 32 + 80; else - /* calculated gain 65..1024 -> (1..120) << 8 + 0x60 */ - data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60; + data = ((gain - 64) * 7 + 28) / 56 + 96; - dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n", - reg_read(icd, MT9T031_GLOBAL_GAIN), data); + dev_dbg(&icd->dev, "Setting gain from %d to %d\n", + reg_read(icd, MT9T031_GLOBAL_GAIN), data); data = reg_write(icd, MT9T031_GLOBAL_GAIN, data); if (data < 0) return -EIO; diff --git a/trunk/drivers/media/video/mt9v022.c b/trunk/drivers/media/video/mt9v022.c index 4d3b4813c322..b04c8cb1644d 100644 --- a/trunk/drivers/media/video/mt9v022.c +++ b/trunk/drivers/media/video/mt9v022.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -88,7 +89,9 @@ struct mt9v022 { struct i2c_client *client; struct soc_camera_device icd; int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ + int switch_gpio; u16 chip_control; + unsigned char datawidth; }; static int reg_read(struct soc_camera_device *icd, const u8 reg) @@ -206,6 +209,66 @@ static int mt9v022_stop_capture(struct soc_camera_device *icd) return 0; } +static int bus_switch_request(struct mt9v022 *mt9v022, struct soc_camera_link *icl) +{ +#ifdef CONFIG_MT9V022_PCA9536_SWITCH + int ret; + unsigned int gpio = icl->gpio; + + if (gpio_is_valid(gpio)) { + /* We have a data bus switch. */ + ret = gpio_request(gpio, "mt9v022"); + if (ret < 0) { + dev_err(&mt9v022->client->dev, "Cannot get GPIO %u\n", gpio); + return ret; + } + + ret = gpio_direction_output(gpio, 0); + if (ret < 0) { + dev_err(&mt9v022->client->dev, + "Cannot set GPIO %u to output\n", gpio); + gpio_free(gpio); + return ret; + } + } + + mt9v022->switch_gpio = gpio; +#else + mt9v022->switch_gpio = -EINVAL; +#endif + return 0; +} + +static void bus_switch_release(struct mt9v022 *mt9v022) +{ +#ifdef CONFIG_MT9V022_PCA9536_SWITCH + if (gpio_is_valid(mt9v022->switch_gpio)) + gpio_free(mt9v022->switch_gpio); +#endif +} + +static int bus_switch_act(struct mt9v022 *mt9v022, int go8bit) +{ +#ifdef CONFIG_MT9V022_PCA9536_SWITCH + if (!gpio_is_valid(mt9v022->switch_gpio)) + return -ENODEV; + + gpio_set_value_cansleep(mt9v022->switch_gpio, go8bit); + return 0; +#else + return -ENODEV; +#endif +} + +static int bus_switch_possible(struct mt9v022 *mt9v022) +{ +#ifdef CONFIG_MT9V022_PCA9536_SWITCH + return gpio_is_valid(mt9v022->switch_gpio); +#else + return 0; +#endif +} + static int mt9v022_set_bus_param(struct soc_camera_device *icd, unsigned long flags) { @@ -219,17 +282,19 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd, if (!is_power_of_2(width_flag)) return -EINVAL; - if (icl->set_bus_param) { - ret = icl->set_bus_param(icl, width_flag); - if (ret) - return ret; - } else { - /* - * Without board specific bus width settings we only support the - * sensors native bus width - */ - if (width_flag != SOCAM_DATAWIDTH_10) + if ((mt9v022->datawidth != 10 && (width_flag == SOCAM_DATAWIDTH_10)) || + (mt9v022->datawidth != 9 && (width_flag == SOCAM_DATAWIDTH_9)) || + (mt9v022->datawidth != 8 && (width_flag == SOCAM_DATAWIDTH_8))) { + /* Well, we actually only can do 10 or 8 bits... */ + if (width_flag == SOCAM_DATAWIDTH_9) return -EINVAL; + + ret = bus_switch_act(mt9v022, + width_flag == SOCAM_DATAWIDTH_8); + if (ret < 0) + return ret; + + mt9v022->datawidth = width_flag == SOCAM_DATAWIDTH_8 ? 8 : 10; } flags = soc_camera_apply_sensor_flags(icl, flags); @@ -263,27 +328,44 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd, static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd) { struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); - struct soc_camera_link *icl = mt9v022->client->dev.platform_data; - unsigned int width_flag; + unsigned int width_flag = SOCAM_DATAWIDTH_10; - if (icl->query_bus_param) - width_flag = icl->query_bus_param(icl) & - SOCAM_DATAWIDTH_MASK; - else - width_flag = SOCAM_DATAWIDTH_10; + if (bus_switch_possible(mt9v022)) + width_flag |= SOCAM_DATAWIDTH_8; return SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW | - SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_SLAVE | + SOCAM_MASTER | SOCAM_SLAVE | width_flag; } -static int mt9v022_set_crop(struct soc_camera_device *icd, - struct v4l2_rect *rect) +static int mt9v022_set_fmt(struct soc_camera_device *icd, + __u32 pixfmt, struct v4l2_rect *rect) { + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); int ret; + /* The caller provides a supported format, as verified per call to + * icd->try_fmt(), datawidth is from our supported format list */ + switch (pixfmt) { + case V4L2_PIX_FMT_GREY: + case V4L2_PIX_FMT_Y16: + if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM) + return -EINVAL; + break; + case V4L2_PIX_FMT_SBGGR8: + case V4L2_PIX_FMT_SBGGR16: + if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) + return -EINVAL; + break; + case 0: + /* No format change, only geometry */ + break; + default: + return -EINVAL; + } + /* Like in example app. Contradicts the datasheet though */ ret = reg_read(icd, MT9V022_AEC_AGC_ENABLE); if (ret >= 0) { @@ -321,42 +403,6 @@ static int mt9v022_set_crop(struct soc_camera_device *icd, return 0; } -static int mt9v022_set_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) -{ - struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); - struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_rect rect = { - .left = icd->x_current, - .top = icd->y_current, - .width = pix->width, - .height = pix->height, - }; - - /* The caller provides a supported format, as verified per call to - * icd->try_fmt(), datawidth is from our supported format list */ - switch (pix->pixelformat) { - case V4L2_PIX_FMT_GREY: - case V4L2_PIX_FMT_Y16: - if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM) - return -EINVAL; - break; - case V4L2_PIX_FMT_SBGGR8: - case V4L2_PIX_FMT_SBGGR16: - if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) - return -EINVAL; - break; - case 0: - /* No format change, only geometry */ - break; - default: - return -EINVAL; - } - - /* No support for scaling on this camera, just crop. */ - return mt9v022_set_crop(icd, &rect); -} - static int mt9v022_try_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { @@ -498,7 +544,6 @@ static struct soc_camera_ops mt9v022_ops = { .release = mt9v022_release, .start_capture = mt9v022_start_capture, .stop_capture = mt9v022_stop_capture, - .set_crop = mt9v022_set_crop, .set_fmt = mt9v022_set_fmt, .try_fmt = mt9v022_try_fmt, .set_bus_param = mt9v022_set_bus_param, @@ -654,7 +699,6 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) struct soc_camera_link *icl = mt9v022->client->dev.platform_data; s32 data; int ret; - unsigned long flags; if (!icd->dev.parent || to_soc_camera_host(icd->dev.parent)->nr != icd->iface) @@ -688,36 +732,22 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; icd->formats = mt9v022_colour_formats; + if (gpio_is_valid(icl->gpio)) + icd->num_formats = ARRAY_SIZE(mt9v022_colour_formats); + else + icd->num_formats = 1; } else { ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 0x11); mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; icd->formats = mt9v022_monochrome_formats; + if (gpio_is_valid(icl->gpio)) + icd->num_formats = ARRAY_SIZE(mt9v022_monochrome_formats); + else + icd->num_formats = 1; } - if (ret < 0) - goto eisis; - - icd->num_formats = 0; - - /* - * This is a 10bit sensor, so by default we only allow 10bit. - * The platform may support different bus widths due to - * different routing of the data lines. - */ - if (icl->query_bus_param) - flags = icl->query_bus_param(icl); - else - flags = SOCAM_DATAWIDTH_10; - - if (flags & SOCAM_DATAWIDTH_10) - icd->num_formats++; - else - icd->formats++; - - if (flags & SOCAM_DATAWIDTH_8) - icd->num_formats++; - - ret = soc_camera_video_start(icd); + if (!ret) + ret = soc_camera_video_start(icd); if (ret < 0) goto eisis; @@ -782,6 +812,14 @@ static int mt9v022_probe(struct i2c_client *client, icd->height_max = 480; icd->y_skip_top = 1; icd->iface = icl->bus_id; + /* Default datawidth - this is the only width this camera (normally) + * supports. It is only with extra logic that it can support + * other widths. Therefore it seems to be a sensible default. */ + mt9v022->datawidth = 10; + + ret = bus_switch_request(mt9v022, icl); + if (ret) + goto eswinit; ret = soc_camera_device_register(icd); if (ret) @@ -790,6 +828,8 @@ static int mt9v022_probe(struct i2c_client *client, return 0; eisdr: + bus_switch_release(mt9v022); +eswinit: kfree(mt9v022); return ret; } @@ -799,6 +839,7 @@ static int mt9v022_remove(struct i2c_client *client) struct mt9v022 *mt9v022 = i2c_get_clientdata(client); soc_camera_device_unregister(&mt9v022->icd); + bus_switch_release(mt9v022); kfree(mt9v022); return 0; diff --git a/trunk/drivers/media/video/mx3_camera.c b/trunk/drivers/media/video/mx3_camera.c deleted file mode 100644 index 70629e172e65..000000000000 --- a/trunk/drivers/media/video/mx3_camera.c +++ /dev/null @@ -1,1220 +0,0 @@ -/* - * V4L2 Driver for i.MX3x camera host - * - * Copyright (C) 2008 - * Guennadi Liakhovetski, DENX Software Engineering, - * - * 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 -#include - -#include -#include -#include -#include - -#include -#include - -#define MX3_CAM_DRV_NAME "mx3-camera" - -/* CMOS Sensor Interface Registers */ -#define CSI_REG_START 0x60 - -#define CSI_SENS_CONF (0x60 - CSI_REG_START) -#define CSI_SENS_FRM_SIZE (0x64 - CSI_REG_START) -#define CSI_ACT_FRM_SIZE (0x68 - CSI_REG_START) -#define CSI_OUT_FRM_CTRL (0x6C - CSI_REG_START) -#define CSI_TST_CTRL (0x70 - CSI_REG_START) -#define CSI_CCIR_CODE_1 (0x74 - CSI_REG_START) -#define CSI_CCIR_CODE_2 (0x78 - CSI_REG_START) -#define CSI_CCIR_CODE_3 (0x7C - CSI_REG_START) -#define CSI_FLASH_STROBE_1 (0x80 - CSI_REG_START) -#define CSI_FLASH_STROBE_2 (0x84 - CSI_REG_START) - -#define CSI_SENS_CONF_VSYNC_POL_SHIFT 0 -#define CSI_SENS_CONF_HSYNC_POL_SHIFT 1 -#define CSI_SENS_CONF_DATA_POL_SHIFT 2 -#define CSI_SENS_CONF_PIX_CLK_POL_SHIFT 3 -#define CSI_SENS_CONF_SENS_PRTCL_SHIFT 4 -#define CSI_SENS_CONF_SENS_CLKSRC_SHIFT 7 -#define CSI_SENS_CONF_DATA_FMT_SHIFT 8 -#define CSI_SENS_CONF_DATA_WIDTH_SHIFT 10 -#define CSI_SENS_CONF_EXT_VSYNC_SHIFT 15 -#define CSI_SENS_CONF_DIVRATIO_SHIFT 16 - -#define CSI_SENS_CONF_DATA_FMT_RGB_YUV444 (0UL << CSI_SENS_CONF_DATA_FMT_SHIFT) -#define CSI_SENS_CONF_DATA_FMT_YUV422 (2UL << CSI_SENS_CONF_DATA_FMT_SHIFT) -#define CSI_SENS_CONF_DATA_FMT_BAYER (3UL << CSI_SENS_CONF_DATA_FMT_SHIFT) - -#define MAX_VIDEO_MEM 16 - -struct mx3_camera_buffer { - /* common v4l buffer stuff -- must be first */ - struct videobuf_buffer vb; - const struct soc_camera_data_format *fmt; - - /* One descriptot per scatterlist (per frame) */ - struct dma_async_tx_descriptor *txd; - - /* We have to "build" a scatterlist ourselves - one element per frame */ - struct scatterlist sg; -}; - -/** - * struct mx3_camera_dev - i.MX3x camera (CSI) object - * @dev: camera device, to which the coherent buffer is attached - * @icd: currently attached camera sensor - * @clk: pointer to clock - * @base: remapped register base address - * @pdata: platform data - * @platform_flags: platform flags - * @mclk: master clock frequency in Hz - * @capture: list of capture videobuffers - * @lock: protects video buffer lists - * @active: active video buffer - * @idmac_channel: array of pointers to IPU DMAC DMA channels - * @soc_host: embedded soc_host object - */ -struct mx3_camera_dev { - struct device *dev; - /* - * i.MX3x is only supposed to handle one camera on its Camera Sensor - * Interface. If anyone ever builds hardware to enable more than one - * camera _simultaneously_, they will have to modify this driver too - */ - struct soc_camera_device *icd; - struct clk *clk; - - void __iomem *base; - - struct mx3_camera_pdata *pdata; - - unsigned long platform_flags; - unsigned long mclk; - - struct list_head capture; - spinlock_t lock; /* Protects video buffer lists */ - struct mx3_camera_buffer *active; - - /* IDMAC / dmaengine interface */ - struct idmac_channel *idmac_channel[1]; /* We need one channel */ - - struct soc_camera_host soc_host; -}; - -struct dma_chan_request { - struct mx3_camera_dev *mx3_cam; - enum ipu_channel id; -}; - -static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt); - -static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg) -{ - return __raw_readl(mx3->base + reg); -} - -static void csi_reg_write(struct mx3_camera_dev *mx3, u32 value, off_t reg) -{ - __raw_writel(value, mx3->base + reg); -} - -/* Called from the IPU IDMAC ISR */ -static void mx3_cam_dma_done(void *arg) -{ - struct idmac_tx_desc *desc = to_tx_desc(arg); - struct dma_chan *chan = desc->txd.chan; - struct idmac_channel *ichannel = to_idmac_chan(chan); - struct mx3_camera_dev *mx3_cam = ichannel->client; - struct videobuf_buffer *vb; - - dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n", - desc->txd.cookie, mx3_cam->active ? sg_dma_address(&mx3_cam->active->sg) : 0); - - spin_lock(&mx3_cam->lock); - if (mx3_cam->active) { - vb = &mx3_cam->active->vb; - - list_del_init(&vb->queue); - vb->state = VIDEOBUF_DONE; - do_gettimeofday(&vb->ts); - vb->field_count++; - wake_up(&vb->done); - } - - if (list_empty(&mx3_cam->capture)) { - mx3_cam->active = NULL; - spin_unlock(&mx3_cam->lock); - - /* - * stop capture - without further buffers IPU_CHA_BUF0_RDY will - * not get updated - */ - return; - } - - mx3_cam->active = list_entry(mx3_cam->capture.next, - struct mx3_camera_buffer, vb.queue); - mx3_cam->active->vb.state = VIDEOBUF_ACTIVE; - spin_unlock(&mx3_cam->lock); -} - -static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf) -{ - struct soc_camera_device *icd = vq->priv_data; - struct videobuf_buffer *vb = &buf->vb; - struct dma_async_tx_descriptor *txd = buf->txd; - struct idmac_channel *ichan; - - BUG_ON(in_interrupt()); - - dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, - vb, vb->baddr, vb->bsize); - - /* - * This waits until this buffer is out of danger, i.e., until it is no - * longer in STATE_QUEUED or STATE_ACTIVE - */ - videobuf_waiton(vb, 0, 0); - if (txd) { - ichan = to_idmac_chan(txd->chan); - async_tx_ack(txd); - } - videobuf_dma_contig_free(vq, vb); - buf->txd = NULL; - - vb->state = VIDEOBUF_NEEDS_INIT; -} - -/* - * Videobuf operations - */ - -/* - * Calculate the __buffer__ (not data) size and number of buffers. - * Called with .vb_lock held - */ -static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, - unsigned int *size) -{ - struct soc_camera_device *icd = vq->priv_data; - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct mx3_camera_dev *mx3_cam = ici->priv; - /* - * bits-per-pixel (depth) as specified in camera's pixel format does - * not necessarily match what the camera interface writes to RAM, but - * it should be good enough for now. - */ - unsigned int bpp = DIV_ROUND_UP(icd->current_fmt->depth, 8); - - if (!mx3_cam->idmac_channel[0]) - return -EINVAL; - - *size = icd->width * icd->height * bpp; - - if (!*count) - *count = 32; - - if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024) - *count = MAX_VIDEO_MEM * 1024 * 1024 / *size; - - return 0; -} - -/* Called with .vb_lock held */ -static int mx3_videobuf_prepare(struct videobuf_queue *vq, - struct videobuf_buffer *vb, enum v4l2_field field) -{ - struct soc_camera_device *icd = vq->priv_data; - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct mx3_camera_dev *mx3_cam = ici->priv; - struct mx3_camera_buffer *buf = - container_of(vb, struct mx3_camera_buffer, vb); - /* current_fmt _must_ always be set */ - size_t new_size = icd->width * icd->height * - ((icd->current_fmt->depth + 7) >> 3); - int ret; - - /* - * I think, in buf_prepare you only have to protect global data, - * the actual buffer is yours - */ - - if (buf->fmt != icd->current_fmt || - vb->width != icd->width || - vb->height != icd->height || - vb->field != field) { - buf->fmt = icd->current_fmt; - vb->width = icd->width; - vb->height = icd->height; - vb->field = field; - if (vb->state != VIDEOBUF_NEEDS_INIT) - free_buffer(vq, buf); - } - - if (vb->baddr && vb->bsize < new_size) { - /* User provided buffer, but it is too small */ - ret = -ENOMEM; - goto out; - } - - if (vb->state == VIDEOBUF_NEEDS_INIT) { - struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; - struct scatterlist *sg = &buf->sg; - - /* - * The total size of video-buffers that will be allocated / mapped. - * *size that we calculated in videobuf_setup gets assigned to - * vb->bsize, and now we use the same calculation to get vb->size. - */ - vb->size = new_size; - - /* This actually (allocates and) maps buffers */ - ret = videobuf_iolock(vq, vb, NULL); - if (ret) - goto fail; - - /* - * We will have to configure the IDMAC channel. It has two slots - * for DMA buffers, we shall enter the first two buffers there, - * and then submit new buffers in DMA-ready interrupts - */ - sg_init_table(sg, 1); - sg_dma_address(sg) = videobuf_to_dma_contig(vb); - sg_dma_len(sg) = vb->size; - - buf->txd = ichan->dma_chan.device->device_prep_slave_sg( - &ichan->dma_chan, sg, 1, DMA_FROM_DEVICE, - DMA_PREP_INTERRUPT); - if (!buf->txd) { - ret = -EIO; - goto fail; - } - - buf->txd->callback_param = buf->txd; - buf->txd->callback = mx3_cam_dma_done; - - vb->state = VIDEOBUF_PREPARED; - } - - return 0; - -fail: - free_buffer(vq, buf); -out: - return ret; -} - -static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc) -{ - /* Add more formats as need arises and test possibilities appear... */ - switch (fourcc) { - case V4L2_PIX_FMT_RGB565: - return IPU_PIX_FMT_RGB565; - case V4L2_PIX_FMT_RGB24: - return IPU_PIX_FMT_RGB24; - case V4L2_PIX_FMT_RGB332: - return IPU_PIX_FMT_RGB332; - case V4L2_PIX_FMT_YUV422P: - return IPU_PIX_FMT_YVU422P; - default: - return IPU_PIX_FMT_GENERIC; - } -} - -/* Called with .vb_lock held */ -static void mx3_videobuf_queue(struct videobuf_queue *vq, - struct videobuf_buffer *vb) -{ - struct soc_camera_device *icd = vq->priv_data; - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct mx3_camera_dev *mx3_cam = ici->priv; - struct mx3_camera_buffer *buf = - container_of(vb, struct mx3_camera_buffer, vb); - struct dma_async_tx_descriptor *txd = buf->txd; - struct idmac_channel *ichan = to_idmac_chan(txd->chan); - struct idmac_video_param *video = &ichan->params.video; - const struct soc_camera_data_format *data_fmt = icd->current_fmt; - dma_cookie_t cookie; - unsigned long flags; - - /* This is the configuration of one sg-element */ - video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc); - video->out_width = icd->width; - video->out_height = icd->height; - video->out_stride = icd->width; - -#ifdef DEBUG - /* helps to see what DMA actually has written */ - memset((void *)vb->baddr, 0xaa, vb->bsize); -#endif - - spin_lock_irqsave(&mx3_cam->lock, flags); - - list_add_tail(&vb->queue, &mx3_cam->capture); - - if (!mx3_cam->active) { - mx3_cam->active = buf; - vb->state = VIDEOBUF_ACTIVE; - } else { - vb->state = VIDEOBUF_QUEUED; - } - - spin_unlock_irqrestore(&mx3_cam->lock, flags); - - cookie = txd->tx_submit(txd); - dev_dbg(&icd->dev, "Submitted cookie %d DMA 0x%08x\n", cookie, sg_dma_address(&buf->sg)); - if (cookie >= 0) - return; - - /* Submit error */ - vb->state = VIDEOBUF_PREPARED; - - spin_lock_irqsave(&mx3_cam->lock, flags); - - list_del_init(&vb->queue); - - if (mx3_cam->active == buf) - mx3_cam->active = NULL; - - spin_unlock_irqrestore(&mx3_cam->lock, flags); -} - -/* Called with .vb_lock held */ -static void mx3_videobuf_release(struct videobuf_queue *vq, - struct videobuf_buffer *vb) -{ - struct soc_camera_device *icd = vq->priv_data; - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct mx3_camera_dev *mx3_cam = ici->priv; - struct mx3_camera_buffer *buf = - container_of(vb, struct mx3_camera_buffer, vb); - unsigned long flags; - - dev_dbg(&icd->dev, "Release%s DMA 0x%08x (state %d), queue %sempty\n", - mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg), - vb->state, list_empty(&vb->queue) ? "" : "not "); - spin_lock_irqsave(&mx3_cam->lock, flags); - if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) && - !list_empty(&vb->queue)) { - vb->state = VIDEOBUF_ERROR; - - list_del_init(&vb->queue); - if (mx3_cam->active == buf) - mx3_cam->active = NULL; - } - spin_unlock_irqrestore(&mx3_cam->lock, flags); - free_buffer(vq, buf); -} - -static struct videobuf_queue_ops mx3_videobuf_ops = { - .buf_setup = mx3_videobuf_setup, - .buf_prepare = mx3_videobuf_prepare, - .buf_queue = mx3_videobuf_queue, - .buf_release = mx3_videobuf_release, -}; - -static void mx3_camera_init_videobuf(struct videobuf_queue *q, - struct soc_camera_device *icd) -{ - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct mx3_camera_dev *mx3_cam = ici->priv; - - videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, mx3_cam->dev, - &mx3_cam->lock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_NONE, - sizeof(struct mx3_camera_buffer), icd); -} - -/* First part of ipu_csi_init_interface() */ -static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam, - struct soc_camera_device *icd) -{ - u32 conf; - long rate; - - /* Set default size: ipu_csi_set_window_size() */ - csi_reg_write(mx3_cam, (640 - 1) | ((480 - 1) << 16), CSI_ACT_FRM_SIZE); - /* ...and position to 0:0: ipu_csi_set_window_pos() */ - conf = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000; - csi_reg_write(mx3_cam, conf, CSI_OUT_FRM_CTRL); - - /* We use only gated clock synchronisation mode so far */ - conf = 0 << CSI_SENS_CONF_SENS_PRTCL_SHIFT; - - /* Set generic data, platform-biggest bus-width */ - conf |= CSI_SENS_CONF_DATA_FMT_BAYER; - - if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15) - conf |= 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; - else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10) - conf |= 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; - else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8) - conf |= 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; - else/* if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)*/ - conf |= 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; - - if (mx3_cam->platform_flags & MX3_CAMERA_CLK_SRC) - conf |= 1 << CSI_SENS_CONF_SENS_CLKSRC_SHIFT; - if (mx3_cam->platform_flags & MX3_CAMERA_EXT_VSYNC) - conf |= 1 << CSI_SENS_CONF_EXT_VSYNC_SHIFT; - if (mx3_cam->platform_flags & MX3_CAMERA_DP) - conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT; - if (mx3_cam->platform_flags & MX3_CAMERA_PCP) - conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT; - if (mx3_cam->platform_flags & MX3_CAMERA_HSP) - conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT; - if (mx3_cam->platform_flags & MX3_CAMERA_VSP) - conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT; - - /* ipu_csi_init_interface() */ - csi_reg_write(mx3_cam, conf, CSI_SENS_CONF); - - clk_enable(mx3_cam->clk); - rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk); - dev_dbg(&icd->dev, "Set SENS_CONF to %x, rate %ld\n", conf, rate); - if (rate) - clk_set_rate(mx3_cam->clk, rate); -} - -/* Called with .video_lock held */ -static int mx3_camera_add_device(struct soc_camera_device *icd) -{ - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct mx3_camera_dev *mx3_cam = ici->priv; - int ret; - - if (mx3_cam->icd) { - ret = -EBUSY; - goto ebusy; - } - - mx3_camera_activate(mx3_cam, icd); - ret = icd->ops->init(icd); - if (ret < 0) { - clk_disable(mx3_cam->clk); - goto einit; - } - - mx3_cam->icd = icd; - -einit: -ebusy: - if (!ret) - dev_info(&icd->dev, "MX3 Camera driver attached to camera %d\n", - icd->devnum); - - return ret; -} - -/* Called with .video_lock held */ -static void mx3_camera_remove_device(struct soc_camera_device *icd) -{ - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct mx3_camera_dev *mx3_cam = ici->priv; - struct idmac_channel **ichan = &mx3_cam->idmac_channel[0]; - - BUG_ON(icd != mx3_cam->icd); - - if (*ichan) { - dma_release_channel(&(*ichan)->dma_chan); - *ichan = NULL; - } - - icd->ops->release(icd); - - clk_disable(mx3_cam->clk); - - mx3_cam->icd = NULL; - - dev_info(&icd->dev, "MX3 Camera driver detached from camera %d\n", - icd->devnum); -} - -static bool channel_change_requested(struct soc_camera_device *icd, - struct v4l2_rect *rect) -{ - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct mx3_camera_dev *mx3_cam = ici->priv; - struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; - - /* Do buffers have to be re-allocated or channel re-configured? */ - return ichan && rect->width * rect->height > icd->width * icd->height; -} - -static int test_platform_param(struct mx3_camera_dev *mx3_cam, - unsigned char buswidth, unsigned long *flags) -{ - /* - * Platform specified synchronization and pixel clock polarities are - * only a recommendation and are only used during probing. MX3x - * camera interface only works in master mode, i.e., uses HSYNC and - * VSYNC signals from the sensor - */ - *flags = SOCAM_MASTER | - SOCAM_HSYNC_ACTIVE_HIGH | - SOCAM_HSYNC_ACTIVE_LOW | - SOCAM_VSYNC_ACTIVE_HIGH | - SOCAM_VSYNC_ACTIVE_LOW | - SOCAM_PCLK_SAMPLE_RISING | - SOCAM_PCLK_SAMPLE_FALLING | - SOCAM_DATA_ACTIVE_HIGH | - SOCAM_DATA_ACTIVE_LOW; - - /* If requested data width is supported by the platform, use it or any - * possible lower value - i.MX31 is smart enough to schift bits */ - switch (buswidth) { - case 15: - if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)) - return -EINVAL; - *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 | - SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; - break; - case 10: - if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)) - return -EINVAL; - *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 | - SOCAM_DATAWIDTH_4; - break; - case 8: - if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)) - return -EINVAL; - *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; - break; - case 4: - if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)) - return -EINVAL; - *flags |= SOCAM_DATAWIDTH_4; - break; - default: - dev_info(mx3_cam->dev, "Unsupported bus width %d\n", buswidth); - return -EINVAL; - } - - return 0; -} - -static int mx3_camera_try_bus_param(struct soc_camera_device *icd, - const unsigned int depth) -{ - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct mx3_camera_dev *mx3_cam = ici->priv; - unsigned long bus_flags, camera_flags; - int ret = test_platform_param(mx3_cam, depth, &bus_flags); - - dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", depth, ret); - - if (ret < 0) - return ret; - - camera_flags = icd->ops->query_bus_param(icd); - - ret = soc_camera_bus_param_compatible(camera_flags, bus_flags); - if (ret < 0) - dev_warn(&icd->dev, "Flags incompatible: camera %lx, host %lx\n", - camera_flags, bus_flags); - - return ret; -} - -static bool chan_filter(struct dma_chan *chan, void *arg) -{ - struct dma_chan_request *rq = arg; - struct mx3_camera_pdata *pdata; - - if (!rq) - return false; - - pdata = rq->mx3_cam->dev->platform_data; - - return rq->id == chan->chan_id && - pdata->dma_dev == chan->device->dev; -} - -static const struct soc_camera_data_format mx3_camera_formats[] = { - { - .name = "Bayer (sRGB) 8 bit", - .depth = 8, - .fourcc = V4L2_PIX_FMT_SBGGR8, - .colorspace = V4L2_COLORSPACE_SRGB, - }, { - .name = "Monochrome 8 bit", - .depth = 8, - .fourcc = V4L2_PIX_FMT_GREY, - .colorspace = V4L2_COLORSPACE_JPEG, - }, -}; - -static bool buswidth_supported(struct soc_camera_host *ici, int depth) -{ - struct mx3_camera_dev *mx3_cam = ici->priv; - - switch (depth) { - case 4: - return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4); - case 8: - return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8); - case 10: - return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10); - case 15: - return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15); - } - return false; -} - -static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, - struct soc_camera_format_xlate *xlate) -{ - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - int formats = 0, buswidth, ret; - - buswidth = icd->formats[idx].depth; - - if (!buswidth_supported(ici, buswidth)) - return 0; - - ret = mx3_camera_try_bus_param(icd, buswidth); - if (ret < 0) - return 0; - - switch (icd->formats[idx].fourcc) { - case V4L2_PIX_FMT_SGRBG10: - formats++; - if (xlate) { - xlate->host_fmt = &mx3_camera_formats[0]; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = buswidth; - xlate++; - dev_dbg(&ici->dev, "Providing format %s using %s\n", - mx3_camera_formats[0].name, - icd->formats[idx].name); - } - goto passthrough; - case V4L2_PIX_FMT_Y16: - formats++; - if (xlate) { - xlate->host_fmt = &mx3_camera_formats[1]; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = buswidth; - xlate++; - dev_dbg(&ici->dev, "Providing format %s using %s\n", - mx3_camera_formats[0].name, - icd->formats[idx].name); - } - default: -passthrough: - /* Generic pass-through */ - formats++; - if (xlate) { - xlate->host_fmt = icd->formats + idx; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = buswidth; - xlate++; - dev_dbg(&ici->dev, - "Providing format %s in pass-through mode\n", - icd->formats[idx].name); - } - } - - return formats; -} - -static void configure_geometry(struct mx3_camera_dev *mx3_cam, - struct v4l2_rect *rect) -{ - u32 ctrl, width_field, height_field; - - /* Setup frame size - this cannot be changed on-the-fly... */ - width_field = rect->width - 1; - height_field = rect->height - 1; - csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_SENS_FRM_SIZE); - - csi_reg_write(mx3_cam, width_field << 16, CSI_FLASH_STROBE_1); - csi_reg_write(mx3_cam, (height_field << 16) | 0x22, CSI_FLASH_STROBE_2); - - csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_ACT_FRM_SIZE); - - /* ...and position */ - ctrl = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000; - /* Sensor does the cropping */ - csi_reg_write(mx3_cam, ctrl | 0 | (0 << 8), CSI_OUT_FRM_CTRL); - - /* - * No need to free resources here if we fail, we'll see if we need to - * do this next time we are called - */ -} - -static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam) -{ - dma_cap_mask_t mask; - struct dma_chan *chan; - struct idmac_channel **ichan = &mx3_cam->idmac_channel[0]; - /* We have to use IDMAC_IC_7 for Bayer / generic data */ - struct dma_chan_request rq = {.mx3_cam = mx3_cam, - .id = IDMAC_IC_7}; - - if (*ichan) { - struct videobuf_buffer *vb, *_vb; - dma_release_channel(&(*ichan)->dma_chan); - *ichan = NULL; - mx3_cam->active = NULL; - list_for_each_entry_safe(vb, _vb, &mx3_cam->capture, queue) { - list_del_init(&vb->queue); - vb->state = VIDEOBUF_ERROR; - wake_up(&vb->done); - } - } - - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - dma_cap_set(DMA_PRIVATE, mask); - chan = dma_request_channel(mask, chan_filter, &rq); - if (!chan) - return -EBUSY; - - *ichan = to_idmac_chan(chan); - (*ichan)->client = mx3_cam; - - return 0; -} - -static int mx3_camera_set_crop(struct soc_camera_device *icd, - struct v4l2_rect *rect) -{ - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct mx3_camera_dev *mx3_cam = ici->priv; - - /* - * We now know pixel formats and can decide upon DMA-channel(s) - * So far only direct camera-to-memory is supported - */ - if (channel_change_requested(icd, rect)) { - int ret = acquire_dma_channel(mx3_cam); - if (ret < 0) - return ret; - } - - configure_geometry(mx3_cam, rect); - - return icd->ops->set_crop(icd, rect); -} - -static int mx3_camera_set_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) -{ - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct mx3_camera_dev *mx3_cam = ici->priv; - const struct soc_camera_format_xlate *xlate; - struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_rect rect = { - .left = icd->x_current, - .top = icd->y_current, - .width = pix->width, - .height = pix->height, - }; - int ret; - - xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); - if (!xlate) { - dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat); - return -EINVAL; - } - - ret = acquire_dma_channel(mx3_cam); - if (ret < 0) - return ret; - - /* - * Might have to perform a complete interface initialisation like in - * ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider - * mxc_v4l2_s_fmt() - */ - - configure_geometry(mx3_cam, &rect); - - ret = icd->ops->set_fmt(icd, f); - if (!ret) { - icd->buswidth = xlate->buswidth; - icd->current_fmt = xlate->host_fmt; - } - - return ret; -} - -static int mx3_camera_try_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) -{ - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - const struct soc_camera_format_xlate *xlate; - struct v4l2_pix_format *pix = &f->fmt.pix; - __u32 pixfmt = pix->pixelformat; - enum v4l2_field field; - int ret; - - xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); - if (pixfmt && !xlate) { - dev_warn(&ici->dev, "Format %x not found\n", pixfmt); - return -EINVAL; - } - - /* limit to MX3 hardware capabilities */ - if (pix->height > 4096) - pix->height = 4096; - if (pix->width > 4096) - pix->width = 4096; - - pix->bytesperline = pix->width * - DIV_ROUND_UP(xlate->host_fmt->depth, 8); - pix->sizeimage = pix->height * pix->bytesperline; - - /* camera has to see its format, but the user the original one */ - pix->pixelformat = xlate->cam_fmt->fourcc; - /* limit to sensor capabilities */ - ret = icd->ops->try_fmt(icd, f); - pix->pixelformat = xlate->host_fmt->fourcc; - - field = pix->field; - - if (field == V4L2_FIELD_ANY) { - pix->field = V4L2_FIELD_NONE; - } else if (field != V4L2_FIELD_NONE) { - dev_err(&icd->dev, "Field type %d unsupported.\n", field); - return -EINVAL; - } - - return ret; -} - -static int mx3_camera_reqbufs(struct soc_camera_file *icf, - struct v4l2_requestbuffers *p) -{ - return 0; -} - -static unsigned int mx3_camera_poll(struct file *file, poll_table *pt) -{ - struct soc_camera_file *icf = file->private_data; - - return videobuf_poll_stream(file, &icf->vb_vidq, pt); -} - -static int mx3_camera_querycap(struct soc_camera_host *ici, - struct v4l2_capability *cap) -{ - /* cap->name is set by the firendly caller:-> */ - strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card)); - cap->version = KERNEL_VERSION(0, 2, 2); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; - - return 0; -} - -static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) -{ - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct mx3_camera_dev *mx3_cam = ici->priv; - unsigned long bus_flags, camera_flags, common_flags; - u32 dw, sens_conf; - int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags); - const struct soc_camera_format_xlate *xlate; - - xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); - if (!xlate) { - dev_warn(&ici->dev, "Format %x not found\n", pixfmt); - return -EINVAL; - } - - dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", - icd->buswidth, ret); - - if (ret < 0) - return ret; - - camera_flags = icd->ops->query_bus_param(icd); - - common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); - if (!common_flags) { - dev_dbg(&ici->dev, "no common flags: camera %lx, host %lx\n", - camera_flags, bus_flags); - return -EINVAL; - } - - /* Make choices, based on platform preferences */ - if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && - (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { - if (mx3_cam->platform_flags & MX3_CAMERA_HSP) - common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; - else - common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; - } - - if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && - (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { - if (mx3_cam->platform_flags & MX3_CAMERA_VSP) - common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; - else - common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; - } - - if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) && - (common_flags & SOCAM_DATA_ACTIVE_LOW)) { - if (mx3_cam->platform_flags & MX3_CAMERA_DP) - common_flags &= ~SOCAM_DATA_ACTIVE_HIGH; - else - common_flags &= ~SOCAM_DATA_ACTIVE_LOW; - } - - if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && - (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { - if (mx3_cam->platform_flags & MX3_CAMERA_PCP) - common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; - else - common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; - } - - /* Make the camera work in widest common mode, we'll take care of - * the rest */ - if (common_flags & SOCAM_DATAWIDTH_15) - common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | - SOCAM_DATAWIDTH_15; - else if (common_flags & SOCAM_DATAWIDTH_10) - common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | - SOCAM_DATAWIDTH_10; - else if (common_flags & SOCAM_DATAWIDTH_8) - common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | - SOCAM_DATAWIDTH_8; - else - common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | - SOCAM_DATAWIDTH_4; - - ret = icd->ops->set_bus_param(icd, common_flags); - if (ret < 0) - return ret; - - /* - * So far only gated clock mode is supported. Add a line - * (3 << CSI_SENS_CONF_SENS_PRTCL_SHIFT) | - * below and select the required mode when supporting other - * synchronisation protocols. - */ - sens_conf = csi_reg_read(mx3_cam, CSI_SENS_CONF) & - ~((1 << CSI_SENS_CONF_VSYNC_POL_SHIFT) | - (1 << CSI_SENS_CONF_HSYNC_POL_SHIFT) | - (1 << CSI_SENS_CONF_DATA_POL_SHIFT) | - (1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT) | - (3 << CSI_SENS_CONF_DATA_FMT_SHIFT) | - (3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT)); - - /* TODO: Support RGB and YUV formats */ - - /* This has been set in mx3_camera_activate(), but we clear it above */ - sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER; - - if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) - sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT; - if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) - sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT; - if (common_flags & SOCAM_VSYNC_ACTIVE_LOW) - sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT; - if (common_flags & SOCAM_DATA_ACTIVE_LOW) - sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT; - - /* Just do what we're asked to do */ - switch (xlate->host_fmt->depth) { - case 4: - dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; - break; - case 8: - dw = 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; - break; - case 10: - dw = 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; - break; - default: - /* - * Actually it can only be 15 now, default is just to silence - * compiler warnings - */ - case 15: - dw = 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; - } - - csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF); - - dev_dbg(&ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw); - - return 0; -} - -static struct soc_camera_host_ops mx3_soc_camera_host_ops = { - .owner = THIS_MODULE, - .add = mx3_camera_add_device, - .remove = mx3_camera_remove_device, -#ifdef CONFIG_PM - .suspend = mx3_camera_suspend, - .resume = mx3_camera_resume, -#endif - .set_crop = mx3_camera_set_crop, - .set_fmt = mx3_camera_set_fmt, - .try_fmt = mx3_camera_try_fmt, - .get_formats = mx3_camera_get_formats, - .init_videobuf = mx3_camera_init_videobuf, - .reqbufs = mx3_camera_reqbufs, - .poll = mx3_camera_poll, - .querycap = mx3_camera_querycap, - .set_bus_param = mx3_camera_set_bus_param, -}; - -static int mx3_camera_probe(struct platform_device *pdev) -{ - struct mx3_camera_dev *mx3_cam; - struct resource *res; - void __iomem *base; - int err = 0; - struct soc_camera_host *soc_host; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - err = -ENODEV; - goto egetres; - } - - mx3_cam = vmalloc(sizeof(*mx3_cam)); - if (!mx3_cam) { - dev_err(&pdev->dev, "Could not allocate mx3 camera object\n"); - err = -ENOMEM; - goto ealloc; - } - memset(mx3_cam, 0, sizeof(*mx3_cam)); - - mx3_cam->clk = clk_get(&pdev->dev, "csi_clk"); - if (IS_ERR(mx3_cam->clk)) { - err = PTR_ERR(mx3_cam->clk); - goto eclkget; - } - - dev_set_drvdata(&pdev->dev, mx3_cam); - - mx3_cam->pdata = pdev->dev.platform_data; - mx3_cam->platform_flags = mx3_cam->pdata->flags; - if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 | - MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10 | - MX3_CAMERA_DATAWIDTH_15))) { - /* Platform hasn't set available data widths. This is bad. - * Warn and use a default. */ - dev_warn(&pdev->dev, "WARNING! Platform hasn't set available " - "data widths, using default 8 bit\n"); - mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8; - } - - mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000; - if (!mx3_cam->mclk) { - dev_warn(&pdev->dev, - "mclk_10khz == 0! Please, fix your platform data. " - "Using default 20MHz\n"); - mx3_cam->mclk = 20000000; - } - - /* list of video-buffers */ - INIT_LIST_HEAD(&mx3_cam->capture); - spin_lock_init(&mx3_cam->lock); - - base = ioremap(res->start, res->end - res->start + 1); - if (!base) { - err = -ENOMEM; - goto eioremap; - } - - mx3_cam->base = base; - mx3_cam->dev = &pdev->dev; - - soc_host = &mx3_cam->soc_host; - soc_host->drv_name = MX3_CAM_DRV_NAME; - soc_host->ops = &mx3_soc_camera_host_ops; - soc_host->priv = mx3_cam; - soc_host->dev.parent = &pdev->dev; - soc_host->nr = pdev->id; - err = soc_camera_host_register(soc_host); - if (err) - goto ecamhostreg; - - /* IDMAC interface */ - dmaengine_get(); - - return 0; - -ecamhostreg: - iounmap(base); -eioremap: - clk_put(mx3_cam->clk); -eclkget: - vfree(mx3_cam); -ealloc: -egetres: - return err; -} - -static int __devexit mx3_camera_remove(struct platform_device *pdev) -{ - struct mx3_camera_dev *mx3_cam = platform_get_drvdata(pdev); - - clk_put(mx3_cam->clk); - - soc_camera_host_unregister(&mx3_cam->soc_host); - - iounmap(mx3_cam->base); - - /* - * The channel has either not been allocated, - * or should have been released - */ - if (WARN_ON(mx3_cam->idmac_channel[0])) - dma_release_channel(&mx3_cam->idmac_channel[0]->dma_chan); - - vfree(mx3_cam); - - dmaengine_put(); - - dev_info(&pdev->dev, "i.MX3x Camera driver unloaded\n"); - - return 0; -} - -static struct platform_driver mx3_camera_driver = { - .driver = { - .name = MX3_CAM_DRV_NAME, - }, - .probe = mx3_camera_probe, - .remove = __exit_p(mx3_camera_remove), -}; - - -static int __devinit mx3_camera_init(void) -{ - return platform_driver_register(&mx3_camera_driver); -} - -static void __exit mx3_camera_exit(void) -{ - platform_driver_unregister(&mx3_camera_driver); -} - -module_init(mx3_camera_init); -module_exit(mx3_camera_exit); - -MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver"); -MODULE_AUTHOR("Guennadi Liakhovetski "); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/media/video/mxb.c b/trunk/drivers/media/video/mxb.c index 84aec62e8452..e3cbe14c349a 100644 --- a/trunk/drivers/media/video/mxb.c +++ b/trunk/drivers/media/video/mxb.c @@ -25,20 +25,16 @@ #include #include +#include #include #include #include "mxb.h" #include "tea6415c.h" #include "tea6420.h" +#include "tda9840.h" -#define I2C_SAA5246A 0x11 -#define I2C_SAA7111A 0x24 -#define I2C_TDA9840 0x42 -#define I2C_TEA6415C 0x43 -#define I2C_TEA6420_1 0x4c -#define I2C_TEA6420_2 0x4d -#define I2C_TUNER 0x60 +#define I2C_SAA7111 0x24 #define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) @@ -83,35 +79,57 @@ static struct { static int video_audio_connect[MXB_INPUTS] = { 0, 1, 3, 3 }; -/* These are the necessary input-output-pins for bringing one audio source - (see above) to the CD-output. Note that gain is set to 0 in this table. */ -static struct v4l2_routing TEA6420_cd[MXB_AUDIOS + 1][2] = { - { { 1, 1 }, { 1, 1 } }, /* Tuner */ - { { 5, 1 }, { 6, 1 } }, /* AUX 1 */ - { { 4, 1 }, { 6, 1 } }, /* AUX 2 */ - { { 3, 1 }, { 6, 1 } }, /* AUX 3 */ - { { 1, 1 }, { 3, 1 } }, /* Radio */ - { { 1, 1 }, { 2, 1 } }, /* CD-Rom */ - { { 6, 1 }, { 6, 1 } } /* Mute */ -}; - -/* These are the necessary input-output-pins for bringing one audio source - (see above) to the line-output. Note that gain is set to 0 in this table. */ -static struct v4l2_routing TEA6420_line[MXB_AUDIOS + 1][2] = { - { { 2, 3 }, { 1, 2 } }, - { { 5, 3 }, { 6, 2 } }, - { { 4, 3 }, { 6, 2 } }, - { { 3, 3 }, { 6, 2 } }, - { { 2, 3 }, { 3, 2 } }, - { { 2, 3 }, { 2, 2 } }, - { { 6, 3 }, { 6, 2 } } /* Mute */ -}; +/* these are the necessary input-output-pins for bringing one audio source +(see above) to the CD-output */ +static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] = + { + {{1,1,0},{1,1,0}}, /* Tuner */ + {{5,1,0},{6,1,0}}, /* AUX 1 */ + {{4,1,0},{6,1,0}}, /* AUX 2 */ + {{3,1,0},{6,1,0}}, /* AUX 3 */ + {{1,1,0},{3,1,0}}, /* Radio */ + {{1,1,0},{2,1,0}}, /* CD-Rom */ + {{6,1,0},{6,1,0}} /* Mute */ + }; + +/* these are the necessary input-output-pins for bringing one audio source +(see above) to the line-output */ +static struct tea6420_multiplex TEA6420_line[MXB_AUDIOS+1][2] = + { + {{2,3,0},{1,2,0}}, + {{5,3,0},{6,2,0}}, + {{4,3,0},{6,2,0}}, + {{3,3,0},{6,2,0}}, + {{2,3,0},{3,2,0}}, + {{2,3,0},{2,2,0}}, + {{6,3,0},{6,2,0}} /* Mute */ + }; #define MAXCONTROLS 1 static struct v4l2_queryctrl mxb_controls[] = { { V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 }, }; +static struct saa7146_extension_ioctls ioctls[] = { + { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE }, + { VIDIOC_QUERYCTRL, SAA7146_BEFORE }, + { VIDIOC_G_CTRL, SAA7146_BEFORE }, + { VIDIOC_S_CTRL, SAA7146_BEFORE }, + { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE }, + { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE }, + { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE }, + { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE }, + { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, + { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, + { VIDIOC_DBG_G_REGISTER, SAA7146_EXCLUSIVE }, + { VIDIOC_DBG_S_REGISTER, SAA7146_EXCLUSIVE }, + { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */ + { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */ + { 0, 0 } +}; + struct mxb { struct video_device *video_dev; @@ -119,12 +137,12 @@ struct mxb struct i2c_adapter i2c_adapter; - struct v4l2_subdev *saa7111a; - struct v4l2_subdev *tda9840; - struct v4l2_subdev *tea6415c; - struct v4l2_subdev *tuner; - struct v4l2_subdev *tea6420_1; - struct v4l2_subdev *tea6420_2; + struct i2c_client *saa7111a; + struct i2c_client *tda9840; + struct i2c_client *tea6415c; + struct i2c_client *tuner; + struct i2c_client *tea6420_1; + struct i2c_client *tea6420_2; int cur_mode; /* current audio mode (mono, stereo, ...) */ int cur_input; /* current input */ @@ -132,51 +150,84 @@ struct mxb struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */ }; -#define saa7111a_call(mxb, o, f, args...) \ - v4l2_subdev_call(mxb->saa7111a, o, f, ##args) -#define tea6420_1_call(mxb, o, f, args...) \ - v4l2_subdev_call(mxb->tea6420_1, o, f, ##args) -#define tea6420_2_call(mxb, o, f, args...) \ - v4l2_subdev_call(mxb->tea6420_2, o, f, ##args) -#define tda9840_call(mxb, o, f, args...) \ - v4l2_subdev_call(mxb->tda9840, o, f, ##args) -#define tea6415c_call(mxb, o, f, args...) \ - v4l2_subdev_call(mxb->tea6415c, o, f, ##args) -#define tuner_call(mxb, o, f, args...) \ - v4l2_subdev_call(mxb->tuner, o, f, ##args) -#define call_all(dev, o, f, args...) \ - v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args) - static struct saa7146_extension extension; -static int mxb_probe(struct saa7146_dev *dev) +static int mxb_check_clients(struct device *dev, void *data) +{ + struct mxb *mxb = data; + struct i2c_client *client = i2c_verify_client(dev); + + if (!client) + return 0; + + if (I2C_ADDR_TEA6420_1 == client->addr) + mxb->tea6420_1 = client; + if (I2C_ADDR_TEA6420_2 == client->addr) + mxb->tea6420_2 = client; + if (I2C_TEA6415C_2 == client->addr) + mxb->tea6415c = client; + if (I2C_ADDR_TDA9840 == client->addr) + mxb->tda9840 = client; + if (I2C_SAA7111 == client->addr) + mxb->saa7111a = client; + if (0x60 == client->addr) + mxb->tuner = client; + + return 0; +} + +static int mxb_probe(struct saa7146_dev* dev) { - struct mxb *mxb = NULL; + struct mxb* mxb = NULL; + int result; + + result = request_module("saa7115"); + if (result < 0) { + printk("mxb: saa7111 i2c module not available.\n"); + return -ENODEV; + } + result = request_module("tea6420"); + if (result < 0) { + printk("mxb: tea6420 i2c module not available.\n"); + return -ENODEV; + } + result = request_module("tea6415c"); + if (result < 0) { + printk("mxb: tea6415c i2c module not available.\n"); + return -ENODEV; + } + result = request_module("tda9840"); + if (result < 0) { + printk("mxb: tda9840 i2c module not available.\n"); + return -ENODEV; + } + result = request_module("tuner"); + if (result < 0) { + printk("mxb: tuner i2c module not available.\n"); + return -ENODEV; + } mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL); - if (mxb == NULL) { + if( NULL == mxb ) { DEB_D(("not enough kernel memory.\n")); return -ENOMEM; } + mxb->i2c_adapter = (struct i2c_adapter) { + .class = I2C_CLASS_TV_ANALOG, + }; + snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num); saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); - if (i2c_add_adapter(&mxb->i2c_adapter) < 0) { + if(i2c_add_adapter(&mxb->i2c_adapter) < 0) { DEB_S(("cannot register i2c-device. skipping.\n")); kfree(mxb); return -EFAULT; } - mxb->saa7111a = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "saa7115", "saa7111", I2C_SAA7111A); - mxb->tea6420_1 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6420", "tea6420", I2C_TEA6420_1); - mxb->tea6420_2 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6420", "tea6420", I2C_TEA6420_2); - mxb->tea6415c = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6415c", "tea6415c", I2C_TEA6415C); - mxb->tda9840 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tda9840", "tda9840", I2C_TDA9840); - mxb->tuner = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tuner", "tuner", I2C_TUNER); - if (v4l2_i2c_new_subdev(&mxb->i2c_adapter, "saa5246a", "saa5246a", I2C_SAA5246A)) { - printk(KERN_INFO "mxb: found teletext decoder\n"); - } + /* loop through all i2c-devices on the bus and look who is there */ + device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients); /* check if all devices are present */ if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c || @@ -264,45 +315,47 @@ static int mxb_init_done(struct saa7146_dev* dev) struct v4l2_routing route; int i = 0, err = 0; + struct tea6415c_multiplex vm; /* select video mode in saa7111a */ - saa7111a_call(mxb, tuner, s_std, std); + mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_S_STD, &std); /* select tuner-output on saa7111a */ i = 0; route.input = SAA7115_COMPOSITE0; route.output = SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS; - saa7111a_call(mxb, video, s_routing, &route); + mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route); /* select a tuner type */ tun_setup.mode_mask = T_ANALOG_TV; tun_setup.addr = ADDR_UNSET; tun_setup.type = TUNER_PHILIPS_PAL; - tuner_call(mxb, tuner, s_type_addr, &tun_setup); + mxb->tuner->driver->command(mxb->tuner, TUNER_SET_TYPE_ADDR, &tun_setup); /* tune in some frequency on tuner */ mxb->cur_freq.tuner = 0; mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV; mxb->cur_freq.frequency = freq; - tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq); + mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, + &mxb->cur_freq); /* set a default video standard */ - tuner_call(mxb, tuner, s_std, std); + mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); /* mute audio on tea6420s */ - tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[6][0]); - tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[6][1]); - tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[6][0]); - tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[6][1]); + mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_line[6][0]); + mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_line[6][1]); + mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_cd[6][0]); + mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_cd[6][1]); - /* switch to tuner-channel on tea6415c */ - route.input = 3; - route.output = 17; - tea6415c_call(mxb, video, s_routing, &route); + /* switch to tuner-channel on tea6415c*/ + vm.out = 17; + vm.in = 3; + mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm); - /* select tuner-output on multicable on tea6415c */ - route.input = 3; - route.output = 13; - tea6415c_call(mxb, video, s_routing, &route); + /* select tuner-output on multicable on tea6415c*/ + vm.in = 3; + vm.out = 13; + mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm); /* the rest for mxb */ mxb->cur_input = 0; @@ -371,414 +424,395 @@ void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask) } */ -static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - int i; - - for (i = MAXCONTROLS - 1; i >= 0; i--) { - if (mxb_controls[i].id == qc->id) { - *qc = mxb_controls[i]; - DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id)); - return 0; - } - } - return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc); -} +static struct saa7146_ext_vv vv_data; -static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc) +/* this function only gets called when the probing was successful */ +static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; struct mxb *mxb = (struct mxb *)dev->ext_priv; - int i; - for (i = MAXCONTROLS - 1; i >= 0; i--) { - if (mxb_controls[i].id == vc->id) - break; - } + DEB_EE(("dev:%p\n", dev)); - if (i < 0) - return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc); + /* checking for i2c-devices can be omitted here, because we + already did this in "mxb_vl42_probe" */ - if (vc->id == V4L2_CID_AUDIO_MUTE) { - vc->value = mxb->cur_mute; - DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value)); - return 0; + saa7146_vv_init(dev, &vv_data); + if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { + ERR(("cannot register capture v4l2 device. skipping.\n")); + return -1; } - DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value)); + /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ + if (MXB_BOARD_CAN_DO_VBI(dev)) { + if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) { + ERR(("cannot register vbi v4l2 device. skipping.\n")); + } + } + + i2c_use_client(mxb->tea6420_1); + i2c_use_client(mxb->tea6420_2); + i2c_use_client(mxb->tea6415c); + i2c_use_client(mxb->tda9840); + i2c_use_client(mxb->saa7111a); + i2c_use_client(mxb->tuner); + + printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num); + + mxb_num++; + mxb_init_done(dev); return 0; } -static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc) +static int mxb_detach(struct saa7146_dev *dev) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; struct mxb *mxb = (struct mxb *)dev->ext_priv; - int i = 0; - for (i = MAXCONTROLS - 1; i >= 0; i--) { - if (mxb_controls[i].id == vc->id) - break; - } + DEB_EE(("dev:%p\n", dev)); - if (i < 0) - return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc); - - if (vc->id == V4L2_CID_AUDIO_MUTE) { - mxb->cur_mute = vc->value; - if (!vc->value) { - /* switch the audio-source */ - tea6420_1_call(mxb, audio, s_routing, - &TEA6420_line[video_audio_connect[mxb->cur_input]][0]); - tea6420_2_call(mxb, audio, s_routing, - &TEA6420_line[video_audio_connect[mxb->cur_input]][1]); - } else { - tea6420_1_call(mxb, audio, s_routing, - &TEA6420_line[6][0]); - tea6420_2_call(mxb, audio, s_routing, - &TEA6420_line[6][1]); - } - DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value)); - } - return 0; -} + i2c_release_client(mxb->tea6420_1); + i2c_release_client(mxb->tea6420_2); + i2c_release_client(mxb->tea6415c); + i2c_release_client(mxb->tda9840); + i2c_release_client(mxb->saa7111a); + i2c_release_client(mxb->tuner); -static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) -{ - DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index)); - if (i->index < 0 || i->index >= MXB_INPUTS) - return -EINVAL; - memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input)); - return 0; -} + saa7146_unregister_device(&mxb->video_dev,dev); + if (MXB_BOARD_CAN_DO_VBI(dev)) + saa7146_unregister_device(&mxb->vbi_dev, dev); + saa7146_vv_release(dev); -static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; - *i = mxb->cur_input; + mxb_num--; + + i2c_del_adapter(&mxb->i2c_adapter); + kfree(mxb); - DEB_EE(("VIDIOC_G_INPUT %d.\n", *i)); return 0; } -static int vidioc_s_input(struct file *file, void *fh, unsigned int input) +static long mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = fh->dev; struct mxb *mxb = (struct mxb *)dev->ext_priv; - struct v4l2_routing route; - int i = 0; - - DEB_EE(("VIDIOC_S_INPUT %d.\n", input)); - - if (input < 0 || input >= MXB_INPUTS) - return -EINVAL; - - mxb->cur_input = input; - - saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, - input_port_selection[input].hps_sync); + struct saa7146_vv *vv = dev->vv_data; - /* prepare switching of tea6415c and saa7111a; - have a look at the 'background'-file for further informations */ - switch (input) { - case TUNER: - i = SAA7115_COMPOSITE0; - route.input = 3; - route.output = 17; + switch(cmd) { + case VIDIOC_ENUMINPUT: + { + struct v4l2_input *i = arg; - if (tea6415c_call(mxb, video, s_routing, &route)) { - printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n"); - return -EFAULT; - } - /* connect tuner-output always to multicable */ - route.input = 3; - route.output = 13; - break; - case AUX3_YC: - /* nothing to be done here. aux3_yc is - directly connected to the saa711a */ - i = SAA7115_SVIDEO1; - break; - case AUX3: - /* nothing to be done here. aux3 is - directly connected to the saa711a */ - i = SAA7115_COMPOSITE1; - break; - case AUX1: - i = SAA7115_COMPOSITE0; - route.input = 1; - route.output = 17; - break; + DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); + if (i->index < 0 || i->index >= MXB_INPUTS) + return -EINVAL; + memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input)); + return 0; } - - /* switch video in tea6415c only if necessary */ - switch (input) { - case TUNER: - case AUX1: - if (tea6415c_call(mxb, video, s_routing, &route)) { - printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n"); - return -EFAULT; + /* the saa7146 provides some controls (brightness, contrast, saturation) + which gets registered *after* this function. because of this we have + to return with a value != 0 even if the function succeded.. */ + case VIDIOC_QUERYCTRL: + { + struct v4l2_queryctrl *qc = arg; + int i; + + for (i = MAXCONTROLS - 1; i >= 0; i--) { + if (mxb_controls[i].id == qc->id) { + *qc = mxb_controls[i]; + DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id)); + return 0; + } } - break; - default: - break; + return -EAGAIN; } + case VIDIOC_G_CTRL: + { + struct v4l2_control *vc = arg; + int i; - /* switch video in saa7111a */ - route.input = i; - route.output = 0; - if (saa7111a_call(mxb, video, s_routing, &route)) - printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n"); - - /* switch the audio-source only if necessary */ - if (0 == mxb->cur_mute) { - tea6420_1_call(mxb, audio, s_routing, - &TEA6420_line[video_audio_connect[input]][0]); - tea6420_2_call(mxb, audio, s_routing, - &TEA6420_line[video_audio_connect[input]][1]); - } + for (i = MAXCONTROLS - 1; i >= 0; i--) { + if (mxb_controls[i].id == vc->id) + break; + } - return 0; -} + if (i < 0) + return -EAGAIN; -static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; + if (vc->id == V4L2_CID_AUDIO_MUTE) { + vc->value = mxb->cur_mute; + DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value)); + return 0; + } - if (t->index) { - DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index)); - return -EINVAL; + DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value)); + return 0; } - DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index)); + case VIDIOC_S_CTRL: + { + struct v4l2_control *vc = arg; + int i = 0; - memset(t, 0, sizeof(*t)); - strlcpy(t->name, "TV Tuner", sizeof(t->name)); - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; - t->audmode = mxb->cur_mode; - return call_all(dev, tuner, g_tuner, t); -} + for (i = MAXCONTROLS - 1; i >= 0; i--) { + if (mxb_controls[i].id == vc->id) + break; + } -static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; + if (i < 0) + return -EAGAIN; + + if (vc->id == V4L2_CID_AUDIO_MUTE) { + mxb->cur_mute = vc->value; + if (!vc->value) { + /* switch the audio-source */ + mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, + &TEA6420_line[video_audio_connect[mxb->cur_input]][0]); + mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, + &TEA6420_line[video_audio_connect[mxb->cur_input]][1]); + } else { + mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, + &TEA6420_line[6][0]); + mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, + &TEA6420_line[6][1]); + } + DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value)); + } + return 0; + } + case VIDIOC_G_INPUT: + { + int *input = (int *)arg; + *input = mxb->cur_input; - if (t->index) { - DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n", t->index)); - return -EINVAL; + DEB_EE(("VIDIOC_G_INPUT %d.\n", *input)); + return 0; } + case VIDIOC_S_INPUT: + { + int input = *(int *)arg; + struct tea6415c_multiplex vm; + struct v4l2_routing route; + int i = 0; - mxb->cur_mode = t->audmode; - return call_all(dev, tuner, s_tuner, t); -} + DEB_EE(("VIDIOC_S_INPUT %d.\n", input)); -static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; + if (input < 0 || input >= MXB_INPUTS) + return -EINVAL; - if (mxb->cur_input) { - DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n", - mxb->cur_input)); - return -EINVAL; - } + mxb->cur_input = input; - *f = mxb->cur_freq; + saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, + input_port_selection[input].hps_sync); - DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency)); - return 0; -} + /* prepare switching of tea6415c and saa7111a; + have a look at the 'background'-file for further informations */ + switch (input) { + case TUNER: + i = SAA7115_COMPOSITE0; + vm.in = 3; + vm.out = 17; -static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; - struct saa7146_vv *vv = dev->vv_data; + if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) { + printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n"); + return -EFAULT; + } + /* connect tuner-output always to multicable */ + vm.in = 3; + vm.out = 13; + break; + case AUX3_YC: + /* nothing to be done here. aux3_yc is + directly connected to the saa711a */ + i = SAA7115_SVIDEO1; + break; + case AUX3: + /* nothing to be done here. aux3 is + directly connected to the saa711a */ + i = SAA7115_COMPOSITE1; + break; + case AUX1: + i = SAA7115_COMPOSITE0; + vm.in = 1; + vm.out = 17; + break; + } - if (f->tuner) - return -EINVAL; + /* switch video in tea6415c only if necessary */ + switch (input) { + case TUNER: + case AUX1: + if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) { + printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n"); + return -EFAULT; + } + break; + default: + break; + } - if (V4L2_TUNER_ANALOG_TV != f->type) - return -EINVAL; + /* switch video in saa7111a */ + route.input = i; + route.output = 0; + if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route)) + printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n"); + + /* switch the audio-source only if necessary */ + if( 0 == mxb->cur_mute ) { + mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, + &TEA6420_line[video_audio_connect[input]][0]); + mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, + &TEA6420_line[video_audio_connect[input]][1]); + } - if (mxb->cur_input) { - DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input)); - return -EINVAL; + return 0; } + case VIDIOC_G_TUNER: + { + struct v4l2_tuner *t = arg; - mxb->cur_freq = *f; - DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency)); + if (t->index) { + DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index)); + return -EINVAL; + } - /* tune in desired frequency */ - tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq); + DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index)); - /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */ - spin_lock(&dev->slock); - vv->vbi_fieldcount = 0; - spin_unlock(&dev->slock); + memset(t, 0, sizeof(*t)); + i2c_clients_command(&mxb->i2c_adapter, cmd, arg); - return 0; -} + strlcpy(t->name, "TV Tuner", sizeof(t->name)); + t->type = V4L2_TUNER_ANALOG_TV; + t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | \ + V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; + t->audmode = mxb->cur_mode; + return 0; + } + case VIDIOC_S_TUNER: + { + struct v4l2_tuner *t = arg; -static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; + if (t->index) { + DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index)); + return -EINVAL; + } - if (a->index < 0 || a->index > MXB_INPUTS) { - DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index)); - return -EINVAL; + mxb->cur_mode = t->audmode; + i2c_clients_command(&mxb->i2c_adapter, cmd, arg); + return 0; } + case VIDIOC_G_FREQUENCY: + { + struct v4l2_frequency *f = arg; - DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index)); - memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio)); - return 0; -} + if (mxb->cur_input) { + DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n", + mxb->cur_input)); + return -EINVAL; + } -static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a) -{ - DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index)); - return 0; -} + *f = mxb->cur_freq; -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency)); + return 0; + } + case VIDIOC_S_FREQUENCY: + { + struct v4l2_frequency *f = arg; - return call_all(dev, core, g_register, reg); -} + if (f->tuner) + return -EINVAL; -static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + if (V4L2_TUNER_ANALOG_TV != f->type) + return -EINVAL; - return call_all(dev, core, s_register, reg); -} -#endif + if (mxb->cur_input) { + DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input)); + return -EINVAL; + } -static long vidioc_default(struct file *file, void *fh, int cmd, void *arg) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; + mxb->cur_freq = *f; + DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency)); + + /* tune in desired frequency */ + mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq); + + /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */ + spin_lock(&dev->slock); + vv->vbi_fieldcount = 0; + spin_unlock(&dev->slock); - switch (cmd) { + return 0; + } case MXB_S_AUDIO_CD: { - int i = *(int *)arg; + int i = *(int*)arg; if (i < 0 || i >= MXB_AUDIOS) { - DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n", i)); + DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i)); return -EINVAL; } - DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n", i)); + DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i)); - tea6420_1_call(mxb, audio, s_routing, &TEA6420_cd[i][0]); - tea6420_2_call(mxb, audio, s_routing, &TEA6420_cd[i][1]); + mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]); + mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]); return 0; } case MXB_S_AUDIO_LINE: { - int i = *(int *)arg; + int i = *(int*)arg; if (i < 0 || i >= MXB_AUDIOS) { - DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n", i)); + DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i)); return -EINVAL; } - DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n", i)); - tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[i][0]); - tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[i][1]); + DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i)); + mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]); + mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]); return 0; } - default: -/* - DEB2(printk("does not handle this ioctl.\n")); -*/ - return -ENOIOCTLCMD; - } - return 0; -} - -static struct saa7146_ext_vv vv_data; + case VIDIOC_G_AUDIO: + { + struct v4l2_audio *a = arg; -/* this function only gets called when the probing was successful */ -static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) -{ - struct mxb *mxb = (struct mxb *)dev->ext_priv; + if (a->index < 0 || a->index > MXB_INPUTS) { + DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index)); + return -EINVAL; + } - DEB_EE(("dev:%p\n", dev)); + DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index)); + memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio)); - /* checking for i2c-devices can be omitted here, because we - already did this in "mxb_vl42_probe" */ + return 0; + } + case VIDIOC_S_AUDIO: + { + struct v4l2_audio *a = arg; - saa7146_vv_init(dev, &vv_data); - vv_data.ops.vidioc_queryctrl = vidioc_queryctrl; - vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl; - vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl; - vv_data.ops.vidioc_enum_input = vidioc_enum_input; - vv_data.ops.vidioc_g_input = vidioc_g_input; - vv_data.ops.vidioc_s_input = vidioc_s_input; - vv_data.ops.vidioc_g_tuner = vidioc_g_tuner; - vv_data.ops.vidioc_s_tuner = vidioc_s_tuner; - vv_data.ops.vidioc_g_frequency = vidioc_g_frequency; - vv_data.ops.vidioc_s_frequency = vidioc_s_frequency; - vv_data.ops.vidioc_g_audio = vidioc_g_audio; - vv_data.ops.vidioc_s_audio = vidioc_s_audio; + DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index)); + return 0; + } #ifdef CONFIG_VIDEO_ADV_DEBUG - vv_data.ops.vidioc_g_register = vidioc_g_register; - vv_data.ops.vidioc_s_register = vidioc_s_register; + case VIDIOC_DBG_S_REGISTER: + case VIDIOC_DBG_G_REGISTER: + i2c_clients_command(&mxb->i2c_adapter, cmd, arg); + return 0; #endif - vv_data.ops.vidioc_default = vidioc_default; - if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { - ERR(("cannot register capture v4l2 device. skipping.\n")); - return -1; - } - - /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ - if (MXB_BOARD_CAN_DO_VBI(dev)) { - if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) { - ERR(("cannot register vbi v4l2 device. skipping.\n")); - } + default: +/* + DEB2(printk("does not handle this ioctl.\n")); +*/ + return -ENOIOCTLCMD; } - - printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num); - - mxb_num++; - mxb_init_done(dev); - return 0; -} - -static int mxb_detach(struct saa7146_dev *dev) -{ - struct mxb *mxb = (struct mxb *)dev->ext_priv; - - DEB_EE(("dev:%p\n", dev)); - - saa7146_unregister_device(&mxb->video_dev,dev); - if (MXB_BOARD_CAN_DO_VBI(dev)) - saa7146_unregister_device(&mxb->vbi_dev, dev); - saa7146_vv_release(dev); - - mxb_num--; - - i2c_del_adapter(&mxb->i2c_adapter); - kfree(mxb); - return 0; } static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard) { struct mxb *mxb = (struct mxb *)dev->ext_priv; + int zero = 0; + int one = 1; if (V4L2_STD_PAL_I == standard->id) { v4l2_std_id std = V4L2_STD_PAL_I; @@ -787,8 +821,8 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa /* set the 7146 gpio register -- I don't know what this does exactly */ saa7146_write(dev, GPIO_CTRL, 0x00404050); /* unset the 7111 gpio register -- I don't know what this does exactly */ - saa7111a_call(mxb, core, s_gpio, 0); - tuner_call(mxb, tuner, s_std, std); + mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &zero); + mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); } else { v4l2_std_id std = V4L2_STD_PAL_BG; @@ -796,8 +830,8 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa /* set the 7146 gpio register -- I don't know what this does exactly */ saa7146_write(dev, GPIO_CTRL, 0x00404050); /* set the 7111 gpio register -- I don't know what this does exactly */ - saa7111a_call(mxb, core, s_gpio, 1); - tuner_call(mxb, tuner, s_std, std); + mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &one); + mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); } return 0; } @@ -851,6 +885,8 @@ static struct saa7146_ext_vv vv_data = { .stds = &standard[0], .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), .std_callback = &std_callback, + .ioctls = &ioctls[0], + .ioctl = mxb_ioctl, }; static struct saa7146_extension extension = { diff --git a/trunk/drivers/media/video/omap24xxcam.c b/trunk/drivers/media/video/omap24xxcam.c index 5fc4ac0d88f0..805faaea6449 100644 --- a/trunk/drivers/media/video/omap24xxcam.c +++ b/trunk/drivers/media/video/omap24xxcam.c @@ -1285,6 +1285,9 @@ static int vidioc_g_parm(struct file *file, void *fh, struct omap24xxcam_device *cam = ofh->cam; int rval; + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + mutex_lock(&cam->mutex); rval = vidioc_int_g_parm(cam->sdev, a); mutex_unlock(&cam->mutex); @@ -1300,6 +1303,9 @@ static int vidioc_s_parm(struct file *file, void *fh, struct v4l2_streamparm old_streamparm; int rval; + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + mutex_lock(&cam->mutex); if (cam->streaming) { rval = -EBUSY; @@ -1659,6 +1665,7 @@ static int omap24xxcam_device_register(struct v4l2_int_device *s) vfd->parent = cam->dev; strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name)); + vfd->vfl_type = VID_TYPE_CAPTURE | VID_TYPE_CHROMAKEY; vfd->fops = &omap24xxcam_fops; vfd->minor = -1; vfd->ioctl_ops = &omap24xxcam_ioctl_fops; diff --git a/trunk/drivers/media/video/ov7670.c b/trunk/drivers/media/video/ov7670.c index 0e2184ec994e..05c14a29375a 100644 --- a/trunk/drivers/media/video/ov7670.c +++ b/trunk/drivers/media/video/ov7670.c @@ -12,22 +12,18 @@ */ #include #include -#include +#include #include -#include -#include +#include +#include #include -#include +#include MODULE_AUTHOR("Jonathan Corbet "); MODULE_DESCRIPTION("A low-level driver for OmniVision ov7670 sensors"); MODULE_LICENSE("GPL"); -static int debug; -module_param(debug, bool, 0644); -MODULE_PARM_DESC(debug, "Debug level (0-1)"); - /* * Basic window sizes. These probably belong somewhere more globally * useful. @@ -193,16 +189,11 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); */ struct ov7670_format_struct; /* coming later */ struct ov7670_info { - struct v4l2_subdev sd; struct ov7670_format_struct *fmt; /* Current format */ unsigned char sat; /* Saturation value */ int hue; /* Hue value */ }; -static inline struct ov7670_info *to_state(struct v4l2_subdev *sd) -{ - return container_of(sd, struct ov7670_info, sd); -} @@ -409,27 +400,24 @@ static struct regval_list ov7670_fmt_raw[] = { * Low-level register I/O. */ -static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg, +static int ov7670_read(struct i2c_client *c, unsigned char reg, unsigned char *value) { - struct i2c_client *client = v4l2_get_subdevdata(sd); int ret; - ret = i2c_smbus_read_byte_data(client, reg); + ret = i2c_smbus_read_byte_data(c, reg); if (ret >= 0) { - *value = (unsigned char)ret; + *value = (unsigned char) ret; ret = 0; } return ret; } -static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg, +static int ov7670_write(struct i2c_client *c, unsigned char reg, unsigned char value) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret = i2c_smbus_write_byte_data(client, reg, value); - + int ret = i2c_smbus_write_byte_data(c, reg, value); if (reg == REG_COM7 && (value & COM7_RESET)) msleep(2); /* Wait for reset to run */ return ret; @@ -439,10 +427,10 @@ static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg, /* * Write a list of register settings; ff/ff stops the process. */ -static int ov7670_write_array(struct v4l2_subdev *sd, struct regval_list *vals) +static int ov7670_write_array(struct i2c_client *c, struct regval_list *vals) { while (vals->reg_num != 0xff || vals->value != 0xff) { - int ret = ov7670_write(sd, vals->reg_num, vals->value); + int ret = ov7670_write(c, vals->reg_num, vals->value); if (ret < 0) return ret; vals++; @@ -454,35 +442,34 @@ static int ov7670_write_array(struct v4l2_subdev *sd, struct regval_list *vals) /* * Stuff that knows about the sensor. */ -static int ov7670_reset(struct v4l2_subdev *sd, u32 val) +static void ov7670_reset(struct i2c_client *client) { - ov7670_write(sd, REG_COM7, COM7_RESET); + ov7670_write(client, REG_COM7, COM7_RESET); msleep(1); - return 0; } -static int ov7670_init(struct v4l2_subdev *sd, u32 val) +static int ov7670_init(struct i2c_client *client) { - return ov7670_write_array(sd, ov7670_default_regs); + return ov7670_write_array(client, ov7670_default_regs); } -static int ov7670_detect(struct v4l2_subdev *sd) +static int ov7670_detect(struct i2c_client *client) { unsigned char v; int ret; - ret = ov7670_init(sd, 0); + ret = ov7670_init(client); if (ret < 0) return ret; - ret = ov7670_read(sd, REG_MIDH, &v); + ret = ov7670_read(client, REG_MIDH, &v); if (ret < 0) return ret; if (v != 0x7f) /* OV manuf. id. */ return -ENODEV; - ret = ov7670_read(sd, REG_MIDL, &v); + ret = ov7670_read(client, REG_MIDL, &v); if (ret < 0) return ret; if (v != 0xa2) @@ -490,12 +477,12 @@ static int ov7670_detect(struct v4l2_subdev *sd) /* * OK, we know we have an OmniVision chip...but which one? */ - ret = ov7670_read(sd, REG_PID, &v); + ret = ov7670_read(client, REG_PID, &v); if (ret < 0) return ret; if (v != 0x76) /* PID + VER = 0x76 / 0x73 */ return -ENODEV; - ret = ov7670_read(sd, REG_VER, &v); + ret = ov7670_read(client, REG_VER, &v); if (ret < 0) return ret; if (v != 0x73) /* PID + VER = 0x76 / 0x73 */ @@ -640,7 +627,7 @@ static struct ov7670_win_size { /* * Store a set of start/stop values into the camera. */ -static int ov7670_set_hw(struct v4l2_subdev *sd, int hstart, int hstop, +static int ov7670_set_hw(struct i2c_client *client, int hstart, int hstop, int vstart, int vstop) { int ret; @@ -650,26 +637,26 @@ static int ov7670_set_hw(struct v4l2_subdev *sd, int hstart, int hstop, * hstart are in href[2:0], bottom 3 of hstop in href[5:3]. There is * a mystery "edge offset" value in the top two bits of href. */ - ret = ov7670_write(sd, REG_HSTART, (hstart >> 3) & 0xff); - ret += ov7670_write(sd, REG_HSTOP, (hstop >> 3) & 0xff); - ret += ov7670_read(sd, REG_HREF, &v); + ret = ov7670_write(client, REG_HSTART, (hstart >> 3) & 0xff); + ret += ov7670_write(client, REG_HSTOP, (hstop >> 3) & 0xff); + ret += ov7670_read(client, REG_HREF, &v); v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x7); msleep(10); - ret += ov7670_write(sd, REG_HREF, v); + ret += ov7670_write(client, REG_HREF, v); /* * Vertical: similar arrangement, but only 10 bits. */ - ret += ov7670_write(sd, REG_VSTART, (vstart >> 2) & 0xff); - ret += ov7670_write(sd, REG_VSTOP, (vstop >> 2) & 0xff); - ret += ov7670_read(sd, REG_VREF, &v); + ret += ov7670_write(client, REG_VSTART, (vstart >> 2) & 0xff); + ret += ov7670_write(client, REG_VSTOP, (vstop >> 2) & 0xff); + ret += ov7670_read(client, REG_VREF, &v); v = (v & 0xf0) | ((vstop & 0x3) << 2) | (vstart & 0x3); msleep(10); - ret += ov7670_write(sd, REG_VREF, v); + ret += ov7670_write(client, REG_VREF, v); return ret; } -static int ov7670_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt) +static int ov7670_enum_fmt(struct i2c_client *c, struct v4l2_fmtdesc *fmt) { struct ov7670_format_struct *ofmt; @@ -684,8 +671,7 @@ static int ov7670_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt) } -static int ov7670_try_fmt_internal(struct v4l2_subdev *sd, - struct v4l2_format *fmt, +static int ov7670_try_fmt(struct i2c_client *c, struct v4l2_format *fmt, struct ov7670_format_struct **ret_fmt, struct ov7670_win_size **ret_wsize) { @@ -729,23 +715,18 @@ static int ov7670_try_fmt_internal(struct v4l2_subdev *sd, return 0; } -static int ov7670_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - return ov7670_try_fmt_internal(sd, fmt, NULL, NULL); -} - /* * Set a format. */ -static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt) { int ret; struct ov7670_format_struct *ovfmt; struct ov7670_win_size *wsize; - struct ov7670_info *info = to_state(sd); - unsigned char com7, clkrc = 0; + struct ov7670_info *info = i2c_get_clientdata(c); + unsigned char com7, clkrc; - ret = ov7670_try_fmt_internal(sd, fmt, &ovfmt, &wsize); + ret = ov7670_try_fmt(c, fmt, &ovfmt, &wsize); if (ret) return ret; /* @@ -754,7 +735,7 @@ static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) * the colors. */ if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) { - ret = ov7670_read(sd, REG_CLKRC, &clkrc); + ret = ov7670_read(c, REG_CLKRC, &clkrc); if (ret) return ret; } @@ -766,20 +747,20 @@ static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) */ com7 = ovfmt->regs[0].value; com7 |= wsize->com7_bit; - ov7670_write(sd, REG_COM7, com7); + ov7670_write(c, REG_COM7, com7); /* * Now write the rest of the array. Also store start/stops */ - ov7670_write_array(sd, ovfmt->regs + 1); - ov7670_set_hw(sd, wsize->hstart, wsize->hstop, wsize->vstart, + ov7670_write_array(c, ovfmt->regs + 1); + ov7670_set_hw(c, wsize->hstart, wsize->hstop, wsize->vstart, wsize->vstop); ret = 0; if (wsize->regs) - ret = ov7670_write_array(sd, wsize->regs); + ret = ov7670_write_array(c, wsize->regs); info->fmt = ovfmt; if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565 && ret == 0) - ret = ov7670_write(sd, REG_CLKRC, clkrc); + ret = ov7670_write(c, REG_CLKRC, clkrc); return ret; } @@ -787,7 +768,7 @@ static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) * Implement G/S_PARM. There is a "high quality" mode we could try * to do someday; for now, we just do the frame rate tweak. */ -static int ov7670_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) +static int ov7670_g_parm(struct i2c_client *c, struct v4l2_streamparm *parms) { struct v4l2_captureparm *cp = &parms->parm.capture; unsigned char clkrc; @@ -795,7 +776,7 @@ static int ov7670_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - ret = ov7670_read(sd, REG_CLKRC, &clkrc); + ret = ov7670_read(c, REG_CLKRC, &clkrc); if (ret < 0) return ret; memset(cp, 0, sizeof(struct v4l2_captureparm)); @@ -807,7 +788,7 @@ static int ov7670_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) return 0; } -static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) +static int ov7670_s_parm(struct i2c_client *c, struct v4l2_streamparm *parms) { struct v4l2_captureparm *cp = &parms->parm.capture; struct v4l2_fract *tpf = &cp->timeperframe; @@ -821,7 +802,7 @@ static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) /* * CLKRC has a reserved bit, so let's preserve it. */ - ret = ov7670_read(sd, REG_CLKRC, &clkrc); + ret = ov7670_read(c, REG_CLKRC, &clkrc); if (ret < 0) return ret; if (tpf->numerator == 0 || tpf->denominator == 0) @@ -835,7 +816,7 @@ static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) clkrc = (clkrc & 0x80) | div; tpf->numerator = 1; tpf->denominator = OV7670_FRAME_RATE/div; - return ov7670_write(sd, REG_CLKRC, clkrc); + return ov7670_write(c, REG_CLKRC, clkrc); } @@ -848,7 +829,7 @@ static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) -static int ov7670_store_cmatrix(struct v4l2_subdev *sd, +static int ov7670_store_cmatrix(struct i2c_client *client, int matrix[CMATRIX_LEN]) { int i, ret; @@ -858,7 +839,7 @@ static int ov7670_store_cmatrix(struct v4l2_subdev *sd, * Weird crap seems to exist in the upper part of * the sign bits register, so let's preserve it. */ - ret = ov7670_read(sd, REG_CMATRIX_SIGN, &signbits); + ret = ov7670_read(client, REG_CMATRIX_SIGN, &signbits); signbits &= 0xc0; for (i = 0; i < CMATRIX_LEN; i++) { @@ -877,9 +858,9 @@ static int ov7670_store_cmatrix(struct v4l2_subdev *sd, else raw = matrix[i] & 0xff; } - ret += ov7670_write(sd, REG_CMATRIX_BASE + i, raw); + ret += ov7670_write(client, REG_CMATRIX_BASE + i, raw); } - ret += ov7670_write(sd, REG_CMATRIX_SIGN, signbits); + ret += ov7670_write(client, REG_CMATRIX_SIGN, signbits); return ret; } @@ -962,29 +943,29 @@ static void ov7670_calc_cmatrix(struct ov7670_info *info, -static int ov7670_s_sat(struct v4l2_subdev *sd, int value) +static int ov7670_t_sat(struct i2c_client *client, int value) { - struct ov7670_info *info = to_state(sd); + struct ov7670_info *info = i2c_get_clientdata(client); int matrix[CMATRIX_LEN]; int ret; info->sat = value; ov7670_calc_cmatrix(info, matrix); - ret = ov7670_store_cmatrix(sd, matrix); + ret = ov7670_store_cmatrix(client, matrix); return ret; } -static int ov7670_g_sat(struct v4l2_subdev *sd, __s32 *value) +static int ov7670_q_sat(struct i2c_client *client, __s32 *value) { - struct ov7670_info *info = to_state(sd); + struct ov7670_info *info = i2c_get_clientdata(client); *value = info->sat; return 0; } -static int ov7670_s_hue(struct v4l2_subdev *sd, int value) +static int ov7670_t_hue(struct i2c_client *client, int value) { - struct ov7670_info *info = to_state(sd); + struct ov7670_info *info = i2c_get_clientdata(client); int matrix[CMATRIX_LEN]; int ret; @@ -992,14 +973,14 @@ static int ov7670_s_hue(struct v4l2_subdev *sd, int value) return -EINVAL; info->hue = value; ov7670_calc_cmatrix(info, matrix); - ret = ov7670_store_cmatrix(sd, matrix); + ret = ov7670_store_cmatrix(client, matrix); return ret; } -static int ov7670_g_hue(struct v4l2_subdev *sd, __s32 *value) +static int ov7670_q_hue(struct i2c_client *client, __s32 *value) { - struct ov7670_info *info = to_state(sd); + struct ov7670_info *info = i2c_get_clientdata(client); *value = info->hue; return 0; @@ -1013,7 +994,8 @@ static unsigned char ov7670_sm_to_abs(unsigned char v) { if ((v & 0x80) == 0) return v + 128; - return 128 - (v & 0x7f); + else + return 128 - (v & 0x7f); } @@ -1021,275 +1003,369 @@ static unsigned char ov7670_abs_to_sm(unsigned char v) { if (v > 127) return v & 0x7f; - return (128 - v) | 0x80; + else + return (128 - v) | 0x80; } -static int ov7670_s_brightness(struct v4l2_subdev *sd, int value) +static int ov7670_t_brightness(struct i2c_client *client, int value) { unsigned char com8 = 0, v; int ret; - ov7670_read(sd, REG_COM8, &com8); + ov7670_read(client, REG_COM8, &com8); com8 &= ~COM8_AEC; - ov7670_write(sd, REG_COM8, com8); + ov7670_write(client, REG_COM8, com8); v = ov7670_abs_to_sm(value); - ret = ov7670_write(sd, REG_BRIGHT, v); + ret = ov7670_write(client, REG_BRIGHT, v); return ret; } -static int ov7670_g_brightness(struct v4l2_subdev *sd, __s32 *value) +static int ov7670_q_brightness(struct i2c_client *client, __s32 *value) { unsigned char v = 0; - int ret = ov7670_read(sd, REG_BRIGHT, &v); + int ret = ov7670_read(client, REG_BRIGHT, &v); *value = ov7670_sm_to_abs(v); return ret; } -static int ov7670_s_contrast(struct v4l2_subdev *sd, int value) +static int ov7670_t_contrast(struct i2c_client *client, int value) { - return ov7670_write(sd, REG_CONTRAS, (unsigned char) value); + return ov7670_write(client, REG_CONTRAS, (unsigned char) value); } -static int ov7670_g_contrast(struct v4l2_subdev *sd, __s32 *value) +static int ov7670_q_contrast(struct i2c_client *client, __s32 *value) { unsigned char v = 0; - int ret = ov7670_read(sd, REG_CONTRAS, &v); + int ret = ov7670_read(client, REG_CONTRAS, &v); *value = v; return ret; } -static int ov7670_g_hflip(struct v4l2_subdev *sd, __s32 *value) +static int ov7670_q_hflip(struct i2c_client *client, __s32 *value) { int ret; unsigned char v = 0; - ret = ov7670_read(sd, REG_MVFP, &v); + ret = ov7670_read(client, REG_MVFP, &v); *value = (v & MVFP_MIRROR) == MVFP_MIRROR; return ret; } -static int ov7670_s_hflip(struct v4l2_subdev *sd, int value) +static int ov7670_t_hflip(struct i2c_client *client, int value) { unsigned char v = 0; int ret; - ret = ov7670_read(sd, REG_MVFP, &v); + ret = ov7670_read(client, REG_MVFP, &v); if (value) v |= MVFP_MIRROR; else v &= ~MVFP_MIRROR; msleep(10); /* FIXME */ - ret += ov7670_write(sd, REG_MVFP, v); + ret += ov7670_write(client, REG_MVFP, v); return ret; } -static int ov7670_g_vflip(struct v4l2_subdev *sd, __s32 *value) +static int ov7670_q_vflip(struct i2c_client *client, __s32 *value) { int ret; unsigned char v = 0; - ret = ov7670_read(sd, REG_MVFP, &v); + ret = ov7670_read(client, REG_MVFP, &v); *value = (v & MVFP_FLIP) == MVFP_FLIP; return ret; } -static int ov7670_s_vflip(struct v4l2_subdev *sd, int value) +static int ov7670_t_vflip(struct i2c_client *client, int value) { unsigned char v = 0; int ret; - ret = ov7670_read(sd, REG_MVFP, &v); + ret = ov7670_read(client, REG_MVFP, &v); if (value) v |= MVFP_FLIP; else v &= ~MVFP_FLIP; msleep(10); /* FIXME */ - ret += ov7670_write(sd, REG_MVFP, v); + ret += ov7670_write(client, REG_MVFP, v); return ret; } -static int ov7670_queryctrl(struct v4l2_subdev *sd, - struct v4l2_queryctrl *qc) -{ - /* Fill in min, max, step and default value for these controls. */ - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); - case V4L2_CID_CONTRAST: - return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64); - case V4L2_CID_VFLIP: - case V4L2_CID_HFLIP: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); - case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(qc, 0, 256, 1, 128); - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(qc, -180, 180, 5, 0); - } - return -EINVAL; -} -static int ov7670_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static struct ov7670_control { + struct v4l2_queryctrl qc; + int (*query)(struct i2c_client *c, __s32 *value); + int (*tweak)(struct i2c_client *c, int value); +} ov7670_controls[] = { - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - return ov7670_g_brightness(sd, &ctrl->value); - case V4L2_CID_CONTRAST: - return ov7670_g_contrast(sd, &ctrl->value); - case V4L2_CID_SATURATION: - return ov7670_g_sat(sd, &ctrl->value); - case V4L2_CID_HUE: - return ov7670_g_hue(sd, &ctrl->value); - case V4L2_CID_VFLIP: - return ov7670_g_vflip(sd, &ctrl->value); - case V4L2_CID_HFLIP: - return ov7670_g_hflip(sd, &ctrl->value); - } - return -EINVAL; -} + { + .qc = { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 0x80, + .flags = V4L2_CTRL_FLAG_SLIDER + }, + .tweak = ov7670_t_brightness, + .query = ov7670_q_brightness, + }, + { + .qc = { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 0x40, /* XXX ov7670 spec */ + .flags = V4L2_CTRL_FLAG_SLIDER + }, + .tweak = ov7670_t_contrast, + .query = ov7670_q_contrast, + }, + { + .qc = { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, + .maximum = 256, + .step = 1, + .default_value = 0x80, + .flags = V4L2_CTRL_FLAG_SLIDER + }, + .tweak = ov7670_t_sat, + .query = ov7670_q_sat, + }, + { + .qc = { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "HUE", + .minimum = -180, + .maximum = 180, + .step = 5, + .default_value = 0, + .flags = V4L2_CTRL_FLAG_SLIDER + }, + .tweak = ov7670_t_hue, + .query = ov7670_q_hue, + }, + { + .qc = { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Vertical flip", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + .tweak = ov7670_t_vflip, + .query = ov7670_q_vflip, + }, + { + .qc = { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Horizontal mirror", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + .tweak = ov7670_t_hflip, + .query = ov7670_q_hflip, + }, +}; +#define N_CONTROLS (ARRAY_SIZE(ov7670_controls)) -static int ov7670_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static struct ov7670_control *ov7670_find_control(__u32 id) { - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - return ov7670_s_brightness(sd, ctrl->value); - case V4L2_CID_CONTRAST: - return ov7670_s_contrast(sd, ctrl->value); - case V4L2_CID_SATURATION: - return ov7670_s_sat(sd, ctrl->value); - case V4L2_CID_HUE: - return ov7670_s_hue(sd, ctrl->value); - case V4L2_CID_VFLIP: - return ov7670_s_vflip(sd, ctrl->value); - case V4L2_CID_HFLIP: - return ov7670_s_hflip(sd, ctrl->value); - } - return -EINVAL; + int i; + + for (i = 0; i < N_CONTROLS; i++) + if (ov7670_controls[i].qc.id == id) + return ov7670_controls + i; + return NULL; } -static int ov7670_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *chip) + +static int ov7670_queryctrl(struct i2c_client *client, + struct v4l2_queryctrl *qc) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov7670_control *ctrl = ov7670_find_control(qc->id); - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV7670, 0); + if (ctrl == NULL) + return -EINVAL; + *qc = ctrl->qc; + return 0; } -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int ov7670_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) +static int ov7670_g_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - unsigned char val = 0; + struct ov7670_control *octrl = ov7670_find_control(ctrl->id); int ret; - if (!v4l2_chip_match_i2c_client(client, ®->match)) + if (octrl == NULL) return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - ret = ov7670_read(sd, reg->reg & 0xff, &val); - reg->val = val; - reg->size = 1; + ret = octrl->query(client, &ctrl->value); + if (ret >= 0) + return 0; return ret; } -static int ov7670_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) +static int ov7670_s_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov7670_control *octrl = ov7670_find_control(ctrl->id); + int ret; - if (!v4l2_chip_match_i2c_client(client, ®->match)) + if (octrl == NULL) return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - ov7670_write(sd, reg->reg & 0xff, reg->val & 0xff); - return 0; + ret = octrl->tweak(client, ctrl->value); + if (ret >= 0) + return 0; + return ret; } -#endif - -/* ----------------------------------------------------------------------- */ - -static const struct v4l2_subdev_core_ops ov7670_core_ops = { - .g_chip_ident = ov7670_g_chip_ident, - .g_ctrl = ov7670_g_ctrl, - .s_ctrl = ov7670_s_ctrl, - .queryctrl = ov7670_queryctrl, - .reset = ov7670_reset, - .init = ov7670_init, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .g_register = ov7670_g_register, - .s_register = ov7670_s_register, -#endif -}; -static const struct v4l2_subdev_video_ops ov7670_video_ops = { - .enum_fmt = ov7670_enum_fmt, - .try_fmt = ov7670_try_fmt, - .s_fmt = ov7670_s_fmt, - .s_parm = ov7670_s_parm, - .g_parm = ov7670_g_parm, -}; -static const struct v4l2_subdev_ops ov7670_ops = { - .core = &ov7670_core_ops, - .video = &ov7670_video_ops, -}; -/* ----------------------------------------------------------------------- */ -static int ov7670_probe(struct i2c_client *client, - const struct i2c_device_id *id) + + +/* + * Basic i2c stuff. + */ +static struct i2c_driver ov7670_driver; + +static int ov7670_attach(struct i2c_adapter *adapter) { - struct v4l2_subdev *sd; - struct ov7670_info *info; int ret; + struct i2c_client *client; + struct ov7670_info *info; + + /* + * For now: only deal with adapters we recognize. + */ + if (adapter->id != I2C_HW_SMBUS_CAFE) + return -ENODEV; - info = kzalloc(sizeof(struct ov7670_info), GFP_KERNEL); - if (info == NULL) + client = kzalloc(sizeof (struct i2c_client), GFP_KERNEL); + if (! client) return -ENOMEM; - sd = &info->sd; - v4l2_i2c_subdev_init(sd, client, &ov7670_ops); - - /* Make sure it's an ov7670 */ - ret = ov7670_detect(sd); - if (ret) { - v4l_dbg(1, debug, client, - "chip found @ 0x%x (%s) is not an ov7670 chip.\n", - client->addr << 1, client->adapter->name); - kfree(info); - return ret; + client->adapter = adapter; + client->addr = OV7670_I2C_ADDR; + client->driver = &ov7670_driver, + strcpy(client->name, "OV7670"); + /* + * Set up our info structure. + */ + info = kzalloc(sizeof (struct ov7670_info), GFP_KERNEL); + if (! info) { + ret = -ENOMEM; + goto out_free; } - v4l_info(client, "chip found @ 0x%02x (%s)\n", - client->addr << 1, client->adapter->name); - info->fmt = &ov7670_formats[0]; info->sat = 128; /* Review this */ + i2c_set_clientdata(client, info); + /* + * Make sure it's an ov7670 + */ + ret = ov7670_detect(client); + if (ret) + goto out_free_info; + ret = i2c_attach_client(client); + if (ret) + goto out_free_info; return 0; + + out_free_info: + kfree(info); + out_free: + kfree(client); + return ret; } -static int ov7670_remove(struct i2c_client *client) +static int ov7670_detach(struct i2c_client *client) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - - v4l2_device_unregister_subdev(sd); - kfree(to_state(sd)); + i2c_detach_client(client); + kfree(i2c_get_clientdata(client)); + kfree(client); return 0; } -static const struct i2c_device_id ov7670_id[] = { - { "ov7670", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, ov7670_id); -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "ov7670", - .probe = ov7670_probe, - .remove = ov7670_remove, - .id_table = ov7670_id, +static int ov7670_command(struct i2c_client *client, unsigned int cmd, + void *arg) +{ + switch (cmd) { + case VIDIOC_DBG_G_CHIP_IDENT: + return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_OV7670, 0); + + case VIDIOC_INT_RESET: + ov7670_reset(client); + return 0; + + case VIDIOC_INT_INIT: + return ov7670_init(client); + + case VIDIOC_ENUM_FMT: + return ov7670_enum_fmt(client, (struct v4l2_fmtdesc *) arg); + case VIDIOC_TRY_FMT: + return ov7670_try_fmt(client, (struct v4l2_format *) arg, NULL, NULL); + case VIDIOC_S_FMT: + return ov7670_s_fmt(client, (struct v4l2_format *) arg); + case VIDIOC_QUERYCTRL: + return ov7670_queryctrl(client, (struct v4l2_queryctrl *) arg); + case VIDIOC_S_CTRL: + return ov7670_s_ctrl(client, (struct v4l2_control *) arg); + case VIDIOC_G_CTRL: + return ov7670_g_ctrl(client, (struct v4l2_control *) arg); + case VIDIOC_S_PARM: + return ov7670_s_parm(client, (struct v4l2_streamparm *) arg); + case VIDIOC_G_PARM: + return ov7670_g_parm(client, (struct v4l2_streamparm *) arg); + } + return -EINVAL; +} + + + +static struct i2c_driver ov7670_driver = { + .driver = { + .name = "ov7670", + }, + .id = I2C_DRIVERID_OV7670, + .attach_adapter = ov7670_attach, + .detach_client = ov7670_detach, + .command = ov7670_command, }; + + +/* + * Module initialization + */ +static int __init ov7670_mod_init(void) +{ + printk(KERN_NOTICE "OmniVision ov7670 sensor driver, at your service\n"); + return i2c_add_driver(&ov7670_driver); +} + +static void __exit ov7670_mod_exit(void) +{ + i2c_del_driver(&ov7670_driver); +} + +module_init(ov7670_mod_init); +module_exit(ov7670_mod_exit); diff --git a/trunk/drivers/media/video/ov772x.c b/trunk/drivers/media/video/ov772x.c index 84b0fc1bb237..3c9e0ba974e9 100644 --- a/trunk/drivers/media/video/ov772x.c +++ b/trunk/drivers/media/video/ov772x.c @@ -217,11 +217,10 @@ #define OCAP_4x 0x03 /* 4x */ /* COM3 */ -#define SWAP_MASK (SWAP_RGB | SWAP_YUV | SWAP_ML) -#define IMG_MASK (VFLIP_IMG | HFLIP_IMG) +#define SWAP_MASK 0x38 -#define VFLIP_IMG 0x80 /* Vertical flip image ON/OFF selection */ -#define HFLIP_IMG 0x40 /* Horizontal mirror image ON/OFF selection */ +#define VFIMG_ON_OFF 0x80 /* Vertical flip image ON/OFF selection */ +#define HMIMG_ON_OFF 0x40 /* Horizontal mirror image ON/OFF selection */ #define SWAP_RGB 0x20 /* Swap B/R output sequence in RGB mode */ #define SWAP_YUV 0x10 /* Swap Y/UV output sequence in YUV mode */ #define SWAP_ML 0x08 /* Swap output MSB/LSB */ @@ -272,13 +271,11 @@ #define SLCT_QVGA 0x40 /* 1 : QVGA */ #define ITU656_ON_OFF 0x20 /* ITU656 protocol ON/OFF selection */ /* RGB output format control */ -#define FMT_MASK 0x0c /* Mask of color format */ #define FMT_GBR422 0x00 /* 00 : GBR 4:2:2 */ #define FMT_RGB565 0x04 /* 01 : RGB 565 */ #define FMT_RGB555 0x08 /* 10 : RGB 555 */ #define FMT_RGB444 0x0c /* 11 : RGB 444 */ /* Output format control */ -#define OFMT_MASK 0x03 /* Mask of output format */ #define OFMT_YUV 0x00 /* 00 : YUV */ #define OFMT_P_BRAW 0x01 /* 01 : Processed Bayer RAW */ #define OFMT_RGB 0x02 /* 10 : RGB */ @@ -302,7 +299,7 @@ #define GAIN_2x 0x00 /* 000 : 2x */ #define GAIN_4x 0x10 /* 001 : 4x */ #define GAIN_8x 0x20 /* 010 : 8x */ -#define GAIN_16x 0x30 /* 011 : 16x */ +#define GAIN_16x 0x30 /* 011 : 16x */ #define GAIN_32x 0x40 /* 100 : 32x */ #define GAIN_64x 0x50 /* 101 : 64x */ #define GAIN_128x 0x60 /* 110 : 128x */ @@ -358,6 +355,13 @@ #define VOSZ_VGA 0xF0 #define VOSZ_QVGA 0x78 +/* + * bit configure (32 bit) + * this is used in struct ov772x_color_format :: option + */ +#define OP_UV 0x00000001 +#define OP_SWAP_RGB 0x00000002 + /* * ID */ @@ -376,9 +380,8 @@ struct regval_list { struct ov772x_color_format { char *name; __u32 fourcc; - u8 dsp3; - u8 com3; - u8 com7; + const struct regval_list *regs; + unsigned int option; }; struct ov772x_win_size { @@ -396,12 +399,38 @@ struct ov772x_priv { const struct ov772x_color_format *fmt; const struct ov772x_win_size *win; int model; - unsigned int flag_vflip:1; - unsigned int flag_hflip:1; }; #define ENDMARKER { 0xff, 0xff } +/* + * register setting for color format + */ +static const struct regval_list ov772x_RGB555_regs[] = { + { COM3, 0x00 }, + { COM7, FMT_RGB555 | OFMT_RGB }, + ENDMARKER, +}; + +static const struct regval_list ov772x_RGB565_regs[] = { + { COM3, 0x00 }, + { COM7, FMT_RGB565 | OFMT_RGB }, + ENDMARKER, +}; + +static const struct regval_list ov772x_YYUV_regs[] = { + { COM3, SWAP_YUV }, + { COM7, OFMT_YUV }, + ENDMARKER, +}; + +static const struct regval_list ov772x_UVYY_regs[] = { + { COM3, 0x00 }, + { COM7, OFMT_YUV }, + ENDMARKER, +}; + + /* * register setting for window size */ @@ -471,48 +500,38 @@ static const struct soc_camera_data_format ov772x_fmt_lists[] = { /* * color format list */ +#define T_YUYV 0 static const struct ov772x_color_format ov772x_cfmts[] = { - { + [T_YUYV] = { SETFOURCC(YUYV), - .dsp3 = 0x0, - .com3 = SWAP_YUV, - .com7 = OFMT_YUV, + .regs = ov772x_YYUV_regs, }, { SETFOURCC(YVYU), - .dsp3 = UV_ON, - .com3 = SWAP_YUV, - .com7 = OFMT_YUV, + .regs = ov772x_YYUV_regs, + .option = OP_UV, }, { SETFOURCC(UYVY), - .dsp3 = 0x0, - .com3 = 0x0, - .com7 = OFMT_YUV, + .regs = ov772x_UVYY_regs, }, { SETFOURCC(RGB555), - .dsp3 = 0x0, - .com3 = SWAP_RGB, - .com7 = FMT_RGB555 | OFMT_RGB, + .regs = ov772x_RGB555_regs, + .option = OP_SWAP_RGB, }, { SETFOURCC(RGB555X), - .dsp3 = 0x0, - .com3 = 0x0, - .com7 = FMT_RGB555 | OFMT_RGB, + .regs = ov772x_RGB555_regs, }, { SETFOURCC(RGB565), - .dsp3 = 0x0, - .com3 = SWAP_RGB, - .com7 = FMT_RGB565 | OFMT_RGB, + .regs = ov772x_RGB565_regs, + .option = OP_SWAP_RGB, }, { SETFOURCC(RGB565X), - .dsp3 = 0x0, - .com3 = 0x0, - .com7 = FMT_RGB565 | OFMT_RGB, + .regs = ov772x_RGB565_regs, }, }; @@ -543,27 +562,6 @@ static const struct ov772x_win_size ov772x_win_qvga = { .regs = ov772x_qvga_regs, }; -static const struct v4l2_queryctrl ov772x_controls[] = { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Vertically", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Horizontally", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, -}; - /* * general function @@ -589,11 +587,8 @@ static int ov772x_mask_set(struct i2c_client *client, u8 set) { s32 val = i2c_smbus_read_byte_data(client, command); - if (val < 0) - return val; - val &= ~mask; - val |= set & mask; + val |= set; return i2c_smbus_write_byte_data(client, command, val); } @@ -640,24 +635,74 @@ static int ov772x_release(struct soc_camera_device *icd) static int ov772x_start_capture(struct soc_camera_device *icd) { struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); + int ret; + + if (!priv->win) + priv->win = &ov772x_win_vga; + if (!priv->fmt) + priv->fmt = &ov772x_cfmts[T_YUYV]; + + /* + * reset hardware + */ + ov772x_reset(priv->client); - if (!priv->win || !priv->fmt) { - dev_err(&icd->dev, "norm or win select error\n"); - return -EPERM; + /* + * set color format + */ + ret = ov772x_write_array(priv->client, priv->fmt->regs); + if (ret < 0) + goto start_end; + + /* + * set size format + */ + ret = ov772x_write_array(priv->client, priv->win->regs); + if (ret < 0) + goto start_end; + + /* + * set COM7 bit ( QVGA or VGA ) + */ + ret = ov772x_mask_set(priv->client, + COM7, SLCT_MASK, priv->win->com7_bit); + if (ret < 0) + goto start_end; + + /* + * set UV setting + */ + if (priv->fmt->option & OP_UV) { + ret = ov772x_mask_set(priv->client, + DSP_CTRL3, UV_MASK, UV_ON); + if (ret < 0) + goto start_end; } - ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, 0); + /* + * set SWAP setting + */ + if (priv->fmt->option & OP_SWAP_RGB) { + ret = ov772x_mask_set(priv->client, + COM3, SWAP_MASK, SWAP_RGB); + if (ret < 0) + goto start_end; + } dev_dbg(&icd->dev, "format %s, win %s\n", priv->fmt->name, priv->win->name); - return 0; +start_end: + priv->fmt = NULL; + priv->win = NULL; + + return ret; } static int ov772x_stop_capture(struct soc_camera_device *icd) { struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); - ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE); + ov772x_reset(priv->client); return 0; } @@ -673,54 +718,11 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd) struct soc_camera_link *icl = priv->client->dev.platform_data; unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | - SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth; + priv->info->buswidth; return soc_camera_apply_sensor_flags(icl, flags); } -static int ov772x_get_control(struct soc_camera_device *icd, - struct v4l2_control *ctrl) -{ - struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); - - switch (ctrl->id) { - case V4L2_CID_VFLIP: - ctrl->value = priv->flag_vflip; - break; - case V4L2_CID_HFLIP: - ctrl->value = priv->flag_hflip; - break; - } - return 0; -} - -static int ov772x_set_control(struct soc_camera_device *icd, - struct v4l2_control *ctrl) -{ - struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); - int ret = 0; - u8 val; - - switch (ctrl->id) { - case V4L2_CID_VFLIP: - val = ctrl->value ? VFLIP_IMG : 0x00; - priv->flag_vflip = ctrl->value; - if (priv->info->flags & OV772X_FLAG_VFLIP) - val ^= VFLIP_IMG; - ret = ov772x_mask_set(priv->client, COM3, VFLIP_IMG, val); - break; - case V4L2_CID_HFLIP: - val = ctrl->value ? HFLIP_IMG : 0x00; - priv->flag_hflip = ctrl->value; - if (priv->info->flags & OV772X_FLAG_HFLIP) - val ^= HFLIP_IMG; - ret = ov772x_mask_set(priv->client, COM3, HFLIP_IMG, val); - break; - } - - return ret; -} - static int ov772x_get_chip_id(struct soc_camera_device *icd, struct v4l2_dbg_chip_ident *id) { @@ -785,11 +787,13 @@ ov772x_select_win(u32 width, u32 height) return win; } -static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height, - u32 pixfmt) + +static int ov772x_set_fmt(struct soc_camera_device *icd, + __u32 pixfmt, + struct v4l2_rect *rect) { + struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); int ret = -EINVAL; - u8 val; int i; /* @@ -799,101 +803,19 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height, for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { if (pixfmt == ov772x_cfmts[i].fourcc) { priv->fmt = ov772x_cfmts + i; + ret = 0; break; } } - if (!priv->fmt) - goto ov772x_set_fmt_error; /* * select win */ - priv->win = ov772x_select_win(width, height); - - /* - * reset hardware - */ - ov772x_reset(priv->client); - - /* - * set size format - */ - ret = ov772x_write_array(priv->client, priv->win->regs); - if (ret < 0) - goto ov772x_set_fmt_error; - - /* - * set DSP_CTRL3 - */ - val = priv->fmt->dsp3; - if (val) { - ret = ov772x_mask_set(priv->client, - DSP_CTRL3, UV_MASK, val); - if (ret < 0) - goto ov772x_set_fmt_error; - } - - /* - * set COM3 - */ - val = priv->fmt->com3; - if (priv->info->flags & OV772X_FLAG_VFLIP) - val |= VFLIP_IMG; - if (priv->info->flags & OV772X_FLAG_HFLIP) - val |= HFLIP_IMG; - if (priv->flag_vflip) - val ^= VFLIP_IMG; - if (priv->flag_hflip) - val ^= HFLIP_IMG; - - ret = ov772x_mask_set(priv->client, - COM3, SWAP_MASK | IMG_MASK, val); - if (ret < 0) - goto ov772x_set_fmt_error; - - /* - * set COM7 - */ - val = priv->win->com7_bit | priv->fmt->com7; - ret = ov772x_mask_set(priv->client, - COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK), - val); - if (ret < 0) - goto ov772x_set_fmt_error; - - return ret; - -ov772x_set_fmt_error: - - ov772x_reset(priv->client); - priv->win = NULL; - priv->fmt = NULL; + priv->win = ov772x_select_win(rect->width, rect->height); return ret; } -static int ov772x_set_crop(struct soc_camera_device *icd, - struct v4l2_rect *rect) -{ - struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); - - if (!priv->fmt) - return -EINVAL; - - return ov772x_set_params(priv, rect->width, rect->height, - priv->fmt->fourcc); -} - -static int ov772x_set_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) -{ - struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); - struct v4l2_pix_format *pix = &f->fmt.pix; - - return ov772x_set_params(priv, pix->width, pix->height, - pix->pixelformat); -} - static int ov772x_try_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { @@ -967,6 +889,7 @@ static int ov772x_video_probe(struct soc_camera_device *icd) i2c_smbus_read_byte_data(priv->client, MIDH), i2c_smbus_read_byte_data(priv->client, MIDL)); + return soc_camera_video_start(icd); } @@ -983,15 +906,10 @@ static struct soc_camera_ops ov772x_ops = { .release = ov772x_release, .start_capture = ov772x_start_capture, .stop_capture = ov772x_stop_capture, - .set_crop = ov772x_set_crop, .set_fmt = ov772x_set_fmt, .try_fmt = ov772x_try_fmt, .set_bus_param = ov772x_set_bus_param, .query_bus_param = ov772x_query_bus_param, - .controls = ov772x_controls, - .num_controls = ARRAY_SIZE(ov772x_controls), - .get_control = ov772x_get_control, - .set_control = ov772x_set_control, .get_chip_id = ov772x_get_chip_id, #ifdef CONFIG_VIDEO_ADV_DEBUG .get_register = ov772x_get_register, diff --git a/trunk/drivers/media/video/ovcamchip/ovcamchip_core.c b/trunk/drivers/media/video/ovcamchip/ovcamchip_core.c index d573d8428998..c841f4e4fbe4 100644 --- a/trunk/drivers/media/video/ovcamchip/ovcamchip_core.c +++ b/trunk/drivers/media/video/ovcamchip/ovcamchip_core.c @@ -15,9 +15,6 @@ #include #include #include -#include -#include -#include #include "ovcamchip_priv.h" #define DRIVER_VERSION "v2.27 for Linux 2.6" @@ -47,7 +44,6 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); - /* Registers common to all chips, that are needed for detection */ #define GENERIC_REG_ID_HIGH 0x1C /* manufacturer ID MSB */ #define GENERIC_REG_ID_LOW 0x1D /* manufacturer ID LSB */ @@ -65,6 +61,10 @@ static char *chip_names[NUM_CC_TYPES] = { [CC_OV6630AF] = "OV6630AF", }; +/* Forward declarations */ +static struct i2c_driver driver; +static struct i2c_client client_template; + /* ----------------------------------------------------------------------- */ int ov_write_regvals(struct i2c_client *c, struct ovcamchip_regvals *rvals) @@ -253,36 +253,112 @@ static int ovcamchip_detect(struct i2c_client *c) /* Test for 7xx0 */ PDEBUG(3, "Testing for 0V7xx0"); - if (init_camchip(c) < 0) - return -ENODEV; - /* 7-bit addresses with bit 0 set are for the OV7xx0 */ - if (c->addr & 1) { + c->addr = OV7xx0_SID; + if (init_camchip(c) < 0) { + /* Test for 6xx0 */ + PDEBUG(3, "Testing for 0V6xx0"); + c->addr = OV6xx0_SID; + if (init_camchip(c) < 0) { + return -ENODEV; + } else { + if (ov6xx0_detect(c) < 0) { + PERROR("Failed to init OV6xx0"); + return -EIO; + } + } + } else { if (ov7xx0_detect(c) < 0) { PERROR("Failed to init OV7xx0"); return -EIO; } - return 0; - } - /* Test for 6xx0 */ - PDEBUG(3, "Testing for 0V6xx0"); - if (ov6xx0_detect(c) < 0) { - PERROR("Failed to init OV6xx0"); - return -EIO; } + return 0; } /* ----------------------------------------------------------------------- */ -static long ovcamchip_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +static int ovcamchip_attach(struct i2c_adapter *adap) { - struct ovcamchip *ov = to_ovcamchip(sd); - struct i2c_client *c = v4l2_get_subdevdata(sd); + int rc = 0; + struct ovcamchip *ov; + struct i2c_client *c; + + /* I2C is not a PnP bus, so we can never be certain that we're talking + * to the right chip. To prevent damage to EEPROMS and such, only + * attach to adapters that are known to contain OV camera chips. */ + + switch (adap->id) { + case I2C_HW_SMBUS_OV511: + case I2C_HW_SMBUS_OV518: + case I2C_HW_SMBUS_W9968CF: + PDEBUG(1, "Adapter ID 0x%06x accepted", adap->id); + break; + default: + PDEBUG(1, "Adapter ID 0x%06x rejected", adap->id); + return -ENODEV; + } + + c = kmalloc(sizeof *c, GFP_KERNEL); + if (!c) { + rc = -ENOMEM; + goto no_client; + } + memcpy(c, &client_template, sizeof *c); + c->adapter = adap; + strcpy(c->name, "OV????"); + + ov = kzalloc(sizeof *ov, GFP_KERNEL); + if (!ov) { + rc = -ENOMEM; + goto no_ov; + } + i2c_set_clientdata(c, ov); + + rc = ovcamchip_detect(c); + if (rc < 0) + goto error; + + strcpy(c->name, chip_names[ov->subtype]); + + PDEBUG(1, "Camera chip detection complete"); + + i2c_attach_client(c); + + return rc; +error: + kfree(ov); +no_ov: + kfree(c); +no_client: + PDEBUG(1, "returning %d", rc); + return rc; +} + +static int ovcamchip_detach(struct i2c_client *c) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); + int rc; + + rc = ov->sops->free(c); + if (rc < 0) + return rc; + + i2c_detach_client(c); + + kfree(ov); + kfree(c); + return 0; +} + +static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg) +{ + struct ovcamchip *ov = i2c_get_clientdata(c); if (!ov->initialized && cmd != OVCAMCHIP_CMD_Q_SUBTYPE && cmd != OVCAMCHIP_CMD_INITIALIZE) { - v4l2_err(sd, "Camera chip not initialized yet!\n"); + dev_err(&c->dev, "ERROR: Camera chip not initialized yet!\n"); return -EPERM; } @@ -303,10 +379,10 @@ static long ovcamchip_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) if (ov->mono) { if (ov->subtype != CC_OV7620) - v4l2_warn(sd, "Monochrome not " + dev_warn(&c->dev, "Warning: Monochrome not " "implemented for this chip\n"); else - v4l2_info(sd, "Initializing chip as " + dev_info(&c->dev, "Initializing chip as " "monochrome\n"); } @@ -324,72 +400,35 @@ static long ovcamchip_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) /* ----------------------------------------------------------------------- */ -static const struct v4l2_subdev_core_ops ovcamchip_core_ops = { - .ioctl = ovcamchip_ioctl, +static struct i2c_driver driver = { + .driver = { + .name = "ovcamchip", + }, + .id = I2C_DRIVERID_OVCAMCHIP, + .attach_adapter = ovcamchip_attach, + .detach_client = ovcamchip_detach, + .command = ovcamchip_command, }; -static const struct v4l2_subdev_ops ovcamchip_ops = { - .core = &ovcamchip_core_ops, +static struct i2c_client client_template = { + .name = "(unset)", + .driver = &driver, }; -static int ovcamchip_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int __init ovcamchip_init(void) { - struct ovcamchip *ov; - struct v4l2_subdev *sd; - int rc = 0; - - ov = kzalloc(sizeof *ov, GFP_KERNEL); - if (!ov) { - rc = -ENOMEM; - goto no_ov; - } - sd = &ov->sd; - v4l2_i2c_subdev_init(sd, client, &ovcamchip_ops); - - rc = ovcamchip_detect(client); - if (rc < 0) - goto error; - - v4l_info(client, "%s found @ 0x%02x (%s)\n", - chip_names[ov->subtype], client->addr << 1, client->adapter->name); - - PDEBUG(1, "Camera chip detection complete"); +#ifdef DEBUG + ovcamchip_debug = debug; +#endif - return rc; -error: - kfree(ov); -no_ov: - PDEBUG(1, "returning %d", rc); - return rc; + PINFO(DRIVER_VERSION " : " DRIVER_DESC); + return i2c_add_driver(&driver); } -static int ovcamchip_remove(struct i2c_client *client) +static void __exit ovcamchip_exit(void) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ovcamchip *ov = to_ovcamchip(sd); - int rc; - - v4l2_device_unregister_subdev(sd); - rc = ov->sops->free(client); - if (rc < 0) - return rc; - - kfree(ov); - return 0; + i2c_del_driver(&driver); } -/* ----------------------------------------------------------------------- */ - -static const struct i2c_device_id ovcamchip_id[] = { - { "ovcamchip", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, ovcamchip_id); - -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "ovcamchip", - .probe = ovcamchip_probe, - .remove = ovcamchip_remove, - .id_table = ovcamchip_id, -}; +module_init(ovcamchip_init); +module_exit(ovcamchip_exit); diff --git a/trunk/drivers/media/video/ovcamchip/ovcamchip_priv.h b/trunk/drivers/media/video/ovcamchip/ovcamchip_priv.h index 4f07b78c88bc..a05650faedda 100644 --- a/trunk/drivers/media/video/ovcamchip/ovcamchip_priv.h +++ b/trunk/drivers/media/video/ovcamchip/ovcamchip_priv.h @@ -16,7 +16,6 @@ #define __LINUX_OVCAMCHIP_PRIV_H #include -#include #include #ifdef DEBUG @@ -47,7 +46,6 @@ struct ovcamchip_ops { }; struct ovcamchip { - struct v4l2_subdev sd; struct ovcamchip_ops *sops; void *spriv; /* Private data for OV7x10.c etc... */ int subtype; /* = SEN_OV7610 etc... */ @@ -55,11 +53,6 @@ struct ovcamchip { int initialized; /* OVCAMCHIP_CMD_INITIALIZE was successful */ }; -static inline struct ovcamchip *to_ovcamchip(struct v4l2_subdev *sd) -{ - return container_of(sd, struct ovcamchip, sd); -} - extern struct ovcamchip_ops ov6x20_ops; extern struct ovcamchip_ops ov6x30_ops; extern struct ovcamchip_ops ov7x10_ops; diff --git a/trunk/drivers/media/video/pvrusb2/Kconfig b/trunk/drivers/media/video/pvrusb2/Kconfig index f9b6001e1dd7..854c2a885358 100644 --- a/trunk/drivers/media/video/pvrusb2/Kconfig +++ b/trunk/drivers/media/video/pvrusb2/Kconfig @@ -40,10 +40,10 @@ config VIDEO_PVRUSB2_DVB select DVB_LGDT330X if !DVB_FE_CUSTOMISE select DVB_S5H1409 if !DVB_FE_CUSTOMISE select DVB_S5H1411 if !DVB_FE_CUSTOMISE - select DVB_TDA10048 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE + select DVB_TDA10048 if !DVB_FE_CUSTOMIZE + select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE + select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE ---help--- This option enables a DVB interface for the pvrusb2 driver. diff --git a/trunk/drivers/media/video/pvrusb2/Makefile b/trunk/drivers/media/video/pvrusb2/Makefile index de2fc14f043b..4fda2de69ab7 100644 --- a/trunk/drivers/media/video/pvrusb2/Makefile +++ b/trunk/drivers/media/video/pvrusb2/Makefile @@ -2,15 +2,14 @@ obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o obj-pvrusb2-dvb-$(CONFIG_VIDEO_PVRUSB2_DVB) := pvrusb2-dvb.o -pvrusb2-objs := pvrusb2-i2c-core.o \ - pvrusb2-audio.o \ +pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \ + pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \ pvrusb2-encoder.o pvrusb2-video-v4l.o \ - pvrusb2-eeprom.o \ + pvrusb2-eeprom.o pvrusb2-tuner.o \ pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \ pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \ pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \ pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \ - pvrusb2-cs53l32a.o \ $(obj-pvrusb2-dvb-y) \ $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y) diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.c index ccf2a3c7ad06..cdedaa55f152 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.c @@ -26,6 +26,14 @@ #include #include +struct pvr2_msp3400_handler { + struct pvr2_hdw *hdw; + struct pvr2_i2c_client *client; + struct pvr2_i2c_handler i2c_handler; + unsigned long stale_mask; +}; + + struct routing_scheme { const int *def; @@ -55,33 +63,123 @@ static const struct routing_scheme routing_schemes[] = { }, }; -void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) +/* This function selects the correct audio input source */ +static void set_stereo(struct pvr2_msp3400_handler *ctxt) +{ + struct pvr2_hdw *hdw = ctxt->hdw; + struct v4l2_routing route; + const struct routing_scheme *sp; + unsigned int sid = hdw->hdw_desc->signal_routing_scheme; + + pvr2_trace(PVR2_TRACE_CHIPS,"i2c msp3400 v4l2 set_stereo"); + + if ((sid < ARRAY_SIZE(routing_schemes)) && + ((sp = routing_schemes + sid) != NULL) && + (hdw->input_val >= 0) && + (hdw->input_val < sp->cnt)) { + route.input = sp->def[hdw->input_val]; + } else { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "*** WARNING *** i2c msp3400 v4l2 set_stereo:" + " Invalid routing scheme (%u) and/or input (%d)", + sid,hdw->input_val); + return; + } + route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); + pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); +} + + +static int check_stereo(struct pvr2_msp3400_handler *ctxt) { - if (hdw->input_dirty || hdw->force_dirty) { - struct v4l2_routing route; - const struct routing_scheme *sp; - unsigned int sid = hdw->hdw_desc->signal_routing_scheme; - - pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo"); - - if ((sid < ARRAY_SIZE(routing_schemes)) && - ((sp = routing_schemes + sid) != NULL) && - (hdw->input_val >= 0) && - (hdw->input_val < sp->cnt)) { - route.input = sp->def[hdw->input_val]; - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "*** WARNING *** subdev msp3400 set_input:" - " Invalid routing scheme (%u)" - " and/or input (%d)", - sid, hdw->input_val); - return; + struct pvr2_hdw *hdw = ctxt->hdw; + return hdw->input_dirty; +} + + +struct pvr2_msp3400_ops { + void (*update)(struct pvr2_msp3400_handler *); + int (*check)(struct pvr2_msp3400_handler *); +}; + + +static const struct pvr2_msp3400_ops msp3400_ops[] = { + { .update = set_stereo, .check = check_stereo}, +}; + + +static int msp3400_check(struct pvr2_msp3400_handler *ctxt) +{ + unsigned long msk; + unsigned int idx; + + for (idx = 0; idx < ARRAY_SIZE(msp3400_ops); idx++) { + msk = 1 << idx; + if (ctxt->stale_mask & msk) continue; + if (msp3400_ops[idx].check(ctxt)) { + ctxt->stale_mask |= msk; } - route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); - sd->ops->audio->s_routing(sd, &route); } + return ctxt->stale_mask != 0; } + +static void msp3400_update(struct pvr2_msp3400_handler *ctxt) +{ + unsigned long msk; + unsigned int idx; + + for (idx = 0; idx < ARRAY_SIZE(msp3400_ops); idx++) { + msk = 1 << idx; + if (!(ctxt->stale_mask & msk)) continue; + ctxt->stale_mask &= ~msk; + msp3400_ops[idx].update(ctxt); + } +} + + +static void pvr2_msp3400_detach(struct pvr2_msp3400_handler *ctxt) +{ + ctxt->client->handler = NULL; + kfree(ctxt); +} + + +static unsigned int pvr2_msp3400_describe(struct pvr2_msp3400_handler *ctxt, + char *buf,unsigned int cnt) +{ + return scnprintf(buf,cnt,"handler: pvrusb2-audio v4l2"); +} + + +static const struct pvr2_i2c_handler_functions msp3400_funcs = { + .detach = (void (*)(void *))pvr2_msp3400_detach, + .check = (int (*)(void *))msp3400_check, + .update = (void (*)(void *))msp3400_update, + .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_msp3400_describe, +}; + + +int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) +{ + struct pvr2_msp3400_handler *ctxt; + if (cp->handler) return 0; + + ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL); + if (!ctxt) return 0; + + ctxt->i2c_handler.func_data = ctxt; + ctxt->i2c_handler.func_table = &msp3400_funcs; + ctxt->client = cp; + ctxt->hdw = hdw; + ctxt->stale_mask = (1 << ARRAY_SIZE(msp3400_ops)) - 1; + cp->handler = &ctxt->i2c_handler; + pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x msp3400 V4L2 handler set up", + cp->client->addr); + return !0; +} + + /* Stuff for Emacs to see, in order to encourage consistent editing style: *** Local Variables: *** diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.h index e3e63d750891..ac54eed3721b 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.h +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.h @@ -22,8 +22,10 @@ #ifndef __PVRUSB2_AUDIO_H #define __PVRUSB2_AUDIO_H -#include "pvrusb2-hdw-internal.h" -void pvr2_msp3400_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *); +#include "pvrusb2-i2c-core.h" + +int pvr2_i2c_msp3400_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); + #endif /* __PVRUSB2_AUDIO_H */ /* diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c deleted file mode 100644 index b5c3428ebb9f..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * 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 - * - */ - -/* - - This source file is specifically designed to interface with the - v4l-dvb cs53l32a module. - -*/ - -#include "pvrusb2-cs53l32a.h" - - -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include -#include -#include -#include - -struct routing_scheme { - const int *def; - unsigned int cnt; -}; - - -static const int routing_scheme1[] = { - [PVR2_CVAL_INPUT_TV] = 2, /* 1 or 2 seems to work here */ - [PVR2_CVAL_INPUT_RADIO] = 2, - [PVR2_CVAL_INPUT_COMPOSITE] = 0, - [PVR2_CVAL_INPUT_SVIDEO] = 0, -}; - -static const struct routing_scheme routing_schemes[] = { - [PVR2_ROUTING_SCHEME_ONAIR] = { - .def = routing_scheme1, - .cnt = ARRAY_SIZE(routing_scheme1), - }, -}; - - -void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) -{ - if (hdw->input_dirty || hdw->force_dirty) { - struct v4l2_routing route; - const struct routing_scheme *sp; - unsigned int sid = hdw->hdw_desc->signal_routing_scheme; - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)", - hdw->input_val); - if ((sid < ARRAY_SIZE(routing_schemes)) && - ((sp = routing_schemes + sid) != NULL) && - (hdw->input_val >= 0) && - (hdw->input_val < sp->cnt)) { - route.input = sp->def[hdw->input_val]; - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "*** WARNING *** subdev v4l2 set_input:" - " Invalid routing scheme (%u)" - " and/or input (%d)", - sid, hdw->input_val); - return; - } - route.output = 0; - sd->ops->audio->s_routing(sd, &route); - } -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c index 4e017ff26c36..895859ec495a 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c @@ -28,6 +28,7 @@ #include "pvrusb2-cx2584x-v4l.h" #include "pvrusb2-video-v4l.h" +#include "pvrusb2-i2c-cmd-v4l2.h" #include "pvrusb2-hdw-internal.h" @@ -38,6 +39,14 @@ #include #include +struct pvr2_v4l_cx2584x { + struct pvr2_i2c_handler handler; + struct pvr2_decoder_ctrl ctrl; + struct pvr2_i2c_client *client; + struct pvr2_hdw *hdw; + unsigned long stale_mask; +}; + struct routing_scheme_item { int vid; @@ -101,44 +110,218 @@ static const struct routing_scheme routing_schemes[] = { }, }; -void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) +static void set_input(struct pvr2_v4l_cx2584x *ctxt) +{ + struct pvr2_hdw *hdw = ctxt->hdw; + struct v4l2_routing route; + enum cx25840_video_input vid_input; + enum cx25840_audio_input aud_input; + const struct routing_scheme *sp; + unsigned int sid = hdw->hdw_desc->signal_routing_scheme; + + memset(&route,0,sizeof(route)); + + if ((sid < ARRAY_SIZE(routing_schemes)) && + ((sp = routing_schemes + sid) != NULL) && + (hdw->input_val >= 0) && + (hdw->input_val < sp->cnt)) { + vid_input = sp->def[hdw->input_val].vid; + aud_input = sp->def[hdw->input_val].aud; + } else { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "*** WARNING *** i2c cx2584x set_input:" + " Invalid routing scheme (%u) and/or input (%d)", + sid,hdw->input_val); + return; + } + + pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x", + vid_input,aud_input); + route.input = (u32)vid_input; + pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route); + route.input = (u32)aud_input; + pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); +} + + +static int check_input(struct pvr2_v4l_cx2584x *ctxt) +{ + struct pvr2_hdw *hdw = ctxt->hdw; + return hdw->input_dirty != 0; +} + + +static void set_audio(struct pvr2_v4l_cx2584x *ctxt) +{ + u32 val; + struct pvr2_hdw *hdw = ctxt->hdw; + + pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_audio %d", + hdw->srate_val); + switch (hdw->srate_val) { + default: + case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000: + val = 48000; + break; + case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100: + val = 44100; + break; + case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000: + val = 32000; + break; + } + pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); +} + + +static int check_audio(struct pvr2_v4l_cx2584x *ctxt) +{ + struct pvr2_hdw *hdw = ctxt->hdw; + return hdw->srate_dirty != 0; +} + + +struct pvr2_v4l_cx2584x_ops { + void (*update)(struct pvr2_v4l_cx2584x *); + int (*check)(struct pvr2_v4l_cx2584x *); +}; + + +static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = { + { .update = set_input, .check = check_input}, + { .update = set_audio, .check = check_audio}, +}; + + +static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt) { - pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update..."); - if (hdw->input_dirty || hdw->force_dirty) { - struct v4l2_routing route; - enum cx25840_video_input vid_input; - enum cx25840_audio_input aud_input; - const struct routing_scheme *sp; - unsigned int sid = hdw->hdw_desc->signal_routing_scheme; - - memset(&route, 0, sizeof(route)); - - if ((sid < ARRAY_SIZE(routing_schemes)) && - ((sp = routing_schemes + sid) != NULL) && - (hdw->input_val >= 0) && - (hdw->input_val < sp->cnt)) { - vid_input = sp->def[hdw->input_val].vid; - aud_input = sp->def[hdw->input_val].aud; - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "*** WARNING *** subdev cx2584x set_input:" - " Invalid routing scheme (%u)" - " and/or input (%d)", - sid, hdw->input_val); - return; + ctxt->client->handler = NULL; + pvr2_hdw_set_decoder(ctxt->hdw,NULL); + kfree(ctxt); +} + + +static int decoder_check(struct pvr2_v4l_cx2584x *ctxt) +{ + unsigned long msk; + unsigned int idx; + + for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) { + msk = 1 << idx; + if (ctxt->stale_mask & msk) continue; + if (decoder_ops[idx].check(ctxt)) { + ctxt->stale_mask |= msk; } + } + return ctxt->stale_mask != 0; +} + - pvr2_trace(PVR2_TRACE_CHIPS, - "subdev cx2584x set_input vid=0x%x aud=0x%x", - vid_input, aud_input); - route.input = (u32)vid_input; - sd->ops->video->s_routing(sd, &route); - route.input = (u32)aud_input; - sd->ops->audio->s_routing(sd, &route); +static void decoder_update(struct pvr2_v4l_cx2584x *ctxt) +{ + unsigned long msk; + unsigned int idx; + + for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) { + msk = 1 << idx; + if (!(ctxt->stale_mask & msk)) continue; + ctxt->stale_mask &= ~msk; + decoder_ops[idx].update(ctxt); } } +static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl) +{ + pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl); + pvr2_v4l2_cmd_stream(ctxt->client,fl); +} + + +static int decoder_detect(struct pvr2_i2c_client *cp) +{ + int ret; + /* Attempt to query the decoder - let's see if it will answer */ + struct v4l2_queryctrl qc; + + memset(&qc,0,sizeof(qc)); + + qc.id = V4L2_CID_BRIGHTNESS; + + ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc); + return ret == 0; /* Return true if it answered */ +} + + +static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt, + char *buf,unsigned int cnt) +{ + return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l"); +} + + +static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt) +{ + int ret; + ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,NULL); + pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret); +} + + +static const struct pvr2_i2c_handler_functions hfuncs = { + .detach = (void (*)(void *))decoder_detach, + .check = (int (*)(void *))decoder_check, + .update = (void (*)(void *))decoder_update, + .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe, +}; + + +int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw, + struct pvr2_i2c_client *cp) +{ + struct pvr2_v4l_cx2584x *ctxt; + + if (hdw->decoder_ctrl) return 0; + if (cp->handler) return 0; + if (!decoder_detect(cp)) return 0; + + ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL); + if (!ctxt) return 0; + + ctxt->handler.func_data = ctxt; + ctxt->handler.func_table = &hfuncs; + ctxt->ctrl.ctxt = ctxt; + ctxt->ctrl.detach = (void (*)(void *))decoder_detach; + ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable; + ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset; + ctxt->client = cp; + ctxt->hdw = hdw; + ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1; + pvr2_hdw_set_decoder(hdw,&ctxt->ctrl); + cp->handler = &ctxt->handler; + { + /* + Mike Isely 19-Nov-2006 - This bit + of nuttiness for cx25840 causes that module to + correctly set up its video scaling. This is really + a problem in the cx25840 module itself, but we work + around it here. The problem has not been seen in + ivtv because there VBI is supported and set up. We + don't do VBI here (at least not yet) and thus we + never attempted to even set it up. + */ + struct v4l2_format fmt; + memset(&fmt,0,sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; + pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_FMT,&fmt); + } + pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up", + cp->client->addr); + return !0; +} + + + /* Stuff for Emacs to see, in order to encourage consistent editing style: diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h index e35c2322a08c..66abf77f51fd 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h @@ -34,9 +34,9 @@ -#include "pvrusb2-hdw-internal.h" +#include "pvrusb2-i2c-core.h" -void pvr2_cx25840_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd); +int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); #endif /* __PVRUSB2_CX2584X_V4L_H */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.c index fbe3856bdca6..ca892fb78a5b 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.c @@ -23,6 +23,7 @@ #include "pvrusb2-debugifc.h" #include "pvrusb2-hdw.h" #include "pvrusb2-debug.h" +#include "pvrusb2-i2c-core.h" struct debugifc_mask_item { const char *name; @@ -146,6 +147,10 @@ int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt) bcnt += ccnt; acnt -= ccnt; buf += ccnt; ccnt = pvr2_hdw_state_report(hdw,buf,acnt); bcnt += ccnt; acnt -= ccnt; buf += ccnt; + ccnt = scnprintf(buf,acnt,"Attached I2C modules:\n"); + bcnt += ccnt; acnt -= ccnt; buf += ccnt; + ccnt = pvr2_i2c_report(hdw,buf,acnt); + bcnt += ccnt; acnt -= ccnt; buf += ccnt; return bcnt; } diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.h index 2f8d46761cd0..e24ff59f8605 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.h +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.h @@ -22,16 +22,16 @@ struct pvr2_hdw; +/* Non-intrusively print some useful debugging info from inside the + driver. This should work even if the driver appears to be + wedged. */ +int pvr2_debugifc_print_info(struct pvr2_hdw *, + char *buf_ptr,unsigned int buf_size); + /* Print general status of driver. This will also trigger a probe of the USB link. Unlike print_info(), this one synchronizes with the driver so the information should be self-consistent (but it will hang if the driver is wedged). */ -int pvr2_debugifc_print_info(struct pvr2_hdw *, - char *buf_ptr, unsigned int buf_size); - -/* Non-intrusively print some useful debugging info from inside the - driver. This should work even if the driver appears to be - wedged. */ int pvr2_debugifc_print_status(struct pvr2_hdw *, char *buf_ptr,unsigned int buf_size); diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-devattr.c index 1cb6a260e8b0..cbe2a3417851 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-devattr.c @@ -46,11 +46,10 @@ pvr2_device_desc structures. /*------------------------------------------------------------------------*/ /* Hauppauge PVR-USB2 Model 29xxx */ -static const struct pvr2_device_client_desc pvr2_cli_29xxx[] = { - { .module_id = PVR2_CLIENT_ID_SAA7115 }, - { .module_id = PVR2_CLIENT_ID_MSP3400 }, - { .module_id = PVR2_CLIENT_ID_TUNER }, - { .module_id = PVR2_CLIENT_ID_DEMOD }, +static const char *pvr2_client_29xxx[] = { + "msp3400", + "saa7115", + "tuner", }; static const char *pvr2_fw1_names_29xxx[] = { @@ -60,8 +59,8 @@ static const char *pvr2_fw1_names_29xxx[] = { static const struct pvr2_device_desc pvr2_device_29xxx = { .description = "WinTV PVR USB2 Model Category 29xxx", .shortname = "29xxx", - .client_table.lst = pvr2_cli_29xxx, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_29xxx), + .client_modules.lst = pvr2_client_29xxx, + .client_modules.cnt = ARRAY_SIZE(pvr2_client_29xxx), .fx2_firmware.lst = pvr2_fw1_names_29xxx, .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_29xxx), .flag_has_hauppauge_rom = !0, @@ -78,11 +77,10 @@ static const struct pvr2_device_desc pvr2_device_29xxx = { /*------------------------------------------------------------------------*/ /* Hauppauge PVR-USB2 Model 24xxx */ -static const struct pvr2_device_client_desc pvr2_cli_24xxx[] = { - { .module_id = PVR2_CLIENT_ID_CX25840 }, - { .module_id = PVR2_CLIENT_ID_TUNER }, - { .module_id = PVR2_CLIENT_ID_WM8775 }, - { .module_id = PVR2_CLIENT_ID_DEMOD }, +static const char *pvr2_client_24xxx[] = { + "cx25840", + "tuner", + "wm8775", }; static const char *pvr2_fw1_names_24xxx[] = { @@ -92,8 +90,8 @@ static const char *pvr2_fw1_names_24xxx[] = { static const struct pvr2_device_desc pvr2_device_24xxx = { .description = "WinTV PVR USB2 Model Category 24xxx", .shortname = "24xxx", - .client_table.lst = pvr2_cli_24xxx, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_24xxx), + .client_modules.lst = pvr2_client_24xxx, + .client_modules.cnt = ARRAY_SIZE(pvr2_client_24xxx), .fx2_firmware.lst = pvr2_fw1_names_24xxx, .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_24xxx), .flag_has_cx25840 = !0, @@ -113,16 +111,16 @@ static const struct pvr2_device_desc pvr2_device_24xxx = { /*------------------------------------------------------------------------*/ /* GOTVIEW USB2.0 DVD2 */ -static const struct pvr2_device_client_desc pvr2_cli_gotview_2[] = { - { .module_id = PVR2_CLIENT_ID_CX25840 }, - { .module_id = PVR2_CLIENT_ID_TUNER }, +static const char *pvr2_client_gotview_2[] = { + "cx25840", + "tuner", }; static const struct pvr2_device_desc pvr2_device_gotview_2 = { .description = "Gotview USB 2.0 DVD 2", .shortname = "gv2", - .client_table.lst = pvr2_cli_gotview_2, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_gotview_2), + .client_modules.lst = pvr2_client_gotview_2, + .client_modules.cnt = ARRAY_SIZE(pvr2_client_gotview_2), .flag_has_cx25840 = !0, .default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3, .flag_has_analogtuner = !0, @@ -142,8 +140,8 @@ static const struct pvr2_device_desc pvr2_device_gotview_2 = { static const struct pvr2_device_desc pvr2_device_gotview_2d = { .description = "Gotview USB 2.0 DVD Deluxe", .shortname = "gv2d", - .client_table.lst = pvr2_cli_gotview_2, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_gotview_2), + .client_modules.lst = pvr2_client_gotview_2, + .client_modules.cnt = ARRAY_SIZE(pvr2_client_gotview_2), .flag_has_cx25840 = !0, .default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3, .flag_has_analogtuner = !0, @@ -183,29 +181,29 @@ static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap) return 0; } -static const struct pvr2_dvb_props pvr2_onair_creator_fe_props = { +static struct pvr2_dvb_props pvr2_onair_creator_fe_props = { .frontend_attach = pvr2_lgdt3303_attach, .tuner_attach = pvr2_lgh06xf_attach, }; #endif -static const struct pvr2_device_client_desc pvr2_cli_onair_creator[] = { - { .module_id = PVR2_CLIENT_ID_SAA7115 }, - { .module_id = PVR2_CLIENT_ID_CS53L32A }, - { .module_id = PVR2_CLIENT_ID_TUNER }, +static const char *pvr2_client_onair_creator[] = { + "saa7115", + "tuner", + "cs53l32a", }; static const struct pvr2_device_desc pvr2_device_onair_creator = { .description = "OnAir Creator Hybrid USB tuner", .shortname = "oac", - .client_table.lst = pvr2_cli_onair_creator, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_onair_creator), + .client_modules.lst = pvr2_client_onair_creator, + .client_modules.cnt = ARRAY_SIZE(pvr2_client_onair_creator), .default_tuner_type = TUNER_LG_TDVS_H06XF, .flag_has_analogtuner = !0, .flag_has_composite = !0, .flag_has_svideo = !0, .flag_digital_requires_cx23416 = !0, - .signal_routing_scheme = PVR2_ROUTING_SCHEME_ONAIR, + .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, .digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR, .default_std_mask = V4L2_STD_NTSC_M, #ifdef CONFIG_VIDEO_PVRUSB2_DVB @@ -243,29 +241,29 @@ static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap) return 0; } -static const struct pvr2_dvb_props pvr2_onair_usb2_fe_props = { +static struct pvr2_dvb_props pvr2_onair_usb2_fe_props = { .frontend_attach = pvr2_lgdt3302_attach, .tuner_attach = pvr2_fcv1236d_attach, }; #endif -static const struct pvr2_device_client_desc pvr2_cli_onair_usb2[] = { - { .module_id = PVR2_CLIENT_ID_SAA7115 }, - { .module_id = PVR2_CLIENT_ID_CS53L32A }, - { .module_id = PVR2_CLIENT_ID_TUNER }, +static const char *pvr2_client_onair_usb2[] = { + "saa7115", + "tuner", + "cs53l32a", }; static const struct pvr2_device_desc pvr2_device_onair_usb2 = { .description = "OnAir USB2 Hybrid USB tuner", .shortname = "oa2", - .client_table.lst = pvr2_cli_onair_usb2, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_onair_usb2), + .client_modules.lst = pvr2_client_onair_usb2, + .client_modules.cnt = ARRAY_SIZE(pvr2_client_onair_usb2), .default_tuner_type = TUNER_PHILIPS_FCV1236D, .flag_has_analogtuner = !0, .flag_has_composite = !0, .flag_has_svideo = !0, .flag_digital_requires_cx23416 = !0, - .signal_routing_scheme = PVR2_ROUTING_SCHEME_ONAIR, + .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, .digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR, .default_std_mask = V4L2_STD_NTSC_M, #ifdef CONFIG_VIDEO_PVRUSB2_DVB @@ -316,16 +314,15 @@ static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap) return 0; } -static const struct pvr2_dvb_props pvr2_73xxx_dvb_props = { +static struct pvr2_dvb_props pvr2_73xxx_dvb_props = { .frontend_attach = pvr2_tda10048_attach, .tuner_attach = pvr2_73xxx_tda18271_8295_attach, }; #endif -static const struct pvr2_device_client_desc pvr2_cli_73xxx[] = { - { .module_id = PVR2_CLIENT_ID_CX25840 }, - { .module_id = PVR2_CLIENT_ID_TUNER, - .i2c_address_list = "\x42"}, +static const char *pvr2_client_73xxx[] = { + "cx25840", + "tuner", }; static const char *pvr2_fw1_names_73xxx[] = { @@ -335,8 +332,8 @@ static const char *pvr2_fw1_names_73xxx[] = { static const struct pvr2_device_desc pvr2_device_73xxx = { .description = "WinTV HVR-1900 Model Category 73xxx", .shortname = "73xxx", - .client_table.lst = pvr2_cli_73xxx, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), + .client_modules.lst = pvr2_client_73xxx, + .client_modules.cnt = ARRAY_SIZE(pvr2_client_73xxx), .fx2_firmware.lst = pvr2_fw1_names_73xxx, .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_73xxx), .flag_has_cx25840 = !0, @@ -421,17 +418,22 @@ static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap) return 0; } -static const struct pvr2_dvb_props pvr2_750xx_dvb_props = { +static struct pvr2_dvb_props pvr2_750xx_dvb_props = { .frontend_attach = pvr2_s5h1409_attach, .tuner_attach = pvr2_tda18271_8295_attach, }; -static const struct pvr2_dvb_props pvr2_751xx_dvb_props = { +static struct pvr2_dvb_props pvr2_751xx_dvb_props = { .frontend_attach = pvr2_s5h1411_attach, .tuner_attach = pvr2_tda18271_8295_attach, }; #endif +static const char *pvr2_client_75xxx[] = { + "cx25840", + "tuner", +}; + static const char *pvr2_fw1_names_75xxx[] = { "v4l-pvrusb2-73xxx-01.fw", }; @@ -439,8 +441,8 @@ static const char *pvr2_fw1_names_75xxx[] = { static const struct pvr2_device_desc pvr2_device_750xx = { .description = "WinTV HVR-1950 Model Category 750xx", .shortname = "750xx", - .client_table.lst = pvr2_cli_73xxx, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), + .client_modules.lst = pvr2_client_75xxx, + .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx), .fx2_firmware.lst = pvr2_fw1_names_75xxx, .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx), .flag_has_cx25840 = !0, @@ -461,8 +463,8 @@ static const struct pvr2_device_desc pvr2_device_750xx = { static const struct pvr2_device_desc pvr2_device_751xx = { .description = "WinTV HVR-1950 Model Category 751xx", .shortname = "751xx", - .client_table.lst = pvr2_cli_73xxx, - .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx), + .client_modules.lst = pvr2_client_75xxx, + .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx), .fx2_firmware.lst = pvr2_fw1_names_75xxx, .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx), .flag_has_cx25840 = !0, diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-devattr.h index 3e553389cbc3..cb3a33eb0276 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-devattr.h +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-devattr.h @@ -33,34 +33,6 @@ */ -#define PVR2_CLIENT_ID_NULL 0 -#define PVR2_CLIENT_ID_MSP3400 1 -#define PVR2_CLIENT_ID_CX25840 2 -#define PVR2_CLIENT_ID_SAA7115 3 -#define PVR2_CLIENT_ID_TUNER 4 -#define PVR2_CLIENT_ID_CS53L32A 5 -#define PVR2_CLIENT_ID_WM8775 6 -#define PVR2_CLIENT_ID_DEMOD 7 - -struct pvr2_device_client_desc { - /* One ovr PVR2_CLIENT_ID_xxxx */ - unsigned char module_id; - - /* Null-terminated array of I2C addresses to try in order - initialize the module. It's safe to make this null terminated - since we're never going to encounter an i2c device with an - address of zero. If this is a null pointer or zero-length, - then no I2C addresses have been specified, in which case we'll - try some compiled in defaults for now. */ - unsigned char *i2c_address_list; -}; - -struct pvr2_device_client_table { - const struct pvr2_device_client_desc *lst; - unsigned char cnt; -}; - - struct pvr2_string_table { const char **lst; unsigned int cnt; @@ -68,7 +40,6 @@ struct pvr2_string_table { #define PVR2_ROUTING_SCHEME_HAUPPAUGE 0 #define PVR2_ROUTING_SCHEME_GOTVIEW 1 -#define PVR2_ROUTING_SCHEME_ONAIR 2 #define PVR2_DIGITAL_SCHEME_NONE 0 #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1 @@ -95,9 +66,6 @@ struct pvr2_device_desc { /* List of additional client modules we need to load */ struct pvr2_string_table client_modules; - /* List of defined client modules we need to load */ - struct pvr2_device_client_table client_table; - /* List of FX2 firmware file names we should search; if empty then FX2 firmware check / load is skipped and we assume the device was initialized from internal ROM. */ @@ -105,7 +73,7 @@ struct pvr2_device_desc { #ifdef CONFIG_VIDEO_PVRUSB2_DVB /* callback functions to handle attachment of digital tuner & demod */ - const struct pvr2_dvb_props *dvb_props; + struct pvr2_dvb_props *dvb_props; #endif /* Initial standard bits to use for this device, if not zero. diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-dvb.c index b7f5c49b1dbc..77b3c3385066 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-dvb.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-dvb.c @@ -321,7 +321,7 @@ static int pvr2_dvb_adapter_exit(struct pvr2_dvb_adapter *adap) static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap) { struct pvr2_hdw *hdw = adap->channel.hdw; - const struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props; + struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props; int ret = 0; if (dvb_props == NULL) { diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 54ac5349dee2..273d2a1aa220 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -347,7 +347,7 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw) int encMisc3Arg = 0; #if 0 - /* This inexplicable bit happens in the Hauppauge windows + /* This inexplicable bit happens in the Hauppage windows driver (for both 24xxx and 29xxx devices). However I currently see no difference in behavior with or without this stuff. Leave this here as a note of its existence, diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index 5d75eb5211b1..de7ee7264be6 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h @@ -38,7 +38,6 @@ #include #include "pvrusb2-hdw.h" #include "pvrusb2-io.h" -#include #include #include "pvrusb2-devattr.h" @@ -58,6 +57,8 @@ #define LOCK_TAKE(x) do { mutex_lock(&x##_mutex); x##_held = !0; } while (0) #define LOCK_GIVE(x) do { x##_held = 0; mutex_unlock(&x##_mutex); } while (0) +struct pvr2_decoder; + typedef int (*pvr2_ctlf_is_dirty)(struct pvr2_ctrl *); typedef void (*pvr2_ctlf_clear_dirty)(struct pvr2_ctrl *); typedef int (*pvr2_ctlf_check_value)(struct pvr2_ctrl *,int); @@ -138,6 +139,22 @@ struct pvr2_ctrl { }; +struct pvr2_decoder_ctrl { + void *ctxt; + void (*detach)(void *); + void (*enable)(void *,int); + void (*force_reset)(void *); +}; + +#define PVR2_I2C_PEND_DETECT 0x01 /* Need to detect a client type */ +#define PVR2_I2C_PEND_CLIENT 0x02 /* Client needs a specific update */ +#define PVR2_I2C_PEND_REFRESH 0x04 /* Client has specific pending bits */ +#define PVR2_I2C_PEND_STALE 0x08 /* Broadcast pending bits */ + +#define PVR2_I2C_PEND_ALL (PVR2_I2C_PEND_DETECT |\ + PVR2_I2C_PEND_CLIENT |\ + PVR2_I2C_PEND_REFRESH |\ + PVR2_I2C_PEND_STALE) /* Disposition of firmware1 loading situation */ #define FW1_STATE_UNKNOWN 0 @@ -162,8 +179,6 @@ struct pvr2_hdw { struct usb_device *usb_dev; struct usb_interface *usb_intf; - /* Our handle into the v4l2 sub-device architecture */ - struct v4l2_device v4l2_dev; /* Device description, anything that must adjust behavior based on device specific info will use information held here. */ const struct pvr2_device_desc *hdw_desc; @@ -171,6 +186,7 @@ struct pvr2_hdw { /* Kernel worker thread handling */ struct workqueue_struct *workqueue; struct work_struct workpoll; /* Update driver state */ + struct work_struct worki2csync; /* Update i2c clients */ /* Video spigot */ struct pvr2_stream *vid_stream; @@ -179,26 +195,20 @@ struct pvr2_hdw { struct mutex big_lock_mutex; int big_lock_held; /* For debugging */ - /* This is a simple string which identifies the instance of this - driver. It is unique within the set of existing devices, but - there is no attempt to keep the name consistent with the same - physical device each time. */ char name[32]; - /* This is a simple string which identifies the physical device - instance itself - if possible. (If not possible, then it is - based on the specific driver instance, similar to name above.) - The idea here is that userspace might hopefully be able to use - this recognize specific tuners. It will encode a serial number, - if available. */ - char identifier[32]; - /* I2C stuff */ struct i2c_adapter i2c_adap; struct i2c_algorithm i2c_algo; pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT]; int i2c_cx25840_hack_state; int i2c_linked; + unsigned int i2c_pend_types; /* Which types of update are needed */ + unsigned long i2c_pend_mask; /* Change bits we need to scan */ + unsigned long i2c_stale_mask; /* Pending broadcast change bits */ + unsigned long i2c_active_mask; /* All change bits currently in use */ + struct list_head i2c_clients; + struct mutex i2c_list_lock; /* Frequency table */ unsigned int freqTable[FREQTABLE_SIZE]; @@ -265,7 +275,6 @@ struct pvr2_hdw { wait_queue_head_t state_wait_data; - int force_dirty; /* consider all controls dirty if true */ int flag_ok; /* device in known good state */ int flag_disconnected; /* flag_ok == 0 due to disconnect */ int flag_init_ok; /* true if structure is fully initialized */ @@ -274,13 +283,17 @@ struct pvr2_hdw { int flag_decoder_missed;/* We've noticed missing decoder */ int flag_tripped; /* Indicates overall failure to start */ - unsigned int decoder_client_id; + struct pvr2_decoder_ctrl *decoder_ctrl; // CPU firmware info (used to help find / save firmware data) char *fw_buffer; unsigned int fw_size; int fw_cpu_flag; /* True if we are dealing with the CPU */ + // True if there is a request to trigger logging of state in each + // module. + int log_requested; + /* Tuner / frequency control stuff */ unsigned int tuner_type; int tuner_updated; @@ -378,8 +391,7 @@ struct pvr2_hdw { /* This function gets the current frequency */ unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *); - -void pvr2_hdw_status_poll(struct pvr2_hdw *); +void pvr2_hdw_set_decoder(struct pvr2_hdw *,struct pvr2_decoder_ctrl *); #endif /* __PVRUSB2_HDW_INTERNAL_H */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 7a65b42a4f53..fa304e5f252a 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -24,22 +24,17 @@ #include #include #include -#include #include "pvrusb2.h" #include "pvrusb2-std.h" #include "pvrusb2-util.h" #include "pvrusb2-hdw.h" #include "pvrusb2-i2c-core.h" +#include "pvrusb2-tuner.h" #include "pvrusb2-eeprom.h" #include "pvrusb2-hdw-internal.h" #include "pvrusb2-encoder.h" #include "pvrusb2-debug.h" #include "pvrusb2-fx2-cmd.h" -#include "pvrusb2-wm8775.h" -#include "pvrusb2-video-v4l.h" -#include "pvrusb2-cx2584x-v4l.h" -#include "pvrusb2-cs53l32a.h" -#include "pvrusb2-audio.h" #define TV_MIN_FREQ 55250000L #define TV_MAX_FREQ 850000000L @@ -109,39 +104,6 @@ MODULE_PARM_DESC(radio_freq, "specify initial radio frequency"); /* size of a firmware chunk */ #define FIRMWARE_CHUNK_SIZE 0x2000 -typedef void (*pvr2_subdev_update_func)(struct pvr2_hdw *, - struct v4l2_subdev *); - -static const pvr2_subdev_update_func pvr2_module_update_functions[] = { - [PVR2_CLIENT_ID_WM8775] = pvr2_wm8775_subdev_update, - [PVR2_CLIENT_ID_SAA7115] = pvr2_saa7115_subdev_update, - [PVR2_CLIENT_ID_MSP3400] = pvr2_msp3400_subdev_update, - [PVR2_CLIENT_ID_CX25840] = pvr2_cx25840_subdev_update, - [PVR2_CLIENT_ID_CS53L32A] = pvr2_cs53l32a_subdev_update, -}; - -static const char *module_names[] = { - [PVR2_CLIENT_ID_MSP3400] = "msp3400", - [PVR2_CLIENT_ID_CX25840] = "cx25840", - [PVR2_CLIENT_ID_SAA7115] = "saa7115", - [PVR2_CLIENT_ID_TUNER] = "tuner", - [PVR2_CLIENT_ID_DEMOD] = "tuner", - [PVR2_CLIENT_ID_CS53L32A] = "cs53l32a", - [PVR2_CLIENT_ID_WM8775] = "wm8775", -}; - - -static const unsigned char *module_i2c_addresses[] = { - [PVR2_CLIENT_ID_TUNER] = "\x60\x61\x62\x63", - [PVR2_CLIENT_ID_DEMOD] = "\x43", - [PVR2_CLIENT_ID_MSP3400] = "\x40", - [PVR2_CLIENT_ID_SAA7115] = "\x21", - [PVR2_CLIENT_ID_WM8775] = "\x1b", - [PVR2_CLIENT_ID_CX25840] = "\x44", - [PVR2_CLIENT_ID_CS53L32A] = "\x11", -}; - - /* Define the list of additional controls we'll dynamically construct based on query of the cx2341x module. */ struct pvr2_mpeg_ids { @@ -315,6 +277,7 @@ static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v); static void pvr2_hdw_state_sched(struct pvr2_hdw *); static int pvr2_hdw_state_eval(struct pvr2_hdw *); static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long); +static void pvr2_hdw_worker_i2c(struct work_struct *work); static void pvr2_hdw_worker_poll(struct work_struct *work); static int pvr2_hdw_wait(struct pvr2_hdw *,int state); static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *); @@ -679,7 +642,7 @@ static int ctrl_freq_max_get(struct pvr2_ctrl *cptr, int *vp) unsigned long fv; struct pvr2_hdw *hdw = cptr->hdw; if (hdw->tuner_signal_stale) { - pvr2_hdw_status_poll(hdw); + pvr2_i2c_core_status_poll(hdw); } fv = hdw->tuner_signal_info.rangehigh; if (!fv) { @@ -701,7 +664,7 @@ static int ctrl_freq_min_get(struct pvr2_ctrl *cptr, int *vp) unsigned long fv; struct pvr2_hdw *hdw = cptr->hdw; if (hdw->tuner_signal_stale) { - pvr2_hdw_status_poll(hdw); + pvr2_i2c_core_status_poll(hdw); } fv = hdw->tuner_signal_info.rangelow; if (!fv) { @@ -895,7 +858,7 @@ static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr) static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp) { struct pvr2_hdw *hdw = cptr->hdw; - pvr2_hdw_status_poll(hdw); + pvr2_i2c_core_status_poll(hdw); *vp = hdw->tuner_signal_info.signal; return 0; } @@ -905,7 +868,7 @@ static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp) int val = 0; unsigned int subchan; struct pvr2_hdw *hdw = cptr->hdw; - pvr2_hdw_status_poll(hdw); + pvr2_i2c_core_status_poll(hdw); subchan = hdw->tuner_signal_info.rxsubchans; if (subchan & V4L2_TUNER_SUB_MONO) { val |= (1 << V4L2_TUNER_MODE_MONO); @@ -1320,12 +1283,6 @@ const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *hdw) } -const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *hdw) -{ - return hdw->identifier; -} - - unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw) { return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio; @@ -1677,27 +1634,33 @@ static const char *pvr2_get_state_name(unsigned int st) static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl) { - /* Even though we really only care about the video decoder chip at - this point, we'll broadcast stream on/off to all sub-devices - anyway, just in case somebody else wants to hear the - command... */ - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 stream=%s", - (enablefl ? "on" : "off")); - v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_stream, enablefl); - if (hdw->decoder_client_id) { - /* We get here if the encoder has been noticed. Otherwise - we'll issue a warning to the user (which should - normally never happen). */ - return 0; + if (!hdw->decoder_ctrl) { + if (!hdw->flag_decoder_missed) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "WARNING: No decoder present"); + hdw->flag_decoder_missed = !0; + trace_stbit("flag_decoder_missed", + hdw->flag_decoder_missed); + } + return -EIO; } - if (!hdw->flag_decoder_missed) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING: No decoder present"); - hdw->flag_decoder_missed = !0; + hdw->decoder_ctrl->enable(hdw->decoder_ctrl->ctxt,enablefl); + return 0; +} + + +void pvr2_hdw_set_decoder(struct pvr2_hdw *hdw,struct pvr2_decoder_ctrl *ptr) +{ + if (hdw->decoder_ctrl == ptr) return; + hdw->decoder_ctrl = ptr; + if (hdw->decoder_ctrl && hdw->flag_decoder_missed) { + hdw->flag_decoder_missed = 0; trace_stbit("flag_decoder_missed", hdw->flag_decoder_missed); + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "Decoder has appeared"); + pvr2_hdw_state_sched(hdw); } - return -EIO; } @@ -1964,166 +1927,6 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw) } -static unsigned int pvr2_copy_i2c_addr_list( - unsigned short *dst, const unsigned char *src, - unsigned int dst_max) -{ - unsigned int cnt = 0; - if (!src) return 0; - while (src[cnt] && (cnt + 1) < dst_max) { - dst[cnt] = src[cnt]; - cnt++; - } - dst[cnt] = I2C_CLIENT_END; - return cnt; -} - - -static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, - const struct pvr2_device_client_desc *cd) -{ - const char *fname; - unsigned char mid; - struct v4l2_subdev *sd; - unsigned int i2ccnt; - const unsigned char *p; - /* Arbitrary count - max # i2c addresses we will probe */ - unsigned short i2caddr[25]; - - mid = cd->module_id; - fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL; - if (!fname) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Module ID %u for device %s has no name", - mid, - hdw->hdw_desc->description); - return -EINVAL; - } - pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u (%s) for device %s being loaded...", - mid, fname, - hdw->hdw_desc->description); - - i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, cd->i2c_address_list, - ARRAY_SIZE(i2caddr)); - if (!i2ccnt && ((p = (mid < ARRAY_SIZE(module_i2c_addresses)) ? - module_i2c_addresses[mid] : NULL) != NULL)) { - /* Second chance: Try default i2c address list */ - i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, p, - ARRAY_SIZE(i2caddr)); - if (i2ccnt) { - pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u:" - " Using default i2c address list", - mid); - } - } - - if (!i2ccnt) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Module ID %u (%s) for device %s:" - " No i2c addresses", - mid, fname, hdw->hdw_desc->description); - return -EINVAL; - } - - /* Note how the 2nd and 3rd arguments are the same for both - * v4l2_i2c_new_subdev() and v4l2_i2c_new_probed_subdev(). Why? - * Well the 2nd argument is the module name to load, while the 3rd - * argument is documented in the framework as being the "chipid" - - * and every other place where I can find examples of this, the - * "chipid" appears to just be the module name again. So here we - * just do the same thing. */ - if (i2ccnt == 1) { - pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u:" - " Setting up with specified i2c address 0x%x", - mid, i2caddr[0]); - sd = v4l2_i2c_new_subdev(&hdw->i2c_adap, - fname, fname, - i2caddr[0]); - } else { - pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u:" - " Setting up with address probe list", - mid); - sd = v4l2_i2c_new_probed_subdev(&hdw->i2c_adap, - fname, fname, - i2caddr); - } - - if (!sd) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Module ID %u (%s) for device %s failed to load", - mid, fname, hdw->hdw_desc->description); - return -EIO; - } - - /* Tag this sub-device instance with the module ID we know about. - In other places we'll use that tag to determine if the instance - requires special handling. */ - sd->grp_id = mid; - - pvr2_trace(PVR2_TRACE_INFO, "Attached sub-driver %s", fname); - - - /* client-specific setup... */ - switch (mid) { - case PVR2_CLIENT_ID_CX25840: - hdw->decoder_client_id = mid; - { - /* - Mike Isely 19-Nov-2006 - This - bit of nuttiness for cx25840 causes that module - to correctly set up its video scaling. This is - really a problem in the cx25840 module itself, - but we work around it here. The problem has not - been seen in ivtv because there VBI is supported - and set up. We don't do VBI here (at least not - yet) and thus we never attempted to even set it - up. - */ - struct v4l2_format fmt; - pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u:" - " Executing cx25840 VBI hack", - mid); - memset(&fmt, 0, sizeof(fmt)); - fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; - v4l2_device_call_all(&hdw->v4l2_dev, mid, - video, s_fmt, &fmt); - } - break; - case PVR2_CLIENT_ID_SAA7115: - hdw->decoder_client_id = mid; - break; - default: break; - } - - return 0; -} - - -static void pvr2_hdw_load_modules(struct pvr2_hdw *hdw) -{ - unsigned int idx; - const struct pvr2_string_table *cm; - const struct pvr2_device_client_table *ct; - int okFl = !0; - - cm = &hdw->hdw_desc->client_modules; - for (idx = 0; idx < cm->cnt; idx++) { - request_module(cm->lst[idx]); - } - - ct = &hdw->hdw_desc->client_table; - for (idx = 0; idx < ct->cnt; idx++) { - if (pvr2_hdw_load_subdev(hdw, &ct->lst[idx]) < 0) okFl = 0; - } - if (!okFl) pvr2_hdw_render_useless(hdw); -} - - static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) { int ret; @@ -2163,7 +1966,9 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) if (!pvr2_hdw_dev_ok(hdw)) return; - hdw->force_dirty = !0; + for (idx = 0; idx < hdw->hdw_desc->client_modules.cnt; idx++) { + request_module(hdw->hdw_desc->client_modules.lst[idx]); + } if (!hdw->hdw_desc->flag_no_powerup) { pvr2_hdw_cmd_powerup(hdw); @@ -2182,11 +1987,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) pvr2_i2c_core_init(hdw); if (!pvr2_hdw_dev_ok(hdw)) return; - pvr2_hdw_load_modules(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - - v4l2_device_call_all(&hdw->v4l2_dev, 0, core, init, 0); - for (idx = 0; idx < CTRLDEF_COUNT; idx++) { cptr = hdw->controls + idx; if (cptr->info->skip_init) continue; @@ -2224,19 +2024,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) hdw->std_mask_eeprom = V4L2_STD_ALL; } - if (hdw->serial_number) { - idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1, - "sn-%lu", hdw->serial_number); - } else if (hdw->unit_number >= 0) { - idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1, - "unit-%c", - hdw->unit_number + 'a'); - } else { - idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1, - "unit-??"); - } - hdw->identifier[idx] = 0; - pvr2_hdw_setup_std(hdw); if (!get_default_tuner_type(hdw)) { @@ -2245,6 +2032,8 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) hdw->tuner_type); } + pvr2_i2c_core_check_stale(hdw); + hdw->tuner_updated = 0; if (!pvr2_hdw_dev_ok(hdw)) return; @@ -2382,14 +2171,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, struct pvr2_hdw *hdw = NULL; int valid_std_mask; struct pvr2_ctrl *cptr; - struct usb_device *usb_dev; const struct pvr2_device_desc *hdw_desc; __u8 ifnum; struct v4l2_queryctrl qctrl; struct pvr2_ctl_info *ciptr; - usb_dev = interface_to_usbdev(intf); - hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info); if (hdw_desc == NULL) { @@ -2574,11 +2360,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL); if (!hdw->ctl_read_urb) goto fail; - if (v4l2_device_register(&usb_dev->dev, &hdw->v4l2_dev) != 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Error registering with v4l core, giving up"); - goto fail; - } mutex_lock(&pvr2_unit_mtx); do { for (idx = 0; idx < PVR_NUM; idx++) { if (unit_pointers[idx]) continue; @@ -2601,6 +2382,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, hdw->workqueue = create_singlethread_workqueue(hdw->name); INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll); + INIT_WORK(&hdw->worki2csync,pvr2_hdw_worker_i2c); pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s", hdw->unit_number,hdw->name); @@ -2609,9 +2391,12 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, hdw->flag_ok = !0; hdw->usb_intf = intf; - hdw->usb_dev = usb_dev; + hdw->usb_dev = interface_to_usbdev(intf); - usb_make_path(hdw->usb_dev, hdw->bus_info, sizeof(hdw->bus_info)); + scnprintf(hdw->bus_info,sizeof(hdw->bus_info), + "usb %s address %d", + dev_name(&hdw->usb_dev->dev), + hdw->usb_dev->devnum); ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber; usb_set_interface(hdw->usb_dev,ifnum,0); @@ -2669,10 +2454,6 @@ static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw) hdw->ctl_write_buffer = NULL; } hdw->flag_disconnected = !0; - /* If we don't do this, then there will be a dangling struct device - reference to our disappearing device persisting inside the V4L - core... */ - v4l2_device_disconnect(&hdw->v4l2_dev); hdw->usb_dev = NULL; hdw->usb_intf = NULL; pvr2_hdw_render_useless(hdw); @@ -2700,8 +2481,10 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) pvr2_stream_destroy(hdw->vid_stream); hdw->vid_stream = NULL; } + if (hdw->decoder_ctrl) { + hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt); + } pvr2_i2c_core_done(hdw); - v4l2_device_unregister(&hdw->v4l2_dev); pvr2_hdw_remove_usb_stuff(hdw); mutex_lock(&pvr2_unit_mtx); do { if ((hdw->unit_number >= 0) && @@ -2895,150 +2678,6 @@ static const char *get_ctrl_typename(enum pvr2_ctl_type tp) } -static void pvr2_subdev_set_control(struct pvr2_hdw *hdw, int id, - const char *name, int val) -{ - struct v4l2_control ctrl; - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 %s=%d", name, val); - memset(&ctrl, 0, sizeof(ctrl)); - ctrl.id = id; - ctrl.value = val; - v4l2_device_call_all(&hdw->v4l2_dev, 0, core, s_ctrl, &ctrl); -} - -#define PVR2_SUBDEV_SET_CONTROL(hdw, id, lab) \ - if ((hdw)->lab##_dirty || (hdw)->force_dirty) { \ - pvr2_subdev_set_control(hdw, id, #lab, (hdw)->lab##_val); \ - } - -/* Execute whatever commands are required to update the state of all the - sub-devices so that they match our current control values. */ -static void pvr2_subdev_update(struct pvr2_hdw *hdw) -{ - struct v4l2_subdev *sd; - unsigned int id; - pvr2_subdev_update_func fp; - - pvr2_trace(PVR2_TRACE_CHIPS, "subdev update..."); - - if (hdw->tuner_updated || hdw->force_dirty) { - struct tuner_setup setup; - pvr2_trace(PVR2_TRACE_CHIPS, "subdev tuner set_type(%d)", - hdw->tuner_type); - if (((int)(hdw->tuner_type)) >= 0) { - setup.addr = ADDR_UNSET; - setup.type = hdw->tuner_type; - setup.mode_mask = T_RADIO | T_ANALOG_TV; - v4l2_device_call_all(&hdw->v4l2_dev, 0, - tuner, s_type_addr, &setup); - } - } - - if (hdw->input_dirty || hdw->std_dirty || hdw->force_dirty) { - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_standard"); - if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { - v4l2_device_call_all(&hdw->v4l2_dev, 0, - tuner, s_radio); - } else { - v4l2_std_id vs; - vs = hdw->std_mask_cur; - v4l2_device_call_all(&hdw->v4l2_dev, 0, - tuner, s_std, vs); - } - hdw->tuner_signal_stale = !0; - hdw->cropcap_stale = !0; - } - - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_BRIGHTNESS, brightness); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_CONTRAST, contrast); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_SATURATION, saturation); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_HUE, hue); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_MUTE, mute); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_VOLUME, volume); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BALANCE, balance); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BASS, bass); - PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_TREBLE, treble); - - if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) { - struct v4l2_tuner vt; - memset(&vt, 0, sizeof(vt)); - vt.audmode = hdw->audiomode_val; - v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt); - } - - if (hdw->freqDirty || hdw->force_dirty) { - unsigned long fv; - struct v4l2_frequency freq; - fv = pvr2_hdw_get_cur_freq(hdw); - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_freq(%lu)", fv); - if (hdw->tuner_signal_stale) pvr2_hdw_status_poll(hdw); - memset(&freq, 0, sizeof(freq)); - if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) { - /* ((fv * 1000) / 62500) */ - freq.frequency = (fv * 2) / 125; - } else { - freq.frequency = fv / 62500; - } - /* tuner-core currently doesn't seem to care about this, but - let's set it anyway for completeness. */ - if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { - freq.type = V4L2_TUNER_RADIO; - } else { - freq.type = V4L2_TUNER_ANALOG_TV; - } - freq.tuner = 0; - v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, - s_frequency, &freq); - } - - if (hdw->res_hor_dirty || hdw->res_ver_dirty || hdw->force_dirty) { - struct v4l2_format fmt; - memset(&fmt, 0, sizeof(fmt)); - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt.fmt.pix.width = hdw->res_hor_val; - fmt.fmt.pix.height = hdw->res_ver_val; - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)", - fmt.fmt.pix.width, fmt.fmt.pix.height); - v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_fmt, &fmt); - } - - if (hdw->srate_dirty || hdw->force_dirty) { - u32 val; - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_audio %d", - hdw->srate_val); - switch (hdw->srate_val) { - default: - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000: - val = 48000; - break; - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100: - val = 44100; - break; - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000: - val = 32000; - break; - } - v4l2_device_call_all(&hdw->v4l2_dev, 0, - audio, s_clock_freq, val); - } - - /* Unable to set crop parameters; there is apparently no equivalent - for VIDIOC_S_CROP */ - - v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) { - id = sd->grp_id; - if (id >= ARRAY_SIZE(pvr2_module_update_functions)) continue; - fp = pvr2_module_update_functions[id]; - if (!fp) continue; - (*fp)(hdw, sd); - } - - if (hdw->tuner_signal_stale || hdw->cropcap_stale) { - pvr2_hdw_status_poll(hdw); - } -} - - /* Figure out if we need to commit control changes. If so, mark internal state flags to indicate this fact and return true. Otherwise do nothing else and return false. */ @@ -3047,7 +2686,7 @@ static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw) unsigned int idx; struct pvr2_ctrl *cptr; int value; - int commit_flag = hdw->force_dirty; + int commit_flag = 0; char buf[100]; unsigned int bcnt,ccnt; @@ -3203,6 +2842,18 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS); } + /* Scan i2c core at this point - before we clear all the dirty + bits. Various parts of the i2c core will notice dirty bits as + appropriate and arrange to broadcast or directly send updates to + the client drivers in order to keep everything in sync */ + pvr2_i2c_core_check_stale(hdw); + + for (idx = 0; idx < hdw->control_cnt; idx++) { + cptr = hdw->controls + idx; + if (!cptr->info->clear_dirty) continue; + cptr->info->clear_dirty(cptr); + } + if (hdw->active_stream_type != hdw->desired_stream_type) { /* Handle any side effects of stream config here */ hdw->active_stream_type = hdw->desired_stream_type; @@ -3222,16 +2873,8 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) } } - /* Check and update state for all sub-devices. */ - pvr2_subdev_update(hdw); - - hdw->tuner_updated = 0; - hdw->force_dirty = 0; - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - if (!cptr->info->clear_dirty) continue; - cptr->info->clear_dirty(cptr); - } + /* Now execute i2c core update */ + pvr2_i2c_core_sync(hdw); if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) && hdw->state_encoder_run) { @@ -3261,6 +2904,15 @@ int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw) } +static void pvr2_hdw_worker_i2c(struct work_struct *work) +{ + struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,worki2csync); + LOCK_TAKE(hdw->big_lock); do { + pvr2_i2c_core_sync(hdw); + } while (0); LOCK_GIVE(hdw->big_lock); +} + + static void pvr2_hdw_worker_poll(struct work_struct *work) { int fl = 0; @@ -3321,7 +2973,7 @@ int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw) void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw) { LOCK_TAKE(hdw->big_lock); do { - pvr2_hdw_status_poll(hdw); + pvr2_i2c_core_status_poll(hdw); } while (0); LOCK_GIVE(hdw->big_lock); } @@ -3331,7 +2983,7 @@ static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw) if (!hdw->cropcap_stale) { return 0; } - pvr2_hdw_status_poll(hdw); + pvr2_i2c_core_status_poll(hdw); if (hdw->cropcap_stale) { return -EIO; } @@ -3358,7 +3010,7 @@ int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp) { LOCK_TAKE(hdw->big_lock); do { if (hdw->tuner_signal_stale) { - pvr2_hdw_status_poll(hdw); + pvr2_i2c_core_status_poll(hdw); } memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner)); } while (0); LOCK_GIVE(hdw->big_lock); @@ -3377,8 +3029,11 @@ void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw) { int nr = pvr2_hdw_get_unit_number(hdw); LOCK_TAKE(hdw->big_lock); do { + hdw->log_requested = !0; printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr); - v4l2_device_call_all(&hdw->v4l2_dev, 0, core, log_status); + pvr2_i2c_core_check_stale(hdw); + hdw->log_requested = 0; + pvr2_i2c_core_sync(hdw); pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:"); cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2"); pvr2_hdw_state_log_state(hdw); @@ -4061,16 +3716,22 @@ int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *hdw) int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw) { - pvr2_trace(PVR2_TRACE_INIT, - "Requesting decoder reset"); - if (hdw->decoder_client_id) { - v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id, - core, reset, 0); - return 0; + if (!hdw->decoder_ctrl) { + pvr2_trace(PVR2_TRACE_INIT, + "Unable to reset decoder: nothing attached"); + return -ENOTTY; + } + + if (!hdw->decoder_ctrl->force_reset) { + pvr2_trace(PVR2_TRACE_INIT, + "Unable to reset decoder: not implemented"); + return -ENOTTY; } + pvr2_trace(PVR2_TRACE_INIT, - "Unable to reset decoder: nothing attached"); - return -ENOTTY; + "Requesting decoder reset"); + hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt); + return 0; } @@ -4815,79 +4476,6 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which, } -/* Generate report containing info about attached sub-devices and attached - i2c clients, including an indication of which attached i2c clients are - actually sub-devices. */ -static unsigned int pvr2_hdw_report_clients(struct pvr2_hdw *hdw, - char *buf, unsigned int acnt) -{ - struct v4l2_subdev *sd; - unsigned int tcnt = 0; - unsigned int ccnt; - struct i2c_client *client; - struct list_head *item; - void *cd; - const char *p; - unsigned int id; - - ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers:"); - tcnt += ccnt; - v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) { - id = sd->grp_id; - p = NULL; - if (id < ARRAY_SIZE(module_names)) p = module_names[id]; - if (p) { - ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s", p); - tcnt += ccnt; - } else { - ccnt = scnprintf(buf + tcnt, acnt - tcnt, - " (unknown id=%u)", id); - tcnt += ccnt; - } - } - ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n"); - tcnt += ccnt; - - ccnt = scnprintf(buf + tcnt, acnt - tcnt, "I2C clients:\n"); - tcnt += ccnt; - - mutex_lock(&hdw->i2c_adap.clist_lock); - list_for_each(item, &hdw->i2c_adap.clients) { - client = list_entry(item, struct i2c_client, list); - ccnt = scnprintf(buf + tcnt, acnt - tcnt, - " %s: i2c=%02x", client->name, client->addr); - tcnt += ccnt; - cd = i2c_get_clientdata(client); - v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) { - if (cd == sd) { - id = sd->grp_id; - p = NULL; - if (id < ARRAY_SIZE(module_names)) { - p = module_names[id]; - } - if (p) { - ccnt = scnprintf(buf + tcnt, - acnt - tcnt, - " subdev=%s", p); - tcnt += ccnt; - } else { - ccnt = scnprintf(buf + tcnt, - acnt - tcnt, - " subdev= id %u)", - id); - tcnt += ccnt; - } - break; - } - } - ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n"); - tcnt += ccnt; - } - mutex_unlock(&hdw->i2c_adap.clist_lock); - return tcnt; -} - - unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw, char *buf,unsigned int acnt) { @@ -4902,8 +4490,6 @@ unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw, buf[0] = '\n'; ccnt = 1; bcnt += ccnt; acnt -= ccnt; buf += ccnt; } - ccnt = pvr2_hdw_report_clients(hdw, buf, acnt); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; LOCK_GIVE(hdw->big_lock); return bcnt; } @@ -4911,25 +4497,14 @@ unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw, static void pvr2_hdw_state_log_state(struct pvr2_hdw *hdw) { - char buf[256]; - unsigned int idx, ccnt; - unsigned int lcnt, ucnt; + char buf[128]; + unsigned int idx,ccnt; for (idx = 0; ; idx++) { ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,sizeof(buf)); if (!ccnt) break; printk(KERN_INFO "%s %.*s\n",hdw->name,ccnt,buf); } - ccnt = pvr2_hdw_report_clients(hdw, buf, sizeof(buf)); - ucnt = 0; - while (ucnt < ccnt) { - lcnt = 0; - while ((lcnt + ucnt < ccnt) && (buf[lcnt + ucnt] != '\n')) { - lcnt++; - } - printk(KERN_INFO "%s %.*s\n", hdw->name, lcnt, buf + ucnt); - ucnt += lcnt + 1; - } } @@ -5066,30 +4641,6 @@ int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val) } -void pvr2_hdw_status_poll(struct pvr2_hdw *hdw) -{ - struct v4l2_tuner *vtp = &hdw->tuner_signal_info; - memset(vtp, 0, sizeof(*vtp)); - hdw->tuner_signal_stale = 0; - /* Note: There apparently is no replacement for VIDIOC_CROPCAP - using v4l2-subdev - therefore we can't support that AT ALL right - now. (Of course, no sub-drivers seem to implement it either. - But now it's a a chicken and egg problem...) */ - v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, g_tuner, - &hdw->tuner_signal_info); - pvr2_trace(PVR2_TRACE_CHIPS, "subdev status poll" - " type=%u strength=%u audio=0x%x cap=0x%x" - " low=%u hi=%u", - vtp->type, - vtp->signal, vtp->rxsubchans, vtp->capability, - vtp->rangelow, vtp->rangehigh); - - /* We have to do this to avoid getting into constant polling if - there's nobody to answer a poll of cropcap info. */ - hdw->cropcap_stale = 0; -} - - unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *hdw) { return hdw->input_avail_mask; @@ -5185,6 +4736,7 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw, int setFl, u64 *val_ptr) { #ifdef CONFIG_VIDEO_ADV_DEBUG + struct pvr2_i2c_client *cp; struct v4l2_dbg_register req; int stat = 0; int okFl = 0; @@ -5194,9 +4746,21 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw, req.match = *match; req.reg = reg_id; if (setFl) req.val = *val_ptr; - /* It would be nice to know if a sub-device answered the request */ - v4l2_device_call_all(&hdw->v4l2_dev, 0, core, g_register, &req); - if (!setFl) *val_ptr = req.val; + mutex_lock(&hdw->i2c_list_lock); do { + list_for_each_entry(cp, &hdw->i2c_clients, list) { + if (!v4l2_chip_match_i2c_client( + cp->client, + &req.match)) { + continue; + } + stat = pvr2_i2c_client_cmd( + cp,(setFl ? VIDIOC_DBG_S_REGISTER : + VIDIOC_DBG_G_REGISTER),&req); + if (!setFl) *val_ptr = req.val; + okFl = !0; + break; + } + } while (0); mutex_unlock(&hdw->i2c_list_lock); if (okFl) { return stat; } diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 7b6940554e9a..1b4fec337c6b 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -132,9 +132,6 @@ unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *); /* Retrieve bus location info of device */ const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *); -/* Retrieve per-instance string identifier for this specific device */ -const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *); - /* Called when hardware has been unplugged */ void pvr2_hdw_disconnect(struct pvr2_hdw *); @@ -239,7 +236,8 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *, enum pvr2_v4l_type index,int); /* Direct read/write access to chip's registers: - match - specify criteria to identify target chip (this is a v4l dbg struct) + match_type - how to interpret match_chip (e.g. driver ID, i2c address) + match_chip - chip match value (e.g. I2C_DRIVERD_xxxx) reg_id - register number to access setFl - true to set the register, false to read it val_ptr - storage location for source / result. */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c new file mode 100644 index 000000000000..94a47718e88e --- /dev/null +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c @@ -0,0 +1,113 @@ +/* + * + * + * Copyright (C) 2005 Mike Isely + * + * 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 + * + * 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 "pvrusb2-i2c-core.h" +#include "pvrusb2-hdw-internal.h" +#include "pvrusb2-debug.h" +#include "pvrusb2-i2c-cmd-v4l2.h" +#include "pvrusb2-audio.h" +#include "pvrusb2-tuner.h" +#include "pvrusb2-video-v4l.h" +#include "pvrusb2-cx2584x-v4l.h" +#include "pvrusb2-wm8775.h" + +#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__) + +#define OP_STANDARD 0 +#define OP_AUDIOMODE 1 +#define OP_BCSH 2 +#define OP_VOLUME 3 +#define OP_FREQ 4 +#define OP_AUDIORATE 5 +#define OP_CROP 6 +#define OP_SIZE 7 +#define OP_LOG 8 + +static const struct pvr2_i2c_op * const ops[] = { + [OP_STANDARD] = &pvr2_i2c_op_v4l2_standard, + [OP_AUDIOMODE] = &pvr2_i2c_op_v4l2_audiomode, + [OP_BCSH] = &pvr2_i2c_op_v4l2_bcsh, + [OP_VOLUME] = &pvr2_i2c_op_v4l2_volume, + [OP_FREQ] = &pvr2_i2c_op_v4l2_frequency, + [OP_CROP] = &pvr2_i2c_op_v4l2_crop, + [OP_SIZE] = &pvr2_i2c_op_v4l2_size, + [OP_LOG] = &pvr2_i2c_op_v4l2_log, +}; + +void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) +{ + int id; + id = cp->client->driver->id; + cp->ctl_mask = ((1 << OP_STANDARD) | + (1 << OP_AUDIOMODE) | + (1 << OP_BCSH) | + (1 << OP_VOLUME) | + (1 << OP_FREQ) | + (1 << OP_CROP) | + (1 << OP_SIZE) | + (1 << OP_LOG)); + cp->status_poll = pvr2_v4l2_cmd_status_poll; + + if (id == I2C_DRIVERID_MSP3400) { + if (pvr2_i2c_msp3400_setup(hdw,cp)) { + return; + } + } + if (id == I2C_DRIVERID_TUNER) { + if (pvr2_i2c_tuner_setup(hdw,cp)) { + return; + } + } + if (id == I2C_DRIVERID_CX25840) { + if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) { + return; + } + } + if (id == I2C_DRIVERID_WM8775) { + if (pvr2_i2c_wm8775_setup(hdw,cp)) { + return; + } + } + if (id == I2C_DRIVERID_SAA711X) { + if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) { + return; + } + } +} + + +const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx) +{ + if (idx >= ARRAY_SIZE(ops)) + return NULL; + return ops[idx]; +} + + +/* + Stuff for Emacs to see, in order to encourage consistent editing style: + *** Local Variables: *** + *** mode: c *** + *** fill-column: 75 *** + *** tab-width: 8 *** + *** c-basic-offset: 8 *** + *** End: *** + */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c new file mode 100644 index 000000000000..16bb11902a52 --- /dev/null +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c @@ -0,0 +1,322 @@ +/* + * + * + * Copyright (C) 2005 Mike Isely + * Copyright (C) 2004 Aurelien Alleaume + * + * 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 + * + * 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 "pvrusb2-i2c-cmd-v4l2.h" +#include "pvrusb2-hdw-internal.h" +#include "pvrusb2-debug.h" +#include +#include + +static void set_standard(struct pvr2_hdw *hdw) +{ + pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_standard"); + + if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { + pvr2_i2c_core_cmd(hdw,AUDC_SET_RADIO,NULL); + } else { + v4l2_std_id vs; + vs = hdw->std_mask_cur; + pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs); + } + hdw->tuner_signal_stale = !0; + hdw->cropcap_stale = !0; +} + + +static int check_standard(struct pvr2_hdw *hdw) +{ + return (hdw->input_dirty != 0) || (hdw->std_dirty != 0); +} + + +const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard = { + .check = check_standard, + .update = set_standard, + .name = "v4l2_standard", +}; + + +static void set_bcsh(struct pvr2_hdw *hdw) +{ + struct v4l2_control ctrl; + pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_bcsh" + " b=%d c=%d s=%d h=%d", + hdw->brightness_val,hdw->contrast_val, + hdw->saturation_val,hdw->hue_val); + memset(&ctrl,0,sizeof(ctrl)); + ctrl.id = V4L2_CID_BRIGHTNESS; + ctrl.value = hdw->brightness_val; + pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); + ctrl.id = V4L2_CID_CONTRAST; + ctrl.value = hdw->contrast_val; + pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); + ctrl.id = V4L2_CID_SATURATION; + ctrl.value = hdw->saturation_val; + pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); + ctrl.id = V4L2_CID_HUE; + ctrl.value = hdw->hue_val; + pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); +} + + +static int check_bcsh(struct pvr2_hdw *hdw) +{ + return (hdw->brightness_dirty || + hdw->contrast_dirty || + hdw->saturation_dirty || + hdw->hue_dirty); +} + + +const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh = { + .check = check_bcsh, + .update = set_bcsh, + .name = "v4l2_bcsh", +}; + + +static void set_volume(struct pvr2_hdw *hdw) +{ + struct v4l2_control ctrl; + pvr2_trace(PVR2_TRACE_CHIPS, + "i2c v4l2 set_volume" + "(vol=%d bal=%d bas=%d treb=%d mute=%d)", + hdw->volume_val, + hdw->balance_val, + hdw->bass_val, + hdw->treble_val, + hdw->mute_val); + memset(&ctrl,0,sizeof(ctrl)); + ctrl.id = V4L2_CID_AUDIO_MUTE; + ctrl.value = hdw->mute_val ? 1 : 0; + pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); + ctrl.id = V4L2_CID_AUDIO_VOLUME; + ctrl.value = hdw->volume_val; + pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); + ctrl.id = V4L2_CID_AUDIO_BALANCE; + ctrl.value = hdw->balance_val; + pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); + ctrl.id = V4L2_CID_AUDIO_BASS; + ctrl.value = hdw->bass_val; + pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); + ctrl.id = V4L2_CID_AUDIO_TREBLE; + ctrl.value = hdw->treble_val; + pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); +} + + +static int check_volume(struct pvr2_hdw *hdw) +{ + return (hdw->volume_dirty || + hdw->balance_dirty || + hdw->bass_dirty || + hdw->treble_dirty || + hdw->mute_dirty); +} + + +const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume = { + .check = check_volume, + .update = set_volume, + .name = "v4l2_volume", +}; + + +static void set_audiomode(struct pvr2_hdw *hdw) +{ + struct v4l2_tuner vt; + memset(&vt,0,sizeof(vt)); + vt.audmode = hdw->audiomode_val; + pvr2_i2c_core_cmd(hdw,VIDIOC_S_TUNER,&vt); +} + + +static int check_audiomode(struct pvr2_hdw *hdw) +{ + return (hdw->input_dirty || + hdw->audiomode_dirty); +} + + +const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode = { + .check = check_audiomode, + .update = set_audiomode, + .name = "v4l2_audiomode", +}; + + +static void set_frequency(struct pvr2_hdw *hdw) +{ + unsigned long fv; + struct v4l2_frequency freq; + fv = pvr2_hdw_get_cur_freq(hdw); + pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_freq(%lu)",fv); + if (hdw->tuner_signal_stale) { + pvr2_i2c_core_status_poll(hdw); + } + memset(&freq,0,sizeof(freq)); + if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) { + // ((fv * 1000) / 62500) + freq.frequency = (fv * 2) / 125; + } else { + freq.frequency = fv / 62500; + } + /* tuner-core currently doesn't seem to care about this, but + let's set it anyway for completeness. */ + if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { + freq.type = V4L2_TUNER_RADIO; + } else { + freq.type = V4L2_TUNER_ANALOG_TV; + } + freq.tuner = 0; + pvr2_i2c_core_cmd(hdw,VIDIOC_S_FREQUENCY,&freq); +} + + +static int check_frequency(struct pvr2_hdw *hdw) +{ + return hdw->freqDirty != 0; +} + + +const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency = { + .check = check_frequency, + .update = set_frequency, + .name = "v4l2_freq", +}; + + +static void set_size(struct pvr2_hdw *hdw) +{ + struct v4l2_format fmt; + + memset(&fmt,0,sizeof(fmt)); + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt.fmt.pix.width = hdw->res_hor_val; + fmt.fmt.pix.height = hdw->res_ver_val; + + pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_size(%dx%d)", + fmt.fmt.pix.width,fmt.fmt.pix.height); + + pvr2_i2c_core_cmd(hdw,VIDIOC_S_FMT,&fmt); +} + + +static int check_size(struct pvr2_hdw *hdw) +{ + return (hdw->res_hor_dirty || hdw->res_ver_dirty); +} + + +const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = { + .check = check_size, + .update = set_size, + .name = "v4l2_size", +}; + + +static void set_crop(struct pvr2_hdw *hdw) +{ + struct v4l2_crop crop; + + memset(&crop, 0, sizeof crop); + crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + crop.c.left = hdw->cropl_val; + crop.c.top = hdw->cropt_val; + crop.c.height = hdw->croph_val; + crop.c.width = hdw->cropw_val; + + pvr2_trace(PVR2_TRACE_CHIPS, + "i2c v4l2 set_crop crop=%d:%d:%d:%d", + crop.c.width, crop.c.height, crop.c.left, crop.c.top); + + pvr2_i2c_core_cmd(hdw, VIDIOC_S_CROP, &crop); +} + +static int check_crop(struct pvr2_hdw *hdw) +{ + return (hdw->cropl_dirty || hdw->cropt_dirty || + hdw->cropw_dirty || hdw->croph_dirty); +} + +const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop = { + .check = check_crop, + .update = set_crop, + .name = "v4l2_crop", +}; + + +static void do_log(struct pvr2_hdw *hdw) +{ + pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()"); + pvr2_i2c_core_cmd(hdw,VIDIOC_LOG_STATUS,NULL); + +} + + +static int check_log(struct pvr2_hdw *hdw) +{ + return hdw->log_requested != 0; +} + + +const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log = { + .check = check_log, + .update = do_log, + .name = "v4l2_log", +}; + + +void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl) +{ + pvr2_i2c_client_cmd(cp, + (fl ? VIDIOC_STREAMON : VIDIOC_STREAMOFF),NULL); +} + + +void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *cp) +{ + int stat; + struct pvr2_hdw *hdw = cp->hdw; + if (hdw->cropcap_stale) { + hdw->cropcap_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + stat = pvr2_i2c_client_cmd(cp, VIDIOC_CROPCAP, + &hdw->cropcap_info); + if (stat == 0) { + /* Check was successful, so the data is no + longer considered stale. */ + hdw->cropcap_stale = 0; + } + } + pvr2_i2c_client_cmd(cp, VIDIOC_G_TUNER, &hdw->tuner_signal_info); +} + + +/* + Stuff for Emacs to see, in order to encourage consistent editing style: + *** Local Variables: *** + *** mode: c *** + *** fill-column: 70 *** + *** tab-width: 8 *** + *** c-basic-offset: 8 *** + *** End: *** + */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h new file mode 100644 index 000000000000..eb744a20610d --- /dev/null +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h @@ -0,0 +1,50 @@ +/* + * + * + * Copyright (C) 2005 Mike Isely + * Copyright (C) 2004 Aurelien Alleaume + * + * 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 + * + * 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 + * + */ + +#ifndef __PVRUSB2_CMD_V4L2_H +#define __PVRUSB2_CMD_V4L2_H + +#include "pvrusb2-i2c-core.h" + +extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard; +extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_radio; +extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh; +extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume; +extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency; +extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop; +extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size; +extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode; +extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log; + +void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *,int); +void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *); + +#endif /* __PVRUSB2_CMD_V4L2_H */ + +/* + Stuff for Emacs to see, in order to encourage consistent editing style: + *** Local Variables: *** + *** mode: c *** + *** fill-column: 70 *** + *** tab-width: 8 *** + *** c-basic-offset: 8 *** + *** End: *** + */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index 9464862745fa..d6a35401fefb 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -18,7 +18,6 @@ * */ -#include #include "pvrusb2-i2c-core.h" #include "pvrusb2-hdw-internal.h" #include "pvrusb2-debug.h" @@ -30,7 +29,8 @@ /* This module attempts to implement a compliant I2C adapter for the pvrusb2 - device. + device. By doing this we can then make use of existing functionality in + V4L (e.g. tuner.c) rather than rolling our own. */ @@ -42,6 +42,10 @@ static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 }; module_param_array(ir_mode, int, NULL, 0444); MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR"); +static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp, + unsigned int detail, + char *buf,unsigned int maxlen); + static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ u8 i2c_addr, /* I2C address we're talking to */ u8 *data, /* Data to write */ @@ -520,13 +524,414 @@ static u32 pvr2_i2c_functionality(struct i2c_adapter *adap) return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; } +static int pvr2_i2c_core_singleton(struct i2c_client *cp, + unsigned int cmd,void *arg) +{ + int stat; + if (!cp) return -EINVAL; + if (!(cp->driver)) return -EINVAL; + if (!(cp->driver->command)) return -EINVAL; + if (!try_module_get(cp->driver->driver.owner)) return -EAGAIN; + stat = cp->driver->command(cp,cmd,arg); + module_put(cp->driver->driver.owner); + return stat; +} + +int pvr2_i2c_client_cmd(struct pvr2_i2c_client *cp,unsigned int cmd,void *arg) +{ + int stat; + if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) { + char buf[100]; + unsigned int cnt; + cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG, + buf,sizeof(buf)); + pvr2_trace(PVR2_TRACE_I2C_CMD, + "i2c COMMAND (code=%u 0x%x) to %.*s", + cmd,cmd,cnt,buf); + } + stat = pvr2_i2c_core_singleton(cp->client,cmd,arg); + if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) { + char buf[100]; + unsigned int cnt; + cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG, + buf,sizeof(buf)); + pvr2_trace(PVR2_TRACE_I2C_CMD, + "i2c COMMAND to %.*s (ret=%d)",cnt,buf,stat); + } + return stat; +} + +int pvr2_i2c_core_cmd(struct pvr2_hdw *hdw,unsigned int cmd,void *arg) +{ + struct pvr2_i2c_client *cp, *ncp; + int stat = -EINVAL; + + if (!hdw) return stat; + + mutex_lock(&hdw->i2c_list_lock); + list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) { + if (!cp->recv_enable) continue; + mutex_unlock(&hdw->i2c_list_lock); + stat = pvr2_i2c_client_cmd(cp,cmd,arg); + mutex_lock(&hdw->i2c_list_lock); + } + mutex_unlock(&hdw->i2c_list_lock); + return stat; +} + + +static int handler_check(struct pvr2_i2c_client *cp) +{ + struct pvr2_i2c_handler *hp = cp->handler; + if (!hp) return 0; + if (!hp->func_table->check) return 0; + return hp->func_table->check(hp->func_data) != 0; +} + +#define BUFSIZE 500 + + +void pvr2_i2c_core_status_poll(struct pvr2_hdw *hdw) +{ + struct pvr2_i2c_client *cp; + mutex_lock(&hdw->i2c_list_lock); do { + struct v4l2_tuner *vtp = &hdw->tuner_signal_info; + memset(vtp,0,sizeof(*vtp)); + list_for_each_entry(cp, &hdw->i2c_clients, list) { + if (!cp->detected_flag) continue; + if (!cp->status_poll) continue; + cp->status_poll(cp); + } + hdw->tuner_signal_stale = 0; + pvr2_trace(PVR2_TRACE_CHIPS,"i2c status poll" + " type=%u strength=%u audio=0x%x cap=0x%x" + " low=%u hi=%u", + vtp->type, + vtp->signal,vtp->rxsubchans,vtp->capability, + vtp->rangelow,vtp->rangehigh); + } while (0); mutex_unlock(&hdw->i2c_list_lock); +} + + +/* Issue various I2C operations to bring chip-level drivers into sync with + state stored in this driver. */ +void pvr2_i2c_core_sync(struct pvr2_hdw *hdw) +{ + unsigned long msk; + unsigned int idx; + struct pvr2_i2c_client *cp, *ncp; + + if (!hdw->i2c_linked) return; + if (!(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL)) { + return; + } + mutex_lock(&hdw->i2c_list_lock); do { + pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync BEGIN"); + if (hdw->i2c_pend_types & PVR2_I2C_PEND_DETECT) { + /* One or more I2C clients have attached since we + last synced. So scan the list and identify the + new clients. */ + char *buf; + unsigned int cnt; + unsigned long amask = 0; + buf = kmalloc(BUFSIZE,GFP_KERNEL); + pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_DETECT"); + hdw->i2c_pend_types &= ~PVR2_I2C_PEND_DETECT; + list_for_each_entry(cp, &hdw->i2c_clients, list) { + if (!cp->detected_flag) { + cp->ctl_mask = 0; + pvr2_i2c_probe(hdw,cp); + cp->detected_flag = !0; + msk = cp->ctl_mask; + cnt = 0; + if (buf) { + cnt = pvr2_i2c_client_describe( + cp, + PVR2_I2C_DETAIL_ALL, + buf,BUFSIZE); + } + trace_i2c("Probed: %.*s",cnt,buf); + if (handler_check(cp)) { + hdw->i2c_pend_types |= + PVR2_I2C_PEND_CLIENT; + } + cp->pend_mask = msk; + hdw->i2c_pend_mask |= msk; + hdw->i2c_pend_types |= + PVR2_I2C_PEND_REFRESH; + } + amask |= cp->ctl_mask; + } + hdw->i2c_active_mask = amask; + if (buf) kfree(buf); + } + if (hdw->i2c_pend_types & PVR2_I2C_PEND_STALE) { + /* Need to do one or more global updates. Arrange + for this to happen. */ + unsigned long m2; + pvr2_trace(PVR2_TRACE_I2C_CORE, + "i2c: PEND_STALE (0x%lx)", + hdw->i2c_stale_mask); + hdw->i2c_pend_types &= ~PVR2_I2C_PEND_STALE; + list_for_each_entry(cp, &hdw->i2c_clients, list) { + m2 = hdw->i2c_stale_mask; + m2 &= cp->ctl_mask; + m2 &= ~cp->pend_mask; + if (m2) { + pvr2_trace(PVR2_TRACE_I2C_CORE, + "i2c: cp=%p setting 0x%lx", + cp,m2); + cp->pend_mask |= m2; + } + } + hdw->i2c_pend_mask |= hdw->i2c_stale_mask; + hdw->i2c_stale_mask = 0; + hdw->i2c_pend_types |= PVR2_I2C_PEND_REFRESH; + } + if (hdw->i2c_pend_types & PVR2_I2C_PEND_CLIENT) { + /* One or more client handlers are asking for an + update. Run through the list of known clients + and update each one. */ + pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_CLIENT"); + hdw->i2c_pend_types &= ~PVR2_I2C_PEND_CLIENT; + list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, + list) { + if (!cp->handler) continue; + if (!cp->handler->func_table->update) continue; + pvr2_trace(PVR2_TRACE_I2C_CORE, + "i2c: cp=%p update",cp); + mutex_unlock(&hdw->i2c_list_lock); + cp->handler->func_table->update( + cp->handler->func_data); + mutex_lock(&hdw->i2c_list_lock); + /* If client's update function set some + additional pending bits, account for that + here. */ + if (cp->pend_mask & ~hdw->i2c_pend_mask) { + hdw->i2c_pend_mask |= cp->pend_mask; + hdw->i2c_pend_types |= + PVR2_I2C_PEND_REFRESH; + } + } + } + if (hdw->i2c_pend_types & PVR2_I2C_PEND_REFRESH) { + const struct pvr2_i2c_op *opf; + unsigned long pm; + /* Some actual updates are pending. Walk through + each update type and perform it. */ + pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_REFRESH" + " (0x%lx)",hdw->i2c_pend_mask); + hdw->i2c_pend_types &= ~PVR2_I2C_PEND_REFRESH; + pm = hdw->i2c_pend_mask; + hdw->i2c_pend_mask = 0; + for (idx = 0, msk = 1; pm; idx++, msk <<= 1) { + if (!(pm & msk)) continue; + pm &= ~msk; + list_for_each_entry(cp, &hdw->i2c_clients, + list) { + if (cp->pend_mask & msk) { + cp->pend_mask &= ~msk; + cp->recv_enable = !0; + } else { + cp->recv_enable = 0; + } + } + opf = pvr2_i2c_get_op(idx); + if (!opf) continue; + mutex_unlock(&hdw->i2c_list_lock); + opf->update(hdw); + mutex_lock(&hdw->i2c_list_lock); + } + } + pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync END"); + } while (0); mutex_unlock(&hdw->i2c_list_lock); +} + +int pvr2_i2c_core_check_stale(struct pvr2_hdw *hdw) +{ + unsigned long msk,sm,pm; + unsigned int idx; + const struct pvr2_i2c_op *opf; + struct pvr2_i2c_client *cp; + unsigned int pt = 0; + + pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale BEGIN"); + + pm = hdw->i2c_active_mask; + sm = 0; + for (idx = 0, msk = 1; pm; idx++, msk <<= 1) { + if (!(msk & pm)) continue; + pm &= ~msk; + opf = pvr2_i2c_get_op(idx); + if (!opf) continue; + if (opf->check(hdw)) { + sm |= msk; + } + } + if (sm) pt |= PVR2_I2C_PEND_STALE; + + list_for_each_entry(cp, &hdw->i2c_clients, list) + if (handler_check(cp)) + pt |= PVR2_I2C_PEND_CLIENT; + + if (pt) { + mutex_lock(&hdw->i2c_list_lock); do { + hdw->i2c_pend_types |= pt; + hdw->i2c_stale_mask |= sm; + hdw->i2c_pend_mask |= hdw->i2c_stale_mask; + } while (0); mutex_unlock(&hdw->i2c_list_lock); + } + + pvr2_trace(PVR2_TRACE_I2C_CORE, + "i2c: types=0x%x stale=0x%lx pend=0x%lx", + hdw->i2c_pend_types, + hdw->i2c_stale_mask, + hdw->i2c_pend_mask); + pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale END"); + + return (hdw->i2c_pend_types & PVR2_I2C_PEND_ALL) != 0; +} + +static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp, + unsigned int detail, + char *buf,unsigned int maxlen) +{ + unsigned int ccnt,bcnt; + int spcfl = 0; + const struct pvr2_i2c_op *opf; + + ccnt = 0; + if (detail & PVR2_I2C_DETAIL_DEBUG) { + bcnt = scnprintf(buf,maxlen, + "ctxt=%p ctl_mask=0x%lx", + cp,cp->ctl_mask); + ccnt += bcnt; buf += bcnt; maxlen -= bcnt; + spcfl = !0; + } + bcnt = scnprintf(buf,maxlen, + "%s%s @ 0x%x", + (spcfl ? " " : ""), + cp->client->name, + cp->client->addr); + ccnt += bcnt; buf += bcnt; maxlen -= bcnt; + if ((detail & PVR2_I2C_DETAIL_HANDLER) && + cp->handler && cp->handler->func_table->describe) { + bcnt = scnprintf(buf,maxlen," ("); + ccnt += bcnt; buf += bcnt; maxlen -= bcnt; + bcnt = cp->handler->func_table->describe( + cp->handler->func_data,buf,maxlen); + ccnt += bcnt; buf += bcnt; maxlen -= bcnt; + bcnt = scnprintf(buf,maxlen,")"); + ccnt += bcnt; buf += bcnt; maxlen -= bcnt; + } + if ((detail & PVR2_I2C_DETAIL_CTLMASK) && cp->ctl_mask) { + unsigned int idx; + unsigned long msk,sm; + + bcnt = scnprintf(buf,maxlen," ["); + ccnt += bcnt; buf += bcnt; maxlen -= bcnt; + sm = 0; + spcfl = 0; + for (idx = 0, msk = 1; msk; idx++, msk <<= 1) { + if (!(cp->ctl_mask & msk)) continue; + opf = pvr2_i2c_get_op(idx); + if (opf) { + bcnt = scnprintf(buf,maxlen,"%s%s", + spcfl ? " " : "", + opf->name); + ccnt += bcnt; buf += bcnt; maxlen -= bcnt; + spcfl = !0; + } else { + sm |= msk; + } + } + if (sm) { + bcnt = scnprintf(buf,maxlen,"%s%lx", + idx != 0 ? " " : "",sm); + ccnt += bcnt; buf += bcnt; maxlen -= bcnt; + } + bcnt = scnprintf(buf,maxlen,"]"); + ccnt += bcnt; buf += bcnt; maxlen -= bcnt; + } + return ccnt; +} + +unsigned int pvr2_i2c_report(struct pvr2_hdw *hdw, + char *buf,unsigned int maxlen) +{ + unsigned int ccnt,bcnt; + struct pvr2_i2c_client *cp; + ccnt = 0; + mutex_lock(&hdw->i2c_list_lock); do { + list_for_each_entry(cp, &hdw->i2c_clients, list) { + bcnt = pvr2_i2c_client_describe( + cp, + (PVR2_I2C_DETAIL_HANDLER| + PVR2_I2C_DETAIL_CTLMASK), + buf,maxlen); + ccnt += bcnt; buf += bcnt; maxlen -= bcnt; + bcnt = scnprintf(buf,maxlen,"\n"); + ccnt += bcnt; buf += bcnt; maxlen -= bcnt; + } + } while (0); mutex_unlock(&hdw->i2c_list_lock); + return ccnt; +} + static int pvr2_i2c_attach_inform(struct i2c_client *client) { + struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data); + struct pvr2_i2c_client *cp; + int fl = !(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL); + cp = kzalloc(sizeof(*cp),GFP_KERNEL); + trace_i2c("i2c_attach [client=%s @ 0x%x ctxt=%p]", + client->name, + client->addr,cp); + if (!cp) return -ENOMEM; + cp->hdw = hdw; + INIT_LIST_HEAD(&cp->list); + cp->client = client; + mutex_lock(&hdw->i2c_list_lock); do { + hdw->cropcap_stale = !0; + list_add_tail(&cp->list,&hdw->i2c_clients); + hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT; + } while (0); mutex_unlock(&hdw->i2c_list_lock); + if (fl) queue_work(hdw->workqueue,&hdw->worki2csync); return 0; } static int pvr2_i2c_detach_inform(struct i2c_client *client) { + struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data); + struct pvr2_i2c_client *cp, *ncp; + unsigned long amask = 0; + int foundfl = 0; + mutex_lock(&hdw->i2c_list_lock); do { + hdw->cropcap_stale = !0; + list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) { + if (cp->client == client) { + trace_i2c("pvr2_i2c_detach" + " [client=%s @ 0x%x ctxt=%p]", + client->name, + client->addr,cp); + if (cp->handler && + cp->handler->func_table->detach) { + cp->handler->func_table->detach( + cp->handler->func_data); + } + list_del(&cp->list); + kfree(cp); + foundfl = !0; + continue; + } + amask |= cp->ctl_mask; + } + hdw->i2c_active_mask = amask; + } while (0); mutex_unlock(&hdw->i2c_list_lock); + if (!foundfl) { + trace_i2c("pvr2_i2c_detach [client=%s @ 0x%x ctxt=]", + client->name, + client->addr); + } return 0; } @@ -537,7 +942,7 @@ static struct i2c_algorithm pvr2_i2c_algo_template = { static struct i2c_adapter pvr2_i2c_adap_template = { .owner = THIS_MODULE, - .class = 0, + .class = I2C_CLASS_TV_ANALOG, .id = I2C_HW_B_BT848, .client_register = pvr2_i2c_attach_inform, .client_unregister = pvr2_i2c_detach_inform, @@ -604,8 +1009,12 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev; hdw->i2c_adap.algo = &hdw->i2c_algo; hdw->i2c_adap.algo_data = hdw; + hdw->i2c_pend_mask = 0; + hdw->i2c_stale_mask = 0; + hdw->i2c_active_mask = 0; + INIT_LIST_HEAD(&hdw->i2c_clients); + mutex_init(&hdw->i2c_list_lock); hdw->i2c_linked = !0; - i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev); i2c_add_adapter(&hdw->i2c_adap); if (hdw->i2c_func[0x18] == i2c_24xxx_ir) { /* Probe for a different type of IR receiver on this diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h index 6a75769200bd..6ef7a1c0e935 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h @@ -20,13 +20,68 @@ #ifndef __PVRUSB2_I2C_CORE_H #define __PVRUSB2_I2C_CORE_H +#include +#include + struct pvr2_hdw; +struct pvr2_i2c_client; +struct pvr2_i2c_handler; +struct pvr2_i2c_handler_functions; +struct pvr2_i2c_op; +struct pvr2_i2c_op_functions; + +struct pvr2_i2c_client { + struct i2c_client *client; + struct pvr2_i2c_handler *handler; + struct list_head list; + struct pvr2_hdw *hdw; + int detected_flag; + int recv_enable; + unsigned long pend_mask; + unsigned long ctl_mask; + void (*status_poll)(struct pvr2_i2c_client *); +}; + +struct pvr2_i2c_handler { + void *func_data; + const struct pvr2_i2c_handler_functions *func_table; +}; + +struct pvr2_i2c_handler_functions { + void (*detach)(void *); + int (*check)(void *); + void (*update)(void *); + unsigned int (*describe)(void *,char *,unsigned int); +}; + +struct pvr2_i2c_op { + int (*check)(struct pvr2_hdw *); + void (*update)(struct pvr2_hdw *); + const char *name; +}; void pvr2_i2c_core_init(struct pvr2_hdw *); void pvr2_i2c_core_done(struct pvr2_hdw *); +int pvr2_i2c_client_cmd(struct pvr2_i2c_client *,unsigned int cmd,void *arg); +int pvr2_i2c_core_cmd(struct pvr2_hdw *,unsigned int cmd,void *arg); + +int pvr2_i2c_core_check_stale(struct pvr2_hdw *); +void pvr2_i2c_core_sync(struct pvr2_hdw *); +void pvr2_i2c_core_status_poll(struct pvr2_hdw *); +unsigned int pvr2_i2c_report(struct pvr2_hdw *,char *buf,unsigned int maxlen); +#define PVR2_I2C_DETAIL_DEBUG 0x0001 +#define PVR2_I2C_DETAIL_HANDLER 0x0002 +#define PVR2_I2C_DETAIL_CTLMASK 0x0004 +#define PVR2_I2C_DETAIL_ALL (\ + PVR2_I2C_DETAIL_DEBUG |\ + PVR2_I2C_DETAIL_HANDLER |\ + PVR2_I2C_DETAIL_CTLMASK) + +void pvr2_i2c_probe(struct pvr2_hdw *,struct pvr2_i2c_client *); +const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx); -#endif /* __PVRUSB2_I2C_ADAPTER_H */ +#endif /* __PVRUSB2_I2C_CORE_H */ /* diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c index 8689ddb54420..9b3c874d96d6 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c @@ -137,10 +137,10 @@ static int __init pvr_init(void) ret = usb_register(&pvr_driver); if (ret == 0) - printk(KERN_INFO "pvrusb2: " DRIVER_VERSION ":" + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" DRIVER_DESC "\n"); if (pvrusb2_debug) - printk(KERN_INFO "pvrusb2: Debug mask is %d (0x%x)\n", + printk(KERN_INFO KBUILD_MODNAME ": Debug mask is %d (0x%x)\n", pvrusb2_debug,pvrusb2_debug); pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete"); diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index e20ba1e6e0ea..e641cd971453 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c @@ -627,8 +627,16 @@ static void class_dev_create(struct pvr2_sysfs *sfp, pvr2_sysfs_trace("Creating class_dev id=%p",class_dev); class_dev->class = &class_ptr->class; - dev_set_name(class_dev, "%s", - pvr2_hdw_get_device_identifier(sfp->channel.hdw)); + if (pvr2_hdw_get_sn(sfp->channel.hdw)) { + dev_set_name(class_dev, "sn-%lu", + pvr2_hdw_get_sn(sfp->channel.hdw)); + } else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) { + dev_set_name(class_dev, "unit-%c", + pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a'); + } else { + kfree(class_dev); + return; + } class_dev->parent = &usb_dev->dev; diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.c new file mode 100644 index 000000000000..07775d1aad4e --- /dev/null +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.c @@ -0,0 +1,120 @@ +/* + * + * + * Copyright (C) 2005 Mike Isely + * Copyright (C) 2004 Aurelien Alleaume + * + * 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 + * + * 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 "pvrusb2.h" +#include "pvrusb2-util.h" +#include "pvrusb2-tuner.h" +#include "pvrusb2-hdw-internal.h" +#include "pvrusb2-debug.h" +#include +#include +#include + +struct pvr2_tuner_handler { + struct pvr2_hdw *hdw; + struct pvr2_i2c_client *client; + struct pvr2_i2c_handler i2c_handler; + int type_update_fl; +}; + + +static void set_type(struct pvr2_tuner_handler *ctxt) +{ + struct pvr2_hdw *hdw = ctxt->hdw; + struct tuner_setup setup; + pvr2_trace(PVR2_TRACE_CHIPS,"i2c tuner set_type(%d)",hdw->tuner_type); + if (((int)(hdw->tuner_type)) < 0) return; + + setup.addr = ADDR_UNSET; + setup.type = hdw->tuner_type; + setup.mode_mask = T_RADIO | T_ANALOG_TV; + /* We may really want mode_mask to be T_ANALOG_TV for now */ + pvr2_i2c_client_cmd(ctxt->client,TUNER_SET_TYPE_ADDR,&setup); + ctxt->type_update_fl = 0; +} + + +static int tuner_check(struct pvr2_tuner_handler *ctxt) +{ + struct pvr2_hdw *hdw = ctxt->hdw; + if (hdw->tuner_updated) ctxt->type_update_fl = !0; + return ctxt->type_update_fl != 0; +} + + +static void tuner_update(struct pvr2_tuner_handler *ctxt) +{ + if (ctxt->type_update_fl) set_type(ctxt); +} + + +static void pvr2_tuner_detach(struct pvr2_tuner_handler *ctxt) +{ + ctxt->client->handler = NULL; + kfree(ctxt); +} + + +static unsigned int pvr2_tuner_describe(struct pvr2_tuner_handler *ctxt,char *buf,unsigned int cnt) +{ + return scnprintf(buf,cnt,"handler: pvrusb2-tuner"); +} + + +static const struct pvr2_i2c_handler_functions tuner_funcs = { + .detach = (void (*)(void *))pvr2_tuner_detach, + .check = (int (*)(void *))tuner_check, + .update = (void (*)(void *))tuner_update, + .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_tuner_describe, +}; + + +int pvr2_i2c_tuner_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) +{ + struct pvr2_tuner_handler *ctxt; + if (cp->handler) return 0; + + ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL); + if (!ctxt) return 0; + + ctxt->i2c_handler.func_data = ctxt; + ctxt->i2c_handler.func_table = &tuner_funcs; + ctxt->type_update_fl = !0; + ctxt->client = cp; + ctxt->hdw = hdw; + cp->handler = &ctxt->i2c_handler; + pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tuner handler set up", + cp->client->addr); + return !0; +} + + + + +/* + Stuff for Emacs to see, in order to encourage consistent editing style: + *** Local Variables: *** + *** mode: c *** + *** fill-column: 70 *** + *** tab-width: 8 *** + *** c-basic-offset: 8 *** + *** End: *** + */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.h similarity index 64% rename from trunk/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h rename to trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.h index 53ba548b72a7..ef4afaf37b0a 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.h @@ -2,7 +2,6 @@ * * * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume * * 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 @@ -18,24 +17,14 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ +#ifndef __PVRUSB2_TUNER_H +#define __PVRUSB2_TUNER_H -#ifndef __PVRUSB2_CS53L32A_H -#define __PVRUSB2_CS53L32A_H +#include "pvrusb2-i2c-core.h" -/* - - This module connects the pvrusb2 driver to the I2C chip level - driver which handles device video processing. This interface is - used internally by the driver; higher level code should only - interact through the interface provided by pvrusb2-hdw.h. - -*/ - - -#include "pvrusb2-hdw-internal.h" -void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *); +int pvr2_i2c_tuner_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); -#endif /* __PVRUSB2_AUDIO_CS53L32A_H */ +#endif /* __PVRUSB2_TUNER_H */ /* Stuff for Emacs to see, in order to encourage consistent editing style: diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 9e0f2b07b93b..878fd52a73b3 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -91,7 +91,7 @@ static struct v4l2_capability pvr_capability ={ .card = "Hauppauge WinTV pvr-usb2", .bus_info = "usb", .version = KERNEL_VERSION(0,8,0), - .capabilities = (V4L2_CAP_VIDEO_CAPTURE | + .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | V4L2_CAP_READWRITE), .reserved = {0,0,0,0} @@ -952,6 +952,10 @@ static long pvr2_v4l2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { +/* Temporary hack : use ivtv api until a v4l2 one is available. */ +#define IVTV_IOC_G_CODEC 0xFFEE7703 +#define IVTV_IOC_S_CODEC 0xFFEE7704 + if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0; return video_usercopy(file, cmd, arg, pvr2_v4l2_do_ioctl); } @@ -1264,9 +1268,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, dip->minor_type = pvr2_v4l_type_video; nr_ptr = video_nr; if (!dip->stream) { - pr_err(KBUILD_MODNAME - ": Failed to set up pvrusb2 v4l video dev" - " due to missing stream instance\n"); + err("Failed to set up pvrusb2 v4l video dev" + " due to missing stream instance"); return; } break; @@ -1283,8 +1286,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, break; default: /* Bail out (this should be impossible) */ - pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev" - " due to unrecognized config\n"); + err("Failed to set up pvrusb2 v4l dev" + " due to unrecognized config"); return; } @@ -1300,8 +1303,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, dip->v4l_type, mindevnum) < 0) && (video_register_device(&dip->devbase, dip->v4l_type, -1) < 0)) { - pr_err(KBUILD_MODNAME - ": Failed to register pvrusb2 v4l device\n"); + err("Failed to register pvrusb2 v4l device"); } printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n", diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c index b3862f5554bd..4059648c7056 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c @@ -28,7 +28,7 @@ */ #include "pvrusb2-video-v4l.h" - +#include "pvrusb2-i2c-cmd-v4l2.h" #include "pvrusb2-hdw-internal.h" @@ -39,6 +39,15 @@ #include #include +struct pvr2_v4l_decoder { + struct pvr2_i2c_handler handler; + struct pvr2_decoder_ctrl ctrl; + struct pvr2_i2c_client *client; + struct pvr2_hdw *hdw; + unsigned long stale_mask; +}; + + struct routing_scheme { const int *def; unsigned int cnt; @@ -54,51 +63,190 @@ static const int routing_scheme0[] = { [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2, }; -static const int routing_scheme1[] = { - [PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4, - [PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5, - [PVR2_CVAL_INPUT_COMPOSITE] = SAA7115_COMPOSITE3, - [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2, /* or SVIDEO0, it seems */ -}; - static const struct routing_scheme routing_schemes[] = { [PVR2_ROUTING_SCHEME_HAUPPAUGE] = { .def = routing_scheme0, .cnt = ARRAY_SIZE(routing_scheme0), }, - [PVR2_ROUTING_SCHEME_ONAIR] = { - .def = routing_scheme1, - .cnt = ARRAY_SIZE(routing_scheme1), - }, }; -void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) +static void set_input(struct pvr2_v4l_decoder *ctxt) +{ + struct pvr2_hdw *hdw = ctxt->hdw; + struct v4l2_routing route; + const struct routing_scheme *sp; + unsigned int sid = hdw->hdw_desc->signal_routing_scheme; + + pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_input(%d)",hdw->input_val); + + if ((sid < ARRAY_SIZE(routing_schemes)) && + ((sp = routing_schemes + sid) != NULL) && + (hdw->input_val >= 0) && + (hdw->input_val < sp->cnt)) { + route.input = sp->def[hdw->input_val]; + } else { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "*** WARNING *** i2c v4l2 set_input:" + " Invalid routing scheme (%u) and/or input (%d)", + sid,hdw->input_val); + return; + } + + route.output = 0; + pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route); +} + + +static int check_input(struct pvr2_v4l_decoder *ctxt) +{ + struct pvr2_hdw *hdw = ctxt->hdw; + return hdw->input_dirty != 0; +} + + +static void set_audio(struct pvr2_v4l_decoder *ctxt) +{ + u32 val; + struct pvr2_hdw *hdw = ctxt->hdw; + + pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_audio %d", + hdw->srate_val); + switch (hdw->srate_val) { + default: + case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000: + val = 48000; + break; + case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100: + val = 44100; + break; + case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000: + val = 32000; + break; + } + pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); +} + + +static int check_audio(struct pvr2_v4l_decoder *ctxt) +{ + struct pvr2_hdw *hdw = ctxt->hdw; + return hdw->srate_dirty != 0; +} + + +struct pvr2_v4l_decoder_ops { + void (*update)(struct pvr2_v4l_decoder *); + int (*check)(struct pvr2_v4l_decoder *); +}; + + +static const struct pvr2_v4l_decoder_ops decoder_ops[] = { + { .update = set_input, .check = check_input}, + { .update = set_audio, .check = check_audio}, +}; + + +static void decoder_detach(struct pvr2_v4l_decoder *ctxt) { - if (hdw->input_dirty || hdw->force_dirty) { - struct v4l2_routing route; - const struct routing_scheme *sp; - unsigned int sid = hdw->hdw_desc->signal_routing_scheme; - pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)", - hdw->input_val); - if ((sid < ARRAY_SIZE(routing_schemes)) && - ((sp = routing_schemes + sid) != NULL) && - (hdw->input_val >= 0) && - (hdw->input_val < sp->cnt)) { - route.input = sp->def[hdw->input_val]; - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "*** WARNING *** subdev v4l2 set_input:" - " Invalid routing scheme (%u)" - " and/or input (%d)", - sid, hdw->input_val); - return; + ctxt->client->handler = NULL; + pvr2_hdw_set_decoder(ctxt->hdw,NULL); + kfree(ctxt); +} + + +static int decoder_check(struct pvr2_v4l_decoder *ctxt) +{ + unsigned long msk; + unsigned int idx; + + for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) { + msk = 1 << idx; + if (ctxt->stale_mask & msk) continue; + if (decoder_ops[idx].check(ctxt)) { + ctxt->stale_mask |= msk; } - route.output = 0; - sd->ops->video->s_routing(sd, &route); } + return ctxt->stale_mask != 0; +} + + +static void decoder_update(struct pvr2_v4l_decoder *ctxt) +{ + unsigned long msk; + unsigned int idx; + + for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) { + msk = 1 << idx; + if (!(ctxt->stale_mask & msk)) continue; + ctxt->stale_mask &= ~msk; + decoder_ops[idx].update(ctxt); + } +} + + +static int decoder_detect(struct pvr2_i2c_client *cp) +{ + /* Attempt to query the decoder - let's see if it will answer */ + struct v4l2_tuner vt; + int ret; + + memset(&vt,0,sizeof(vt)); + ret = pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&vt); + return ret == 0; /* Return true if it answered */ +} + + +static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl) +{ + pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 decoder_enable(%d)",fl); + pvr2_v4l2_cmd_stream(ctxt->client,fl); +} + + +static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt) +{ + return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l"); +} + + +static const struct pvr2_i2c_handler_functions hfuncs = { + .detach = (void (*)(void *))decoder_detach, + .check = (int (*)(void *))decoder_check, + .update = (void (*)(void *))decoder_update, + .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe, +}; + + +int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw, + struct pvr2_i2c_client *cp) +{ + struct pvr2_v4l_decoder *ctxt; + + if (hdw->decoder_ctrl) return 0; + if (cp->handler) return 0; + if (!decoder_detect(cp)) return 0; + + ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL); + if (!ctxt) return 0; + + ctxt->handler.func_data = ctxt; + ctxt->handler.func_table = &hfuncs; + ctxt->ctrl.ctxt = ctxt; + ctxt->ctrl.detach = (void (*)(void *))decoder_detach; + ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable; + ctxt->client = cp; + ctxt->hdw = hdw; + ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1; + pvr2_hdw_set_decoder(hdw,&ctxt->ctrl); + cp->handler = &ctxt->handler; + pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up", + cp->client->addr); + return !0; } + + /* Stuff for Emacs to see, in order to encourage consistent editing style: *** Local Variables: *** diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h index 3b0bd5db602b..4ff5b892b303 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h @@ -32,8 +32,11 @@ */ -#include "pvrusb2-hdw-internal.h" -void pvr2_saa7115_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *); + +#include "pvrusb2-i2c-core.h" + +int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); + #endif /* __PVRUSB2_VIDEO_V4L_H */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.c index 1670aa4051ce..f6fcf0ac6118 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.c @@ -27,6 +27,7 @@ */ #include "pvrusb2-wm8775.h" +#include "pvrusb2-i2c-cmd-v4l2.h" #include "pvrusb2-hdw-internal.h" @@ -36,31 +37,128 @@ #include #include -void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) +struct pvr2_v4l_wm8775 { + struct pvr2_i2c_handler handler; + struct pvr2_i2c_client *client; + struct pvr2_hdw *hdw; + unsigned long stale_mask; +}; + + +static void set_input(struct pvr2_v4l_wm8775 *ctxt) +{ + struct v4l2_routing route; + struct pvr2_hdw *hdw = ctxt->hdw; + + memset(&route,0,sizeof(route)); + + switch(hdw->input_val) { + case PVR2_CVAL_INPUT_RADIO: + route.input = 1; + break; + default: + /* All other cases just use the second input */ + route.input = 2; + break; + } + pvr2_trace(PVR2_TRACE_CHIPS,"i2c wm8775 set_input(val=%d route=0x%x)", + hdw->input_val,route.input); + + pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); +} + +static int check_input(struct pvr2_v4l_wm8775 *ctxt) +{ + struct pvr2_hdw *hdw = ctxt->hdw; + return hdw->input_dirty != 0; +} + + +struct pvr2_v4l_wm8775_ops { + void (*update)(struct pvr2_v4l_wm8775 *); + int (*check)(struct pvr2_v4l_wm8775 *); +}; + + +static const struct pvr2_v4l_wm8775_ops wm8775_ops[] = { + { .update = set_input, .check = check_input}, +}; + + +static unsigned int wm8775_describe(struct pvr2_v4l_wm8775 *ctxt, + char *buf,unsigned int cnt) +{ + return scnprintf(buf,cnt,"handler: pvrusb2-wm8775"); +} + + +static void wm8775_detach(struct pvr2_v4l_wm8775 *ctxt) { - if (hdw->input_dirty || hdw->force_dirty) { - struct v4l2_routing route; - - memset(&route, 0, sizeof(route)); - - switch (hdw->input_val) { - case PVR2_CVAL_INPUT_RADIO: - route.input = 1; - break; - default: - /* All other cases just use the second input */ - route.input = 2; - break; + ctxt->client->handler = NULL; + kfree(ctxt); +} + + +static int wm8775_check(struct pvr2_v4l_wm8775 *ctxt) +{ + unsigned long msk; + unsigned int idx; + + for (idx = 0; idx < ARRAY_SIZE(wm8775_ops); idx++) { + msk = 1 << idx; + if (ctxt->stale_mask & msk) continue; + if (wm8775_ops[idx].check(ctxt)) { + ctxt->stale_mask |= msk; } - pvr2_trace(PVR2_TRACE_CHIPS, "subdev wm8775" - " set_input(val=%d route=0x%x)", - hdw->input_val, route.input); + } + return ctxt->stale_mask != 0; +} + + +static void wm8775_update(struct pvr2_v4l_wm8775 *ctxt) +{ + unsigned long msk; + unsigned int idx; - sd->ops->audio->s_routing(sd, &route); + for (idx = 0; idx < ARRAY_SIZE(wm8775_ops); idx++) { + msk = 1 << idx; + if (!(ctxt->stale_mask & msk)) continue; + ctxt->stale_mask &= ~msk; + wm8775_ops[idx].update(ctxt); } } +static const struct pvr2_i2c_handler_functions hfuncs = { + .detach = (void (*)(void *))wm8775_detach, + .check = (int (*)(void *))wm8775_check, + .update = (void (*)(void *))wm8775_update, + .describe = (unsigned int (*)(void *,char *,unsigned int))wm8775_describe, +}; + + +int pvr2_i2c_wm8775_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) +{ + struct pvr2_v4l_wm8775 *ctxt; + + if (cp->handler) return 0; + + ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL); + if (!ctxt) return 0; + + ctxt->handler.func_data = ctxt; + ctxt->handler.func_table = &hfuncs; + ctxt->client = cp; + ctxt->hdw = hdw; + ctxt->stale_mask = (1 << ARRAY_SIZE(wm8775_ops)) - 1; + cp->handler = &ctxt->handler; + pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x wm8775 V4L2 handler set up", + cp->client->addr); + return !0; +} + + + /* Stuff for Emacs to see, in order to encourage consistent editing style: diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.h index 0577bc7246fb..807090961255 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.h +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.h @@ -34,9 +34,9 @@ -#include "pvrusb2-hdw-internal.h" +#include "pvrusb2-i2c-core.h" -void pvr2_wm8775_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd); +int pvr2_i2c_wm8775_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); #endif /* __PVRUSB2_WM8775_H */ diff --git a/trunk/drivers/media/video/pwc/Kconfig b/trunk/drivers/media/video/pwc/Kconfig index 8b9f0aa844a1..7298cf2e1650 100644 --- a/trunk/drivers/media/video/pwc/Kconfig +++ b/trunk/drivers/media/video/pwc/Kconfig @@ -35,13 +35,3 @@ config USB_PWC_DEBUG Say Y here in order to have the pwc driver generate verbose debugging messages. A special module options 'trace' is used to control the verbosity. - -config USB_PWC_INPUT_EVDEV - bool "USB Philips Cameras input events device support" - default y - depends on USB_PWC && INPUT - ---help--- - This option makes USB Philips cameras register the snapshot button as - an input device to report button events. - - If you are in doubt, say Y. diff --git a/trunk/drivers/media/video/pwc/pwc-if.c b/trunk/drivers/media/video/pwc/pwc-if.c index 7c542caf248e..0d810189dd87 100644 --- a/trunk/drivers/media/video/pwc/pwc-if.c +++ b/trunk/drivers/media/video/pwc/pwc-if.c @@ -53,7 +53,6 @@ - Xavier Roche: QuickCam Pro 4000 ID - Jens Knudsen: QuickCam Zoom ID - J. Debert: QuickCam for Notebooks ID - - Pham Thanh Nam: webcam snapshot button as an event input device */ #include @@ -62,9 +61,6 @@ #include #include #include -#ifdef CONFIG_USB_PWC_INPUT_EVDEV -#include -#endif #include #include @@ -590,23 +586,6 @@ static void pwc_frame_dumped(struct pwc_device *pdev) pdev->vframe_count); } -static void pwc_snapshot_button(struct pwc_device *pdev, int down) -{ - if (down) { - PWC_TRACE("Snapshot button pressed.\n"); - pdev->snapshot_button_status = 1; - } else { - PWC_TRACE("Snapshot button released.\n"); - } - -#ifdef CONFIG_USB_PWC_INPUT_EVDEV - if (pdev->button_dev) { - input_report_key(pdev->button_dev, BTN_0, down); - input_sync(pdev->button_dev); - } -#endif -} - static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_buf *fbuf) { int awake = 0; @@ -624,7 +603,13 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_ pdev->vframes_error++; } if ((ptr[0] ^ pdev->vmirror) & 0x01) { - pwc_snapshot_button(pdev, ptr[0] & 0x01); + if (ptr[0] & 0x01) { + pdev->snapshot_button_status = 1; + PWC_TRACE("Snapshot button pressed.\n"); + } + else { + PWC_TRACE("Snapshot button released.\n"); + } } if ((ptr[0] ^ pdev->vmirror) & 0x02) { if (ptr[0] & 0x02) @@ -648,7 +633,12 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_ else if (pdev->type == 740 || pdev->type == 720) { unsigned char *ptr = (unsigned char *)fbuf->data; if ((ptr[0] ^ pdev->vmirror) & 0x01) { - pwc_snapshot_button(pdev, ptr[0] & 0x01); + if (ptr[0] & 0x01) { + pdev->snapshot_button_status = 1; + PWC_TRACE("Snapshot button pressed.\n"); + } + else + PWC_TRACE("Snapshot button released.\n"); } pdev->vmirror = ptr[0] & 0x03; } @@ -1125,7 +1115,6 @@ static int pwc_video_open(struct file *file) } mutex_lock(&pdev->modlock); - pwc_construct(pdev); /* set min/max sizes correct */ if (!pdev->usb_init) { PWC_DEBUG_OPEN("Doing first time initialization.\n"); pdev->usb_init = 1; @@ -1150,6 +1139,7 @@ static int pwc_video_open(struct file *file) if (pwc_set_leds(pdev, led_on, led_off) < 0) PWC_DEBUG_OPEN("Failed to set LED on/off time.\n"); + pwc_construct(pdev); /* set min/max sizes correct */ /* So far, so good. Allocate memory. */ i = pwc_allocate_buffers(pdev); @@ -1226,15 +1216,6 @@ static void pwc_cleanup(struct pwc_device *pdev) { pwc_remove_sysfs_files(pdev->vdev); video_unregister_device(pdev->vdev); - -#ifdef CONFIG_USB_PWC_INPUT_EVDEV - if (pdev->button_dev) { - input_unregister_device(pdev->button_dev); - input_free_device(pdev->button_dev); - kfree(pdev->button_dev->phys); - pdev->button_dev = NULL; - } -#endif } /* Note that all cleanup is done in the reverse order as in _open */ @@ -1502,9 +1483,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id int features = 0; int video_nr = -1; /* default: use next available device */ char serial_number[30], *name; -#ifdef CONFIG_USB_PWC_INPUT_EVDEV - char *phys = NULL; -#endif vendor_id = le16_to_cpu(udev->descriptor.idVendor); product_id = le16_to_cpu(udev->descriptor.idProduct); @@ -1829,35 +1807,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id pwc_set_leds(pdev, 0, 0); pwc_camera_power(pdev, 0); -#ifdef CONFIG_USB_PWC_INPUT_EVDEV - /* register webcam snapshot button input device */ - pdev->button_dev = input_allocate_device(); - if (!pdev->button_dev) { - PWC_ERROR("Err, insufficient memory for webcam snapshot button device."); - return -ENOMEM; - } - - pdev->button_dev->name = "PWC snapshot button"; - phys = kasprintf(GFP_KERNEL,"usb-%s-%s", pdev->udev->bus->bus_name, pdev->udev->devpath); - if (!phys) { - input_free_device(pdev->button_dev); - return -ENOMEM; - } - pdev->button_dev->phys = phys; - usb_to_input_id(pdev->udev, &pdev->button_dev->id); - pdev->button_dev->dev.parent = &pdev->udev->dev; - pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY); - pdev->button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); - - rc = input_register_device(pdev->button_dev); - if (rc) { - input_free_device(pdev->button_dev); - kfree(pdev->button_dev->phys); - pdev->button_dev = NULL; - return rc; - } -#endif - return 0; err_unreg: diff --git a/trunk/drivers/media/video/pwc/pwc.h b/trunk/drivers/media/video/pwc/pwc.h index 0be6f814f539..01411fb2337a 100644 --- a/trunk/drivers/media/video/pwc/pwc.h +++ b/trunk/drivers/media/video/pwc/pwc.h @@ -37,9 +37,6 @@ #include #include #include -#ifdef CONFIG_USB_PWC_INPUT_EVDEV -#include -#endif #include "pwc-uncompress.h" #include @@ -258,9 +255,6 @@ struct pwc_device int pan_angle; /* in degrees * 100 */ int tilt_angle; /* absolute angle; 0,0 is home position */ int snapshot_button_status; /* set to 1 when the user push the button, reset to 0 when this value is read */ -#ifdef CONFIG_USB_PWC_INPUT_EVDEV - struct input_dev *button_dev; /* webcam snapshot button input */ -#endif /*** Misc. data ***/ wait_queue_head_t frameq; /* When waiting for a frame to finish... */ diff --git a/trunk/drivers/media/video/pxa_camera.c b/trunk/drivers/media/video/pxa_camera.c index c522616ef38f..0c4ce58c53d5 100644 --- a/trunk/drivers/media/video/pxa_camera.c +++ b/trunk/drivers/media/video/pxa_camera.c @@ -878,7 +878,6 @@ static int test_platform_param(struct pxa_camera_dev *pcdev, SOCAM_HSYNC_ACTIVE_LOW | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW | - SOCAM_DATA_ACTIVE_HIGH | SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING; @@ -1150,43 +1149,8 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, return formats; } -static int pxa_camera_set_crop(struct soc_camera_device *icd, - struct v4l2_rect *rect) -{ - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct pxa_camera_dev *pcdev = ici->priv; - struct soc_camera_sense sense = { - .master_clock = pcdev->mclk, - .pixel_clock_max = pcdev->ciclk / 4, - }; - int ret; - - /* If PCLK is used to latch data from the sensor, check sense */ - if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) - icd->sense = &sense; - - ret = icd->ops->set_crop(icd, rect); - - icd->sense = NULL; - - if (ret < 0) { - dev_warn(&ici->dev, "Failed to crop to %ux%u@%u:%u\n", - rect->width, rect->height, rect->left, rect->top); - } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { - if (sense.pixel_clock > sense.pixel_clock_max) { - dev_err(&ici->dev, - "pixel clock %lu set by the camera too high!", - sense.pixel_clock); - return -EIO; - } - recalculate_fifo_timeout(pcdev, sense.pixel_clock); - } - - return ret; -} - static int pxa_camera_set_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) + __u32 pixfmt, struct v4l2_rect *rect) { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct pxa_camera_dev *pcdev = ici->priv; @@ -1196,30 +1160,35 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, .master_clock = pcdev->mclk, .pixel_clock_max = pcdev->ciclk / 4, }; - struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_format cam_f = *f; int ret; - xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); - if (!xlate) { - dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat); - return -EINVAL; - } + if (pixfmt) { + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); + if (!xlate) { + dev_warn(&ici->dev, "Format %x not found\n", pixfmt); + return -EINVAL; + } - cam_fmt = xlate->cam_fmt; + cam_fmt = xlate->cam_fmt; + } /* If PCLK is used to latch data from the sensor, check sense */ if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) icd->sense = &sense; - cam_f.fmt.pix.pixelformat = cam_fmt->fourcc; - ret = icd->ops->set_fmt(icd, &cam_f); + switch (pixfmt) { + case 0: /* Only geometry change */ + ret = icd->ops->set_fmt(icd, pixfmt, rect); + break; + default: + ret = icd->ops->set_fmt(icd, cam_fmt->fourcc, rect); + } icd->sense = NULL; if (ret < 0) { dev_warn(&ici->dev, "Failed to configure for format %x\n", - pix->pixelformat); + pixfmt); } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { if (sense.pixel_clock > sense.pixel_clock_max) { dev_err(&ici->dev, @@ -1230,7 +1199,7 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, recalculate_fifo_timeout(pcdev, sense.pixel_clock); } - if (!ret) { + if (pixfmt && !ret) { icd->buswidth = xlate->buswidth; icd->current_fmt = xlate->host_fmt; } @@ -1394,7 +1363,6 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = { .remove = pxa_camera_remove_device, .suspend = pxa_camera_suspend, .resume = pxa_camera_resume, - .set_crop = pxa_camera_set_crop, .get_formats = pxa_camera_get_formats, .set_fmt = pxa_camera_set_fmt, .try_fmt = pxa_camera_try_fmt, diff --git a/trunk/drivers/media/video/s2255drv.c b/trunk/drivers/media/video/s2255drv.c index b5be633e3bb0..13f85ad363cd 100644 --- a/trunk/drivers/media/video/s2255drv.c +++ b/trunk/drivers/media/video/s2255drv.c @@ -336,19 +336,14 @@ static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req, u16 index, u16 value, void *buf, s32 buf_len, int bOut); -/* dev_err macro with driver name */ -#define S2255_DRIVER_NAME "s2255" -#define s2255_dev_err(dev, fmt, arg...) \ - dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg) - #define dprintk(level, fmt, arg...) \ do { \ if (*s2255_debug >= (level)) { \ - printk(KERN_DEBUG S2255_DRIVER_NAME \ - ": " fmt, ##arg); \ + printk(KERN_DEBUG "s2255: " fmt, ##arg); \ } \ } while (0) + static struct usb_driver s2255_driver; @@ -533,14 +528,14 @@ static void s2255_fwchunk_complete(struct urb *urb) int len; dprintk(100, "udev %p urb %p", udev, urb); if (urb->status) { - dev_err(&udev->dev, "URB failed with status %d\n", urb->status); + dev_err(&udev->dev, "URB failed with status %d", urb->status); atomic_set(&data->fw_state, S2255_FW_FAILED); /* wake up anything waiting for the firmware */ wake_up(&data->wait_fw); return; } if (data->fw_urb == NULL) { - s2255_dev_err(&udev->dev, "disconnected\n"); + dev_err(&udev->dev, "s2255 disconnected\n"); atomic_set(&data->fw_state, S2255_FW_FAILED); /* wake up anything waiting for the firmware */ wake_up(&data->wait_fw); @@ -846,7 +841,8 @@ static int vidioc_querycap(struct file *file, void *priv, struct s2255_dev *dev = fh->dev; strlcpy(cap->driver, "s2255", sizeof(cap->driver)); strlcpy(cap->card, "s2255", sizeof(cap->card)); - usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); + strlcpy(cap->bus_info, dev_name(&dev->udev->dev), + sizeof(cap->bus_info)); cap->version = S2255_VERSION; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; return 0; @@ -1282,7 +1278,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) } if (!res_get(dev, fh)) { - s2255_dev_err(&dev->udev->dev, "stream busy\n"); + dev_err(&dev->udev->dev, "s2255: stream busy\n"); return -EBUSY; } @@ -1549,8 +1545,7 @@ static int s2255_open(struct file *file) switch (atomic_read(&dev->fw_data->fw_state)) { case S2255_FW_FAILED: - s2255_dev_err(&dev->udev->dev, - "firmware load failed. retrying.\n"); + err("2255 firmware load failed. retrying.\n"); s2255_fwload_start(dev, 1); wait_event_timeout(dev->fw_data->wait_fw, ((atomic_read(&dev->fw_data->fw_state) @@ -2178,8 +2173,7 @@ static int s2255_board_init(struct s2255_dev *dev) printk(KERN_INFO "2255 usb firmware version %d \n", fw_ver); if (fw_ver < CUR_USB_FWVER) - dev_err(&dev->udev->dev, - "usb firmware not up to date %d\n", fw_ver); + err("usb firmware not up to date %d\n", fw_ver); for (j = 0; j < MAX_CHANNELS; j++) { dev->b_acquire[j] = 0; @@ -2234,13 +2228,13 @@ static void read_pipe_completion(struct urb *purb) dprintk(100, "read pipe completion %p, status %d\n", purb, purb->status); if (pipe_info == NULL) { - dev_err(&purb->dev->dev, "no context!\n"); + err("no context !"); return; } dev = pipe_info->dev; if (dev == NULL) { - dev_err(&purb->dev->dev, "no context!\n"); + err("no context !"); return; } status = purb->status; @@ -2292,7 +2286,7 @@ static int s2255_start_readpipe(struct s2255_dev *dev) pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); if (!pipe_info->stream_urb) { dev_err(&dev->udev->dev, - "ReadStream: Unable to alloc URB\n"); + "ReadStream: Unable to alloc URB"); return -ENOMEM; } /* transfer buffer allocated in board_init */ @@ -2397,7 +2391,7 @@ static void s2255_stop_readpipe(struct s2255_dev *dev) int j; if (dev == NULL) { - s2255_dev_err(&dev->udev->dev, "invalid device\n"); + err("s2255: invalid device"); return; } dprintk(4, "stop read pipe\n"); @@ -2459,7 +2453,7 @@ static int s2255_probe(struct usb_interface *interface, /* allocate memory for our device state and initialize it to zero */ dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL); if (dev == NULL) { - s2255_dev_err(&interface->dev, "out of memory\n"); + err("s2255: out of memory"); goto error; } @@ -2493,7 +2487,7 @@ static int s2255_probe(struct usb_interface *interface, } if (!dev->read_endpoint) { - dev_err(&interface->dev, "Could not find bulk-in endpoint\n"); + dev_err(&interface->dev, "Could not find bulk-in endpoint"); goto error; } @@ -2589,7 +2583,7 @@ static void s2255_disconnect(struct usb_interface *interface) } static struct usb_driver s2255_driver = { - .name = S2255_DRIVER_NAME, + .name = "s2255", .probe = s2255_probe, .disconnect = s2255_disconnect, .id_table = s2255_table, @@ -2603,8 +2597,7 @@ static int __init usb_s2255_init(void) result = usb_register(&s2255_driver); if (result) - pr_err(KBUILD_MODNAME - ": usb_register failed. Error number %d\n", result); + err("usb_register failed. Error number %d", result); dprintk(2, "s2255_init: done\n"); return result; diff --git a/trunk/drivers/media/video/saa5246a.c b/trunk/drivers/media/video/saa5246a.c index da47b2f05288..e637e440b6d5 100644 --- a/trunk/drivers/media/video/saa5246a.c +++ b/trunk/drivers/media/video/saa5246a.c @@ -46,11 +46,10 @@ #include #include #include -#include -#include -#include +#include +#include #include -#include +#include MODULE_AUTHOR("Michael Geng "); MODULE_DESCRIPTION("Philips SAA5246A, SAA5281 Teletext decoder driver"); @@ -389,19 +388,13 @@ MODULE_LICENSE("GPL"); struct saa5246a_device { - struct v4l2_subdev sd; - struct video_device *vdev; u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE]; int is_searching[NUM_DAUS]; + struct i2c_client *client; unsigned long in_use; struct mutex lock; }; -static inline struct saa5246a_device *to_dev(struct v4l2_subdev *sd) -{ - return container_of(sd, struct saa5246a_device, sd); -} - static struct video_device saa_template; /* Declared near bottom */ /* @@ -410,13 +403,12 @@ static struct video_device saa_template; /* Declared near bottom */ static int i2c_sendbuf(struct saa5246a_device *t, int reg, int count, u8 *data) { - struct i2c_client *client = v4l2_get_subdevdata(&t->sd); char buf[64]; buf[0] = reg; memcpy(buf+1, data, count); - if (i2c_master_send(client, buf, count + 1) == count + 1) + if(i2c_master_send(t->client, buf, count+1)==count+1) return 0; return -1; } @@ -444,9 +436,7 @@ static int i2c_senddata(struct saa5246a_device *t, ...) */ static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf) { - struct i2c_client *client = v4l2_get_subdevdata(&t->sd); - - if (i2c_master_recv(client, buf, count) != count) + if(i2c_master_recv(t->client, buf, count)!=count) return -1; return 0; } @@ -971,6 +961,9 @@ static int saa5246a_open(struct file *file) { struct saa5246a_device *t = video_drvdata(file); + if (t->client == NULL) + return -ENODEV; + if (test_and_set_bit(0, &t->in_use)) return -EBUSY; @@ -1040,29 +1033,18 @@ static struct video_device saa_template = .minor = -1, }; -static int saa5246a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA5246A, 0); -} - -static const struct v4l2_subdev_core_ops saa5246a_core_ops = { - .g_chip_ident = saa5246a_g_chip_ident, -}; - -static const struct v4l2_subdev_ops saa5246a_ops = { - .core = &saa5246a_core_ops, -}; +/* Addresses to scan */ +static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; +I2C_CLIENT_INSMOD; static int saa5246a_probe(struct i2c_client *client, const struct i2c_device_id *id) { int pgbuf; int err; + struct video_device *vd; struct saa5246a_device *t; - struct v4l2_subdev *sd; v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); @@ -1071,43 +1053,40 @@ static int saa5246a_probe(struct i2c_client *client, t = kzalloc(sizeof(*t), GFP_KERNEL); if (t == NULL) return -ENOMEM; - sd = &t->sd; - v4l2_i2c_subdev_init(sd, client, &saa5246a_ops); mutex_init(&t->lock); /* Now create a video4linux device */ - t->vdev = video_device_alloc(); - if (t->vdev == NULL) { + vd = video_device_alloc(); + if (vd == NULL) { kfree(t); return -ENOMEM; } - memcpy(t->vdev, &saa_template, sizeof(*t->vdev)); + i2c_set_clientdata(client, vd); + memcpy(vd, &saa_template, sizeof(*vd)); for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0])); t->is_searching[pgbuf] = false; } - video_set_drvdata(t->vdev, t); + video_set_drvdata(vd, t); /* Register it */ - err = video_register_device(t->vdev, VFL_TYPE_VTX, -1); + err = video_register_device(vd, VFL_TYPE_VTX, -1); if (err < 0) { kfree(t); - video_device_release(t->vdev); - t->vdev = NULL; + video_device_release(vd); return err; } + t->client = client; return 0; } static int saa5246a_remove(struct i2c_client *client) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct saa5246a_device *t = to_dev(sd); + struct video_device *vd = i2c_get_clientdata(client); - video_unregister_device(t->vdev); - v4l2_device_unregister_subdev(sd); - kfree(t); + video_unregister_device(vd); + kfree(video_get_drvdata(vd)); return 0; } @@ -1119,6 +1098,7 @@ MODULE_DEVICE_TABLE(i2c, saa5246a_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa5246a", + .driverid = I2C_DRIVERID_SAA5249, .probe = saa5246a_probe, .remove = saa5246a_remove, .id_table = saa5246a_id, diff --git a/trunk/drivers/media/video/saa5249.c b/trunk/drivers/media/video/saa5249.c index 48b27fe48087..e29765192469 100644 --- a/trunk/drivers/media/video/saa5249.c +++ b/trunk/drivers/media/video/saa5249.c @@ -50,17 +50,15 @@ #include #include #include -#include -#include -#include +#include +#include #include -#include +#include MODULE_AUTHOR("Michael Geng "); MODULE_DESCRIPTION("Philips SAA5249 Teletext decoder driver"); MODULE_LICENSE("GPL"); - #define VTX_VER_MAJ 1 #define VTX_VER_MIN 8 @@ -97,23 +95,17 @@ typedef struct { struct saa5249_device { - struct v4l2_subdev sd; - struct video_device *vdev; vdau_t vdau[NUM_DAUS]; /* Data for virtual DAUs (the 5249 only has one */ /* real DAU, so we have to simulate some more) */ int vtx_use_count; int is_searching[NUM_DAUS]; int disp_mode; int virtual_mode; + struct i2c_client *client; unsigned long in_use; struct mutex lock; }; -static inline struct saa5249_device *to_dev(struct v4l2_subdev *sd) -{ - return container_of(sd, struct saa5249_device, sd); -} - #define CCTWR 34 /* I²C write/read-address of vtx-chip */ #define CCTRD 35 @@ -155,13 +147,12 @@ static void jdelay(unsigned long delay) static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data) { - struct i2c_client *client = v4l2_get_subdevdata(&t->sd); char buf[64]; buf[0] = reg; memcpy(buf+1, data, count); - if (i2c_master_send(client, buf, count + 1) == count + 1) + if (i2c_master_send(t->client, buf, count + 1) == count + 1) return 0; return -1; } @@ -189,9 +180,7 @@ static int i2c_senddata(struct saa5249_device *t, ...) static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf) { - struct i2c_client *client = v4l2_get_subdevdata(&t->sd); - - if (i2c_master_recv(client, buf, count) != count) + if(i2c_master_recv(t->client, buf, count)!=count) return -1; return 0; } @@ -508,6 +497,9 @@ static int saa5249_open(struct file *file) struct saa5249_device *t = video_drvdata(file); int pgbuf; + if (t->client == NULL) + return -ENODEV; + if (test_and_set_bit(0, &t->in_use)) return -EBUSY; @@ -561,28 +553,18 @@ static struct video_device saa_template = .release = video_device_release, }; -static int saa5249_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA5249, 0); -} +/* Addresses to scan */ +static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; -static const struct v4l2_subdev_core_ops saa5249_core_ops = { - .g_chip_ident = saa5249_g_chip_ident, -}; - -static const struct v4l2_subdev_ops saa5249_ops = { - .core = &saa5249_core_ops, -}; +I2C_CLIENT_INSMOD; static int saa5249_probe(struct i2c_client *client, const struct i2c_device_id *id) { int pgbuf; int err; + struct video_device *vd; struct saa5249_device *t; - struct v4l2_subdev *sd; v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); @@ -591,17 +573,16 @@ static int saa5249_probe(struct i2c_client *client, t = kzalloc(sizeof(*t), GFP_KERNEL); if (t == NULL) return -ENOMEM; - sd = &t->sd; - v4l2_i2c_subdev_init(sd, client, &saa5249_ops); mutex_init(&t->lock); /* Now create a video4linux device */ - t->vdev = video_device_alloc(); - if (t->vdev == NULL) { + vd = kmalloc(sizeof(struct video_device), GFP_KERNEL); + if (vd == NULL) { kfree(client); return -ENOMEM; } - memcpy(t->vdev, &saa_template, sizeof(*t->vdev)); + i2c_set_clientdata(client, vd); + memcpy(vd, &saa_template, sizeof(*vd)); for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); @@ -612,27 +593,26 @@ static int saa5249_probe(struct i2c_client *client, t->vdau[pgbuf].stopped = true; t->is_searching[pgbuf] = false; } - video_set_drvdata(t->vdev, t); + video_set_drvdata(vd, t); /* Register it */ - err = video_register_device(t->vdev, VFL_TYPE_VTX, -1); + err = video_register_device(vd, VFL_TYPE_VTX, -1); if (err < 0) { kfree(t); - video_device_release(t->vdev); - t->vdev = NULL; + kfree(vd); return err; } + t->client = client; return 0; } static int saa5249_remove(struct i2c_client *client) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct saa5249_device *t = to_dev(sd); + struct video_device *vd = i2c_get_clientdata(client); - video_unregister_device(t->vdev); - v4l2_device_unregister_subdev(sd); - kfree(t); + video_unregister_device(vd); + kfree(video_get_drvdata(vd)); + kfree(vd); return 0; } @@ -644,6 +624,7 @@ MODULE_DEVICE_TABLE(i2c, saa5249_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa5249", + .driverid = I2C_DRIVERID_SAA5249, .probe = saa5249_probe, .remove = saa5249_remove, .id_table = saa5249_id, diff --git a/trunk/drivers/media/video/saa6588.c b/trunk/drivers/media/video/saa6588.c index c25e81af5ce0..f05024259f01 100644 --- a/trunk/drivers/media/video/saa6588.c +++ b/trunk/drivers/media/video/saa6588.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -32,10 +32,15 @@ #include #include -#include -#include -#include +/* Addresses to scan */ +static unsigned short normal_i2c[] = { + 0x20 >> 1, + 0x22 >> 1, + I2C_CLIENT_END, +}; + +I2C_CLIENT_INSMOD; /* insmod options */ static unsigned int debug; @@ -67,8 +72,9 @@ MODULE_LICENSE("GPL"); #define dprintk if (debug) printk struct saa6588 { - struct v4l2_subdev sd; - struct delayed_work work; + struct i2c_client client; + struct work_struct work; + struct timer_list timer; spinlock_t lock; unsigned char *buffer; unsigned int buf_size; @@ -80,10 +86,8 @@ struct saa6588 { int data_available_for_read; }; -static inline struct saa6588 *to_saa6588(struct v4l2_subdev *sd) -{ - return container_of(sd, struct saa6588, sd); -} +static struct i2c_driver driver; +static struct i2c_client client_template; /* ---------------------------------------------------------------------- */ @@ -254,7 +258,6 @@ static void block_to_buf(struct saa6588 *s, unsigned char *blockbuf) static void saa6588_i2c_poll(struct saa6588 *s) { - struct i2c_client *client = v4l2_get_subdevdata(&s->sd); unsigned long flags; unsigned char tmpbuf[6]; unsigned char blocknum; @@ -262,7 +265,7 @@ static void saa6588_i2c_poll(struct saa6588 *s) /* Although we only need 3 bytes, we have to read at least 6. SAA6588 returns garbage otherwise */ - if (6 != i2c_master_recv(client, &tmpbuf[0], 6)) { + if (6 != i2c_master_recv(&s->client, &tmpbuf[0], 6)) { if (debug > 1) dprintk(PREFIX "read error!\n"); return; @@ -313,17 +316,23 @@ static void saa6588_i2c_poll(struct saa6588 *s) wake_up_interruptible(&s->read_queue); } +static void saa6588_timer(unsigned long data) +{ + struct saa6588 *s = (struct saa6588 *)data; + + schedule_work(&s->work); +} + static void saa6588_work(struct work_struct *work) { - struct saa6588 *s = container_of(work, struct saa6588, work.work); + struct saa6588 *s = container_of(work, struct saa6588, work); saa6588_i2c_poll(s); - schedule_delayed_work(&s->work, msecs_to_jiffies(20)); + mod_timer(&s->timer, jiffies + msecs_to_jiffies(20)); } static int saa6588_configure(struct saa6588 *s) { - struct i2c_client *client = v4l2_get_subdevdata(&s->sd); unsigned char buf[3]; int rc; @@ -371,8 +380,7 @@ static int saa6588_configure(struct saa6588 *s) dprintk(PREFIX "writing: 0w=0x%02x 1w=0x%02x 2w=0x%02x\n", buf[0], buf[1], buf[2]); - rc = i2c_master_send(client, buf, 3); - if (rc != 3) + if (3 != (rc = i2c_master_send(&s->client, buf, 3))) printk(PREFIX "i2c i/o error: rc == %d (should be 3)\n", rc); return 0; @@ -380,10 +388,70 @@ static int saa6588_configure(struct saa6588 *s) /* ---------------------------------------------------------------------- */ -static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind) +{ + struct saa6588 *s; + client_template.adapter = adap; + client_template.addr = addr; + + printk(PREFIX "chip found @ 0x%x\n", addr << 1); + + if (NULL == (s = kmalloc(sizeof(*s), GFP_KERNEL))) + return -ENOMEM; + + s->buf_size = bufblocks * 3; + + if (NULL == (s->buffer = kmalloc(s->buf_size, GFP_KERNEL))) { + kfree(s); + return -ENOMEM; + } + spin_lock_init(&s->lock); + s->client = client_template; + s->block_count = 0; + s->wr_index = 0; + s->rd_index = 0; + s->last_blocknum = 0xff; + init_waitqueue_head(&s->read_queue); + s->data_available_for_read = 0; + i2c_set_clientdata(&s->client, s); + i2c_attach_client(&s->client); + + saa6588_configure(s); + + /* start polling via eventd */ + INIT_WORK(&s->work, saa6588_work); + init_timer(&s->timer); + s->timer.function = saa6588_timer; + s->timer.data = (unsigned long)s; + schedule_work(&s->work); + return 0; +} + +static int saa6588_probe(struct i2c_adapter *adap) +{ + if (adap->class & I2C_CLASS_TV_ANALOG) + return i2c_probe(adap, &addr_data, saa6588_attach); + return 0; +} + +static int saa6588_detach(struct i2c_client *client) +{ + struct saa6588 *s = i2c_get_clientdata(client); + + del_timer_sync(&s->timer); + flush_scheduled_work(); + + i2c_detach_client(client); + kfree(s->buffer); + kfree(s); + return 0; +} + +static int saa6588_command(struct i2c_client *client, unsigned int cmd, + void *arg) { - struct saa6588 *s = to_saa6588(sd); - struct rds_command *a = arg; + struct saa6588 *s = i2c_get_clientdata(client); + struct rds_command *a = (struct rds_command *)arg; switch (cmd) { /* --- open() for /dev/radio --- */ @@ -411,94 +479,45 @@ static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) default: /* nothing */ - return -ENOIOCTLCMD; + break; } return 0; } -static int saa6588_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA6588, 0); -} - /* ----------------------------------------------------------------------- */ -static const struct v4l2_subdev_core_ops saa6588_core_ops = { - .g_chip_ident = saa6588_g_chip_ident, - .ioctl = saa6588_ioctl, +static struct i2c_driver driver = { + .driver = { + .name = "saa6588", + }, + .id = -1, /* FIXME */ + .attach_adapter = saa6588_probe, + .detach_client = saa6588_detach, + .command = saa6588_command, }; -static const struct v4l2_subdev_ops saa6588_ops = { - .core = &saa6588_core_ops, +static struct i2c_client client_template = { + .name = "saa6588", + .driver = &driver, }; -/* ---------------------------------------------------------------------- */ - -static int saa6588_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int __init saa6588_init_module(void) { - struct saa6588 *s; - struct v4l2_subdev *sd; - - v4l_info(client, "saa6588 found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); - - s = kzalloc(sizeof(*s), GFP_KERNEL); - if (s == NULL) - return -ENOMEM; - - s->buf_size = bufblocks * 3; - - s->buffer = kmalloc(s->buf_size, GFP_KERNEL); - if (s->buffer == NULL) { - kfree(s); - return -ENOMEM; - } - sd = &s->sd; - v4l2_i2c_subdev_init(sd, client, &saa6588_ops); - spin_lock_init(&s->lock); - s->block_count = 0; - s->wr_index = 0; - s->rd_index = 0; - s->last_blocknum = 0xff; - init_waitqueue_head(&s->read_queue); - s->data_available_for_read = 0; - - saa6588_configure(s); - - /* start polling via eventd */ - INIT_DELAYED_WORK(&s->work, saa6588_work); - schedule_delayed_work(&s->work, 0); - return 0; + return i2c_add_driver(&driver); } -static int saa6588_remove(struct i2c_client *client) +static void __exit saa6588_cleanup_module(void) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct saa6588 *s = to_saa6588(sd); - - v4l2_device_unregister_subdev(sd); - - cancel_delayed_work_sync(&s->work); - - kfree(s->buffer); - kfree(s); - return 0; + i2c_del_driver(&driver); } -/* ----------------------------------------------------------------------- */ +module_init(saa6588_init_module); +module_exit(saa6588_cleanup_module); -static const struct i2c_device_id saa6588_id[] = { - { "saa6588", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, saa6588_id); - -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "saa6588", - .probe = saa6588_probe, - .remove = saa6588_remove, - .id_table = saa6588_id, -}; +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/trunk/drivers/media/video/saa7110.c b/trunk/drivers/media/video/saa7110.c index df4e08d2dceb..37860698f782 100644 --- a/trunk/drivers/media/video/saa7110.c +++ b/trunk/drivers/media/video/saa7110.c @@ -33,16 +33,15 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include MODULE_DESCRIPTION("Philips SAA7110 video decoder driver"); MODULE_AUTHOR("Pauline Middelink"); MODULE_LICENSE("GPL"); - static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); @@ -53,10 +52,9 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); #define SAA7110_NR_REG 0x35 struct saa7110 { - struct v4l2_subdev sd; u8 reg[SAA7110_NR_REG]; - v4l2_std_id norm; + int norm; int input; int enable; int bright; @@ -67,28 +65,20 @@ struct saa7110 { wait_queue_head_t wq; }; -static inline struct saa7110 *to_saa7110(struct v4l2_subdev *sd) -{ - return container_of(sd, struct saa7110, sd); -} - /* ----------------------------------------------------------------------- */ /* I2C support functions */ /* ----------------------------------------------------------------------- */ -static int saa7110_write(struct v4l2_subdev *sd, u8 reg, u8 value) +static int saa7110_write(struct i2c_client *client, u8 reg, u8 value) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct saa7110 *decoder = to_saa7110(sd); + struct saa7110 *decoder = i2c_get_clientdata(client); decoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } -static int saa7110_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len) +static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsigned int len) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct saa7110 *decoder = to_saa7110(sd); int ret = -1; u8 reg = *data; /* first register to write to */ @@ -99,13 +89,15 @@ static int saa7110_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned /* the saa7110 has an autoincrement function, use it if * the adapter understands raw I2C */ if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + struct saa7110 *decoder = i2c_get_clientdata(client); + ret = i2c_master_send(client, data, len); /* Cache the written data */ memcpy(decoder->reg + reg, data + 1, len - 1); } else { for (++data, --len; len; len--) { - ret = saa7110_write(sd, reg++, *data++); + ret = saa7110_write(client, reg++, *data++); if (ret < 0) break; } @@ -114,10 +106,8 @@ static int saa7110_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned return ret; } -static inline int saa7110_read(struct v4l2_subdev *sd) +static inline int saa7110_read(struct i2c_client *client) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - return i2c_smbus_read_byte(client); } @@ -125,11 +115,11 @@ static inline int saa7110_read(struct v4l2_subdev *sd) /* SAA7110 functions */ /* ----------------------------------------------------------------------- */ -#define FRESP_06H_COMPST 0x03 /*0x13*/ -#define FRESP_06H_SVIDEO 0x83 /*0xC0*/ +#define FRESP_06H_COMPST 0x03 //0x13 +#define FRESP_06H_SVIDEO 0x83 //0xC0 -static int saa7110_selmux(struct v4l2_subdev *sd, int chan) +static int saa7110_selmux(struct i2c_client *client, int chan) { static const unsigned char modes[9][8] = { /* mode 0 */ @@ -160,17 +150,17 @@ static int saa7110_selmux(struct v4l2_subdev *sd, int chan) {FRESP_06H_SVIDEO, 0x3C, 0x27, 0xC1, 0x23, 0x44, 0x75, 0x21} }; - struct saa7110 *decoder = to_saa7110(sd); + struct saa7110 *decoder = i2c_get_clientdata(client); const unsigned char *ptr = modes[chan]; - saa7110_write(sd, 0x06, ptr[0]); /* Luminance control */ - saa7110_write(sd, 0x20, ptr[1]); /* Analog Control #1 */ - saa7110_write(sd, 0x21, ptr[2]); /* Analog Control #2 */ - saa7110_write(sd, 0x22, ptr[3]); /* Mixer Control #1 */ - saa7110_write(sd, 0x2C, ptr[4]); /* Mixer Control #2 */ - saa7110_write(sd, 0x30, ptr[5]); /* ADCs gain control */ - saa7110_write(sd, 0x31, ptr[6]); /* Mixer Control #3 */ - saa7110_write(sd, 0x21, ptr[7]); /* Analog Control #2 */ + saa7110_write(client, 0x06, ptr[0]); /* Luminance control */ + saa7110_write(client, 0x20, ptr[1]); /* Analog Control #1 */ + saa7110_write(client, 0x21, ptr[2]); /* Analog Control #2 */ + saa7110_write(client, 0x22, ptr[3]); /* Mixer Control #1 */ + saa7110_write(client, 0x2C, ptr[4]); /* Mixer Control #2 */ + saa7110_write(client, 0x30, ptr[5]); /* ADCs gain control */ + saa7110_write(client, 0x31, ptr[6]); /* Mixer Control #3 */ + saa7110_write(client, 0x21, ptr[7]); /* Analog Control #2 */ decoder->input = chan; return 0; @@ -186,260 +176,246 @@ static const unsigned char initseq[1 + SAA7110_NR_REG] = { /* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02 }; -static v4l2_std_id determine_norm(struct v4l2_subdev *sd) +static int determine_norm(struct i2c_client *client) { DEFINE_WAIT(wait); - struct saa7110 *decoder = to_saa7110(sd); + struct saa7110 *decoder = i2c_get_clientdata(client); int status; /* mode changed, start automatic detection */ - saa7110_write_block(sd, initseq, sizeof(initseq)); - saa7110_selmux(sd, decoder->input); + saa7110_write_block(client, initseq, sizeof(initseq)); + saa7110_selmux(client, decoder->input); prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(250)); finish_wait(&decoder->wq, &wait); - status = saa7110_read(sd); + status = saa7110_read(client); if (status & 0x40) { - v4l2_dbg(1, debug, sd, "status=0x%02x (no signal)\n", status); - return decoder->norm; /* no change*/ + v4l_dbg(1, debug, client, "status=0x%02x (no signal)\n", status); + return decoder->norm; // no change } if ((status & 3) == 0) { - saa7110_write(sd, 0x06, 0x83); + saa7110_write(client, 0x06, 0x83); if (status & 0x20) { - v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC/no color)\n", status); - /*saa7110_write(sd,0x2E,0x81);*/ - return V4L2_STD_NTSC; + v4l_dbg(1, debug, client, "status=0x%02x (NTSC/no color)\n", status); + //saa7110_write(client,0x2E,0x81); + return VIDEO_MODE_NTSC; } - v4l2_dbg(1, debug, sd, "status=0x%02x (PAL/no color)\n", status); - /*saa7110_write(sd,0x2E,0x9A);*/ - return V4L2_STD_PAL; + v4l_dbg(1, debug, client, "status=0x%02x (PAL/no color)\n", status); + //saa7110_write(client,0x2E,0x9A); + return VIDEO_MODE_PAL; } - /*saa7110_write(sd,0x06,0x03);*/ + //saa7110_write(client,0x06,0x03); if (status & 0x20) { /* 60Hz */ - v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC)\n", status); - saa7110_write(sd, 0x0D, 0x86); - saa7110_write(sd, 0x0F, 0x50); - saa7110_write(sd, 0x11, 0x2C); - /*saa7110_write(sd,0x2E,0x81);*/ - return V4L2_STD_NTSC; + v4l_dbg(1, debug, client, "status=0x%02x (NTSC)\n", status); + saa7110_write(client, 0x0D, 0x86); + saa7110_write(client, 0x0F, 0x50); + saa7110_write(client, 0x11, 0x2C); + //saa7110_write(client,0x2E,0x81); + return VIDEO_MODE_NTSC; } /* 50Hz -> PAL/SECAM */ - saa7110_write(sd, 0x0D, 0x86); - saa7110_write(sd, 0x0F, 0x10); - saa7110_write(sd, 0x11, 0x59); - /*saa7110_write(sd,0x2E,0x9A);*/ + saa7110_write(client, 0x0D, 0x86); + saa7110_write(client, 0x0F, 0x10); + saa7110_write(client, 0x11, 0x59); + //saa7110_write(client,0x2E,0x9A); prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(250)); finish_wait(&decoder->wq, &wait); - status = saa7110_read(sd); + status = saa7110_read(client); if ((status & 0x03) == 0x01) { - v4l2_dbg(1, debug, sd, "status=0x%02x (SECAM)\n", status); - saa7110_write(sd, 0x0D, 0x87); - return V4L2_STD_SECAM; - } - v4l2_dbg(1, debug, sd, "status=0x%02x (PAL)\n", status); - return V4L2_STD_PAL; -} - -static int saa7110_g_input_status(struct v4l2_subdev *sd, u32 *pstatus) -{ - struct saa7110 *decoder = to_saa7110(sd); - int res = V4L2_IN_ST_NO_SIGNAL; - int status = saa7110_read(sd); - - v4l2_dbg(1, debug, sd, "status=0x%02x norm=%llx\n", - status, (unsigned long long)decoder->norm); - if (!(status & 0x40)) - res = 0; - if (!(status & 0x03)) - res |= V4L2_IN_ST_NO_COLOR; - - *pstatus = res; - return 0; -} - -static int saa7110_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) -{ - *(v4l2_std_id *)std = determine_norm(sd); - return 0; -} - -static int saa7110_s_std(struct v4l2_subdev *sd, v4l2_std_id std) -{ - struct saa7110 *decoder = to_saa7110(sd); - - if (decoder->norm != std) { - decoder->norm = std; - /*saa7110_write(sd, 0x06, 0x03);*/ - if (std & V4L2_STD_NTSC) { - saa7110_write(sd, 0x0D, 0x86); - saa7110_write(sd, 0x0F, 0x50); - saa7110_write(sd, 0x11, 0x2C); - /*saa7110_write(sd, 0x2E, 0x81);*/ - v4l2_dbg(1, debug, sd, "switched to NTSC\n"); - } else if (std & V4L2_STD_PAL) { - saa7110_write(sd, 0x0D, 0x86); - saa7110_write(sd, 0x0F, 0x10); - saa7110_write(sd, 0x11, 0x59); - /*saa7110_write(sd, 0x2E, 0x9A);*/ - v4l2_dbg(1, debug, sd, "switched to PAL\n"); - } else if (std & V4L2_STD_SECAM) { - saa7110_write(sd, 0x0D, 0x87); - saa7110_write(sd, 0x0F, 0x10); - saa7110_write(sd, 0x11, 0x59); - /*saa7110_write(sd, 0x2E, 0x9A);*/ - v4l2_dbg(1, debug, sd, "switched to SECAM\n"); - } else { - return -EINVAL; - } + v4l_dbg(1, debug, client, "status=0x%02x (SECAM)\n", status); + saa7110_write(client, 0x0D, 0x87); + return VIDEO_MODE_SECAM; } - return 0; + v4l_dbg(1, debug, client, "status=0x%02x (PAL)\n", status); + return VIDEO_MODE_PAL; } -static int saa7110_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) +static int +saa7110_command (struct i2c_client *client, + unsigned int cmd, + void *arg) { - struct saa7110 *decoder = to_saa7110(sd); + struct saa7110 *decoder = i2c_get_clientdata(client); + int v; - if (route->input < 0 || route->input >= SAA7110_MAX_INPUT) { - v4l2_dbg(1, debug, sd, "input=%d not available\n", route->input); - return -EINVAL; - } - if (decoder->input != route->input) { - saa7110_selmux(sd, route->input); - v4l2_dbg(1, debug, sd, "switched to input=%d\n", route->input); - } - return 0; -} + switch (cmd) { + case 0: + //saa7110_write_block(client, initseq, sizeof(initseq)); + break; -static int saa7110_s_stream(struct v4l2_subdev *sd, int enable) -{ - struct saa7110 *decoder = to_saa7110(sd); + case DECODER_GET_CAPABILITIES: + { + struct video_decoder_capability *dc = arg; - if (decoder->enable != enable) { - decoder->enable = enable; - saa7110_write(sd, 0x0E, enable ? 0x18 : 0x80); - v4l2_dbg(1, debug, sd, "YUV %s\n", enable ? "on" : "off"); + dc->flags = + VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC | + VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO; + dc->inputs = SAA7110_MAX_INPUT; + dc->outputs = SAA7110_MAX_OUTPUT; + break; } - return 0; -} -static int saa7110_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) -{ - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); - case V4L2_CID_CONTRAST: - case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64); - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); - default: - return -EINVAL; + case DECODER_GET_STATUS: + { + int status; + int res = 0; + + status = saa7110_read(client); + v4l_dbg(1, debug, client, "status=0x%02x norm=%d\n", + status, decoder->norm); + if (!(status & 0x40)) + res |= DECODER_STATUS_GOOD; + if (status & 0x03) + res |= DECODER_STATUS_COLOR; + + switch (decoder->norm) { + case VIDEO_MODE_NTSC: + res |= DECODER_STATUS_NTSC; + break; + case VIDEO_MODE_PAL: + res |= DECODER_STATUS_PAL; + break; + case VIDEO_MODE_SECAM: + res |= DECODER_STATUS_SECAM; + break; + } + *(int *) arg = res; + break; } - return 0; -} - -static int saa7110_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct saa7110 *decoder = to_saa7110(sd); - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = decoder->bright; + case DECODER_SET_NORM: + v = *(int *) arg; + if (decoder->norm != v) { + decoder->norm = v; + //saa7110_write(client, 0x06, 0x03); + switch (v) { + case VIDEO_MODE_NTSC: + saa7110_write(client, 0x0D, 0x86); + saa7110_write(client, 0x0F, 0x50); + saa7110_write(client, 0x11, 0x2C); + //saa7110_write(client, 0x2E, 0x81); + v4l_dbg(1, debug, client, "switched to NTSC\n"); + break; + case VIDEO_MODE_PAL: + saa7110_write(client, 0x0D, 0x86); + saa7110_write(client, 0x0F, 0x10); + saa7110_write(client, 0x11, 0x59); + //saa7110_write(client, 0x2E, 0x9A); + v4l_dbg(1, debug, client, "switched to PAL\n"); + break; + case VIDEO_MODE_SECAM: + saa7110_write(client, 0x0D, 0x87); + saa7110_write(client, 0x0F, 0x10); + saa7110_write(client, 0x11, 0x59); + //saa7110_write(client, 0x2E, 0x9A); + v4l_dbg(1, debug, client, "switched to SECAM\n"); + break; + case VIDEO_MODE_AUTO: + v4l_dbg(1, debug, client, "switched to AUTO\n"); + decoder->norm = determine_norm(client); + *(int *) arg = decoder->norm; + break; + default: + return -EPERM; + } + } break; - case V4L2_CID_CONTRAST: - ctrl->value = decoder->contrast; + + case DECODER_SET_INPUT: + v = *(int *) arg; + if (v < 0 || v >= SAA7110_MAX_INPUT) { + v4l_dbg(1, debug, client, "input=%d not available\n", v); + return -EINVAL; + } + if (decoder->input != v) { + saa7110_selmux(client, v); + v4l_dbg(1, debug, client, "switched to input=%d\n", v); + } break; - case V4L2_CID_SATURATION: - ctrl->value = decoder->sat; + + case DECODER_SET_OUTPUT: + v = *(int *) arg; + /* not much choice of outputs */ + if (v != 0) + return -EINVAL; break; - case V4L2_CID_HUE: - ctrl->value = decoder->hue; + + case DECODER_ENABLE_OUTPUT: + v = *(int *) arg; + if (decoder->enable != v) { + decoder->enable = v; + saa7110_write(client, 0x0E, v ? 0x18 : 0x80); + v4l_dbg(1, debug, client, "YUV %s\n", v ? "on" : "off"); + } break; - default: - return -EINVAL; - } - return 0; -} -static int saa7110_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct saa7110 *decoder = to_saa7110(sd); + case DECODER_SET_PICTURE: + { + struct video_picture *pic = arg; - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - if (decoder->bright != ctrl->value) { - decoder->bright = ctrl->value; - saa7110_write(sd, 0x19, decoder->bright); + if (decoder->bright != pic->brightness) { + /* We want 0 to 255 we get 0-65535 */ + decoder->bright = pic->brightness; + saa7110_write(client, 0x19, decoder->bright >> 8); } - break; - case V4L2_CID_CONTRAST: - if (decoder->contrast != ctrl->value) { - decoder->contrast = ctrl->value; - saa7110_write(sd, 0x13, decoder->contrast); + if (decoder->contrast != pic->contrast) { + /* We want 0 to 127 we get 0-65535 */ + decoder->contrast = pic->contrast; + saa7110_write(client, 0x13, + decoder->contrast >> 9); } - break; - case V4L2_CID_SATURATION: - if (decoder->sat != ctrl->value) { - decoder->sat = ctrl->value; - saa7110_write(sd, 0x12, decoder->sat); + if (decoder->sat != pic->colour) { + /* We want 0 to 127 we get 0-65535 */ + decoder->sat = pic->colour; + saa7110_write(client, 0x12, decoder->sat >> 9); + } + if (decoder->hue != pic->hue) { + /* We want -128 to 127 we get 0-65535 */ + decoder->hue = pic->hue; + saa7110_write(client, 0x07, + (decoder->hue >> 8) - 128); } break; - case V4L2_CID_HUE: - if (decoder->hue != ctrl->value) { - decoder->hue = ctrl->value; - saa7110_write(sd, 0x07, decoder->hue); + } + + case DECODER_DUMP: + if (!debug) + break; + for (v = 0; v < SAA7110_NR_REG; v += 16) { + int j; + v4l_dbg(1, debug, client, "%02x:", v); + for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++) + printk(KERN_CONT " %02x", decoder->reg[v + j]); + printk(KERN_CONT "\n"); } break; + default: + v4l_dbg(1, debug, client, "unknown command %08x\n", cmd); return -EINVAL; } return 0; } -static int saa7110_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7110, 0); -} - /* ----------------------------------------------------------------------- */ -static const struct v4l2_subdev_core_ops saa7110_core_ops = { - .g_chip_ident = saa7110_g_chip_ident, - .g_ctrl = saa7110_g_ctrl, - .s_ctrl = saa7110_s_ctrl, - .queryctrl = saa7110_queryctrl, -}; - -static const struct v4l2_subdev_tuner_ops saa7110_tuner_ops = { - .s_std = saa7110_s_std, -}; - -static const struct v4l2_subdev_video_ops saa7110_video_ops = { - .s_routing = saa7110_s_routing, - .s_stream = saa7110_s_stream, - .querystd = saa7110_querystd, - .g_input_status = saa7110_g_input_status, -}; +/* + * Generic i2c probe + * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' + */ -static const struct v4l2_subdev_ops saa7110_ops = { - .core = &saa7110_core_ops, - .tuner = &saa7110_tuner_ops, - .video = &saa7110_video_ops, -}; +static unsigned short normal_i2c[] = { 0x9c >> 1, 0x9e >> 1, I2C_CLIENT_END }; -/* ----------------------------------------------------------------------- */ +I2C_CLIENT_INSMOD; static int saa7110_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct saa7110 *decoder; - struct v4l2_subdev *sd; int rv; /* Check if the adapter supports the needed features */ @@ -453,9 +429,7 @@ static int saa7110_probe(struct i2c_client *client, decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL); if (!decoder) return -ENOMEM; - sd = &decoder->sd; - v4l2_i2c_subdev_init(sd, client, &saa7110_ops); - decoder->norm = V4L2_STD_PAL; + decoder->norm = VIDEO_MODE_PAL; decoder->input = 0; decoder->enable = 1; decoder->bright = 32768; @@ -463,29 +437,30 @@ static int saa7110_probe(struct i2c_client *client, decoder->hue = 32768; decoder->sat = 32768; init_waitqueue_head(&decoder->wq); + i2c_set_clientdata(client, decoder); - rv = saa7110_write_block(sd, initseq, sizeof(initseq)); + rv = saa7110_write_block(client, initseq, sizeof(initseq)); if (rv < 0) { - v4l2_dbg(1, debug, sd, "init status %d\n", rv); + v4l_dbg(1, debug, client, "init status %d\n", rv); } else { int ver, status; - saa7110_write(sd, 0x21, 0x10); - saa7110_write(sd, 0x0e, 0x18); - saa7110_write(sd, 0x0D, 0x04); - ver = saa7110_read(sd); - saa7110_write(sd, 0x0D, 0x06); - /*mdelay(150);*/ - status = saa7110_read(sd); - v4l2_dbg(1, debug, sd, "version %x, status=0x%02x\n", + saa7110_write(client, 0x21, 0x10); + saa7110_write(client, 0x0e, 0x18); + saa7110_write(client, 0x0D, 0x04); + ver = saa7110_read(client); + saa7110_write(client, 0x0D, 0x06); + //mdelay(150); + status = saa7110_read(client); + v4l_dbg(1, debug, client, "version %x, status=0x%02x\n", ver, status); - saa7110_write(sd, 0x0D, 0x86); - saa7110_write(sd, 0x0F, 0x10); - saa7110_write(sd, 0x11, 0x59); - /*saa7110_write(sd, 0x2E, 0x9A);*/ + saa7110_write(client, 0x0D, 0x86); + saa7110_write(client, 0x0F, 0x10); + saa7110_write(client, 0x11, 0x59); + //saa7110_write(client, 0x2E, 0x9A); } - /*saa7110_selmux(sd,0);*/ - /*determine_norm(sd);*/ + //saa7110_selmux(client,0); + //determine_norm(client); /* setup and implicit mode 0 select has been performed */ return 0; @@ -493,10 +468,7 @@ static int saa7110_probe(struct i2c_client *client, static int saa7110_remove(struct i2c_client *client) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - - v4l2_device_unregister_subdev(sd); - kfree(to_saa7110(sd)); + kfree(i2c_get_clientdata(client)); return 0; } @@ -510,6 +482,8 @@ MODULE_DEVICE_TABLE(i2c, saa7110_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa7110", + .driverid = I2C_DRIVERID_SAA7110, + .command = saa7110_command, .probe = saa7110_probe, .remove = saa7110_remove, .id_table = saa7110_id, diff --git a/trunk/drivers/media/video/saa7111.c b/trunk/drivers/media/video/saa7111.c new file mode 100644 index 000000000000..a4738a2fb4d3 --- /dev/null +++ b/trunk/drivers/media/video/saa7111.c @@ -0,0 +1,492 @@ +/* + * saa7111 - Philips SAA7111A video decoder driver version 0.0.3 + * + * Copyright (C) 1998 Dave Perks + * + * Slight changes for video timing and attachment output by + * Wolfgang Scherr + * + * Changes by Ronald Bultje + * - moved over to linux>=2.4.x i2c protocol (1/1/2003) + * + * Changes by Michael Hunold + * - implemented DECODER_SET_GPIO, DECODER_INIT, DECODER_SET_VBI_BYPASS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_DESCRIPTION("Philips SAA7111 video decoder driver"); +MODULE_AUTHOR("Dave Perks"); +MODULE_LICENSE("GPL"); + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Debug level (0-1)"); + +/* ----------------------------------------------------------------------- */ + +#define SAA7111_NR_REG 0x18 + +struct saa7111 { + unsigned char reg[SAA7111_NR_REG]; + + int norm; + int input; + int enable; +}; + +/* ----------------------------------------------------------------------- */ + +static inline int saa7111_write(struct i2c_client *client, u8 reg, u8 value) +{ + struct saa7111 *decoder = i2c_get_clientdata(client); + + decoder->reg[reg] = value; + return i2c_smbus_write_byte_data(client, reg, value); +} + +static inline void saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value) +{ + struct saa7111 *decoder = i2c_get_clientdata(client); + + if (decoder->reg[reg] != value) { + decoder->reg[reg] = value; + i2c_smbus_write_byte_data(client, reg, value); + } +} + +static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsigned int len) +{ + int ret = -1; + u8 reg; + + /* the saa7111 has an autoincrement function, use it if + * the adapter understands raw I2C */ + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + /* do raw I2C, not smbus compatible */ + struct saa7111 *decoder = i2c_get_clientdata(client); + u8 block_data[32]; + int block_len; + + while (len >= 2) { + block_len = 0; + block_data[block_len++] = reg = data[0]; + do { + block_data[block_len++] = + decoder->reg[reg++] = data[1]; + len -= 2; + data += 2; + } while (len >= 2 && data[0] == reg && block_len < 32); + ret = i2c_master_send(client, block_data, block_len); + if (ret < 0) + break; + } + } else { + /* do some slow I2C emulation kind of thing */ + while (len >= 2) { + reg = *data++; + ret = saa7111_write(client, reg, *data++); + if (ret < 0) + break; + len -= 2; + } + } + + return ret; +} + +static int saa7111_init_decoder(struct i2c_client *client, + struct video_decoder_init *init) +{ + return saa7111_write_block(client, init->data, init->len); +} + +static inline int saa7111_read(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +/* ----------------------------------------------------------------------- */ + +static const unsigned char saa7111_i2c_init[] = { + 0x00, 0x00, /* 00 - ID byte */ + 0x01, 0x00, /* 01 - reserved */ + + /*front end */ + 0x02, 0xd0, /* 02 - FUSE=3, GUDL=2, MODE=0 */ + 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, + * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */ + 0x04, 0x00, /* 04 - GAI1=256 */ + 0x05, 0x00, /* 05 - GAI2=256 */ + + /* decoder */ + 0x06, 0xf3, /* 06 - HSB at 13(50Hz) / 17(60Hz) + * pixels after end of last line */ + /*0x07, 0x13, * 07 - HSS at 113(50Hz) / 117(60Hz) pixels + * after end of last line */ + 0x07, 0xe8, /* 07 - HSS seems to be needed to + * work with NTSC, too */ + 0x08, 0xc8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, + * VTRC=1, HPLL=0, VNOI=0 */ + 0x09, 0x01, /* 09 - BYPS=0, PREF=0, BPSS=0, + * VBLB=0, UPTCV=0, APER=1 */ + 0x0a, 0x80, /* 0a - BRIG=128 */ + 0x0b, 0x47, /* 0b - CONT=1.109 */ + 0x0c, 0x40, /* 0c - SATN=1.0 */ + 0x0d, 0x00, /* 0d - HUE=0 */ + 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, + * FCTC=0, CHBW=1 */ + 0x0f, 0x00, /* 0f - reserved */ + 0x10, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */ + 0x11, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1, + * OEYC=1, OEHV=1, VIPB=0, COLO=0 */ + 0x12, 0x00, /* 12 - output control 2 */ + 0x13, 0x00, /* 13 - output control 3 */ + 0x14, 0x00, /* 14 - reserved */ + 0x15, 0x00, /* 15 - VBI */ + 0x16, 0x00, /* 16 - VBI */ + 0x17, 0x00, /* 17 - VBI */ +}; + +static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + struct saa7111 *decoder = i2c_get_clientdata(client); + + switch (cmd) { + case 0: + break; + case DECODER_INIT: + { + struct video_decoder_init *init = arg; + struct video_decoder_init vdi; + + if (NULL != init) + return saa7111_init_decoder(client, init); + vdi.data = saa7111_i2c_init; + vdi.len = sizeof(saa7111_i2c_init); + return saa7111_init_decoder(client, &vdi); + } + + case DECODER_DUMP: + { + int i; + + for (i = 0; i < SAA7111_NR_REG; i += 16) { + int j; + + v4l_info(client, "%03x", i); + for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) { + printk(KERN_CONT " %02x", + saa7111_read(client, i + j)); + } + printk(KERN_CONT "\n"); + } + break; + } + + case DECODER_GET_CAPABILITIES: + { + struct video_decoder_capability *cap = arg; + + cap->flags = VIDEO_DECODER_PAL | + VIDEO_DECODER_NTSC | + VIDEO_DECODER_SECAM | + VIDEO_DECODER_AUTO | + VIDEO_DECODER_CCIR; + cap->inputs = 8; + cap->outputs = 1; + break; + } + + case DECODER_GET_STATUS: + { + int *iarg = arg; + int status; + int res; + + status = saa7111_read(client, 0x1f); + v4l_dbg(1, debug, client, "status: 0x%02x\n", status); + res = 0; + if ((status & (1 << 6)) == 0) { + res |= DECODER_STATUS_GOOD; + } + switch (decoder->norm) { + case VIDEO_MODE_NTSC: + res |= DECODER_STATUS_NTSC; + break; + case VIDEO_MODE_PAL: + res |= DECODER_STATUS_PAL; + break; + case VIDEO_MODE_SECAM: + res |= DECODER_STATUS_SECAM; + break; + default: + case VIDEO_MODE_AUTO: + if ((status & (1 << 5)) != 0) { + res |= DECODER_STATUS_NTSC; + } else { + res |= DECODER_STATUS_PAL; + } + break; + } + if ((status & (1 << 0)) != 0) { + res |= DECODER_STATUS_COLOR; + } + *iarg = res; + break; + } + + case DECODER_SET_GPIO: + { + int *iarg = arg; + if (0 != *iarg) { + saa7111_write(client, 0x11, + (decoder->reg[0x11] | 0x80)); + } else { + saa7111_write(client, 0x11, + (decoder->reg[0x11] & 0x7f)); + } + break; + } + + case DECODER_SET_VBI_BYPASS: + { + int *iarg = arg; + if (0 != *iarg) { + saa7111_write(client, 0x13, + (decoder->reg[0x13] & 0xf0) | 0x0a); + } else { + saa7111_write(client, 0x13, + (decoder->reg[0x13] & 0xf0)); + } + break; + } + + case DECODER_SET_NORM: + { + int *iarg = arg; + + switch (*iarg) { + + case VIDEO_MODE_NTSC: + saa7111_write(client, 0x08, + (decoder->reg[0x08] & 0x3f) | 0x40); + saa7111_write(client, 0x0e, + (decoder->reg[0x0e] & 0x8f)); + break; + + case VIDEO_MODE_PAL: + saa7111_write(client, 0x08, + (decoder->reg[0x08] & 0x3f) | 0x00); + saa7111_write(client, 0x0e, + (decoder->reg[0x0e] & 0x8f)); + break; + + case VIDEO_MODE_SECAM: + saa7111_write(client, 0x08, + (decoder->reg[0x08] & 0x3f) | 0x00); + saa7111_write(client, 0x0e, + (decoder->reg[0x0e] & 0x8f) | 0x50); + break; + + case VIDEO_MODE_AUTO: + saa7111_write(client, 0x08, + (decoder->reg[0x08] & 0x3f) | 0x80); + saa7111_write(client, 0x0e, + (decoder->reg[0x0e] & 0x8f)); + break; + + default: + return -EINVAL; + + } + decoder->norm = *iarg; + break; + } + + case DECODER_SET_INPUT: + { + int *iarg = arg; + + if (*iarg < 0 || *iarg > 7) { + return -EINVAL; + } + + if (decoder->input != *iarg) { + decoder->input = *iarg; + /* select mode */ + saa7111_write(client, 0x02, + (decoder-> + reg[0x02] & 0xf8) | decoder->input); + /* bypass chrominance trap for modes 4..7 */ + saa7111_write(client, 0x09, + (decoder-> + reg[0x09] & 0x7f) | ((decoder-> + input > + 3) ? 0x80 : + 0)); + } + break; + } + + case DECODER_SET_OUTPUT: + { + int *iarg = arg; + + /* not much choice of outputs */ + if (*iarg != 0) { + return -EINVAL; + } + break; + } + + case DECODER_ENABLE_OUTPUT: + { + int *iarg = arg; + int enable = (*iarg != 0); + + if (decoder->enable != enable) { + decoder->enable = enable; + + /* RJ: If output should be disabled (for + * playing videos), we also need a open PLL. + * The input is set to 0 (where no input + * source is connected), although this + * is not necessary. + * + * If output should be enabled, we have to + * reverse the above. + */ + + if (decoder->enable) { + saa7111_write(client, 0x02, + (decoder-> + reg[0x02] & 0xf8) | + decoder->input); + saa7111_write(client, 0x08, + (decoder->reg[0x08] & 0xfb)); + saa7111_write(client, 0x11, + (decoder-> + reg[0x11] & 0xf3) | 0x0c); + } else { + saa7111_write(client, 0x02, + (decoder->reg[0x02] & 0xf8)); + saa7111_write(client, 0x08, + (decoder-> + reg[0x08] & 0xfb) | 0x04); + saa7111_write(client, 0x11, + (decoder->reg[0x11] & 0xf3)); + } + } + break; + } + + case DECODER_SET_PICTURE: + { + struct video_picture *pic = arg; + + /* We want 0 to 255 we get 0-65535 */ + saa7111_write_if_changed(client, 0x0a, pic->brightness >> 8); + /* We want 0 to 127 we get 0-65535 */ + saa7111_write(client, 0x0b, pic->contrast >> 9); + /* We want 0 to 127 we get 0-65535 */ + saa7111_write(client, 0x0c, pic->colour >> 9); + /* We want -128 to 127 we get 0-65535 */ + saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8); + break; + } + + default: + return -EINVAL; + } + + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static unsigned short normal_i2c[] = { 0x48 >> 1, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; + +static int saa7111_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int i; + struct saa7111 *decoder; + struct video_decoder_init vdi; + + /* Check if the adapter supports the needed features */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); + + decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL); + if (decoder == NULL) { + kfree(client); + return -ENOMEM; + } + decoder->norm = VIDEO_MODE_NTSC; + decoder->input = 0; + decoder->enable = 1; + i2c_set_clientdata(client, decoder); + + vdi.data = saa7111_i2c_init; + vdi.len = sizeof(saa7111_i2c_init); + i = saa7111_init_decoder(client, &vdi); + if (i < 0) { + v4l_dbg(1, debug, client, "init status %d\n", i); + } else { + v4l_dbg(1, debug, client, "revision %x\n", + saa7111_read(client, 0x00) >> 4); + } + return 0; +} + +static int saa7111_remove(struct i2c_client *client) +{ + kfree(i2c_get_clientdata(client)); + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static const struct i2c_device_id saa7111_id[] = { + { "saa7111_old", 0 }, /* "saa7111" maps to the saa7115 driver */ + { } +}; +MODULE_DEVICE_TABLE(i2c, saa7111_id); + +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "saa7111", + .driverid = I2C_DRIVERID_SAA7111A, + .command = saa7111_command, + .probe = saa7111_probe, + .remove = saa7111_remove, + .id_table = saa7111_id, +}; diff --git a/trunk/drivers/media/video/saa7114.c b/trunk/drivers/media/video/saa7114.c new file mode 100644 index 000000000000..7ca709fda5f4 --- /dev/null +++ b/trunk/drivers/media/video/saa7114.c @@ -0,0 +1,1068 @@ +/* + * saa7114 - Philips SAA7114H video decoder driver version 0.0.1 + * + * Copyright (C) 2002 Maxim Yevtyushkin + * + * Based on saa7111 driver by Dave Perks + * + * Copyright (C) 1998 Dave Perks + * + * Slight changes for video timing and attachment output by + * Wolfgang Scherr + * + * Changes by Ronald Bultje + * - moved over to linux>=2.4.x i2c protocol (1/1/2003) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_DESCRIPTION("Philips SAA7114H video decoder driver"); +MODULE_AUTHOR("Maxim Yevtyushkin"); +MODULE_LICENSE("GPL"); + +static int debug; +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "Debug level (0-1)"); + +/* ----------------------------------------------------------------------- */ + +struct saa7114 { + unsigned char reg[0xf0 * 2]; + + int norm; + int input; + int enable; + int bright; + int contrast; + int hue; + int sat; + int playback; +}; + +#define I2C_DELAY 10 + + +//#define SAA_7114_NTSC_HSYNC_START (-3) +//#define SAA_7114_NTSC_HSYNC_STOP (-18) + +#define SAA_7114_NTSC_HSYNC_START (-17) +#define SAA_7114_NTSC_HSYNC_STOP (-32) + +//#define SAA_7114_NTSC_HOFFSET (5) +#define SAA_7114_NTSC_HOFFSET (6) +#define SAA_7114_NTSC_VOFFSET (10) +#define SAA_7114_NTSC_WIDTH (720) +#define SAA_7114_NTSC_HEIGHT (250) + +#define SAA_7114_SECAM_HSYNC_START (-17) +#define SAA_7114_SECAM_HSYNC_STOP (-32) + +#define SAA_7114_SECAM_HOFFSET (2) +#define SAA_7114_SECAM_VOFFSET (10) +#define SAA_7114_SECAM_WIDTH (720) +#define SAA_7114_SECAM_HEIGHT (300) + +#define SAA_7114_PAL_HSYNC_START (-17) +#define SAA_7114_PAL_HSYNC_STOP (-32) + +#define SAA_7114_PAL_HOFFSET (2) +#define SAA_7114_PAL_VOFFSET (10) +#define SAA_7114_PAL_WIDTH (720) +#define SAA_7114_PAL_HEIGHT (300) + + + +#define SAA_7114_VERTICAL_CHROMA_OFFSET 0 //0x50504040 +#define SAA_7114_VERTICAL_LUMA_OFFSET 0 + +#define REG_ADDR(x) (((x) << 1) + 1) +#define LOBYTE(x) ((unsigned char)((x) & 0xff)) +#define HIBYTE(x) ((unsigned char)(((x) >> 8) & 0xff)) +#define LOWORD(x) ((unsigned short int)((x) & 0xffff)) +#define HIWORD(x) ((unsigned short int)(((x) >> 16) & 0xffff)) + + +/* ----------------------------------------------------------------------- */ + +static inline int saa7114_write(struct i2c_client *client, u8 reg, u8 value) +{ + return i2c_smbus_write_byte_data(client, reg, value); +} + +static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsigned int len) +{ + int ret = -1; + u8 reg; + + /* the saa7114 has an autoincrement function, use it if + * the adapter understands raw I2C */ + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + /* do raw I2C, not smbus compatible */ + u8 block_data[32]; + int block_len; + + while (len >= 2) { + block_len = 0; + block_data[block_len++] = reg = data[0]; + do { + block_data[block_len++] = data[1]; + reg++; + len -= 2; + data += 2; + } while (len >= 2 && data[0] == reg && block_len < 32); + ret = i2c_master_send(client, block_data, block_len); + if (ret < 0) + break; + } + } else { + /* do some slow I2C emulation kind of thing */ + while (len >= 2) { + reg = *data++; + ret = saa7114_write(client, reg, *data++); + if (ret < 0) + break; + len -= 2; + } + } + + return ret; +} + +static inline int saa7114_read(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +/* ----------------------------------------------------------------------- */ + +// initially set NTSC, composite + + +static const unsigned char init[] = { + 0x00, 0x00, /* 00 - ID byte , chip version, + * read only */ + 0x01, 0x08, /* 01 - X,X,X,X, IDEL3 to IDEL0 - + * horizontal increment delay, + * recommended position */ + 0x02, 0x00, /* 02 - FUSE=3, GUDL=2, MODE=0 ; + * input control */ + 0x03, 0x10, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, + * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */ + 0x04, 0x90, /* 04 - GAI1=256 */ + 0x05, 0x90, /* 05 - GAI2=256 */ + 0x06, SAA_7114_NTSC_HSYNC_START, /* 06 - HSB: hsync start, + * depends on the video standard */ + 0x07, SAA_7114_NTSC_HSYNC_STOP, /* 07 - HSS: hsync stop, depends + *on the video standard */ + 0x08, 0xb8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1, + * HPLL: free running in playback, locked + * in capture, VNOI=0 */ + 0x09, 0x80, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0, + * UPTCV=0, APER=1; depends from input */ + 0x0a, 0x80, /* 0a - BRIG=128 */ + 0x0b, 0x44, /* 0b - CONT=1.109 */ + 0x0c, 0x40, /* 0c - SATN=1.0 */ + 0x0d, 0x00, /* 0d - HUE=0 */ + 0x0e, 0x84, /* 0e - CDTO, CSTD2 to 0, DCVF, FCTC, + * CCOMB; depends from video standard */ + 0x0f, 0x24, /* 0f - ACGC,CGAIN6 to CGAIN0; depends + * from video standard */ + 0x10, 0x03, /* 10 - OFFU1 to 0, OFFV1 to 0, CHBW, + * LCBW2 to 0 */ + 0x11, 0x59, /* 11 - COLO, RTP1, HEDL1 to 0, RTP0, + * YDEL2 to 0 */ + 0x12, 0xc9, /* 12 - RT signal control RTSE13 to 10 + * and 03 to 00 */ + 0x13, 0x80, /* 13 - RT/X port output control */ + 0x14, 0x00, /* 14 - analog, ADC, compatibility control */ + 0x15, 0x00, /* 15 - VGATE start FID change */ + 0x16, 0xfe, /* 16 - VGATE stop */ + 0x17, 0x00, /* 17 - Misc., VGATE MSBs */ + 0x18, 0x40, /* RAWG */ + 0x19, 0x80, /* RAWO */ + 0x1a, 0x00, + 0x1b, 0x00, + 0x1c, 0x00, + 0x1d, 0x00, + 0x1e, 0x00, + 0x1f, 0x00, /* status byte, read only */ + 0x20, 0x00, /* video decoder reserved part */ + 0x21, 0x00, + 0x22, 0x00, + 0x23, 0x00, + 0x24, 0x00, + 0x25, 0x00, + 0x26, 0x00, + 0x27, 0x00, + 0x28, 0x00, + 0x29, 0x00, + 0x2a, 0x00, + 0x2b, 0x00, + 0x2c, 0x00, + 0x2d, 0x00, + 0x2e, 0x00, + 0x2f, 0x00, + 0x30, 0xbc, /* audio clock generator */ + 0x31, 0xdf, + 0x32, 0x02, + 0x33, 0x00, + 0x34, 0xcd, + 0x35, 0xcc, + 0x36, 0x3a, + 0x37, 0x00, + 0x38, 0x03, + 0x39, 0x10, + 0x3a, 0x00, + 0x3b, 0x00, + 0x3c, 0x00, + 0x3d, 0x00, + 0x3e, 0x00, + 0x3f, 0x00, + 0x40, 0x00, /* VBI data slicer */ + 0x41, 0xff, + 0x42, 0xff, + 0x43, 0xff, + 0x44, 0xff, + 0x45, 0xff, + 0x46, 0xff, + 0x47, 0xff, + 0x48, 0xff, + 0x49, 0xff, + 0x4a, 0xff, + 0x4b, 0xff, + 0x4c, 0xff, + 0x4d, 0xff, + 0x4e, 0xff, + 0x4f, 0xff, + 0x50, 0xff, + 0x51, 0xff, + 0x52, 0xff, + 0x53, 0xff, + 0x54, 0xff, + 0x55, 0xff, + 0x56, 0xff, + 0x57, 0xff, + 0x58, 0x40, // framing code + 0x59, 0x47, // horizontal offset + 0x5a, 0x06, // vertical offset + 0x5b, 0x83, // field offset + 0x5c, 0x00, // reserved + 0x5d, 0x3e, // header and data + 0x5e, 0x00, // sliced data + 0x5f, 0x00, // reserved + 0x60, 0x00, /* video decoder reserved part */ + 0x61, 0x00, + 0x62, 0x00, + 0x63, 0x00, + 0x64, 0x00, + 0x65, 0x00, + 0x66, 0x00, + 0x67, 0x00, + 0x68, 0x00, + 0x69, 0x00, + 0x6a, 0x00, + 0x6b, 0x00, + 0x6c, 0x00, + 0x6d, 0x00, + 0x6e, 0x00, + 0x6f, 0x00, + 0x70, 0x00, /* video decoder reserved part */ + 0x71, 0x00, + 0x72, 0x00, + 0x73, 0x00, + 0x74, 0x00, + 0x75, 0x00, + 0x76, 0x00, + 0x77, 0x00, + 0x78, 0x00, + 0x79, 0x00, + 0x7a, 0x00, + 0x7b, 0x00, + 0x7c, 0x00, + 0x7d, 0x00, + 0x7e, 0x00, + 0x7f, 0x00, + 0x80, 0x00, /* X-port, I-port and scaler */ + 0x81, 0x00, + 0x82, 0x00, + 0x83, 0x00, + 0x84, 0xc5, + 0x85, 0x0d, // hsync and vsync ? + 0x86, 0x40, + 0x87, 0x01, + 0x88, 0x00, + 0x89, 0x00, + 0x8a, 0x00, + 0x8b, 0x00, + 0x8c, 0x00, + 0x8d, 0x00, + 0x8e, 0x00, + 0x8f, 0x00, + 0x90, 0x03, /* Task A definition */ + 0x91, 0x08, + 0x92, 0x00, + 0x93, 0x40, + 0x94, 0x00, // window settings + 0x95, 0x00, + 0x96, 0x00, + 0x97, 0x00, + 0x98, 0x00, + 0x99, 0x00, + 0x9a, 0x00, + 0x9b, 0x00, + 0x9c, 0x00, + 0x9d, 0x00, + 0x9e, 0x00, + 0x9f, 0x00, + 0xa0, 0x01, /* horizontal integer prescaling ratio */ + 0xa1, 0x00, /* horizontal prescaler accumulation + * sequence length */ + 0xa2, 0x00, /* UV FIR filter, Y FIR filter, prescaler + * DC gain */ + 0xa3, 0x00, + 0xa4, 0x80, // luminance brightness + 0xa5, 0x40, // luminance gain + 0xa6, 0x40, // chrominance saturation + 0xa7, 0x00, + 0xa8, 0x00, // horizontal luminance scaling increment + 0xa9, 0x04, + 0xaa, 0x00, // horizontal luminance phase offset + 0xab, 0x00, + 0xac, 0x00, // horizontal chrominance scaling increment + 0xad, 0x02, + 0xae, 0x00, // horizontal chrominance phase offset + 0xaf, 0x00, + 0xb0, 0x00, // vertical luminance scaling increment + 0xb1, 0x04, + 0xb2, 0x00, // vertical chrominance scaling increment + 0xb3, 0x04, + 0xb4, 0x00, + 0xb5, 0x00, + 0xb6, 0x00, + 0xb7, 0x00, + 0xb8, 0x00, + 0xb9, 0x00, + 0xba, 0x00, + 0xbb, 0x00, + 0xbc, 0x00, + 0xbd, 0x00, + 0xbe, 0x00, + 0xbf, 0x00, + 0xc0, 0x02, // Task B definition + 0xc1, 0x08, + 0xc2, 0x00, + 0xc3, 0x40, + 0xc4, 0x00, // window settings + 0xc5, 0x00, + 0xc6, 0x00, + 0xc7, 0x00, + 0xc8, 0x00, + 0xc9, 0x00, + 0xca, 0x00, + 0xcb, 0x00, + 0xcc, 0x00, + 0xcd, 0x00, + 0xce, 0x00, + 0xcf, 0x00, + 0xd0, 0x01, // horizontal integer prescaling ratio + 0xd1, 0x00, // horizontal prescaler accumulation sequence length + 0xd2, 0x00, // UV FIR filter, Y FIR filter, prescaler DC gain + 0xd3, 0x00, + 0xd4, 0x80, // luminance brightness + 0xd5, 0x40, // luminance gain + 0xd6, 0x40, // chrominance saturation + 0xd7, 0x00, + 0xd8, 0x00, // horizontal luminance scaling increment + 0xd9, 0x04, + 0xda, 0x00, // horizontal luminance phase offset + 0xdb, 0x00, + 0xdc, 0x00, // horizontal chrominance scaling increment + 0xdd, 0x02, + 0xde, 0x00, // horizontal chrominance phase offset + 0xdf, 0x00, + 0xe0, 0x00, // vertical luminance scaling increment + 0xe1, 0x04, + 0xe2, 0x00, // vertical chrominance scaling increment + 0xe3, 0x04, + 0xe4, 0x00, + 0xe5, 0x00, + 0xe6, 0x00, + 0xe7, 0x00, + 0xe8, 0x00, + 0xe9, 0x00, + 0xea, 0x00, + 0xeb, 0x00, + 0xec, 0x00, + 0xed, 0x00, + 0xee, 0x00, + 0xef, 0x00 +}; + +static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + struct saa7114 *decoder = i2c_get_clientdata(client); + + switch (cmd) { + case 0: + //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client)); + //saa7114_write_block(client, init, sizeof(init)); + break; + + case DECODER_DUMP: + { + int i; + + if (!debug) + break; + v4l_info(client, "decoder dump\n"); + + for (i = 0; i < 32; i += 16) { + int j; + + v4l_info(client, "%03x", i); + for (j = 0; j < 16; ++j) { + printk(KERN_CONT " %02x", + saa7114_read(client, i + j)); + } + printk(KERN_CONT "\n"); + } + break; + } + + case DECODER_GET_CAPABILITIES: + { + struct video_decoder_capability *cap = arg; + + v4l_dbg(1, debug, client, "get capabilities\n"); + + cap->flags = VIDEO_DECODER_PAL | + VIDEO_DECODER_NTSC | + VIDEO_DECODER_AUTO | + VIDEO_DECODER_CCIR; + cap->inputs = 8; + cap->outputs = 1; + break; + } + + case DECODER_GET_STATUS: + { + int *iarg = arg; + int status; + int res; + + status = saa7114_read(client, 0x1f); + + v4l_dbg(1, debug, client, "status: 0x%02x\n", status); + res = 0; + if ((status & (1 << 6)) == 0) { + res |= DECODER_STATUS_GOOD; + } + switch (decoder->norm) { + case VIDEO_MODE_NTSC: + res |= DECODER_STATUS_NTSC; + break; + case VIDEO_MODE_PAL: + res |= DECODER_STATUS_PAL; + break; + case VIDEO_MODE_SECAM: + res |= DECODER_STATUS_SECAM; + break; + default: + case VIDEO_MODE_AUTO: + if ((status & (1 << 5)) != 0) { + res |= DECODER_STATUS_NTSC; + } else { + res |= DECODER_STATUS_PAL; + } + break; + } + if ((status & (1 << 0)) != 0) { + res |= DECODER_STATUS_COLOR; + } + *iarg = res; + break; + } + + case DECODER_SET_NORM: + { + int *iarg = arg; + + short int hoff = 0, voff = 0, w = 0, h = 0; + + v4l_dbg(1, debug, client, "set norm\n"); + + switch (*iarg) { + case VIDEO_MODE_NTSC: + v4l_dbg(1, debug, client, "NTSC\n"); + decoder->reg[REG_ADDR(0x06)] = + SAA_7114_NTSC_HSYNC_START; + decoder->reg[REG_ADDR(0x07)] = + SAA_7114_NTSC_HSYNC_STOP; + + decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture + + decoder->reg[REG_ADDR(0x0e)] = 0x85; + decoder->reg[REG_ADDR(0x0f)] = 0x24; + + hoff = SAA_7114_NTSC_HOFFSET; + voff = SAA_7114_NTSC_VOFFSET; + w = SAA_7114_NTSC_WIDTH; + h = SAA_7114_NTSC_HEIGHT; + + break; + + case VIDEO_MODE_PAL: + v4l_dbg(1, debug, client, "PAL\n"); + decoder->reg[REG_ADDR(0x06)] = + SAA_7114_PAL_HSYNC_START; + decoder->reg[REG_ADDR(0x07)] = + SAA_7114_PAL_HSYNC_STOP; + + decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture + + decoder->reg[REG_ADDR(0x0e)] = 0x81; + decoder->reg[REG_ADDR(0x0f)] = 0x24; + + hoff = SAA_7114_PAL_HOFFSET; + voff = SAA_7114_PAL_VOFFSET; + w = SAA_7114_PAL_WIDTH; + h = SAA_7114_PAL_HEIGHT; + + break; + + default: + v4l_dbg(1, debug, client, "Unknown video mode\n"); + return -EINVAL; + } + + + decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low + decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high + decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low + decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high + decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low + decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high + decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low + decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high + decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low + decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high + decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low + decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high + + decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low + decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high + decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low + decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high + decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low + decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high + decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low + decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high + decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low + decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high + decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low + decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high + + + saa7114_write(client, 0x80, 0x06); // i-port and scaler back end clock selection, task A&B off + saa7114_write(client, 0x88, 0xd8); // sw reset scaler + saa7114_write(client, 0x88, 0xf8); // sw reset scaler release + + saa7114_write_block(client, decoder->reg + (0x06 << 1), + 3 << 1); + saa7114_write_block(client, decoder->reg + (0x0e << 1), + 2 << 1); + saa7114_write_block(client, decoder->reg + (0x5a << 1), + 2 << 1); + + saa7114_write_block(client, decoder->reg + (0x94 << 1), + (0x9f + 1 - 0x94) << 1); + saa7114_write_block(client, decoder->reg + (0xc4 << 1), + (0xcf + 1 - 0xc4) << 1); + + saa7114_write(client, 0x88, 0xd8); // sw reset scaler + saa7114_write(client, 0x88, 0xf8); // sw reset scaler release + saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection + + decoder->norm = *iarg; + break; + } + + case DECODER_SET_INPUT: + { + int *iarg = arg; + + v4l_dbg(1, debug, client, "set input (%d)\n", *iarg); + if (*iarg < 0 || *iarg > 7) { + return -EINVAL; + } + + if (decoder->input != *iarg) { + v4l_dbg(1, debug, client, "now setting %s input\n", + *iarg >= 6 ? "S-Video" : "Composite"); + decoder->input = *iarg; + + /* select mode */ + decoder->reg[REG_ADDR(0x02)] = + (decoder-> + reg[REG_ADDR(0x02)] & 0xf0) | (decoder-> + input < + 6 ? 0x0 : 0x9); + saa7114_write(client, 0x02, + decoder->reg[REG_ADDR(0x02)]); + + /* bypass chrominance trap for modes 6..9 */ + decoder->reg[REG_ADDR(0x09)] = + (decoder-> + reg[REG_ADDR(0x09)] & 0x7f) | (decoder-> + input < + 6 ? 0x0 : + 0x80); + saa7114_write(client, 0x09, + decoder->reg[REG_ADDR(0x09)]); + + decoder->reg[REG_ADDR(0x0e)] = + decoder->input < + 6 ? decoder-> + reg[REG_ADDR(0x0e)] | 1 : decoder-> + reg[REG_ADDR(0x0e)] & ~1; + saa7114_write(client, 0x0e, + decoder->reg[REG_ADDR(0x0e)]); + } + break; + } + + case DECODER_SET_OUTPUT: + { + int *iarg = arg; + + v4l_dbg(1, debug, client, "set output\n"); + + /* not much choice of outputs */ + if (*iarg != 0) { + return -EINVAL; + } + break; + } + + case DECODER_ENABLE_OUTPUT: + { + int *iarg = arg; + int enable = (*iarg != 0); + + v4l_dbg(1, debug, client, "%s output\n", + enable ? "enable" : "disable"); + + decoder->playback = !enable; + + if (decoder->enable != enable) { + decoder->enable = enable; + + /* RJ: If output should be disabled (for + * playing videos), we also need a open PLL. + * The input is set to 0 (where no input + * source is connected), although this + * is not necessary. + * + * If output should be enabled, we have to + * reverse the above. + */ + + if (decoder->enable) { + decoder->reg[REG_ADDR(0x08)] = 0xb8; + decoder->reg[REG_ADDR(0x12)] = 0xc9; + decoder->reg[REG_ADDR(0x13)] = 0x80; + decoder->reg[REG_ADDR(0x87)] = 0x01; + } else { + decoder->reg[REG_ADDR(0x08)] = 0x7c; + decoder->reg[REG_ADDR(0x12)] = 0x00; + decoder->reg[REG_ADDR(0x13)] = 0x00; + decoder->reg[REG_ADDR(0x87)] = 0x00; + } + + saa7114_write_block(client, + decoder->reg + (0x12 << 1), + 2 << 1); + saa7114_write(client, 0x08, + decoder->reg[REG_ADDR(0x08)]); + saa7114_write(client, 0x87, + decoder->reg[REG_ADDR(0x87)]); + saa7114_write(client, 0x88, 0xd8); // sw reset scaler + saa7114_write(client, 0x88, 0xf8); // sw reset scaler release + saa7114_write(client, 0x80, 0x36); + + } + break; + } + + case DECODER_SET_PICTURE: + { + struct video_picture *pic = arg; + + v4l_dbg(1, debug, client, + "decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n", + pic->brightness, pic->contrast, pic->colour, pic->hue); + + if (decoder->bright != pic->brightness) { + /* We want 0 to 255 we get 0-65535 */ + decoder->bright = pic->brightness; + saa7114_write(client, 0x0a, decoder->bright >> 8); + } + if (decoder->contrast != pic->contrast) { + /* We want 0 to 127 we get 0-65535 */ + decoder->contrast = pic->contrast; + saa7114_write(client, 0x0b, + decoder->contrast >> 9); + } + if (decoder->sat != pic->colour) { + /* We want 0 to 127 we get 0-65535 */ + decoder->sat = pic->colour; + saa7114_write(client, 0x0c, decoder->sat >> 9); + } + if (decoder->hue != pic->hue) { + /* We want -128 to 127 we get 0-65535 */ + decoder->hue = pic->hue; + saa7114_write(client, 0x0d, + (decoder->hue - 32768) >> 8); + } + break; + } + + default: + return -EINVAL; + } + + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; + +static int saa7114_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int i, err[30]; + short int hoff = SAA_7114_NTSC_HOFFSET; + short int voff = SAA_7114_NTSC_VOFFSET; + short int w = SAA_7114_NTSC_WIDTH; + short int h = SAA_7114_NTSC_HEIGHT; + struct saa7114 *decoder; + + /* Check if the adapter supports the needed features */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); + + decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL); + if (decoder == NULL) + return -ENOMEM; + decoder->norm = VIDEO_MODE_NTSC; + decoder->input = -1; + decoder->enable = 1; + decoder->bright = 32768; + decoder->contrast = 32768; + decoder->hue = 32768; + decoder->sat = 32768; + decoder->playback = 0; // initially capture mode useda + i2c_set_clientdata(client, decoder); + + memcpy(decoder->reg, init, sizeof(init)); + + decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low + decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high + decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low + decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high + decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low + decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high + decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low + decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high + decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low + decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high + decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low + decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high + + decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low + decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high + decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low + decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high + decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low + decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high + decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low + decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high + decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low + decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high + decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low + decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high + + decoder->reg[REG_ADDR(0xb8)] = + LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); + decoder->reg[REG_ADDR(0xb9)] = + HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); + decoder->reg[REG_ADDR(0xba)] = + LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); + decoder->reg[REG_ADDR(0xbb)] = + HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); + + decoder->reg[REG_ADDR(0xbc)] = + LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); + decoder->reg[REG_ADDR(0xbd)] = + HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); + decoder->reg[REG_ADDR(0xbe)] = + LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); + decoder->reg[REG_ADDR(0xbf)] = + HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); + + decoder->reg[REG_ADDR(0xe8)] = + LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); + decoder->reg[REG_ADDR(0xe9)] = + HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); + decoder->reg[REG_ADDR(0xea)] = + LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); + decoder->reg[REG_ADDR(0xeb)] = + HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); + + decoder->reg[REG_ADDR(0xec)] = + LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); + decoder->reg[REG_ADDR(0xed)] = + HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); + decoder->reg[REG_ADDR(0xee)] = + LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); + decoder->reg[REG_ADDR(0xef)] = + HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); + + + decoder->reg[REG_ADDR(0x13)] = 0x80; // RTC0 on + decoder->reg[REG_ADDR(0x87)] = 0x01; // I-Port + decoder->reg[REG_ADDR(0x12)] = 0xc9; // RTS0 + + decoder->reg[REG_ADDR(0x02)] = 0xc0; // set composite1 input, aveasy + decoder->reg[REG_ADDR(0x09)] = 0x00; // chrominance trap + decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on + + + v4l_dbg(1, debug, client, "starting init\n"); + + err[0] = + saa7114_write_block(client, decoder->reg + (0x20 << 1), + 0x10 << 1); + err[1] = + saa7114_write_block(client, decoder->reg + (0x30 << 1), + 0x10 << 1); + err[2] = + saa7114_write_block(client, decoder->reg + (0x63 << 1), + (0x7f + 1 - 0x63) << 1); + err[3] = + saa7114_write_block(client, decoder->reg + (0x89 << 1), + 6 << 1); + err[4] = + saa7114_write_block(client, decoder->reg + (0xb8 << 1), + 8 << 1); + err[5] = + saa7114_write_block(client, decoder->reg + (0xe8 << 1), + 8 << 1); + + + for (i = 0; i <= 5; i++) { + if (err[i] < 0) { + v4l_dbg(1, debug, client, + "init error %d at stage %d, leaving attach.\n", + i, err[i]); + kfree(decoder); + return -EIO; + } + } + + for (i = 6; i < 8; i++) { + v4l_dbg(1, debug, client, + "reg[0x%02x] = 0x%02x (0x%02x)\n", + i, saa7114_read(client, i), + decoder->reg[REG_ADDR(i)]); + } + + v4l_dbg(1, debug, client, + "performing decoder reset sequence\n"); + + err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off + err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler + err[8] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release + + for (i = 6; i <= 8; i++) { + if (err[i] < 0) { + v4l_dbg(1, debug, client, + "init error %d at stage %d, leaving attach.\n", + i, err[i]); + kfree(decoder); + return -EIO; + } + } + + v4l_dbg(1, debug, client, "performing the rest of init\n"); + + err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]); + err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq + err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1); // slicer + err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1); // ? + err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1); // ? + err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1); // Task A + err[15] = + saa7114_write_block(client, decoder->reg + (0x94 << 1), + 12 << 1); + err[16] = + saa7114_write_block(client, decoder->reg + (0xa0 << 1), + 8 << 1); + err[17] = + saa7114_write_block(client, decoder->reg + (0xa8 << 1), + 8 << 1); + err[18] = + saa7114_write_block(client, decoder->reg + (0xb0 << 1), + 8 << 1); + err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1); // Task B + err[15] = + saa7114_write_block(client, decoder->reg + (0xc4 << 1), + 12 << 1); + err[16] = + saa7114_write_block(client, decoder->reg + (0xd0 << 1), + 8 << 1); + err[17] = + saa7114_write_block(client, decoder->reg + (0xd8 << 1), + 8 << 1); + err[18] = + saa7114_write_block(client, decoder->reg + (0xe0 << 1), + 8 << 1); + + for (i = 9; i <= 18; i++) { + if (err[i] < 0) { + v4l_dbg(1, debug, client, + "init error %d at stage %d, leaving attach.\n", + i, err[i]); + kfree(decoder); + return -EIO; + } + } + + + for (i = 6; i < 8; i++) { + v4l_dbg(1, debug, client, + "reg[0x%02x] = 0x%02x (0x%02x)\n", + i, saa7114_read(client, i), + decoder->reg[REG_ADDR(i)]); + } + + + for (i = 0x11; i <= 0x13; i++) { + v4l_dbg(1, debug, client, + "reg[0x%02x] = 0x%02x (0x%02x)\n", + i, saa7114_read(client, i), + decoder->reg[REG_ADDR(i)]); + } + + + v4l_dbg(1, debug, client, "setting video input\n"); + + err[19] = + saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]); + err[20] = + saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]); + err[21] = + saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]); + + for (i = 19; i <= 21; i++) { + if (err[i] < 0) { + v4l_dbg(1, debug, client, + "init error %d at stage %d, leaving attach.\n", + i, err[i]); + kfree(decoder); + return -EIO; + } + } + + v4l_dbg(1, debug, client, "performing decoder reset sequence\n"); + + err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler + err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release + err[24] = saa7114_write(client, 0x80, 0x36); // i-port and scaler backend clock selection, task A&B off + + + for (i = 22; i <= 24; i++) { + if (err[i] < 0) { + v4l_dbg(1, debug, client, + "init error %d at stage %d, leaving attach.\n", + i, err[i]); + kfree(decoder); + return -EIO; + } + } + + err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]); + err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]); + err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]); + + v4l_dbg(1, debug, client, "chip version %x, decoder status 0x%02x\n", + saa7114_read(client, 0x00) >> 4, + saa7114_read(client, 0x1f)); + v4l_dbg(1, debug, client, + "power save control: 0x%02x, scaler status: 0x%02x\n", + saa7114_read(client, 0x88), + saa7114_read(client, 0x8f)); + + + for (i = 0x94; i < 0x96; i++) { + v4l_dbg(1, debug, client, + "reg[0x%02x] = 0x%02x (0x%02x)\n", + i, saa7114_read(client, i), + decoder->reg[REG_ADDR(i)]); + } + + //i = saa7114_write_block(client, init, sizeof(init)); + return 0; +} + +static int saa7114_remove(struct i2c_client *client) +{ + kfree(i2c_get_clientdata(client)); + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static const struct i2c_device_id saa7114_id[] = { + { "saa7114_old", 0 }, /* "saa7114" maps to the saa7115 driver */ + { } +}; +MODULE_DEVICE_TABLE(i2c, saa7114_id); + +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "saa7114", + .driverid = I2C_DRIVERID_SAA7114, + .command = saa7114_command, + .probe = saa7114_probe, + .remove = saa7114_remove, + .id_table = saa7114_id, +}; diff --git a/trunk/drivers/media/video/saa7115.c b/trunk/drivers/media/video/saa7115.c index cebf159f52cf..46c796c3fec8 100644 --- a/trunk/drivers/media/video/saa7115.c +++ b/trunk/drivers/media/video/saa7115.c @@ -778,7 +778,7 @@ static int saa711x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) break; case V4L2_CID_HUE: - if (ctrl->value < -128 || ctrl->value > 127) { + if (ctrl->value < -127 || ctrl->value > 127) { v4l2_err(sd, "invalid hue setting %d\n", ctrl->value); return -ERANGE; } @@ -931,8 +931,8 @@ static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std) /* Prevent unnecessary standard changes. During a standard change the I-Port is temporarily disabled. Any devices reading from that port can get confused. - Note that s_std is also used to switch from - radio to TV mode, so if a s_std is broadcast to + Note that VIDIOC_S_STD is also used to switch from + radio to TV mode, so if a VIDIOC_S_STD is broadcast to all I2C devices then you do not want to have an unwanted side-effect here. */ if (std == state->std) @@ -1206,12 +1206,10 @@ static int saa711x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) { switch (qc->id) { case V4L2_CID_BRIGHTNESS: - return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); case V4L2_CID_CONTRAST: case V4L2_CID_SATURATION: - return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64); case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); + return v4l2_ctrl_query_fill_std(qc); default: return -EINVAL; } @@ -1310,12 +1308,11 @@ static int saa711x_s_stream(struct v4l2_subdev *sd, int enable) v4l2_dbg(1, debug, sd, "%s output\n", enable ? "enable" : "disable"); - if (state->enable == enable) - return 0; - state->enable = enable; - if (!saa711x_has_reg(state->ident, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED)) - return 0; - saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, state->enable); + if (state->enable != enable) { + state->enable = enable; + saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, + state->enable); + } return 0; } @@ -1373,47 +1370,6 @@ static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_dat } } -static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) -{ - struct saa711x_state *state = to_state(sd); - int reg1e; - - *std = V4L2_STD_ALL; - if (state->ident != V4L2_IDENT_SAA7115) - return 0; - reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC); - - switch (reg1e & 0x03) { - case 1: - *std = V4L2_STD_NTSC; - break; - case 2: - *std = V4L2_STD_PAL; - break; - case 3: - *std = V4L2_STD_SECAM; - break; - default: - break; - } - return 0; -} - -static int saa711x_g_input_status(struct v4l2_subdev *sd, u32 *status) -{ - struct saa711x_state *state = to_state(sd); - int reg1e = 0x80; - int reg1f; - - *status = V4L2_IN_ST_NO_SIGNAL; - if (state->ident == V4L2_IDENT_SAA7115) - reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC); - reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC); - if ((reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80) - *status = 0; - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { @@ -1537,8 +1493,6 @@ static const struct v4l2_subdev_video_ops saa711x_video_ops = { .g_vbi_data = saa711x_g_vbi_data, .decode_vbi_line = saa711x_decode_vbi_line, .s_stream = saa711x_s_stream, - .querystd = saa711x_querystd, - .g_input_status = saa711x_g_input_status, }; static const struct v4l2_subdev_ops saa711x_ops = { diff --git a/trunk/drivers/media/video/saa7127.c b/trunk/drivers/media/video/saa7127.c index 128bb8b8dbbf..05221d47dd4c 100644 --- a/trunk/drivers/media/video/saa7127.c +++ b/trunk/drivers/media/video/saa7127.c @@ -810,6 +810,7 @@ MODULE_DEVICE_TABLE(i2c, saa7127_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa7127", + .driverid = I2C_DRIVERID_SAA7127, .probe = saa7127_probe, .remove = saa7127_remove, .id_table = saa7127_id, diff --git a/trunk/drivers/media/video/saa7134/Kconfig b/trunk/drivers/media/video/saa7134/Kconfig index 0ba68987bfce..fc2164e28e76 100644 --- a/trunk/drivers/media/video/saa7134/Kconfig +++ b/trunk/drivers/media/video/saa7134/Kconfig @@ -6,7 +6,6 @@ config VIDEO_SAA7134 select VIDEO_TUNER select VIDEO_TVEEPROM select CRC32 - select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO ---help--- This is a video4linux driver for Philips SAA713x based TV cards. @@ -36,16 +35,8 @@ config VIDEO_SAA7134_DVB select DVB_TDA10086 if !DVB_FE_CUSTOMISE select DVB_TDA826X if !DVB_FE_CUSTOMISE select DVB_ISL6421 if !DVB_FE_CUSTOMISE - select DVB_ISL6405 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE - select DVB_ZL10036 if !DVB_FE_CUSTOMISE - select DVB_MT312 if !DVB_FE_CUSTOMISE - select DVB_LNBP21 if !DVB_FE_CUSTOMISE - select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select DVB_LGDT3305 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE ---help--- This adds support for DVB cards based on the Philips saa7134 chip. diff --git a/trunk/drivers/media/video/saa7134/saa6752hs.c b/trunk/drivers/media/video/saa7134/saa6752hs.c index dc2213e2f86e..1fee6e84a512 100644 --- a/trunk/drivers/media/video/saa7134/saa6752hs.c +++ b/trunk/drivers/media/video/saa7134/saa6752hs.c @@ -33,10 +33,9 @@ #include #include #include -#include #include #include -#include +#include #include #include @@ -45,6 +44,10 @@ #define MPEG_TOTAL_TARGET_BITRATE_MAX 27000 #define MPEG_PID_MAX ((1 << 14) - 1) +/* Addresses to scan */ +static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END}; + +I2C_CLIENT_INSMOD; MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder"); MODULE_AUTHOR("Andrew de Quincey"); @@ -92,7 +95,6 @@ static const struct v4l2_format v4l2_format_table[] = }; struct saa6752hs_state { - struct v4l2_subdev sd; int chip; u32 revision; int has_ac3; @@ -113,11 +115,6 @@ enum saa6752hs_command { SAA6752HS_COMMAND_MAX }; -static inline struct saa6752hs_state *to_state(struct v4l2_subdev *sd) -{ - return container_of(sd, struct saa6752hs_state, sd); -} - /* ---------------------------------------------------------------------- */ static u8 PAT[] = { @@ -363,191 +360,185 @@ static int saa6752hs_set_bitrate(struct i2c_client *client, return 0; } - -static int get_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params, - struct v4l2_ext_control *ctrl) +static void saa6752hs_set_subsampling(struct i2c_client *client, + struct v4l2_format *f) { - switch (ctrl->id) { - case V4L2_CID_MPEG_STREAM_TYPE: - ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS; - break; - case V4L2_CID_MPEG_STREAM_PID_PMT: - ctrl->value = params->ts_pid_pmt; - break; - case V4L2_CID_MPEG_STREAM_PID_AUDIO: - ctrl->value = params->ts_pid_audio; - break; - case V4L2_CID_MPEG_STREAM_PID_VIDEO: - ctrl->value = params->ts_pid_video; - break; - case V4L2_CID_MPEG_STREAM_PID_PCR: - ctrl->value = params->ts_pid_pcr; - break; - case V4L2_CID_MPEG_AUDIO_ENCODING: - ctrl->value = params->au_encoding; - break; - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: - ctrl->value = params->au_l2_bitrate; - break; - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: - if (!has_ac3) - return -EINVAL; - ctrl->value = params->au_ac3_bitrate; - break; - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: - ctrl->value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; - break; - case V4L2_CID_MPEG_VIDEO_ENCODING: - ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2; - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - ctrl->value = params->vi_aspect; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE: - ctrl->value = params->vi_bitrate * 1000; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - ctrl->value = params->vi_bitrate_peak * 1000; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - ctrl->value = params->vi_bitrate_mode; - break; - default: - return -EINVAL; + struct saa6752hs_state *h = i2c_get_clientdata(client); + int dist_352, dist_480, dist_720; + + /* + FIXME: translate and round width/height into EMPRESS + subsample type: + + type | PAL | NTSC + --------------------------- + SIF | 352x288 | 352x240 + 1/2 D1 | 352x576 | 352x480 + 2/3 D1 | 480x576 | 480x480 + D1 | 720x576 | 720x480 + */ + + dist_352 = abs(f->fmt.pix.width - 352); + dist_480 = abs(f->fmt.pix.width - 480); + dist_720 = abs(f->fmt.pix.width - 720); + if (dist_720 < dist_480) { + f->fmt.pix.width = 720; + f->fmt.pix.height = 576; + h->video_format = SAA6752HS_VF_D1; + } + else if (dist_480 < dist_352) { + f->fmt.pix.width = 480; + f->fmt.pix.height = 576; + h->video_format = SAA6752HS_VF_2_3_D1; + } + else { + f->fmt.pix.width = 352; + if (abs(f->fmt.pix.height - 576) < + abs(f->fmt.pix.height - 288)) { + f->fmt.pix.height = 576; + h->video_format = SAA6752HS_VF_1_2_D1; + } + else { + f->fmt.pix.height = 288; + h->video_format = SAA6752HS_VF_SIF; + } } - return 0; } + static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params, - struct v4l2_ext_control *ctrl, int set) + struct v4l2_ext_control *ctrl, unsigned int cmd) { int old = 0, new; + int set = (cmd == VIDIOC_S_EXT_CTRLS); new = ctrl->value; switch (ctrl->id) { - case V4L2_CID_MPEG_STREAM_TYPE: - old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS; - if (set && new != old) - return -ERANGE; - new = old; - break; - case V4L2_CID_MPEG_STREAM_PID_PMT: - old = params->ts_pid_pmt; - if (set && new > MPEG_PID_MAX) - return -ERANGE; - if (new > MPEG_PID_MAX) - new = MPEG_PID_MAX; - params->ts_pid_pmt = new; - break; - case V4L2_CID_MPEG_STREAM_PID_AUDIO: - old = params->ts_pid_audio; - if (set && new > MPEG_PID_MAX) - return -ERANGE; - if (new > MPEG_PID_MAX) - new = MPEG_PID_MAX; - params->ts_pid_audio = new; - break; - case V4L2_CID_MPEG_STREAM_PID_VIDEO: - old = params->ts_pid_video; - if (set && new > MPEG_PID_MAX) - return -ERANGE; - if (new > MPEG_PID_MAX) - new = MPEG_PID_MAX; - params->ts_pid_video = new; - break; - case V4L2_CID_MPEG_STREAM_PID_PCR: - old = params->ts_pid_pcr; - if (set && new > MPEG_PID_MAX) - return -ERANGE; - if (new > MPEG_PID_MAX) - new = MPEG_PID_MAX; - params->ts_pid_pcr = new; - break; - case V4L2_CID_MPEG_AUDIO_ENCODING: - old = params->au_encoding; - if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 && - (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3)) - return -ERANGE; - new = old; - break; - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: - old = params->au_l2_bitrate; - if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K && - new != V4L2_MPEG_AUDIO_L2_BITRATE_384K) - return -ERANGE; - if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K) - new = V4L2_MPEG_AUDIO_L2_BITRATE_256K; - else - new = V4L2_MPEG_AUDIO_L2_BITRATE_384K; - params->au_l2_bitrate = new; - break; - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: - if (!has_ac3) + case V4L2_CID_MPEG_STREAM_TYPE: + old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS; + if (set && new != old) + return -ERANGE; + new = old; + break; + case V4L2_CID_MPEG_STREAM_PID_PMT: + old = params->ts_pid_pmt; + if (set && new > MPEG_PID_MAX) + return -ERANGE; + if (new > MPEG_PID_MAX) + new = MPEG_PID_MAX; + params->ts_pid_pmt = new; + break; + case V4L2_CID_MPEG_STREAM_PID_AUDIO: + old = params->ts_pid_audio; + if (set && new > MPEG_PID_MAX) + return -ERANGE; + if (new > MPEG_PID_MAX) + new = MPEG_PID_MAX; + params->ts_pid_audio = new; + break; + case V4L2_CID_MPEG_STREAM_PID_VIDEO: + old = params->ts_pid_video; + if (set && new > MPEG_PID_MAX) + return -ERANGE; + if (new > MPEG_PID_MAX) + new = MPEG_PID_MAX; + params->ts_pid_video = new; + break; + case V4L2_CID_MPEG_STREAM_PID_PCR: + old = params->ts_pid_pcr; + if (set && new > MPEG_PID_MAX) + return -ERANGE; + if (new > MPEG_PID_MAX) + new = MPEG_PID_MAX; + params->ts_pid_pcr = new; + break; + case V4L2_CID_MPEG_AUDIO_ENCODING: + old = params->au_encoding; + if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 && + (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3)) + return -ERANGE; + new = old; + break; + case V4L2_CID_MPEG_AUDIO_L2_BITRATE: + old = params->au_l2_bitrate; + if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K && + new != V4L2_MPEG_AUDIO_L2_BITRATE_384K) + return -ERANGE; + if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K) + new = V4L2_MPEG_AUDIO_L2_BITRATE_256K; + else + new = V4L2_MPEG_AUDIO_L2_BITRATE_384K; + params->au_l2_bitrate = new; + break; + case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: + if (!has_ac3) + return -EINVAL; + old = params->au_ac3_bitrate; + if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K && + new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K) + return -ERANGE; + if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K) + new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K; + else + new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K; + params->au_ac3_bitrate = new; + break; + case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: + old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; + if (set && new != old) + return -ERANGE; + new = old; + break; + case V4L2_CID_MPEG_VIDEO_ENCODING: + old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2; + if (set && new != old) + return -ERANGE; + new = old; + break; + case V4L2_CID_MPEG_VIDEO_ASPECT: + old = params->vi_aspect; + if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 && + new != V4L2_MPEG_VIDEO_ASPECT_4x3) + return -ERANGE; + if (new != V4L2_MPEG_VIDEO_ASPECT_16x9) + new = V4L2_MPEG_VIDEO_ASPECT_4x3; + params->vi_aspect = new; + break; + case V4L2_CID_MPEG_VIDEO_BITRATE: + old = params->vi_bitrate * 1000; + new = 1000 * (new / 1000); + if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) + return -ERANGE; + if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) + new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000; + params->vi_bitrate = new / 1000; + break; + case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: + old = params->vi_bitrate_peak * 1000; + new = 1000 * (new / 1000); + if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) + return -ERANGE; + if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) + new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000; + params->vi_bitrate_peak = new / 1000; + break; + case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: + old = params->vi_bitrate_mode; + params->vi_bitrate_mode = new; + break; + default: return -EINVAL; - old = params->au_ac3_bitrate; - if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K && - new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K) - return -ERANGE; - if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K) - new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K; - else - new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K; - params->au_ac3_bitrate = new; - break; - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: - old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; - if (set && new != old) - return -ERANGE; - new = old; - break; - case V4L2_CID_MPEG_VIDEO_ENCODING: - old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2; - if (set && new != old) - return -ERANGE; - new = old; - break; - case V4L2_CID_MPEG_VIDEO_ASPECT: - old = params->vi_aspect; - if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 && - new != V4L2_MPEG_VIDEO_ASPECT_4x3) - return -ERANGE; - if (new != V4L2_MPEG_VIDEO_ASPECT_16x9) - new = V4L2_MPEG_VIDEO_ASPECT_4x3; - params->vi_aspect = new; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE: - old = params->vi_bitrate * 1000; - new = 1000 * (new / 1000); - if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) - return -ERANGE; - if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) - new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000; - params->vi_bitrate = new / 1000; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - old = params->vi_bitrate_peak * 1000; - new = 1000 * (new / 1000); - if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) - return -ERANGE; - if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000) - new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000; - params->vi_bitrate_peak = new / 1000; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - old = params->vi_bitrate_mode; - params->vi_bitrate_mode = new; - break; - default: - return -EINVAL; } - ctrl->value = new; + if (cmd == VIDIOC_G_EXT_CTRLS) + ctrl->value = old; + else + ctrl->value = new; return 0; } - -static int saa6752hs_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl) +static int saa6752hs_qctrl(struct saa6752hs_state *h, + struct v4l2_queryctrl *qctrl) { - struct saa6752hs_state *h = to_state(sd); struct saa6752hs_mpeg_params *params = &h->params; int err; @@ -592,7 +583,7 @@ static int saa6752hs_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc V4L2_MPEG_VIDEO_ASPECT_4x3); case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: - err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000); + err = v4l2_ctrl_query_fill_std(qctrl); if (err == 0 && params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) @@ -606,20 +597,12 @@ static int saa6752hs_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc V4L2_MPEG_STREAM_TYPE_MPEG2_TS); case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - return v4l2_ctrl_query_fill(qctrl, - V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1, - V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); case V4L2_CID_MPEG_VIDEO_BITRATE: - return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000); case V4L2_CID_MPEG_STREAM_PID_PMT: - return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16); case V4L2_CID_MPEG_STREAM_PID_AUDIO: - return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260); case V4L2_CID_MPEG_STREAM_PID_VIDEO: - return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256); case V4L2_CID_MPEG_STREAM_PID_PCR: - return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259); + return v4l2_ctrl_query_fill_std(qctrl); default: break; @@ -627,7 +610,8 @@ static int saa6752hs_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc return -EINVAL; } -static int saa6752hs_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qmenu) +static int saa6752hs_qmenu(struct saa6752hs_state *h, + struct v4l2_querymenu *qmenu) { static const u32 mpeg_audio_encoding[] = { V4L2_MPEG_AUDIO_ENCODING_LAYER_2, @@ -648,12 +632,11 @@ static int saa6752hs_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qm V4L2_MPEG_AUDIO_AC3_BITRATE_384K, V4L2_CTRL_MENU_IDS_END }; - struct saa6752hs_state *h = to_state(sd); struct v4l2_queryctrl qctrl; int err; qctrl.id = qmenu->id; - err = saa6752hs_queryctrl(sd, &qctrl); + err = saa6752hs_qctrl(h, &qctrl); if (err) return err; switch (qmenu->id) { @@ -673,16 +656,17 @@ static int saa6752hs_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qm return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL); } -static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes) +static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes) { unsigned char buf[9], buf2[4]; - struct saa6752hs_state *h = to_state(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct saa6752hs_state *h; unsigned size; u32 crc; unsigned char localPAT[256]; unsigned char localPMT[256]; + h = i2c_get_clientdata(client); + /* Set video format - must be done first as it resets other settings */ set_reg8(client, 0x41, h->video_format); @@ -778,7 +762,7 @@ static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes) buf[3] = 0x82; buf[4] = 0xB0; buf[5] = buf2[0]; - switch (h->params.vi_aspect) { + switch(h->params.vi_aspect) { case V4L2_MPEG_VIDEO_ASPECT_16x9: buf[6] = buf2[1] | 0x40; break; @@ -786,6 +770,7 @@ static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes) default: buf[6] = buf2[1] & 0xBF; break; + break; } buf[7] = buf2[2]; buf[8] = buf2[3]; @@ -794,162 +779,81 @@ static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes) return 0; } -static int saa6752hs_do_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls, int set) +static int +saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) { - struct saa6752hs_state *h = to_state(sd); + struct saa6752hs_state *h = i2c_get_clientdata(client); + struct v4l2_ext_controls *ctrls = arg; struct saa6752hs_mpeg_params params; + int err = 0; int i; - if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - - params = h->params; - for (i = 0; i < ctrls->count; i++) { - int err = handle_ctrl(h->has_ac3, ¶ms, ctrls->controls + i, set); - - if (err) { - ctrls->error_idx = i; - return err; + switch (cmd) { + case VIDIOC_INT_INIT: + /* apply settings and start encoder */ + saa6752hs_init(client, *(u32 *)arg); + break; + case VIDIOC_S_EXT_CTRLS: + if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) + return -EINVAL; + /* fall through */ + case VIDIOC_TRY_EXT_CTRLS: + case VIDIOC_G_EXT_CTRLS: + if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) + return -EINVAL; + params = h->params; + for (i = 0; i < ctrls->count; i++) { + err = handle_ctrl(h->has_ac3, ¶ms, ctrls->controls + i, cmd); + if (err) { + ctrls->error_idx = i; + return err; + } } - } - if (set) h->params = params; - return 0; -} - -static int saa6752hs_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls) -{ - return saa6752hs_do_ext_ctrls(sd, ctrls, 1); -} - -static int saa6752hs_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls) -{ - return saa6752hs_do_ext_ctrls(sd, ctrls, 0); -} - -static int saa6752hs_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls) -{ - struct saa6752hs_state *h = to_state(sd); - int i; - - if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - - for (i = 0; i < ctrls->count; i++) { - int err = get_ctrl(h->has_ac3, &h->params, ctrls->controls + i); - - if (err) { - ctrls->error_idx = i; - return err; - } + break; + case VIDIOC_QUERYCTRL: + return saa6752hs_qctrl(h, arg); + case VIDIOC_QUERYMENU: + return saa6752hs_qmenu(h, arg); + case VIDIOC_G_FMT: + { + struct v4l2_format *f = arg; + + if (h->video_format == SAA6752HS_VF_UNKNOWN) + h->video_format = SAA6752HS_VF_D1; + f->fmt.pix.width = + v4l2_format_table[h->video_format].fmt.pix.width; + f->fmt.pix.height = + v4l2_format_table[h->video_format].fmt.pix.height; + break ; } - return 0; -} - -static int saa6752hs_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) -{ - struct saa6752hs_state *h = to_state(sd); - - if (h->video_format == SAA6752HS_VF_UNKNOWN) - h->video_format = SAA6752HS_VF_D1; - f->fmt.pix.width = - v4l2_format_table[h->video_format].fmt.pix.width; - f->fmt.pix.height = - v4l2_format_table[h->video_format].fmt.pix.height; - return 0; -} - -static int saa6752hs_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) -{ - struct saa6752hs_state *h = to_state(sd); - int dist_352, dist_480, dist_720; - - /* - FIXME: translate and round width/height into EMPRESS - subsample type: - - type | PAL | NTSC - --------------------------- - SIF | 352x288 | 352x240 - 1/2 D1 | 352x576 | 352x480 - 2/3 D1 | 480x576 | 480x480 - D1 | 720x576 | 720x480 - */ + case VIDIOC_S_FMT: + { + struct v4l2_format *f = arg; - dist_352 = abs(f->fmt.pix.width - 352); - dist_480 = abs(f->fmt.pix.width - 480); - dist_720 = abs(f->fmt.pix.width - 720); - if (dist_720 < dist_480) { - f->fmt.pix.width = 720; - f->fmt.pix.height = 576; - h->video_format = SAA6752HS_VF_D1; - } else if (dist_480 < dist_352) { - f->fmt.pix.width = 480; - f->fmt.pix.height = 576; - h->video_format = SAA6752HS_VF_2_3_D1; - } else { - f->fmt.pix.width = 352; - if (abs(f->fmt.pix.height - 576) < - abs(f->fmt.pix.height - 288)) { - f->fmt.pix.height = 576; - h->video_format = SAA6752HS_VF_1_2_D1; - } else { - f->fmt.pix.height = 288; - h->video_format = SAA6752HS_VF_SIF; - } + saa6752hs_set_subsampling(client, f); + break; } - return 0; -} - -static int saa6752hs_s_std(struct v4l2_subdev *sd, v4l2_std_id std) -{ - struct saa6752hs_state *h = to_state(sd); + case VIDIOC_S_STD: + h->standard = *((v4l2_std_id *) arg); + break; - h->standard = std; - return 0; -} + case VIDIOC_DBG_G_CHIP_IDENT: + return v4l2_chip_ident_i2c_client(client, + arg, h->chip, h->revision); -static int saa6752hs_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct saa6752hs_state *h = to_state(sd); + default: + /* nothing */ + break; + } - return v4l2_chip_ident_i2c_client(client, - chip, h->chip, h->revision); + return err; } -/* ----------------------------------------------------------------------- */ - -static const struct v4l2_subdev_core_ops saa6752hs_core_ops = { - .g_chip_ident = saa6752hs_g_chip_ident, - .init = saa6752hs_init, - .queryctrl = saa6752hs_queryctrl, - .querymenu = saa6752hs_querymenu, - .g_ext_ctrls = saa6752hs_g_ext_ctrls, - .s_ext_ctrls = saa6752hs_s_ext_ctrls, - .try_ext_ctrls = saa6752hs_try_ext_ctrls, -}; - -static const struct v4l2_subdev_tuner_ops saa6752hs_tuner_ops = { - .s_std = saa6752hs_s_std, -}; - -static const struct v4l2_subdev_video_ops saa6752hs_video_ops = { - .s_fmt = saa6752hs_s_fmt, - .g_fmt = saa6752hs_g_fmt, -}; - -static const struct v4l2_subdev_ops saa6752hs_ops = { - .core = &saa6752hs_core_ops, - .tuner = &saa6752hs_tuner_ops, - .video = &saa6752hs_video_ops, -}; - static int saa6752hs_probe(struct i2c_client *client, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL); - struct v4l2_subdev *sd; u8 addr = 0x13; u8 data[12]; @@ -957,8 +861,6 @@ static int saa6752hs_probe(struct i2c_client *client, client->addr << 1, client->adapter->name); if (h == NULL) return -ENOMEM; - sd = &h->sd; - v4l2_i2c_subdev_init(sd, client, &saa6752hs_ops); i2c_master_send(client, &addr, 1); i2c_master_recv(client, data, sizeof(data)); @@ -972,15 +874,14 @@ static int saa6752hs_probe(struct i2c_client *client, } h->params = param_defaults; h->standard = 0; /* Assume 625 input lines */ + + i2c_set_clientdata(client, h); return 0; } static int saa6752hs_remove(struct i2c_client *client) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - - v4l2_device_unregister_subdev(sd); - kfree(to_state(sd)); + kfree(i2c_get_clientdata(client)); return 0; } @@ -992,6 +893,8 @@ MODULE_DEVICE_TABLE(i2c, saa6752hs_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa6752hs", + .driverid = I2C_DRIVERID_SAA6752HS, + .command = saa6752hs_command, .probe = saa6752hs_probe, .remove = saa6752hs_remove, .id_table = saa6752hs_id, diff --git a/trunk/drivers/media/video/saa7134/saa7134-cards.c b/trunk/drivers/media/video/saa7134/saa7134-cards.c index a790a7246a63..e2febcd6e529 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-cards.c +++ b/trunk/drivers/media/video/saa7134/saa7134-cards.c @@ -31,7 +31,6 @@ #include #include #include "tea5767.h" -#include "tda18271.h" /* commly used strings */ static char name_mute[] = "mute"; @@ -273,7 +272,6 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x20, .inputs = {{ .name = name_comp1, @@ -410,7 +408,6 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x20, .tda9887_conf = TDA9887_PRESENT, .gpiomask = 0x820000, .inputs = {{ @@ -821,7 +818,6 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x20, .inputs = {{ .name = name_comp1, .vmux = 4, @@ -981,7 +977,6 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x20, .inputs = {{ .name = name_comp1, .vmux = 1, @@ -1704,7 +1699,6 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .rds_addr = 0x10, .tda9887_conf = TDA9887_PRESENT, .inputs = {{ .name = name_tv, @@ -2370,7 +2364,6 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x21, .inputs = {{ .name = "Composite 0", .vmux = 0, @@ -3298,68 +3291,6 @@ struct saa7134_board saa7134_boards[] = { .gpio = 0x0200100, }, }, - [SAA7134_BOARD_HAUPPAUGE_HVR1120] = { - .name = "Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid", - .audio_clock = 0x00187de7, - .tuner_type = TUNER_PHILIPS_TDA8290, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tuner_config = 3, - .mpeg = SAA7134_MPEG_DVB, - .ts_type = SAA7134_MPEG_TS_SERIAL, - .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */ - .inputs = {{ - .name = name_tv, - .vmux = 1, - .amux = TV, - .tv = 1, - .gpio = 0x0000100, - }, { - .name = name_comp1, - .vmux = 3, - .amux = LINE1, - }, { - .name = name_svideo, - .vmux = 8, - .amux = LINE1, - } }, - .radio = { - .name = name_radio, - .amux = TV, - .gpio = 0x0800100, /* GPIO 23 HI for FM */ - }, - }, - [SAA7134_BOARD_HAUPPAUGE_HVR1110R3] = { - .name = "Hauppauge WinTV-HVR1110r3", - .audio_clock = 0x00187de7, - .tuner_type = TUNER_PHILIPS_TDA8290, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tuner_config = 3, - .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */ - .inputs = {{ - .name = name_tv, - .vmux = 1, - .amux = TV, - .tv = 1, - .gpio = 0x0000100, - }, { - .name = name_comp1, - .vmux = 3, - .amux = LINE1, - }, { - .name = name_svideo, - .vmux = 8, - .amux = LINE1, - } }, - .radio = { - .name = name_radio, - .amux = TV, - .gpio = 0x0800100, /* GPIO 23 HI for FM */ - }, - }, [SAA7134_BOARD_CINERGY_HT_PCMCIA] = { .name = "Terratec Cinergy HT PCMCIA", .audio_clock = 0x00187de7, @@ -4139,7 +4070,6 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x20, .tda9887_conf = TDA9887_PRESENT, .inputs = { { .name = name_tv, @@ -4176,7 +4106,6 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x20, .tda9887_conf = TDA9887_PRESENT, .inputs = { { .name = name_tv, @@ -4214,7 +4143,6 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x20, .tda9887_conf = TDA9887_PRESENT, .inputs = { { .name = name_tv, @@ -4395,13 +4323,13 @@ struct saa7134_board saa7134_boards[] = { .amux = TV, .tv = 1, }, { - .name = name_comp1, - .vmux = 3, + .name = name_comp, + .vmux = 0, .amux = LINE1, }, { .name = name_svideo, .vmux = 8, - .amux = LINE2, + .amux = LINE1, } }, .radio = { .name = name_radio, @@ -4493,7 +4421,8 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .mpeg = SAA7134_MPEG_DVB, + /* no DVB support for now */ + /* .mpeg = SAA7134_MPEG_DVB, */ .inputs = { { .name = name_comp, .vmux = 1, @@ -4512,7 +4441,8 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .mpeg = SAA7134_MPEG_DVB, + /* no DVB support for now */ + /* .mpeg = SAA7134_MPEG_DVB, */ .inputs = { { .name = name_comp, .vmux = 1, @@ -4681,7 +4611,7 @@ struct saa7134_board saa7134_boards[] = { .tuner_type = TUNER_YMEC_TVF_5533MF, .radio_type = TUNER_TEA5767, .tuner_addr = ADDR_UNSET, - .radio_addr = 0x60, + .radio_addr = ADDR_UNSET, .gpiomask = 0x80000700, .inputs = { { .name = name_tv, @@ -5472,36 +5402,6 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x0070, .subdevice = 0x6705, .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110, - },{ - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, - .subvendor = 0x0070, - .subdevice = 0x6706, - .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120, - },{ - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, - .subvendor = 0x0070, - .subdevice = 0x6707, - .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110R3, - },{ - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, - .subvendor = 0x0070, - .subdevice = 0x6708, - .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120, - },{ - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, - .subvendor = 0x0070, - .subdevice = 0x6709, - .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110R3, - },{ - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, - .subvendor = 0x0070, - .subdevice = 0x670a, - .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110R3, },{ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, @@ -5921,8 +5821,8 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev, } -static int saa7134_tda8290_827x_callback(struct saa7134_dev *dev, - int command, int arg) +static int saa7134_tda8290_callback(struct saa7134_dev *dev, + int command, int arg) { u8 sync_control; @@ -5948,65 +5848,6 @@ static int saa7134_tda8290_827x_callback(struct saa7134_dev *dev, return 0; } -static inline int saa7134_tda18271_hvr11x0_toggle_agc(struct saa7134_dev *dev, - enum tda18271_mode mode) -{ - /* toggle AGC switch through GPIO 26 */ - switch (mode) { - case TDA18271_ANALOG: - saa7134_set_gpio(dev, 26, 0); - break; - case TDA18271_DIGITAL: - saa7134_set_gpio(dev, 26, 1); - break; - default: - return -EINVAL; - } - return 0; -} - -static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev, - int command, int arg) -{ - int ret = 0; - - switch (command) { - case TDA18271_CALLBACK_CMD_AGC_ENABLE: /* 0 */ - switch (dev->board) { - case SAA7134_BOARD_HAUPPAUGE_HVR1120: - case SAA7134_BOARD_HAUPPAUGE_HVR1110R3: - ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg); - break; - default: - break; - } - break; - default: - ret = -EINVAL; - break; - } - return ret; -} - -static int saa7134_tda8290_callback(struct saa7134_dev *dev, - int command, int arg) -{ - int ret; - - switch (dev->board) { - case SAA7134_BOARD_HAUPPAUGE_HVR1120: - case SAA7134_BOARD_HAUPPAUGE_HVR1110R3: - /* tda8290 + tda18271 */ - ret = saa7134_tda8290_18271_callback(dev, command, arg); - break; - default: - /* tda8290 + tda827x */ - ret = saa7134_tda8290_827x_callback(dev, command, arg); - break; - } - return ret; -} - int saa7134_tuner_callback(void *priv, int component, int command, int arg) { struct saa7134_dev *dev = priv; @@ -6037,16 +5878,11 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data) switch (tv.model) { case 67019: /* WinTV-HVR1110 (Retail, IR Blaster, hybrid, FM, SVid/Comp, 3.5mm audio in) */ case 67109: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */ - case 67201: /* WinTV-HVR1120 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */ - case 67301: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */ - case 67209: /* WinTV-HVR1110 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */ case 67559: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */ case 67569: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM) */ case 67579: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM) */ case 67589: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */ case 67599: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */ - case 67651: /* WinTV-HVR1120 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */ - case 67659: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */ break; default: printk(KERN_WARNING "%s: warning: " @@ -6183,11 +6019,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) msleep(10); break; case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: - saa7134_set_gpio(dev, 23, 0); - msleep(10); - saa7134_set_gpio(dev, 23, 1); - dev->has_remote = SAA7134_REMOTE_I2C; - break; case SAA7134_BOARD_AVERMEDIA_M103: saa7134_set_gpio(dev, 23, 0); msleep(10); @@ -6223,16 +6054,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00); break; - case SAA7134_BOARD_HAUPPAUGE_HVR1120: - case SAA7134_BOARD_HAUPPAUGE_HVR1110R3: - /* GPIO 26 high for digital, low for analog */ - saa7134_set_gpio(dev, 26, 0); - msleep(1); - - saa7134_set_gpio(dev, 22, 0); - msleep(10); - saa7134_set_gpio(dev, 22, 1); - break; /* i2c remotes */ case SAA7134_BOARD_PINNACLE_PCTV_110i: case SAA7134_BOARD_PINNACLE_PCTV_310i: @@ -6258,15 +6079,15 @@ int saa7134_board_init1(struct saa7134_dev *dev) saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x8c040007, 0x8c040007); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0c0007cd, 0x0c0007cd); break; - case SAA7134_BOARD_AVERMEDIA_A700_HYBRID: - printk("%s: %s: hybrid analog/dvb card\n" - "%s: Sorry, of the analog inputs, only analog s-video and composite " - "are supported for now.\n", - dev->name, card(dev).name, dev->name); case SAA7134_BOARD_AVERMEDIA_A700_PRO: + case SAA7134_BOARD_AVERMEDIA_A700_HYBRID: /* write windows gpio values */ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x80040100, 0x80040100); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100); + printk("%s: %s: hybrid analog/dvb card\n" + "%s: Sorry, only analog s-video and composite input " + "are supported for now.\n", + dev->name, card(dev).name, dev->name); break; } return 0; @@ -6288,7 +6109,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev) tun_setup.mode_mask = T_RADIO; - saa_call_all(dev, tuner, s_type_addr, &tun_setup); + saa7134_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup); mode_mask &= ~T_RADIO; } @@ -6300,7 +6121,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev) tun_setup.mode_mask = mode_mask; - saa_call_all(dev, tuner, s_type_addr, &tun_setup); + saa7134_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup); } if (dev->tda9887_conf) { @@ -6309,7 +6130,8 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev) tda9887_cfg.tuner = TUNER_TDA9887; tda9887_cfg.priv = &dev->tda9887_conf; - saa_call_all(dev, tuner, s_config, &tda9887_cfg); + saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, + &tda9887_cfg); } if (dev->tuner_type == TUNER_XC2028) { @@ -6336,7 +6158,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev) xc2028_cfg.tuner = TUNER_XC2028; xc2028_cfg.priv = &ctl; - saa_call_all(dev, tuner, s_config, &xc2028_cfg); + saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg); } } @@ -6346,20 +6168,9 @@ int saa7134_board_init2(struct saa7134_dev *dev) unsigned char buf; int board; - /* Put here the code that enables the chips that are needed - for analog mode and doesn't depend on the tuner attachment. - It is also a good idea to get tuner type from eeprom, etc before - initializing tuner, since we can avoid loading tuner driver - on devices that has TUNER_ABSENT - */ switch (dev->board) { case SAA7134_BOARD_BMK_MPEX_NOTUNER: case SAA7134_BOARD_BMK_MPEX_TUNER: - /* Checks if the device has a tuner at 0x60 addr - If the device doesn't have a tuner, TUNER_ABSENT - will be used at tuner_type, avoiding loading tuner - without needing it - */ dev->i2c_client.addr = 0x60; board = (i2c_master_recv(&dev->i2c_client, &buf, 0) < 0) ? SAA7134_BOARD_BMK_MPEX_NOTUNER @@ -6377,15 +6188,11 @@ int saa7134_board_init2(struct saa7134_dev *dev) u8 subaddr; u8 data[3]; int ret, tuner_t; + struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, .len = 1}, {.addr=0x50, .flags=I2C_M_RD, .buf=data, .len = 3}}; - subaddr= 0x14; tuner_t = 0; - - /* Retrieve device data from eeprom, checking for the - proper tuner_type. - */ ret = i2c_transfer(&dev->i2c_adap, msg, 2); if (ret != 2) { printk(KERN_ERR "EEPROM read failure\n"); @@ -6441,14 +6248,12 @@ int saa7134_board_init2(struct saa7134_dev *dev) dev->name, saa7134_boards[dev->board].name); break; } - /* break intentionally omitted */ case SAA7134_BOARD_VIDEOMATE_DVBT_300: case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: { - /* The Philips EUROPA based hybrid boards have the tuner - connected through the channel decoder. We have to make it - transparent to find it + /* The Philips EUROPA based hybrid boards have the tuner connected through + * the channel decoder. We have to make it transparent to find it */ u8 data[] = { 0x07, 0x02}; struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; @@ -6469,15 +6274,21 @@ int saa7134_board_init2(struct saa7134_dev *dev) if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) { dev->tuner_type = TUNER_PHILIPS_TDA8290; + saa7134_tuner_setup(dev); + data[2] = 0x68; i2c_transfer(&dev->i2c_adap, &msg, 1); - break; + + /* Tuner setup is handled before I2C transfer. + Due to that, there's no need to do it later + */ + return 0; } i2c_transfer(&dev->i2c_adap, &msg, 1); break; } - case SAA7134_BOARD_ASUSTeK_TVFM7135: - /* The card below is detected as card=53, but is different */ + case SAA7134_BOARD_ASUSTeK_TVFM7135: + /* The card below is detected as card=53, but is different */ if (dev->autodetected && (dev->eedata[0x27] == 0x03)) { dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG; printk(KERN_INFO "%s: P7131 analog only, using " @@ -6485,10 +6296,6 @@ int saa7134_board_init2(struct saa7134_dev *dev) dev->name, saa7134_boards[dev->board].name); } break; - case SAA7134_BOARD_HAUPPAUGE_HVR1120: - case SAA7134_BOARD_HAUPPAUGE_HVR1110R3: - hauppauge_eeprom(dev, dev->eedata+0x80); - break; case SAA7134_BOARD_HAUPPAUGE_HVR1110: hauppauge_eeprom(dev, dev->eedata+0x80); /* break intentionally omitted */ @@ -6544,6 +6351,22 @@ int saa7134_board_init2(struct saa7134_dev *dev) i2c_transfer(&dev->i2c_adap, &msg, 1); break; } + case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI: + case SAA7134_BOARD_KWORLD_ATSC110: + { + /* enable tuner */ + int i; + static const u8 buffer [] = { 0x10, 0x12, 0x13, 0x04, 0x16, + 0x00, 0x14, 0x04, 0x17, 0x00 }; + dev->i2c_client.addr = 0x0a; + for (i = 0; i < 5; i++) + if (2 != i2c_master_send(&dev->i2c_client, + &buffer[i*2], 2)) + printk(KERN_WARNING + "%s: Unable to enable tuner(%i).\n", + dev->name, i); + break; + } case SAA7134_BOARD_VIDEOMATE_DVBT_200: case SAA7134_BOARD_VIDEOMATE_DVBT_200A: /* The T200 and the T200A share the same pci id. Consequently, @@ -6552,9 +6375,9 @@ int saa7134_board_init2(struct saa7134_dev *dev) /* Don't do this if the board was specifically selected with an * insmod option or if we have the default configuration T200*/ - if (!dev->autodetected || (dev->eedata[0x41] == 0xd0)) + if(!dev->autodetected || (dev->eedata[0x41] == 0xd0)) break; - if (dev->eedata[0x41] == 0x02) { + if(dev->eedata[0x41] == 0x02) { /* Reconfigure board as T200A */ dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A; dev->tuner_type = saa7134_boards[dev->board].tuner_type; @@ -6567,58 +6390,6 @@ int saa7134_board_init2(struct saa7134_dev *dev) break; } break; - case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI: - case SAA7134_BOARD_KWORLD_ATSC110: - { - struct i2c_msg msg = { .addr = 0x0a, .flags = 0 }; - int i; - static u8 buffer[][2] = { - { 0x10, 0x12 }, - { 0x13, 0x04 }, - { 0x16, 0x00 }, - { 0x14, 0x04 }, - { 0x17, 0x00 }, - }; - - for (i = 0; i < ARRAY_SIZE(buffer); i++) { - msg.buf = &buffer[i][0]; - msg.len = ARRAY_SIZE(buffer[0]); - if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) - printk(KERN_WARNING - "%s: Unable to enable tuner(%i).\n", - dev->name, i); - } - break; - } - } /* switch() */ - - /* initialize tuner */ - if (TUNER_ABSENT != dev->tuner_type) { - int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); - - /* Note: radio tuner address is always filled in, - so we do not need to probe for a radio tuner device. */ - if (dev->radio_type != UNSET) - v4l2_i2c_new_subdev(&dev->i2c_adap, - "tuner", "tuner", dev->radio_addr); - if (has_demod) - v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner", - "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); - if (dev->tuner_addr == ADDR_UNSET) { - enum v4l2_i2c_tuner_type type = - has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; - - v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner", - "tuner", v4l2_i2c_tuner_addrs(type)); - } else { - v4l2_i2c_new_subdev(&dev->i2c_adap, - "tuner", "tuner", dev->tuner_addr); - } - } - - saa7134_tuner_setup(dev); - - switch (dev->board) { case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: { struct v4l2_priv_tun_config tea5767_cfg; @@ -6630,10 +6401,12 @@ int saa7134_board_init2(struct saa7134_dev *dev) ctl.xtal_freq = TEA5767_HIGH_LO_13MHz; tea5767_cfg.tuner = TUNER_TEA5767; tea5767_cfg.priv = &ctl; - saa_call_all(dev, tuner, s_config, &tea5767_cfg); + saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tea5767_cfg); break; } } /* switch() */ + saa7134_tuner_setup(dev); + return 0; } diff --git a/trunk/drivers/media/video/saa7134/saa7134-core.c b/trunk/drivers/media/video/saa7134/saa7134-core.c index dafa0d88bed0..99221d726edb 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-core.c +++ b/trunk/drivers/media/video/saa7134/saa7134-core.c @@ -54,9 +54,13 @@ static unsigned int gpio_tracking; module_param(gpio_tracking, int, 0644); MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]"); -static unsigned int alsa = 1; +static unsigned int alsa; module_param(alsa, int, 0644); -MODULE_PARM_DESC(alsa,"enable/disable ALSA DMA sound [dmasound]"); +MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]"); + +static unsigned int oss; +module_param(oss, int, 0644); +MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]"); static unsigned int latency = UNSET; module_param(latency, int, 0444); @@ -86,10 +90,8 @@ MODULE_PARM_DESC(radio_nr, "radio device number"); MODULE_PARM_DESC(tuner, "tuner type"); MODULE_PARM_DESC(card, "card type"); -DEFINE_MUTEX(saa7134_devlist_lock); -EXPORT_SYMBOL(saa7134_devlist_lock); +static DEFINE_MUTEX(devlist_lock); LIST_HEAD(saa7134_devlist); -EXPORT_SYMBOL(saa7134_devlist); static LIST_HEAD(mops_list); static unsigned int saa7134_devcount; @@ -154,10 +156,10 @@ static void request_module_async(struct work_struct *work){ request_module("saa7134-empress"); if (card_is_dvb(dev)) request_module("saa7134-dvb"); - if (alsa) { - if (dev->pci->device != PCI_DEVICE_ID_PHILIPS_SAA7130) - request_module("saa7134-alsa"); - } + if (alsa) + request_module("saa7134-alsa"); + if (oss) + request_module("saa7134-oss"); } static void request_submodules(struct saa7134_dev *dev) @@ -776,7 +778,7 @@ static struct video_device *vdev_init(struct saa7134_dev *dev, return NULL; *vfd = *template; vfd->minor = -1; - vfd->v4l2_dev = &dev->v4l2_dev; + vfd->parent = &dev->pci->dev; vfd->release = video_device_release; vfd->debug = video_debug; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", @@ -849,10 +851,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, if (NULL == dev) return -ENOMEM; - err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev); - if (err) - goto fail0; - /* pci init */ dev->pci = pci_dev; if (pci_enable_device(pci_dev)) { @@ -929,8 +927,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, dev->autodetected = card[dev->nr] != dev->board; dev->tuner_type = saa7134_boards[dev->board].tuner_type; dev->tuner_addr = saa7134_boards[dev->board].tuner_addr; - dev->radio_type = saa7134_boards[dev->board].radio_type; - dev->radio_addr = saa7134_boards[dev->board].radio_addr; dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf; if (UNSET != tuner[dev->nr]) dev->tuner_type = tuner[dev->nr]; @@ -975,48 +971,23 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, /* wait a bit, register i2c bus */ msleep(100); saa7134_i2c_register(dev); + + /* initialize hardware #2 */ + if (TUNER_ABSENT != dev->tuner_type) + request_module("tuner"); saa7134_board_init2(dev); saa7134_hwinit2(dev); /* load i2c helpers */ if (card_is_empress(dev)) { - struct v4l2_subdev *sd = - v4l2_i2c_new_subdev(&dev->i2c_adap, - "saa6752hs", "saa6752hs", - saa7134_boards[dev->board].empress_addr); - - if (sd) - sd->grp_id = GRP_EMPRESS; - } - - if (saa7134_boards[dev->board].rds_addr) { - unsigned short addrs[2] = { 0, I2C_CLIENT_END }; - struct v4l2_subdev *sd; - - addrs[0] = saa7134_boards[dev->board].rds_addr; - sd = v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "saa6588", - "saa6588", addrs); - if (sd) - printk(KERN_INFO "%s: found RDS decoder\n", dev->name); + request_module("saa6752hs"); } request_submodules(dev); v4l2_prio_init(&dev->prio); - mutex_lock(&saa7134_devlist_lock); - list_for_each_entry(mops, &mops_list, next) - mpeg_ops_attach(mops, dev); - list_add_tail(&dev->devlist, &saa7134_devlist); - mutex_unlock(&saa7134_devlist_lock); - - /* check for signal */ - saa7134_irq_video_signalchange(dev); - - if (TUNER_ABSENT != dev->tuner_type) - saa_call_all(dev, core, s_standby, 0); - /* register v4l devices */ if (saa7134_no_overlay > 0) printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name); @@ -1052,10 +1023,24 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, } /* everything worked */ + pci_set_drvdata(pci_dev,dev); saa7134_devcount++; - if (saa7134_dmasound_init && !dev->dmasound.priv_data) + mutex_lock(&devlist_lock); + list_for_each_entry(mops, &mops_list, next) + mpeg_ops_attach(mops, dev); + list_add_tail(&dev->devlist,&saa7134_devlist); + mutex_unlock(&devlist_lock); + + /* check for signal */ + saa7134_irq_video_signalchange(dev); + + if (saa7134_dmasound_init && !dev->dmasound.priv_data) { saa7134_dmasound_init(dev); + } + + if (TUNER_ABSENT != dev->tuner_type) + saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL); return 0; @@ -1070,16 +1055,13 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, release_mem_region(pci_resource_start(pci_dev,0), pci_resource_len(pci_dev,0)); fail1: - v4l2_device_unregister(&dev->v4l2_dev); - fail0: kfree(dev); return err; } static void __devexit saa7134_finidev(struct pci_dev *pci_dev) { - struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); - struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev); + struct saa7134_dev *dev = pci_get_drvdata(pci_dev); struct saa7134_mpeg_ops *mops; /* Release DMA sound modules if present */ @@ -1106,11 +1088,11 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) saa7134_hwfini(dev); /* unregister */ - mutex_lock(&saa7134_devlist_lock); + mutex_lock(&devlist_lock); list_del(&dev->devlist); list_for_each_entry(mops, &mops_list, next) mpeg_ops_detach(mops, dev); - mutex_unlock(&saa7134_devlist_lock); + mutex_unlock(&devlist_lock); saa7134_devcount--; saa7134_i2c_unregister(dev); @@ -1131,8 +1113,7 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) release_mem_region(pci_resource_start(pci_dev,0), pci_resource_len(pci_dev,0)); - - v4l2_device_unregister(&dev->v4l2_dev); + pci_set_drvdata(pci_dev, NULL); /* free memory */ kfree(dev); @@ -1167,8 +1148,8 @@ static int saa7134_buffer_requeue(struct saa7134_dev *dev, static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state) { - struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); - struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev); + + struct saa7134_dev *dev = pci_get_drvdata(pci_dev); /* disable overlay - apps should enable it explicitly on resume*/ dev->ovenable = 0; @@ -1204,8 +1185,7 @@ static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state) static int saa7134_resume(struct pci_dev *pci_dev) { - struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); - struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev); + struct saa7134_dev *dev = pci_get_drvdata(pci_dev); unsigned long flags; pci_set_power_state(pci_dev, PCI_D0); @@ -1267,11 +1247,11 @@ int saa7134_ts_register(struct saa7134_mpeg_ops *ops) { struct saa7134_dev *dev; - mutex_lock(&saa7134_devlist_lock); + mutex_lock(&devlist_lock); list_for_each_entry(dev, &saa7134_devlist, devlist) mpeg_ops_attach(ops, dev); list_add_tail(&ops->next,&mops_list); - mutex_unlock(&saa7134_devlist_lock); + mutex_unlock(&devlist_lock); return 0; } @@ -1279,11 +1259,11 @@ void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops) { struct saa7134_dev *dev; - mutex_lock(&saa7134_devlist_lock); + mutex_lock(&devlist_lock); list_del(&ops->next); list_for_each_entry(dev, &saa7134_devlist, devlist) mpeg_ops_detach(ops, dev); - mutex_unlock(&saa7134_devlist_lock); + mutex_unlock(&devlist_lock); } EXPORT_SYMBOL(saa7134_ts_register); @@ -1327,6 +1307,8 @@ module_exit(saa7134_fini); /* ----------------------------------------------------------- */ EXPORT_SYMBOL(saa7134_set_gpio); +EXPORT_SYMBOL(saa7134_i2c_call_clients); +EXPORT_SYMBOL(saa7134_devlist); EXPORT_SYMBOL(saa7134_boards); /* ----------------- for the DMA sound modules --------------- */ diff --git a/trunk/drivers/media/video/saa7134/saa7134-dvb.c b/trunk/drivers/media/video/saa7134/saa7134-dvb.c index 4eff1ca8593c..b5370b3e1a3d 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-dvb.c +++ b/trunk/drivers/media/video/saa7134/saa7134-dvb.c @@ -48,15 +48,9 @@ #include "isl6405.h" #include "lnbp21.h" #include "tuner-simple.h" -#include "tda18271.h" -#include "lgdt3305.h" -#include "tda8290.h" #include "zl10353.h" -#include "zl10036.h" -#include "mt312.h" - MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); MODULE_LICENSE("GPL"); @@ -195,7 +189,7 @@ static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe, if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &msg, 1); - saa_call_all(dev, tuner, s_frequency, &f); + saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f); msg.buf = on; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); @@ -956,45 +950,6 @@ static struct nxt200x_config kworldatsc110 = { .demod_address = 0x0a, }; -/* ------------------------------------------------------------------ */ - -static struct mt312_config avertv_a700_mt312 = { - .demod_address = 0x0e, - .voltage_inverted = 1, -}; - -static struct zl10036_config avertv_a700_tuner = { - .tuner_address = 0x60, -}; - -static struct lgdt3305_config hcw_lgdt3305_config = { - .i2c_addr = 0x0e, - .mpeg_mode = LGDT3305_MPEG_SERIAL, - .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE, - .tpvalid_polarity = LGDT3305_TP_VALID_HIGH, - .deny_i2c_rptr = 1, - .spectral_inversion = 1, - .qam_if_khz = 4000, - .vsb_if_khz = 3250, -}; - -static struct tda18271_std_map hauppauge_tda18271_std_map = { - .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4, - .if_lvl = 1, .rfagc_top = 0x58, }, - .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5, - .if_lvl = 1, .rfagc_top = 0x58, }, -}; - -static struct tda18271_config hcw_tda18271_config = { - .std_map = &hauppauge_tda18271_std_map, - .gate = TDA18271_GATE_ANALOG, - .config = 3, -}; - -static struct tda829x_config tda829x_no_probe = { - .probe_tuner = TDA829X_DONT_PROBE, -}; - /* ================================================================== * Core code */ @@ -1121,19 +1076,6 @@ static int dvb_init(struct saa7134_dev *dev) &tda827x_cfg_1) < 0) goto dettach_frontend; break; - case SAA7134_BOARD_HAUPPAUGE_HVR1120: - fe0->dvb.frontend = dvb_attach(lgdt3305_attach, - &hcw_lgdt3305_config, - &dev->i2c_adap); - if (fe0->dvb.frontend) { - dvb_attach(tda829x_attach, fe0->dvb.frontend, - &dev->i2c_adap, 0x4b, - &tda829x_no_probe); - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_adap, - &hcw_tda18271_config); - } - break; case SAA7134_BOARD_ASUSTeK_P7131_DUAL: if (configure_tda827x_fe(dev, &asus_p7131_dual_config, &tda827x_cfg_0) < 0) @@ -1434,19 +1376,6 @@ static int dvb_init(struct saa7134_dev *dev) TUNER_PHILIPS_FMD1216ME_MK3); } break; - case SAA7134_BOARD_AVERMEDIA_A700_PRO: - case SAA7134_BOARD_AVERMEDIA_A700_HYBRID: - /* Zarlink ZL10313 */ - fe0->dvb.frontend = dvb_attach(mt312_attach, - &avertv_a700_mt312, &dev->i2c_adap); - if (fe0->dvb.frontend) { - if (dvb_attach(zl10036_attach, fe0->dvb.frontend, - &avertv_a700_tuner, &dev->i2c_adap) == NULL) { - wprintk("%s: No zl10036 found!\n", - __func__); - } - } - break; default: wprintk("Huh? unknown DVB card?\n"); break; @@ -1520,7 +1449,7 @@ static int dvb_fini(struct saa7134_dev *dev) tda9887_cfg.priv = &on; /* otherwise we don't detect the tuner on next insmod */ - saa_call_all(dev, tuner, s_config, &tda9887_cfg); + saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tda9887_cfg); } else if (dev->board == SAA7134_BOARD_MEDION_MD8800_QUADRO) { if ((dev->eedata[2] == 0x07) && use_frontend) { /* turn off the 2nd lnb supply */ diff --git a/trunk/drivers/media/video/saa7134/saa7134-empress.c b/trunk/drivers/media/video/saa7134/saa7134-empress.c index 9db3472667e5..c9d8beb87a60 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-empress.c +++ b/trunk/drivers/media/video/saa7134/saa7134-empress.c @@ -76,7 +76,7 @@ static int ts_init_encoder(struct saa7134_dev* dev) break; } ts_reset_encoder(dev); - saa_call_all(dev, core, init, leading_null_bytes); + saa7134_i2c_call_clients(dev, VIDIOC_INT_INIT, &leading_null_bytes); dev->empress_started = 1; return 0; } @@ -234,7 +234,7 @@ static int empress_g_fmt_vid_cap(struct file *file, void *priv, { struct saa7134_dev *dev = file->private_data; - saa_call_all(dev, video, g_fmt, f); + saa7134_i2c_call_clients(dev, VIDIOC_G_FMT, f); f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; @@ -247,7 +247,7 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv, { struct saa7134_dev *dev = file->private_data; - saa_call_all(dev, video, s_fmt, f); + saa7134_i2c_call_clients(dev, VIDIOC_S_FMT, f); f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; @@ -317,7 +317,7 @@ static int empress_s_ext_ctrls(struct file *file, void *priv, if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) return -EINVAL; - err = saa_call_empress(dev, core, s_ext_ctrls, ctrls); + err = saa7134_i2c_call_saa6752(dev, VIDIOC_S_EXT_CTRLS, ctrls); ts_init_encoder(dev); return err; @@ -330,7 +330,7 @@ static int empress_g_ext_ctrls(struct file *file, void *priv, if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) return -EINVAL; - return saa_call_empress(dev, core, g_ext_ctrls, ctrls); + return saa7134_i2c_call_saa6752(dev, VIDIOC_G_EXT_CTRLS, ctrls); } static int empress_g_ctrl(struct file *file, void *priv, @@ -352,7 +352,6 @@ static int empress_s_ctrl(struct file *file, void *priv, static int empress_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c) { - /* Must be sorted from low to high control ID! */ static const u32 user_ctrls[] = { V4L2_CID_USER_CLASS, V4L2_CID_BRIGHTNESS, @@ -365,7 +364,6 @@ static int empress_queryctrl(struct file *file, void *priv, 0 }; - /* Must be sorted from low to high control ID! */ static const u32 mpeg_ctrls[] = { V4L2_CID_MPEG_CLASS, V4L2_CID_MPEG_STREAM_TYPE, @@ -390,10 +388,10 @@ static int empress_queryctrl(struct file *file, void *priv, if (c->id == 0) return -EINVAL; if (c->id == V4L2_CID_USER_CLASS || c->id == V4L2_CID_MPEG_CLASS) - return v4l2_ctrl_query_fill(c, 0, 0, 0, 0); + return v4l2_ctrl_query_fill_std(c); if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG) return saa7134_queryctrl(file, priv, c); - return saa_call_empress(dev, core, queryctrl, c); + return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYCTRL, c); } static int empress_querymenu(struct file *file, void *priv, @@ -403,7 +401,7 @@ static int empress_querymenu(struct file *file, void *priv, if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG) return -EINVAL; - return saa_call_empress(dev, core, querymenu, c); + return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYMENU, c); } static int empress_g_chip_ident(struct file *file, void *fh, @@ -413,11 +411,14 @@ static int empress_g_chip_ident(struct file *file, void *fh, chip->ident = V4L2_IDENT_NONE; chip->revision = 0; + if (dev->mpeg_i2c_client == NULL) + return -EINVAL; if (chip->match.type == V4L2_CHIP_MATCH_I2C_DRIVER && !strcmp(chip->match.name, "saa6752hs")) - return saa_call_empress(dev, core, g_chip_ident, chip); - if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR) - return saa_call_empress(dev, core, g_chip_ident, chip); + return saa7134_i2c_call_saa6752(dev, VIDIOC_DBG_G_CHIP_IDENT, chip); + if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR && + chip->match.addr == dev->mpeg_i2c_client->addr) + return saa7134_i2c_call_saa6752(dev, VIDIOC_DBG_G_CHIP_IDENT, chip); return -EINVAL; } diff --git a/trunk/drivers/media/video/saa7134/saa7134-i2c.c b/trunk/drivers/media/video/saa7134/saa7134-i2c.c index f3e285aa2fb4..20c1b33caf7b 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-i2c.c +++ b/trunk/drivers/media/video/saa7134/saa7134-i2c.c @@ -255,7 +255,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, addr = msgs[i].addr << 1; if (msgs[i].flags & I2C_M_RD) addr |= 1; - if (i > 0 && msgs[i].flags & I2C_M_RD && msgs[i].addr != 0x40) { + if (i > 0 && msgs[i].flags & I2C_M_RD) { /* workaround for a saa7134 i2c bug * needed to talk to the mt352 demux * thanks to pinnacle for the hint */ @@ -327,6 +327,8 @@ static int attach_inform(struct i2c_client *client) d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", client->driver->driver.name, client->addr, client->name); + if (client->addr == 0x20 && client->driver && client->driver->command) + dev->mpeg_i2c_client = client; /* Am I an i2c remote control? */ @@ -355,6 +357,7 @@ static struct i2c_algorithm saa7134_algo = { static struct i2c_adapter saa7134_adap_template = { .owner = THIS_MODULE, + .class = I2C_CLASS_TV_ANALOG, .name = "saa7134", .id = I2C_HW_SAA7134, .algo = &saa7134_algo, @@ -418,13 +421,29 @@ static void do_i2c_scan(char *name, struct i2c_client *c) } } +void saa7134_i2c_call_clients(struct saa7134_dev *dev, + unsigned int cmd, void *arg) +{ + BUG_ON(NULL == dev->i2c_adap.algo_data); + i2c_clients_command(&dev->i2c_adap, cmd, arg); +} + +int saa7134_i2c_call_saa6752(struct saa7134_dev *dev, + unsigned int cmd, void *arg) +{ + if (dev->mpeg_i2c_client == NULL) + return -EINVAL; + return dev->mpeg_i2c_client->driver->command(dev->mpeg_i2c_client, + cmd, arg); +} +EXPORT_SYMBOL_GPL(saa7134_i2c_call_saa6752); + int saa7134_i2c_register(struct saa7134_dev *dev) { dev->i2c_adap = saa7134_adap_template; dev->i2c_adap.dev.parent = &dev->pci->dev; strcpy(dev->i2c_adap.name,dev->name); dev->i2c_adap.algo_data = dev; - i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev); i2c_add_adapter(&dev->i2c_adap); dev->i2c_client = saa7134_client_template; diff --git a/trunk/drivers/media/video/saa7134/saa7134-ts.c b/trunk/drivers/media/video/saa7134/saa7134-ts.c index cc8b923afbc0..ef55a59f0cda 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-ts.c +++ b/trunk/drivers/media/video/saa7134/saa7134-ts.c @@ -79,19 +79,8 @@ static int buffer_activate(struct saa7134_dev *dev, saa_writeb(SAA7134_TS_SERIAL1, 0x00); /* Start TS stream */ - switch (saa7134_boards[dev->board].ts_type) { - case SAA7134_MPEG_TS_PARALLEL: - saa_writeb(SAA7134_TS_SERIAL0, 0x40); - saa_writeb(SAA7134_TS_PARALLEL, 0xec); - break; - case SAA7134_MPEG_TS_SERIAL: - saa_writeb(SAA7134_TS_SERIAL0, 0xd8); - saa_writeb(SAA7134_TS_PARALLEL, 0x6c); - saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc); - saa_writeb(SAA7134_TS_SERIAL1, 0x02); - break; - } - + saa_writeb(SAA7134_TS_SERIAL0, 0x40); + saa_writeb(SAA7134_TS_PARALLEL, 0xEC); dev->ts_state = SAA7134_TS_STARTED; } diff --git a/trunk/drivers/media/video/saa7134/saa7134-video.c b/trunk/drivers/media/video/saa7134/saa7134-video.c index 404f70eeb355..a1f7e351f572 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-video.c +++ b/trunk/drivers/media/video/saa7134/saa7134-video.c @@ -30,7 +30,11 @@ #include "saa7134-reg.h" #include "saa7134.h" #include -#include + +#ifdef CONFIG_VIDEO_V4L1_COMPAT +/* Include V4L1 specific functions. Should be removed soon */ +#include +#endif /* ------------------------------------------------------------------ */ @@ -448,7 +452,6 @@ static const struct v4l2_queryctrl video_ctrls[] = { .name = "y offset odd field", .minimum = 0, .maximum = 128, - .step = 1, .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, },{ @@ -456,7 +459,6 @@ static const struct v4l2_queryctrl video_ctrls[] = { .name = "y offset even field", .minimum = 0, .maximum = 128, - .step = 1, .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, },{ @@ -625,10 +627,10 @@ void saa7134_set_tvnorm_hw(struct saa7134_dev *dev) saa7134_set_decoder(dev); if (card_in(dev, dev->ctl_input).tv) - saa_call_all(dev, tuner, s_std, dev->tvnorm->id); + saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id); /* Set the correct norm for the saa6752hs. This function does nothing if there is no saa6752hs. */ - saa_call_empress(dev, tuner, s_std, dev->tvnorm->id); + saa7134_i2c_call_saa6752(dev, VIDIOC_S_STD, &dev->tvnorm->id); } static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale) @@ -1264,7 +1266,8 @@ int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, str else dev->tda9887_conf &= ~TDA9887_AUTOMUTE; - saa_call_all(dev, tuner, s_config, &tda9887_cfg); + saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, + &tda9887_cfg); } break; } @@ -1331,7 +1334,7 @@ static int video_open(struct file *file) enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; int radio = 0; - mutex_lock(&saa7134_devlist_lock); + lock_kernel(); list_for_each_entry(dev, &saa7134_devlist, devlist) { if (dev->video_dev && (dev->video_dev->minor == minor)) goto found; @@ -1344,20 +1347,19 @@ static int video_open(struct file *file) goto found; } } - mutex_unlock(&saa7134_devlist_lock); + unlock_kernel(); return -ENODEV; - -found: - mutex_unlock(&saa7134_devlist_lock); + found: dprintk("open minor=%d radio=%d type=%s\n",minor,radio, v4l2_type_names[type]); /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh),GFP_KERNEL); - if (NULL == fh) + if (NULL == fh) { + unlock_kernel(); return -ENOMEM; - + } file->private_data = fh; fh->dev = dev; fh->radio = radio; @@ -1385,11 +1387,12 @@ static int video_open(struct file *file) if (fh->radio) { /* switch to radio mode */ saa7134_tvaudio_setinput(dev,&card(dev).radio); - saa_call_all(dev, tuner, s_radio); + saa7134_i2c_call_clients(dev,AUDC_SET_RADIO, NULL); } else { /* switch to video/vbi mode */ video_mux(dev,dev->ctl_input); } + unlock_kernel(); return 0; } @@ -1463,7 +1466,6 @@ static int video_release(struct file *file) { struct saa7134_fh *fh = file->private_data; struct saa7134_dev *dev = fh->dev; - struct rds_command cmd; unsigned long flags; /* turn off overlay */ @@ -1496,9 +1498,7 @@ static int video_release(struct file *file) saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0); saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0); - saa_call_all(dev, core, s_standby, 0); - if (fh->radio) - saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd); + saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL); /* free stuff */ videobuf_mmap_free(&fh->cap); @@ -1519,37 +1519,6 @@ static int video_mmap(struct file *file, struct vm_area_struct * vma) return videobuf_mmap_mapper(saa7134_queue(fh), vma); } -static ssize_t radio_read(struct file *file, char __user *data, - size_t count, loff_t *ppos) -{ - struct saa7134_fh *fh = file->private_data; - struct saa7134_dev *dev = fh->dev; - struct rds_command cmd; - - cmd.block_count = count/3; - cmd.buffer = data; - cmd.instance = file; - cmd.result = -ENODEV; - - saa_call_all(dev, core, ioctl, RDS_CMD_READ, &cmd); - - return cmd.result; -} - -static unsigned int radio_poll(struct file *file, poll_table *wait) -{ - struct saa7134_fh *fh = file->private_data; - struct saa7134_dev *dev = fh->dev; - struct rds_command cmd; - - cmd.instance = file; - cmd.event_list = wait; - cmd.result = -ENODEV; - saa_call_all(dev, core, ioctl, RDS_CMD_POLL, &cmd); - - return cmd.result; -} - /* ------------------------------------------------------------------ */ static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv, @@ -2072,7 +2041,7 @@ static int saa7134_s_frequency(struct file *file, void *priv, mutex_lock(&dev->lock); dev->ctl_freq = f->frequency; - saa_call_all(dev, tuner, s_frequency, f); + saa7134_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); saa7134_tvaudio_do_scan(dev); mutex_unlock(&dev->lock); @@ -2330,7 +2299,7 @@ static int radio_g_tuner(struct file *file, void *priv, strcpy(t->name, "Radio"); t->type = V4L2_TUNER_RADIO; - saa_call_all(dev, tuner, g_tuner, t); + saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); if (dev->input->amux == TV) { t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11); t->rxsubchans = (saa_readb(0x529) & 0x08) ? @@ -2347,7 +2316,7 @@ static int radio_s_tuner(struct file *file, void *priv, if (0 != t->index) return -EINVAL; - saa_call_all(dev, tuner, s_tuner, t); + saa7134_i2c_call_clients(dev, VIDIOC_S_TUNER, t); return 0; } @@ -2474,10 +2443,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { static const struct v4l2_file_operations radio_fops = { .owner = THIS_MODULE, .open = video_open, - .read = radio_read, .release = video_release, .ioctl = video_ioctl2, - .poll = radio_poll, }; static const struct v4l2_ioctl_ops radio_ioctl_ops = { diff --git a/trunk/drivers/media/video/saa7134/saa7134.h b/trunk/drivers/media/video/saa7134/saa7134.h index a2dd326de5b9..14ee265f3374 100644 --- a/trunk/drivers/media/video/saa7134/saa7134.h +++ b/trunk/drivers/media/video/saa7134/saa7134.h @@ -35,7 +35,6 @@ #include #include -#include #include #include #include @@ -278,8 +277,6 @@ struct saa7134_format { #define SAA7134_BOARD_ASUSTeK_TIGER 152 #define SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG 153 #define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154 -#define SAA7134_BOARD_HAUPPAUGE_HVR1120 155 -#define SAA7134_BOARD_HAUPPAUGE_HVR1110R3 156 #define SAA7134_MAXBOARDS 32 #define SAA7134_INPUT_MAX 8 @@ -312,11 +309,6 @@ enum saa7134_mpeg_type { SAA7134_MPEG_DVB, }; -enum saa7134_mpeg_ts_type { - SAA7134_MPEG_TS_PARALLEL = 0, - SAA7134_MPEG_TS_SERIAL, -}; - struct saa7134_board { char *name; unsigned int audio_clock; @@ -332,8 +324,6 @@ struct saa7134_board { unsigned int radio_type; unsigned char tuner_addr; unsigned char radio_addr; - unsigned char empress_addr; - unsigned char rds_addr; unsigned int tda9887_conf; unsigned int tuner_config; @@ -341,7 +331,6 @@ struct saa7134_board { /* peripheral I/O */ enum saa7134_video_out video_out; enum saa7134_mpeg_type mpeg; - enum saa7134_mpeg_ts_type ts_type; unsigned int vid_port_opts; }; @@ -456,6 +445,7 @@ struct saa7134_dmasound { unsigned int bufsize; struct saa7134_pgtable pt; struct videobuf_dmabuf dma; + wait_queue_head_t wq; unsigned int dma_blk; unsigned int read_offset; unsigned int read_count; @@ -492,7 +482,6 @@ struct saa7134_dev { struct mutex lock; spinlock_t slock; struct v4l2_prio_state prio; - struct v4l2_device v4l2_dev; /* workstruct for loading modules */ struct work_struct request_module_wk; @@ -583,6 +572,7 @@ struct saa7134_dev { enum saa7134_ts_status ts_state; unsigned int buff_cnt; struct saa7134_mpeg_ops *mops; + struct i2c_client *mpeg_i2c_client; /* SAA7134_MPEG_EMPRESS only */ struct video_device *empress_dev; @@ -598,7 +588,6 @@ struct saa7134_dev { int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg); #endif - void (*gate_ctrl)(struct saa7134_dev *dev, int open); }; /* ----------------------------------------------------------- */ @@ -627,31 +616,10 @@ struct saa7134_dev { V4L2_STD_NTSC | V4L2_STD_PAL_M | \ V4L2_STD_PAL_60) -#define GRP_EMPRESS (1) -#define saa_call_all(dev, o, f, args...) do { \ - if (dev->gate_ctrl) \ - dev->gate_ctrl(dev, 1); \ - v4l2_device_call_all(&(dev)->v4l2_dev, 0, o, f , ##args); \ - if (dev->gate_ctrl) \ - dev->gate_ctrl(dev, 0); \ -} while (0) - -#define saa_call_empress(dev, o, f, args...) ({ \ - long _rc; \ - if (dev->gate_ctrl) \ - dev->gate_ctrl(dev, 1); \ - _rc = v4l2_device_call_until_err(&(dev)->v4l2_dev, \ - GRP_EMPRESS, o, f , ##args); \ - if (dev->gate_ctrl) \ - dev->gate_ctrl(dev, 0); \ - _rc; \ -}) - /* ----------------------------------------------------------- */ /* saa7134-core.c */ extern struct list_head saa7134_devlist; -extern struct mutex saa7134_devlist_lock; extern int saa7134_no_overlay; void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); @@ -700,6 +668,10 @@ int saa7134_tuner_callback(void *priv, int component, int command, int arg); int saa7134_i2c_register(struct saa7134_dev *dev); int saa7134_i2c_unregister(struct saa7134_dev *dev); +void saa7134_i2c_call_clients(struct saa7134_dev *dev, + unsigned int cmd, void *arg); +int saa7134_i2c_call_saa6752(struct saa7134_dev *dev, + unsigned int cmd, void *arg); /* ----------------------------------------------------------- */ diff --git a/trunk/drivers/media/video/saa7146.h b/trunk/drivers/media/video/saa7146.h index 9fadb331a40b..2830b5e33aec 100644 --- a/trunk/drivers/media/video/saa7146.h +++ b/trunk/drivers/media/video/saa7146.h @@ -25,6 +25,8 @@ #include #include +#include + #ifndef O_NONCAP #define O_NONCAP O_TRUNC #endif diff --git a/trunk/drivers/media/video/saa717x.c b/trunk/drivers/media/video/saa717x.c index 25bf2303a6b5..88c5e942f751 100644 --- a/trunk/drivers/media/video/saa717x.c +++ b/trunk/drivers/media/video/saa717x.c @@ -931,7 +931,7 @@ static int saa717x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) break; case V4L2_CID_HUE: - if (ctrl->value < -128 || ctrl->value > 127) { + if (ctrl->value < -127 || ctrl->value > 127) { v4l2_err(sd, "invalid hue setting %d\n", ctrl->value); return -ERANGE; } @@ -1380,6 +1380,11 @@ static int saa717x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) return 0; } +static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops saa717x_core_ops = { @@ -1523,7 +1528,10 @@ MODULE_DEVICE_TABLE(i2c, saa717x_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa717x", + .driverid = I2C_DRIVERID_SAA717X, + .command = saa717x_command, .probe = saa717x_probe, .remove = saa717x_remove, + .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL, .id_table = saa717x_id, }; diff --git a/trunk/drivers/media/video/saa7185.c b/trunk/drivers/media/video/saa7185.c index 75747b104d07..6debb65152ee 100644 --- a/trunk/drivers/media/video/saa7185.c +++ b/trunk/drivers/media/video/saa7185.c @@ -30,58 +30,52 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include MODULE_DESCRIPTION("Philips SAA7185 video encoder driver"); MODULE_AUTHOR("Dave Perks"); MODULE_LICENSE("GPL"); + static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); - /* ----------------------------------------------------------------------- */ struct saa7185 { - struct v4l2_subdev sd; unsigned char reg[128]; - v4l2_std_id norm; + int norm; + int enable; + int bright; + int contrast; + int hue; + int sat; }; -static inline struct saa7185 *to_saa7185(struct v4l2_subdev *sd) -{ - return container_of(sd, struct saa7185, sd); -} - /* ----------------------------------------------------------------------- */ -static inline int saa7185_read(struct v4l2_subdev *sd) +static inline int saa7185_read(struct i2c_client *client) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - return i2c_smbus_read_byte(client); } -static int saa7185_write(struct v4l2_subdev *sd, u8 reg, u8 value) +static int saa7185_write(struct i2c_client *client, u8 reg, u8 value) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct saa7185 *encoder = to_saa7185(sd); + struct saa7185 *encoder = i2c_get_clientdata(client); - v4l2_dbg(1, debug, sd, "%02x set to %02x\n", reg, value); + v4l_dbg(1, debug, client, "%02x set to %02x\n", reg, value); encoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } -static int saa7185_write_block(struct v4l2_subdev *sd, +static int saa7185_write_block(struct i2c_client *client, const u8 *data, unsigned int len) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct saa7185 *encoder = to_saa7185(sd); int ret = -1; u8 reg; @@ -89,6 +83,7 @@ static int saa7185_write_block(struct v4l2_subdev *sd, * the adapter understands raw I2C */ if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { /* do raw I2C, not smbus compatible */ + struct saa7185 *encoder = i2c_get_clientdata(client); u8 block_data[32]; int block_len; @@ -109,7 +104,7 @@ static int saa7185_write_block(struct v4l2_subdev *sd, /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - ret = saa7185_write(sd, reg, *data++); + ret = saa7185_write(client, reg, *data++); if (ret < 0) break; len -= 2; @@ -218,106 +213,133 @@ static const unsigned char init_ntsc[] = { 0x66, 0x21, /* FSC3 */ }; - -static int saa7185_init(struct v4l2_subdev *sd, u32 val) +static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) { - struct saa7185 *encoder = to_saa7185(sd); + struct saa7185 *encoder = i2c_get_clientdata(client); - saa7185_write_block(sd, init_common, sizeof(init_common)); - if (encoder->norm & V4L2_STD_NTSC) - saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc)); - else - saa7185_write_block(sd, init_pal, sizeof(init_pal)); - return 0; -} + switch (cmd) { + case 0: + saa7185_write_block(client, init_common, + sizeof(init_common)); + switch (encoder->norm) { + + case VIDEO_MODE_NTSC: + saa7185_write_block(client, init_ntsc, + sizeof(init_ntsc)); + break; + + case VIDEO_MODE_PAL: + saa7185_write_block(client, init_pal, + sizeof(init_pal)); + break; + } + break; -static int saa7185_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) -{ - struct saa7185 *encoder = to_saa7185(sd); + case ENCODER_GET_CAPABILITIES: + { + struct video_encoder_capability *cap = arg; - if (std & V4L2_STD_NTSC) - saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc)); - else if (std & V4L2_STD_PAL) - saa7185_write_block(sd, init_pal, sizeof(init_pal)); - else - return -EINVAL; - encoder->norm = std; - return 0; -} + cap->flags = + VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC | + VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR; + cap->inputs = 1; + cap->outputs = 1; + break; + } -static int saa7185_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) -{ - struct saa7185 *encoder = to_saa7185(sd); + case ENCODER_SET_NORM: + { + int *iarg = arg; - /* RJ: route->input = 0: input is from SA7111 - route->input = 1: input is from ZR36060 */ + //saa7185_write_block(client, init_common, sizeof(init_common)); - switch (route->input) { - case 0: - /* turn off colorbar */ - saa7185_write(sd, 0x3a, 0x0f); - /* Switch RTCE to 1 */ - saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08); - saa7185_write(sd, 0x6e, 0x01); + switch (*iarg) { + case VIDEO_MODE_NTSC: + saa7185_write_block(client, init_ntsc, + sizeof(init_ntsc)); + break; + + case VIDEO_MODE_PAL: + saa7185_write_block(client, init_pal, + sizeof(init_pal)); + break; + + case VIDEO_MODE_SECAM: + default: + return -EINVAL; + } + encoder->norm = *iarg; + break; + } + + case ENCODER_SET_INPUT: + { + int *iarg = arg; + + /* RJ: *iarg = 0: input is from SA7111 + *iarg = 1: input is from ZR36060 */ + + switch (*iarg) { + case 0: + /* Switch RTCE to 1 */ + saa7185_write(client, 0x61, + (encoder->reg[0x61] & 0xf7) | 0x08); + saa7185_write(client, 0x6e, 0x01); + break; + + case 1: + /* Switch RTCE to 0 */ + saa7185_write(client, 0x61, + (encoder->reg[0x61] & 0xf7) | 0x00); + /* SW: a slight sync problem... */ + saa7185_write(client, 0x6e, 0x00); + break; + + default: + return -EINVAL; + } break; + } - case 1: - /* turn off colorbar */ - saa7185_write(sd, 0x3a, 0x0f); - /* Switch RTCE to 0 */ - saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x00); - /* SW: a slight sync problem... */ - saa7185_write(sd, 0x6e, 0x00); + case ENCODER_SET_OUTPUT: + { + int *iarg = arg; + + /* not much choice of outputs */ + if (*iarg != 0) + return -EINVAL; break; + } + + case ENCODER_ENABLE_OUTPUT: + { + int *iarg = arg; - case 2: - /* turn on colorbar */ - saa7185_write(sd, 0x3a, 0x8f); - /* Switch RTCE to 0 */ - saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08); - /* SW: a slight sync problem... */ - saa7185_write(sd, 0x6e, 0x01); + encoder->enable = !!*iarg; + saa7185_write(client, 0x61, + (encoder->reg[0x61] & 0xbf) | + (encoder->enable ? 0x00 : 0x40)); break; + } default: return -EINVAL; } - return 0; -} -static int saa7185_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7185, 0); + return 0; } /* ----------------------------------------------------------------------- */ -static const struct v4l2_subdev_core_ops saa7185_core_ops = { - .g_chip_ident = saa7185_g_chip_ident, - .init = saa7185_init, -}; +static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; -static const struct v4l2_subdev_video_ops saa7185_video_ops = { - .s_std_output = saa7185_s_std_output, - .s_routing = saa7185_s_routing, -}; - -static const struct v4l2_subdev_ops saa7185_ops = { - .core = &saa7185_core_ops, - .video = &saa7185_video_ops, -}; - - -/* ----------------------------------------------------------------------- */ +I2C_CLIENT_INSMOD; static int saa7185_probe(struct i2c_client *client, const struct i2c_device_id *id) { int i; struct saa7185 *encoder; - struct v4l2_subdev *sd; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) @@ -329,29 +351,28 @@ static int saa7185_probe(struct i2c_client *client, encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - encoder->norm = V4L2_STD_NTSC; - sd = &encoder->sd; - v4l2_i2c_subdev_init(sd, client, &saa7185_ops); + encoder->norm = VIDEO_MODE_NTSC; + encoder->enable = 1; + i2c_set_clientdata(client, encoder); - i = saa7185_write_block(sd, init_common, sizeof(init_common)); + i = saa7185_write_block(client, init_common, sizeof(init_common)); if (i >= 0) - i = saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc)); + i = saa7185_write_block(client, init_ntsc, sizeof(init_ntsc)); if (i < 0) - v4l2_dbg(1, debug, sd, "init error %d\n", i); + v4l_dbg(1, debug, client, "init error %d\n", i); else - v4l2_dbg(1, debug, sd, "revision 0x%x\n", - saa7185_read(sd) >> 5); + v4l_dbg(1, debug, client, "revision 0x%x\n", + saa7185_read(client) >> 5); return 0; } static int saa7185_remove(struct i2c_client *client) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct saa7185 *encoder = to_saa7185(sd); + struct saa7185 *encoder = i2c_get_clientdata(client); + + saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */ + //saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */ - v4l2_device_unregister_subdev(sd); - /* SW: output off is active */ - saa7185_write(sd, 0x61, (encoder->reg[0x61]) | 0x40); kfree(encoder); return 0; } @@ -366,6 +387,8 @@ MODULE_DEVICE_TABLE(i2c, saa7185_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "saa7185", + .driverid = I2C_DRIVERID_SAA7185B, + .command = saa7185_command, .probe = saa7185_probe, .remove = saa7185_remove, .id_table = saa7185_id, diff --git a/trunk/drivers/media/video/saa7191.c b/trunk/drivers/media/video/saa7191.c index 3f523aeec56e..b4018cce3285 100644 --- a/trunk/drivers/media/video/saa7191.c +++ b/trunk/drivers/media/video/saa7191.c @@ -19,11 +19,9 @@ #include #include -#include +#include +#include #include -#include -#include -#include #include "saa7191.h" @@ -34,7 +32,6 @@ MODULE_VERSION(SAA7191_MODULE_VERSION); MODULE_AUTHOR("Mikael Nousiainen "); MODULE_LICENSE("GPL"); - // #define SAA7191_DEBUG #ifdef SAA7191_DEBUG @@ -47,20 +44,17 @@ MODULE_LICENSE("GPL"); #define SAA7191_SYNC_DELAY 100 /* milliseconds */ struct saa7191 { - struct v4l2_subdev sd; + struct i2c_client *client; /* the register values are stored here as the actual * I2C-registers are write-only */ u8 reg[25]; int input; - v4l2_std_id norm; + int norm; }; -static inline struct saa7191 *to_saa7191(struct v4l2_subdev *sd) -{ - return container_of(sd, struct saa7191, sd); -} +static struct i2c_driver i2c_driver_saa7191; static const u8 initseq[] = { 0, /* Subaddress */ @@ -106,14 +100,15 @@ static const u8 initseq[] = { /* SAA7191 register handling */ -static u8 saa7191_read_reg(struct v4l2_subdev *sd, u8 reg) +static u8 saa7191_read_reg(struct i2c_client *client, + u8 reg) { - return to_saa7191(sd)->reg[reg]; + return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg]; } -static int saa7191_read_status(struct v4l2_subdev *sd, u8 *value) +static int saa7191_read_status(struct i2c_client *client, + u8 *value) { - struct i2c_client *client = v4l2_get_subdevdata(sd); int ret; ret = i2c_master_recv(client, value, 1); @@ -126,23 +121,21 @@ static int saa7191_read_status(struct v4l2_subdev *sd, u8 *value) } -static int saa7191_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value) +static int saa7191_write_reg(struct i2c_client *client, u8 reg, + u8 value) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - - to_saa7191(sd)->reg[reg] = value; + ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } /* the first byte of data must be the first subaddress number (register) */ -static int saa7191_write_block(struct v4l2_subdev *sd, +static int saa7191_write_block(struct i2c_client *client, u8 length, const u8 *data) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct saa7191 *decoder = to_saa7191(sd); int i; int ret; + struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client); for (i = 0; i < (length - 1); i++) { decoder->reg[data[0] + i] = data[i + 1]; } @@ -159,15 +152,14 @@ static int saa7191_write_block(struct v4l2_subdev *sd, /* Helper functions */ -static int saa7191_s_routing(struct v4l2_subdev *sd, - const struct v4l2_routing *route) +static int saa7191_set_input(struct i2c_client *client, int input) { - struct saa7191 *decoder = to_saa7191(sd); - u8 luma = saa7191_read_reg(sd, SAA7191_REG_LUMA); - u8 iock = saa7191_read_reg(sd, SAA7191_REG_IOCK); + struct saa7191 *decoder = i2c_get_clientdata(client); + u8 luma = saa7191_read_reg(client, SAA7191_REG_LUMA); + u8 iock = saa7191_read_reg(client, SAA7191_REG_IOCK); int err; - switch (route->input) { + switch (input) { case SAA7191_INPUT_COMPOSITE: /* Set Composite input */ iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1 | SAA7191_IOCK_GPSW2); @@ -183,50 +175,54 @@ static int saa7191_s_routing(struct v4l2_subdev *sd, return -EINVAL; } - err = saa7191_write_reg(sd, SAA7191_REG_LUMA, luma); + err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma); if (err) return -EIO; - err = saa7191_write_reg(sd, SAA7191_REG_IOCK, iock); + err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock); if (err) return -EIO; - decoder->input = route->input; + decoder->input = input; return 0; } -static int saa7191_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) +static int saa7191_set_norm(struct i2c_client *client, int norm) { - struct saa7191 *decoder = to_saa7191(sd); - u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC); - u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3); - u8 chcv = saa7191_read_reg(sd, SAA7191_REG_CHCV); + struct saa7191 *decoder = i2c_get_clientdata(client); + u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC); + u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3); + u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV); int err; - if (norm & V4L2_STD_PAL) { + switch(norm) { + case SAA7191_NORM_PAL: stdc &= ~SAA7191_STDC_SECS; ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL); chcv = SAA7191_CHCV_PAL; - } else if (norm & V4L2_STD_NTSC) { + break; + case SAA7191_NORM_NTSC: stdc &= ~SAA7191_STDC_SECS; ctl3 &= ~SAA7191_CTL3_AUFD; ctl3 |= SAA7191_CTL3_FSEL; chcv = SAA7191_CHCV_NTSC; - } else if (norm & V4L2_STD_SECAM) { + break; + case SAA7191_NORM_SECAM: stdc |= SAA7191_STDC_SECS; ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL); chcv = SAA7191_CHCV_PAL; - } else { + break; + default: return -EINVAL; } - err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3); + err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3); if (err) return -EIO; - err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc); + err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc); if (err) return -EIO; - err = saa7191_write_reg(sd, SAA7191_REG_CHCV, chcv); + err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv); if (err) return -EIO; @@ -234,19 +230,19 @@ static int saa7191_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3, stdc, chcv); - dprintk("norm: %llx\n", norm); + dprintk("norm: %d\n", norm); return 0; } -static int saa7191_wait_for_signal(struct v4l2_subdev *sd, u8 *status) +static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status) { int i = 0; dprintk("Checking for signal...\n"); for (i = 0; i < SAA7191_SYNC_COUNT; i++) { - if (saa7191_read_status(sd, status)) + if (saa7191_read_status(client, status)) return -EIO; if (((*status) & SAA7191_STATUS_HLCK) == 0) { @@ -262,34 +258,31 @@ static int saa7191_wait_for_signal(struct v4l2_subdev *sd, u8 *status) return -EBUSY; } -static int saa7191_querystd(struct v4l2_subdev *sd, v4l2_std_id *norm) +static int saa7191_autodetect_norm_extended(struct i2c_client *client) { - struct saa7191 *decoder = to_saa7191(sd); - u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC); - u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3); + u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC); + u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3); u8 status; - v4l2_std_id old_norm = decoder->norm; int err = 0; dprintk("SAA7191 extended signal auto-detection...\n"); - *norm = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM; stdc &= ~SAA7191_STDC_SECS; ctl3 &= ~(SAA7191_CTL3_FSEL); - err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc); + err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc); if (err) { err = -EIO; goto out; } - err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3); + err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3); if (err) { err = -EIO; goto out; } ctl3 |= SAA7191_CTL3_AUFD; - err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3); + err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3); if (err) { err = -EIO; goto out; @@ -297,54 +290,53 @@ static int saa7191_querystd(struct v4l2_subdev *sd, v4l2_std_id *norm) msleep(SAA7191_SYNC_DELAY); - err = saa7191_wait_for_signal(sd, &status); + err = saa7191_wait_for_signal(client, &status); if (err) goto out; if (status & SAA7191_STATUS_FIDT) { /* 60Hz signal -> NTSC */ dprintk("60Hz signal: NTSC\n"); - *norm = V4L2_STD_NTSC; - return 0; + return saa7191_set_norm(client, SAA7191_NORM_NTSC); } /* 50Hz signal */ dprintk("50Hz signal: Trying PAL...\n"); /* try PAL first */ - err = saa7191_s_std(sd, V4L2_STD_PAL); + err = saa7191_set_norm(client, SAA7191_NORM_PAL); if (err) goto out; msleep(SAA7191_SYNC_DELAY); - err = saa7191_wait_for_signal(sd, &status); + err = saa7191_wait_for_signal(client, &status); if (err) goto out; /* not 50Hz ? */ if (status & SAA7191_STATUS_FIDT) { dprintk("No 50Hz signal\n"); - saa7191_s_std(sd, old_norm); - return -EAGAIN; + err = -EAGAIN; + goto out; } if (status & SAA7191_STATUS_CODE) { dprintk("PAL\n"); - *norm = V4L2_STD_PAL; - return saa7191_s_std(sd, old_norm); + return 0; } dprintk("No color detected with PAL - Trying SECAM...\n"); /* no color detected ? -> try SECAM */ - err = saa7191_s_std(sd, V4L2_STD_SECAM); + err = saa7191_set_norm(client, + SAA7191_NORM_SECAM); if (err) goto out; msleep(SAA7191_SYNC_DELAY); - err = saa7191_wait_for_signal(sd, &status); + err = saa7191_wait_for_signal(client, &status); if (err) goto out; @@ -358,17 +350,32 @@ static int saa7191_querystd(struct v4l2_subdev *sd, v4l2_std_id *norm) if (status & SAA7191_STATUS_CODE) { /* Color detected -> SECAM */ dprintk("SECAM\n"); - *norm = V4L2_STD_SECAM; - return saa7191_s_std(sd, old_norm); + return 0; } dprintk("No color detected with SECAM - Going back to PAL.\n"); + /* still no color detected ? + * -> set norm back to PAL */ + err = saa7191_set_norm(client, + SAA7191_NORM_PAL); + if (err) + goto out; + out: - return saa7191_s_std(sd, old_norm); + ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3); + if (ctl3 & SAA7191_CTL3_AUFD) { + ctl3 &= ~(SAA7191_CTL3_AUFD); + err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3); + if (err) { + err = -EIO; + } + } + + return err; } -static int saa7191_autodetect_norm(struct v4l2_subdev *sd) +static int saa7191_autodetect_norm(struct i2c_client *client) { u8 status; @@ -376,7 +383,7 @@ static int saa7191_autodetect_norm(struct v4l2_subdev *sd) dprintk("Reading status...\n"); - if (saa7191_read_status(sd, &status)) + if (saa7191_read_status(client, &status)) return -EIO; dprintk("Checking for signal...\n"); @@ -392,25 +399,26 @@ static int saa7191_autodetect_norm(struct v4l2_subdev *sd) if (status & SAA7191_STATUS_FIDT) { /* 60hz signal -> NTSC */ dprintk("NTSC\n"); - return saa7191_s_std(sd, V4L2_STD_NTSC); + return saa7191_set_norm(client, SAA7191_NORM_NTSC); } else { /* 50hz signal -> PAL */ dprintk("PAL\n"); - return saa7191_s_std(sd, V4L2_STD_PAL); + return saa7191_set_norm(client, SAA7191_NORM_PAL); } } -static int saa7191_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static int saa7191_get_control(struct i2c_client *client, + struct saa7191_control *ctrl) { u8 reg; int ret = 0; - switch (ctrl->id) { + switch (ctrl->type) { case SAA7191_CONTROL_BANDPASS: case SAA7191_CONTROL_BANDPASS_WEIGHT: case SAA7191_CONTROL_CORING: - reg = saa7191_read_reg(sd, SAA7191_REG_LUMA); - switch (ctrl->id) { + reg = saa7191_read_reg(client, SAA7191_REG_LUMA); + switch (ctrl->type) { case SAA7191_CONTROL_BANDPASS: ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK) >> SAA7191_LUMA_BPSS_SHIFT; @@ -427,15 +435,15 @@ static int saa7191_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) break; case SAA7191_CONTROL_FORCE_COLOUR: case SAA7191_CONTROL_CHROMA_GAIN: - reg = saa7191_read_reg(sd, SAA7191_REG_GAIN); - if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) + reg = saa7191_read_reg(client, SAA7191_REG_GAIN); + if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0; else ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK) >> SAA7191_GAIN_LFIS_SHIFT; break; - case V4L2_CID_HUE: - reg = saa7191_read_reg(sd, SAA7191_REG_HUEC); + case SAA7191_CONTROL_HUE: + reg = saa7191_read_reg(client, SAA7191_REG_HUEC); if (reg < 0x80) reg += 0x80; else @@ -443,18 +451,18 @@ static int saa7191_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) ctrl->value = (s32)reg; break; case SAA7191_CONTROL_VTRC: - reg = saa7191_read_reg(sd, SAA7191_REG_STDC); + reg = saa7191_read_reg(client, SAA7191_REG_STDC); ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0; break; case SAA7191_CONTROL_LUMA_DELAY: - reg = saa7191_read_reg(sd, SAA7191_REG_CTL3); + reg = saa7191_read_reg(client, SAA7191_REG_CTL3); ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK) >> SAA7191_CTL3_YDEL_SHIFT; if (ctrl->value >= 4) ctrl->value -= 8; break; case SAA7191_CONTROL_VNR: - reg = saa7191_read_reg(sd, SAA7191_REG_CTL4); + reg = saa7191_read_reg(client, SAA7191_REG_CTL4); ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK) >> SAA7191_CTL4_VNOI_SHIFT; break; @@ -465,17 +473,18 @@ static int saa7191_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) return ret; } -static int saa7191_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static int saa7191_set_control(struct i2c_client *client, + struct saa7191_control *ctrl) { u8 reg; int ret = 0; - switch (ctrl->id) { + switch (ctrl->type) { case SAA7191_CONTROL_BANDPASS: case SAA7191_CONTROL_BANDPASS_WEIGHT: case SAA7191_CONTROL_CORING: - reg = saa7191_read_reg(sd, SAA7191_REG_LUMA); - switch (ctrl->id) { + reg = saa7191_read_reg(client, SAA7191_REG_LUMA); + switch (ctrl->type) { case SAA7191_CONTROL_BANDPASS: reg &= ~SAA7191_LUMA_BPSS_MASK; reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT) @@ -492,12 +501,12 @@ static int saa7191_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) & SAA7191_LUMA_CORI_MASK; break; } - ret = saa7191_write_reg(sd, SAA7191_REG_LUMA, reg); + ret = saa7191_write_reg(client, SAA7191_REG_LUMA, reg); break; case SAA7191_CONTROL_FORCE_COLOUR: case SAA7191_CONTROL_CHROMA_GAIN: - reg = saa7191_read_reg(sd, SAA7191_REG_GAIN); - if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) { + reg = saa7191_read_reg(client, SAA7191_REG_GAIN); + if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) { if (ctrl->value) reg |= SAA7191_GAIN_COLO; else @@ -507,41 +516,41 @@ static int saa7191_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT) & SAA7191_GAIN_LFIS_MASK; } - ret = saa7191_write_reg(sd, SAA7191_REG_GAIN, reg); + ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg); break; - case V4L2_CID_HUE: + case SAA7191_CONTROL_HUE: reg = ctrl->value & 0xff; if (reg < 0x80) reg += 0x80; else reg -= 0x80; - ret = saa7191_write_reg(sd, SAA7191_REG_HUEC, reg); + ret = saa7191_write_reg(client, SAA7191_REG_HUEC, reg); break; case SAA7191_CONTROL_VTRC: - reg = saa7191_read_reg(sd, SAA7191_REG_STDC); + reg = saa7191_read_reg(client, SAA7191_REG_STDC); if (ctrl->value) reg |= SAA7191_STDC_VTRC; else reg &= ~SAA7191_STDC_VTRC; - ret = saa7191_write_reg(sd, SAA7191_REG_STDC, reg); + ret = saa7191_write_reg(client, SAA7191_REG_STDC, reg); break; case SAA7191_CONTROL_LUMA_DELAY: { s32 value = ctrl->value; if (value < 0) value += 8; - reg = saa7191_read_reg(sd, SAA7191_REG_CTL3); + reg = saa7191_read_reg(client, SAA7191_REG_CTL3); reg &= ~SAA7191_CTL3_YDEL_MASK; reg |= (value << SAA7191_CTL3_YDEL_SHIFT) & SAA7191_CTL3_YDEL_MASK; - ret = saa7191_write_reg(sd, SAA7191_REG_CTL3, reg); + ret = saa7191_write_reg(client, SAA7191_REG_CTL3, reg); break; } case SAA7191_CONTROL_VNR: - reg = saa7191_read_reg(sd, SAA7191_REG_CTL4); + reg = saa7191_read_reg(client, SAA7191_REG_CTL4); reg &= ~SAA7191_CTL4_VNOI_MASK; reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT) & SAA7191_CTL4_VNOI_MASK; - ret = saa7191_write_reg(sd, SAA7191_REG_CTL4, reg); + ret = saa7191_write_reg(client, SAA7191_REG_CTL4, reg); break; default: ret = -EINVAL; @@ -552,108 +561,247 @@ static int saa7191_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) /* I2C-interface */ -static int saa7191_g_input_status(struct v4l2_subdev *sd, u32 *status) +static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind) { - u8 status_reg; - int res = V4L2_IN_ST_NO_SIGNAL; + int err = 0; + struct saa7191 *decoder; + struct i2c_client *client; + + printk(KERN_INFO "Philips SAA7191 driver version %s\n", + SAA7191_MODULE_VERSION); + + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client) + return -ENOMEM; + decoder = kzalloc(sizeof(*decoder), GFP_KERNEL); + if (!decoder) { + err = -ENOMEM; + goto out_free_client; + } + + client->addr = addr; + client->adapter = adap; + client->driver = &i2c_driver_saa7191; + client->flags = 0; + strcpy(client->name, "saa7191 client"); + i2c_set_clientdata(client, decoder); + + decoder->client = client; + + err = i2c_attach_client(client); + if (err) + goto out_free_decoder; + + err = saa7191_write_block(client, sizeof(initseq), initseq); + if (err) { + printk(KERN_ERR "SAA7191 initialization failed\n"); + goto out_detach_client; + } + + printk(KERN_INFO "SAA7191 initialized\n"); + + decoder->input = SAA7191_INPUT_COMPOSITE; + decoder->norm = SAA7191_NORM_PAL; + + err = saa7191_autodetect_norm(client); + if (err && (err != -EBUSY)) { + printk(KERN_ERR "SAA7191: Signal auto-detection failed\n"); + } - if (saa7191_read_status(sd, &status_reg)) - return -EIO; - if ((status_reg & SAA7191_STATUS_HLCK) == 0) - res = 0; - if (!(status_reg & SAA7191_STATUS_CODE)) - res |= V4L2_IN_ST_NO_COLOR; - *status = res; return 0; -} +out_detach_client: + i2c_detach_client(client); +out_free_decoder: + kfree(decoder); +out_free_client: + kfree(client); + return err; +} -static int saa7191_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *chip) +static int saa7191_probe(struct i2c_adapter *adap) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7191, 0); + /* Always connected to VINO */ + if (adap->id == I2C_HW_SGI_VINO) + return saa7191_attach(adap, SAA7191_ADDR, 0); + /* Feel free to add probe here :-) */ + return -ENODEV; } -/* ----------------------------------------------------------------------- */ +static int saa7191_detach(struct i2c_client *client) +{ + struct saa7191 *decoder = i2c_get_clientdata(client); -static const struct v4l2_subdev_core_ops saa7191_core_ops = { - .g_chip_ident = saa7191_g_chip_ident, - .g_ctrl = saa7191_g_ctrl, - .s_ctrl = saa7191_s_ctrl, -}; + i2c_detach_client(client); + kfree(decoder); + kfree(client); + return 0; +} -static const struct v4l2_subdev_tuner_ops saa7191_tuner_ops = { - .s_std = saa7191_s_std, -}; +static int saa7191_command(struct i2c_client *client, unsigned int cmd, + void *arg) +{ + struct saa7191 *decoder = i2c_get_clientdata(client); -static const struct v4l2_subdev_video_ops saa7191_video_ops = { - .s_routing = saa7191_s_routing, - .querystd = saa7191_querystd, - .g_input_status = saa7191_g_input_status, -}; + switch (cmd) { + case DECODER_GET_CAPABILITIES: { + struct video_decoder_capability *cap = arg; -static const struct v4l2_subdev_ops saa7191_ops = { - .core = &saa7191_core_ops, - .video = &saa7191_video_ops, - .tuner = &saa7191_tuner_ops, -}; + cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC | + VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO; + cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1; + cap->outputs = 1; + break; + } + case DECODER_GET_STATUS: { + int *iarg = arg; + u8 status; + int res = 0; -static int saa7191_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int err = 0; - struct saa7191 *decoder; - struct v4l2_subdev *sd; + if (saa7191_read_status(client, &status)) { + return -EIO; + } + if ((status & SAA7191_STATUS_HLCK) == 0) + res |= DECODER_STATUS_GOOD; + if (status & SAA7191_STATUS_CODE) + res |= DECODER_STATUS_COLOR; + switch (decoder->norm) { + case SAA7191_NORM_NTSC: + res |= DECODER_STATUS_NTSC; + break; + case SAA7191_NORM_PAL: + res |= DECODER_STATUS_PAL; + break; + case SAA7191_NORM_SECAM: + res |= DECODER_STATUS_SECAM; + break; + case SAA7191_NORM_AUTO: + default: + if (status & SAA7191_STATUS_FIDT) + res |= DECODER_STATUS_NTSC; + else + res |= DECODER_STATUS_PAL; + break; + } + *iarg = res; + break; + } + case DECODER_SET_NORM: { + int *iarg = arg; + + switch (*iarg) { + case VIDEO_MODE_AUTO: + return saa7191_autodetect_norm(client); + case VIDEO_MODE_PAL: + return saa7191_set_norm(client, SAA7191_NORM_PAL); + case VIDEO_MODE_NTSC: + return saa7191_set_norm(client, SAA7191_NORM_NTSC); + case VIDEO_MODE_SECAM: + return saa7191_set_norm(client, SAA7191_NORM_SECAM); + default: + return -EINVAL; + } + break; + } + case DECODER_SET_INPUT: { + int *iarg = arg; + + switch (client->adapter->id) { + case I2C_HW_SGI_VINO: + return saa7191_set_input(client, *iarg); + default: + if (*iarg != 0) + return -EINVAL; + } + break; + } + case DECODER_SET_OUTPUT: { + int *iarg = arg; - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); + /* not much choice of outputs */ + if (*iarg != 0) + return -EINVAL; + break; + } + case DECODER_ENABLE_OUTPUT: { + /* Always enabled */ + break; + } + case DECODER_SET_PICTURE: { + struct video_picture *pic = arg; + unsigned val; + int err; - decoder = kzalloc(sizeof(*decoder), GFP_KERNEL); - if (!decoder) - return -ENOMEM; + val = (pic->hue >> 8) - 0x80; - sd = &decoder->sd; - v4l2_i2c_subdev_init(sd, client, &saa7191_ops); + err = saa7191_write_reg(client, SAA7191_REG_HUEC, val); + if (err) + return -EIO; - err = saa7191_write_block(sd, sizeof(initseq), initseq); - if (err) { - printk(KERN_ERR "SAA7191 initialization failed\n"); - kfree(decoder); - return err; + break; } + case DECODER_SAA7191_GET_STATUS: { + struct saa7191_status *status = arg; + u8 status_reg; - printk(KERN_INFO "SAA7191 initialized\n"); + if (saa7191_read_status(client, &status_reg)) + return -EIO; - decoder->input = SAA7191_INPUT_COMPOSITE; - decoder->norm = V4L2_STD_PAL; + status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0) + ? 1 : 0; + status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT) + ? 1 : 0; + status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0; - err = saa7191_autodetect_norm(sd); - if (err && (err != -EBUSY)) - printk(KERN_ERR "SAA7191: Signal auto-detection failed\n"); + status->input = decoder->input; + status->norm = decoder->norm; + + break; + } + case DECODER_SAA7191_SET_NORM: { + int *norm = arg; + + switch (*norm) { + case SAA7191_NORM_AUTO: + return saa7191_autodetect_norm(client); + case SAA7191_NORM_AUTO_EXT: + return saa7191_autodetect_norm_extended(client); + default: + return saa7191_set_norm(client, *norm); + } + } + case DECODER_SAA7191_GET_CONTROL: { + return saa7191_get_control(client, arg); + } + case DECODER_SAA7191_SET_CONTROL: { + return saa7191_set_control(client, arg); + } + default: + return -EINVAL; + } return 0; } -static int saa7191_remove(struct i2c_client *client) -{ - struct v4l2_subdev *sd = i2c_get_clientdata(client); +static struct i2c_driver i2c_driver_saa7191 = { + .driver = { + .name = "saa7191", + }, + .id = I2C_DRIVERID_SAA7191, + .attach_adapter = saa7191_probe, + .detach_client = saa7191_detach, + .command = saa7191_command +}; - v4l2_device_unregister_subdev(sd); - kfree(to_saa7191(sd)); - return 0; +static int saa7191_init(void) +{ + return i2c_add_driver(&i2c_driver_saa7191); } -static const struct i2c_device_id saa7191_id[] = { - { "saa7191", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, saa7191_id); +static void saa7191_exit(void) +{ + i2c_del_driver(&i2c_driver_saa7191); +} -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "saa7191", - .probe = saa7191_probe, - .remove = saa7191_remove, - .id_table = saa7191_id, -}; +module_init(saa7191_init); +module_exit(saa7191_exit); diff --git a/trunk/drivers/media/video/saa7191.h b/trunk/drivers/media/video/saa7191.h index 803c74d6066f..a2310da1940d 100644 --- a/trunk/drivers/media/video/saa7191.h +++ b/trunk/drivers/media/video/saa7191.h @@ -176,9 +176,11 @@ #define SAA7191_INPUT_COMPOSITE 0 #define SAA7191_INPUT_SVIDEO 1 +#define SAA7191_NORM_AUTO 0 #define SAA7191_NORM_PAL 1 #define SAA7191_NORM_NTSC 2 #define SAA7191_NORM_SECAM 3 +#define SAA7191_NORM_AUTO_EXT 4 /* extended auto-detection */ struct saa7191_status { /* 0=no signal, 1=signal detected */ @@ -230,16 +232,24 @@ struct saa7191_status { #define SAA7191_VNR_MAX 0x03 #define SAA7191_VNR_DEFAULT 0x00 -#define SAA7191_CONTROL_BANDPASS (V4L2_CID_PRIVATE_BASE + 0) -#define SAA7191_CONTROL_BANDPASS_WEIGHT (V4L2_CID_PRIVATE_BASE + 1) -#define SAA7191_CONTROL_CORING (V4L2_CID_PRIVATE_BASE + 2) -#define SAA7191_CONTROL_FORCE_COLOUR (V4L2_CID_PRIVATE_BASE + 3) -#define SAA7191_CONTROL_CHROMA_GAIN (V4L2_CID_PRIVATE_BASE + 4) -#define SAA7191_CONTROL_VTRC (V4L2_CID_PRIVATE_BASE + 5) -#define SAA7191_CONTROL_LUMA_DELAY (V4L2_CID_PRIVATE_BASE + 6) -#define SAA7191_CONTROL_VNR (V4L2_CID_PRIVATE_BASE + 7) +#define SAA7191_CONTROL_BANDPASS 0 +#define SAA7191_CONTROL_BANDPASS_WEIGHT 1 +#define SAA7191_CONTROL_CORING 2 +#define SAA7191_CONTROL_FORCE_COLOUR 3 /* boolean */ +#define SAA7191_CONTROL_CHROMA_GAIN 4 +#define SAA7191_CONTROL_HUE 5 +#define SAA7191_CONTROL_VTRC 6 /* boolean */ +#define SAA7191_CONTROL_LUMA_DELAY 7 +#define SAA7191_CONTROL_VNR 8 + +struct saa7191_control { + u8 type; + s32 value; +}; #define DECODER_SAA7191_GET_STATUS _IOR('d', 195, struct saa7191_status) #define DECODER_SAA7191_SET_NORM _IOW('d', 196, int) +#define DECODER_SAA7191_GET_CONTROL _IOR('d', 197, struct saa7191_control) +#define DECODER_SAA7191_SET_CONTROL _IOW('d', 198, struct saa7191_control) #endif diff --git a/trunk/drivers/media/video/sh_mobile_ceu_camera.c b/trunk/drivers/media/video/sh_mobile_ceu_camera.c index b5e37a530c62..ddcb81d0b81a 100644 --- a/trunk/drivers/media/video/sh_mobile_ceu_camera.c +++ b/trunk/drivers/media/video/sh_mobile_ceu_camera.c @@ -94,37 +94,13 @@ struct sh_mobile_ceu_dev { spinlock_t lock; struct list_head capture; struct videobuf_buffer *active; - int is_interlaced; + int is_interlace; struct sh_mobile_ceu_info *pdata; const struct soc_camera_data_format *camera_fmt; }; -static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev) -{ - unsigned long flags; - - flags = SOCAM_MASTER | - SOCAM_PCLK_SAMPLE_RISING | - SOCAM_HSYNC_ACTIVE_HIGH | - SOCAM_HSYNC_ACTIVE_LOW | - SOCAM_VSYNC_ACTIVE_HIGH | - SOCAM_VSYNC_ACTIVE_LOW | - SOCAM_DATA_ACTIVE_HIGH; - - if (pcdev->pdata->flags & SH_CEU_FLAG_USE_8BIT_BUS) - flags |= SOCAM_DATAWIDTH_8; - - if (pcdev->pdata->flags & SH_CEU_FLAG_USE_16BIT_BUS) - flags |= SOCAM_DATAWIDTH_16; - - if (flags & SOCAM_DATAWIDTH_MASK) - return flags; - - return 0; -} - static void ceu_write(struct sh_mobile_ceu_dev *priv, unsigned long reg_offs, u32 data) { @@ -174,7 +150,6 @@ static void free_buffer(struct videobuf_queue *vq, if (in_interrupt()) BUG(); - videobuf_waiton(&buf->vb, 0, 0); videobuf_dma_contig_free(vq, &buf->vb); dev_dbg(&icd->dev, "%s freed\n", __func__); buf->vb.state = VIDEOBUF_NEEDS_INIT; @@ -206,7 +181,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) phys_addr_top = videobuf_to_dma_contig(pcdev->active); ceu_write(pcdev, CDAYR, phys_addr_top); - if (pcdev->is_interlaced) { + if (pcdev->is_interlace) { phys_addr_bottom = phys_addr_top + icd->width; ceu_write(pcdev, CDBYR, phys_addr_bottom); } @@ -218,7 +193,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) case V4L2_PIX_FMT_NV61: phys_addr_top += icd->width * icd->height; ceu_write(pcdev, CDACR, phys_addr_top); - if (pcdev->is_interlaced) { + if (pcdev->is_interlace) { phys_addr_bottom = phys_addr_top + icd->width; ceu_write(pcdev, CDBCR, phys_addr_bottom); } @@ -421,7 +396,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, camera_flags = icd->ops->query_bus_param(icd); common_flags = soc_camera_bus_param_compatible(camera_flags, - make_bus_param(pcdev)); + pcdev->pdata->flags); if (!common_flags) return -EINVAL; @@ -482,7 +457,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, ceu_write(pcdev, CAMCR, value); ceu_write(pcdev, CAPCR, 0x00300000); - ceu_write(pcdev, CAIFR, pcdev->is_interlaced ? 0x101 : 0); + ceu_write(pcdev, CAIFR, (pcdev->is_interlace) ? 0x101 : 0); mdelay(1); @@ -498,7 +473,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, } height = icd->height; - if (pcdev->is_interlaced) { + if (pcdev->is_interlace) { height /= 2; cdwdr_width *= 2; } @@ -542,7 +517,7 @@ static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd) camera_flags = icd->ops->query_bus_param(icd); common_flags = soc_camera_bus_param_compatible(camera_flags, - make_bus_param(pcdev)); + pcdev->pdata->flags); if (!common_flags) return -EINVAL; @@ -587,29 +562,11 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, if (ret < 0) return 0; - /* Beginning of a pass */ - if (!idx) - icd->host_priv = NULL; - switch (icd->formats[idx].fourcc) { case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_VYUY: case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_YVYU: - if (icd->host_priv) - goto add_single_format; - - /* - * Our case is simple so far: for any of the above four camera - * formats we add all our four synthesized NV* formats, so, - * just marking the device with a single flag suffices. If - * the format generation rules are more complex, you would have - * to actually hang your already added / counted formats onto - * the host_priv pointer and check whether the format you're - * going to add now is already there. - */ - icd->host_priv = (void *)sh_mobile_ceu_formats; - n = ARRAY_SIZE(sh_mobile_ceu_formats); formats += n; for (k = 0; xlate && k < n; k++) { @@ -622,7 +579,6 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, icd->formats[idx].name); } default: -add_single_format: /* Generic pass-through */ formats++; if (xlate) { @@ -639,30 +595,24 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, return formats; } -static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, - struct v4l2_rect *rect) -{ - return icd->ops->set_crop(icd, rect); -} - static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) + __u32 pixfmt, struct v4l2_rect *rect) { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct sh_mobile_ceu_dev *pcdev = ici->priv; - __u32 pixfmt = f->fmt.pix.pixelformat; const struct soc_camera_format_xlate *xlate; - struct v4l2_format cam_f = *f; int ret; + if (!pixfmt) + return icd->ops->set_fmt(icd, pixfmt, rect); + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (!xlate) { dev_warn(&ici->dev, "Format %x not found\n", pixfmt); return -EINVAL; } - cam_f.fmt.pix.pixelformat = xlate->cam_fmt->fourcc; - ret = icd->ops->set_fmt(icd, &cam_f); + ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect); if (!ret) { icd->buswidth = xlate->buswidth; @@ -712,13 +662,13 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, switch (f->fmt.pix.field) { case V4L2_FIELD_INTERLACED: - pcdev->is_interlaced = 1; + pcdev->is_interlace = 1; break; case V4L2_FIELD_ANY: f->fmt.pix.field = V4L2_FIELD_NONE; /* fall-through */ case V4L2_FIELD_NONE: - pcdev->is_interlaced = 0; + pcdev->is_interlace = 0; break; default: ret = -EINVAL; @@ -784,8 +734,7 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q, &sh_mobile_ceu_videobuf_ops, &ici->dev, &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, - pcdev->is_interlaced ? - V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE, + V4L2_FIELD_ANY, sizeof(struct sh_mobile_ceu_buffer), icd); } @@ -795,7 +744,6 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = { .add = sh_mobile_ceu_add_device, .remove = sh_mobile_ceu_remove_device, .get_formats = sh_mobile_ceu_get_formats, - .set_crop = sh_mobile_ceu_set_crop, .set_fmt = sh_mobile_ceu_set_fmt, .try_fmt = sh_mobile_ceu_try_fmt, .reqbufs = sh_mobile_ceu_reqbufs, diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_devtable.h b/trunk/drivers/media/video/sn9c102/sn9c102_devtable.h index 38a716020d7f..8cb3457e778d 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_devtable.h +++ b/trunk/drivers/media/video/sn9c102/sn9c102_devtable.h @@ -96,7 +96,9 @@ static const struct usb_device_id sn9c102_id_table[] = { #if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), }, { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), }, +#endif { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), }, +#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE { SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), }, #endif { SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), }, @@ -121,9 +123,7 @@ static const struct usb_device_id sn9c102_id_table[] = { { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), }, #endif { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), }, -#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), }, -#endif { SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), }, { } }; diff --git a/trunk/drivers/media/video/soc_camera.c b/trunk/drivers/media/video/soc_camera.c index 6d8bfd4d97e2..fcb05f06de8f 100644 --- a/trunk/drivers/media/video/soc_camera.c +++ b/trunk/drivers/media/video/soc_camera.c @@ -30,10 +30,6 @@ #include #include -/* Default to VGA resolution */ -#define DEFAULT_WIDTH 640 -#define DEFAULT_HEIGHT 480 - static LIST_HEAD(hosts); static LIST_HEAD(devices); static DEFINE_MUTEX(list_lock); @@ -260,46 +256,6 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd) vfree(icd->user_formats); } -/* Called with .vb_lock held */ -static int soc_camera_set_fmt(struct soc_camera_file *icf, - struct v4l2_format *f) -{ - struct soc_camera_device *icd = icf->icd; - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - struct v4l2_pix_format *pix = &f->fmt.pix; - int ret; - - /* We always call try_fmt() before set_fmt() or set_crop() */ - ret = ici->ops->try_fmt(icd, f); - if (ret < 0) - return ret; - - ret = ici->ops->set_fmt(icd, f); - if (ret < 0) { - return ret; - } else if (!icd->current_fmt || - icd->current_fmt->fourcc != pix->pixelformat) { - dev_err(&ici->dev, - "Host driver hasn't set up current format correctly!\n"); - return -EINVAL; - } - - icd->width = pix->width; - icd->height = pix->height; - icf->vb_vidq.field = - icd->field = pix->field; - - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n", - f->type); - - dev_dbg(&icd->dev, "set width: %d height: %d\n", - icd->width, icd->height); - - /* set physical bus parameters */ - return ici->ops->set_bus_param(icd, pix->pixelformat); -} - static int soc_camera_open(struct file *file) { struct video_device *vdev; @@ -341,28 +297,14 @@ static int soc_camera_open(struct file *file) /* Now we really have to activate the camera */ if (icd->use_count == 1) { - /* Restore parameters before the last close() per V4L2 API */ - struct v4l2_format f = { - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .fmt.pix = { - .width = icd->width, - .height = icd->height, - .field = icd->field, - .pixelformat = icd->current_fmt->fourcc, - .colorspace = icd->current_fmt->colorspace, - }, - }; - + ret = soc_camera_init_user_formats(icd); + if (ret < 0) + goto eiufmt; ret = ici->ops->add(icd); if (ret < 0) { dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret); goto eiciadd; } - - /* Try to configure with default parameters */ - ret = soc_camera_set_fmt(icf, &f); - if (ret < 0) - goto esfmt; } mutex_unlock(&icd->video_lock); @@ -374,13 +316,10 @@ static int soc_camera_open(struct file *file) return 0; - /* - * First three errors are entered with the .video_lock held - * and use_count == 1 - */ -esfmt: - ici->ops->remove(icd); + /* First two errors are entered with the .video_lock held */ eiciadd: + soc_camera_free_user_formats(icd); +eiufmt: icd->use_count--; mutex_unlock(&icd->video_lock); module_put(ici->ops->owner); @@ -400,9 +339,10 @@ static int soc_camera_close(struct file *file) mutex_lock(&icd->video_lock); icd->use_count--; - if (!icd->use_count) + if (!icd->use_count) { ici->ops->remove(icd); - + soc_camera_free_user_formats(icd); + } mutex_unlock(&icd->video_lock); module_put(icd->ops->owner); @@ -475,10 +415,18 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, { struct soc_camera_file *icf = file->private_data; struct soc_camera_device *icd = icf->icd; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct v4l2_pix_format *pix = &f->fmt.pix; + __u32 pixfmt = pix->pixelformat; int ret; + struct v4l2_rect rect; WARN_ON(priv != file->private_data); + ret = soc_camera_try_fmt_vid_cap(file, priv, f); + if (ret < 0) + return ret; + mutex_lock(&icf->vb_vidq.vb_lock); if (videobuf_queue_is_busy(&icf->vb_vidq)) { @@ -487,7 +435,33 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, goto unlock; } - ret = soc_camera_set_fmt(icf, f); + rect.left = icd->x_current; + rect.top = icd->y_current; + rect.width = pix->width; + rect.height = pix->height; + ret = ici->ops->set_fmt(icd, pix->pixelformat, &rect); + if (ret < 0) { + goto unlock; + } else if (!icd->current_fmt || + icd->current_fmt->fourcc != pixfmt) { + dev_err(&ici->dev, + "Host driver hasn't set up current format correctly!\n"); + ret = -EINVAL; + goto unlock; + } + + icd->width = rect.width; + icd->height = rect.height; + icf->vb_vidq.field = pix->field; + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n", + f->type); + + dev_dbg(&icd->dev, "set width: %d height: %d\n", + icd->width, icd->height); + + /* set physical bus parameters */ + ret = ici->ops->set_bus_param(icd, pixfmt); unlock: mutex_unlock(&icf->vb_vidq.vb_lock); @@ -674,8 +648,8 @@ static int soc_camera_cropcap(struct file *file, void *fh, a->bounds.height = icd->height_max; a->defrect.left = icd->x_min; a->defrect.top = icd->y_min; - a->defrect.width = DEFAULT_WIDTH; - a->defrect.height = DEFAULT_HEIGHT; + a->defrect.width = 640; + a->defrect.height = 480; a->pixelaspect.numerator = 1; a->pixelaspect.denominator = 1; @@ -711,7 +685,7 @@ static int soc_camera_s_crop(struct file *file, void *fh, /* Cropping is allowed during a running capture, guard consistency */ mutex_lock(&icf->vb_vidq.vb_lock); - ret = ici->ops->set_crop(icd, &a->c); + ret = ici->ops->set_fmt(icd, 0, &a->c); if (!ret) { icd->width = a->c.width; icd->height = a->c.height; @@ -870,18 +844,9 @@ static int soc_camera_probe(struct device *dev) qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); icd->exposure = qctrl ? qctrl->default_value : (unsigned short)~0; - - ret = soc_camera_init_user_formats(icd); - if (ret < 0) - goto eiufmt; - - icd->height = DEFAULT_HEIGHT; - icd->width = DEFAULT_WIDTH; - icd->field = V4L2_FIELD_ANY; } - -eiufmt: ici->ops->remove(icd); + eiadd: mutex_unlock(&icd->video_lock); module_put(ici->ops->owner); @@ -900,8 +865,6 @@ static int soc_camera_remove(struct device *dev) if (icd->ops->remove) icd->ops->remove(icd); - soc_camera_free_user_formats(icd); - return 0; } @@ -955,7 +918,6 @@ int soc_camera_host_register(struct soc_camera_host *ici) if (!ici || !ici->ops || !ici->ops->try_fmt || !ici->ops->set_fmt || - !ici->ops->set_crop || !ici->ops->set_bus_param || !ici->ops->querycap || !ici->ops->init_videobuf || @@ -1036,7 +998,6 @@ int soc_camera_device_register(struct soc_camera_device *icd) !icd->ops->release || !icd->ops->start_capture || !icd->ops->stop_capture || - !icd->ops->set_crop || !icd->ops->set_fmt || !icd->ops->try_fmt || !icd->ops->query_bus_param || diff --git a/trunk/drivers/media/video/soc_camera_platform.c b/trunk/drivers/media/video/soc_camera_platform.c index c48676356ab7..013ab06e3180 100644 --- a/trunk/drivers/media/video/soc_camera_platform.c +++ b/trunk/drivers/media/video/soc_camera_platform.c @@ -79,14 +79,8 @@ soc_camera_platform_query_bus_param(struct soc_camera_device *icd) return p->bus_param; } -static int soc_camera_platform_set_crop(struct soc_camera_device *icd, - struct v4l2_rect *rect) -{ - return 0; -} - static int soc_camera_platform_set_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) + __u32 pixfmt, struct v4l2_rect *rect) { return 0; } @@ -131,7 +125,6 @@ static struct soc_camera_ops soc_camera_platform_ops = { .release = soc_camera_platform_release, .start_capture = soc_camera_platform_start_capture, .stop_capture = soc_camera_platform_stop_capture, - .set_crop = soc_camera_platform_set_crop, .set_fmt = soc_camera_platform_set_fmt, .try_fmt = soc_camera_platform_try_fmt, .set_bus_param = soc_camera_platform_set_bus_param, diff --git a/trunk/drivers/media/video/stk-webcam.c b/trunk/drivers/media/video/stk-webcam.c index 1a6d39cbd6f3..26378cf390fc 100644 --- a/trunk/drivers/media/video/stk-webcam.c +++ b/trunk/drivers/media/video/stk-webcam.c @@ -933,6 +933,8 @@ static int stk_vidioc_s_ctrl(struct file *filp, static int stk_vidioc_enum_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_fmtdesc *fmtd) { + fmtd->flags = 0; + switch (fmtd->index) { case 0: fmtd->pixelformat = V4L2_PIX_FMT_RGB565; @@ -990,6 +992,7 @@ static int stk_vidioc_g_fmt_vid_cap(struct file *filp, pix_format->height = stk_sizes[i].h; pix_format->field = V4L2_FIELD_NONE; pix_format->colorspace = V4L2_COLORSPACE_SRGB; + pix_format->priv = 0; pix_format->pixelformat = dev->vsettings.palette; if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8) pix_format->bytesperline = pix_format->width; @@ -1112,6 +1115,8 @@ static int stk_vidioc_reqbufs(struct file *filp, if (dev == NULL) return -ENODEV; + if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; if (rb->memory != V4L2_MEMORY_MMAP) return -EINVAL; if (is_streaming(dev) @@ -1134,10 +1139,16 @@ static int stk_vidioc_reqbufs(struct file *filp, static int stk_vidioc_querybuf(struct file *filp, void *priv, struct v4l2_buffer *buf) { + int index; struct stk_camera *dev = priv; struct stk_sio_buffer *sbuf; - if (buf->index < 0 || buf->index >= dev->n_sbufs) + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + index = buf->index; + + if (index < 0 || index >= dev->n_sbufs) return -EINVAL; sbuf = dev->sio_bufs + buf->index; *buf = sbuf->v4lbuf; @@ -1150,6 +1161,8 @@ static int stk_vidioc_qbuf(struct file *filp, struct stk_camera *dev = priv; struct stk_sio_buffer *sbuf; unsigned long flags; + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; if (buf->memory != V4L2_MEMORY_MMAP) return -EINVAL; @@ -1176,7 +1189,8 @@ static int stk_vidioc_dqbuf(struct file *filp, unsigned long flags; int ret; - if (!is_streaming(dev)) + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE + || !is_streaming(dev)) return -EINVAL; if (filp->f_flags & O_NONBLOCK && list_empty(&dev->sio_full)) @@ -1235,10 +1249,16 @@ static int stk_vidioc_streamoff(struct file *filp, static int stk_vidioc_g_parm(struct file *filp, void *priv, struct v4l2_streamparm *sp) { + if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + sp->parm.capture.capability = 0; + sp->parm.capture.capturemode = 0; /*FIXME This is not correct */ sp->parm.capture.timeperframe.numerator = 1; sp->parm.capture.timeperframe.denominator = 30; sp->parm.capture.readbuffers = 2; + sp->parm.capture.extendedmode = 0; return 0; } diff --git a/trunk/drivers/media/video/tcm825x.c b/trunk/drivers/media/video/tcm825x.c index b30c49248217..29991d1cf13e 100644 --- a/trunk/drivers/media/video/tcm825x.c +++ b/trunk/drivers/media/video/tcm825x.c @@ -50,7 +50,7 @@ struct tcm825x_sensor { }; /* list of image formats supported by TCM825X sensor */ -static const struct v4l2_fmtdesc tcm825x_formats[] = { +const static struct v4l2_fmtdesc tcm825x_formats[] = { { .description = "YUYV (YUV 4:2:2), packed", .pixelformat = V4L2_PIX_FMT_UYVY, @@ -76,15 +76,15 @@ static const struct v4l2_fmtdesc tcm825x_formats[] = { * TCM825X register configuration for all combinations of pixel format and * image size */ -static const struct tcm825x_reg subqcif = { 0x20, TCM825X_PICSIZ }; -static const struct tcm825x_reg qcif = { 0x18, TCM825X_PICSIZ }; -static const struct tcm825x_reg cif = { 0x14, TCM825X_PICSIZ }; -static const struct tcm825x_reg qqvga = { 0x0c, TCM825X_PICSIZ }; -static const struct tcm825x_reg qvga = { 0x04, TCM825X_PICSIZ }; -static const struct tcm825x_reg vga = { 0x00, TCM825X_PICSIZ }; +const static struct tcm825x_reg subqcif = { 0x20, TCM825X_PICSIZ }; +const static struct tcm825x_reg qcif = { 0x18, TCM825X_PICSIZ }; +const static struct tcm825x_reg cif = { 0x14, TCM825X_PICSIZ }; +const static struct tcm825x_reg qqvga = { 0x0c, TCM825X_PICSIZ }; +const static struct tcm825x_reg qvga = { 0x04, TCM825X_PICSIZ }; +const static struct tcm825x_reg vga = { 0x00, TCM825X_PICSIZ }; -static const struct tcm825x_reg yuv422 = { 0x00, TCM825X_PICFMT }; -static const struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT }; +const static struct tcm825x_reg yuv422 = { 0x00, TCM825X_PICFMT }; +const static struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT }; /* Our own specific controls */ #define V4L2_CID_ALC V4L2_CID_PRIVATE_BASE @@ -248,10 +248,10 @@ static struct vcontrol { }; -static const struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] = +const static struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] = { &subqcif, &qqvga, &qcif, &qvga, &cif, &vga }; -static const struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] = +const static struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] = { &yuv422, &rgb565 }; /* diff --git a/trunk/drivers/media/video/tcm825x.h b/trunk/drivers/media/video/tcm825x.h index 5b7e69682368..770ebacfa344 100644 --- a/trunk/drivers/media/video/tcm825x.h +++ b/trunk/drivers/media/video/tcm825x.h @@ -188,7 +188,7 @@ struct tcm825x_platform_data { /* Array of image sizes supported by TCM825X. These must be ordered from * smallest image size to largest. */ -static const struct capture_size tcm825x_sizes[] = { +const static struct capture_size tcm825x_sizes[] = { { 128, 96 }, /* subQCIF */ { 160, 120 }, /* QQVGA */ { 176, 144 }, /* QCIF */ diff --git a/trunk/drivers/media/video/tda7432.c b/trunk/drivers/media/video/tda7432.c index 005f8a468031..0c020585fffb 100644 --- a/trunk/drivers/media/video/tda7432.c +++ b/trunk/drivers/media/video/tda7432.c @@ -50,7 +50,7 @@ #include #include #include -#include +#include #ifndef VIDEO_AUDIO_BALANCE # define VIDEO_AUDIO_BALANCE 32 @@ -69,6 +69,13 @@ MODULE_PARM_DESC(maxvol,"Set maximium volume to +20db (0), default is 0db(1)"); module_param(maxvol, int, S_IRUGO | S_IWUSR); +/* Address to scan (I2C address of this chip) */ +static unsigned short normal_i2c[] = { + I2C_ADDR_TDA7432 >> 1, + I2C_CLIENT_END, +}; + +I2C_CLIENT_INSMOD; /* Structure of address and subaddresses for the tda7432 */ @@ -414,18 +421,21 @@ static int tda7432_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) static int tda7432_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) { switch (qc->id) { - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880); case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); + case V4L2_CID_AUDIO_VOLUME: case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_BASS: case V4L2_CID_AUDIO_TREBLE: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768); + return v4l2_ctrl_query_fill_std(qc); } return -EINVAL; } +static int tda7432_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops tda7432_core_ops = { @@ -488,6 +498,8 @@ MODULE_DEVICE_TABLE(i2c, tda7432_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tda7432", + .driverid = I2C_DRIVERID_TDA7432, + .command = tda7432_command, .probe = tda7432_probe, .remove = tda7432_remove, .id_table = tda7432_id, diff --git a/trunk/drivers/media/video/tda9840.c b/trunk/drivers/media/video/tda9840.c index fe1158094c24..6afb7059502d 100644 --- a/trunk/drivers/media/video/tda9840.c +++ b/trunk/drivers/media/video/tda9840.c @@ -30,8 +30,8 @@ #include #include #include -#include -#include +#include +#include "tda9840.h" MODULE_AUTHOR("Michael Hunold "); MODULE_DESCRIPTION("tda9840 driver"); @@ -56,6 +56,11 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); #define TDA9840_SET_BOTH_R 0x16 #define TDA9840_SET_EXTERNAL 0x7a +/* addresses to scan, found only at 0x42 (7-Bit) */ +static unsigned short normal_i2c[] = { I2C_ADDR_TDA9840, I2C_CLIENT_END }; + +/* magic definition of all other variables and things */ +I2C_CLIENT_INSMOD; static void tda9840_write(struct v4l2_subdev *sd, u8 reg, u8 val) { @@ -132,17 +137,60 @@ static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t) return 0; } -static int tda9840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) +static long tda9840_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + int byte; + + switch (cmd) { + case TDA9840_LEVEL_ADJUST: + byte = *(int *)arg; + v4l2_dbg(1, debug, sd, "TDA9840_LEVEL_ADJUST: %d\n", byte); + + /* check for correct range */ + if (byte > 25 || byte < -20) + return -EINVAL; + + /* calculate actual value to set, see specs, page 18 */ + byte /= 5; + if (0 < byte) + byte += 0x8; + else + byte = -byte; + tda9840_write(sd, LEVEL_ADJUST, byte); + break; + + case TDA9840_STEREO_ADJUST: + byte = *(int *)arg; + v4l2_dbg(1, debug, sd, "TDA9840_STEREO_ADJUST: %d\n", byte); + + /* check for correct range */ + if (byte > 25 || byte < -24) + return -EINVAL; + + /* calculate actual value to set */ + byte /= 5; + if (0 < byte) + byte += 0x20; + else + byte = -byte; + + tda9840_write(sd, STEREO_ADJUST, byte); + break; + default: + return -ENOIOCTLCMD; + } + return 0; +} - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TDA9840, 0); +static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); } /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops tda9840_core_ops = { - .g_chip_ident = tda9840_g_chip_ident, + .ioctl = tda9840_ioctl, }; static const struct v4l2_subdev_tuner_ops tda9840_tuner_ops = { @@ -161,6 +209,8 @@ static int tda9840_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct v4l2_subdev *sd; + int result; + int byte; /* let's see whether this adapter can support what we need */ if (!i2c_check_functionality(client->adapter, @@ -177,9 +227,15 @@ static int tda9840_probe(struct i2c_client *client, v4l2_i2c_subdev_init(sd, client, &tda9840_ops); /* set initial values for level & stereo - adjustment, mode */ - tda9840_write(sd, LEVEL_ADJUST, 0); - tda9840_write(sd, STEREO_ADJUST, 0); + byte = 0; + result = tda9840_ioctl(sd, TDA9840_LEVEL_ADJUST, &byte); + result |= tda9840_ioctl(sd, TDA9840_STEREO_ADJUST, &byte); tda9840_write(sd, SWITCH, TDA9840_SET_STEREO); + if (result) { + v4l2_dbg(1, debug, sd, "could not initialize tda9840\n"); + kfree(sd); + return -ENODEV; + } return 0; } @@ -192,7 +248,12 @@ static int tda9840_remove(struct i2c_client *client) return 0; } - +static int tda9840_legacy_probe(struct i2c_adapter *adapter) +{ + /* Let's see whether this is a known adapter we can attach to. + Prevents conflicts with tvaudio.c. */ + return adapter->id == I2C_HW_SAA7146; +} static const struct i2c_device_id tda9840_id[] = { { "tda9840", 0 }, { } @@ -201,7 +262,10 @@ MODULE_DEVICE_TABLE(i2c, tda9840_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tda9840", + .driverid = I2C_DRIVERID_TDA9840, + .command = tda9840_command, .probe = tda9840_probe, .remove = tda9840_remove, + .legacy_probe = tda9840_legacy_probe, .id_table = tda9840_id, }; diff --git a/trunk/drivers/media/video/tda9840.h b/trunk/drivers/media/video/tda9840.h new file mode 100644 index 000000000000..dc12ae7caf6f --- /dev/null +++ b/trunk/drivers/media/video/tda9840.h @@ -0,0 +1,14 @@ +#ifndef __INCLUDED_TDA9840__ +#define __INCLUDED_TDA9840__ + +#define I2C_ADDR_TDA9840 0x42 + +/* values may range between +2.5 and -2.0; + the value has to be multiplied with 10 */ +#define TDA9840_LEVEL_ADJUST _IOW('v',3,int) + +/* values may range between +2.5 and -2.4; + the value has to be multiplied with 10 */ +#define TDA9840_STEREO_ADJUST _IOW('v',4,int) + +#endif diff --git a/trunk/drivers/media/video/tda9875.c b/trunk/drivers/media/video/tda9875.c index 24e2b7d2ae58..00c6cbe06ab0 100644 --- a/trunk/drivers/media/video/tda9875.c +++ b/trunk/drivers/media/video/tda9875.c @@ -28,13 +28,20 @@ #include #include #include -#include +#include #include static int debug; /* insmod parameter */ module_param(debug, int, S_IRUGO | S_IWUSR); MODULE_LICENSE("GPL"); +/* Addresses to scan */ +static unsigned short normal_i2c[] = { + I2C_ADDR_TDA9875 >> 1, + I2C_CLIENT_END +}; + +I2C_CLIENT_INSMOD; /* This is a superset of the TDA9875 */ struct tda9875 { @@ -306,14 +313,18 @@ static int tda9875_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) { switch (qc->id) { case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880); case V4L2_CID_AUDIO_BASS: case V4L2_CID_AUDIO_TREBLE: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768); + return v4l2_ctrl_query_fill_std(qc); } return -EINVAL; } +static int tda9875_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops tda9875_core_ops = { @@ -390,6 +401,8 @@ MODULE_DEVICE_TABLE(i2c, tda9875_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tda9875", + .driverid = I2C_DRIVERID_TDA9875, + .command = tda9875_command, .probe = tda9875_probe, .remove = tda9875_remove, .id_table = tda9875_id, diff --git a/trunk/drivers/media/video/tea6415c.c b/trunk/drivers/media/video/tea6415c.c index d61c56f42bcd..7519fd1f57ef 100644 --- a/trunk/drivers/media/video/tea6415c.c +++ b/trunk/drivers/media/video/tea6415c.c @@ -32,8 +32,7 @@ #include #include #include -#include -#include +#include #include "tea6415c.h" MODULE_AUTHOR("Michael Hunold "); @@ -45,22 +44,25 @@ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +/* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */ +static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END }; -/* makes a connection between the input-pin 'i' and the output-pin 'o' */ -static int tea6415c_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) +/* magic definition of all other variables and things */ +I2C_CLIENT_INSMOD; + +/* makes a connection between the input-pin 'i' and the output-pin 'o' + for the tea6415c-client 'client' */ +static int switch_matrix(struct i2c_client *client, int i, int o) { - struct i2c_client *client = v4l2_get_subdevdata(sd); u8 byte = 0; - u32 i = route->input; - u32 o = route->output; int ret; - v4l2_dbg(1, debug, sd, "i=%d, o=%d\n", i, o); + v4l_dbg(1, debug, client, "i=%d, o=%d\n", i, o); /* check if the pins are valid */ if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i) && (18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o))) - return -EINVAL; + return -1; /* to understand this, have a look at the tea6415c-specs (p.5) */ switch (o) { @@ -113,33 +115,37 @@ static int tea6415c_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing ret = i2c_smbus_write_byte(client, byte); if (ret) { - v4l2_dbg(1, debug, sd, + v4l_dbg(1, debug, client, "i2c_smbus_write_byte() failed, ret:%d\n", ret); return -EIO; } return ret; } -static int tea6415c_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) +static long tea6415c_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + if (cmd == TEA6415C_SWITCH) { + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg; - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6415C, 0); + return switch_matrix(client, v->in, v->out); + } + return -ENOIOCTLCMD; +} + +static int tea6415c_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); } /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops tea6415c_core_ops = { - .g_chip_ident = tea6415c_g_chip_ident, -}; - -static const struct v4l2_subdev_video_ops tea6415c_video_ops = { - .s_routing = tea6415c_s_routing, + .ioctl = tea6415c_ioctl, }; static const struct v4l2_subdev_ops tea6415c_ops = { .core = &tea6415c_core_ops, - .video = &tea6415c_video_ops, }; /* this function is called by i2c_probe */ @@ -170,6 +176,12 @@ static int tea6415c_remove(struct i2c_client *client) return 0; } +static int tea6415c_legacy_probe(struct i2c_adapter *adapter) +{ + /* Let's see whether this is a known adapter we can attach to. + Prevents conflicts with tvaudio.c. */ + return adapter->id == I2C_HW_SAA7146; +} static const struct i2c_device_id tea6415c_id[] = { { "tea6415c", 0 }, @@ -179,7 +191,10 @@ MODULE_DEVICE_TABLE(i2c, tea6415c_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tea6415c", + .driverid = I2C_DRIVERID_TEA6415C, + .command = tea6415c_command, .probe = tea6415c_probe, .remove = tea6415c_remove, + .legacy_probe = tea6415c_legacy_probe, .id_table = tea6415c_id, }; diff --git a/trunk/drivers/media/video/tea6415c.h b/trunk/drivers/media/video/tea6415c.h index 3a47d697536e..f84ed80050b3 100644 --- a/trunk/drivers/media/video/tea6415c.h +++ b/trunk/drivers/media/video/tea6415c.h @@ -1,6 +1,10 @@ #ifndef __INCLUDED_TEA6415C__ #define __INCLUDED_TEA6415C__ +/* possible i2c-addresses */ +#define I2C_TEA6415C_1 0x03 +#define I2C_TEA6415C_2 0x43 + /* the tea6415c's design is quite brain-dead. although there are 8 inputs and 6 outputs, these aren't enumerated in any way. because I don't want to say "connect input pin 20 to output pin 17", I define @@ -24,4 +28,12 @@ #define TEA6415C_INPUT7 1 #define TEA6415C_INPUT8 11 +struct tea6415c_multiplex +{ + int in; /* input-pin */ + int out; /* output-pin */ +}; + +#define TEA6415C_SWITCH _IOW('v',1,struct tea6415c_multiplex) + #endif diff --git a/trunk/drivers/media/video/tea6420.c b/trunk/drivers/media/video/tea6420.c index 34922232402a..081e74fa3b2e 100644 --- a/trunk/drivers/media/video/tea6420.c +++ b/trunk/drivers/media/video/tea6420.c @@ -32,8 +32,7 @@ #include #include #include -#include -#include +#include #include "tea6420.h" MODULE_AUTHOR("Michael Hunold "); @@ -45,23 +44,24 @@ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +/* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ +static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I2C_CLIENT_END }; + +/* magic definition of all other variables and things */ +I2C_CLIENT_INSMOD; /* make a connection between the input 'i' and the output 'o' - with gain 'g' (note: i = 6 means 'mute') */ -static int tea6420_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) + with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */ +static int tea6420_switch(struct i2c_client *client, int i, int o, int g) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - int i = route->input; - int o = route->output & 0xf; - int g = (route->output >> 4) & 0xf; u8 byte; int ret; - v4l2_dbg(1, debug, sd, "i=%d, o=%d, g=%d\n", i, o, g); + v4l_dbg(1, debug, client, "i=%d, o=%d, g=%d\n", i, o, g); /* check if the parameters are valid */ if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0) - return -EINVAL; + return -1; byte = ((o - 1) << 5); byte |= (i - 1); @@ -83,33 +83,37 @@ static int tea6420_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing * ret = i2c_smbus_write_byte(client, byte); if (ret) { - v4l2_dbg(1, debug, sd, + v4l_dbg(1, debug, client, "i2c_smbus_write_byte() failed, ret:%d\n", ret); return -EIO; } return 0; } -static int tea6420_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) +static long tea6420_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + if (cmd == TEA6420_SWITCH) { + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg; - return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6420, 0); + return tea6420_switch(client, a->in, a->out, a->gain); + } + return -ENOIOCTLCMD; +} + +static int tea6420_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); } /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops tea6420_core_ops = { - .g_chip_ident = tea6420_g_chip_ident, -}; - -static const struct v4l2_subdev_audio_ops tea6420_audio_ops = { - .s_routing = tea6420_s_routing, + .ioctl = tea6420_ioctl, }; static const struct v4l2_subdev_ops tea6420_ops = { .core = &tea6420_core_ops, - .audio = &tea6420_audio_ops, }; /* this function is called by i2c_probe */ @@ -126,24 +130,20 @@ static int tea6420_probe(struct i2c_client *client, v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); - sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); - if (sd == NULL) - return -ENOMEM; - v4l2_i2c_subdev_init(sd, client, &tea6420_ops); - /* set initial values: set "mute"-input to all outputs at gain 0 */ err = 0; for (i = 1; i < 5; i++) { - struct v4l2_routing route; - - route.input = 6; - route.output = i; - err += tea6420_s_routing(sd, &route); + err += tea6420_switch(client, 6, i, 0); } if (err) { v4l_dbg(1, debug, client, "could not initialize tea6420\n"); return -ENODEV; } + + sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); + if (sd == NULL) + return -ENOMEM; + v4l2_i2c_subdev_init(sd, client, &tea6420_ops); return 0; } @@ -156,6 +156,12 @@ static int tea6420_remove(struct i2c_client *client) return 0; } +static int tea6420_legacy_probe(struct i2c_adapter *adapter) +{ + /* Let's see whether this is a known adapter we can attach to. + Prevents conflicts with tvaudio.c. */ + return adapter->id == I2C_HW_SAA7146; +} static const struct i2c_device_id tea6420_id[] = { { "tea6420", 0 }, @@ -165,7 +171,10 @@ MODULE_DEVICE_TABLE(i2c, tea6420_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tea6420", + .driverid = I2C_DRIVERID_TEA6420, + .command = tea6420_command, .probe = tea6420_probe, .remove = tea6420_remove, + .legacy_probe = tea6420_legacy_probe, .id_table = tea6420_id, }; diff --git a/trunk/drivers/media/video/tea6420.h b/trunk/drivers/media/video/tea6420.h index 4aa3edb3e193..5ef7c18e0c54 100644 --- a/trunk/drivers/media/video/tea6420.h +++ b/trunk/drivers/media/video/tea6420.h @@ -1,24 +1,17 @@ #ifndef __INCLUDED_TEA6420__ #define __INCLUDED_TEA6420__ -/* input pins */ -#define TEA6420_OUTPUT1 1 -#define TEA6420_OUTPUT2 2 -#define TEA6420_OUTPUT3 3 -#define TEA6420_OUTPUT4 4 +/* possible addresses */ +#define I2C_ADDR_TEA6420_1 0x4c +#define I2C_ADDR_TEA6420_2 0x4d -/* output pins */ -#define TEA6420_INPUT1 1 -#define TEA6420_INPUT2 2 -#define TEA6420_INPUT3 3 -#define TEA6420_INPUT4 4 -#define TEA6420_INPUT5 5 -#define TEA6420_INPUT6 6 +struct tea6420_multiplex +{ + int in; /* input of audio switch */ + int out; /* output of audio switch */ + int gain; /* gain of connection */ +}; -/* gain on the output pins, ORed with the output pin */ -#define TEA6420_GAIN0 0x00 -#define TEA6420_GAIN2 0x20 -#define TEA6420_GAIN4 0x40 -#define TEA6420_GAIN6 0x60 +#define TEA6420_SWITCH _IOW('v',1,struct tea6420_multiplex) #endif diff --git a/trunk/drivers/media/video/tlv320aic23b.c b/trunk/drivers/media/video/tlv320aic23b.c index 07789c64814c..5c95ecd09dc2 100644 --- a/trunk/drivers/media/video/tlv320aic23b.c +++ b/trunk/drivers/media/video/tlv320aic23b.c @@ -31,12 +31,15 @@ #include #include #include -#include +#include MODULE_DESCRIPTION("tlv320aic23b driver"); MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil"); MODULE_LICENSE("GPL"); +static unsigned short normal_i2c[] = { 0x34 >> 1, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; /* ----------------------------------------------------------------------- */ @@ -118,6 +121,11 @@ static int tlv320aic23b_log_status(struct v4l2_subdev *sd) return 0; } +static int tlv320aic23b_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops tlv320aic23b_core_ops = { @@ -200,6 +208,8 @@ MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tlv320aic23b", + .driverid = I2C_DRIVERID_TLV320AIC23B, + .command = tlv320aic23b_command, .probe = tlv320aic23b_probe, .remove = tlv320aic23b_remove, .id_table = tlv320aic23b_id, diff --git a/trunk/drivers/media/video/tuner-core.c b/trunk/drivers/media/video/tuner-core.c index 72d41032742d..30640fbfd0f9 100644 --- a/trunk/drivers/media/video/tuner-core.c +++ b/trunk/drivers/media/video/tuner-core.c @@ -364,8 +364,7 @@ static void set_type(struct i2c_client *c, unsigned int type, } t->type = type; - /* prevent invalid config values */ - t->config = ((new_config >= 0) && (new_config < 256)) ? new_config : 0; + t->config = new_config; if (tuner_callback != NULL) { tuner_dbg("defining GPIO callback\n"); t->fe.callback = tuner_callback; @@ -453,8 +452,7 @@ static void set_type(struct i2c_client *c, unsigned int type, struct dvb_tuner_ops *xc_tuner_ops; xc5000_cfg.i2c_address = t->i2c->addr; - /* if_khz will be set when the digital dvb_attach() occurs */ - xc5000_cfg.if_khz = 0; + xc5000_cfg.if_khz = 5380; if (!dvb_attach(xc5000_attach, &t->fe, t->i2c->adapter, &xc5000_cfg)) goto attach_failed; @@ -778,7 +776,8 @@ static int tuner_s_radio(struct v4l2_subdev *sd) struct tuner *t = to_tuner(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - if (set_mode(client, t, V4L2_TUNER_RADIO, "s_radio") == -EINVAL) + if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO") + == -EINVAL) return 0; if (t->radio_freq) set_freq(client, t->radio_freq); @@ -792,7 +791,7 @@ static int tuner_s_standby(struct v4l2_subdev *sd, u32 standby) tuner_dbg("Putting tuner to sleep\n"); - if (check_mode(t, "s_standby") == -EINVAL) + if (check_mode(t, "TUNER_SET_STANDBY") == -EINVAL) return 0; t->mode = T_STANDBY; if (analog_ops->standby) @@ -800,6 +799,132 @@ static int tuner_s_standby(struct v4l2_subdev *sd, u32 standby) return 0; } +#ifdef CONFIG_VIDEO_ALLOW_V4L1 +static long tuner_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct tuner *t = to_tuner(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; + struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; + + switch (cmd) { + case VIDIOCSAUDIO: + if (check_mode(t, "VIDIOCSAUDIO") == -EINVAL) + return 0; + if (check_v4l2(t) == -EINVAL) + return 0; + + /* Should be implemented, since bttv calls it */ + tuner_dbg("VIDIOCSAUDIO not implemented.\n"); + break; + case VIDIOCSCHAN: + { + static const v4l2_std_id map[] = { + [VIDEO_MODE_PAL] = V4L2_STD_PAL, + [VIDEO_MODE_NTSC] = V4L2_STD_NTSC_M, + [VIDEO_MODE_SECAM] = V4L2_STD_SECAM, + [4 /* bttv */ ] = V4L2_STD_PAL_M, + [5 /* bttv */ ] = V4L2_STD_PAL_N, + [6 /* bttv */ ] = V4L2_STD_NTSC_M_JP, + }; + struct video_channel *vc = arg; + + if (check_v4l2(t) == -EINVAL) + return 0; + + if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==-EINVAL) + return 0; + + if (vc->norm < ARRAY_SIZE(map)) + t->std = map[vc->norm]; + tuner_fixup_std(t); + if (t->tv_freq) + set_tv_freq(client, t->tv_freq); + return 0; + } + case VIDIOCSFREQ: + { + unsigned long *v = arg; + + if (check_mode(t, "VIDIOCSFREQ") == -EINVAL) + return 0; + if (check_v4l2(t) == -EINVAL) + return 0; + + set_freq(client, *v); + return 0; + } + case VIDIOCGTUNER: + { + struct video_tuner *vt = arg; + + if (check_mode(t, "VIDIOCGTUNER") == -EINVAL) + return 0; + if (check_v4l2(t) == -EINVAL) + return 0; + + if (V4L2_TUNER_RADIO == t->mode) { + if (fe_tuner_ops->get_status) { + u32 tuner_status; + + fe_tuner_ops->get_status(&t->fe, &tuner_status); + if (tuner_status & TUNER_STATUS_STEREO) + vt->flags |= VIDEO_TUNER_STEREO_ON; + else + vt->flags &= ~VIDEO_TUNER_STEREO_ON; + } else { + if (analog_ops->is_stereo) { + if (analog_ops->is_stereo(&t->fe)) + vt->flags |= + VIDEO_TUNER_STEREO_ON; + else + vt->flags &= + ~VIDEO_TUNER_STEREO_ON; + } + } + if (analog_ops->has_signal) + vt->signal = + analog_ops->has_signal(&t->fe); + + vt->flags |= VIDEO_TUNER_LOW; /* Allow freqs at 62.5 Hz */ + + vt->rangelow = radio_range[0] * 16000; + vt->rangehigh = radio_range[1] * 16000; + + } else { + vt->rangelow = tv_range[0] * 16; + vt->rangehigh = tv_range[1] * 16; + } + + return 0; + } + case VIDIOCGAUDIO: + { + struct video_audio *va = arg; + + if (check_mode(t, "VIDIOCGAUDIO") == -EINVAL) + return 0; + if (check_v4l2(t) == -EINVAL) + return 0; + + if (V4L2_TUNER_RADIO == t->mode) { + if (fe_tuner_ops->get_status) { + u32 tuner_status; + + fe_tuner_ops->get_status(&t->fe, &tuner_status); + va->mode = (tuner_status & TUNER_STATUS_STEREO) + ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; + } else if (analog_ops->is_stereo) + va->mode = analog_ops->is_stereo(&t->fe) + ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; + } + return 0; + } + } + return -ENOIOCTLCMD; +} +#endif + static int tuner_s_config(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *cfg) { struct tuner *t = to_tuner(sd); @@ -825,7 +950,8 @@ static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std) struct tuner *t = to_tuner(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "s_std") == -EINVAL) + if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD") + == -EINVAL) return 0; switch_v4l2(); @@ -842,7 +968,8 @@ static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) struct tuner *t = to_tuner(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - if (set_mode(client, t, f->type, "s_frequency") == -EINVAL) + if (set_mode(client, t, f->type, "VIDIOC_S_FREQUENCY") + == -EINVAL) return 0; switch_v4l2(); set_freq(client, f->frequency); @@ -855,7 +982,7 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) struct tuner *t = to_tuner(sd); struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; - if (check_mode(t, "g_frequency") == -EINVAL) + if (check_mode(t, "VIDIOC_G_FREQUENCY") == -EINVAL) return 0; switch_v4l2(); f->type = t->mode; @@ -879,7 +1006,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; - if (check_mode(t, "g_tuner") == -EINVAL) + if (check_mode(t, "VIDIOC_G_TUNER") == -EINVAL) return 0; switch_v4l2(); @@ -928,7 +1055,7 @@ static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) struct tuner *t = to_tuner(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - if (check_mode(t, "s_tuner") == -EINVAL) + if (check_mode(t, "VIDIOC_S_TUNER") == -EINVAL) return 0; switch_v4l2(); @@ -985,6 +1112,9 @@ static int tuner_resume(struct i2c_client *c) static const struct v4l2_subdev_core_ops tuner_core_ops = { .log_status = tuner_log_status, .s_standby = tuner_s_standby, +#ifdef CONFIG_VIDEO_ALLOW_V4L1 + .ioctl = tuner_ioctl, +#endif }; static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = { diff --git a/trunk/drivers/media/video/tvaudio.c b/trunk/drivers/media/video/tvaudio.c index 226bf3565ac9..076ed5bf48b1 100644 --- a/trunk/drivers/media/video/tvaudio.c +++ b/trunk/drivers/media/video/tvaudio.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include @@ -1047,116 +1047,6 @@ static int tda9874a_initialize(struct CHIPSTATE *chip) return 0; } -/* ---------------------------------------------------------------------- */ -/* audio chip description - defines+functions for tda9875 */ -/* The TDA9875 is made by Philips Semiconductor - * http://www.semiconductors.philips.com - * TDA9875: I2C-bus controlled DSP audio processor, FM demodulator - * - */ - -/* subaddresses for TDA9875 */ -#define TDA9875_MUT 0x12 /*General mute (value --> 0b11001100*/ -#define TDA9875_CFG 0x01 /* Config register (value --> 0b00000000 */ -#define TDA9875_DACOS 0x13 /*DAC i/o select (ADC) 0b0000100*/ -#define TDA9875_LOSR 0x16 /*Line output select regirter 0b0100 0001*/ - -#define TDA9875_CH1V 0x0c /*Channel 1 volume (mute)*/ -#define TDA9875_CH2V 0x0d /*Channel 2 volume (mute)*/ -#define TDA9875_SC1 0x14 /*SCART 1 in (mono)*/ -#define TDA9875_SC2 0x15 /*SCART 2 in (mono)*/ - -#define TDA9875_ADCIS 0x17 /*ADC input select (mono) 0b0110 000*/ -#define TDA9875_AER 0x19 /*Audio effect (AVL+Pseudo) 0b0000 0110*/ -#define TDA9875_MCS 0x18 /*Main channel select (DAC) 0b0000100*/ -#define TDA9875_MVL 0x1a /* Main volume gauche */ -#define TDA9875_MVR 0x1b /* Main volume droite */ -#define TDA9875_MBA 0x1d /* Main Basse */ -#define TDA9875_MTR 0x1e /* Main treble */ -#define TDA9875_ACS 0x1f /* Auxilary channel select (FM) 0b0000000*/ -#define TDA9875_AVL 0x20 /* Auxilary volume gauche */ -#define TDA9875_AVR 0x21 /* Auxilary volume droite */ -#define TDA9875_ABA 0x22 /* Auxilary Basse */ -#define TDA9875_ATR 0x23 /* Auxilary treble */ - -#define TDA9875_MSR 0x02 /* Monitor select register */ -#define TDA9875_C1MSB 0x03 /* Carrier 1 (FM) frequency register MSB */ -#define TDA9875_C1MIB 0x04 /* Carrier 1 (FM) frequency register (16-8]b */ -#define TDA9875_C1LSB 0x05 /* Carrier 1 (FM) frequency register LSB */ -#define TDA9875_C2MSB 0x06 /* Carrier 2 (nicam) frequency register MSB */ -#define TDA9875_C2MIB 0x07 /* Carrier 2 (nicam) frequency register (16-8]b */ -#define TDA9875_C2LSB 0x08 /* Carrier 2 (nicam) frequency register LSB */ -#define TDA9875_DCR 0x09 /* Demodulateur configuration regirter*/ -#define TDA9875_DEEM 0x0a /* FM de-emphasis regirter*/ -#define TDA9875_FMAT 0x0b /* FM Matrix regirter*/ - -/* values */ -#define TDA9875_MUTE_ON 0xff /* general mute */ -#define TDA9875_MUTE_OFF 0xcc /* general no mute */ - -static int tda9875_initialize(struct CHIPSTATE *chip) -{ - chip_write(chip, TDA9875_CFG, 0xd0); /*reg de config 0 (reset)*/ - chip_write(chip, TDA9875_MSR, 0x03); /* Monitor 0b00000XXX*/ - chip_write(chip, TDA9875_C1MSB, 0x00); /*Car1(FM) MSB XMHz*/ - chip_write(chip, TDA9875_C1MIB, 0x00); /*Car1(FM) MIB XMHz*/ - chip_write(chip, TDA9875_C1LSB, 0x00); /*Car1(FM) LSB XMHz*/ - chip_write(chip, TDA9875_C2MSB, 0x00); /*Car2(NICAM) MSB XMHz*/ - chip_write(chip, TDA9875_C2MIB, 0x00); /*Car2(NICAM) MIB XMHz*/ - chip_write(chip, TDA9875_C2LSB, 0x00); /*Car2(NICAM) LSB XMHz*/ - chip_write(chip, TDA9875_DCR, 0x00); /*Demod config 0x00*/ - chip_write(chip, TDA9875_DEEM, 0x44); /*DE-Emph 0b0100 0100*/ - chip_write(chip, TDA9875_FMAT, 0x00); /*FM Matrix reg 0x00*/ - chip_write(chip, TDA9875_SC1, 0x00); /* SCART 1 (SC1)*/ - chip_write(chip, TDA9875_SC2, 0x01); /* SCART 2 (sc2)*/ - - chip_write(chip, TDA9875_CH1V, 0x10); /* Channel volume 1 mute*/ - chip_write(chip, TDA9875_CH2V, 0x10); /* Channel volume 2 mute */ - chip_write(chip, TDA9875_DACOS, 0x02); /* sig DAC i/o(in:nicam)*/ - chip_write(chip, TDA9875_ADCIS, 0x6f); /* sig ADC input(in:mono)*/ - chip_write(chip, TDA9875_LOSR, 0x00); /* line out (in:mono)*/ - chip_write(chip, TDA9875_AER, 0x00); /*06 Effect (AVL+PSEUDO) */ - chip_write(chip, TDA9875_MCS, 0x44); /* Main ch select (DAC) */ - chip_write(chip, TDA9875_MVL, 0x03); /* Vol Main left 10dB */ - chip_write(chip, TDA9875_MVR, 0x03); /* Vol Main right 10dB*/ - chip_write(chip, TDA9875_MBA, 0x00); /* Main Bass Main 0dB*/ - chip_write(chip, TDA9875_MTR, 0x00); /* Main Treble Main 0dB*/ - chip_write(chip, TDA9875_ACS, 0x44); /* Aux chan select (dac)*/ - chip_write(chip, TDA9875_AVL, 0x00); /* Vol Aux left 0dB*/ - chip_write(chip, TDA9875_AVR, 0x00); /* Vol Aux right 0dB*/ - chip_write(chip, TDA9875_ABA, 0x00); /* Aux Bass Main 0dB*/ - chip_write(chip, TDA9875_ATR, 0x00); /* Aux Aigus Main 0dB*/ - - chip_write(chip, TDA9875_MUT, 0xcc); /* General mute */ - return 0; -} - -static int tda9875_volume(int val) { return (unsigned char)(val / 602 - 84); } -static int tda9875_bass(int val) { return (unsigned char)(max(-12, val / 2115 - 15)); } -static int tda9875_treble(int val) { return (unsigned char)(val / 2622 - 12); } - -/* ----------------------------------------------------------------------- */ - - -/* *********************** * - * i2c interface functions * - * *********************** */ - -static int tda9875_checkit(struct CHIPSTATE *chip) -{ - struct v4l2_subdev *sd = &chip->sd; - int dic, rev; - - dic = chip_read2(chip, 254); - rev = chip_read2(chip, 255); - - if (dic == 0 || dic == 2) { /* tda9875 and tda9875A */ - v4l2_info(sd, "found tda9875%s rev. %d.\n", - dic == 0 ? "" : "A", rev); - return 1; - } - return 0; -} /* ---------------------------------------------------------------------- */ /* audio chip descriptions - defines+functions for tea6420 */ @@ -1390,7 +1280,6 @@ static int tda9850 = 1; static int tda9855 = 1; static int tda9873 = 1; static int tda9874a = 1; -static int tda9875 = 1; static int tea6300; /* default 0 - address clash with msp34xx */ static int tea6320; /* default 0 - address clash with msp34xx */ static int tea6420 = 1; @@ -1403,7 +1292,6 @@ module_param(tda9850, int, 0444); module_param(tda9855, int, 0444); module_param(tda9873, int, 0444); module_param(tda9874a, int, 0444); -module_param(tda9875, int, 0444); module_param(tea6300, int, 0444); module_param(tea6320, int, 0444); module_param(tea6420, int, 0444); @@ -1460,26 +1348,6 @@ static struct CHIPDESC chiplist[] = { .getmode = tda9874a_getmode, .setmode = tda9874a_setmode, }, - { - .name = "tda9875", - .insmodopt = &tda9875, - .addr_lo = I2C_ADDR_TDA9875 >> 1, - .addr_hi = I2C_ADDR_TDA9875 >> 1, - .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE, - - /* callbacks */ - .initialize = tda9875_initialize, - .checkit = tda9875_checkit, - .volfunc = tda9875_volume, - .bassfunc = tda9875_bass, - .treblefunc = tda9875_treble, - .leftreg = TDA9875_MVL, - .rightreg = TDA9875_MVR, - .bassreg = TDA9875_MBA, - .treblereg = TDA9875_MTR, - .leftinit = 58880, - .rightinit = 58880, - }, { .name = "tda9850", .insmodopt = &tda9850, @@ -1643,8 +1511,6 @@ static int tvaudio_g_ctrl(struct v4l2_subdev *sd, switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: - if (!(desc->flags & CHIP_HAS_INPUTSEL)) - break; ctrl->value=chip->muted; return 0; case V4L2_CID_AUDIO_VOLUME: @@ -1686,9 +1552,6 @@ static int tvaudio_s_ctrl(struct v4l2_subdev *sd, switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: - if (!(desc->flags & CHIP_HAS_INPUTSEL)) - break; - if (ctrl->value < 0 || ctrl->value >= 2) return -ERANGE; chip->muted = ctrl->value; @@ -1773,26 +1636,21 @@ static int tvaudio_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) switch (qc->id) { case V4L2_CID_AUDIO_MUTE: - if (desc->flags & CHIP_HAS_INPUTSEL) - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); break; case V4L2_CID_AUDIO_VOLUME: - if (desc->flags & CHIP_HAS_VOLUME) - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880); - break; case V4L2_CID_AUDIO_BALANCE: - if (desc->flags & CHIP_HAS_VOLUME) - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768); + if (!(desc->flags & CHIP_HAS_VOLUME)) + return -EINVAL; break; case V4L2_CID_AUDIO_BASS: case V4L2_CID_AUDIO_TREBLE: - if (desc->flags & CHIP_HAS_BASSTREBLE) - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768); + if (!(desc->flags & CHIP_HAS_BASSTREBLE)) + return -EINVAL; break; default: - break; + return -EINVAL; } - return -EINVAL; + return v4l2_ctrl_query_fill_std(qc); } static int tvaudio_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *rt) @@ -1800,9 +1658,7 @@ static int tvaudio_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing * struct CHIPSTATE *chip = to_state(sd); struct CHIPDESC *desc = chip->desc; - if (!(desc->flags & CHIP_HAS_INPUTSEL)) - return 0; - if (rt->input >= 4) + if (!(desc->flags & CHIP_HAS_INPUTSEL) || rt->input >= 4) return -EINVAL; /* There are four inputs: tuner, radio, extern and intern. */ chip->input = rt->input; @@ -1819,11 +1675,8 @@ static int tvaudio_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) struct CHIPDESC *desc = chip->desc; int mode = 0; - if (!desc->setmode) - return 0; if (chip->radio) return 0; - switch (vt->audmode) { case V4L2_TUNER_MODE_MONO: case V4L2_TUNER_MODE_STEREO: @@ -1839,7 +1692,7 @@ static int tvaudio_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) } chip->audmode = vt->audmode; - if (mode) { + if (desc->setmode && mode) { chip->watch_stereo = 0; /* del_timer(&chip->wt); */ chip->mode = mode; @@ -1854,17 +1707,15 @@ static int tvaudio_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) struct CHIPDESC *desc = chip->desc; int mode = V4L2_TUNER_MODE_MONO; - if (!desc->getmode) - return 0; if (chip->radio) return 0; - vt->audmode = chip->audmode; vt->rxsubchans = 0; vt->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; - mode = desc->getmode(chip); + if (desc->getmode) + mode = desc->getmode(chip); if (mode & V4L2_TUNER_MODE_MONO) vt->rxsubchans |= V4L2_TUNER_SUB_MONO; @@ -2050,7 +1901,6 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id * } chip->thread = NULL; - init_timer(&chip->wt); if (desc->flags & CHIP_NEED_CHECKMODE) { if (!desc->getmode || !desc->setmode) { /* This shouldn't be happen. Warn user, but keep working @@ -2060,6 +1910,7 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id * return 0; } /* start async thread */ + init_timer(&chip->wt); chip->wt.function = chip_thread_wake; chip->wt.data = (unsigned long)chip; chip->thread = kthread_run(chip_thread, chip, client->name); diff --git a/trunk/drivers/media/video/tveeprom.c b/trunk/drivers/media/video/tveeprom.c index e24a38c7fa46..78277abb733b 100644 --- a/trunk/drivers/media/video/tveeprom.c +++ b/trunk/drivers/media/video/tveeprom.c @@ -261,12 +261,7 @@ hauppauge_tuner[] = { TUNER_ABSENT, "MaxLinear MXL5005_v2"}, { TUNER_PHILIPS_TDA8290, "Philips 18271_8295"}, /* 150-159 */ - { TUNER_XC5000, "Xceive XC5000"}, - { TUNER_ABSENT, "Xceive XC3028L"}, - { TUNER_ABSENT, "NXP 18271C2_716x"}, - { TUNER_ABSENT, "Xceive XC4000"}, - { TUNER_ABSENT, "Dibcom 7070"}, - { TUNER_PHILIPS_TDA8290, "NXP 18271C2"}, + { TUNER_ABSENT, "Xceive XC5000"}, }; /* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are diff --git a/trunk/drivers/media/video/tvp514x.c b/trunk/drivers/media/video/tvp514x.c index 4262e60b8116..8e23aa53c29a 100644 --- a/trunk/drivers/media/video/tvp514x.c +++ b/trunk/drivers/media/video/tvp514x.c @@ -86,12 +86,9 @@ struct tvp514x_std_info { struct v4l2_standard standard; }; -static struct tvp514x_reg tvp514x_reg_list_default[0x40]; /** - * struct tvp514x_decoder - TVP5146/47 decoder object + * struct tvp514x_decoded - TVP5146/47 decoder object * @v4l2_int_device: Slave handle - * @tvp514x_slave: Slave pointer which is used by @v4l2_int_device - * @tvp514x_regs: copy of hw's regs with preset values. * @pdata: Board specific * @client: I2C client data * @id: Entry from I2C table @@ -106,9 +103,7 @@ static struct tvp514x_reg tvp514x_reg_list_default[0x40]; * @route: input and output routing at chip level */ struct tvp514x_decoder { - struct v4l2_int_device v4l2_int_device; - struct v4l2_int_slave tvp514x_slave; - struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)]; + struct v4l2_int_device *v4l2_int_device; const struct tvp514x_platform_data *pdata; struct i2c_client *client; @@ -129,7 +124,7 @@ struct tvp514x_decoder { }; /* TVP514x default register values */ -static struct tvp514x_reg tvp514x_reg_list_default[] = { +static struct tvp514x_reg tvp514x_reg_list[] = { {TOK_WRITE, REG_INPUT_SEL, 0x05}, /* Composite selected */ {TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F}, {TOK_WRITE, REG_VIDEO_STD, 0x00}, /* Auto mode */ @@ -427,7 +422,7 @@ static int tvp514x_configure(struct tvp514x_decoder *decoder) /* common register initialization */ err = - tvp514x_write_regs(decoder->client, decoder->tvp514x_regs); + tvp514x_write_regs(decoder->client, tvp514x_reg_list); if (err) return err; @@ -585,8 +580,7 @@ static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id) return err; decoder->current_std = i; - decoder->tvp514x_regs[REG_VIDEO_STD].val = - decoder->std_list[i].video_std; + tvp514x_reg_list[REG_VIDEO_STD].val = decoder->std_list[i].video_std; v4l_dbg(1, debug, decoder->client, "Standard set to: %s", decoder->std_list[i].standard.name); @@ -631,8 +625,8 @@ static int ioctl_s_routing(struct v4l2_int_device *s, if (err) return err; - decoder->tvp514x_regs[REG_INPUT_SEL].val = input_sel; - decoder->tvp514x_regs[REG_OUTPUT_FORMATTER1].val = output_sel; + tvp514x_reg_list[REG_INPUT_SEL].val = input_sel; + tvp514x_reg_list[REG_OUTPUT_FORMATTER1].val = output_sel; /* Clear status */ msleep(LOCK_RETRY_DELAY); @@ -692,7 +686,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s, break; /* Input detected */ } - if ((current_std == STD_INVALID) || (try_count <= 0)) + if ((current_std == STD_INVALID) || (try_count < 0)) return -EINVAL; decoder->current_std = current_std; @@ -725,9 +719,10 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl) switch (qctrl->id) { case V4L2_CID_BRIGHTNESS: - /* Brightness supported is (0-255), + /* Brightness supported is same as standard one (0-255), + * so make use of standard API provided. */ - err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128); + err = v4l2_ctrl_query_fill_std(qctrl); break; case V4L2_CID_CONTRAST: case V4L2_CID_SATURATION: @@ -784,16 +779,16 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: - ctrl->value = decoder->tvp514x_regs[REG_BRIGHTNESS].val; + ctrl->value = tvp514x_reg_list[REG_BRIGHTNESS].val; break; case V4L2_CID_CONTRAST: - ctrl->value = decoder->tvp514x_regs[REG_CONTRAST].val; + ctrl->value = tvp514x_reg_list[REG_CONTRAST].val; break; case V4L2_CID_SATURATION: - ctrl->value = decoder->tvp514x_regs[REG_SATURATION].val; + ctrl->value = tvp514x_reg_list[REG_SATURATION].val; break; case V4L2_CID_HUE: - ctrl->value = decoder->tvp514x_regs[REG_HUE].val; + ctrl->value = tvp514x_reg_list[REG_HUE].val; if (ctrl->value == 0x7F) ctrl->value = 180; else if (ctrl->value == 0x80) @@ -803,7 +798,7 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) break; case V4L2_CID_AUTOGAIN: - ctrl->value = decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val; + ctrl->value = tvp514x_reg_list[REG_AFE_GAIN_CTRL].val; if ((ctrl->value & 0x3) == 3) ctrl->value = 1; else @@ -853,7 +848,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - decoder->tvp514x_regs[REG_BRIGHTNESS].val = value; + tvp514x_reg_list[REG_BRIGHTNESS].val = value; break; case V4L2_CID_CONTRAST: if (ctrl->value < 0 || ctrl->value > 255) { @@ -866,7 +861,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - decoder->tvp514x_regs[REG_CONTRAST].val = value; + tvp514x_reg_list[REG_CONTRAST].val = value; break; case V4L2_CID_SATURATION: if (ctrl->value < 0 || ctrl->value > 255) { @@ -879,7 +874,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - decoder->tvp514x_regs[REG_SATURATION].val = value; + tvp514x_reg_list[REG_SATURATION].val = value; break; case V4L2_CID_HUE: if (value == 180) @@ -898,7 +893,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - decoder->tvp514x_regs[REG_HUE].val = value; + tvp514x_reg_list[REG_HUE].val = value; break; case V4L2_CID_AUTOGAIN: if (value == 1) @@ -915,7 +910,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value; + tvp514x_reg_list[REG_AFE_GAIN_CTRL].val = value; break; default: v4l_err(decoder->client, @@ -1280,7 +1275,7 @@ static int ioctl_init(struct v4l2_int_device *s) struct tvp514x_decoder *decoder = s->priv; /* Set default standard to auto */ - decoder->tvp514x_regs[REG_VIDEO_STD].val = + tvp514x_reg_list[REG_VIDEO_STD].val = VIDEO_STD_AUTO_SWITCH_BIT; return tvp514x_configure(decoder); @@ -1349,6 +1344,11 @@ static struct v4l2_int_ioctl_desc tvp514x_ioctl_desc[] = { (v4l2_int_ioctl_func *) ioctl_s_routing}, }; +static struct v4l2_int_slave tvp514x_slave = { + .ioctls = tvp514x_ioctl_desc, + .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc), +}; + static struct tvp514x_decoder tvp514x_dev = { .state = STATE_NOT_DETECTED, @@ -1369,15 +1369,17 @@ static struct tvp514x_decoder tvp514x_dev = { .current_std = STD_NTSC_MJ, .std_list = tvp514x_std_list, .num_stds = ARRAY_SIZE(tvp514x_std_list), - .v4l2_int_device = { - .module = THIS_MODULE, - .name = TVP514X_MODULE_NAME, - .type = v4l2_int_type_slave, - }, - .tvp514x_slave = { - .ioctls = tvp514x_ioctl_desc, - .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc), - }, + +}; + +static struct v4l2_int_device tvp514x_int_device = { + .module = THIS_MODULE, + .name = TVP514X_MODULE_NAME, + .priv = &tvp514x_dev, + .type = v4l2_int_type_slave, + .u = { + .slave = &tvp514x_slave, + }, }; /** @@ -1390,37 +1392,26 @@ static struct tvp514x_decoder tvp514x_dev = { static int tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct tvp514x_decoder *decoder; + struct tvp514x_decoder *decoder = &tvp514x_dev; int err; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - decoder = kzalloc(sizeof(*decoder), GFP_KERNEL); - if (!decoder) - return -ENOMEM; - - if (!client->dev.platform_data) { + decoder->pdata = client->dev.platform_data; + if (!decoder->pdata) { v4l_err(client, "No platform data!!\n"); - err = -ENODEV; - goto out_free; + return -ENODEV; } - - *decoder = tvp514x_dev; - decoder->v4l2_int_device.priv = decoder; - decoder->pdata = client->dev.platform_data; - decoder->v4l2_int_device.u.slave = &decoder->tvp514x_slave; - memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default, - sizeof(tvp514x_reg_list_default)); /* * Fetch platform specific data, and configure the * tvp514x_reg_list[] accordingly. Since this is one * time configuration, no need to preserve. */ - decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |= + tvp514x_reg_list[REG_OUTPUT_FORMATTER2].val |= (decoder->pdata->clk_polarity << 1); - decoder->tvp514x_regs[REG_SYNC_CONTROL].val |= + tvp514x_reg_list[REG_SYNC_CONTROL].val |= ((decoder->pdata->hs_polarity << 2) | (decoder->pdata->vs_polarity << 3)); /* @@ -1428,27 +1419,23 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) */ decoder->id = (struct i2c_device_id *)id; /* Attach to Master */ - strcpy(decoder->v4l2_int_device.u.slave->attach_to, - decoder->pdata->master); + strcpy(tvp514x_int_device.u.slave->attach_to, decoder->pdata->master); + decoder->v4l2_int_device = &tvp514x_int_device; decoder->client = client; i2c_set_clientdata(client, decoder); /* Register with V4L2 layer as slave device */ - err = v4l2_int_device_register(&decoder->v4l2_int_device); + err = v4l2_int_device_register(decoder->v4l2_int_device); if (err) { i2c_set_clientdata(client, NULL); v4l_err(client, "Unable to register to v4l2. Err[%d]\n", err); - goto out_free; } else v4l_info(client, "Registered to v4l2 master %s!!\n", decoder->pdata->master); - return 0; -out_free: - kfree(decoder); - return err; + return 0; } /** @@ -1465,9 +1452,9 @@ static int __exit tvp514x_remove(struct i2c_client *client) if (!client->adapter) return -ENODEV; /* our client isn't attached */ - v4l2_int_device_unregister(&decoder->v4l2_int_device); + v4l2_int_device_unregister(decoder->v4l2_int_device); i2c_set_clientdata(client, NULL); - kfree(decoder); + return 0; } /* diff --git a/trunk/drivers/media/video/tvp5150.c b/trunk/drivers/media/video/tvp5150.c index 3a5a95f134b4..2cd64ef27b95 100644 --- a/trunk/drivers/media/video/tvp5150.c +++ b/trunk/drivers/media/video/tvp5150.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -631,7 +632,7 @@ static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd, const struct i2c_vbi_ram_value *regs = vbi_ram_default; int line; - v4l2_dbg(1, debug, sd, "g_sliced_vbi_cap\n"); + v4l2_dbg(1, debug, sd, "VIDIOC_G_SLICED_VBI_CAP\n"); memset(cap, 0, sizeof *cap); while (regs->reg != (u16)-1 ) { @@ -830,7 +831,7 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val) static int tvp5150_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { - v4l2_dbg(1, debug, sd, "g_ctrl called\n"); + v4l2_dbg(1, debug, sd, "VIDIOC_G_CTRL called\n"); switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: @@ -860,7 +861,7 @@ static int tvp5150_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) if (ctrl->value < tvp5150_qctrl[i].minimum || ctrl->value > tvp5150_qctrl[i].maximum) return -ERANGE; - v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n", + v4l2_dbg(1, debug, sd, "VIDIOC_S_CTRL: id=%d, value=%d\n", ctrl->id, ctrl->value); break; } @@ -1014,7 +1015,7 @@ static int tvp5150_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) { int i; - v4l2_dbg(1, debug, sd, "queryctrl called\n"); + v4l2_dbg(1, debug, sd, "VIDIOC_QUERYCTRL called\n"); for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++) if (qc->id && qc->id == tvp5150_qctrl[i].id) { @@ -1125,6 +1126,7 @@ MODULE_DEVICE_TABLE(i2c, tvp5150_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "tvp5150", + .driverid = I2C_DRIVERID_TVP5150, .command = tvp5150_command, .probe = tvp5150_probe, .remove = tvp5150_remove, diff --git a/trunk/drivers/media/video/tw9910.c b/trunk/drivers/media/video/tw9910.c index a39947643992..52c0357faa5d 100644 --- a/trunk/drivers/media/video/tw9910.c +++ b/trunk/drivers/media/video/tw9910.c @@ -460,11 +460,9 @@ static int tw9910_mask_set(struct i2c_client *client, u8 command, u8 mask, u8 set) { s32 val = i2c_smbus_read_byte_data(client, command); - if (val < 0) - return val; val &= ~mask; - val |= set & mask; + val |= set; return i2c_smbus_write_byte_data(client, command, val); } @@ -641,8 +639,8 @@ static int tw9910_set_register(struct soc_camera_device *icd, } #endif -static int tw9910_set_crop(struct soc_camera_device *icd, - struct v4l2_rect *rect) +static int tw9910_set_fmt(struct soc_camera_device *icd, __u32 pixfmt, + struct v4l2_rect *rect) { struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); int ret = -EINVAL; @@ -733,33 +731,8 @@ static int tw9910_set_crop(struct soc_camera_device *icd, return ret; } -static int tw9910_set_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) -{ - struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_rect rect = { - .left = icd->x_current, - .top = icd->y_current, - .width = pix->width, - .height = pix->height, - }; - int i; - - /* - * check color format - */ - for (i = 0; i < ARRAY_SIZE(tw9910_color_fmt); i++) - if (pix->pixelformat == tw9910_color_fmt[i].fourcc) - break; - - if (i == ARRAY_SIZE(tw9910_color_fmt)) - return -EINVAL; - - return tw9910_set_crop(icd, &rect); -} - static int tw9910_try_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) + struct v4l2_format *f) { struct v4l2_pix_format *pix = &f->fmt.pix; const struct tw9910_scale_ctrl *scale; @@ -847,7 +820,6 @@ static struct soc_camera_ops tw9910_ops = { .release = tw9910_release, .start_capture = tw9910_start_capture, .stop_capture = tw9910_stop_capture, - .set_crop = tw9910_set_crop, .set_fmt = tw9910_set_fmt, .try_fmt = tw9910_try_fmt, .set_bus_param = tw9910_set_bus_param, diff --git a/trunk/drivers/media/video/upd64031a.c b/trunk/drivers/media/video/upd64031a.c index c0ac651bb358..f4522bb08916 100644 --- a/trunk/drivers/media/video/upd64031a.c +++ b/trunk/drivers/media/video/upd64031a.c @@ -187,6 +187,11 @@ static int upd64031a_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register } #endif +static int upd64031a_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops upd64031a_core_ops = { @@ -262,6 +267,8 @@ MODULE_DEVICE_TABLE(i2c, upd64031a_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "upd64031a", + .driverid = I2C_DRIVERID_UPD64031A, + .command = upd64031a_command, .probe = upd64031a_probe, .remove = upd64031a_remove, .id_table = upd64031a_id, diff --git a/trunk/drivers/media/video/upd64083.c b/trunk/drivers/media/video/upd64083.c index 410c915d51fa..a5fb74bf2407 100644 --- a/trunk/drivers/media/video/upd64083.c +++ b/trunk/drivers/media/video/upd64083.c @@ -164,6 +164,11 @@ static int upd64083_log_status(struct v4l2_subdev *sd) return 0; } +static int upd64083_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops upd64083_core_ops = { @@ -234,6 +239,8 @@ MODULE_DEVICE_TABLE(i2c, upd64083_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "upd64083", + .driverid = I2C_DRIVERID_UPD64083, + .command = upd64083_command, .probe = upd64083_probe, .remove = upd64083_remove, .id_table = upd64083_id, diff --git a/trunk/drivers/media/video/usbvideo/vicam.c b/trunk/drivers/media/video/usbvideo/vicam.c index 8d73979596f9..2f1106338c08 100644 --- a/trunk/drivers/media/video/usbvideo/vicam.c +++ b/trunk/drivers/media/video/usbvideo/vicam.c @@ -191,7 +191,7 @@ initialize_camera(struct vicam_camera *cam) { int err; const struct ihex_binrec *rec; - const struct firmware *uninitialized_var(fw); + const struct firmware *fw; err = request_ihex_firmware(&fw, "vicam/firmware.fw", &cam->udev->dev); if (err) { diff --git a/trunk/drivers/media/video/usbvision/usbvision-core.c b/trunk/drivers/media/video/usbvision/usbvision-core.c index a0feb1c97736..9e4f50639975 100644 --- a/trunk/drivers/media/video/usbvision/usbvision-core.c +++ b/trunk/drivers/media/video/usbvision/usbvision-core.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -380,9 +381,8 @@ int usbvision_scratch_alloc(struct usb_usbvision *usbvision) usbvision->scratch = vmalloc_32(scratch_buf_size); scratch_reset(usbvision); if(usbvision->scratch == NULL) { - dev_err(&usbvision->dev->dev, - "%s: unable to allocate %d bytes for scratch\n", - __func__, scratch_buf_size); + err("%s: unable to allocate %d bytes for scratch", + __func__, scratch_buf_size); return -ENOMEM; } return 0; @@ -491,9 +491,8 @@ int usbvision_decompress_alloc(struct usb_usbvision *usbvision) int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2; usbvision->IntraFrameBuffer = vmalloc_32(IFB_size); if (usbvision->IntraFrameBuffer == NULL) { - dev_err(&usbvision->dev->dev, - "%s: unable to allocate %d for compr. frame buffer\n", - __func__, IFB_size); + err("%s: unable to allocate %d for compr. frame buffer", + __func__, IFB_size); return -ENOMEM; } return 0; @@ -1515,9 +1514,8 @@ static void usbvision_isocIrq(struct urb *urb) errCode = usb_submit_urb (urb, GFP_ATOMIC); if(errCode) { - dev_err(&usbvision->dev->dev, - "%s: usb_submit_urb failed: error %d\n", - __func__, errCode); + err("%s: usb_submit_urb failed: error %d", + __func__, errCode); } return; @@ -1548,8 +1546,7 @@ int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg) 0, (__u16) reg, buffer, 1, HZ); if (errCode < 0) { - dev_err(&usbvision->dev->dev, - "%s: failed: error %d\n", __func__, errCode); + err("%s: failed: error %d", __func__, errCode); return errCode; } return buffer[0]; @@ -1577,8 +1574,7 @@ int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg, USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ); if (errCode < 0) { - dev_err(&usbvision->dev->dev, - "%s: failed: error %d\n", __func__, errCode); + err("%s: failed: error %d", __func__, errCode); } return errCode; } @@ -1854,8 +1850,7 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width, 0, (__u16) USBVISION_LXSIZE_O, value, 4, HZ); if (errCode < 0) { - dev_err(&usbvision->dev->dev, - "%s failed: error %d\n", __func__, errCode); + err("%s failed: error %d", __func__, errCode); return errCode; } usbvision->curwidth = usbvision->stretch_width * UsbWidth; @@ -2241,7 +2236,7 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision) (__u16) USBVISION_DRM_PRM1, value, 8, HZ); if (rc < 0) { - dev_err(&usbvision->dev->dev, "%sERROR=%d\n", __func__, rc); + err("%sERROR=%d", __func__, rc); return rc; } @@ -2437,9 +2432,8 @@ int usbvision_set_alternate(struct usb_usbvision *dev) PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize); errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt); if (errCode < 0) { - dev_err(&dev->dev->dev, - "cannot change alternate number to %d (error=%i)\n", - dev->ifaceAlt, errCode); + err ("cannot change alternate number to %d (error=%i)", + dev->ifaceAlt, errCode); return errCode; } } @@ -2490,8 +2484,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL); if (urb == NULL) { - dev_err(&usbvision->dev->dev, - "%s: usb_alloc_urb() failed\n", __func__); + err("%s: usb_alloc_urb() failed", __func__); return -ENOMEM; } usbvision->sbuf[bufIdx].urb = urb; @@ -2503,7 +2496,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) urb->dev = dev; urb->context = usbvision; urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp); - urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; + urb->transfer_flags = URB_ISO_ASAP; urb->interval = 1; urb->transfer_buffer = usbvision->sbuf[bufIdx].data; urb->complete = usbvision_isocIrq; @@ -2523,9 +2516,8 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb, GFP_KERNEL); if (errCode) { - dev_err(&usbvision->dev->dev, - "%s: usb_submit_urb(%d) failed: error %d\n", - __func__, bufIdx, errCode); + err("%s: usb_submit_urb(%d) failed: error %d", + __func__, bufIdx, errCode); } } @@ -2574,9 +2566,8 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision) errCode = usb_set_interface(usbvision->dev, usbvision->iface, usbvision->ifaceAlt); if (errCode < 0) { - dev_err(&usbvision->dev->dev, - "%s: usb_set_interface() failed: error %d\n", - __func__, errCode); + err("%s: usb_set_interface() failed: error %d", + __func__, errCode); usbvision->last_error = errCode; } regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; @@ -2632,7 +2623,7 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel) } route.input = mode[channel]; route.output = 0; - call_all(usbvision, video, s_routing, &route); + call_i2c_clients(usbvision, VIDIOC_INT_S_VIDEO_ROUTING,&route); usbvision_set_audio(usbvision, audio[channel]); return 0; } diff --git a/trunk/drivers/media/video/usbvision/usbvision-i2c.c b/trunk/drivers/media/video/usbvision/usbvision-i2c.c index dd2f8f27c73b..6b66ae4f430f 100644 --- a/trunk/drivers/media/video/usbvision/usbvision-i2c.c +++ b/trunk/drivers/media/video/usbvision/usbvision-i2c.c @@ -119,8 +119,7 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap, /* try extended address code... */ ret = try_write_address(i2c_adap, addr, retries); if (ret != 1) { - dev_err(&i2c_adap->dev, - "died at extended address code, while writing\n"); + err("died at extended address code, while writing"); return -EREMOTEIO; } add[0] = addr; @@ -129,8 +128,7 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap, addr |= 0x01; ret = try_read_address(i2c_adap, addr, retries); if (ret != 1) { - dev_err(&i2c_adap->dev, - "died at extended address code, while reading\n"); + err("died at extended address code, while reading"); return -EREMOTEIO; } } @@ -202,78 +200,72 @@ static struct i2c_algorithm usbvision_algo = { }; +/* + * registering functions to load algorithms at runtime + */ +static int usbvision_i2c_usb_add_bus(struct i2c_adapter *adap) +{ + PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]"); + PDEBUG(DBG_I2C, "ALGO debugging is enabled [i2c]"); + + /* register new adapter to i2c module... */ + + adap->algo = &usbvision_algo; + + adap->timeout = 100; /* default values, should */ + adap->retries = 3; /* be replaced by defines */ + + i2c_add_adapter(adap); + + PDEBUG(DBG_I2C,"i2c bus for %s registered", adap->name); + + return 0; +} + /* ----------------------------------------------------------------------- */ /* usbvision specific I2C functions */ /* ----------------------------------------------------------------------- */ static struct i2c_adapter i2c_adap_template; +static struct i2c_client i2c_client_template; int usbvision_i2c_register(struct usb_usbvision *usbvision) { - static unsigned short saa711x_addrs[] = { - 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */ - 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */ - I2C_CLIENT_END }; - memcpy(&usbvision->i2c_adap, &i2c_adap_template, sizeof(struct i2c_adapter)); + memcpy(&usbvision->i2c_client, &i2c_client_template, + sizeof(struct i2c_client)); sprintf(usbvision->i2c_adap.name + strlen(usbvision->i2c_adap.name), " #%d", usbvision->vdev->num); PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name); usbvision->i2c_adap.dev.parent = &usbvision->dev->dev; - i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev); + i2c_set_adapdata(&usbvision->i2c_adap, usbvision); + i2c_set_clientdata(&usbvision->i2c_client, usbvision); + + usbvision->i2c_client.adapter = &usbvision->i2c_adap; if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) { printk(KERN_ERR "usbvision_register: can't write reg\n"); return -EBUSY; } - PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]"); - PDEBUG(DBG_I2C, "ALGO debugging is enabled [i2c]"); - - /* register new adapter to i2c module... */ - - usbvision->i2c_adap.algo = &usbvision_algo; - - usbvision->i2c_adap.timeout = 100; /* default values, should */ - usbvision->i2c_adap.retries = 3; /* be replaced by defines */ - - i2c_add_adapter(&usbvision->i2c_adap); - - PDEBUG(DBG_I2C, "i2c bus for %s registered", usbvision->i2c_adap.name); - +#ifdef CONFIG_MODULES /* Request the load of the i2c modules we need */ switch (usbvision_device_data[usbvision->DevModel].Codec) { case CODEC_SAA7113: + request_module("saa7115"); + break; case CODEC_SAA7111: - v4l2_i2c_new_probed_subdev(&usbvision->i2c_adap, "saa7115", - "saa7115_auto", saa711x_addrs); + request_module("saa7115"); break; } if (usbvision_device_data[usbvision->DevModel].Tuner == 1) { - struct v4l2_subdev *sd; - enum v4l2_i2c_tuner_type type; - struct tuner_setup tun_setup; - - sd = v4l2_i2c_new_probed_subdev(&usbvision->i2c_adap, "tuner", - "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); - /* depending on whether we found a demod or not, select - the tuner type. */ - type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; - - sd = v4l2_i2c_new_probed_subdev(&usbvision->i2c_adap, "tuner", - "tuner", v4l2_i2c_tuner_addrs(type)); - - if (usbvision->tuner_type != -1) { - tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; - tun_setup.type = usbvision->tuner_type; - tun_setup.addr = v4l2_i2c_subdev_addr(sd); - call_all(usbvision, tuner, s_type_addr, &tun_setup); - } + request_module("tuner"); } +#endif - return 0; + return usbvision_i2c_usb_add_bus(&usbvision->i2c_adap); } int usbvision_i2c_unregister(struct usb_usbvision *usbvision) @@ -286,6 +278,67 @@ int usbvision_i2c_unregister(struct usb_usbvision *usbvision) return 0; } +void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd, + void *arg) +{ + i2c_clients_command(&usbvision->i2c_adap, cmd, arg); +} + +static int attach_inform(struct i2c_client *client) +{ + struct usb_usbvision *usbvision; + + usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter); + + switch (client->addr << 1) { + case 0x42 << 1: + case 0x43 << 1: + case 0x4a << 1: + case 0x4b << 1: + PDEBUG(DBG_I2C,"attach_inform: tda9887 detected."); + break; + case 0x42: + PDEBUG(DBG_I2C,"attach_inform: saa7114 detected."); + break; + case 0x4a: + PDEBUG(DBG_I2C,"attach_inform: saa7113 detected."); + break; + case 0x48: + PDEBUG(DBG_I2C,"attach_inform: saa7111 detected."); + break; + case 0xa0: + PDEBUG(DBG_I2C,"attach_inform: eeprom detected."); + break; + + default: + { + struct tuner_setup tun_setup; + + PDEBUG(DBG_I2C,"attach inform: detected I2C address %x", client->addr << 1); + usbvision->tuner_addr = client->addr; + + if ((usbvision->have_tuner) && (usbvision->tuner_type != -1)) { + tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; + tun_setup.type = usbvision->tuner_type; + tun_setup.addr = usbvision->tuner_addr; + call_i2c_clients(usbvision, TUNER_SET_TYPE_ADDR, &tun_setup); + } + } + break; + } + return 0; +} + +static int detach_inform(struct i2c_client *client) +{ + struct usb_usbvision *usbvision; + + usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter); + + PDEBUG(DBG_I2C,"usbvision[%d] detaches %s", usbvision->nr, client->name); + return 0; +} + static int usbvision_i2c_read_max4(struct usb_usbvision *usbvision, unsigned char addr, char *buf, short len) @@ -458,6 +511,14 @@ static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char add static struct i2c_adapter i2c_adap_template = { .owner = THIS_MODULE, .name = "usbvision", + .id = I2C_HW_B_BT848, /* FIXME */ + .client_register = attach_inform, + .client_unregister = detach_inform, + .class = I2C_CLASS_TV_ANALOG, +}; + +static struct i2c_client i2c_client_template = { + .name = "usbvision internal", }; /* diff --git a/trunk/drivers/media/video/usbvision/usbvision-video.c b/trunk/drivers/media/video/usbvision/usbvision-video.c index fa62a2fd7b22..2622de003a45 100644 --- a/trunk/drivers/media/video/usbvision/usbvision-video.c +++ b/trunk/drivers/media/video/usbvision/usbvision-video.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -211,7 +212,7 @@ static ssize_t show_hue(struct device *cd, ctrl.id = V4L2_CID_HUE; ctrl.value = 0; if(usbvision->user) - call_all(usbvision, core, g_ctrl, &ctrl); + call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); return sprintf(buf, "%d\n", ctrl.value); } static DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL); @@ -226,7 +227,7 @@ static ssize_t show_contrast(struct device *cd, ctrl.id = V4L2_CID_CONTRAST; ctrl.value = 0; if(usbvision->user) - call_all(usbvision, core, g_ctrl, &ctrl); + call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); return sprintf(buf, "%d\n", ctrl.value); } static DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL); @@ -241,7 +242,7 @@ static ssize_t show_brightness(struct device *cd, ctrl.id = V4L2_CID_BRIGHTNESS; ctrl.value = 0; if(usbvision->user) - call_all(usbvision, core, g_ctrl, &ctrl); + call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); return sprintf(buf, "%d\n", ctrl.value); } static DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL); @@ -256,7 +257,7 @@ static ssize_t show_saturation(struct device *cd, ctrl.id = V4L2_CID_SATURATION; ctrl.value = 0; if(usbvision->user) - call_all(usbvision, core, g_ctrl, &ctrl); + call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); return sprintf(buf, "%d\n", ctrl.value); } static DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL); @@ -328,7 +329,7 @@ static void usbvision_create_sysfs(struct video_device *vdev) return; } while (0); - dev_err(&vdev->dev, "%s error: %d\n", __func__, res); + err("%s error: %d\n", __func__, res); } static void usbvision_remove_sysfs(struct video_device *vdev) @@ -486,9 +487,8 @@ static int vidioc_g_register (struct file *file, void *priv, /* NT100x has a 8-bit register space */ errCode = usbvision_read_reg(usbvision, reg->reg&0xff); if (errCode < 0) { - dev_err(&usbvision->vdev->dev, - "%s: VIDIOC_DBG_G_REGISTER failed: error %d\n", - __func__, errCode); + err("%s: VIDIOC_DBG_G_REGISTER failed: error %d", + __func__, errCode); return errCode; } reg->val = errCode; @@ -507,9 +507,8 @@ static int vidioc_s_register (struct file *file, void *priv, /* NT100x has a 8-bit register space */ errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); if (errCode < 0) { - dev_err(&usbvision->vdev->dev, - "%s: VIDIOC_DBG_S_REGISTER failed: error %d\n", - __func__, errCode); + err("%s: VIDIOC_DBG_S_REGISTER failed: error %d", + __func__, errCode); return errCode; } return 0; @@ -525,7 +524,8 @@ static int vidioc_querycap (struct file *file, void *priv, strlcpy(vc->card, usbvision_device_data[usbvision->DevModel].ModelString, sizeof(vc->card)); - usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info)); + strlcpy(vc->bus_info, dev_name(&usbvision->dev->dev), + sizeof(vc->bus_info)); vc->version = USBVISION_DRIVER_VERSION; vc->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO | @@ -621,7 +621,8 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id) usbvision->tvnormId=*id; mutex_lock(&usbvision->lock); - call_all(usbvision, tuner, s_std, usbvision->tvnormId); + call_i2c_clients(usbvision, VIDIOC_S_STD, + &usbvision->tvnormId); mutex_unlock(&usbvision->lock); /* propagate the change to the decoder */ usbvision_muxsel(usbvision, usbvision->ctl_input); @@ -643,7 +644,7 @@ static int vidioc_g_tuner (struct file *file, void *priv, strcpy(vt->name, "Television"); } /* Let clients fill in the remainder of this struct */ - call_all(usbvision, tuner, g_tuner, vt); + call_i2c_clients(usbvision,VIDIOC_G_TUNER,vt); return 0; } @@ -657,7 +658,7 @@ static int vidioc_s_tuner (struct file *file, void *priv, if (!usbvision->have_tuner || vt->index) return -EINVAL; /* let clients handle this */ - call_all(usbvision, tuner, s_tuner, vt); + call_i2c_clients(usbvision,VIDIOC_S_TUNER,vt); return 0; } @@ -688,7 +689,7 @@ static int vidioc_s_frequency (struct file *file, void *priv, return -EINVAL; usbvision->freq = freq->frequency; - call_all(usbvision, tuner, s_frequency, freq); + call_i2c_clients(usbvision, VIDIOC_S_FREQUENCY, freq); return 0; } @@ -697,6 +698,7 @@ static int vidioc_g_audio (struct file *file, void *priv, struct v4l2_audio *a) { struct usb_usbvision *usbvision = video_drvdata(file); + memset(a,0,sizeof(*a)); if(usbvision->radio) { strcpy(a->name,"Radio"); } else { @@ -720,8 +722,12 @@ static int vidioc_queryctrl (struct file *file, void *priv, struct v4l2_queryctrl *ctrl) { struct usb_usbvision *usbvision = video_drvdata(file); + int id=ctrl->id; - call_all(usbvision, core, queryctrl, ctrl); + memset(ctrl,0,sizeof(*ctrl)); + ctrl->id=id; + + call_i2c_clients(usbvision, VIDIOC_QUERYCTRL, ctrl); if (!ctrl->type) return -EINVAL; @@ -733,7 +739,7 @@ static int vidioc_g_ctrl (struct file *file, void *priv, struct v4l2_control *ctrl) { struct usb_usbvision *usbvision = video_drvdata(file); - call_all(usbvision, core, g_ctrl, ctrl); + call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl); return 0; } @@ -742,7 +748,7 @@ static int vidioc_s_ctrl (struct file *file, void *priv, struct v4l2_control *ctrl) { struct usb_usbvision *usbvision = video_drvdata(file); - call_all(usbvision, core, s_ctrl, ctrl); + call_i2c_clients(usbvision, VIDIOC_S_CTRL, ctrl); return 0; } @@ -757,7 +763,8 @@ static int vidioc_reqbufs (struct file *file, /* Check input validity: the user must do a VIDEO CAPTURE and MMAP method. */ - if (vr->memory != V4L2_MEMORY_MMAP) + if((vr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) || + (vr->memory != V4L2_MEMORY_MMAP)) return -EINVAL; if(usbvision->streaming == Stream_On) { @@ -782,6 +789,9 @@ static int vidioc_querybuf (struct file *file, /* FIXME : must control that buffers are mapped (VIDIOC_REQBUFS has been called) */ + if(vb->type != V4L2_CAP_VIDEO_CAPTURE) { + return -EINVAL; + } if(vb->index>=usbvision->num_frames) { return -EINVAL; } @@ -815,6 +825,9 @@ static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *vb) unsigned long lock_flags; /* FIXME : works only on VIDEO_CAPTURE MODE, MMAP. */ + if(vb->type != V4L2_CAP_VIDEO_CAPTURE) { + return -EINVAL; + } if(vb->index>=usbvision->num_frames) { return -EINVAL; } @@ -849,6 +862,9 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb) struct usbvision_frame *f; unsigned long lock_flags; + if (vb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (list_empty(&(usbvision->outqueue))) { if (usbvision->streaming == Stream_Idle) return -EINVAL; @@ -883,9 +899,10 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb) static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) { struct usb_usbvision *usbvision = video_drvdata(file); + int b=V4L2_BUF_TYPE_VIDEO_CAPTURE; usbvision->streaming = Stream_On; - call_all(usbvision, video, s_stream, 1); + call_i2c_clients(usbvision,VIDIOC_STREAMON , &b); return 0; } @@ -894,6 +911,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type type) { struct usb_usbvision *usbvision = video_drvdata(file); + int b=V4L2_BUF_TYPE_VIDEO_CAPTURE; if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -901,7 +919,7 @@ static int vidioc_streamoff(struct file *file, if(usbvision->streaming == Stream_On) { usbvision_stream_interrupt(usbvision); /* Stop all video streamings */ - call_all(usbvision, video, s_stream, 0); + call_i2c_clients(usbvision,VIDIOC_STREAMOFF , &b); } usbvision_empty_framequeues(usbvision); @@ -914,8 +932,11 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, if(vfd->index>=USBVISION_SUPPORTED_PALETTES-1) { return -EINVAL; } + vfd->flags = 0; + vfd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; strcpy(vfd->description,usbvision_v4l2_format[vfd->index].desc); vfd->pixelformat = usbvision_v4l2_format[vfd->index].format; + memset(vfd->reserved, 0, sizeof(vfd->reserved)); return 0; } @@ -1021,7 +1042,7 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, if(usbvision->streaming != Stream_On) { /* no stream is running, make it running ! */ usbvision->streaming = Stream_On; - call_all(usbvision, video, s_stream, 1); + call_i2c_clients(usbvision,VIDIOC_STREAMON , NULL); } /* Then, enqueue as many frames as possible @@ -1168,9 +1189,7 @@ static int usbvision_radio_open(struct file *file) mutex_lock(&usbvision->lock); if (usbvision->user) { - dev_err(&usbvision->rdev->dev, - "%s: Someone tried to open an already opened USBVision Radio!\n", - __func__); + err("%s: Someone tried to open an already opened USBVision Radio!", __func__); errCode = -EBUSY; } else { @@ -1192,7 +1211,7 @@ static int usbvision_radio_open(struct file *file) // If so far no errors then we shall start the radio usbvision->radio = 1; - call_all(usbvision, tuner, s_radio); + call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type); usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO); usbvision->user++; } @@ -1394,8 +1413,7 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision, struct video_device *vdev; if (usb_dev == NULL) { - dev_err(&usbvision->dev->dev, - "%s: usbvision->dev is not set\n", __func__); + err("%s: usbvision->dev is not set", __func__); return NULL; } @@ -1405,7 +1423,7 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision, } *vdev = *vdev_template; // vdev->minor = -1; - vdev->v4l2_dev = &usbvision->v4l2_dev; + vdev->parent = &usb_dev->dev; snprintf(vdev->name, sizeof(vdev->name), "%s", name); video_set_drvdata(vdev, usbvision); return vdev; @@ -1506,9 +1524,7 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision) return 0; err_exit: - dev_err(&usbvision->dev->dev, - "USBVision[%d]: video_register_device() failed\n", - usbvision->nr); + err("USBVision[%d]: video_register_device() failed", usbvision->nr); usbvision_unregister_video(usbvision); return -1; } @@ -1526,30 +1542,33 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev) { struct usb_usbvision *usbvision; - usbvision = kzalloc(sizeof(struct usb_usbvision), GFP_KERNEL); - if (usbvision == NULL) - return NULL; + if ((usbvision = kzalloc(sizeof(struct usb_usbvision), GFP_KERNEL)) == + NULL) { + goto err_exit; + } usbvision->dev = dev; - if (v4l2_device_register(&dev->dev, &usbvision->v4l2_dev)) - goto err_free; mutex_init(&usbvision->lock); /* available */ // prepare control urb for control messages during interrupts usbvision->ctrlUrb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL); - if (usbvision->ctrlUrb == NULL) - goto err_unreg; + if (usbvision->ctrlUrb == NULL) { + goto err_exit; + } init_waitqueue_head(&usbvision->ctrlUrb_wq); usbvision_init_powerOffTimer(usbvision); return usbvision; -err_unreg: - v4l2_device_unregister(&usbvision->v4l2_dev); -err_free: - kfree(usbvision); +err_exit: + if (usbvision && usbvision->ctrlUrb) { + usb_free_urb(usbvision->ctrlUrb); + } + if (usbvision) { + kfree(usbvision); + } return NULL; } @@ -1579,7 +1598,6 @@ static void usbvision_release(struct usb_usbvision *usbvision) usb_free_urb(usbvision->ctrlUrb); } - v4l2_device_unregister(&usbvision->v4l2_dev); kfree(usbvision); PDEBUG(DBG_PROBE, "success"); @@ -1657,20 +1675,20 @@ static int __devinit usbvision_probe(struct usb_interface *intf, } endpoint = &interface->endpoint[1].desc; if (!usb_endpoint_xfer_isoc(endpoint)) { - dev_err(&intf->dev, "%s: interface %d. has non-ISO endpoint!\n", + err("%s: interface %d. has non-ISO endpoint!", __func__, ifnum); - dev_err(&intf->dev, "%s: Endpoint attributes %d", + err("%s: Endpoint attributes %d", __func__, endpoint->bmAttributes); return -ENODEV; } if (usb_endpoint_dir_out(endpoint)) { - dev_err(&intf->dev, "%s: interface %d. has ISO OUT endpoint!\n", + err("%s: interface %d. has ISO OUT endpoint!", __func__, ifnum); return -ENODEV; } if ((usbvision = usbvision_alloc(dev)) == NULL) { - dev_err(&intf->dev, "%s: couldn't allocate USBVision struct\n", __func__); + err("%s: couldn't allocate USBVision struct", __func__); return -ENOMEM; } @@ -1693,7 +1711,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf, usbvision->alt_max_pkt_size = kmalloc(32* usbvision->num_alt,GFP_KERNEL); if (usbvision->alt_max_pkt_size == NULL) { - dev_err(&intf->dev, "usbvision: out of memory!\n"); + err("usbvision: out of memory!\n"); mutex_unlock(&usbvision->lock); return -ENOMEM; } @@ -1715,6 +1733,8 @@ static int __devinit usbvision_probe(struct usb_interface *intf, usbvision->tuner_type = usbvision_device_data[model].TunerType; } + usbvision->tuner_addr = ADDR_UNSET; + usbvision->DevModel = model; usbvision->remove_pending = 0; usbvision->iface = ifnum; @@ -1752,8 +1772,7 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf) PDEBUG(DBG_PROBE, ""); if (usbvision == NULL) { - dev_err(&usbvision->dev->dev, - "%s: usb_get_intfdata() failed\n", __func__); + err("%s: usb_get_intfdata() failed", __func__); return; } usb_set_intfdata (intf, NULL); @@ -1763,8 +1782,6 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf) // At this time we ask to cancel outstanding URBs usbvision_stop_isoc(usbvision); - v4l2_device_disconnect(&usbvision->v4l2_dev); - if (usbvision->power) { usbvision_i2c_unregister(usbvision); usbvision_power_off(usbvision); diff --git a/trunk/drivers/media/video/usbvision/usbvision.h b/trunk/drivers/media/video/usbvision/usbvision.h index f8d7458daf3e..20d7ec624999 100644 --- a/trunk/drivers/media/video/usbvision/usbvision.h +++ b/trunk/drivers/media/video/usbvision/usbvision.h @@ -6,7 +6,7 @@ * Dwaine Garden * * - * Report problems to v4l MailingList: linux-media@vger.kernel.org + * Report problems to v4l MailingList : http://www.redhat.com/mailman/listinfo/video4linux-list * * This module is part of usbvision driver project. * Updates to driver completed by Dwaine P. Garden @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include @@ -357,13 +357,13 @@ extern struct usbvision_device_data_st usbvision_device_data[]; extern struct usb_device_id usbvision_table[]; struct usb_usbvision { - struct v4l2_device v4l2_dev; struct video_device *vdev; /* Video Device */ struct video_device *rdev; /* Radio Device */ struct video_device *vbi; /* VBI Device */ /* i2c Declaration Section*/ struct i2c_adapter i2c_adap; + struct i2c_client i2c_client; struct urb *ctrlUrb; unsigned char ctrlUrbBuffer[8]; @@ -374,6 +374,7 @@ struct usb_usbvision { /* configuration part */ int have_tuner; int tuner_type; + int tuner_addr; int bridgeType; // NT1003, NT1004, NT1005 int radio; int video_inputs; // # of inputs @@ -463,8 +464,6 @@ struct usb_usbvision { int ComprBlockTypes[4]; }; -#define call_all(usbvision, o, f, args...) \ - v4l2_device_call_all(&usbvision->v4l2_dev, 0, o, f, ##args) /* --------------------------------------------------------------- */ /* defined in usbvision-i2c.c */ @@ -476,6 +475,7 @@ struct usb_usbvision { /* ----------------------------------------------------------------------- */ int usbvision_i2c_register(struct usb_usbvision *usbvision); int usbvision_i2c_unregister(struct usb_usbvision *usbvision); +void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,void *arg); /* defined in usbvision-core.c */ int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg); diff --git a/trunk/drivers/media/video/uvc/uvc_ctrl.c b/trunk/drivers/media/video/uvc/uvc_ctrl.c index 0d7e38d6ff6a..d2576f6391c0 100644 --- a/trunk/drivers/media/video/uvc/uvc_ctrl.c +++ b/trunk/drivers/media/video/uvc/uvc_ctrl.c @@ -786,7 +786,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); v4l2_ctrl->id = mapping->id; v4l2_ctrl->type = mapping->v4l2_type; - strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); + strncpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); v4l2_ctrl->flags = 0; if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR)) diff --git a/trunk/drivers/media/video/uvc/uvc_driver.c b/trunk/drivers/media/video/uvc/uvc_driver.c index 399412d7f020..b12873265cc5 100644 --- a/trunk/drivers/media/video/uvc/uvc_driver.c +++ b/trunk/drivers/media/video/uvc/uvc_driver.c @@ -314,7 +314,7 @@ static int uvc_parse_format(struct uvc_device *dev, fmtdesc = uvc_format_by_guid(&buffer[5]); if (fmtdesc != NULL) { - strlcpy(format->name, fmtdesc->name, + strncpy(format->name, fmtdesc->name, sizeof format->name); format->fcc = fmtdesc->fcc; } else { @@ -345,7 +345,7 @@ static int uvc_parse_format(struct uvc_device *dev, return -EINVAL; } - strlcpy(format->name, "MJPEG", sizeof format->name); + strncpy(format->name, "MJPEG", sizeof format->name); format->fcc = V4L2_PIX_FMT_MJPEG; format->flags = UVC_FMT_FLAG_COMPRESSED; format->bpp = 0; @@ -363,13 +363,13 @@ static int uvc_parse_format(struct uvc_device *dev, switch (buffer[8] & 0x7f) { case 0: - strlcpy(format->name, "SD-DV", sizeof format->name); + strncpy(format->name, "SD-DV", sizeof format->name); break; case 1: - strlcpy(format->name, "SDL-DV", sizeof format->name); + strncpy(format->name, "SDL-DV", sizeof format->name); break; case 2: - strlcpy(format->name, "HD-DV", sizeof format->name); + strncpy(format->name, "HD-DV", sizeof format->name); break; default: uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" @@ -379,7 +379,7 @@ static int uvc_parse_format(struct uvc_device *dev, return -EINVAL; } - strlcat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz", + strncat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz", sizeof format->name); format->fcc = V4L2_PIX_FMT_DV; @@ -1526,7 +1526,7 @@ static int uvc_register_video(struct uvc_device *dev) vdev->minor = -1; vdev->fops = &uvc_fops; vdev->release = video_device_release; - strlcpy(vdev->name, dev->name, sizeof vdev->name); + strncpy(vdev->name, dev->name, sizeof vdev->name); /* Set the driver data before calling video_register_device, otherwise * uvc_v4l2_open might race us. @@ -1621,7 +1621,7 @@ static int uvc_probe(struct usb_interface *intf, dev->quirks = id->driver_info | uvc_quirks_param; if (udev->product != NULL) - strlcpy(dev->name, udev->product, sizeof dev->name); + strncpy(dev->name, udev->product, sizeof dev->name); else snprintf(dev->name, sizeof dev->name, "UVC Camera (%04x:%04x)", @@ -1833,15 +1833,6 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceClass = USB_CLASS_VENDOR_SPEC, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0 }, - /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x058f, - .idProduct = 0x3820, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* Apple Built-In iSight */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -1861,15 +1852,6 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_STREAM_NO_FID }, - /* ViMicro */ - { .match_flags = USB_DEVICE_ID_MATCH_VENDOR - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x0ac8, - .idProduct = 0x0000, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_FIX_BANDWIDTH }, /* MT6227 */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -1897,7 +1879,7 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_STREAM_NO_FID }, - /* Syntek (Asus F9SG) */ + /* Asus F9SG */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x174f, @@ -1915,15 +1897,6 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_STREAM_NO_FID }, - /* Syntek (JAOtech Smart Terminal) */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x174f, - .idProduct = 0x8a34, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_STREAM_NO_FID }, /* Lenovo Thinkpad SL500 */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, diff --git a/trunk/drivers/media/video/uvc/uvc_status.c b/trunk/drivers/media/video/uvc/uvc_status.c index 21d87124986b..c705f248da88 100644 --- a/trunk/drivers/media/video/uvc/uvc_status.c +++ b/trunk/drivers/media/video/uvc/uvc_status.c @@ -24,19 +24,26 @@ #ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV static int uvc_input_init(struct uvc_device *dev) { + struct usb_device *udev = dev->udev; struct input_dev *input; + char *phys = NULL; int ret; input = input_allocate_device(); if (input == NULL) return -ENOMEM; - usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys)); - strlcat(dev->input_phys, "/button", sizeof(dev->input_phys)); + phys = kmalloc(6 + strlen(udev->bus->bus_name) + strlen(udev->devpath), + GFP_KERNEL); + if (phys == NULL) { + ret = -ENOMEM; + goto error; + } + sprintf(phys, "usb-%s-%s", udev->bus->bus_name, udev->devpath); input->name = dev->name; - input->phys = dev->input_phys; - usb_to_input_id(dev->udev, &input->id); + input->phys = phys; + usb_to_input_id(udev, &input->id); input->dev.parent = &dev->intf->dev; __set_bit(EV_KEY, input->evbit); @@ -50,6 +57,7 @@ static int uvc_input_init(struct uvc_device *dev) error: input_free_device(input); + kfree(phys); return ret; } diff --git a/trunk/drivers/media/video/uvc/uvc_v4l2.c b/trunk/drivers/media/video/uvc/uvc_v4l2.c index 2a80caa54fb4..d681519d0c8a 100644 --- a/trunk/drivers/media/video/uvc/uvc_v4l2.c +++ b/trunk/drivers/media/video/uvc/uvc_v4l2.c @@ -55,7 +55,7 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video, return -EINVAL; menu_info = &mapping->menu_info[query_menu->index]; - strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); + strncpy(query_menu->name, menu_info->name, 32); return 0; } @@ -486,10 +486,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) struct v4l2_capability *cap = arg; memset(cap, 0, sizeof *cap); - strlcpy(cap->driver, "uvcvideo", sizeof cap->driver); - strlcpy(cap->card, vdev->name, sizeof cap->card); - usb_make_path(video->dev->udev, - cap->bus_info, sizeof(cap->bus_info)); + strncpy(cap->driver, "uvcvideo", sizeof cap->driver); + strncpy(cap->card, vdev->name, 32); + strncpy(cap->bus_info, video->dev->udev->bus->bus_name, + sizeof cap->bus_info); cap->version = DRIVER_VERSION_NUMBER; if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) cap->capabilities = V4L2_CAP_VIDEO_CAPTURE @@ -620,7 +620,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) memset(input, 0, sizeof *input); input->index = index; - strlcpy(input->name, iterm->name, sizeof input->name); + strncpy(input->name, iterm->name, sizeof input->name); if (UVC_ENTITY_TYPE(iterm) == ITT_CAMERA) input->type = V4L2_INPUT_TYPE_CAMERA; break; @@ -673,22 +673,16 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct v4l2_fmtdesc *fmt = arg; struct uvc_format *format; - enum v4l2_buf_type type = fmt->type; - __u32 index = fmt->index; if (fmt->type != video->streaming->type || fmt->index >= video->streaming->nformats) return -EINVAL; - memset(fmt, 0, sizeof(*fmt)); - fmt->index = index; - fmt->type = type; - format = &video->streaming->format[fmt->index]; fmt->flags = 0; if (format->flags & UVC_FMT_FLAG_COMPRESSED) fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; - strlcpy(fmt->description, format->name, + strncpy(fmt->description, format->name, sizeof fmt->description); fmt->description[sizeof fmt->description - 1] = 0; fmt->pixelformat = format->fcc; diff --git a/trunk/drivers/media/video/uvc/uvc_video.c b/trunk/drivers/media/video/uvc/uvc_video.c index a95e17329c5b..9bc4705be78d 100644 --- a/trunk/drivers/media/video/uvc/uvc_video.c +++ b/trunk/drivers/media/video/uvc/uvc_video.c @@ -61,7 +61,7 @@ int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, return 0; } -static void uvc_fixup_video_ctrl(struct uvc_video_device *video, +static void uvc_fixup_buffer_size(struct uvc_video_device *video, struct uvc_streaming_control *ctrl) { struct uvc_format *format; @@ -84,31 +84,6 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video, video->dev->uvc_version < 0x0110)) ctrl->dwMaxVideoFrameSize = frame->dwMaxVideoFrameBufferSize; - - if (video->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH && - video->streaming->intf->num_altsetting > 1) { - u32 interval; - u32 bandwidth; - - interval = (ctrl->dwFrameInterval > 100000) - ? ctrl->dwFrameInterval - : frame->dwFrameInterval[0]; - - /* Compute a bandwidth estimation by multiplying the frame - * size by the number of video frames per second, divide the - * result by the number of USB frames (or micro-frames for - * high-speed devices) per second and add the UVC header size - * (assumed to be 12 bytes long). - */ - bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp; - bandwidth *= 10000000 / interval + 1; - bandwidth /= 1000; - if (video->dev->udev->speed == USB_SPEED_HIGH) - bandwidth /= 8; - bandwidth += 12; - - ctrl->dwMaxPayloadTransferSize = bandwidth; - } } static int uvc_get_video_ctrl(struct uvc_video_device *video, @@ -183,11 +158,10 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, ctrl->bMaxVersion = 0; } - /* Some broken devices return null or wrong dwMaxVideoFrameSize and - * dwMaxPayloadTransferSize fields. Try to get the value from the - * format and frame descriptors. + /* Some broken devices return a null or wrong dwMaxVideoFrameSize. + * Try to get the value from the format and frame descriptors. */ - uvc_fixup_video_ctrl(video, ctrl); + uvc_fixup_buffer_size(video, ctrl); ret = 0; out: @@ -566,9 +540,6 @@ static void uvc_video_decode_bulk(struct urb *urb, u8 *mem; int len, ret; - if (urb->actual_length == 0) - return; - mem = urb->transfer_buffer; len = urb->actual_length; video->bulk.payload_size += len; @@ -728,47 +699,27 @@ static void uvc_free_urb_buffers(struct uvc_video_device *video) * already allocated when resuming from suspend, in which case it will * return without touching the buffers. * - * Limit the buffer size to UVC_MAX_PACKETS bulk/isochronous packets. If the - * system is too low on memory try successively smaller numbers of packets - * until allocation succeeds. - * - * Return the number of allocated packets on success or 0 when out of memory. + * Return 0 on success or -ENOMEM when out of memory. */ static int uvc_alloc_urb_buffers(struct uvc_video_device *video, - unsigned int size, unsigned int psize, gfp_t gfp_flags) + unsigned int size) { - unsigned int npackets; unsigned int i; /* Buffers are already allocated, bail out. */ if (video->urb_size) return 0; - /* Compute the number of packets. Bulk endpoints might transfer UVC - * payloads accross multiple URBs. - */ - npackets = DIV_ROUND_UP(size, psize); - if (npackets > UVC_MAX_PACKETS) - npackets = UVC_MAX_PACKETS; - - /* Retry allocations until one succeed. */ - for (; npackets > 1; npackets /= 2) { - for (i = 0; i < UVC_URBS; ++i) { - video->urb_buffer[i] = usb_buffer_alloc( - video->dev->udev, psize * npackets, - gfp_flags | __GFP_NOWARN, &video->urb_dma[i]); - if (!video->urb_buffer[i]) { - uvc_free_urb_buffers(video); - break; - } - } - - if (i == UVC_URBS) { - video->urb_size = psize * npackets; - return npackets; + for (i = 0; i < UVC_URBS; ++i) { + video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, + size, GFP_KERNEL, &video->urb_dma[i]); + if (video->urb_buffer[i] == NULL) { + uvc_free_urb_buffers(video); + return -ENOMEM; } } + video->urb_size = size; return 0; } @@ -802,19 +753,29 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, { struct urb *urb; unsigned int npackets, i, j; - u16 psize; - u32 size; + __u16 psize; + __u32 size; + /* Compute the number of isochronous packets to allocate by dividing + * the maximum video frame size by the packet size. Limit the result + * to UVC_MAX_ISO_PACKETS. + */ psize = le16_to_cpu(ep->desc.wMaxPacketSize); psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); + size = video->streaming->ctrl.dwMaxVideoFrameSize; + if (size > UVC_MAX_FRAME_SIZE) + return -EINVAL; - npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags); - if (npackets == 0) - return -ENOMEM; + npackets = DIV_ROUND_UP(size, psize); + if (npackets > UVC_MAX_ISO_PACKETS) + npackets = UVC_MAX_ISO_PACKETS; size = npackets * psize; + if (uvc_alloc_urb_buffers(video, size) < 0) + return -ENOMEM; + for (i = 0; i < UVC_URBS; ++i) { urb = usb_alloc_urb(npackets, gfp_flags); if (urb == NULL) { @@ -853,20 +814,25 @@ static int uvc_init_video_bulk(struct uvc_video_device *video, struct usb_host_endpoint *ep, gfp_t gfp_flags) { struct urb *urb; - unsigned int npackets, pipe, i; - u16 psize; - u32 size; - + unsigned int pipe, i; + __u16 psize; + __u32 size; + + /* Compute the bulk URB size. Some devices set the maximum payload + * size to a value too high for memory-constrained devices. We must + * then transfer the payload accross multiple URBs. To be consistant + * with isochronous mode, allocate maximum UVC_MAX_ISO_PACKETS per bulk + * URB. + */ psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff; size = video->streaming->ctrl.dwMaxPayloadTransferSize; video->bulk.max_payload_size = size; + if (size > psize * UVC_MAX_ISO_PACKETS) + size = psize * UVC_MAX_ISO_PACKETS; - npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags); - if (npackets == 0) + if (uvc_alloc_urb_buffers(video, size) < 0) return -ENOMEM; - size = npackets * psize; - if (usb_endpoint_dir_in(&ep->desc)) pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress); @@ -1055,20 +1021,11 @@ int uvc_video_init(struct uvc_video_device *video) */ usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); - /* Set the streaming probe control with default streaming parameters - * retrieved from the device. Webcams that don't suport GET_DEF - * requests on the probe control will just keep their current streaming - * parameters. - */ - if (uvc_get_video_ctrl(video, probe, 1, GET_DEF) == 0) - uvc_set_video_ctrl(video, probe, 1); - - /* Initialize the streaming parameters with the probe control current - * value. This makes sure SET_CUR requests on the streaming commit - * control will always use values retrieved from a successful GET_CUR - * request on the probe control, as required by the UVC specification. + /* Some webcams don't suport GET_DEF requests on the probe control. We + * fall back to GET_CUR if GET_DEF fails. */ - if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0) + if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 && + (ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0) return ret; /* Check if the default format descriptor exists. Use the first diff --git a/trunk/drivers/media/video/uvc/uvcvideo.h b/trunk/drivers/media/video/uvc/uvcvideo.h index e5014e668f99..027947ea9b6e 100644 --- a/trunk/drivers/media/video/uvc/uvcvideo.h +++ b/trunk/drivers/media/video/uvc/uvcvideo.h @@ -296,8 +296,10 @@ struct uvc_xu_control { /* Number of isochronous URBs. */ #define UVC_URBS 5 -/* Maximum number of packets per URB. */ -#define UVC_MAX_PACKETS 32 +/* Maximum number of packets per isochronous URB. */ +#define UVC_MAX_ISO_PACKETS 40 +/* Maximum frame size in bytes, for sanity checking. */ +#define UVC_MAX_FRAME_SIZE (16*1024*1024) /* Maximum number of video buffers. */ #define UVC_MAX_VIDEO_BUFFERS 32 /* Maximum status buffer size in bytes of interrupt URB. */ @@ -314,7 +316,6 @@ struct uvc_xu_control { #define UVC_QUIRK_STREAM_NO_FID 0x00000010 #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 #define UVC_QUIRK_PRUNE_CONTROLS 0x00000040 -#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 @@ -648,7 +649,6 @@ struct uvc_device { struct urb *int_urb; __u8 *status; struct input_dev *input; - char input_phys[64]; /* Video Streaming interfaces */ struct list_head streaming; diff --git a/trunk/drivers/media/video/v4l2-common.c b/trunk/drivers/media/video/v4l2-common.c index 1da8cb836cb6..b8f2be8d5c0e 100644 --- a/trunk/drivers/media/video/v4l2-common.c +++ b/trunk/drivers/media/video/v4l2-common.c @@ -334,12 +334,6 @@ const char **v4l2_ctrl_get_menu(u32 id) "Aperture Priority Mode", NULL }; - static const char *colorfx[] = { - "None", - "Black & White", - "Sepia", - NULL - }; switch (id) { case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: @@ -376,8 +370,6 @@ const char **v4l2_ctrl_get_menu(u32 id) return camera_power_line_frequency; case V4L2_CID_EXPOSURE_AUTO: return camera_exposure_auto; - case V4L2_CID_COLORFX: - return colorfx; default: return NULL; } @@ -390,16 +382,16 @@ const char *v4l2_ctrl_get_name(u32 id) switch (id) { /* USER controls */ case V4L2_CID_USER_CLASS: return "User Controls"; - case V4L2_CID_BRIGHTNESS: return "Brightness"; - case V4L2_CID_CONTRAST: return "Contrast"; - case V4L2_CID_SATURATION: return "Saturation"; - case V4L2_CID_HUE: return "Hue"; case V4L2_CID_AUDIO_VOLUME: return "Volume"; + case V4L2_CID_AUDIO_MUTE: return "Mute"; case V4L2_CID_AUDIO_BALANCE: return "Balance"; case V4L2_CID_AUDIO_BASS: return "Bass"; case V4L2_CID_AUDIO_TREBLE: return "Treble"; - case V4L2_CID_AUDIO_MUTE: return "Mute"; case V4L2_CID_AUDIO_LOUDNESS: return "Loudness"; + case V4L2_CID_BRIGHTNESS: return "Brightness"; + case V4L2_CID_CONTRAST: return "Contrast"; + case V4L2_CID_SATURATION: return "Saturation"; + case V4L2_CID_HUE: return "Hue"; case V4L2_CID_BLACK_LEVEL: return "Black Level"; case V4L2_CID_AUTO_WHITE_BALANCE: return "White Balance, Automatic"; case V4L2_CID_DO_WHITE_BALANCE: return "Do White Balance"; @@ -420,7 +412,6 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_BACKLIGHT_COMPENSATION: return "Backlight Compensation"; case V4L2_CID_CHROMA_AGC: return "Chroma AGC"; case V4L2_CID_COLOR_KILLER: return "Color Killer"; - case V4L2_CID_COLORFX: return "Color Effects"; /* MPEG controls */ case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls"; @@ -499,25 +490,16 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste case V4L2_CID_HFLIP: case V4L2_CID_VFLIP: case V4L2_CID_HUE_AUTO: - case V4L2_CID_CHROMA_AGC: - case V4L2_CID_COLOR_KILLER: case V4L2_CID_MPEG_AUDIO_MUTE: case V4L2_CID_MPEG_VIDEO_MUTE: case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: case V4L2_CID_MPEG_VIDEO_PULLDOWN: case V4L2_CID_EXPOSURE_AUTO_PRIORITY: - case V4L2_CID_FOCUS_AUTO: case V4L2_CID_PRIVACY: qctrl->type = V4L2_CTRL_TYPE_BOOLEAN; min = 0; max = step = 1; break; - case V4L2_CID_PAN_RESET: - case V4L2_CID_TILT_RESET: - qctrl->type = V4L2_CTRL_TYPE_BUTTON; - qctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; - min = max = step = def = 0; - break; case V4L2_CID_POWER_LINE_FREQUENCY: case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: case V4L2_CID_MPEG_AUDIO_ENCODING: @@ -535,7 +517,6 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste case V4L2_CID_MPEG_STREAM_TYPE: case V4L2_CID_MPEG_STREAM_VBI_FMT: case V4L2_CID_EXPOSURE_AUTO: - case V4L2_CID_COLORFX: qctrl->type = V4L2_CTRL_TYPE_MENU; step = 1; break; @@ -566,29 +547,161 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste case V4L2_CID_CONTRAST: case V4L2_CID_SATURATION: case V4L2_CID_HUE: - case V4L2_CID_RED_BALANCE: - case V4L2_CID_BLUE_BALANCE: - case V4L2_CID_GAMMA: - case V4L2_CID_SHARPNESS: qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; break; - case V4L2_CID_PAN_RELATIVE: - case V4L2_CID_TILT_RELATIVE: - case V4L2_CID_FOCUS_RELATIVE: - case V4L2_CID_ZOOM_RELATIVE: - qctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; - break; } qctrl->minimum = min; qctrl->maximum = max; qctrl->step = step; qctrl->default_value = def; qctrl->reserved[0] = qctrl->reserved[1] = 0; - strlcpy(qctrl->name, name, sizeof(qctrl->name)); + snprintf(qctrl->name, sizeof(qctrl->name), name); return 0; } EXPORT_SYMBOL(v4l2_ctrl_query_fill); +/* Fill in a struct v4l2_queryctrl with standard values based on + the control ID. */ +int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) +{ + switch (qctrl->id) { + /* USER controls */ + case V4L2_CID_USER_CLASS: + case V4L2_CID_MPEG_CLASS: + return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0); + case V4L2_CID_AUDIO_VOLUME: + return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 58880); + case V4L2_CID_AUDIO_MUTE: + case V4L2_CID_AUDIO_LOUDNESS: + return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0); + case V4L2_CID_AUDIO_BALANCE: + case V4L2_CID_AUDIO_BASS: + case V4L2_CID_AUDIO_TREBLE: + return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 32768); + case V4L2_CID_BRIGHTNESS: + return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128); + case V4L2_CID_CONTRAST: + case V4L2_CID_SATURATION: + return v4l2_ctrl_query_fill(qctrl, 0, 127, 1, 64); + case V4L2_CID_HUE: + return v4l2_ctrl_query_fill(qctrl, -128, 127, 1, 0); + + /* MPEG controls */ + case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000); + case V4L2_CID_MPEG_AUDIO_ENCODING: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_ENCODING_LAYER_1, + V4L2_MPEG_AUDIO_ENCODING_AC3, 1, + V4L2_MPEG_AUDIO_ENCODING_LAYER_2); + case V4L2_CID_MPEG_AUDIO_L1_BITRATE: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_L1_BITRATE_32K, + V4L2_MPEG_AUDIO_L1_BITRATE_448K, 1, + V4L2_MPEG_AUDIO_L1_BITRATE_256K); + case V4L2_CID_MPEG_AUDIO_L2_BITRATE: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_L2_BITRATE_32K, + V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, + V4L2_MPEG_AUDIO_L2_BITRATE_224K); + case V4L2_CID_MPEG_AUDIO_L3_BITRATE: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_L3_BITRATE_32K, + V4L2_MPEG_AUDIO_L3_BITRATE_320K, 1, + V4L2_MPEG_AUDIO_L3_BITRATE_192K); + case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: + return v4l2_ctrl_query_fill(qctrl, 0, 6400, 1, 3200000); + case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_AC3_BITRATE_32K, + V4L2_MPEG_AUDIO_AC3_BITRATE_640K, 1, + V4L2_MPEG_AUDIO_AC3_BITRATE_384K); + case V4L2_CID_MPEG_AUDIO_MODE: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_MODE_STEREO, + V4L2_MPEG_AUDIO_MODE_MONO, 1, + V4L2_MPEG_AUDIO_MODE_STEREO); + case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4); + case V4L2_CID_MPEG_AUDIO_EMPHASIS: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_EMPHASIS_NONE, + V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1, + V4L2_MPEG_AUDIO_EMPHASIS_NONE); + case V4L2_CID_MPEG_AUDIO_CRC: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_CRC_NONE, + V4L2_MPEG_AUDIO_CRC_CRC16, 1, + V4L2_MPEG_AUDIO_CRC_NONE); + case V4L2_CID_MPEG_AUDIO_MUTE: + return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0); + case V4L2_CID_MPEG_VIDEO_ENCODING: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_VIDEO_ENCODING_MPEG_1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2); + case V4L2_CID_MPEG_VIDEO_ASPECT: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_VIDEO_ASPECT_1x1, + V4L2_MPEG_VIDEO_ASPECT_221x100, 1, + V4L2_MPEG_VIDEO_ASPECT_4x3); + case V4L2_CID_MPEG_VIDEO_B_FRAMES: + return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2); + case V4L2_CID_MPEG_VIDEO_GOP_SIZE: + return v4l2_ctrl_query_fill(qctrl, 1, 34, 1, 12); + case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: + return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1); + case V4L2_CID_MPEG_VIDEO_PULLDOWN: + return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0); + case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, + V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1, + V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); + case V4L2_CID_MPEG_VIDEO_BITRATE: + return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000); + case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: + return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000); + case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: + return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0); + case V4L2_CID_MPEG_VIDEO_MUTE: + return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0); + case V4L2_CID_MPEG_VIDEO_MUTE_YUV: /* Init YUV (really YCbCr) to black */ + return v4l2_ctrl_query_fill(qctrl, 0, 0xffffff, 1, 0x008080); + case V4L2_CID_MPEG_STREAM_TYPE: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_STREAM_TYPE_MPEG2_PS, + V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1, + V4L2_MPEG_STREAM_TYPE_MPEG2_PS); + case V4L2_CID_MPEG_STREAM_PID_PMT: + return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16); + case V4L2_CID_MPEG_STREAM_PID_AUDIO: + return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260); + case V4L2_CID_MPEG_STREAM_PID_VIDEO: + return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256); + case V4L2_CID_MPEG_STREAM_PID_PCR: + return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259); + case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: + return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0); + case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: + return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0); + case V4L2_CID_MPEG_STREAM_VBI_FMT: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_STREAM_VBI_FMT_NONE, + V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1, + V4L2_MPEG_STREAM_VBI_FMT_NONE); + default: + return -EINVAL; + } +} +EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); + /* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and the menu. The qctrl pointer may be NULL, in which case it is ignored. If menu_items is NULL, then the menu items are retrieved using @@ -607,7 +720,7 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc for (i = 0; i < qmenu->index && menu_items[i]; i++) ; if (menu_items[i] == NULL || menu_items[i][0] == '\0') return -EINVAL; - strlcpy(qmenu->name, menu_items[qmenu->index], sizeof(qmenu->name)); + snprintf(qmenu->name, sizeof(qmenu->name), menu_items[qmenu->index]); return 0; } EXPORT_SYMBOL(v4l2_ctrl_query_menu); @@ -624,8 +737,8 @@ int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *id return -EINVAL; while (*ids != V4L2_CTRL_MENU_IDS_END) { if (*ids++ == qmenu->index) { - strlcpy(qmenu->name, menu_items[qmenu->index], - sizeof(qmenu->name)); + snprintf(qmenu->name, sizeof(qmenu->name), + menu_items[qmenu->index]); return 0; } } @@ -636,7 +749,7 @@ EXPORT_SYMBOL(v4l2_ctrl_query_menu_valid_items); /* ctrl_classes points to an array of u32 pointers, the last element is a NULL pointer. Each u32 array is a 0-terminated array of control IDs. Each array must be sorted low to high and belong to the same control - class. The array of u32 pointers must also be sorted, from low class IDs + class. The array of u32 pointer must also be sorted, from low class IDs to high class IDs. This function returns the first ID that follows after the given ID. @@ -797,10 +910,10 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter, struct i2c_board_info info; BUG_ON(!dev); - +#ifdef MODULE if (module_name) request_module(module_name); - +#endif /* Setup the i2c board info with the device type and the device address. */ memset(&info, 0, sizeof(info)); @@ -814,11 +927,11 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter, We need better support from the kernel so that we can easily wait for the load to finish. */ if (client == NULL || client->driver == NULL) - goto error; + return NULL; /* Lock the module so we can safely get the v4l2_subdev pointer */ if (!try_module_get(client->driver->driver.owner)) - goto error; + return NULL; sd = i2c_get_clientdata(client); /* Register with the v4l2_device which increases the module's @@ -827,13 +940,8 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter, sd = NULL; /* Decrease the module use count to match the first try_module_get. */ module_put(client->driver->driver.owner); - -error: - /* If we have a client but no subdev, then something went wrong and - we must unregister the client. */ - if (client && sd == NULL) - i2c_unregister_device(client); return sd; + } EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev); @@ -850,10 +958,10 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter, struct i2c_board_info info; BUG_ON(!dev); - +#ifdef MODULE if (module_name) request_module(module_name); - +#endif /* Setup the i2c board info with the device type and the device address. */ memset(&info, 0, sizeof(info)); @@ -866,11 +974,11 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter, We need better support from the kernel so that we can easily wait for the load to finish. */ if (client == NULL || client->driver == NULL) - goto error; + return NULL; /* Lock the module so we can safely get the v4l2_subdev pointer */ if (!try_module_get(client->driver->driver.owner)) - goto error; + return NULL; sd = i2c_get_clientdata(client); /* Register with the v4l2_device which increases the module's @@ -879,59 +987,8 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter, sd = NULL; /* Decrease the module use count to match the first try_module_get. */ module_put(client->driver->driver.owner); - -error: - /* If we have a client but no subdev, then something went wrong and - we must unregister the client. */ - if (client && sd == NULL) - i2c_unregister_device(client); return sd; } EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev); -/* Return i2c client address of v4l2_subdev. */ -unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return client ? client->addr : I2C_CLIENT_END; -} -EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_addr); - -/* Return a list of I2C tuner addresses to probe. Use only if the tuner - addresses are unknown. */ -const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type) -{ - static const unsigned short radio_addrs[] = { -#if defined(CONFIG_MEDIA_TUNER_TEA5761) || defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE) - 0x10, -#endif - 0x60, - I2C_CLIENT_END - }; - static const unsigned short demod_addrs[] = { - 0x42, 0x43, 0x4a, 0x4b, - I2C_CLIENT_END - }; - static const unsigned short tv_addrs[] = { - 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */ - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - I2C_CLIENT_END - }; - - switch (type) { - case ADDRS_RADIO: - return radio_addrs; - case ADDRS_DEMOD: - return demod_addrs; - case ADDRS_TV: - return tv_addrs; - case ADDRS_TV_WITH_DEMOD: - return tv_addrs + 4; - } - return NULL; -} -EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs); - #endif diff --git a/trunk/drivers/media/video/v4l2-compat-ioctl32.c b/trunk/drivers/media/video/v4l2-compat-ioctl32.c index 0056b115b42e..110376be5d2b 100644 --- a/trunk/drivers/media/video/v4l2-compat-ioctl32.c +++ b/trunk/drivers/media/video/v4l2-compat-ioctl32.c @@ -1047,6 +1047,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case VIDIOC_DBG_S_REGISTER: case VIDIOC_DBG_G_REGISTER: case VIDIOC_DBG_G_CHIP_IDENT: + case VIDIOC_G_CHIP_IDENT_OLD: case VIDIOC_S_HW_FREQ_SEEK: ret = do_video_ioctl(file, cmd, arg); break; diff --git a/trunk/drivers/media/video/v4l2-dev.c b/trunk/drivers/media/video/v4l2-dev.c index 91228b3df07d..13f87c22e78d 100644 --- a/trunk/drivers/media/video/v4l2-dev.c +++ b/trunk/drivers/media/video/v4l2-dev.c @@ -198,23 +198,6 @@ static long v4l2_unlocked_ioctl(struct file *filp, return vdev->fops->unlocked_ioctl(filp, cmd, arg); } -#ifdef CONFIG_MMU -#define v4l2_get_unmapped_area NULL -#else -static unsigned long v4l2_get_unmapped_area(struct file *filp, - unsigned long addr, unsigned long len, unsigned long pgoff, - unsigned long flags) -{ - struct video_device *vdev = video_devdata(filp); - - if (!vdev->fops->get_unmapped_area) - return -ENOSYS; - if (video_is_unregistered(vdev)) - return -ENODEV; - return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags); -} -#endif - static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) { struct video_device *vdev = video_devdata(filp); @@ -267,7 +250,6 @@ static const struct file_operations v4l2_unlocked_fops = { .read = v4l2_read, .write = v4l2_write, .open = v4l2_open, - .get_unmapped_area = v4l2_get_unmapped_area, .mmap = v4l2_mmap, .unlocked_ioctl = v4l2_unlocked_ioctl, #ifdef CONFIG_COMPAT @@ -283,7 +265,6 @@ static const struct file_operations v4l2_fops = { .read = v4l2_read, .write = v4l2_write, .open = v4l2_open, - .get_unmapped_area = v4l2_get_unmapped_area, .mmap = v4l2_mmap, .ioctl = v4l2_ioctl, #ifdef CONFIG_COMPAT @@ -307,38 +288,37 @@ static const struct file_operations v4l2_fops = { */ static int get_index(struct video_device *vdev, int num) { - /* This can be static since this function is called with the global - videodev_lock held. */ - static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES); + u32 used = 0; + const int max_index = sizeof(used) * 8 - 1; int i; - if (num >= VIDEO_NUM_DEVICES) { + /* Currently a single v4l driver instance cannot create more than + 32 devices. + Increase to u64 or an array of u32 if more are needed. */ + if (num > max_index) { printk(KERN_ERR "videodev: %s num is too large\n", __func__); return -EINVAL; } - /* Some drivers do not set the parent. In that case always return - num or 0. */ + /* Some drivers do not set the parent. In that case always return 0. */ if (vdev->parent == NULL) - return num >= 0 ? num : 0; - - bitmap_zero(used, VIDEO_NUM_DEVICES); + return 0; for (i = 0; i < VIDEO_NUM_DEVICES; i++) { if (video_device[i] != NULL && video_device[i]->parent == vdev->parent) { - set_bit(video_device[i]->index, used); + used |= 1 << video_device[i]->index; } } if (num >= 0) { - if (test_bit(num, used)) + if (used & (1 << num)) return -ENFILE; return num; } - i = find_first_zero_bit(used, VIDEO_NUM_DEVICES); - return i == VIDEO_NUM_DEVICES ? -ENFILE : i; + i = ffz(used); + return i > max_index ? -ENFILE : i; } int video_register_device(struct video_device *vdev, int type, int nr) @@ -385,11 +365,12 @@ int video_register_device_index(struct video_device *vdev, int type, int nr, /* A minor value of -1 marks this video device as never having been registered */ - vdev->minor = -1; + if (vdev) + vdev->minor = -1; /* the release callback MUST be present */ - WARN_ON(!vdev->release); - if (!vdev->release) + WARN_ON(!vdev || !vdev->release); + if (!vdev || !vdev->release) return -EINVAL; /* Part 1: check device type */ @@ -414,7 +395,7 @@ int video_register_device_index(struct video_device *vdev, int type, int nr, vdev->vfl_type = type; vdev->cdev = NULL; - if (vdev->v4l2_dev && vdev->v4l2_dev->dev) + if (vdev->v4l2_dev) vdev->parent = vdev->v4l2_dev->dev; /* Part 2: find a free minor, kernel number and device index. */ @@ -601,7 +582,6 @@ module_exit(videodev_exit) MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab "); MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2"); MODULE_LICENSE("GPL"); -MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR); /* diff --git a/trunk/drivers/media/video/v4l2-device.c b/trunk/drivers/media/video/v4l2-device.c index 94aa485ade52..8a4b74f3129f 100644 --- a/trunk/drivers/media/video/v4l2-device.c +++ b/trunk/drivers/media/video/v4l2-device.c @@ -26,66 +26,48 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) { - if (v4l2_dev == NULL) + if (dev == NULL || v4l2_dev == NULL) return -EINVAL; - + /* Warn if we apparently re-register a device */ + WARN_ON(dev_get_drvdata(dev) != NULL); INIT_LIST_HEAD(&v4l2_dev->subdevs); spin_lock_init(&v4l2_dev->lock); v4l2_dev->dev = dev; - if (dev == NULL) { - /* If dev == NULL, then name must be filled in by the caller */ - WARN_ON(!v4l2_dev->name[0]); - return 0; - } - - /* Set name to driver name + device name if it is empty. */ - if (!v4l2_dev->name[0]) - snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s", + snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s", dev->driver->name, dev_name(dev)); - if (dev_get_drvdata(dev)) - v4l2_warn(v4l2_dev, "Non-NULL drvdata on register\n"); dev_set_drvdata(dev, v4l2_dev); return 0; } EXPORT_SYMBOL_GPL(v4l2_device_register); -void v4l2_device_disconnect(struct v4l2_device *v4l2_dev) -{ - if (v4l2_dev->dev) { - dev_set_drvdata(v4l2_dev->dev, NULL); - v4l2_dev->dev = NULL; - } -} -EXPORT_SYMBOL_GPL(v4l2_device_disconnect); - void v4l2_device_unregister(struct v4l2_device *v4l2_dev) { struct v4l2_subdev *sd, *next; - if (v4l2_dev == NULL) + if (v4l2_dev == NULL || v4l2_dev->dev == NULL) return; - v4l2_device_disconnect(v4l2_dev); - - /* Unregister subdevs */ + dev_set_drvdata(v4l2_dev->dev, NULL); + /* unregister subdevs */ list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) v4l2_device_unregister_subdev(sd); + + v4l2_dev->dev = NULL; } EXPORT_SYMBOL_GPL(v4l2_device_unregister); -int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, - struct v4l2_subdev *sd) +int v4l2_device_register_subdev(struct v4l2_device *dev, struct v4l2_subdev *sd) { /* Check for valid input */ - if (v4l2_dev == NULL || sd == NULL || !sd->name[0]) + if (dev == NULL || sd == NULL || !sd->name[0]) return -EINVAL; /* Warn if we apparently re-register a subdev */ - WARN_ON(sd->v4l2_dev != NULL); + WARN_ON(sd->dev != NULL); if (!try_module_get(sd->owner)) return -ENODEV; - sd->v4l2_dev = v4l2_dev; - spin_lock(&v4l2_dev->lock); - list_add_tail(&sd->list, &v4l2_dev->subdevs); - spin_unlock(&v4l2_dev->lock); + sd->dev = dev; + spin_lock(&dev->lock); + list_add_tail(&sd->list, &dev->subdevs); + spin_unlock(&dev->lock); return 0; } EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); @@ -93,12 +75,12 @@ EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); void v4l2_device_unregister_subdev(struct v4l2_subdev *sd) { /* return if it isn't registered */ - if (sd == NULL || sd->v4l2_dev == NULL) + if (sd == NULL || sd->dev == NULL) return; - spin_lock(&sd->v4l2_dev->lock); + spin_lock(&sd->dev->lock); list_del(&sd->list); - spin_unlock(&sd->v4l2_dev->lock); - sd->v4l2_dev = NULL; + spin_unlock(&sd->dev->lock); + sd->dev = NULL; module_put(sd->owner); } EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev); diff --git a/trunk/drivers/media/video/v4l2-ioctl.c b/trunk/drivers/media/video/v4l2-ioctl.c index f41c6f506f42..52d687b165e0 100644 --- a/trunk/drivers/media/video/v4l2-ioctl.c +++ b/trunk/drivers/media/video/v4l2-ioctl.c @@ -17,7 +17,6 @@ #include #define __OLD_VIDIOC_ /* To allow fixing old calls */ -#include #include #ifdef CONFIG_VIDEO_V4L1 @@ -25,7 +24,7 @@ #endif #include #include -#include +#include #define dbgarg(cmd, fmt, arg...) \ do { \ @@ -101,27 +100,25 @@ const char *v4l2_norm_to_name(v4l2_std_id id) } EXPORT_SYMBOL(v4l2_norm_to_name); -/* Returns frame period for the given standard */ -void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod) -{ - if (id & V4L2_STD_525_60) { - frameperiod->numerator = 1001; - frameperiod->denominator = 30000; - } else { - frameperiod->numerator = 1; - frameperiod->denominator = 25; - } -} -EXPORT_SYMBOL(v4l2_video_std_frame_period); - /* Fill in the fields of a v4l2_standard structure according to the 'id' and 'transmission' parameters. Returns negative on error. */ int v4l2_video_std_construct(struct v4l2_standard *vs, int id, const char *name) { - vs->id = id; - v4l2_video_std_frame_period(id, &vs->frameperiod); - vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625; + u32 index = vs->index; + + memset(vs, 0, sizeof(struct v4l2_standard)); + vs->index = index; + vs->id = id; + if (id & V4L2_STD_525_60) { + vs->frameperiod.numerator = 1001; + vs->frameperiod.denominator = 30000; + vs->framelines = 525; + } else { + vs->frameperiod.numerator = 1; + vs->frameperiod.denominator = 25; + vs->framelines = 625; + } strlcpy(vs->name, name, sizeof(vs->name)); return 0; } @@ -276,6 +273,19 @@ static const char *v4l2_ioctls[] = { #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) static const char *v4l2_int_ioctls[] = { +#ifdef CONFIG_VIDEO_V4L1_COMPAT + [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", + [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", + [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", + [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT", + [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT", + [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT", + [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE", + [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO", + [_IOC_NR(DECODER_INIT)] = "DECODER_INIT", + [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS", + [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP", +#endif [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", @@ -644,6 +654,8 @@ static long __video_do_ioctl(struct file *file, if (cmd == VIDIOCGMBUF) { struct video_mbuf *p = arg; + memset(p, 0, sizeof(*p)); + if (!ops->vidiocgmbuf) return ret; ret = ops->vidiocgmbuf(file, fh, p); @@ -670,6 +682,7 @@ static long __video_do_ioctl(struct file *file, case VIDIOC_QUERYCAP: { struct v4l2_capability *cap = (struct v4l2_capability *)arg; + memset(cap, 0, sizeof(*cap)); if (!ops->vidioc_querycap) break; @@ -712,8 +725,16 @@ static long __video_do_ioctl(struct file *file, case VIDIOC_ENUM_FMT: { struct v4l2_fmtdesc *f = arg; + enum v4l2_buf_type type; + unsigned int index; - switch (f->type) { + index = f->index; + type = f->type; + memset(f, 0, sizeof(*f)); + f->index = index; + f->type = type; + + switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: if (ops->vidioc_enum_fmt_vid_cap) ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f); @@ -750,6 +771,8 @@ static long __video_do_ioctl(struct file *file, { struct v4l2_format *f = (struct v4l2_format *)arg; + memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data)); + /* FIXME: Should be one dump per type */ dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); @@ -1065,6 +1088,7 @@ static long __video_do_ioctl(struct file *file, return -EINVAL; v4l2_video_std_construct(p, curr_id, descr); + p->index = index; dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, " "framelines=%d\n", p->index, @@ -1129,9 +1153,12 @@ static long __video_do_ioctl(struct file *file, case VIDIOC_ENUMINPUT: { struct v4l2_input *p = arg; + int i = p->index; if (!ops->vidioc_enum_input) break; + memset(p, 0, sizeof(*p)); + p->index = i; ret = ops->vidioc_enum_input(file, fh, p); if (!ret) @@ -1170,9 +1197,12 @@ static long __video_do_ioctl(struct file *file, case VIDIOC_ENUMOUTPUT: { struct v4l2_output *p = arg; + int i = p->index; if (!ops->vidioc_enum_output) break; + memset(p, 0, sizeof(*p)); + p->index = i; ret = ops->vidioc_enum_output(file, fh, p); if (!ret) @@ -1348,10 +1378,13 @@ static long __video_do_ioctl(struct file *file, case VIDIOC_G_AUDIO: { struct v4l2_audio *p = arg; + __u32 index = p->index; if (!ops->vidioc_g_audio) break; + memset(p, 0, sizeof(*p)); + p->index = index; ret = ops->vidioc_g_audio(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " @@ -1393,7 +1426,7 @@ static long __video_do_ioctl(struct file *file, if (!ops->vidioc_g_audout) break; - + dbgarg(cmd, "Enum for index=%d\n", p->index); ret = ops->vidioc_g_audout(file, fh, p); if (!ret) dbgarg2("index=%d, name=%s, capability=%d, " @@ -1446,10 +1479,15 @@ static long __video_do_ioctl(struct file *file, case VIDIOC_G_CROP: { struct v4l2_crop *p = arg; + __u32 type; if (!ops->vidioc_g_crop) break; + type = p->type; + memset(p, 0, sizeof(*p)); + p->type = type; + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); ret = ops->vidioc_g_crop(file, fh, p); if (!ret) @@ -1470,11 +1508,16 @@ static long __video_do_ioctl(struct file *file, case VIDIOC_CROPCAP: { struct v4l2_cropcap *p = arg; + __u32 type; /*FIXME: Should also show v4l2_fract pixelaspect */ if (!ops->vidioc_cropcap) break; + type = p->type; + memset(p, 0, sizeof(*p)); + p->type = type; + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); ret = ops->vidioc_cropcap(file, fh, p); if (!ret) { @@ -1490,6 +1533,8 @@ static long __video_do_ioctl(struct file *file, if (!ops->vidioc_g_jpegcomp) break; + memset(p, 0, sizeof(*p)); + ret = ops->vidioc_g_jpegcomp(file, fh, p); if (!ret) dbgarg(cmd, "quality=%d, APPn=%d, " @@ -1530,6 +1575,7 @@ static long __video_do_ioctl(struct file *file, if (!ops->vidioc_encoder_cmd) break; + memset(&p->raw, 0, sizeof(p->raw)); ret = ops->vidioc_encoder_cmd(file, fh, p); if (!ret) dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); @@ -1541,6 +1587,7 @@ static long __video_do_ioctl(struct file *file, if (!ops->vidioc_try_encoder_cmd) break; + memset(&p->raw, 0, sizeof(p->raw)); ret = ops->vidioc_try_encoder_cmd(file, fh, p); if (!ret) dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); @@ -1549,18 +1596,23 @@ static long __video_do_ioctl(struct file *file, case VIDIOC_G_PARM: { struct v4l2_streamparm *p = arg; + __u32 type = p->type; + + memset(p, 0, sizeof(*p)); + p->type = type; if (ops->vidioc_g_parm) { - ret = check_fmt(ops, p->type); - if (ret) - break; ret = ops->vidioc_g_parm(file, fh, p); } else { + struct v4l2_standard s; + if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - v4l2_video_std_frame_period(vfd->current_norm, - &p->parm.capture.timeperframe); + v4l2_video_std_construct(&s, vfd->current_norm, + v4l2_norm_to_name(vfd->current_norm)); + + p->parm.capture.timeperframe = s.frameperiod; ret = 0; } @@ -1573,10 +1625,6 @@ static long __video_do_ioctl(struct file *file, if (!ops->vidioc_s_parm) break; - ret = check_fmt(ops, p->type); - if (ret) - break; - dbgarg(cmd, "type=%d\n", p->type); ret = ops->vidioc_s_parm(file, fh, p); break; @@ -1584,10 +1632,14 @@ static long __video_do_ioctl(struct file *file, case VIDIOC_G_TUNER: { struct v4l2_tuner *p = arg; + __u32 index = p->index; if (!ops->vidioc_g_tuner) break; + memset(p, 0, sizeof(*p)); + p->index = index; + ret = ops->vidioc_g_tuner(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, type=%d, " @@ -1624,6 +1676,8 @@ static long __video_do_ioctl(struct file *file, if (!ops->vidioc_g_frequency) break; + memset(p->reserved, 0, sizeof(p->reserved)); + ret = ops->vidioc_g_frequency(file, fh, p); if (!ret) dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", @@ -1644,13 +1698,12 @@ static long __video_do_ioctl(struct file *file, case VIDIOC_G_SLICED_VBI_CAP: { struct v4l2_sliced_vbi_cap *p = arg; + __u32 type = p->type; if (!ops->vidioc_g_sliced_vbi_cap) break; - - /* Clear up to type, everything after type is zerod already */ - memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type)); - + memset(p, 0, sizeof(*p)); + p->type = type; dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p); if (!ret) @@ -1692,13 +1745,16 @@ static long __video_do_ioctl(struct file *file, if (!ops->vidioc_g_chip_ident) break; - p->ident = V4L2_IDENT_NONE; - p->revision = 0; ret = ops->vidioc_g_chip_ident(file, fh, p); if (!ret) dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); break; } + case VIDIOC_G_CHIP_IDENT_OLD: + printk(KERN_ERR "VIDIOC_G_CHIP_IDENT has been deprecated and will disappear in 2.6.30.\n"); + printk(KERN_ERR "It is a debugging ioctl and must not be used in applications!\n"); + return -EINVAL; + case VIDIOC_S_HW_FREQ_SEEK: { struct v4l2_hw_freq_seek *p = arg; @@ -1718,6 +1774,8 @@ static long __video_do_ioctl(struct file *file, if (!ops->vidioc_enum_framesizes) break; + memset(p, 0, sizeof(*p)); + ret = ops->vidioc_enum_framesizes(file, fh, p); dbgarg(cmd, "index=%d, pixelformat=%d, type=%d ", @@ -1749,6 +1807,8 @@ static long __video_do_ioctl(struct file *file, if (!ops->vidioc_enum_frameintervals) break; + memset(p, 0, sizeof(*p)); + ret = ops->vidioc_enum_frameintervals(file, fh, p); dbgarg(cmd, "index=%d, pixelformat=%d, width=%d, height=%d, type=%d ", @@ -1797,45 +1857,6 @@ static long __video_do_ioctl(struct file *file, return ret; } -/* In some cases, only a few fields are used as input, i.e. when the app sets - * "index" and then the driver fills in the rest of the structure for the thing - * with that index. We only need to copy up the first non-input field. */ -static unsigned long cmd_input_size(unsigned int cmd) -{ - /* Size of structure up to and including 'field' */ -#define CMDINSIZE(cmd, type, field) \ - case VIDIOC_##cmd: \ - return offsetof(struct v4l2_##type, field) + \ - sizeof(((struct v4l2_##type *)0)->field); - - switch (cmd) { - CMDINSIZE(ENUM_FMT, fmtdesc, type); - CMDINSIZE(G_FMT, format, type); - CMDINSIZE(QUERYBUF, buffer, type); - CMDINSIZE(G_PARM, streamparm, type); - CMDINSIZE(ENUMSTD, standard, index); - CMDINSIZE(ENUMINPUT, input, index); - CMDINSIZE(G_CTRL, control, id); - CMDINSIZE(G_TUNER, tuner, index); - CMDINSIZE(QUERYCTRL, queryctrl, id); - CMDINSIZE(QUERYMENU, querymenu, index); - CMDINSIZE(ENUMOUTPUT, output, index); - CMDINSIZE(G_MODULATOR, modulator, index); - CMDINSIZE(G_FREQUENCY, frequency, tuner); - CMDINSIZE(CROPCAP, cropcap, type); - CMDINSIZE(G_CROP, crop, type); - CMDINSIZE(ENUMAUDIO, audio, index); - CMDINSIZE(ENUMAUDOUT, audioout, index); - CMDINSIZE(ENCODER_CMD, encoder_cmd, flags); - CMDINSIZE(TRY_ENCODER_CMD, encoder_cmd, flags); - CMDINSIZE(G_SLICED_VBI_CAP, sliced_vbi_cap, type); - CMDINSIZE(ENUM_FRAMESIZES, frmsizeenum, pixel_format); - CMDINSIZE(ENUM_FRAMEINTERVALS, frmivalenum, height); - default: - return _IOC_SIZE(cmd); - } -} - long video_ioctl2(struct file *file, unsigned int cmd, unsigned long arg) { @@ -1854,7 +1875,13 @@ long video_ioctl2(struct file *file, cmd == VIDIOC_TRY_EXT_CTRLS); /* Copy arguments into temp kernel buffer */ - if (_IOC_DIR(cmd) != _IOC_NONE) { + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: + parg = NULL; + break; + case _IOC_READ: + case _IOC_WRITE: + case (_IOC_WRITE | _IOC_READ): if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { parg = sbuf; } else { @@ -1866,19 +1893,10 @@ long video_ioctl2(struct file *file, } err = -EFAULT; - if (_IOC_DIR(cmd) & _IOC_WRITE) { - unsigned long n = cmd_input_size(cmd); - - if (copy_from_user(parg, (void __user *)arg, n)) + if (_IOC_DIR(cmd) & _IOC_WRITE) + if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) goto out; - - /* zero out anything we don't copy from userspace */ - if (n < _IOC_SIZE(cmd)) - memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n); - } else { - /* read-only ioctl */ - memset(parg, 0, _IOC_SIZE(cmd)); - } + break; } if (is_ext_ctrl) { diff --git a/trunk/drivers/media/video/v4l2-subdev.c b/trunk/drivers/media/video/v4l2-subdev.c index dc881671d536..21208805ea9b 100644 --- a/trunk/drivers/media/video/v4l2-subdev.c +++ b/trunk/drivers/media/video/v4l2-subdev.c @@ -33,12 +33,6 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg) return v4l2_subdev_call(sd, core, g_ctrl, arg); case VIDIOC_S_CTRL: return v4l2_subdev_call(sd, core, s_ctrl, arg); - case VIDIOC_G_EXT_CTRLS: - return v4l2_subdev_call(sd, core, g_ext_ctrls, arg); - case VIDIOC_S_EXT_CTRLS: - return v4l2_subdev_call(sd, core, s_ext_ctrls, arg); - case VIDIOC_TRY_EXT_CTRLS: - return v4l2_subdev_call(sd, core, try_ext_ctrls, arg); case VIDIOC_QUERYMENU: return v4l2_subdev_call(sd, core, querymenu, arg); case VIDIOC_LOG_STATUS: @@ -98,28 +92,16 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg) return v4l2_subdev_call(sd, video, g_vbi_data, arg); case VIDIOC_G_SLICED_VBI_CAP: return v4l2_subdev_call(sd, video, g_sliced_vbi_cap, arg); - case VIDIOC_ENUM_FMT: - return v4l2_subdev_call(sd, video, enum_fmt, arg); - case VIDIOC_TRY_FMT: - return v4l2_subdev_call(sd, video, try_fmt, arg); case VIDIOC_S_FMT: return v4l2_subdev_call(sd, video, s_fmt, arg); case VIDIOC_G_FMT: return v4l2_subdev_call(sd, video, g_fmt, arg); case VIDIOC_INT_S_STD_OUTPUT: return v4l2_subdev_call(sd, video, s_std_output, *(v4l2_std_id *)arg); - case VIDIOC_QUERYSTD: - return v4l2_subdev_call(sd, video, querystd, arg); - case VIDIOC_INT_G_INPUT_STATUS: - return v4l2_subdev_call(sd, video, g_input_status, arg); case VIDIOC_STREAMON: return v4l2_subdev_call(sd, video, s_stream, 1); case VIDIOC_STREAMOFF: return v4l2_subdev_call(sd, video, s_stream, 0); - case VIDIOC_S_PARM: - return v4l2_subdev_call(sd, video, s_parm, arg); - case VIDIOC_G_PARM: - return v4l2_subdev_call(sd, video, g_parm, arg); default: return v4l2_subdev_call(sd, core, ioctl, cmd, arg); diff --git a/trunk/drivers/media/video/videobuf-dma-contig.c b/trunk/drivers/media/video/videobuf-dma-contig.c index 6109fb5f34e2..31944b11e6ea 100644 --- a/trunk/drivers/media/video/videobuf-dma-contig.c +++ b/trunk/drivers/media/video/videobuf-dma-contig.c @@ -400,7 +400,7 @@ void videobuf_dma_contig_free(struct videobuf_queue *q, So, it should free memory only if the memory were allocated for read() operation. */ - if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr) + if ((buf->memory != V4L2_MEMORY_USERPTR) || !buf->baddr) return; if (!mem) diff --git a/trunk/drivers/media/video/videobuf-vmalloc.c b/trunk/drivers/media/video/videobuf-vmalloc.c index 30ae30f99ccc..be65a2fb3976 100644 --- a/trunk/drivers/media/video/videobuf-vmalloc.c +++ b/trunk/drivers/media/video/videobuf-vmalloc.c @@ -425,7 +425,7 @@ void videobuf_vmalloc_free (struct videobuf_buffer *buf) So, it should free memory only if the memory were allocated for read() operation. */ - if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr) + if ((buf->memory != V4L2_MEMORY_USERPTR) || (buf->baddr == 0)) return; if (!mem) diff --git a/trunk/drivers/media/video/vino.c b/trunk/drivers/media/video/vino.c index 8da4dd1e0e94..88bf845a3d56 100644 --- a/trunk/drivers/media/video/vino.c +++ b/trunk/drivers/media/video/vino.c @@ -8,12 +8,6 @@ * * Based on the previous version of the driver for 2.4 kernels by: * Copyright (C) 2003 Ladislav Michl - * - * v4l2_device/v4l2_subdev conversion by: - * Copyright (C) 2009 Hans Verkuil - * - * Note: this conversion is untested! Please contact the linux-media - * mailinglist if you can test this, together with the test results. */ /* @@ -39,10 +33,12 @@ #include #include +#include #include -#include +#include #include +#include #include #include @@ -143,23 +139,13 @@ MODULE_LICENSE("GPL"); #define VINO_DATA_NORM_PAL 1 #define VINO_DATA_NORM_SECAM 2 #define VINO_DATA_NORM_D1 3 +/* The following are special entries that can be used to + * autodetect the norm. */ +#define VINO_DATA_NORM_AUTO 0xfe +#define VINO_DATA_NORM_AUTO_EXT 0xff #define VINO_DATA_NORM_COUNT 4 -/* I2C controller flags */ -#define SGI_I2C_FORCE_IDLE (0 << 0) -#define SGI_I2C_NOT_IDLE (1 << 0) -#define SGI_I2C_WRITE (0 << 1) -#define SGI_I2C_READ (1 << 1) -#define SGI_I2C_RELEASE_BUS (0 << 2) -#define SGI_I2C_HOLD_BUS (1 << 2) -#define SGI_I2C_XFER_DONE (0 << 4) -#define SGI_I2C_XFER_BUSY (1 << 4) -#define SGI_I2C_ACK (0 << 5) -#define SGI_I2C_NACK (1 << 5) -#define SGI_I2C_BUS_OK (0 << 7) -#define SGI_I2C_BUS_ERR (1 << 7) - /* Internal data structure definitions */ struct vino_input { @@ -303,20 +289,22 @@ struct vino_channel_settings { struct vino_interrupt_data int_data; /* V4L support */ - struct video_device *vdev; + struct video_device *v4l_device; +}; + +struct vino_client { + /* the channel which owns this client: + * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */ + unsigned int owner; + struct i2c_client *driver; }; struct vino_settings { - struct v4l2_device v4l2_dev; struct vino_channel_settings a; struct vino_channel_settings b; - /* the channel which owns this client: - * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */ - unsigned int decoder_owner; - struct v4l2_subdev *decoder; - unsigned int camera_owner; - struct v4l2_subdev *camera; + struct vino_client decoder; + struct vino_client camera; /* a lock for vino register access */ spinlock_t vino_lock; @@ -356,16 +344,11 @@ static struct sgi_vino *vino; static struct vino_settings *vino_drvdata; -#define camera_call(o, f, args...) \ - v4l2_subdev_call(vino_drvdata->camera, o, f, ##args) -#define decoder_call(o, f, args...) \ - v4l2_subdev_call(vino_drvdata->decoder, o, f, ##args) - static const char *vino_driver_name = "vino"; static const char *vino_driver_description = "SGI VINO"; static const char *vino_bus_name = "GIO64 bus"; -static const char *vino_vdev_name_a = "SGI VINO Channel A"; -static const char *vino_vdev_name_b = "SGI VINO Channel B"; +static const char *vino_v4l_device_name_a = "SGI VINO Channel A"; +static const char *vino_v4l_device_name_b = "SGI VINO Channel B"; static void vino_capture_tasklet(unsigned long channel); @@ -377,11 +360,11 @@ static const struct vino_input vino_inputs[] = { .name = "Composite", .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, - }, { + },{ .name = "S-Video", .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, - }, { + },{ .name = "D1/IndyCam", .std = V4L2_STD_NTSC, } @@ -393,17 +376,17 @@ static const struct vino_data_format vino_data_formats[] = { .bpp = 1, .pixelformat = V4L2_PIX_FMT_GREY, .colorspace = V4L2_COLORSPACE_SMPTE170M, - }, { + },{ .description = "8-bit dithered RGB 3-3-2", .bpp = 1, .pixelformat = V4L2_PIX_FMT_RGB332, .colorspace = V4L2_COLORSPACE_SRGB, - }, { + },{ .description = "32-bit RGB", .bpp = 4, .pixelformat = V4L2_PIX_FMT_RGB32, .colorspace = V4L2_COLORSPACE_SRGB, - }, { + },{ .description = "YUV 4:2:2", .bpp = 2, .pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped? @@ -434,7 +417,7 @@ static const struct vino_data_norm vino_data_norms[] = { + VINO_NTSC_HEIGHT / 2 - 1, .right = VINO_NTSC_WIDTH, }, - }, { + },{ .description = "PAL", .std = V4L2_STD_PAL, .fps_min = 5, @@ -456,7 +439,7 @@ static const struct vino_data_norm vino_data_norms[] = { + VINO_PAL_HEIGHT / 2 - 1, .right = VINO_PAL_WIDTH, }, - }, { + },{ .description = "SECAM", .std = V4L2_STD_SECAM, .fps_min = 5, @@ -478,7 +461,7 @@ static const struct vino_data_norm vino_data_norms[] = { + VINO_PAL_HEIGHT / 2 - 1, .right = VINO_PAL_WIDTH, }, - }, { + },{ .description = "NTSC/D1", .std = V4L2_STD_NTSC, .fps_min = 6, @@ -514,7 +497,9 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { .maximum = 1, .step = 1, .default_value = INDYCAM_AGC_DEFAULT, - }, { + .flags = 0, + .reserved = { INDYCAM_CONTROL_AGC, 0 }, + },{ .id = V4L2_CID_AUTO_WHITE_BALANCE, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Automatic White Balance", @@ -522,7 +507,9 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { .maximum = 1, .step = 1, .default_value = INDYCAM_AWB_DEFAULT, - }, { + .flags = 0, + .reserved = { INDYCAM_CONTROL_AWB, 0 }, + },{ .id = V4L2_CID_GAIN, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Gain", @@ -530,23 +517,29 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { .maximum = INDYCAM_GAIN_MAX, .step = 1, .default_value = INDYCAM_GAIN_DEFAULT, - }, { - .id = INDYCAM_CONTROL_RED_SATURATION, + .flags = 0, + .reserved = { INDYCAM_CONTROL_GAIN, 0 }, + },{ + .id = V4L2_CID_PRIVATE_BASE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Red Saturation", .minimum = INDYCAM_RED_SATURATION_MIN, .maximum = INDYCAM_RED_SATURATION_MAX, .step = 1, .default_value = INDYCAM_RED_SATURATION_DEFAULT, - }, { - .id = INDYCAM_CONTROL_BLUE_SATURATION, + .flags = 0, + .reserved = { INDYCAM_CONTROL_RED_SATURATION, 0 }, + },{ + .id = V4L2_CID_PRIVATE_BASE + 1, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Blue Saturation", .minimum = INDYCAM_BLUE_SATURATION_MIN, .maximum = INDYCAM_BLUE_SATURATION_MAX, .step = 1, .default_value = INDYCAM_BLUE_SATURATION_DEFAULT, - }, { + .flags = 0, + .reserved = { INDYCAM_CONTROL_BLUE_SATURATION, 0 }, + },{ .id = V4L2_CID_RED_BALANCE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Red Balance", @@ -554,7 +547,9 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { .maximum = INDYCAM_RED_BALANCE_MAX, .step = 1, .default_value = INDYCAM_RED_BALANCE_DEFAULT, - }, { + .flags = 0, + .reserved = { INDYCAM_CONTROL_RED_BALANCE, 0 }, + },{ .id = V4L2_CID_BLUE_BALANCE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Blue Balance", @@ -562,7 +557,9 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { .maximum = INDYCAM_BLUE_BALANCE_MAX, .step = 1, .default_value = INDYCAM_BLUE_BALANCE_DEFAULT, - }, { + .flags = 0, + .reserved = { INDYCAM_CONTROL_BLUE_BALANCE, 0 }, + },{ .id = V4L2_CID_EXPOSURE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Shutter Control", @@ -570,7 +567,9 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { .maximum = INDYCAM_SHUTTER_MAX, .step = 1, .default_value = INDYCAM_SHUTTER_DEFAULT, - }, { + .flags = 0, + .reserved = { INDYCAM_CONTROL_SHUTTER, 0 }, + },{ .id = V4L2_CID_GAMMA, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Gamma", @@ -578,6 +577,8 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { .maximum = INDYCAM_GAMMA_MAX, .step = 1, .default_value = INDYCAM_GAMMA_DEFAULT, + .flags = 0, + .reserved = { INDYCAM_CONTROL_GAMMA, 0 }, } }; @@ -592,73 +593,209 @@ struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = { .maximum = SAA7191_HUE_MAX, .step = 1, .default_value = SAA7191_HUE_DEFAULT, - }, { - .id = SAA7191_CONTROL_BANDPASS, + .flags = 0, + .reserved = { SAA7191_CONTROL_HUE, 0 }, + },{ + .id = V4L2_CID_PRIVATE_BASE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Luminance Bandpass", .minimum = SAA7191_BANDPASS_MIN, .maximum = SAA7191_BANDPASS_MAX, .step = 1, .default_value = SAA7191_BANDPASS_DEFAULT, - }, { - .id = SAA7191_CONTROL_BANDPASS_WEIGHT, + .flags = 0, + .reserved = { SAA7191_CONTROL_BANDPASS, 0 }, + },{ + .id = V4L2_CID_PRIVATE_BASE + 1, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Luminance Bandpass Weight", .minimum = SAA7191_BANDPASS_WEIGHT_MIN, .maximum = SAA7191_BANDPASS_WEIGHT_MAX, .step = 1, .default_value = SAA7191_BANDPASS_WEIGHT_DEFAULT, - }, { - .id = SAA7191_CONTROL_CORING, + .flags = 0, + .reserved = { SAA7191_CONTROL_BANDPASS_WEIGHT, 0 }, + },{ + .id = V4L2_CID_PRIVATE_BASE + 2, .type = V4L2_CTRL_TYPE_INTEGER, .name = "HF Luminance Coring", .minimum = SAA7191_CORING_MIN, .maximum = SAA7191_CORING_MAX, .step = 1, .default_value = SAA7191_CORING_DEFAULT, - }, { - .id = SAA7191_CONTROL_FORCE_COLOUR, + .flags = 0, + .reserved = { SAA7191_CONTROL_CORING, 0 }, + },{ + .id = V4L2_CID_PRIVATE_BASE + 3, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Force Colour", .minimum = SAA7191_FORCE_COLOUR_MIN, .maximum = SAA7191_FORCE_COLOUR_MAX, .step = 1, .default_value = SAA7191_FORCE_COLOUR_DEFAULT, - }, { - .id = SAA7191_CONTROL_CHROMA_GAIN, + .flags = 0, + .reserved = { SAA7191_CONTROL_FORCE_COLOUR, 0 }, + },{ + .id = V4L2_CID_PRIVATE_BASE + 4, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Chrominance Gain Control", .minimum = SAA7191_CHROMA_GAIN_MIN, .maximum = SAA7191_CHROMA_GAIN_MAX, .step = 1, .default_value = SAA7191_CHROMA_GAIN_DEFAULT, - }, { - .id = SAA7191_CONTROL_VTRC, + .flags = 0, + .reserved = { SAA7191_CONTROL_CHROMA_GAIN, 0 }, + },{ + .id = V4L2_CID_PRIVATE_BASE + 5, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "VTR Time Constant", .minimum = SAA7191_VTRC_MIN, .maximum = SAA7191_VTRC_MAX, .step = 1, .default_value = SAA7191_VTRC_DEFAULT, - }, { - .id = SAA7191_CONTROL_LUMA_DELAY, + .flags = 0, + .reserved = { SAA7191_CONTROL_VTRC, 0 }, + },{ + .id = V4L2_CID_PRIVATE_BASE + 6, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Luminance Delay Compensation", .minimum = SAA7191_LUMA_DELAY_MIN, .maximum = SAA7191_LUMA_DELAY_MAX, .step = 1, .default_value = SAA7191_LUMA_DELAY_DEFAULT, - }, { - .id = SAA7191_CONTROL_VNR, + .flags = 0, + .reserved = { SAA7191_CONTROL_LUMA_DELAY, 0 }, + },{ + .id = V4L2_CID_PRIVATE_BASE + 7, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Vertical Noise Reduction", .minimum = SAA7191_VNR_MIN, .maximum = SAA7191_VNR_MAX, .step = 1, .default_value = SAA7191_VNR_DEFAULT, + .flags = 0, + .reserved = { SAA7191_CONTROL_VNR, 0 }, + } +}; + +/* VINO I2C bus functions */ + +unsigned i2c_vino_getctrl(void *data) +{ + return vino->i2c_control; +} + +void i2c_vino_setctrl(void *data, unsigned val) +{ + vino->i2c_control = val; +} + +unsigned i2c_vino_rdata(void *data) +{ + return vino->i2c_data; +} + +void i2c_vino_wdata(void *data, unsigned val) +{ + vino->i2c_data = val; +} + +static struct i2c_algo_sgi_data i2c_sgi_vino_data = +{ + .getctrl = &i2c_vino_getctrl, + .setctrl = &i2c_vino_setctrl, + .rdata = &i2c_vino_rdata, + .wdata = &i2c_vino_wdata, + .xfer_timeout = 200, + .ack_timeout = 1000, +}; + +/* + * There are two possible clients on VINO I2C bus, so we limit usage only + * to them. + */ +static int i2c_vino_client_reg(struct i2c_client *client) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&vino_drvdata->input_lock, flags); + switch (client->driver->id) { + case I2C_DRIVERID_SAA7191: + if (vino_drvdata->decoder.driver) + ret = -EBUSY; + else + vino_drvdata->decoder.driver = client; + break; + case I2C_DRIVERID_INDYCAM: + if (vino_drvdata->camera.driver) + ret = -EBUSY; + else + vino_drvdata->camera.driver = client; + break; + default: + ret = -ENODEV; + } + spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); + + return ret; +} + +static int i2c_vino_client_unreg(struct i2c_client *client) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&vino_drvdata->input_lock, flags); + if (client == vino_drvdata->decoder.driver) { + if (vino_drvdata->decoder.owner != VINO_NO_CHANNEL) + ret = -EBUSY; + else + vino_drvdata->decoder.driver = NULL; + } else if (client == vino_drvdata->camera.driver) { + if (vino_drvdata->camera.owner != VINO_NO_CHANNEL) + ret = -EBUSY; + else + vino_drvdata->camera.driver = NULL; } + spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); + + return ret; +} + +static struct i2c_adapter vino_i2c_adapter = +{ + .name = "VINO I2C bus", + .id = I2C_HW_SGI_VINO, + .algo_data = &i2c_sgi_vino_data, + .client_register = &i2c_vino_client_reg, + .client_unregister = &i2c_vino_client_unreg, }; +static int vino_i2c_add_bus(void) +{ + return i2c_sgi_add_bus(&vino_i2c_adapter); +} + +static int vino_i2c_del_bus(void) +{ + return i2c_del_adapter(&vino_i2c_adapter); +} + +static int i2c_camera_command(unsigned int cmd, void *arg) +{ + return vino_drvdata->camera.driver-> + driver->command(vino_drvdata->camera.driver, + cmd, arg); +} + +static int i2c_decoder_command(unsigned int cmd, void *arg) +{ + return vino_drvdata->decoder.driver-> + driver->command(vino_drvdata->decoder.driver, + cmd, arg); +} + /* VINO framebuffer/DMA descriptor management */ static void vino_free_buffer_with_count(struct vino_framebuffer *fb, @@ -1604,184 +1741,6 @@ static inline void vino_set_default_framerate(struct vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max); } -/* VINO I2C bus functions */ - -struct i2c_algo_sgi_data { - void *data; /* private data for lowlevel routines */ - unsigned (*getctrl)(void *data); - void (*setctrl)(void *data, unsigned val); - unsigned (*rdata)(void *data); - void (*wdata)(void *data, unsigned val); - - int xfer_timeout; - int ack_timeout; -}; - -static int wait_xfer_done(struct i2c_algo_sgi_data *adap) -{ - int i; - - for (i = 0; i < adap->xfer_timeout; i++) { - if ((adap->getctrl(adap->data) & SGI_I2C_XFER_BUSY) == 0) - return 0; - udelay(1); - } - - return -ETIMEDOUT; -} - -static int wait_ack(struct i2c_algo_sgi_data *adap) -{ - int i; - - if (wait_xfer_done(adap)) - return -ETIMEDOUT; - for (i = 0; i < adap->ack_timeout; i++) { - if ((adap->getctrl(adap->data) & SGI_I2C_NACK) == 0) - return 0; - udelay(1); - } - - return -ETIMEDOUT; -} - -static int force_idle(struct i2c_algo_sgi_data *adap) -{ - int i; - - adap->setctrl(adap->data, SGI_I2C_FORCE_IDLE); - for (i = 0; i < adap->xfer_timeout; i++) { - if ((adap->getctrl(adap->data) & SGI_I2C_NOT_IDLE) == 0) - goto out; - udelay(1); - } - return -ETIMEDOUT; -out: - if (adap->getctrl(adap->data) & SGI_I2C_BUS_ERR) - return -EIO; - return 0; -} - -static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr, - int rd) -{ - if (rd) - adap->setctrl(adap->data, SGI_I2C_NOT_IDLE); - /* Check if bus is idle, eventually force it to do so */ - if (adap->getctrl(adap->data) & SGI_I2C_NOT_IDLE) - if (force_idle(adap)) - return -EIO; - /* Write out the i2c chip address and specify operation */ - adap->setctrl(adap->data, - SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE); - if (rd) - addr |= 1; - adap->wdata(adap->data, addr); - if (wait_ack(adap)) - return -EIO; - return 0; -} - -static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf, - unsigned int len) -{ - int i; - - adap->setctrl(adap->data, - SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE); - for (i = 0; i < len; i++) { - if (wait_xfer_done(adap)) - return -EIO; - buf[i] = adap->rdata(adap->data); - } - adap->setctrl(adap->data, SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE); - - return 0; - -} - -static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf, - unsigned int len) -{ - int i; - - /* We are already in write state */ - for (i = 0; i < len; i++) { - adap->wdata(adap->data, buf[i]); - if (wait_ack(adap)) - return -EIO; - } - return 0; -} - -static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, - int num) -{ - struct i2c_algo_sgi_data *adap = i2c_adap->algo_data; - struct i2c_msg *p; - int i, err = 0; - - for (i = 0; !err && i < num; i++) { - p = &msgs[i]; - err = do_address(adap, p->addr, p->flags & I2C_M_RD); - if (err || !p->len) - continue; - if (p->flags & I2C_M_RD) - err = i2c_read(adap, p->buf, p->len); - else - err = i2c_write(adap, p->buf, p->len); - } - - return (err < 0) ? err : i; -} - -static u32 sgi_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_SMBUS_EMUL; -} - -static const struct i2c_algorithm sgi_algo = { - .master_xfer = sgi_xfer, - .functionality = sgi_func, -}; - -static unsigned i2c_vino_getctrl(void *data) -{ - return vino->i2c_control; -} - -static void i2c_vino_setctrl(void *data, unsigned val) -{ - vino->i2c_control = val; -} - -static unsigned i2c_vino_rdata(void *data) -{ - return vino->i2c_data; -} - -static void i2c_vino_wdata(void *data, unsigned val) -{ - vino->i2c_data = val; -} - -static struct i2c_algo_sgi_data i2c_sgi_vino_data = { - .getctrl = &i2c_vino_getctrl, - .setctrl = &i2c_vino_setctrl, - .rdata = &i2c_vino_rdata, - .wdata = &i2c_vino_wdata, - .xfer_timeout = 200, - .ack_timeout = 1000, -}; - -static struct i2c_adapter vino_i2c_adapter = { - .name = "VINO I2C bus", - .id = I2C_HW_SGI_VINO, - .algo = &sgi_algo, - .algo_data = &i2c_sgi_vino_data, - .owner = THIS_MODULE, -}; - /* * Prepare VINO for DMA transfer... * (execute only with vino_lock and input_lock locked) @@ -2531,15 +2490,86 @@ static int vino_get_saa7191_input(int input) } } +static int vino_get_saa7191_norm(unsigned int data_norm) +{ + switch (data_norm) { + case VINO_DATA_NORM_AUTO: + return SAA7191_NORM_AUTO; + case VINO_DATA_NORM_AUTO_EXT: + return SAA7191_NORM_AUTO_EXT; + case VINO_DATA_NORM_PAL: + return SAA7191_NORM_PAL; + case VINO_DATA_NORM_NTSC: + return SAA7191_NORM_NTSC; + case VINO_DATA_NORM_SECAM: + return SAA7191_NORM_SECAM; + default: + printk(KERN_ERR "VINO: vino_get_saa7191_norm(): " + "invalid norm!\n"); + return -1; + } +} + +static int vino_get_from_saa7191_norm(int saa7191_norm) +{ + switch (saa7191_norm) { + case SAA7191_NORM_PAL: + return VINO_DATA_NORM_PAL; + case SAA7191_NORM_NTSC: + return VINO_DATA_NORM_NTSC; + case SAA7191_NORM_SECAM: + return VINO_DATA_NORM_SECAM; + default: + printk(KERN_ERR "VINO: vino_get_from_saa7191_norm(): " + "invalid norm!\n"); + return VINO_DATA_NORM_NONE; + } +} + +static int vino_saa7191_set_norm(unsigned int *data_norm) +{ + int saa7191_norm, new_data_norm; + int err = 0; + + saa7191_norm = vino_get_saa7191_norm(*data_norm); + + err = i2c_decoder_command(DECODER_SAA7191_SET_NORM, + &saa7191_norm); + if (err) + goto out; + + if ((*data_norm == VINO_DATA_NORM_AUTO) + || (*data_norm == VINO_DATA_NORM_AUTO_EXT)) { + struct saa7191_status status; + + err = i2c_decoder_command(DECODER_SAA7191_GET_STATUS, + &status); + if (err) + goto out; + + new_data_norm = + vino_get_from_saa7191_norm(status.norm); + if (new_data_norm == VINO_DATA_NORM_NONE) { + err = -EINVAL; + goto out; + } + + *data_norm = (unsigned int)new_data_norm; + } + +out: + return err; +} + /* execute with input_lock locked */ static int vino_is_input_owner(struct vino_channel_settings *vcs) { switch(vcs->input) { case VINO_INPUT_COMPOSITE: case VINO_INPUT_SVIDEO: - return vino_drvdata->decoder_owner == vcs->channel; + return (vino_drvdata->decoder.owner == vcs->channel); case VINO_INPUT_D1: - return vino_drvdata->camera_owner == vcs->channel; + return (vino_drvdata->camera.owner == vcs->channel); default: return 0; } @@ -2555,22 +2585,23 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) spin_lock_irqsave(&vino_drvdata->input_lock, flags); /* First try D1 and then SAA7191 */ - if (vino_drvdata->camera - && (vino_drvdata->camera_owner == VINO_NO_CHANNEL)) { - vino_drvdata->camera_owner = vcs->channel; + if (vino_drvdata->camera.driver + && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) { + i2c_use_client(vino_drvdata->camera.driver); + vino_drvdata->camera.owner = vcs->channel; vcs->input = VINO_INPUT_D1; vcs->data_norm = VINO_DATA_NORM_D1; - } else if (vino_drvdata->decoder - && (vino_drvdata->decoder_owner == VINO_NO_CHANNEL)) { - int input; - int data_norm; - v4l2_std_id norm; - struct v4l2_routing route = { 0, 0 }; + } else if (vino_drvdata->decoder.driver + && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) { + int input, data_norm; + int saa7191_input; + i2c_use_client(vino_drvdata->decoder.driver); input = VINO_INPUT_COMPOSITE; - route.input = vino_get_saa7191_input(input); - ret = decoder_call(video, s_routing, &route); + saa7191_input = vino_get_saa7191_input(input); + ret = i2c_decoder_command(DECODER_SET_INPUT, + &saa7191_input); if (ret) { ret = -EINVAL; goto out; @@ -2581,15 +2612,12 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) /* Don't hold spinlocks while auto-detecting norm * as it may take a while... */ - ret = decoder_call(video, querystd, &norm); - if (!ret) { - for (data_norm = 0; data_norm < 3; data_norm++) { - if (vino_data_norms[data_norm].std & norm) - break; - } - if (data_norm == 3) - data_norm = VINO_DATA_NORM_PAL; - ret = decoder_call(tuner, s_std, norm); + data_norm = VINO_DATA_NORM_AUTO_EXT; + + ret = vino_saa7191_set_norm(&data_norm); + if ((ret == -EBUSY) || (ret == -EAGAIN)) { + data_norm = VINO_DATA_NORM_PAL; + ret = vino_saa7191_set_norm(&data_norm); } spin_lock_irqsave(&vino_drvdata->input_lock, flags); @@ -2599,7 +2627,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) goto out; } - vino_drvdata->decoder_owner = vcs->channel; + vino_drvdata->decoder.owner = vcs->channel; vcs->input = input; vcs->data_norm = data_norm; @@ -2644,24 +2672,25 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) switch (input) { case VINO_INPUT_COMPOSITE: case VINO_INPUT_SVIDEO: - if (!vino_drvdata->decoder) { + if (!vino_drvdata->decoder.driver) { ret = -EINVAL; goto out; } - if (vino_drvdata->decoder_owner == VINO_NO_CHANNEL) { - vino_drvdata->decoder_owner = vcs->channel; + if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) { + i2c_use_client(vino_drvdata->decoder.driver); + vino_drvdata->decoder.owner = vcs->channel; } - if (vino_drvdata->decoder_owner == vcs->channel) { + if (vino_drvdata->decoder.owner == vcs->channel) { int data_norm; - v4l2_std_id norm; - struct v4l2_routing route = { 0, 0 }; + int saa7191_input; - route.input = vino_get_saa7191_input(input); - ret = decoder_call(video, s_routing, &route); + saa7191_input = vino_get_saa7191_input(input); + ret = i2c_decoder_command(DECODER_SET_INPUT, + &saa7191_input); if (ret) { - vino_drvdata->decoder_owner = VINO_NO_CHANNEL; + vino_drvdata->decoder.owner = VINO_NO_CHANNEL; ret = -EINVAL; goto out; } @@ -2671,21 +2700,18 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) /* Don't hold spinlocks while auto-detecting norm * as it may take a while... */ - ret = decoder_call(video, querystd, &norm); - if (!ret) { - for (data_norm = 0; data_norm < 3; data_norm++) { - if (vino_data_norms[data_norm].std & norm) - break; - } - if (data_norm == 3) - data_norm = VINO_DATA_NORM_PAL; - ret = decoder_call(tuner, s_std, norm); + data_norm = VINO_DATA_NORM_AUTO_EXT; + + ret = vino_saa7191_set_norm(&data_norm); + if ((ret == -EBUSY) || (ret == -EAGAIN)) { + data_norm = VINO_DATA_NORM_PAL; + ret = vino_saa7191_set_norm(&data_norm); } spin_lock_irqsave(&vino_drvdata->input_lock, flags); if (ret) { - vino_drvdata->decoder_owner = VINO_NO_CHANNEL; + vino_drvdata->decoder.owner = VINO_NO_CHANNEL; ret = -EINVAL; goto out; } @@ -2702,31 +2728,37 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) vcs->data_norm = vcs2->data_norm; } - if (vino_drvdata->camera_owner == vcs->channel) { + if (vino_drvdata->camera.owner == vcs->channel) { /* Transfer the ownership or release the input */ if (vcs2->input == VINO_INPUT_D1) { - vino_drvdata->camera_owner = vcs2->channel; + vino_drvdata->camera.owner = vcs2->channel; } else { - vino_drvdata->camera_owner = VINO_NO_CHANNEL; + i2c_release_client(vino_drvdata-> + camera.driver); + vino_drvdata->camera.owner = VINO_NO_CHANNEL; } } break; case VINO_INPUT_D1: - if (!vino_drvdata->camera) { + if (!vino_drvdata->camera.driver) { ret = -EINVAL; goto out; } - if (vino_drvdata->camera_owner == VINO_NO_CHANNEL) - vino_drvdata->camera_owner = vcs->channel; + if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) { + i2c_use_client(vino_drvdata->camera.driver); + vino_drvdata->camera.owner = vcs->channel; + } - if (vino_drvdata->decoder_owner == vcs->channel) { + if (vino_drvdata->decoder.owner == vcs->channel) { /* Transfer the ownership or release the input */ if ((vcs2->input == VINO_INPUT_COMPOSITE) || (vcs2->input == VINO_INPUT_SVIDEO)) { - vino_drvdata->decoder_owner = vcs2->channel; + vino_drvdata->decoder.owner = vcs2->channel; } else { - vino_drvdata->decoder_owner = VINO_NO_CHANNEL; + i2c_release_client(vino_drvdata-> + decoder.driver); + vino_drvdata->decoder.owner = VINO_NO_CHANNEL; } } @@ -2763,18 +2795,20 @@ static void vino_release_input(struct vino_channel_settings *vcs) /* Release ownership of the channel * and if the other channel takes input from * the same source, transfer the ownership */ - if (vino_drvdata->camera_owner == vcs->channel) { + if (vino_drvdata->camera.owner == vcs->channel) { if (vcs2->input == VINO_INPUT_D1) { - vino_drvdata->camera_owner = vcs2->channel; + vino_drvdata->camera.owner = vcs2->channel; } else { - vino_drvdata->camera_owner = VINO_NO_CHANNEL; + i2c_release_client(vino_drvdata->camera.driver); + vino_drvdata->camera.owner = VINO_NO_CHANNEL; } - } else if (vino_drvdata->decoder_owner == vcs->channel) { + } else if (vino_drvdata->decoder.owner == vcs->channel) { if ((vcs2->input == VINO_INPUT_COMPOSITE) || (vcs2->input == VINO_INPUT_SVIDEO)) { - vino_drvdata->decoder_owner = vcs2->channel; + vino_drvdata->decoder.owner = vcs2->channel; } else { - vino_drvdata->decoder_owner = VINO_NO_CHANNEL; + i2c_release_client(vino_drvdata->decoder.driver); + vino_drvdata->decoder.owner = VINO_NO_CHANNEL; } } vcs->input = VINO_INPUT_NONE; @@ -2795,16 +2829,18 @@ static int vino_set_data_norm(struct vino_channel_settings *vcs, switch (vcs->input) { case VINO_INPUT_D1: /* only one "norm" supported */ - if (data_norm != VINO_DATA_NORM_D1) + if ((data_norm != VINO_DATA_NORM_D1) + && (data_norm != VINO_DATA_NORM_AUTO) + && (data_norm != VINO_DATA_NORM_AUTO_EXT)) return -EINVAL; break; case VINO_INPUT_COMPOSITE: case VINO_INPUT_SVIDEO: { - v4l2_std_id norm; - if ((data_norm != VINO_DATA_NORM_PAL) && (data_norm != VINO_DATA_NORM_NTSC) - && (data_norm != VINO_DATA_NORM_SECAM)) + && (data_norm != VINO_DATA_NORM_SECAM) + && (data_norm != VINO_DATA_NORM_AUTO) + && (data_norm != VINO_DATA_NORM_AUTO_EXT)) return -EINVAL; spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags); @@ -2812,8 +2848,7 @@ static int vino_set_data_norm(struct vino_channel_settings *vcs, /* Don't hold spinlocks while setting norm * as it may take a while... */ - norm = vino_data_norms[data_norm].std; - err = decoder_call(tuner, s_std, norm); + err = vino_saa7191_set_norm(&data_norm); spin_lock_irqsave(&vino_drvdata->input_lock, *flags); @@ -2849,13 +2884,41 @@ static int vino_find_data_format(__u32 pixelformat) return VINO_DATA_FMT_NONE; } -static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index) +static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index) +{ + int data_norm = VINO_DATA_NORM_NONE; + unsigned long flags; + + spin_lock_irqsave(&vino_drvdata->input_lock, flags); + switch(vcs->input) { + case VINO_INPUT_COMPOSITE: + case VINO_INPUT_SVIDEO: + if (index == 0) { + data_norm = VINO_DATA_NORM_PAL; + } else if (index == 1) { + data_norm = VINO_DATA_NORM_NTSC; + } else if (index == 2) { + data_norm = VINO_DATA_NORM_SECAM; + } + break; + case VINO_INPUT_D1: + if (index == 0) { + data_norm = VINO_DATA_NORM_D1; + } + break; + } + spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); + + return data_norm; +} + +static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index) { int input = VINO_INPUT_NONE; unsigned long flags; spin_lock_irqsave(&vino_drvdata->input_lock, flags); - if (vino_drvdata->decoder && vino_drvdata->camera) { + if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) { switch (index) { case 0: input = VINO_INPUT_COMPOSITE; @@ -2867,7 +2930,7 @@ static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index) input = VINO_INPUT_D1; break; } - } else if (vino_drvdata->decoder) { + } else if (vino_drvdata->decoder.driver) { switch (index) { case 0: input = VINO_INPUT_COMPOSITE; @@ -2876,7 +2939,7 @@ static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index) input = VINO_INPUT_SVIDEO; break; } - } else if (vino_drvdata->camera) { + } else if (vino_drvdata->camera.driver) { switch (index) { case 0: input = VINO_INPUT_D1; @@ -2894,7 +2957,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs) __u32 index = 0; // FIXME: detect when no inputs available - if (vino_drvdata->decoder && vino_drvdata->camera) { + if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) { switch (vcs->input) { case VINO_INPUT_COMPOSITE: index = 0; @@ -2906,7 +2969,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs) index = 2; break; } - } else if (vino_drvdata->decoder) { + } else if (vino_drvdata->decoder.driver) { switch (vcs->input) { case VINO_INPUT_COMPOSITE: index = 0; @@ -2915,7 +2978,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs) index = 1; break; } - } else if (vino_drvdata->camera) { + } else if (vino_drvdata->camera.driver) { switch (vcs->input) { case VINO_INPUT_D1: index = 0; @@ -2928,8 +2991,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs) /* V4L2 ioctls */ -static int vino_querycap(struct file *file, void *__fh, - struct v4l2_capability *cap) +static void vino_v4l2_querycap(struct v4l2_capability *cap) { memset(cap, 0, sizeof(struct v4l2_capability)); @@ -2941,18 +3003,16 @@ static int vino_querycap(struct file *file, void *__fh, V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; // V4L2_CAP_OVERLAY, V4L2_CAP_READWRITE - return 0; } -static int vino_enum_input(struct file *file, void *__fh, +static int vino_v4l2_enuminput(struct vino_channel_settings *vcs, struct v4l2_input *i) { - struct vino_channel_settings *vcs = video_drvdata(file); __u32 index = i->index; int input; dprintk("requested index = %d\n", index); - input = vino_int_enum_input(vcs, index); + input = vino_enum_input(vcs, index); if (input == VINO_INPUT_NONE) return -EINVAL; @@ -2963,15 +3023,20 @@ static int vino_enum_input(struct file *file, void *__fh, i->std = vino_inputs[input].std; strcpy(i->name, vino_inputs[input].name); - if (input == VINO_INPUT_COMPOSITE || input == VINO_INPUT_SVIDEO) - decoder_call(video, g_input_status, &i->status); + if ((input == VINO_INPUT_COMPOSITE) + || (input == VINO_INPUT_SVIDEO)) { + struct saa7191_status status; + i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status); + i->status |= status.signal ? 0 : V4L2_IN_ST_NO_SIGNAL; + i->status |= status.color ? 0 : V4L2_IN_ST_NO_COLOR; + } + return 0; } -static int vino_g_input(struct file *file, void *__fh, +static int vino_v4l2_g_input(struct vino_channel_settings *vcs, unsigned int *i) { - struct vino_channel_settings *vcs = video_drvdata(file); __u32 index; int input; unsigned long flags; @@ -2992,36 +3057,76 @@ static int vino_g_input(struct file *file, void *__fh, return 0; } -static int vino_s_input(struct file *file, void *__fh, - unsigned int i) +static int vino_v4l2_s_input(struct vino_channel_settings *vcs, + unsigned int *i) { - struct vino_channel_settings *vcs = video_drvdata(file); int input; - dprintk("requested input = %d\n", i); + dprintk("requested input = %d\n", *i); - input = vino_int_enum_input(vcs, i); + input = vino_enum_input(vcs, *i); if (input == VINO_INPUT_NONE) return -EINVAL; return vino_set_input(vcs, input); } -static int vino_querystd(struct file *file, void *__fh, - v4l2_std_id *std) +static int vino_v4l2_enumstd(struct vino_channel_settings *vcs, + struct v4l2_standard *s) { - struct vino_channel_settings *vcs = video_drvdata(file); - unsigned long flags; - int err = 0; + int index = s->index; + int data_norm; - spin_lock_irqsave(&vino_drvdata->input_lock, flags); + data_norm = vino_enum_data_norm(vcs, index); + dprintk("standard index = %d\n", index); - switch (vcs->input) { - case VINO_INPUT_D1: + if (data_norm == VINO_DATA_NORM_NONE) + return -EINVAL; + + dprintk("standard name = %s\n", + vino_data_norms[data_norm].description); + + memset(s, 0, sizeof(struct v4l2_standard)); + s->index = index; + + s->id = vino_data_norms[data_norm].std; + s->frameperiod.numerator = 1; + s->frameperiod.denominator = + vino_data_norms[data_norm].fps_max; + s->framelines = + vino_data_norms[data_norm].framelines; + strcpy(s->name, + vino_data_norms[data_norm].description); + + return 0; +} + +static int vino_v4l2_querystd(struct vino_channel_settings *vcs, + v4l2_std_id *std) +{ + unsigned long flags; + int err = 0; + + spin_lock_irqsave(&vino_drvdata->input_lock, flags); + + switch (vcs->input) { + case VINO_INPUT_D1: *std = vino_inputs[vcs->input].std; break; case VINO_INPUT_COMPOSITE: case VINO_INPUT_SVIDEO: { - decoder_call(video, querystd, std); + struct saa7191_status status; + + i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status); + + if (status.signal) { + if (status.signal_60hz) { + *std = V4L2_STD_NTSC; + } else { + *std = V4L2_STD_PAL | V4L2_STD_SECAM; + } + } else { + *std = vino_inputs[vcs->input].std; + } break; } default: @@ -3033,10 +3138,9 @@ static int vino_querystd(struct file *file, void *__fh, return err; } -static int vino_g_std(struct file *file, void *__fh, +static int vino_v4l2_g_std(struct vino_channel_settings *vcs, v4l2_std_id *std) { - struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; spin_lock_irqsave(&vino_drvdata->input_lock, flags); @@ -3049,10 +3153,9 @@ static int vino_g_std(struct file *file, void *__fh, return 0; } -static int vino_s_std(struct file *file, void *__fh, +static int vino_v4l2_s_std(struct vino_channel_settings *vcs, v4l2_std_id *std) { - struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; int ret = 0; @@ -3073,7 +3176,12 @@ static int vino_s_std(struct file *file, void *__fh, if (vcs->input == VINO_INPUT_D1) goto out; - if ((*std) & V4L2_STD_PAL) { + if (((*std) & V4L2_STD_PAL) + && ((*std) & V4L2_STD_NTSC) + && ((*std) & V4L2_STD_SECAM)) { + ret = vino_set_data_norm(vcs, VINO_DATA_NORM_AUTO_EXT, + &flags); + } else if ((*std) & V4L2_STD_PAL) { ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL, &flags); } else if ((*std) & V4L2_STD_NTSC) { @@ -3099,144 +3207,185 @@ static int vino_s_std(struct file *file, void *__fh, return ret; } -static int vino_enum_fmt_vid_cap(struct file *file, void *__fh, +static int vino_v4l2_enum_fmt(struct vino_channel_settings *vcs, struct v4l2_fmtdesc *fd) { - dprintk("format index = %d\n", fd->index); + enum v4l2_buf_type type = fd->type; + int index = fd->index; + dprintk("format index = %d\n", index); - if (fd->index >= VINO_DATA_FMT_COUNT) + switch (fd->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if ((fd->index < 0) || + (fd->index >= VINO_DATA_FMT_COUNT)) + return -EINVAL; + dprintk("format name = %s\n", + vino_data_formats[index].description); + + memset(fd, 0, sizeof(struct v4l2_fmtdesc)); + fd->index = index; + fd->type = type; + fd->pixelformat = vino_data_formats[index].pixelformat; + strcpy(fd->description, vino_data_formats[index].description); + break; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: return -EINVAL; - dprintk("format name = %s\n", vino_data_formats[fd->index].description); + } - fd->pixelformat = vino_data_formats[fd->index].pixelformat; - strcpy(fd->description, vino_data_formats[fd->index].description); return 0; } -static int vino_try_fmt_vid_cap(struct file *file, void *__fh, +static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs, struct v4l2_format *f) { - struct vino_channel_settings *vcs = video_drvdata(file); struct vino_channel_settings tempvcs; unsigned long flags; - struct v4l2_pix_format *pf = &f->fmt.pix; - dprintk("requested: w = %d, h = %d\n", - pf->width, pf->height); + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct v4l2_pix_format *pf = &f->fmt.pix; - spin_lock_irqsave(&vino_drvdata->input_lock, flags); - memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings)); - spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); + dprintk("requested: w = %d, h = %d\n", + pf->width, pf->height); - tempvcs.data_format = vino_find_data_format(pf->pixelformat); - if (tempvcs.data_format == VINO_DATA_FMT_NONE) { - tempvcs.data_format = VINO_DATA_FMT_GREY; - pf->pixelformat = - vino_data_formats[tempvcs.data_format]. - pixelformat; - } + spin_lock_irqsave(&vino_drvdata->input_lock, flags); + memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings)); + spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); + + tempvcs.data_format = vino_find_data_format(pf->pixelformat); + if (tempvcs.data_format == VINO_DATA_FMT_NONE) { + tempvcs.data_format = VINO_DATA_FMT_GREY; + pf->pixelformat = + vino_data_formats[tempvcs.data_format]. + pixelformat; + } - /* data format must be set before clipping/scaling */ - vino_set_scaling(&tempvcs, pf->width, pf->height); + /* data format must be set before clipping/scaling */ + vino_set_scaling(&tempvcs, pf->width, pf->height); - dprintk("data format = %s\n", - vino_data_formats[tempvcs.data_format].description); + dprintk("data format = %s\n", + vino_data_formats[tempvcs.data_format].description); - pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) / - tempvcs.decimation; - pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) / - tempvcs.decimation; + pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) / + tempvcs.decimation; + pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) / + tempvcs.decimation; - pf->field = V4L2_FIELD_INTERLACED; - pf->bytesperline = tempvcs.line_size; - pf->sizeimage = tempvcs.line_size * - (tempvcs.clipping.bottom - tempvcs.clipping.top) / - tempvcs.decimation; - pf->colorspace = - vino_data_formats[tempvcs.data_format].colorspace; + pf->field = V4L2_FIELD_INTERLACED; + pf->bytesperline = tempvcs.line_size; + pf->sizeimage = tempvcs.line_size * + (tempvcs.clipping.bottom - tempvcs.clipping.top) / + tempvcs.decimation; + pf->colorspace = + vino_data_formats[tempvcs.data_format].colorspace; + + pf->priv = 0; + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } - pf->priv = 0; return 0; } -static int vino_g_fmt_vid_cap(struct file *file, void *__fh, +static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs, struct v4l2_format *f) { - struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; - struct v4l2_pix_format *pf = &f->fmt.pix; - spin_lock_irqsave(&vino_drvdata->input_lock, flags); + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct v4l2_pix_format *pf = &f->fmt.pix; + + spin_lock_irqsave(&vino_drvdata->input_lock, flags); - pf->width = (vcs->clipping.right - vcs->clipping.left) / - vcs->decimation; - pf->height = (vcs->clipping.bottom - vcs->clipping.top) / - vcs->decimation; - pf->pixelformat = - vino_data_formats[vcs->data_format].pixelformat; + pf->width = (vcs->clipping.right - vcs->clipping.left) / + vcs->decimation; + pf->height = (vcs->clipping.bottom - vcs->clipping.top) / + vcs->decimation; + pf->pixelformat = + vino_data_formats[vcs->data_format].pixelformat; - pf->field = V4L2_FIELD_INTERLACED; - pf->bytesperline = vcs->line_size; - pf->sizeimage = vcs->line_size * - (vcs->clipping.bottom - vcs->clipping.top) / - vcs->decimation; - pf->colorspace = - vino_data_formats[vcs->data_format].colorspace; + pf->field = V4L2_FIELD_INTERLACED; + pf->bytesperline = vcs->line_size; + pf->sizeimage = vcs->line_size * + (vcs->clipping.bottom - vcs->clipping.top) / + vcs->decimation; + pf->colorspace = + vino_data_formats[vcs->data_format].colorspace; - pf->priv = 0; + pf->priv = 0; + + spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } - spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); return 0; } -static int vino_s_fmt_vid_cap(struct file *file, void *__fh, +static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs, struct v4l2_format *f) { - struct vino_channel_settings *vcs = video_drvdata(file); int data_format; unsigned long flags; - struct v4l2_pix_format *pf = &f->fmt.pix; - spin_lock_irqsave(&vino_drvdata->input_lock, flags); + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct v4l2_pix_format *pf = &f->fmt.pix; - data_format = vino_find_data_format(pf->pixelformat); + spin_lock_irqsave(&vino_drvdata->input_lock, flags); - if (data_format == VINO_DATA_FMT_NONE) { - vcs->data_format = VINO_DATA_FMT_GREY; - pf->pixelformat = - vino_data_formats[vcs->data_format]. - pixelformat; - } else { - vcs->data_format = data_format; - } + data_format = vino_find_data_format(pf->pixelformat); - /* data format must be set before clipping/scaling */ - vino_set_scaling(vcs, pf->width, pf->height); + if (data_format == VINO_DATA_FMT_NONE) { + vcs->data_format = VINO_DATA_FMT_GREY; + pf->pixelformat = + vino_data_formats[vcs->data_format]. + pixelformat; + } else { + vcs->data_format = data_format; + } - dprintk("data format = %s\n", - vino_data_formats[vcs->data_format].description); + /* data format must be set before clipping/scaling */ + vino_set_scaling(vcs, pf->width, pf->height); - pf->width = vcs->clipping.right - vcs->clipping.left; - pf->height = vcs->clipping.bottom - vcs->clipping.top; + dprintk("data format = %s\n", + vino_data_formats[vcs->data_format].description); - pf->field = V4L2_FIELD_INTERLACED; - pf->bytesperline = vcs->line_size; - pf->sizeimage = vcs->line_size * - (vcs->clipping.bottom - vcs->clipping.top) / - vcs->decimation; - pf->colorspace = - vino_data_formats[vcs->data_format].colorspace; + pf->width = vcs->clipping.right - vcs->clipping.left; + pf->height = vcs->clipping.bottom - vcs->clipping.top; - pf->priv = 0; + pf->field = V4L2_FIELD_INTERLACED; + pf->bytesperline = vcs->line_size; + pf->sizeimage = vcs->line_size * + (vcs->clipping.bottom - vcs->clipping.top) / + vcs->decimation; + pf->colorspace = + vino_data_formats[vcs->data_format].colorspace; + + pf->priv = 0; + + spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } - spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); return 0; } -static int vino_cropcap(struct file *file, void *__fh, +static int vino_v4l2_cropcap(struct vino_channel_settings *vcs, struct v4l2_cropcap *ccap) { - struct vino_channel_settings *vcs = video_drvdata(file); const struct vino_data_norm *norm; unsigned long flags; @@ -3266,10 +3415,9 @@ static int vino_cropcap(struct file *file, void *__fh, return 0; } -static int vino_g_crop(struct file *file, void *__fh, +static int vino_v4l2_g_crop(struct vino_channel_settings *vcs, struct v4l2_crop *c) { - struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; switch (c->type) { @@ -3291,10 +3439,9 @@ static int vino_g_crop(struct file *file, void *__fh, return 0; } -static int vino_s_crop(struct file *file, void *__fh, +static int vino_v4l2_s_crop(struct vino_channel_settings *vcs, struct v4l2_crop *c) { - struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; switch (c->type) { @@ -3314,83 +3461,108 @@ static int vino_s_crop(struct file *file, void *__fh, return 0; } -static int vino_g_parm(struct file *file, void *__fh, +static int vino_v4l2_g_parm(struct vino_channel_settings *vcs, struct v4l2_streamparm *sp) { - struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; - struct v4l2_captureparm *cp = &sp->parm.capture; - cp->capability = V4L2_CAP_TIMEPERFRAME; - cp->timeperframe.numerator = 1; + switch (sp->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct v4l2_captureparm *cp = &sp->parm.capture; + memset(cp, 0, sizeof(struct v4l2_captureparm)); - spin_lock_irqsave(&vino_drvdata->input_lock, flags); + cp->capability = V4L2_CAP_TIMEPERFRAME; + cp->timeperframe.numerator = 1; + + spin_lock_irqsave(&vino_drvdata->input_lock, flags); - cp->timeperframe.denominator = vcs->fps; + cp->timeperframe.denominator = vcs->fps; - spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); + spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); - /* TODO: cp->readbuffers = xxx; */ + // TODO: cp->readbuffers = xxx; + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } return 0; } -static int vino_s_parm(struct file *file, void *__fh, +static int vino_v4l2_s_parm(struct vino_channel_settings *vcs, struct v4l2_streamparm *sp) { - struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; - struct v4l2_captureparm *cp = &sp->parm.capture; - spin_lock_irqsave(&vino_drvdata->input_lock, flags); + switch (sp->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct v4l2_captureparm *cp = &sp->parm.capture; - if ((cp->timeperframe.numerator == 0) || - (cp->timeperframe.denominator == 0)) { - /* reset framerate */ - vino_set_default_framerate(vcs); - } else { - vino_set_framerate(vcs, cp->timeperframe.denominator / - cp->timeperframe.numerator); - } + spin_lock_irqsave(&vino_drvdata->input_lock, flags); - spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); + if ((cp->timeperframe.numerator == 0) || + (cp->timeperframe.denominator == 0)) { + /* reset framerate */ + vino_set_default_framerate(vcs); + } else { + vino_set_framerate(vcs, cp->timeperframe.denominator / + cp->timeperframe.numerator); + } + + spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); + + // TODO: set buffers according to cp->readbuffers + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } return 0; } -static int vino_reqbufs(struct file *file, void *__fh, +static int vino_v4l2_reqbufs(struct vino_channel_settings *vcs, struct v4l2_requestbuffers *rb) { - struct vino_channel_settings *vcs = video_drvdata(file); - if (vcs->reading) return -EBUSY; - /* TODO: check queue type */ - if (rb->memory != V4L2_MEMORY_MMAP) { - dprintk("type not mmap\n"); - return -EINVAL; - } - - dprintk("count = %d\n", rb->count); - if (rb->count > 0) { - if (vino_is_capturing(vcs)) { - dprintk("busy, capturing\n"); - return -EBUSY; + switch (rb->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + // TODO: check queue type + if (rb->memory != V4L2_MEMORY_MMAP) { + dprintk("type not mmap\n"); + return -EINVAL; } - if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) { - dprintk("busy, buffers still mapped\n"); - return -EBUSY; + dprintk("count = %d\n", rb->count); + if (rb->count > 0) { + if (vino_is_capturing(vcs)) { + dprintk("busy, capturing\n"); + return -EBUSY; + } + + if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) { + dprintk("busy, buffers still mapped\n"); + return -EBUSY; + } else { + vcs->streaming = 0; + vino_queue_free(&vcs->fb_queue); + vino_queue_init(&vcs->fb_queue, &rb->count); + } } else { vcs->streaming = 0; + vino_capture_stop(vcs); vino_queue_free(&vcs->fb_queue); - vino_queue_init(&vcs->fb_queue, &rb->count); } - } else { - vcs->streaming = 0; - vino_capture_stop(vcs); - vino_queue_free(&vcs->fb_queue); + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; } return 0; @@ -3434,135 +3606,156 @@ static void vino_v4l2_get_buffer_status(struct vino_channel_settings *vcs, fb->id, fb->size, fb->data_size, fb->offset); } -static int vino_querybuf(struct file *file, void *__fh, +static int vino_v4l2_querybuf(struct vino_channel_settings *vcs, struct v4l2_buffer *b) { - struct vino_channel_settings *vcs = video_drvdata(file); - struct vino_framebuffer *fb; - if (vcs->reading) return -EBUSY; - /* TODO: check queue type */ - if (b->index >= vino_queue_get_length(&vcs->fb_queue)) { - dprintk("invalid index = %d\n", - b->index); - return -EINVAL; - } + switch (b->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct vino_framebuffer *fb; - fb = vino_queue_get_buffer(&vcs->fb_queue, - b->index); - if (fb == NULL) { - dprintk("vino_queue_get_buffer() failed"); + // TODO: check queue type + if (b->index >= vino_queue_get_length(&vcs->fb_queue)) { + dprintk("invalid index = %d\n", + b->index); + return -EINVAL; + } + + fb = vino_queue_get_buffer(&vcs->fb_queue, + b->index); + if (fb == NULL) { + dprintk("vino_queue_get_buffer() failed"); + return -EINVAL; + } + + vino_v4l2_get_buffer_status(vcs, fb, b); + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: return -EINVAL; } - vino_v4l2_get_buffer_status(vcs, fb, b); - return 0; } -static int vino_qbuf(struct file *file, void *__fh, +static int vino_v4l2_qbuf(struct vino_channel_settings *vcs, struct v4l2_buffer *b) { - struct vino_channel_settings *vcs = video_drvdata(file); - struct vino_framebuffer *fb; - int ret; - if (vcs->reading) return -EBUSY; - /* TODO: check queue type */ - if (b->memory != V4L2_MEMORY_MMAP) { - dprintk("type not mmap\n"); - return -EINVAL; - } + switch (b->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct vino_framebuffer *fb; + int ret; - fb = vino_capture_enqueue(vcs, b->index); - if (fb == NULL) - return -EINVAL; + // TODO: check queue type + if (b->memory != V4L2_MEMORY_MMAP) { + dprintk("type not mmap\n"); + return -EINVAL; + } - vino_v4l2_get_buffer_status(vcs, fb, b); + fb = vino_capture_enqueue(vcs, b->index); + if (fb == NULL) + return -EINVAL; - if (vcs->streaming) { - ret = vino_capture_next(vcs, 1); - if (ret) - return ret; + vino_v4l2_get_buffer_status(vcs, fb, b); + + if (vcs->streaming) { + ret = vino_capture_next(vcs, 1); + if (ret) + return ret; + } + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; } return 0; } -static int vino_dqbuf(struct file *file, void *__fh, - struct v4l2_buffer *b) +static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs, + struct v4l2_buffer *b, + unsigned int nonblocking) { - struct vino_channel_settings *vcs = video_drvdata(file); - unsigned int nonblocking = file->f_flags & O_NONBLOCK; - struct vino_framebuffer *fb; - unsigned int incoming, outgoing; - int err; - if (vcs->reading) return -EBUSY; - /* TODO: check queue type */ - - err = vino_queue_get_incoming(&vcs->fb_queue, &incoming); - if (err) { - dprintk("vino_queue_get_incoming() failed\n"); - return -EINVAL; - } - err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing); - if (err) { - dprintk("vino_queue_get_outgoing() failed\n"); - return -EINVAL; - } + switch (b->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct vino_framebuffer *fb; + unsigned int incoming, outgoing; + int err; - dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing); + // TODO: check queue type - if (outgoing == 0) { - if (incoming == 0) { - dprintk("no incoming or outgoing buffers\n"); + err = vino_queue_get_incoming(&vcs->fb_queue, &incoming); + if (err) { + dprintk("vino_queue_get_incoming() failed\n"); return -EINVAL; } - if (nonblocking) { - dprintk("non-blocking I/O was selected and " - "there are no buffers to dequeue\n"); - return -EAGAIN; + err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing); + if (err) { + dprintk("vino_queue_get_outgoing() failed\n"); + return -EINVAL; } - err = vino_wait_for_frame(vcs); - if (err) { + dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing); + + if (outgoing == 0) { + if (incoming == 0) { + dprintk("no incoming or outgoing buffers\n"); + return -EINVAL; + } + if (nonblocking) { + dprintk("non-blocking I/O was selected and " + "there are no buffers to dequeue\n"); + return -EAGAIN; + } + err = vino_wait_for_frame(vcs); if (err) { - /* interrupted or no frames captured because of - * frame skipping */ - /* vino_capture_failed(vcs); */ - return -EIO; + err = vino_wait_for_frame(vcs); + if (err) { + /* interrupted or + * no frames captured because + * of frame skipping */ + // vino_capture_failed(vcs); + return -EIO; + } } } - } - fb = vino_queue_remove(&vcs->fb_queue, &b->index); - if (fb == NULL) { - dprintk("vino_queue_remove() failed\n"); - return -EINVAL; - } + fb = vino_queue_remove(&vcs->fb_queue, &b->index); + if (fb == NULL) { + dprintk("vino_queue_remove() failed\n"); + return -EINVAL; + } - err = vino_check_buffer(vcs, fb); + err = vino_check_buffer(vcs, fb); - vino_v4l2_get_buffer_status(vcs, fb, b); + vino_v4l2_get_buffer_status(vcs, fb, b); - if (err) - return -EIO; + if (err) + return -EIO; + + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } return 0; } -static int vino_streamon(struct file *file, void *__fh, - enum v4l2_buf_type i) +static int vino_v4l2_streamon(struct vino_channel_settings *vcs) { - struct vino_channel_settings *vcs = video_drvdata(file); unsigned int incoming; int ret; if (vcs->reading) @@ -3599,10 +3792,8 @@ static int vino_streamon(struct file *file, void *__fh, return 0; } -static int vino_streamoff(struct file *file, void *__fh, - enum v4l2_buf_type i) +static int vino_v4l2_streamoff(struct vino_channel_settings *vcs) { - struct vino_channel_settings *vcs = video_drvdata(file); if (vcs->reading) return -EBUSY; @@ -3615,10 +3806,9 @@ static int vino_streamoff(struct file *file, void *__fh, return 0; } -static int vino_queryctrl(struct file *file, void *__fh, +static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs, struct v4l2_queryctrl *queryctrl) { - struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; int i; int err = 0; @@ -3665,10 +3855,9 @@ static int vino_queryctrl(struct file *file, void *__fh, return err; } -static int vino_g_ctrl(struct file *file, void *__fh, +static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs, struct v4l2_control *control) { - struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; int i; int err = 0; @@ -3677,38 +3866,56 @@ static int vino_g_ctrl(struct file *file, void *__fh, switch (vcs->input) { case VINO_INPUT_D1: { - err = -EINVAL; + struct indycam_control indycam_ctrl; + for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) { - if (vino_indycam_v4l2_controls[i].id == control->id) { - err = 0; - break; + if (vino_indycam_v4l2_controls[i].id == + control->id) { + goto found1; } } - if (err) - goto out; + err = -EINVAL; + goto out; - err = camera_call(core, g_ctrl, control); - if (err) +found1: + indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0]; + + err = i2c_camera_command(DECODER_INDYCAM_GET_CONTROL, + &indycam_ctrl); + if (err) { err = -EINVAL; + goto out; + } + + control->value = indycam_ctrl.value; break; } case VINO_INPUT_COMPOSITE: case VINO_INPUT_SVIDEO: { - err = -EINVAL; + struct saa7191_control saa7191_ctrl; + for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) { - if (vino_saa7191_v4l2_controls[i].id == control->id) { - err = 0; - break; + if (vino_saa7191_v4l2_controls[i].id == + control->id) { + goto found2; } } - if (err) - goto out; + err = -EINVAL; + goto out; - err = decoder_call(core, g_ctrl, control); - if (err) +found2: + saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0]; + + err = i2c_decoder_command(DECODER_SAA7191_GET_CONTROL, + &saa7191_ctrl); + if (err) { err = -EINVAL; + goto out; + } + + control->value = saa7191_ctrl.value; break; } default: @@ -3721,10 +3928,9 @@ static int vino_g_ctrl(struct file *file, void *__fh, return err; } -static int vino_s_ctrl(struct file *file, void *__fh, +static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs, struct v4l2_control *control) { - struct vino_channel_settings *vcs = video_drvdata(file); unsigned long flags; int i; int err = 0; @@ -3738,43 +3944,65 @@ static int vino_s_ctrl(struct file *file, void *__fh, switch (vcs->input) { case VINO_INPUT_D1: { - err = -EINVAL; + struct indycam_control indycam_ctrl; + for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) { - if (vino_indycam_v4l2_controls[i].id == control->id) { - err = 0; - break; + if (vino_indycam_v4l2_controls[i].id == + control->id) { + if ((control->value >= + vino_indycam_v4l2_controls[i].minimum) + && (control->value <= + vino_indycam_v4l2_controls[i]. + maximum)) { + goto found1; + } else { + err = -ERANGE; + goto out; + } } } - if (err) - goto out; - if (control->value < vino_indycam_v4l2_controls[i].minimum || - control->value > vino_indycam_v4l2_controls[i].maximum) { - err = -ERANGE; - goto out; - } - err = camera_call(core, s_ctrl, control); + + err = -EINVAL; + goto out; + +found1: + indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0]; + indycam_ctrl.value = control->value; + + err = i2c_camera_command(DECODER_INDYCAM_SET_CONTROL, + &indycam_ctrl); if (err) err = -EINVAL; break; } case VINO_INPUT_COMPOSITE: case VINO_INPUT_SVIDEO: { - err = -EINVAL; + struct saa7191_control saa7191_ctrl; + for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) { - if (vino_saa7191_v4l2_controls[i].id == control->id) { - err = 0; - break; + if (vino_saa7191_v4l2_controls[i].id == + control->id) { + if ((control->value >= + vino_saa7191_v4l2_controls[i].minimum) + && (control->value <= + vino_saa7191_v4l2_controls[i]. + maximum)) { + goto found2; + } else { + err = -ERANGE; + goto out; + } } } - if (err) - goto out; - if (control->value < vino_saa7191_v4l2_controls[i].minimum || - control->value > vino_saa7191_v4l2_controls[i].maximum) { - err = -ERANGE; - goto out; - } + err = -EINVAL; + goto out; + +found2: + saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0]; + saa7191_ctrl.value = control->value; - err = decoder_call(core, s_ctrl, control); + err = i2c_decoder_command(DECODER_SAA7191_SET_CONTROL, + &saa7191_ctrl); if (err) err = -EINVAL; break; @@ -4005,9 +4233,116 @@ static unsigned int vino_poll(struct file *file, poll_table *pt) ret = POLLIN | POLLRDNORM; error: + return ret; } +static long vino_do_ioctl(struct file *file, unsigned int cmd, void *arg) +{ + struct vino_channel_settings *vcs = video_drvdata(file); + +#ifdef VINO_DEBUG + switch (_IOC_TYPE(cmd)) { + case 'v': + dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd); + break; + case 'V': + dprintk("ioctl(): V4L2 %s (0x%08x)\n", + v4l2_ioctl_names[_IOC_NR(cmd)], cmd); + break; + default: + dprintk("ioctl(): unsupported command 0x%08x\n", cmd); + } +#endif + + switch (cmd) { + /* V4L2 interface */ + case VIDIOC_QUERYCAP: { + vino_v4l2_querycap(arg); + break; + } + case VIDIOC_ENUMINPUT: { + return vino_v4l2_enuminput(vcs, arg); + } + case VIDIOC_G_INPUT: { + return vino_v4l2_g_input(vcs, arg); + } + case VIDIOC_S_INPUT: { + return vino_v4l2_s_input(vcs, arg); + } + case VIDIOC_ENUMSTD: { + return vino_v4l2_enumstd(vcs, arg); + } + case VIDIOC_QUERYSTD: { + return vino_v4l2_querystd(vcs, arg); + } + case VIDIOC_G_STD: { + return vino_v4l2_g_std(vcs, arg); + } + case VIDIOC_S_STD: { + return vino_v4l2_s_std(vcs, arg); + } + case VIDIOC_ENUM_FMT: { + return vino_v4l2_enum_fmt(vcs, arg); + } + case VIDIOC_TRY_FMT: { + return vino_v4l2_try_fmt(vcs, arg); + } + case VIDIOC_G_FMT: { + return vino_v4l2_g_fmt(vcs, arg); + } + case VIDIOC_S_FMT: { + return vino_v4l2_s_fmt(vcs, arg); + } + case VIDIOC_CROPCAP: { + return vino_v4l2_cropcap(vcs, arg); + } + case VIDIOC_G_CROP: { + return vino_v4l2_g_crop(vcs, arg); + } + case VIDIOC_S_CROP: { + return vino_v4l2_s_crop(vcs, arg); + } + case VIDIOC_G_PARM: { + return vino_v4l2_g_parm(vcs, arg); + } + case VIDIOC_S_PARM: { + return vino_v4l2_s_parm(vcs, arg); + } + case VIDIOC_REQBUFS: { + return vino_v4l2_reqbufs(vcs, arg); + } + case VIDIOC_QUERYBUF: { + return vino_v4l2_querybuf(vcs, arg); + } + case VIDIOC_QBUF: { + return vino_v4l2_qbuf(vcs, arg); + } + case VIDIOC_DQBUF: { + return vino_v4l2_dqbuf(vcs, arg, file->f_flags & O_NONBLOCK); + } + case VIDIOC_STREAMON: { + return vino_v4l2_streamon(vcs); + } + case VIDIOC_STREAMOFF: { + return vino_v4l2_streamoff(vcs); + } + case VIDIOC_QUERYCTRL: { + return vino_v4l2_queryctrl(vcs, arg); + } + case VIDIOC_G_CTRL: { + return vino_v4l2_g_ctrl(vcs, arg); + } + case VIDIOC_S_CTRL: { + return vino_v4l2_s_ctrl(vcs, arg); + } + default: + return -ENOIOCTLCMD; + } + + return 0; +} + static long vino_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -4017,7 +4352,7 @@ static long vino_ioctl(struct file *file, if (mutex_lock_interruptible(&vcs->mutex)) return -EINTR; - ret = video_ioctl2(file, cmd, arg); + ret = video_usercopy(file, cmd, arg, vino_do_ioctl); mutex_unlock(&vcs->mutex); @@ -4029,75 +4364,45 @@ static long vino_ioctl(struct file *file, /* __initdata */ static int vino_init_stage; -const struct v4l2_ioctl_ops vino_ioctl_ops = { - .vidioc_enum_fmt_vid_cap = vino_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vino_g_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vino_s_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vino_try_fmt_vid_cap, - .vidioc_querycap = vino_querycap, - .vidioc_enum_input = vino_enum_input, - .vidioc_g_input = vino_g_input, - .vidioc_s_input = vino_s_input, - .vidioc_g_std = vino_g_std, - .vidioc_s_std = vino_s_std, - .vidioc_querystd = vino_querystd, - .vidioc_cropcap = vino_cropcap, - .vidioc_s_crop = vino_s_crop, - .vidioc_g_crop = vino_g_crop, - .vidioc_s_parm = vino_s_parm, - .vidioc_g_parm = vino_g_parm, - .vidioc_reqbufs = vino_reqbufs, - .vidioc_querybuf = vino_querybuf, - .vidioc_qbuf = vino_qbuf, - .vidioc_dqbuf = vino_dqbuf, - .vidioc_streamon = vino_streamon, - .vidioc_streamoff = vino_streamoff, - .vidioc_queryctrl = vino_queryctrl, - .vidioc_g_ctrl = vino_g_ctrl, - .vidioc_s_ctrl = vino_s_ctrl, -}; - static const struct v4l2_file_operations vino_fops = { .owner = THIS_MODULE, .open = vino_open, .release = vino_close, - .unlocked_ioctl = vino_ioctl, + .ioctl = vino_ioctl, .mmap = vino_mmap, .poll = vino_poll, }; -static struct video_device vdev_template = { +static struct video_device v4l_device_template = { .name = "NOT SET", .fops = &vino_fops, - .ioctl_ops = &vino_ioctl_ops, - .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, .minor = -1, }; static void vino_module_cleanup(int stage) { switch(stage) { - case 11: - video_unregister_device(vino_drvdata->b.vdev); - vino_drvdata->b.vdev = NULL; case 10: - video_unregister_device(vino_drvdata->a.vdev); - vino_drvdata->a.vdev = NULL; + video_unregister_device(vino_drvdata->b.v4l_device); + vino_drvdata->b.v4l_device = NULL; case 9: - i2c_del_adapter(&vino_i2c_adapter); + video_unregister_device(vino_drvdata->a.v4l_device); + vino_drvdata->a.v4l_device = NULL; case 8: - free_irq(SGI_VINO_IRQ, NULL); + vino_i2c_del_bus(); case 7: - if (vino_drvdata->b.vdev) { - video_device_release(vino_drvdata->b.vdev); - vino_drvdata->b.vdev = NULL; - } + free_irq(SGI_VINO_IRQ, NULL); case 6: - if (vino_drvdata->a.vdev) { - video_device_release(vino_drvdata->a.vdev); - vino_drvdata->a.vdev = NULL; + if (vino_drvdata->b.v4l_device) { + video_device_release(vino_drvdata->b.v4l_device); + vino_drvdata->b.v4l_device = NULL; } case 5: + if (vino_drvdata->a.v4l_device) { + video_device_release(vino_drvdata->a.v4l_device); + vino_drvdata->a.v4l_device = NULL; + } + case 4: /* all entries in dma_cpu dummy table have the same address */ dma_unmap_single(NULL, vino_drvdata->dummy_desc_table.dma_cpu[0], @@ -4107,10 +4412,8 @@ static void vino_module_cleanup(int stage) (void *)vino_drvdata-> dummy_desc_table.dma_cpu, vino_drvdata->dummy_desc_table.dma); - case 4: - free_page(vino_drvdata->dummy_page); case 3: - v4l2_device_unregister(&vino_drvdata->v4l2_dev); + free_page(vino_drvdata->dummy_page); case 2: kfree(vino_drvdata); case 1: @@ -4165,7 +4468,6 @@ static int vino_probe(void) static int vino_init(void) { dma_addr_t dma_dummy_address; - int err; int i; vino_drvdata = kzalloc(sizeof(struct vino_settings), GFP_KERNEL); @@ -4174,12 +4476,6 @@ static int vino_init(void) return -ENOMEM; } vino_init_stage++; - strlcpy(vino_drvdata->v4l2_dev.name, "vino", - sizeof(vino_drvdata->v4l2_dev.name)); - err = v4l2_device_register(NULL, &vino_drvdata->v4l2_dev); - if (err) - return err; - vino_init_stage++; /* create a dummy dma descriptor */ vino_drvdata->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA); @@ -4246,27 +4542,25 @@ static int vino_init_channel_settings(struct vino_channel_settings *vcs, spin_lock_init(&vcs->fb_queue.queue_lock); init_waitqueue_head(&vcs->fb_queue.frame_wait_queue); - vcs->vdev = video_device_alloc(); - if (!vcs->vdev) { + vcs->v4l_device = video_device_alloc(); + if (!vcs->v4l_device) { vino_module_cleanup(vino_init_stage); return -ENOMEM; } vino_init_stage++; - memcpy(vcs->vdev, &vdev_template, + memcpy(vcs->v4l_device, &v4l_device_template, sizeof(struct video_device)); - strcpy(vcs->vdev->name, name); - vcs->vdev->release = video_device_release; - vcs->vdev->v4l2_dev = &vino_drvdata->v4l2_dev; + strcpy(vcs->v4l_device->name, name); + vcs->v4l_device->release = video_device_release; - video_set_drvdata(vcs->vdev, vcs); + video_set_drvdata(vcs->v4l_device, vcs); return 0; } static int __init vino_module_init(void) { - unsigned short addr[] = { 0, I2C_CLIENT_END }; int ret; printk(KERN_INFO "SGI VINO driver version %s\n", @@ -4286,12 +4580,12 @@ static int __init vino_module_init(void) spin_lock_init(&vino_drvdata->input_lock); ret = vino_init_channel_settings(&vino_drvdata->a, VINO_CHANNEL_A, - vino_vdev_name_a); + vino_v4l_device_name_a); if (ret) return ret; ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B, - vino_vdev_name_b); + vino_v4l_device_name_b); if (ret) return ret; @@ -4307,16 +4601,15 @@ static int __init vino_module_init(void) } vino_init_stage++; - ret = i2c_add_adapter(&vino_i2c_adapter); + ret = vino_i2c_add_bus(); if (ret) { printk(KERN_ERR "VINO I2C bus registration failed\n"); vino_module_cleanup(vino_init_stage); return ret; } - i2c_set_adapdata(&vino_i2c_adapter, &vino_drvdata->v4l2_dev); vino_init_stage++; - ret = video_register_device(vino_drvdata->a.vdev, + ret = video_register_device(vino_drvdata->a.v4l_device, VFL_TYPE_GRABBER, -1); if (ret < 0) { printk(KERN_ERR "VINO channel A Video4Linux-device " @@ -4326,7 +4619,7 @@ static int __init vino_module_init(void) } vino_init_stage++; - ret = video_register_device(vino_drvdata->b.vdev, + ret = video_register_device(vino_drvdata->b.v4l_device, VFL_TYPE_GRABBER, -1); if (ret < 0) { printk(KERN_ERR "VINO channel B Video4Linux-device " @@ -4336,12 +4629,10 @@ static int __init vino_module_init(void) } vino_init_stage++; - addr[0] = 0x45; - vino_drvdata->decoder = v4l2_i2c_new_probed_subdev(&vino_i2c_adapter, - "saa7191", "saa7191", addr); - addr[0] = 0x2b; - vino_drvdata->camera = v4l2_i2c_new_probed_subdev(&vino_i2c_adapter, - "indycam", "indycam", addr); +#ifdef MODULE + request_module("saa7191"); + request_module("indycam"); +#endif dprintk("init complete!\n"); diff --git a/trunk/drivers/media/video/vivi.c b/trunk/drivers/media/video/vivi.c index fbfefae7886f..81d5aa5cf331 100644 --- a/trunk/drivers/media/video/vivi.c +++ b/trunk/drivers/media/video/vivi.c @@ -28,14 +28,17 @@ #include #include #include +#ifdef CONFIG_VIDEO_V4L1_COMPAT +/* Include V4L1 specific functions. Should be removed soon */ +#include +#endif #include +#include +#include +#include #include #include #include -#include -#include -#include -#include "font.h" #define VIVI_MODULE_NAME "vivi" @@ -44,32 +47,18 @@ #define WAKE_DENOMINATOR 1001 #define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ +#include "font.h" + #define VIVI_MAJOR_VERSION 0 -#define VIVI_MINOR_VERSION 6 +#define VIVI_MINOR_VERSION 5 #define VIVI_RELEASE 0 #define VIVI_VERSION \ KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) -MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board"); -MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); -MODULE_LICENSE("Dual BSD/GPL"); - -static unsigned video_nr = -1; -module_param(video_nr, uint, 0644); -MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect"); - -static unsigned n_devs = 1; -module_param(n_devs, uint, 0644); -MODULE_PARM_DESC(n_devs, "number of video devices to create"); - -static unsigned debug; -module_param(debug, uint, 0644); -MODULE_PARM_DESC(debug, "activates debug info"); - -static unsigned int vid_limit = 16; -module_param(vid_limit, uint, 0644); -MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); - +/* Declare static vars that will be used as parameters */ +static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ +static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ +static int n_devs = 1; /* Number of virtual devices */ /* supported controls */ static struct v4l2_queryctrl vivi_qctrl[] = { @@ -80,7 +69,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 65535, .step = 65535/100, .default_value = 65535, - .flags = V4L2_CTRL_FLAG_SLIDER, + .flags = 0, .type = V4L2_CTRL_TYPE_INTEGER, }, { .id = V4L2_CID_BRIGHTNESS, @@ -90,7 +79,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 255, .step = 1, .default_value = 127, - .flags = V4L2_CTRL_FLAG_SLIDER, + .flags = 0, }, { .id = V4L2_CID_CONTRAST, .type = V4L2_CTRL_TYPE_INTEGER, @@ -99,7 +88,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 255, .step = 0x1, .default_value = 0x10, - .flags = V4L2_CTRL_FLAG_SLIDER, + .flags = 0, }, { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, @@ -108,7 +97,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 255, .step = 0x1, .default_value = 127, - .flags = V4L2_CTRL_FLAG_SLIDER, + .flags = 0, }, { .id = V4L2_CID_HUE, .type = V4L2_CTRL_TYPE_INTEGER, @@ -117,12 +106,17 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 127, .step = 0x1, .default_value = 0, - .flags = V4L2_CTRL_FLAG_SLIDER, + .flags = 0, } }; -#define dprintk(dev, level, fmt, arg...) \ - v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg) +static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; + +#define dprintk(dev, level, fmt, arg...) \ + do { \ + if (dev->vfd->debug >= (level)) \ + printk(KERN_DEBUG "vivi: " fmt , ## arg); \ + } while (0) /* ------------------------------------------------------------------ Basic structures @@ -212,7 +206,6 @@ static LIST_HEAD(vivi_devlist); struct vivi_dev { struct list_head vivi_devlist; - struct v4l2_device v4l2_dev; spinlock_t slock; struct mutex mutex; @@ -230,12 +223,6 @@ struct vivi_dev { char timestr[13]; int mv_count; /* Controls bars movement */ - - /* Input Number */ - int input; - - /* Control 'registers' */ - int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; }; struct vivi_fh { @@ -248,7 +235,6 @@ struct vivi_fh { enum v4l2_buf_type type; unsigned char bars[8][3]; - int input; /* Input Number on bars */ }; /* ------------------------------------------------------------------ @@ -268,72 +254,18 @@ enum colors { BLACK, }; +static u8 bars[8][3] = { /* R G B */ -#define COLOR_WHITE {204, 204, 204} -#define COLOR_AMBAR {208, 208, 0} -#define COLOR_CIAN { 0, 206, 206} -#define COLOR_GREEN { 0, 239, 0} -#define COLOR_MAGENTA {239, 0, 239} -#define COLOR_RED {205, 0, 0} -#define COLOR_BLUE { 0, 0, 255} -#define COLOR_BLACK { 0, 0, 0} - -struct bar_std { - u8 bar[8][3]; + {204, 204, 204}, /* white */ + {208, 208, 0}, /* ambar */ + { 0, 206, 206}, /* cyan */ + { 0, 239, 0}, /* green */ + {239, 0, 239}, /* magenta */ + {205, 0, 0}, /* red */ + { 0, 0, 255}, /* blue */ + { 0, 0, 0}, /* black */ }; -/* Maximum number of bars are 10 - otherwise, the input print code - should be modified */ -static struct bar_std bars[] = { - { /* Standard ITU-R color bar sequence */ - { - COLOR_WHITE, - COLOR_AMBAR, - COLOR_CIAN, - COLOR_GREEN, - COLOR_MAGENTA, - COLOR_RED, - COLOR_BLUE, - COLOR_BLACK, - } - }, { - { - COLOR_WHITE, - COLOR_AMBAR, - COLOR_BLACK, - COLOR_WHITE, - COLOR_AMBAR, - COLOR_BLACK, - COLOR_WHITE, - COLOR_AMBAR, - } - }, { - { - COLOR_WHITE, - COLOR_CIAN, - COLOR_BLACK, - COLOR_WHITE, - COLOR_CIAN, - COLOR_BLACK, - COLOR_WHITE, - COLOR_CIAN, - } - }, { - { - COLOR_WHITE, - COLOR_GREEN, - COLOR_BLACK, - COLOR_WHITE, - COLOR_GREEN, - COLOR_BLACK, - COLOR_WHITE, - COLOR_GREEN, - } - }, -}; - -#define NUM_INPUTS ARRAY_SIZE(bars) - #define TO_Y(r, g, b) \ (((16829 * r + 33039 * g + 6416 * b + 32768) >> 16) + 16) /* RGB to V(Cr) Color transform */ @@ -343,10 +275,9 @@ static struct bar_std bars[] = { #define TO_U(r, g, b) \ (((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128) -#define TSTAMP_MIN_Y 24 -#define TSTAMP_MAX_Y (TSTAMP_MIN_Y + 15) -#define TSTAMP_INPUT_X 10 -#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X) +#define TSTAMP_MIN_Y 24 +#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 +#define TSTAMP_MIN_X 64 static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos) { @@ -461,29 +392,9 @@ static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax, pos += 4; /* only 16 bpp supported for now */ } - /* Prints input entry number */ - - /* Checks if it is possible to input number */ + /* Checks if it is possible to show timestamp */ if (TSTAMP_MAX_Y >= hmax) goto end; - - if (TSTAMP_INPUT_X + strlen(timestr) >= wmax) - goto end; - - if (line >= TSTAMP_MIN_Y && line <= TSTAMP_MAX_Y) { - chr = rom8x16_bits[fh->input * 16 + line - TSTAMP_MIN_Y]; - pos = TSTAMP_INPUT_X; - for (i = 0; i < 7; i++) { - /* Draw white font on black background */ - if (chr & 1 << (7 - i)) - gen_twopix(fh, basep + pos, WHITE); - else - gen_twopix(fh, basep + pos, BLACK); - pos += 2; - } - } - - /* Checks if it is possible to show timestamp */ if (TSTAMP_MIN_X + strlen(timestr) >= wmax) goto end; @@ -666,7 +577,7 @@ static int vivi_start_thread(struct vivi_fh *fh) dma_q->kthread = kthread_run(vivi_thread, fh, "vivi"); if (IS_ERR(dma_q->kthread)) { - v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n"); + printk(KERN_ERR "vivi: kernel_thread() failed\n"); return PTR_ERR(dma_q->kthread); } /* Wakes thread */ @@ -809,12 +720,8 @@ static struct videobuf_queue_ops vivi_video_qops = { static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct vivi_fh *fh = priv; - struct vivi_dev *dev = fh->dev; - strcpy(cap->driver, "vivi"); strcpy(cap->card, "vivi"); - strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); cap->version = VIVI_VERSION; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | @@ -900,19 +807,38 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, return 0; } -/* precalculate color bar values to speed up rendering */ -static void precalculate_bars(struct vivi_fh *fh) +/*FIXME: This seems to be generic enough to be at videodev2 */ +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) { - struct vivi_dev *dev = fh->dev; + struct vivi_fh *fh = priv; + struct videobuf_queue *q = &fh->vb_vidq; unsigned char r, g, b; int k, is_yuv; - fh->input = dev->input; + int ret = vidioc_try_fmt_vid_cap(file, fh, f); + if (ret < 0) + return (ret); + + mutex_lock(&q->vb_lock); + + if (videobuf_queue_is_busy(&fh->vb_vidq)) { + dprintk(fh->dev, 1, "%s queue busy\n", __func__); + ret = -EBUSY; + goto out; + } + + fh->fmt = get_format(f); + fh->width = f->fmt.pix.width; + fh->height = f->fmt.pix.height; + fh->vb_vidq.field = f->fmt.pix.field; + fh->type = f->type; + /* precalculate color bar values to speed up rendering */ for (k = 0; k < 8; k++) { - r = bars[fh->input].bar[k][0]; - g = bars[fh->input].bar[k][1]; - b = bars[fh->input].bar[k][2]; + r = bars[k][0]; + g = bars[k][1]; + b = bars[k][2]; is_yuv = 0; switch (fh->fmt->fourcc) { @@ -945,40 +871,11 @@ static void precalculate_bars(struct vivi_fh *fh) } } -} - -/*FIXME: This seems to be generic enough to be at videodev2 */ -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct vivi_fh *fh = priv; - struct videobuf_queue *q = &fh->vb_vidq; - - int ret = vidioc_try_fmt_vid_cap(file, fh, f); - if (ret < 0) - return ret; - - mutex_lock(&q->vb_lock); - - if (videobuf_queue_is_busy(&fh->vb_vidq)) { - dprintk(fh->dev, 1, "%s queue busy\n", __func__); - ret = -EBUSY; - goto out; - } - - fh->fmt = get_format(f); - fh->width = f->fmt.pix.width; - fh->height = f->fmt.pix.height; - fh->vb_vidq.field = f->fmt.pix.field; - fh->type = f->type; - - precalculate_bars(fh); - ret = 0; out: mutex_unlock(&q->vb_lock); - return ret; + return (ret); } static int vidioc_reqbufs(struct file *file, void *priv, @@ -1053,36 +950,27 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *inp) { - if (inp->index >= NUM_INPUTS) + if (inp->index != 0) return -EINVAL; inp->type = V4L2_INPUT_TYPE_CAMERA; inp->std = V4L2_STD_525_60; - sprintf(inp->name, "Camera %u", inp->index); + strcpy(inp->name, "Camera"); return (0); } static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) { - struct vivi_fh *fh = priv; - struct vivi_dev *dev = fh->dev; - - *i = dev->input; + *i = 0; return (0); } static int vidioc_s_input(struct file *file, void *priv, unsigned int i) { - struct vivi_fh *fh = priv; - struct vivi_dev *dev = fh->dev; - - if (i >= NUM_INPUTS) + if (i > 0) return -EINVAL; - dev->input = i; - precalculate_bars(fh); - return (0); } @@ -1105,14 +993,12 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct vivi_fh *fh = priv; - struct vivi_dev *dev = fh->dev; int i; for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) if (ctrl->id == vivi_qctrl[i].id) { - ctrl->value = dev->qctl_regs[i]; - return 0; + ctrl->value = qctl_regs[i]; + return (0); } return -EINVAL; @@ -1120,18 +1006,16 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { - struct vivi_fh *fh = priv; - struct vivi_dev *dev = fh->dev; int i; for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) if (ctrl->id == vivi_qctrl[i].id) { - if (ctrl->value < vivi_qctrl[i].minimum || - ctrl->value > vivi_qctrl[i].maximum) { - return -ERANGE; - } - dev->qctl_regs[i] = ctrl->value; - return 0; + if (ctrl->value < vivi_qctrl[i].minimum + || ctrl->value > vivi_qctrl[i].maximum) { + return (-ERANGE); + } + qctl_regs[i] = ctrl->value; + return (0); } return -EINVAL; } @@ -1142,20 +1026,32 @@ static int vidioc_s_ctrl(struct file *file, void *priv, static int vivi_open(struct file *file) { - struct vivi_dev *dev = video_drvdata(file); + int minor = video_devdata(file)->minor; + struct vivi_dev *dev; struct vivi_fh *fh = NULL; + int i; int retval = 0; + printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor); + + lock_kernel(); + list_for_each_entry(dev, &vivi_devlist, vivi_devlist) + if (dev->vfd->minor == minor) + goto found; + unlock_kernel(); + return -ENODEV; + +found: mutex_lock(&dev->mutex); dev->users++; if (dev->users > 1) { dev->users--; - mutex_unlock(&dev->mutex); - return -EBUSY; + retval = -EBUSY; + goto unlock; } - dprintk(dev, 1, "open /dev/video%d type=%s users=%d\n", dev->vfd->num, + dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor, v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); /* allocate + initialize per filehandle data */ @@ -1163,11 +1059,14 @@ static int vivi_open(struct file *file) if (NULL == fh) { dev->users--; retval = -ENOMEM; + goto unlock; } +unlock: mutex_unlock(&dev->mutex); - - if (retval) + if (retval) { + unlock_kernel(); return retval; + } file->private_data = fh; fh->dev = dev; @@ -1177,6 +1076,10 @@ static int vivi_open(struct file *file) fh->width = 640; fh->height = 480; + /* Put all controls at a sane state */ + for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) + qctl_regs[i] = vivi_qctrl[i].default_value; + /* Resets frame counters */ dev->h = 0; dev->m = 0; @@ -1192,6 +1095,7 @@ static int vivi_open(struct file *file) sizeof(struct vivi_buffer), fh); vivi_start_thread(fh); + unlock_kernel(); return 0; } @@ -1247,6 +1151,32 @@ static int vivi_close(struct file *file) return 0; } +static int vivi_release(void) +{ + struct vivi_dev *dev; + struct list_head *list; + + while (!list_empty(&vivi_devlist)) { + list = vivi_devlist.next; + list_del(list); + dev = list_entry(list, struct vivi_dev, vivi_devlist); + + if (-1 != dev->vfd->minor) { + printk(KERN_INFO "%s: unregistering /dev/video%d\n", + VIVI_MODULE_NAME, dev->vfd->num); + video_unregister_device(dev->vfd); + } else { + printk(KERN_INFO "%s: releasing /dev/video%d\n", + VIVI_MODULE_NAME, dev->vfd->num); + video_device_release(dev->vfd); + } + + kfree(dev); + } + + return 0; +} + static int vivi_mmap(struct file *file, struct vm_area_struct *vma) { struct vivi_fh *fh = file->private_data; @@ -1309,130 +1239,87 @@ static struct video_device vivi_template = { .tvnorms = V4L2_STD_525_60, .current_norm = V4L2_STD_NTSC_M, }; - /* ----------------------------------------------------------------- Initialization and module stuff ------------------------------------------------------------------*/ -static int vivi_release(void) -{ - struct vivi_dev *dev; - struct list_head *list; - - while (!list_empty(&vivi_devlist)) { - list = vivi_devlist.next; - list_del(list); - dev = list_entry(list, struct vivi_dev, vivi_devlist); - - v4l2_info(&dev->v4l2_dev, "unregistering /dev/video%d\n", - dev->vfd->num); - video_unregister_device(dev->vfd); - v4l2_device_unregister(&dev->v4l2_dev); - kfree(dev); - } - - return 0; -} +/* This routine allocates from 1 to n_devs virtual drivers. -static int __init vivi_create_instance(int inst) + The real maximum number of virtual drivers will depend on how many drivers + will succeed. This is limited to the maximum number of devices that + videodev supports. Since there are 64 minors for video grabbers, this is + currently the theoretical maximum limit. However, a further limit does + exist at videodev that forbids any driver to register more than 32 video + grabbers. + */ +static int __init vivi_init(void) { + int ret = -ENOMEM, i; struct vivi_dev *dev; struct video_device *vfd; - int ret, i; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), - "%s-%03d", VIVI_MODULE_NAME, inst); - ret = v4l2_device_register(NULL, &dev->v4l2_dev); - if (ret) - goto free_dev; - /* init video dma queues */ - INIT_LIST_HEAD(&dev->vidq.active); - init_waitqueue_head(&dev->vidq.wq); - - /* initialize locks */ - spin_lock_init(&dev->slock); - mutex_init(&dev->mutex); - - ret = -ENOMEM; - vfd = video_device_alloc(); - if (!vfd) - goto unreg_dev; - - *vfd = vivi_template; + if (n_devs <= 0) + n_devs = 1; - ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); - if (ret < 0) - goto rel_vdev; + for (i = 0; i < n_devs; i++) { + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + break; - video_set_drvdata(vfd, dev); + /* init video dma queues */ + INIT_LIST_HEAD(&dev->vidq.active); + init_waitqueue_head(&dev->vidq.wq); - /* Set all controls to their default value. */ - for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) - dev->qctl_regs[i] = vivi_qctrl[i].default_value; + /* initialize locks */ + spin_lock_init(&dev->slock); + mutex_init(&dev->mutex); - /* Now that everything is fine, let's add it to device list */ - list_add_tail(&dev->vivi_devlist, &vivi_devlist); + vfd = video_device_alloc(); + if (!vfd) { + kfree(dev); + break; + } - snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", - vivi_template.name, vfd->num); + *vfd = vivi_template; - if (video_nr >= 0) - video_nr++; + ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); + if (ret < 0) { + video_device_release(vfd); + kfree(dev); - dev->vfd = vfd; - v4l2_info(&dev->v4l2_dev, "V4L2 device registered as /dev/video%d\n", - vfd->num); - return 0; + /* If some registers succeeded, keep driver */ + if (i) + ret = 0; -rel_vdev: - video_device_release(vfd); -unreg_dev: - v4l2_device_unregister(&dev->v4l2_dev); -free_dev: - kfree(dev); - return ret; -} + break; + } -/* This routine allocates from 1 to n_devs virtual drivers. + /* Now that everything is fine, let's add it to device list */ + list_add_tail(&dev->vivi_devlist, &vivi_devlist); - The real maximum number of virtual drivers will depend on how many drivers - will succeed. This is limited to the maximum number of devices that - videodev supports, which is equal to VIDEO_NUM_DEVICES. - */ -static int __init vivi_init(void) -{ - int ret = 0, i; + snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", + vivi_template.name, vfd->minor); - if (n_devs <= 0) - n_devs = 1; + if (video_nr >= 0) + video_nr++; - for (i = 0; i < n_devs; i++) { - ret = vivi_create_instance(i); - if (ret) { - /* If some instantiations succeeded, keep driver */ - if (i) - ret = 0; - break; - } + dev->vfd = vfd; + printk(KERN_INFO "%s: V4L2 device registered as /dev/video%d\n", + VIVI_MODULE_NAME, vfd->num); } if (ret < 0) { + vivi_release(); printk(KERN_INFO "Error %d while loading vivi driver\n", ret); - return ret; - } - - printk(KERN_INFO "Video Technology Magazine Virtual Video " + } else { + printk(KERN_INFO "Video Technology Magazine Virtual Video " "Capture Board ver %u.%u.%u successfully loaded.\n", (VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF, VIVI_VERSION & 0xFF); - /* n_devs will reflect the actual number of allocated devices */ - n_devs = i; + /* n_devs will reflect the actual number of allocated devices */ + n_devs = i; + } return ret; } @@ -1444,3 +1331,19 @@ static void __exit vivi_exit(void) module_init(vivi_init); module_exit(vivi_exit); + +MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board"); +MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); +MODULE_LICENSE("Dual BSD/GPL"); + +module_param(video_nr, uint, 0444); +MODULE_PARM_DESC(video_nr, "video iminor start number"); + +module_param(n_devs, uint, 0444); +MODULE_PARM_DESC(n_devs, "number of video devices to create"); + +module_param_named(debug, vivi_template.debug, int, 0444); +MODULE_PARM_DESC(debug, "activates debug info"); + +module_param(vid_limit, int, 0644); +MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); diff --git a/trunk/drivers/media/video/vp27smpx.c b/trunk/drivers/media/video/vp27smpx.c index 42e23a4fa607..5d73f66d9f55 100644 --- a/trunk/drivers/media/video/vp27smpx.c +++ b/trunk/drivers/media/video/vp27smpx.c @@ -129,6 +129,11 @@ static int vp27smpx_log_status(struct v4l2_subdev *sd) return 0; } +static int vp27smpx_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops vp27smpx_core_ops = { @@ -201,6 +206,8 @@ MODULE_DEVICE_TABLE(i2c, vp27smpx_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "vp27smpx", + .driverid = I2C_DRIVERID_VP27SMPX, + .command = vp27smpx_command, .probe = vp27smpx_probe, .remove = vp27smpx_remove, .id_table = vp27smpx_id, diff --git a/trunk/drivers/media/video/vpx3220.c b/trunk/drivers/media/video/vpx3220.c index 2fa7e8bb5746..67aa0db4b81a 100644 --- a/trunk/drivers/media/video/vpx3220.c +++ b/trunk/drivers/media/video/vpx3220.c @@ -24,10 +24,10 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver"); MODULE_AUTHOR("Laurent Pinchart"); @@ -37,17 +37,14 @@ static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); - #define VPX_TIMEOUT_COUNT 10 /* ----------------------------------------------------------------------- */ struct vpx3220 { - struct v4l2_subdev sd; unsigned char reg[255]; - v4l2_std_id norm; - int ident; + int norm; int input; int enable; int bright; @@ -56,38 +53,30 @@ struct vpx3220 { int sat; }; -static inline struct vpx3220 *to_vpx3220(struct v4l2_subdev *sd) -{ - return container_of(sd, struct vpx3220, sd); -} - static char *inputs[] = { "internal", "composite", "svideo" }; /* ----------------------------------------------------------------------- */ -static inline int vpx3220_write(struct v4l2_subdev *sd, u8 reg, u8 value) +static inline int vpx3220_write(struct i2c_client *client, u8 reg, u8 value) { - struct i2c_client *client = v4l2_get_subdevdata(sd); struct vpx3220 *decoder = i2c_get_clientdata(client); decoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } -static inline int vpx3220_read(struct v4l2_subdev *sd, u8 reg) +static inline int vpx3220_read(struct i2c_client *client, u8 reg) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - return i2c_smbus_read_byte_data(client, reg); } -static int vpx3220_fp_status(struct v4l2_subdev *sd) +static int vpx3220_fp_status(struct i2c_client *client) { unsigned char status; unsigned int i; for (i = 0; i < VPX_TIMEOUT_COUNT; i++) { - status = vpx3220_read(sd, 0x29); + status = vpx3220_read(client, 0x29); if (!(status & 4)) return 0; @@ -101,60 +90,57 @@ static int vpx3220_fp_status(struct v4l2_subdev *sd) return -1; } -static int vpx3220_fp_write(struct v4l2_subdev *sd, u8 fpaddr, u16 data) +static int vpx3220_fp_write(struct i2c_client *client, u8 fpaddr, u16 data) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - /* Write the 16-bit address to the FPWR register */ if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) { - v4l2_dbg(1, debug, sd, "%s: failed\n", __func__); + v4l_dbg(1, debug, client, "%s: failed\n", __func__); return -1; } - if (vpx3220_fp_status(sd) < 0) + if (vpx3220_fp_status(client) < 0) return -1; /* Write the 16-bit data to the FPDAT register */ if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) { - v4l2_dbg(1, debug, sd, "%s: failed\n", __func__); + v4l_dbg(1, debug, client, "%s: failed\n", __func__); return -1; } return 0; } -static u16 vpx3220_fp_read(struct v4l2_subdev *sd, u16 fpaddr) +static u16 vpx3220_fp_read(struct i2c_client *client, u16 fpaddr) { - struct i2c_client *client = v4l2_get_subdevdata(sd); s16 data; /* Write the 16-bit address to the FPRD register */ if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) { - v4l2_dbg(1, debug, sd, "%s: failed\n", __func__); + v4l_dbg(1, debug, client, "%s: failed\n", __func__); return -1; } - if (vpx3220_fp_status(sd) < 0) + if (vpx3220_fp_status(client) < 0) return -1; /* Read the 16-bit data from the FPDAT register */ data = i2c_smbus_read_word_data(client, 0x28); if (data == -1) { - v4l2_dbg(1, debug, sd, "%s: failed\n", __func__); + v4l_dbg(1, debug, client, "%s: failed\n", __func__); return -1; } return swab16(data); } -static int vpx3220_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len) +static int vpx3220_write_block(struct i2c_client *client, const u8 *data, unsigned int len) { u8 reg; int ret = -1; while (len >= 2) { reg = *data++; - ret = vpx3220_write(sd, reg, *data++); + ret = vpx3220_write(client, reg, *data++); if (ret < 0) break; len -= 2; @@ -163,7 +149,7 @@ static int vpx3220_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned return ret; } -static int vpx3220_write_fp_block(struct v4l2_subdev *sd, +static int vpx3220_write_fp_block(struct i2c_client *client, const u16 *data, unsigned int len) { u8 reg; @@ -171,7 +157,7 @@ static int vpx3220_write_fp_block(struct v4l2_subdev *sd, while (len > 1) { reg = *data++; - ret |= vpx3220_fp_write(sd, reg, *data++); + ret |= vpx3220_fp_write(client, reg, *data++); len -= 2; } @@ -273,277 +259,276 @@ static const unsigned short init_fp[] = { 0x4b, 0x298, /* PLL gain */ }; - -static int vpx3220_init(struct v4l2_subdev *sd, u32 val) +static void vpx3220_dump_i2c(struct i2c_client *client) { - struct vpx3220 *decoder = to_vpx3220(sd); - - vpx3220_write_block(sd, init_common, sizeof(init_common)); - vpx3220_write_fp_block(sd, init_fp, sizeof(init_fp) >> 1); - if (decoder->norm & V4L2_STD_NTSC) - vpx3220_write_fp_block(sd, init_ntsc, sizeof(init_ntsc) >> 1); - else if (decoder->norm & V4L2_STD_PAL) - vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1); - else if (decoder->norm & V4L2_STD_SECAM) - vpx3220_write_fp_block(sd, init_secam, sizeof(init_secam) >> 1); - else - vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1); - return 0; + int len = sizeof(init_common); + const unsigned char *data = init_common; + + while (len > 1) { + v4l_dbg(1, debug, client, "i2c reg 0x%02x data 0x%02x\n", + *data, vpx3220_read(client, *data)); + data += 2; + len -= 2; + } } -static int vpx3220_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd) +static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) { - int res = V4L2_IN_ST_NO_SIGNAL, status; - v4l2_std_id std = 0; - - status = vpx3220_fp_read(sd, 0x0f3); - - v4l2_dbg(1, debug, sd, "status: 0x%04x\n", status); - - if (status < 0) - return status; - - if ((status & 0x20) == 0) { - res = 0; + struct vpx3220 *decoder = i2c_get_clientdata(client); - switch (status & 0x18) { - case 0x00: - case 0x10: - case 0x14: - case 0x18: - std = V4L2_STD_PAL; + switch (cmd) { + case 0: + { + vpx3220_write_block(client, init_common, + sizeof(init_common)); + vpx3220_write_fp_block(client, init_fp, + sizeof(init_fp) >> 1); + switch (decoder->norm) { + case VIDEO_MODE_NTSC: + vpx3220_write_fp_block(client, init_ntsc, + sizeof(init_ntsc) >> 1); break; - case 0x08: - std = V4L2_STD_SECAM; + case VIDEO_MODE_PAL: + vpx3220_write_fp_block(client, init_pal, + sizeof(init_pal) >> 1); break; - - case 0x04: - case 0x0c: - case 0x1c: - std = V4L2_STD_NTSC; + case VIDEO_MODE_SECAM: + vpx3220_write_fp_block(client, init_secam, + sizeof(init_secam) >> 1); + break; + default: + vpx3220_write_fp_block(client, init_pal, + sizeof(init_pal) >> 1); break; } + break; } - if (pstd) - *pstd = std; - if (pstatus) - *pstatus = status; - return 0; -} -static int vpx3220_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) -{ - v4l2_dbg(1, debug, sd, "querystd\n"); - return vpx3220_status(sd, NULL, std); -} + case DECODER_DUMP: + { + vpx3220_dump_i2c(client); + break; + } -static int vpx3220_g_input_status(struct v4l2_subdev *sd, u32 *status) -{ - v4l2_dbg(1, debug, sd, "g_input_status\n"); - return vpx3220_status(sd, status, NULL); -} + case DECODER_GET_CAPABILITIES: + { + struct video_decoder_capability *cap = arg; -static int vpx3220_s_std(struct v4l2_subdev *sd, v4l2_std_id std) -{ - struct vpx3220 *decoder = to_vpx3220(sd); - int temp_input; - - /* Here we back up the input selection because it gets - overwritten when we fill the registers with the - choosen video norm */ - temp_input = vpx3220_fp_read(sd, 0xf2); - - v4l2_dbg(1, debug, sd, "s_std %llx\n", (unsigned long long)std); - if (std & V4L2_STD_NTSC) { - vpx3220_write_fp_block(sd, init_ntsc, sizeof(init_ntsc) >> 1); - v4l2_dbg(1, debug, sd, "norm switched to NTSC\n"); - } else if (std & V4L2_STD_PAL) { - vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1); - v4l2_dbg(1, debug, sd, "norm switched to PAL\n"); - } else if (std & V4L2_STD_SECAM) { - vpx3220_write_fp_block(sd, init_secam, sizeof(init_secam) >> 1); - v4l2_dbg(1, debug, sd, "norm switched to SECAM\n"); - } else { - return -EINVAL; + v4l_dbg(1, debug, client, "DECODER_GET_CAPABILITIES\n"); + + cap->flags = VIDEO_DECODER_PAL | + VIDEO_DECODER_NTSC | + VIDEO_DECODER_SECAM | + VIDEO_DECODER_AUTO | + VIDEO_DECODER_CCIR; + cap->inputs = 3; + cap->outputs = 1; + break; } - decoder->norm = std; + case DECODER_GET_STATUS: + { + int res = 0, status; - /* And here we set the backed up video input again */ - vpx3220_fp_write(sd, 0xf2, temp_input | 0x0010); - udelay(10); - return 0; -} + v4l_dbg(1, debug, client, "DECODER_GET_STATUS\n"); -static int vpx3220_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) -{ - int data; + status = vpx3220_fp_read(client, 0x0f3); - /* RJ: route->input = 0: ST8 (PCTV) input - route->input = 1: COMPOSITE input - route->input = 2: SVHS input */ + v4l_dbg(1, debug, client, "status: 0x%04x\n", status); - const int input[3][2] = { - {0x0c, 0}, - {0x0d, 0}, - {0x0e, 1} - }; + if (status < 0) + return status; - if (route->input < 0 || route->input > 2) - return -EINVAL; + if ((status & 0x20) == 0) { + res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR; - v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[route->input]); + switch (status & 0x18) { + case 0x00: + case 0x10: + case 0x14: + case 0x18: + res |= DECODER_STATUS_PAL; + break; - vpx3220_write(sd, 0x33, input[route->input][0]); + case 0x08: + res |= DECODER_STATUS_SECAM; + break; - data = vpx3220_fp_read(sd, 0xf2) & ~(0x0020); - if (data < 0) - return data; - /* 0x0010 is required to latch the setting */ - vpx3220_fp_write(sd, 0xf2, - data | (input[route->input][1] << 5) | 0x0010); + case 0x04: + case 0x0c: + case 0x1c: + res |= DECODER_STATUS_NTSC; + break; + } + } - udelay(10); - return 0; -} + *(int *) arg = res; + break; + } -static int vpx3220_s_stream(struct v4l2_subdev *sd, int enable) -{ - v4l2_dbg(1, debug, sd, "s_stream %s\n", enable ? "on" : "off"); + case DECODER_SET_NORM: + { + int *iarg = arg, data; + int temp_input; + + /* Here we back up the input selection because it gets + overwritten when we fill the registers with the + choosen video norm */ + temp_input = vpx3220_fp_read(client, 0xf2); + + v4l_dbg(1, debug, client, "DECODER_SET_NORM %d\n", *iarg); + switch (*iarg) { + case VIDEO_MODE_NTSC: + vpx3220_write_fp_block(client, init_ntsc, + sizeof(init_ntsc) >> 1); + v4l_dbg(1, debug, client, "norm switched to NTSC\n"); + break; - vpx3220_write(sd, 0xf2, (enable ? 0x1b : 0x00)); - return 0; -} + case VIDEO_MODE_PAL: + vpx3220_write_fp_block(client, init_pal, + sizeof(init_pal) >> 1); + v4l_dbg(1, debug, client, "norm switched to PAL\n"); + break; -static int vpx3220_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) -{ - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); - break; + case VIDEO_MODE_SECAM: + vpx3220_write_fp_block(client, init_secam, + sizeof(init_secam) >> 1); + v4l_dbg(1, debug, client, "norm switched to SECAM\n"); + break; - case V4L2_CID_CONTRAST: - v4l2_ctrl_query_fill(qc, 0, 63, 1, 32); - break; + case VIDEO_MODE_AUTO: + /* FIXME This is only preliminary support */ + data = vpx3220_fp_read(client, 0xf2) & 0x20; + vpx3220_fp_write(client, 0xf2, 0x00c0 | data); + v4l_dbg(1, debug, client, "norm switched to AUTO\n"); + break; - case V4L2_CID_SATURATION: - v4l2_ctrl_query_fill(qc, 0, 4095, 1, 2048); - break; + default: + return -EINVAL; + } + decoder->norm = *iarg; - case V4L2_CID_HUE: - v4l2_ctrl_query_fill(qc, -512, 511, 1, 0); + /* And here we set the backed up video input again */ + vpx3220_fp_write(client, 0xf2, temp_input | 0x0010); + udelay(10); break; - - default: - return -EINVAL; } - return 0; -} -static int vpx3220_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct vpx3220 *decoder = to_vpx3220(sd); + case DECODER_SET_INPUT: + { + int *iarg = arg, data; - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = decoder->bright; - break; - case V4L2_CID_CONTRAST: - ctrl->value = decoder->contrast; + /* RJ: *iarg = 0: ST8 (PCTV) input + *iarg = 1: COMPOSITE input + *iarg = 2: SVHS input */ + + const int input[3][2] = { + {0x0c, 0}, + {0x0d, 0}, + {0x0e, 1} + }; + + if (*iarg < 0 || *iarg > 2) + return -EINVAL; + + v4l_dbg(1, debug, client, "input switched to %s\n", inputs[*iarg]); + + vpx3220_write(client, 0x33, input[*iarg][0]); + + data = vpx3220_fp_read(client, 0xf2) & ~(0x0020); + if (data < 0) + return data; + /* 0x0010 is required to latch the setting */ + vpx3220_fp_write(client, 0xf2, + data | (input[*iarg][1] << 5) | 0x0010); + + udelay(10); break; - case V4L2_CID_SATURATION: - ctrl->value = decoder->sat; + } + + case DECODER_SET_OUTPUT: + { + int *iarg = arg; + + /* not much choice of outputs */ + if (*iarg != 0) { + return -EINVAL; + } break; - case V4L2_CID_HUE: - ctrl->value = decoder->hue; + } + + case DECODER_ENABLE_OUTPUT: + { + int *iarg = arg; + + v4l_dbg(1, debug, client, "DECODER_ENABLE_OUTPUT %d\n", *iarg); + + vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00)); break; - default: - return -EINVAL; } - return 0; -} -static int vpx3220_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct vpx3220 *decoder = to_vpx3220(sd); + case DECODER_SET_PICTURE: + { + struct video_picture *pic = arg; - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - if (decoder->bright != ctrl->value) { - decoder->bright = ctrl->value; - vpx3220_write(sd, 0xe6, decoder->bright); + if (decoder->bright != pic->brightness) { + /* We want -128 to 128 we get 0-65535 */ + decoder->bright = pic->brightness; + vpx3220_write(client, 0xe6, + (decoder->bright - 32768) >> 8); } - break; - case V4L2_CID_CONTRAST: - if (decoder->contrast != ctrl->value) { + if (decoder->contrast != pic->contrast) { + /* We want 0 to 64 we get 0-65535 */ /* Bit 7 and 8 is for noise shaping */ - decoder->contrast = ctrl->value; - vpx3220_write(sd, 0xe7, decoder->contrast + 192); + decoder->contrast = pic->contrast; + vpx3220_write(client, 0xe7, + (decoder->contrast >> 10) + 192); } - break; - case V4L2_CID_SATURATION: - if (decoder->sat != ctrl->value) { - decoder->sat = ctrl->value; - vpx3220_fp_write(sd, 0xa0, decoder->sat); + if (decoder->sat != pic->colour) { + /* We want 0 to 4096 we get 0-65535 */ + decoder->sat = pic->colour; + vpx3220_fp_write(client, 0xa0, + decoder->sat >> 4); } - break; - case V4L2_CID_HUE: - if (decoder->hue != ctrl->value) { - decoder->hue = ctrl->value; - vpx3220_fp_write(sd, 0x1c, decoder->hue); + if (decoder->hue != pic->hue) { + /* We want -512 to 512 we get 0-65535 */ + decoder->hue = pic->hue; + vpx3220_fp_write(client, 0x1c, + ((decoder->hue - 32768) >> 6) & 0xFFF); } break; + } + default: return -EINVAL; } + return 0; } -static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) +static int vpx3220_init_client(struct i2c_client *client) { - struct vpx3220 *decoder = to_vpx3220(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); + vpx3220_write_block(client, init_common, sizeof(init_common)); + vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1); + /* Default to PAL */ + vpx3220_write_fp_block(client, init_pal, sizeof(init_pal) >> 1); - return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0); + return 0; } -/* ----------------------------------------------------------------------- */ - -static const struct v4l2_subdev_core_ops vpx3220_core_ops = { - .g_chip_ident = vpx3220_g_chip_ident, - .init = vpx3220_init, - .g_ctrl = vpx3220_g_ctrl, - .s_ctrl = vpx3220_s_ctrl, - .queryctrl = vpx3220_queryctrl, -}; - -static const struct v4l2_subdev_tuner_ops vpx3220_tuner_ops = { - .s_std = vpx3220_s_std, -}; - -static const struct v4l2_subdev_video_ops vpx3220_video_ops = { - .s_routing = vpx3220_s_routing, - .s_stream = vpx3220_s_stream, - .querystd = vpx3220_querystd, - .g_input_status = vpx3220_g_input_status, -}; - -static const struct v4l2_subdev_ops vpx3220_ops = { - .core = &vpx3220_core_ops, - .tuner = &vpx3220_tuner_ops, - .video = &vpx3220_video_ops, -}; - /* ----------------------------------------------------------------------- * Client management code */ +static unsigned short normal_i2c[] = { 0x86 >> 1, 0x8e >> 1, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; + static int vpx3220_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct vpx3220 *decoder; - struct v4l2_subdev *sd; const char *name = NULL; u8 ver; u16 pn; @@ -556,20 +541,18 @@ static int vpx3220_probe(struct i2c_client *client, decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL); if (decoder == NULL) return -ENOMEM; - sd = &decoder->sd; - v4l2_i2c_subdev_init(sd, client, &vpx3220_ops); - decoder->norm = V4L2_STD_PAL; + decoder->norm = VIDEO_MODE_PAL; decoder->input = 0; decoder->enable = 1; decoder->bright = 32768; decoder->contrast = 32768; decoder->hue = 32768; decoder->sat = 32768; + i2c_set_clientdata(client, decoder); ver = i2c_smbus_read_byte_data(client, 0x00); pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) + i2c_smbus_read_byte_data(client, 0x01); - decoder->ident = V4L2_IDENT_VPX3220A; if (ver == 0xec) { switch (pn) { case 0x4680: @@ -577,34 +560,26 @@ static int vpx3220_probe(struct i2c_client *client, break; case 0x4260: name = "vpx3216b"; - decoder->ident = V4L2_IDENT_VPX3216B; break; case 0x4280: name = "vpx3214c"; - decoder->ident = V4L2_IDENT_VPX3214C; break; } } if (name) - v4l2_info(sd, "%s found @ 0x%x (%s)\n", name, + v4l_info(client, "%s found @ 0x%x (%s)\n", name, client->addr << 1, client->adapter->name); else - v4l2_info(sd, "chip (%02x:%04x) found @ 0x%x (%s)\n", + v4l_info(client, "chip (%02x:%04x) found @ 0x%x (%s)\n", ver, pn, client->addr << 1, client->adapter->name); - vpx3220_write_block(sd, init_common, sizeof(init_common)); - vpx3220_write_fp_block(sd, init_fp, sizeof(init_fp) >> 1); - /* Default to PAL */ - vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1); + vpx3220_init_client(client); return 0; } static int vpx3220_remove(struct i2c_client *client) { - struct v4l2_subdev *sd = i2c_get_clientdata(client); - - v4l2_device_unregister_subdev(sd); - kfree(to_vpx3220(sd)); + kfree(i2c_get_clientdata(client)); return 0; } @@ -618,6 +593,8 @@ MODULE_DEVICE_TABLE(i2c, vpx3220_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "vpx3220", + .driverid = I2C_DRIVERID_VPX3220, + .command = vpx3220_command, .probe = vpx3220_probe, .remove = vpx3220_remove, .id_table = vpx3220_id, diff --git a/trunk/drivers/media/video/w9966.c b/trunk/drivers/media/video/w9966.c index dcade619cbd8..038ff32b01b8 100644 --- a/trunk/drivers/media/video/w9966.c +++ b/trunk/drivers/media/video/w9966.c @@ -57,7 +57,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/drivers/media/video/w9968cf.c b/trunk/drivers/media/video/w9968cf.c index 3b08bc4af909..105a832531f2 100644 --- a/trunk/drivers/media/video/w9968cf.c +++ b/trunk/drivers/media/video/w9968cf.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include "w9968cf.h" @@ -69,6 +68,7 @@ MODULE_VERSION(W9968CF_MODULE_VERSION); MODULE_LICENSE(W9968CF_MODULE_LICENSE); MODULE_SUPPORTED_DEVICE("Video"); +static int ovmod_load = W9968CF_OVMOD_LOAD; static unsigned short simcams = W9968CF_SIMCAMS; static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/ static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] = @@ -111,6 +111,9 @@ static int specific_debug = W9968CF_SPECIFIC_DEBUG; static unsigned int param_nv[24]; /* number of values per parameter */ +#ifdef CONFIG_MODULES +module_param(ovmod_load, bool, 0644); +#endif module_param(simcams, ushort, 0644); module_param_array(video_nr, short, ¶m_nv[0], 0444); module_param_array(packet_size, uint, ¶m_nv[1], 0444); @@ -141,6 +144,18 @@ module_param(debug, ushort, 0644); module_param(specific_debug, bool, 0644); #endif +#ifdef CONFIG_MODULES +MODULE_PARM_DESC(ovmod_load, + "\n<0|1> Automatic 'ovcamchip' module loading." + "\n0 disabled, 1 enabled." + "\nIf enabled,'insmod' searches for the required 'ovcamchip'" + "\nmodule in the system, according to its configuration, and" + "\nattempts to load that module automatically. This action is" + "\nperformed once as soon as the 'w9968cf' module is loaded" + "\ninto memory." + "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"." + "\n"); +#endif MODULE_PARM_DESC(simcams, "\n Number of cameras allowed to stream simultaneously." "\nn may vary from 0 to " @@ -428,6 +443,8 @@ static int w9968cf_i2c_smbus_xfer(struct i2c_adapter*, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data*); static u32 w9968cf_i2c_func(struct i2c_adapter*); +static int w9968cf_i2c_attach_inform(struct i2c_client*); +static int w9968cf_i2c_detach_inform(struct i2c_client*); /* Memory management */ static void* rvmalloc(unsigned long size); @@ -1426,11 +1443,19 @@ w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data) { - struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter); - struct w9968cf_device *cam = to_cam(v4l2_dev); + struct w9968cf_device* cam = i2c_get_adapdata(adapter); u8 i; int err = 0; + switch (addr) { + case OV6xx0_SID: + case OV7xx0_SID: + break; + default: + DBG(4, "Rejected slave ID 0x%04X", addr) + return -EINVAL; + } + if (size == I2C_SMBUS_BYTE) { /* Why addr <<= 1? See OVXXX0_SID defines in ovcamchip.h */ addr <<= 1; @@ -1438,17 +1463,8 @@ w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, if (read_write == I2C_SMBUS_WRITE) err = w9968cf_i2c_adap_write_byte(cam, addr, command); else if (read_write == I2C_SMBUS_READ) - for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) { - err = w9968cf_i2c_adap_read_byte(cam, addr, - &data->byte); - if (err) { - if (w9968cf_smbus_refresh_bus(cam)) { - err = -EIO; - break; - } - } else - break; - } + err = w9968cf_i2c_adap_read_byte(cam,addr,&data->byte); + } else if (size == I2C_SMBUS_BYTE_DATA) { addr <<= 1; @@ -1475,6 +1491,7 @@ w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, DBG(4, "Unsupported I2C transfer mode (%d)", size) return -EINVAL; } + return err; } @@ -1487,6 +1504,44 @@ static u32 w9968cf_i2c_func(struct i2c_adapter* adap) } +static int w9968cf_i2c_attach_inform(struct i2c_client* client) +{ + struct w9968cf_device* cam = i2c_get_adapdata(client->adapter); + int id = client->driver->id, err = 0; + + if (id == I2C_DRIVERID_OVCAMCHIP) { + cam->sensor_client = client; + err = w9968cf_sensor_init(cam); + if (err) { + cam->sensor_client = NULL; + return err; + } + } else { + DBG(4, "Rejected client [%s] with driver [%s]", + client->name, client->driver->driver.name) + return -EINVAL; + } + + DBG(5, "I2C attach client [%s] with driver [%s]", + client->name, client->driver->driver.name) + + return 0; +} + + +static int w9968cf_i2c_detach_inform(struct i2c_client* client) +{ + struct w9968cf_device* cam = i2c_get_adapdata(client->adapter); + + if (cam->sensor_client == client) + cam->sensor_client = NULL; + + DBG(5, "I2C detach client [%s]", client->name) + + return 0; +} + + static int w9968cf_i2c_init(struct w9968cf_device* cam) { int err = 0; @@ -1499,13 +1554,15 @@ static int w9968cf_i2c_init(struct w9968cf_device* cam) static struct i2c_adapter adap = { .id = I2C_HW_SMBUS_W9968CF, .owner = THIS_MODULE, + .client_register = w9968cf_i2c_attach_inform, + .client_unregister = w9968cf_i2c_detach_inform, .algo = &algo, }; memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter)); strcpy(cam->i2c_adapter.name, "w9968cf"); cam->i2c_adapter.dev.parent = &cam->usbdev->dev; - i2c_set_adapdata(&cam->i2c_adapter, &cam->v4l2_dev); + i2c_set_adapdata(&cam->i2c_adapter, cam); DBG(6, "Registering I2C adapter with kernel...") @@ -2108,9 +2165,13 @@ w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val) static int w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg) { - int rc; + struct i2c_client* c = cam->sensor_client; + int rc = 0; + + if (!c || !c->driver || !c->driver->command) + return -EINVAL; - rc = v4l2_subdev_call(cam->sensor_sd, core, ioctl, cmd, arg); + rc = c->driver->command(c, cmd, arg); /* The I2C driver returns -EPERM on non-supported controls */ return (rc < 0 && rc != -EPERM) ? rc : 0; } @@ -2285,7 +2346,7 @@ static int w9968cf_sensor_init(struct w9968cf_device* cam) goto error; /* NOTE: Make sure width and height are a multiple of 16 */ - switch (v4l2_i2c_subdev_addr(cam->sensor_sd)) { + switch (cam->sensor_client->addr) { case OV6xx0_SID: cam->maxwidth = 352; cam->maxheight = 288; @@ -2590,7 +2651,6 @@ static void w9968cf_release_resources(struct w9968cf_device* cam) w9968cf_deallocate_memory(cam); kfree(cam->control_buffer); kfree(cam->data_buffer); - v4l2_device_unregister(&cam->v4l2_dev); mutex_unlock(&w9968cf_devlist_mutex); } @@ -3420,11 +3480,6 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) struct list_head* ptr; u8 sc = 0; /* number of simultaneous cameras */ static unsigned short dev_nr; /* 0 - we are handling device number n */ - static unsigned short addrs[] = { - OV7xx0_SID, - OV6xx0_SID, - I2C_CLIENT_END - }; if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[0].idVendor && le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct) @@ -3440,14 +3495,12 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) if (!cam) return -ENOMEM; - err = v4l2_device_register(&udev->dev, &cam->v4l2_dev); - if (err) - goto fail0; - mutex_init(&cam->dev_mutex); mutex_lock(&cam->dev_mutex); cam->usbdev = udev; + /* NOTE: a local copy is used to avoid possible race conditions */ + memcpy(&cam->dev, &udev->dev, sizeof(struct device)); DBG(2, "%s detected", symbolic(camlist, mod_id)) @@ -3496,7 +3549,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; video_set_drvdata(cam->v4ldev, cam); - cam->v4ldev->v4l2_dev = &cam->v4l2_dev; + cam->v4ldev->parent = &cam->dev; err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, video_nr[dev_nr]); @@ -3523,13 +3576,9 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) w9968cf_turn_on_led(cam); w9968cf_i2c_init(cam); - cam->sensor_sd = v4l2_i2c_new_probed_subdev(&cam->i2c_adapter, - "ovcamchip", "ovcamchip", addrs); usb_set_intfdata(intf, cam); mutex_unlock(&cam->dev_mutex); - - err = w9968cf_sensor_init(cam); return 0; fail: /* Free unused memory */ @@ -3538,8 +3587,6 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) if (cam->v4ldev) video_device_release(cam->v4ldev); mutex_unlock(&cam->dev_mutex); - v4l2_device_unregister(&cam->v4l2_dev); -fail0: kfree(cam); return err; } @@ -3550,16 +3597,15 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf) struct w9968cf_device* cam = (struct w9968cf_device*)usb_get_intfdata(intf); + down_write(&w9968cf_disconnect); + if (cam) { - down_write(&w9968cf_disconnect); /* Prevent concurrent accesses to data */ mutex_lock(&cam->dev_mutex); cam->disconnected = 1; - DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id)); - - v4l2_device_disconnect(&cam->v4l2_dev); + DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id)) wake_up_interruptible_all(&cam->open); @@ -3575,12 +3621,12 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf) w9968cf_release_resources(cam); mutex_unlock(&cam->dev_mutex); - up_write(&w9968cf_disconnect); - if (!cam->users) { + if (!cam->users) kfree(cam); - } } + + up_write(&w9968cf_disconnect); } @@ -3604,6 +3650,9 @@ static int __init w9968cf_module_init(void) KDBG(2, W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION) KDBG(3, W9968CF_MODULE_AUTHOR) + if (ovmod_load) + request_module("ovcamchip"); + if ((err = usb_register(&w9968cf_usb_driver))) return err; diff --git a/trunk/drivers/media/video/w9968cf.h b/trunk/drivers/media/video/w9968cf.h index fdfc6a4e1c8f..30032e15e23c 100644 --- a/trunk/drivers/media/video/w9968cf.h +++ b/trunk/drivers/media/video/w9968cf.h @@ -33,7 +33,6 @@ #include #include -#include #include #include "w9968cf_vpp.h" @@ -43,6 +42,7 @@ * Default values * ****************************************************************************/ +#define W9968CF_OVMOD_LOAD 1 /* automatic 'ovcamchip' module loading */ #define W9968CF_VPPMOD_LOAD 1 /* automatic 'w9968cf-vpp' module loading */ /* Comment/uncomment the following line to enable/disable debugging messages */ @@ -195,9 +195,10 @@ enum w9968cf_vpp_flag { /* Main device driver structure */ struct w9968cf_device { + struct device dev; /* device structure */ + enum w9968cf_model_id id; /* private device identifier */ - struct v4l2_device v4l2_dev; struct video_device* v4ldev; /* -> V4L structure */ struct list_head v4llist; /* entry of the list of V4L cameras */ @@ -264,7 +265,7 @@ struct w9968cf_device { /* I2C interface to kernel */ struct i2c_adapter i2c_adapter; - struct v4l2_subdev *sensor_sd; + struct i2c_client* sensor_client; /* Locks */ struct mutex dev_mutex, /* for probe, disconnect,open and close */ @@ -276,11 +277,6 @@ struct w9968cf_device { char command[16]; /* name of the program holding the device */ }; -static inline struct w9968cf_device *to_cam(struct v4l2_device *v4l2_dev) -{ - return container_of(v4l2_dev, struct w9968cf_device, v4l2_dev); -} - /**************************************************************************** * Macros for debugging * @@ -295,14 +291,14 @@ static inline struct w9968cf_device *to_cam(struct v4l2_device *v4l2_dev) if ( ((specific_debug) && (debug == (level))) || \ ((!specific_debug) && (debug >= (level))) ) { \ if ((level) == 1) \ - v4l2_err(&cam->v4l2_dev, fmt "\n", ## args); \ + dev_err(&cam->dev, fmt "\n", ## args); \ else if ((level) == 2 || (level) == 3) \ - v4l2_info(&cam->v4l2_dev, fmt "\n", ## args); \ + dev_info(&cam->dev, fmt "\n", ## args); \ else if ((level) == 4) \ - v4l2_warn(&cam->v4l2_dev, fmt "\n", ## args); \ + dev_warn(&cam->dev, fmt "\n", ## args); \ else if ((level) >= 5) \ - v4l2_info(&cam->v4l2_dev, "[%s:%d] " fmt "\n", \ - __func__, __LINE__ , ## args); \ + dev_info(&cam->dev, "[%s:%d] " fmt "\n", \ + __func__, __LINE__ , ## args); \ } \ } /* For generic kernel (not device specific) messages */ @@ -325,7 +321,7 @@ static inline struct w9968cf_device *to_cam(struct v4l2_device *v4l2_dev) #undef PDBG #define PDBG(fmt, args...) \ -v4l2_info(&cam->v4l2_dev, "[%s:%d] " fmt "\n", __func__, __LINE__ , ## args); +dev_info(&cam->dev, "[%s:%d] " fmt "\n", __func__, __LINE__ , ## args); #undef PDBGG #define PDBGG(fmt, args...) do {;} while(0); /* nothing: it's a placeholder */ diff --git a/trunk/drivers/media/video/wm8739.c b/trunk/drivers/media/video/wm8739.c index b572ce288e14..f2864d5cd180 100644 --- a/trunk/drivers/media/video/wm8739.c +++ b/trunk/drivers/media/video/wm8739.c @@ -252,6 +252,11 @@ static int wm8739_log_status(struct v4l2_subdev *sd) return 0; } +static int wm8739_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops wm8739_core_ops = { @@ -338,6 +343,8 @@ MODULE_DEVICE_TABLE(i2c, wm8739_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "wm8739", + .driverid = I2C_DRIVERID_WM8739, + .command = wm8739_command, .probe = wm8739_probe, .remove = wm8739_remove, .id_table = wm8739_id, diff --git a/trunk/drivers/media/video/wm8775.c b/trunk/drivers/media/video/wm8775.c index eddf11abe1d9..53fcd42843e0 100644 --- a/trunk/drivers/media/video/wm8775.c +++ b/trunk/drivers/media/video/wm8775.c @@ -34,12 +34,15 @@ #include #include #include -#include +#include MODULE_DESCRIPTION("wm8775 driver"); MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); MODULE_LICENSE("GPL"); +static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; /* ----------------------------------------------------------------------- */ @@ -158,6 +161,11 @@ static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *fre return 0; } +static int wm8775_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops wm8775_core_ops = { @@ -260,6 +268,8 @@ MODULE_DEVICE_TABLE(i2c, wm8775_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "wm8775", + .driverid = I2C_DRIVERID_WM8775, + .command = wm8775_command, .probe = wm8775_probe, .remove = wm8775_remove, .id_table = wm8775_id, diff --git a/trunk/drivers/media/video/zc0301/zc0301_sensor.h b/trunk/drivers/media/video/zc0301/zc0301_sensor.h index 3a408de91b9c..b0cd49c438a3 100644 --- a/trunk/drivers/media/video/zc0301/zc0301_sensor.h +++ b/trunk/drivers/media/video/zc0301/zc0301_sensor.h @@ -58,20 +58,12 @@ zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor); .idProduct = (prod), \ .bInterfaceClass = (intclass) -#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE #define ZC0301_ID_TABLE \ static const struct usb_device_id zc0301_id_table[] = { \ { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ { ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \ { } \ }; -#else -#define ZC0301_ID_TABLE \ -static const struct usb_device_id zc0301_id_table[] = { \ - { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ - { } \ -}; -#endif /*****************************************************************************/ diff --git a/trunk/drivers/media/video/zoran/Kconfig b/trunk/drivers/media/video/zoran/Kconfig index fd4120e4c104..8666e19f31a7 100644 --- a/trunk/drivers/media/video/zoran/Kconfig +++ b/trunk/drivers/media/video/zoran/Kconfig @@ -1,6 +1,6 @@ config VIDEO_ZORAN tristate "Zoran ZR36057/36067 Video For Linux" - depends on PCI && I2C_ALGOBIT && VIDEO_V4L2 && VIRT_TO_BUS + depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && VIRT_TO_BUS help Say Y for support for MJPEG capture cards based on the Zoran 36057/36067 PCI controller chipset. This includes the Iomega @@ -32,7 +32,7 @@ config VIDEO_ZORAN_ZR36060 config VIDEO_ZORAN_BUZ tristate "Iomega Buz support" depends on VIDEO_ZORAN_ZR36060 - select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO help Support for the Iomega Buz MJPEG capture/playback card. @@ -58,7 +58,7 @@ config VIDEO_ZORAN_LML33 config VIDEO_ZORAN_LML33R10 tristate "Linux Media Labs LML33R10 support" depends on VIDEO_ZORAN_ZR36060 - select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_SAA7114 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO help support for the Linux Media Labs LML33R10 MJPEG capture/playback @@ -66,7 +66,7 @@ config VIDEO_ZORAN_LML33R10 config VIDEO_ZORAN_AVS6EYES tristate "AverMedia 6 Eyes support (EXPERIMENTAL)" - depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL + depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL && VIDEO_V4L1 select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_BT866 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO diff --git a/trunk/drivers/media/video/zoran/videocodec.h b/trunk/drivers/media/video/zoran/videocodec.h index 5c27b251354e..97a3bbeda505 100644 --- a/trunk/drivers/media/video/zoran/videocodec.h +++ b/trunk/drivers/media/video/zoran/videocodec.h @@ -97,7 +97,7 @@ available) - it returns 0 if the mode is possible set_size -> this fn-ref. sets the norm and image size for compression/decompression (returns 0 on success) - the norm param is defined in videodev2.h (V4L2_STD_*) + the norm param is defined in videodev.h (VIDEO_MODE_*) additional setup may be available, too - but the codec should work with some default values even without this @@ -144,8 +144,9 @@ M zr36055[1] 0001 0000c001 00000000 (zr36050[1]) #ifndef __LINUX_VIDEOCODEC_H #define __LINUX_VIDEOCODEC_H -#include +#include +//should be in videodev.h ??? (VID_DO_....) #define CODEC_DO_COMPRESSION 0 #define CODEC_DO_EXPANSION 1 @@ -236,6 +237,10 @@ struct vfe_settings { __u32 width, height; /* Area to capture */ __u16 decimation; /* Decimation divider */ __u16 flags; /* Flags for capture */ +/* flags are the same as in struct video_capture - see videodev.h: +#define VIDEO_CAPTURE_ODD 0 +#define VIDEO_CAPTURE_EVEN 1 +*/ __u16 quality; /* quality of the video */ }; diff --git a/trunk/drivers/media/video/zoran/zoran.h b/trunk/drivers/media/video/zoran/zoran.h index afecf32f1a87..e873a916250f 100644 --- a/trunk/drivers/media/video/zoran/zoran.h +++ b/trunk/drivers/media/video/zoran/zoran.h @@ -31,8 +31,6 @@ #ifndef _BUZ_H_ #define _BUZ_H_ -#include - struct zoran_requestbuffers { unsigned long count; /* Number of buffers for MJPEG grabbing */ unsigned long size; /* Size PER BUFFER in bytes */ @@ -172,7 +170,7 @@ Private IOCTL to set up for displaying MJPEG #endif #define V4L_MASK_FRAME (V4L_MAX_FRAME - 1) -#define MAX_FRAME (BUZ_MAX_FRAME > VIDEO_MAX_FRAME ? BUZ_MAX_FRAME : VIDEO_MAX_FRAME) +#define MAX_KMALLOC_MEM (128*1024) #include "zr36057.h" @@ -242,6 +240,9 @@ enum gpcs_type { struct zoran_format { char *name; +#ifdef CONFIG_VIDEO_V4L1_COMPAT + int palette; +#endif __u32 fourcc; int colorspace; int depth; @@ -282,21 +283,21 @@ struct zoran_mapping { int count; }; -struct zoran_buffer { +struct zoran_jpg_buffer { + struct zoran_mapping *map; + __le32 *frag_tab; /* addresses of frag table */ + u32 frag_tab_bus; /* same value cached to save time in ISR */ + enum zoran_buffer_state state; /* non-zero if corresponding buffer is in use in grab queue */ + struct zoran_sync bs; /* DONE: info to return to application */ +}; + +struct zoran_v4l_buffer { struct zoran_mapping *map; - enum zoran_buffer_state state; /* state: unused/pending/dma/done */ - struct zoran_sync bs; /* DONE: info to return to application */ - union { - struct { - __le32 *frag_tab; /* addresses of frag table */ - u32 frag_tab_bus; /* same value cached to save time in ISR */ - } jpg; - struct { - char *fbuffer; /* virtual address of frame buffer */ - unsigned long fbuffer_phys;/* physical address of frame buffer */ - unsigned long fbuffer_bus;/* bus address of frame buffer */ - } v4l; - }; + char *fbuffer; /* virtual address of frame buffer */ + unsigned long fbuffer_phys; /* physical address of frame buffer */ + unsigned long fbuffer_bus; /* bus address of frame buffer */ + enum zoran_buffer_state state; /* state: unused/pending/done */ + struct zoran_sync bs; /* DONE: info to return to application */ }; enum zoran_lock_activity { @@ -306,13 +307,21 @@ enum zoran_lock_activity { }; /* buffer collections */ -struct zoran_buffer_col { +struct zoran_jpg_struct { enum zoran_lock_activity active; /* feature currently in use? */ - unsigned int num_buffers, buffer_size; - struct zoran_buffer buffer[MAX_FRAME]; /* buffers */ + struct zoran_jpg_buffer buffer[BUZ_MAX_FRAME]; /* buffers */ + int num_buffers, buffer_size; u8 allocated; /* Flag if buffers are allocated */ + u8 ready_to_be_freed; /* hack - see zoran_driver.c */ u8 need_contiguous; /* Flag if contiguous buffers are needed */ - /* only applies to jpg buffers, raw buffers are always contiguous */ +}; + +struct zoran_v4l_struct { + enum zoran_lock_activity active; /* feature currently in use? */ + struct zoran_v4l_buffer buffer[VIDEO_MAX_FRAME]; /* buffers */ + int num_buffers, buffer_size; + u8 allocated; /* Flag if buffers are allocated */ + u8 ready_to_be_freed; /* hack - see zoran_driver.c */ }; struct zoran; @@ -321,27 +330,23 @@ struct zoran; struct zoran_fh { struct zoran *zr; - enum zoran_map_mode map_mode; /* Flag which bufferset will map by next mmap() */ + enum zoran_map_mode map_mode; /* Flag which bufferset will map by next mmap() */ struct zoran_overlay_settings overlay_settings; - u32 *overlay_mask; /* overlay mask */ - enum zoran_lock_activity overlay_active;/* feature currently in use? */ - - struct zoran_buffer_col buffers; /* buffers' info */ + u32 *overlay_mask; /* overlay mask */ + enum zoran_lock_activity overlay_active; /* feature currently in use? */ struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */ + struct zoran_v4l_struct v4l_buffers; /* V4L buffers' info */ + struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */ + struct zoran_jpg_struct jpg_buffers; /* MJPEG buffers' info */ }; struct card_info { enum card_type type; char name[32]; - const char *i2c_decoder; /* i2c decoder device */ - const char *mod_decoder; /* i2c decoder module */ - const unsigned short *addrs_decoder; - const char *i2c_encoder; /* i2c encoder device */ - const char *mod_encoder; /* i2c encoder module */ - const unsigned short *addrs_encoder; + u16 i2c_decoder, i2c_encoder; /* I2C types */ u16 video_vfe, video_codec; /* videocodec types */ u16 audio_chip; /* audio type */ @@ -351,7 +356,7 @@ struct card_info { char name[32]; } input[BUZ_MAX_INPUT]; - v4l2_std_id norms; + int norms; struct tvnorm *tvn[3]; /* supported TV norms */ u32 jpeg_int; /* JPEG interrupt */ @@ -372,15 +377,14 @@ struct card_info { }; struct zoran { - struct v4l2_device v4l2_dev; struct video_device *video_dev; struct i2c_adapter i2c_adapter; /* */ struct i2c_algo_bit_data i2c_algo; /* */ u32 i2cbr; - struct v4l2_subdev *decoder; /* video decoder sub-device */ - struct v4l2_subdev *encoder; /* video encoder sub-device */ + struct i2c_client *decoder; /* video decoder i2c client */ + struct i2c_client *encoder; /* video encoder i2c client */ struct videocodec *codec; /* video codec */ struct videocodec *vfe; /* video front end */ @@ -401,15 +405,9 @@ struct zoran { spinlock_t spinlock; /* Spinlock */ /* Video for Linux parameters */ - int input; /* card's norm and input - norm=VIDEO_MODE_* */ - v4l2_std_id norm; - - /* Current buffer params */ - void *vbuf_base; - int vbuf_height, vbuf_width; - int vbuf_depth; - int vbuf_bytesperline; - + int input, norm; /* card's norm and input - norm=VIDEO_MODE_* */ + int hue, saturation, contrast, brightness; /* Current picture params */ + struct video_buffer buffer; /* Current buffer params */ struct zoran_overlay_settings overlay_settings; u32 *overlay_mask; /* overlay mask */ enum zoran_lock_activity overlay_active; /* feature currently in use? */ @@ -429,7 +427,7 @@ struct zoran { unsigned long v4l_pend_tail; unsigned long v4l_sync_tail; int v4l_pend[V4L_MAX_FRAME]; - struct zoran_buffer_col v4l_buffers; /* V4L buffers' info */ + struct zoran_v4l_struct v4l_buffers; /* V4L buffers' info */ /* Buz MJPEG parameters */ enum zoran_codec_mode codec_mode; /* status of codec */ @@ -456,7 +454,7 @@ struct zoran { int jpg_pend[BUZ_MAX_FRAME]; /* array indexed by frame number */ - struct zoran_buffer_col jpg_buffers; /* MJPEG buffers' info */ + struct zoran_jpg_struct jpg_buffers; /* MJPEG buffers' info */ /* Additional stuff for testing */ #ifdef CONFIG_PROC_FS @@ -490,11 +488,6 @@ struct zoran { wait_queue_head_t test_q; }; -static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev) -{ - return container_of(v4l2_dev, struct zoran, v4l2_dev); -} - /* There was something called _ALPHA_BUZ that used the PCI address instead of * the kernel iomapped address for btread/btwrite. */ #define btwrite(dat,adr) writel((dat), zr->zr36057_mem+(adr)) diff --git a/trunk/drivers/media/video/zoran/zoran_card.c b/trunk/drivers/media/video/zoran/zoran_card.c index f91bba435ed5..5d2f090aa0f8 100644 --- a/trunk/drivers/media/video/zoran/zoran_card.c +++ b/trunk/drivers/media/video/zoran/zoran_card.c @@ -38,7 +38,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -46,10 +47,11 @@ #include #include +#include +#include #include -#include -#include -#include + +#include #include "videocodec.h" #include "zoran.h" @@ -106,8 +108,25 @@ static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 }; module_param_array(video_nr, int, NULL, 0444); MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)"); -int v4l_nbufs = 4; -int v4l_bufsize = 864; /* Everybody should be able to work with this setting */ +/* + Number and size of grab buffers for Video 4 Linux + The vast majority of applications should not need more than 2, + the very popular BTTV driver actually does ONLY have 2. + Time sensitive applications might need more, the maximum + is VIDEO_MAX_FRAME (defined in ). + + The size is set so that the maximum possible request + can be satisfied. Decrease it, if bigphys_area alloc'd + memory is low. If you don't have the bigphys_area patch, + set it to 128 KB. Will you allow only to grab small + images with V4L, but that's better than nothing. + + v4l_bufsize has to be given in KB ! + +*/ + +int v4l_nbufs = 2; +int v4l_bufsize = 128; /* Everybody should be able to work with this setting */ module_param(v4l_nbufs, int, 0644); MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use"); module_param(v4l_bufsize, int, 0644); @@ -254,7 +273,7 @@ zr36016_write (struct videocodec *codec, static void dc10_init (struct zoran *zr) { - dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); + dprintk(3, KERN_DEBUG "%s: dc10_init()\n", ZR_DEVNAME(zr)); /* Pixel clock selection */ GPIO(zr, 4, 0); @@ -266,13 +285,13 @@ dc10_init (struct zoran *zr) static void dc10plus_init (struct zoran *zr) { - dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); + dprintk(3, KERN_DEBUG "%s: dc10plus_init()\n", ZR_DEVNAME(zr)); } static void buz_init (struct zoran *zr) { - dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); + dprintk(3, KERN_DEBUG "%s: buz_init()\n", ZR_DEVNAME(zr)); /* some stuff from Iomega */ pci_write_config_dword(zr->pci_dev, 0xfc, 0x90680f15); @@ -283,7 +302,7 @@ buz_init (struct zoran *zr) static void lml33_init (struct zoran *zr) { - dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); + dprintk(3, KERN_DEBUG "%s: lml33_init()\n", ZR_DEVNAME(zr)); GPIO(zr, 2, 1); // Set Composite input/output } @@ -312,6 +331,50 @@ avs6eyes_init (struct zoran *zr) } +static char * +i2cid_to_modulename (u16 i2c_id) +{ + char *name = NULL; + + switch (i2c_id) { + case I2C_DRIVERID_SAA7110: + name = "saa7110"; + break; + case I2C_DRIVERID_SAA7111A: + name = "saa7111"; + break; + case I2C_DRIVERID_SAA7114: + name = "saa7114"; + break; + case I2C_DRIVERID_SAA7185B: + name = "saa7185"; + break; + case I2C_DRIVERID_ADV7170: + name = "adv7170"; + break; + case I2C_DRIVERID_ADV7175: + name = "adv7175"; + break; + case I2C_DRIVERID_BT819: + name = "bt819"; + break; + case I2C_DRIVERID_BT856: + name = "bt856"; + break; + case I2C_DRIVERID_BT866: + name = "bt866"; + break; + case I2C_DRIVERID_VPX3220: + name = "vpx3220"; + break; + case I2C_DRIVERID_KS0127: + name = "ks0127"; + break; + } + + return name; +} + static char * codecid_to_modulename (u16 codecid) { @@ -362,24 +425,11 @@ static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 } static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 }; static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 }; -static const unsigned short vpx3220_addrs[] = { 0x43, 0x47, I2C_CLIENT_END }; -static const unsigned short saa7110_addrs[] = { 0x4e, 0x4f, I2C_CLIENT_END }; -static const unsigned short saa7111_addrs[] = { 0x25, 0x24, I2C_CLIENT_END }; -static const unsigned short saa7114_addrs[] = { 0x21, 0x20, I2C_CLIENT_END }; -static const unsigned short adv717x_addrs[] = { 0x6a, 0x6b, 0x2a, 0x2b, I2C_CLIENT_END }; -static const unsigned short ks0127_addrs[] = { 0x6c, 0x6d, I2C_CLIENT_END }; -static const unsigned short saa7185_addrs[] = { 0x44, I2C_CLIENT_END }; -static const unsigned short bt819_addrs[] = { 0x45, I2C_CLIENT_END }; -static const unsigned short bt856_addrs[] = { 0x44, I2C_CLIENT_END }; -static const unsigned short bt866_addrs[] = { 0x44, I2C_CLIENT_END }; - static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { .type = DC10_old, .name = "DC10(old)", - .i2c_decoder = "vpx3220a", - .mod_decoder = "vpx3220", - .addrs_decoder = vpx3220_addrs, + .i2c_decoder = I2C_DRIVERID_VPX3220, .video_codec = CODEC_TYPE_ZR36050, .video_vfe = CODEC_TYPE_ZR36016, @@ -389,7 +439,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 2, "S-Video" }, { 0, "Internal/comp" } }, - .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, + .norms = 3, .tvn = { &f50sqpixel_dc10, &f60sqpixel_dc10, @@ -407,12 +457,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = DC10_new, .name = "DC10(new)", - .i2c_decoder = "saa7110", - .mod_decoder = "saa7110", - .addrs_decoder = saa7110_addrs, - .i2c_encoder = "adv7175", - .mod_encoder = "adv7175", - .addrs_encoder = adv717x_addrs, + .i2c_decoder = I2C_DRIVERID_SAA7110, + .i2c_encoder = I2C_DRIVERID_ADV7175, .video_codec = CODEC_TYPE_ZR36060, .inputs = 3, @@ -421,7 +467,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 7, "S-Video" }, { 5, "Internal/comp" } }, - .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, + .norms = 3, .tvn = { &f50sqpixel, &f60sqpixel, @@ -438,12 +484,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = DC10plus, .name = "DC10plus", - .i2c_decoder = "saa7110", - .mod_decoder = "saa7110", - .addrs_decoder = saa7110_addrs, - .i2c_encoder = "adv7175", - .mod_encoder = "adv7175", - .addrs_encoder = adv717x_addrs, + .i2c_decoder = I2C_DRIVERID_SAA7110, + .i2c_encoder = I2C_DRIVERID_ADV7175, .video_codec = CODEC_TYPE_ZR36060, .inputs = 3, @@ -452,7 +494,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 7, "S-Video" }, { 5, "Internal/comp" } }, - .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, + .norms = 3, .tvn = { &f50sqpixel, &f60sqpixel, @@ -470,12 +512,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = DC30, .name = "DC30", - .i2c_decoder = "vpx3220a", - .mod_decoder = "vpx3220", - .addrs_decoder = vpx3220_addrs, - .i2c_encoder = "adv7175", - .mod_encoder = "adv7175", - .addrs_encoder = adv717x_addrs, + .i2c_decoder = I2C_DRIVERID_VPX3220, + .i2c_encoder = I2C_DRIVERID_ADV7175, .video_codec = CODEC_TYPE_ZR36050, .video_vfe = CODEC_TYPE_ZR36016, @@ -485,7 +523,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 2, "S-Video" }, { 0, "Internal/comp" } }, - .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, + .norms = 3, .tvn = { &f50sqpixel_dc10, &f60sqpixel_dc10, @@ -503,12 +541,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = DC30plus, .name = "DC30plus", - .i2c_decoder = "vpx3220a", - .mod_decoder = "vpx3220", - .addrs_decoder = vpx3220_addrs, - .i2c_encoder = "adv7175", - .mod_encoder = "adv7175", - .addrs_encoder = adv717x_addrs, + .i2c_decoder = I2C_DRIVERID_VPX3220, + .i2c_encoder = I2C_DRIVERID_ADV7175, .video_codec = CODEC_TYPE_ZR36050, .video_vfe = CODEC_TYPE_ZR36016, @@ -518,7 +552,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 2, "S-Video" }, { 0, "Internal/comp" } }, - .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, + .norms = 3, .tvn = { &f50sqpixel_dc10, &f60sqpixel_dc10, @@ -536,12 +570,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = LML33, .name = "LML33", - .i2c_decoder = "bt819a", - .mod_decoder = "bt819", - .addrs_decoder = bt819_addrs, - .i2c_encoder = "bt856", - .mod_encoder = "bt856", - .addrs_encoder = bt856_addrs, + .i2c_decoder = I2C_DRIVERID_BT819, + .i2c_encoder = I2C_DRIVERID_BT856, .video_codec = CODEC_TYPE_ZR36060, .inputs = 2, @@ -549,7 +579,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 0, "Composite" }, { 7, "S-Video" } }, - .norms = V4L2_STD_NTSC|V4L2_STD_PAL, + .norms = 2, .tvn = { &f50ccir601_lml33, &f60ccir601_lml33, @@ -567,12 +597,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = LML33R10, .name = "LML33R10", - .i2c_decoder = "saa7114", - .mod_decoder = "saa7115", - .addrs_decoder = saa7114_addrs, - .i2c_encoder = "adv7170", - .mod_encoder = "adv7170", - .addrs_encoder = adv717x_addrs, + .i2c_decoder = I2C_DRIVERID_SAA7114, + .i2c_encoder = I2C_DRIVERID_ADV7170, .video_codec = CODEC_TYPE_ZR36060, .inputs = 2, @@ -580,7 +606,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 0, "Composite" }, { 7, "S-Video" } }, - .norms = V4L2_STD_NTSC|V4L2_STD_PAL, + .norms = 2, .tvn = { &f50ccir601_lm33r10, &f60ccir601_lm33r10, @@ -598,12 +624,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = BUZ, .name = "Buz", - .i2c_decoder = "saa7111", - .mod_decoder = "saa7115", - .addrs_decoder = saa7111_addrs, - .i2c_encoder = "saa7185", - .mod_encoder = "saa7185", - .addrs_encoder = saa7185_addrs, + .i2c_decoder = I2C_DRIVERID_SAA7111A, + .i2c_encoder = I2C_DRIVERID_SAA7185B, .video_codec = CODEC_TYPE_ZR36060, .inputs = 2, @@ -611,7 +633,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 3, "Composite" }, { 7, "S-Video" } }, - .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, + .norms = 3, .tvn = { &f50ccir601, &f60ccir601, @@ -631,12 +653,8 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { .name = "6-Eyes", /* AverMedia chose not to brand the 6-Eyes. Thus it can't be autodetected, and requires card=x. */ - .i2c_decoder = "ks0127", - .mod_decoder = "ks0127", - .addrs_decoder = ks0127_addrs, - .i2c_encoder = "bt866", - .mod_encoder = "bt866", - .addrs_encoder = bt866_addrs, + .i2c_decoder = I2C_DRIVERID_KS0127, + .i2c_encoder = I2C_DRIVERID_BT866, .video_codec = CODEC_TYPE_ZR36060, .inputs = 10, @@ -652,7 +670,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { {10, "S-Video 3" }, {15, "YCbCr" } }, - .norms = V4L2_STD_NTSC|V4L2_STD_PAL, + .norms = 2, .tvn = { &f50ccir601_avs6eyes, &f60ccir601_avs6eyes, @@ -717,6 +735,69 @@ zoran_i2c_setscl (void *data, btwrite(zr->i2cbr, ZR36057_I2CBR); } +static int +zoran_i2c_client_register (struct i2c_client *client) +{ + struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter); + int res = 0; + + dprintk(2, + KERN_DEBUG "%s: i2c_client_register() - driver id = %d\n", + ZR_DEVNAME(zr), client->driver->id); + + mutex_lock(&zr->resource_lock); + + if (zr->user > 0) { + /* we're already busy, so we keep a reference to + * them... Could do a lot of stuff here, but this + * is easiest. (Did I ever mention I'm a lazy ass?) + */ + res = -EBUSY; + goto clientreg_unlock_and_return; + } + + if (client->driver->id == zr->card.i2c_decoder) + zr->decoder = client; + else if (client->driver->id == zr->card.i2c_encoder) + zr->encoder = client; + else { + res = -ENODEV; + goto clientreg_unlock_and_return; + } + +clientreg_unlock_and_return: + mutex_unlock(&zr->resource_lock); + + return res; +} + +static int +zoran_i2c_client_unregister (struct i2c_client *client) +{ + struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter); + int res = 0; + + dprintk(2, KERN_DEBUG "%s: i2c_client_unregister()\n", ZR_DEVNAME(zr)); + + mutex_lock(&zr->resource_lock); + + if (zr->user > 0) { + res = -EBUSY; + goto clientunreg_unlock_and_return; + } + + /* try to locate it */ + if (client == zr->encoder) { + zr->encoder = NULL; + } else if (client == zr->decoder) { + zr->decoder = NULL; + snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%d]", zr->id); + } +clientunreg_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} + static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = { .setsda = zoran_i2c_setsda, .setscl = zoran_i2c_setscl, @@ -732,10 +813,13 @@ zoran_register_i2c (struct zoran *zr) memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template, sizeof(struct i2c_algo_bit_data)); zr->i2c_algo.data = zr; + zr->i2c_adapter.class = I2C_CLASS_TV_ANALOG; zr->i2c_adapter.id = I2C_HW_B_ZR36067; + zr->i2c_adapter.client_register = zoran_i2c_client_register; + zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister; strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr), sizeof(zr->i2c_adapter.name)); - i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev); + i2c_set_adapdata(&zr->i2c_adapter, zr); zr->i2c_adapter.algo_data = &zr->i2c_algo; zr->i2c_adapter.dev.parent = &zr->pci_dev->dev; return i2c_bit_add_bus(&zr->i2c_adapter); @@ -751,20 +835,19 @@ zoran_unregister_i2c (struct zoran *zr) int zoran_check_jpg_settings (struct zoran *zr, - struct zoran_jpg_settings *settings, - int try) + struct zoran_jpg_settings *settings) { int err = 0, err0 = 0; dprintk(4, KERN_DEBUG - "%s: %s - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n", - ZR_DEVNAME(zr), __func__, settings->decimation, settings->HorDcm, + "%s: check_jpg_settings() - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n", + ZR_DEVNAME(zr), settings->decimation, settings->HorDcm, settings->VerDcm, settings->TmpDcm); dprintk(4, KERN_DEBUG - "%s: %s - x: %d, y: %d, w: %d, y: %d\n", - ZR_DEVNAME(zr), __func__, settings->img_x, settings->img_y, + "%s: check_jpg_settings() - x: %d, y: %d, w: %d, y: %d\n", + ZR_DEVNAME(zr), settings->img_x, settings->img_y, settings->img_width, settings->img_height); /* Check decimation, set default values for decimation = 1, 2, 4 */ switch (settings->decimation) { @@ -796,8 +879,8 @@ zoran_check_jpg_settings (struct zoran *zr, if (zr->card.type == DC10_new) { dprintk(1, KERN_DEBUG - "%s: %s - HDec by 4 is not supported on the DC10\n", - ZR_DEVNAME(zr), __func__); + "%s: check_jpg_settings() - HDec by 4 is not supported on the DC10\n", + ZR_DEVNAME(zr)); err0++; break; } @@ -817,73 +900,50 @@ zoran_check_jpg_settings (struct zoran *zr, /* We have to check the data the user has set */ if (settings->HorDcm != 1 && settings->HorDcm != 2 && - (zr->card.type == DC10_new || settings->HorDcm != 4)) { - settings->HorDcm = clamp(settings->HorDcm, 1, 2); + (zr->card.type == DC10_new || settings->HorDcm != 4)) err0++; - } - if (settings->VerDcm != 1 && settings->VerDcm != 2) { - settings->VerDcm = clamp(settings->VerDcm, 1, 2); + if (settings->VerDcm != 1 && settings->VerDcm != 2) err0++; - } - if (settings->TmpDcm != 1 && settings->TmpDcm != 2) { - settings->TmpDcm = clamp(settings->TmpDcm, 1, 2); + if (settings->TmpDcm != 1 && settings->TmpDcm != 2) err0++; - } if (settings->field_per_buff != 1 && - settings->field_per_buff != 2) { - settings->field_per_buff = clamp(settings->field_per_buff, 1, 2); + settings->field_per_buff != 2) err0++; - } - if (settings->img_x < 0) { - settings->img_x = 0; + if (settings->img_x < 0) err0++; - } - if (settings->img_y < 0) { - settings->img_y = 0; + if (settings->img_y < 0) err0++; - } - if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) { - settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH); + if (settings->img_width < 0) err0++; - } - if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) { - settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2); + if (settings->img_height < 0) err0++; - } - if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) { - settings->img_x = BUZ_MAX_WIDTH - settings->img_width; + if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) err0++; - } - if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) { - settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height; - err0++; - } - if (settings->img_width % (16 * settings->HorDcm) != 0) { - settings->img_width -= settings->img_width % (16 * settings->HorDcm); - if (settings->img_width == 0) - settings->img_width = 16 * settings->HorDcm; - err0++; - } - if (settings->img_height % (8 * settings->VerDcm) != 0) { - settings->img_height -= settings->img_height % (8 * settings->VerDcm); - if (settings->img_height == 0) - settings->img_height = 8 * settings->VerDcm; + if (settings->img_y + settings->img_height > + BUZ_MAX_HEIGHT / 2) err0++; + if (settings->HorDcm && settings->VerDcm) { + if (settings->img_width % + (16 * settings->HorDcm) != 0) + err0++; + if (settings->img_height % + (8 * settings->VerDcm) != 0) + err0++; } - if (!try && err0) { + if (err0) { dprintk(1, KERN_ERR - "%s: %s - error in params for decimation = 0\n", - ZR_DEVNAME(zr), __func__); + "%s: check_jpg_settings() - error in params for decimation = 0\n", + ZR_DEVNAME(zr)); err++; } break; default: dprintk(1, KERN_ERR - "%s: %s - decimation = %d, must be 0, 1, 2 or 4\n", - ZR_DEVNAME(zr), __func__, settings->decimation); + "%s: check_jpg_settings() - decimation = %d, must be 0, 1, 2 or 4\n", + ZR_DEVNAME(zr), settings->decimation); err++; break; } @@ -961,10 +1021,12 @@ zoran_open_init_params (struct zoran *zr) sizeof(zr->jpg_settings.jpg_comp.COM_data)); zr->jpg_settings.jpg_comp.jpeg_markers = JPEG_MARKER_DHT | JPEG_MARKER_DQT; - i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0); + i = zoran_check_jpg_settings(zr, &zr->jpg_settings); if (i) - dprintk(1, KERN_ERR "%s: %s internal error\n", - ZR_DEVNAME(zr), __func__); + dprintk(1, + KERN_ERR + "%s: zoran_open_init_params() internal error\n", + ZR_DEVNAME(zr)); clear_interrupt_counters(zr); zr->testing = 0; @@ -1000,11 +1062,13 @@ static int __devinit zr36057_init (struct zoran *zr) { int j, err; + int two = 2; + int zero = 0; dprintk(1, KERN_INFO - "%s: %s - initializing card[%d], zr=%p\n", - ZR_DEVNAME(zr), __func__, zr->id, zr); + "%s: zr36057_init() - initializing card[%d], zr=%p\n", + ZR_DEVNAME(zr), zr->id, zr); /* default setup of all parameters which will persist between opens */ zr->user = 0; @@ -1015,32 +1079,24 @@ zr36057_init (struct zoran *zr) zr->jpg_buffers.allocated = 0; zr->v4l_buffers.allocated = 0; - zr->vbuf_base = (void *) vidmem; - zr->vbuf_width = 0; - zr->vbuf_height = 0; - zr->vbuf_depth = 0; - zr->vbuf_bytesperline = 0; + zr->buffer.base = (void *) vidmem; + zr->buffer.width = 0; + zr->buffer.height = 0; + zr->buffer.depth = 0; + zr->buffer.bytesperline = 0; /* Avoid nonsense settings from user for default input/norm */ - if (default_norm < 0 && default_norm > 2) - default_norm = 0; - if (default_norm == 0) { - zr->norm = V4L2_STD_PAL; - zr->timing = zr->card.tvn[0]; - } else if (default_norm == 1) { - zr->norm = V4L2_STD_NTSC; - zr->timing = zr->card.tvn[1]; - } else { - zr->norm = V4L2_STD_SECAM; - zr->timing = zr->card.tvn[2]; - } - if (zr->timing == NULL) { + if (default_norm < VIDEO_MODE_PAL && + default_norm > VIDEO_MODE_SECAM) + default_norm = VIDEO_MODE_PAL; + zr->norm = default_norm; + if (!(zr->timing = zr->card.tvn[zr->norm])) { dprintk(1, KERN_WARNING - "%s: %s - default TV standard not supported by hardware. PAL will be used.\n", - ZR_DEVNAME(zr), __func__); - zr->norm = V4L2_STD_PAL; - zr->timing = zr->card.tvn[0]; + "%s: zr36057_init() - default TV standard not supported by hardware. PAL will be used.\n", + ZR_DEVNAME(zr)); + zr->norm = VIDEO_MODE_PAL; + zr->timing = zr->card.tvn[zr->norm]; } if (default_input > zr->card.inputs-1) { @@ -1052,6 +1108,12 @@ zr36057_init (struct zoran *zr) } zr->input = default_input; + /* Should the following be reset at every open ? */ + zr->hue = 32768; + zr->contrast = 32768; + zr->saturation = 32768; + zr->brightness = 32768; + /* default setup (will be repeated at every open) */ zoran_open_init_params(zr); @@ -1062,8 +1124,8 @@ zr36057_init (struct zoran *zr) if (!zr->stat_com || !zr->video_dev) { dprintk(1, KERN_ERR - "%s: %s - kmalloc (STAT_COM) failed\n", - ZR_DEVNAME(zr), __func__); + "%s: zr36057_init() - kmalloc (STAT_COM) failed\n", + ZR_DEVNAME(zr)); err = -ENOMEM; goto exit_free; } @@ -1075,7 +1137,6 @@ zr36057_init (struct zoran *zr) * Now add the template and register the device unit. */ memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template)); - zr->video_dev->parent = &zr->pci_dev->dev; strcpy(zr->video_dev->name, ZR_DEVNAME(zr)); err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]); if (err < 0) @@ -1087,10 +1148,8 @@ zr36057_init (struct zoran *zr) detect_guest_activity(zr); test_interrupts(zr); if (!pass_through) { - struct v4l2_routing route = { 2, 0 }; - - decoder_call(zr, video, s_stream, 0); - encoder_call(zr, video, s_routing, &route); + decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero); + encoder_command(zr, ENCODER_SET_INPUT, &two); } zr->zoran_proc = NULL; @@ -1105,8 +1164,7 @@ zr36057_init (struct zoran *zr) static void __devexit zoran_remove(struct pci_dev *pdev) { - struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); - struct zoran *zr = to_zoran(v4l2_dev); + struct zoran *zr = pci_get_drvdata(pdev); if (!zr->initialized) goto exit_free; @@ -1139,7 +1197,7 @@ static void __devexit zoran_remove(struct pci_dev *pdev) pci_disable_device(zr->pci_dev); video_unregister_device(zr->video_dev); exit_free: - v4l2_device_unregister(&zr->v4l2_dev); + pci_set_drvdata(pdev, NULL); kfree(zr); } @@ -1157,8 +1215,10 @@ zoran_setup_videocodec (struct zoran *zr, m = kmalloc(sizeof(struct videocodec_master), GFP_KERNEL); if (!m) { - dprintk(1, KERN_ERR "%s: %s - no memory\n", - ZR_DEVNAME(zr), __func__); + dprintk(1, + KERN_ERR + "%s: zoran_setup_videocodec() - no memory\n", + ZR_DEVNAME(zr)); return m; } @@ -1196,18 +1256,6 @@ zoran_setup_videocodec (struct zoran *zr, return m; } -static void zoran_subdev_notify(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - struct zoran *zr = to_zoran(sd->v4l2_dev); - - /* Bt819 needs to reset its FIFO buffer using #FRST pin and - LML33 card uses GPIO(7) for that. */ - if (cmd == BT819_FIFO_RESET_LOW) - GPIO(zr, 7, 0); - else if (cmd == BT819_FIFO_RESET_HIGH) - GPIO(zr, 7, 1); -} - /* * Scan for a Buz card (actually for the PCI controller ZR36057), * request the irq and map the io memory @@ -1221,33 +1269,34 @@ static int __devinit zoran_probe(struct pci_dev *pdev, struct videocodec_master *master_vfe = NULL; struct videocodec_master *master_codec = NULL; int card_num; - char *codec_name, *vfe_name; + char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name; unsigned int nr; nr = zoran_num++; if (nr >= BUZ_MAX) { - dprintk(1, KERN_ERR "%s: driver limited to %d card(s) maximum\n", + dprintk(1, + KERN_ERR + "%s: driver limited to %d card(s) maximum\n", ZORAN_NAME, BUZ_MAX); return -ENOENT; } zr = kzalloc(sizeof(struct zoran), GFP_KERNEL); if (!zr) { - dprintk(1, KERN_ERR "%s: %s - kzalloc failed\n", - ZORAN_NAME, __func__); + dprintk(1, + KERN_ERR + "%s: find_zr36057() - kzalloc failed\n", + ZORAN_NAME); return -ENOMEM; } - zr->v4l2_dev.notify = zoran_subdev_notify; - if (v4l2_device_register(&pdev->dev, &zr->v4l2_dev)) - goto zr_free_mem; zr->pci_dev = pdev; zr->id = nr; snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); spin_lock_init(&zr->spinlock); mutex_init(&zr->resource_lock); if (pci_enable_device(pdev)) - goto zr_unreg; + goto zr_free_mem; pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision); dprintk(1, @@ -1274,7 +1323,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev, KERN_ERR "%s: It is not possible to auto-detect ZR36057 based cards\n", ZR_DEVNAME(zr)); - goto zr_unreg; + goto zr_free_mem; } card_num = ent->driver_data; @@ -1283,7 +1332,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev, KERN_ERR "%s: Unknown card, try specifying card=X module parameter\n", ZR_DEVNAME(zr)); - goto zr_unreg; + goto zr_free_mem; } dprintk(3, KERN_DEBUG @@ -1296,7 +1345,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev, KERN_ERR "%s: User specified card type %d out of range (0 .. %d)\n", ZR_DEVNAME(zr), card_num, NUM_CARDS - 1); - goto zr_unreg; + goto zr_free_mem; } } @@ -1311,9 +1360,11 @@ static int __devinit zoran_probe(struct pci_dev *pdev, zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0); if (!zr->zr36057_mem) { - dprintk(1, KERN_ERR "%s: %s() - ioremap failed\n", + dprintk(1, + KERN_ERR + "%s: %s() - ioremap failed\n", ZR_DEVNAME(zr), __func__); - goto zr_unreg; + goto zr_free_mem; } result = request_irq(zr->pci_dev->irq, zoran_irq, @@ -1322,18 +1373,18 @@ static int __devinit zoran_probe(struct pci_dev *pdev, if (result == -EINVAL) { dprintk(1, KERN_ERR - "%s: %s - bad irq number or handler\n", - ZR_DEVNAME(zr), __func__); + "%s: find_zr36057() - bad irq number or handler\n", + ZR_DEVNAME(zr)); } else if (result == -EBUSY) { dprintk(1, KERN_ERR - "%s: %s - IRQ %d busy, change your PnP config in BIOS\n", - ZR_DEVNAME(zr), __func__, zr->pci_dev->irq); + "%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n", + ZR_DEVNAME(zr), zr->pci_dev->irq); } else { dprintk(1, KERN_ERR - "%s: %s - can't assign irq, error code %d\n", - ZR_DEVNAME(zr), __func__, result); + "%s: find_zr36057() - can't assign irq, error code %d\n", + ZR_DEVNAME(zr), result); } goto zr_unmap; } @@ -1343,7 +1394,9 @@ static int __devinit zoran_probe(struct pci_dev *pdev, &latency); need_latency = zr->revision > 1 ? 32 : 48; if (latency != need_latency) { - dprintk(2, KERN_INFO "%s: Changing PCI latency from %d to %d\n", + dprintk(2, + KERN_INFO + "%s: Changing PCI latency from %d to %d\n", ZR_DEVNAME(zr), latency, need_latency); pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, need_latency); @@ -1354,19 +1407,53 @@ static int __devinit zoran_probe(struct pci_dev *pdev, dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n", ZR_DEVNAME(zr)); - if (zoran_register_i2c(zr) < 0) { - dprintk(1, KERN_ERR "%s: %s - can't initialize i2c bus\n", - ZR_DEVNAME(zr), __func__); - goto zr_free_irq; + /* i2c decoder */ + if (decoder[zr->id] != -1) { + i2c_dec_name = i2cid_to_modulename(decoder[zr->id]); + zr->card.i2c_decoder = decoder[zr->id]; + } else if (zr->card.i2c_decoder != 0) { + i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder); + } else { + i2c_dec_name = NULL; } - zr->decoder = v4l2_i2c_new_probed_subdev(&zr->i2c_adapter, - zr->card.mod_decoder, zr->card.i2c_decoder, zr->card.addrs_decoder); + if (i2c_dec_name) { + result = request_module(i2c_dec_name); + if (result < 0) { + dprintk(1, + KERN_ERR + "%s: failed to load module %s: %d\n", + ZR_DEVNAME(zr), i2c_dec_name, result); + } + } - if (zr->card.mod_encoder) - zr->encoder = v4l2_i2c_new_probed_subdev(&zr->i2c_adapter, - zr->card.mod_encoder, zr->card.i2c_encoder, - zr->card.addrs_encoder); + /* i2c encoder */ + if (encoder[zr->id] != -1) { + i2c_enc_name = i2cid_to_modulename(encoder[zr->id]); + zr->card.i2c_encoder = encoder[zr->id]; + } else if (zr->card.i2c_encoder != 0) { + i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder); + } else { + i2c_enc_name = NULL; + } + + if (i2c_enc_name) { + result = request_module(i2c_enc_name); + if (result < 0) { + dprintk(1, + KERN_ERR + "%s: failed to load module %s: %d\n", + ZR_DEVNAME(zr), i2c_enc_name, result); + } + } + + if (zoran_register_i2c(zr) < 0) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - can't initialize i2c bus\n", + ZR_DEVNAME(zr)); + goto zr_free_irq; + } dprintk(2, KERN_INFO "%s: Initializing videocodec bus...\n", @@ -1408,13 +1495,17 @@ static int __devinit zoran_probe(struct pci_dev *pdev, goto zr_unreg_i2c; zr->codec = videocodec_attach(master_codec); if (!zr->codec) { - dprintk(1, KERN_ERR "%s: %s - no codec found\n", - ZR_DEVNAME(zr), __func__); + dprintk(1, + KERN_ERR + "%s: find_zr36057() - no codec found\n", + ZR_DEVNAME(zr)); goto zr_free_codec; } if (zr->codec->type != zr->card.video_codec) { - dprintk(1, KERN_ERR "%s: %s - wrong codec\n", - ZR_DEVNAME(zr), __func__); + dprintk(1, + KERN_ERR + "%s: find_zr36057() - wrong codec\n", + ZR_DEVNAME(zr)); goto zr_detach_codec; } } @@ -1424,13 +1515,17 @@ static int __devinit zoran_probe(struct pci_dev *pdev, goto zr_detach_codec; zr->vfe = videocodec_attach(master_vfe); if (!zr->vfe) { - dprintk(1, KERN_ERR "%s: %s - no VFE found\n", - ZR_DEVNAME(zr), __func__); + dprintk(1, + KERN_ERR + "%s: find_zr36057() - no VFE found\n", + ZR_DEVNAME(zr)); goto zr_free_vfe; } if (zr->vfe->type != zr->card.video_vfe) { - dprintk(1, KERN_ERR "%s: %s = wrong VFE\n", - ZR_DEVNAME(zr), __func__); + dprintk(1, + KERN_ERR + "%s: find_zr36057() = wrong VFE\n", + ZR_DEVNAME(zr)); goto zr_detach_vfe; } } @@ -1438,7 +1533,8 @@ static int __devinit zoran_probe(struct pci_dev *pdev, /* take care of Natoma chipset and a revision 1 zr36057 */ if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) { zr->jpg_buffers.need_contiguous = 1; - dprintk(1, KERN_INFO + dprintk(1, + KERN_INFO "%s: ZR36057/Natoma bug, max. buffer size is 128K\n", ZR_DEVNAME(zr)); } @@ -1448,6 +1544,8 @@ static int __devinit zoran_probe(struct pci_dev *pdev, zoran_proc_init(zr); + pci_set_drvdata(pdev, zr); + return 0; zr_detach_vfe: @@ -1465,8 +1563,6 @@ static int __devinit zoran_probe(struct pci_dev *pdev, free_irq(zr->pci_dev->irq, zr); zr_unmap: iounmap(zr->zr36057_mem); -zr_unreg: - v4l2_device_unregister(&zr->v4l2_dev); zr_free_mem: kfree(zr); @@ -1517,6 +1613,9 @@ static int __init zoran_init(void) ZORAN_NAME, vidmem); } + /* random nonsense */ + dprintk(6, KERN_DEBUG "Jotti is een held!\n"); + /* some mainboards might not do PCI-PCI data transfer well */ if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL|PCIPCI_ALIMAGIK)) { dprintk(1, diff --git a/trunk/drivers/media/video/zoran/zoran_card.h b/trunk/drivers/media/video/zoran/zoran_card.h index 4936fead73e8..4507bdc5e338 100644 --- a/trunk/drivers/media/video/zoran/zoran_card.h +++ b/trunk/drivers/media/video/zoran/zoran_card.h @@ -44,8 +44,7 @@ extern int zr36067_debug; extern struct video_device zoran_template; extern int zoran_check_jpg_settings(struct zoran *zr, - struct zoran_jpg_settings *settings, - int try); + struct zoran_jpg_settings *settings); extern void zoran_open_init_params(struct zoran *zr); extern void zoran_vdev_release(struct video_device *vdev); diff --git a/trunk/drivers/media/video/zoran/zoran_device.c b/trunk/drivers/media/video/zoran/zoran_device.c index e0223deed35e..5d948ff7faf0 100644 --- a/trunk/drivers/media/video/zoran/zoran_device.c +++ b/trunk/drivers/media/video/zoran/zoran_device.c @@ -36,12 +36,13 @@ #include #include #include -#include -#include +#include #include #include #include +#include +#include #include #include @@ -311,9 +312,9 @@ zr36057_adjust_vfe (struct zoran *zr, case BUZ_MODE_MOTION_COMPRESS: case BUZ_MODE_IDLE: default: - if ((zr->norm & V4L2_STD_NTSC) || + if (zr->norm == VIDEO_MODE_NTSC || (zr->card.type == LML33R10 && - (zr->norm & V4L2_STD_PAL))) + zr->norm == VIDEO_MODE_PAL)) btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); else btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); @@ -354,6 +355,14 @@ zr36057_set_vfe (struct zoran *zr, dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n", ZR_DEVNAME(zr), video_width, video_height); + if (zr->norm != VIDEO_MODE_PAL && + zr->norm != VIDEO_MODE_NTSC && + zr->norm != VIDEO_MODE_SECAM) { + dprintk(1, + KERN_ERR "%s: set_vfe() - norm = %d not valid\n", + ZR_DEVNAME(zr), zr->norm); + return; + } if (video_width < BUZ_MIN_WIDTH || video_height < BUZ_MIN_HEIGHT || video_width > Wa || video_height > Ha) { @@ -417,7 +426,7 @@ zr36057_set_vfe (struct zoran *zr, * we get the correct colors when uncompressing to the screen */ //reg |= ZR36057_VFESPFR_VCLKPol; /**/ /* RJ: Don't know if that is needed for NTSC also */ - if (!(zr->norm & V4L2_STD_NTSC)) + if (zr->norm != VIDEO_MODE_NTSC) reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang reg |= ZR36057_VFESPFR_TopField; if (HorDcm >= 48) { @@ -488,11 +497,11 @@ zr36057_overlay (struct zoran *zr, * All error messages are internal driver checking only! */ /* video display top and bottom registers */ - reg = (long) zr->vbuf_base + + reg = (long) zr->buffer.base + zr->overlay_settings.x * ((zr->overlay_settings.format->depth + 7) / 8) + zr->overlay_settings.y * - zr->vbuf_bytesperline; + zr->buffer.bytesperline; btwrite(reg, ZR36057_VDTR); if (reg & 3) dprintk(1, @@ -500,15 +509,15 @@ zr36057_overlay (struct zoran *zr, "%s: zr36057_overlay() - video_address not aligned\n", ZR_DEVNAME(zr)); if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2) - reg += zr->vbuf_bytesperline; + reg += zr->buffer.bytesperline; btwrite(reg, ZR36057_VDBR); /* video stride, status, and frame grab register */ - reg = zr->vbuf_bytesperline - + reg = zr->buffer.bytesperline - zr->overlay_settings.width * ((zr->overlay_settings.format->depth + 7) / 8); if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2) - reg += zr->vbuf_bytesperline; + reg += zr->buffer.bytesperline; if (reg & 3) dprintk(1, KERN_ERR @@ -535,8 +544,12 @@ zr36057_overlay (struct zoran *zr, * and the maximum window size is BUZ_MAX_WIDTH * BUZ_MAX_HEIGHT pixels. */ -void write_overlay_mask(struct zoran_fh *fh, struct v4l2_clip *vp, int count) +void +write_overlay_mask (struct file *file, + struct video_clip *vp, + int count) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; unsigned mask_line_size = (BUZ_MAX_WIDTH + 31) / 32; u32 *mask; @@ -550,10 +563,10 @@ void write_overlay_mask(struct zoran_fh *fh, struct v4l2_clip *vp, int count) for (i = 0; i < count; ++i) { /* pick up local copy of clip */ - x = vp[i].c.left; - y = vp[i].c.top; - width = vp[i].c.width; - height = vp[i].c.height; + x = vp[i].x; + y = vp[i].y; + width = vp[i].width; + height = vp[i].height; /* trim clips that extend beyond the window */ if (x < 0) { @@ -968,10 +981,11 @@ void zr36057_enable_jpg (struct zoran *zr, enum zoran_codec_mode mode) { + static int zero; + static int one = 1; struct vfe_settings cap; int field_size = zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff; - struct v4l2_routing route = { 0, 0 }; zr->codec_mode = mode; @@ -993,9 +1007,8 @@ zr36057_enable_jpg (struct zoran *zr, * the video bus direction set to input. */ set_videobus_dir(zr, 0); - decoder_call(zr, video, s_stream, 1); - route.input = 0; - encoder_call(zr, video, s_routing, &route); + decoder_command(zr, DECODER_ENABLE_OUTPUT, &one); + encoder_command(zr, ENCODER_SET_INPUT, &zero); /* Take the JPEG codec and the VFE out of sleep */ jpeg_codec_sleep(zr, 0); @@ -1041,10 +1054,9 @@ zr36057_enable_jpg (struct zoran *zr, /* In motion decompression mode, the decoder output must be disabled, and * the video bus direction set to output. */ - decoder_call(zr, video, s_stream, 0); + decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero); set_videobus_dir(zr, 1); - route.input = 1; - encoder_call(zr, video, s_routing, &route); + encoder_command(zr, ENCODER_SET_INPUT, &one); /* Take the JPEG codec and the VFE out of sleep */ jpeg_codec_sleep(zr, 0); @@ -1088,9 +1100,8 @@ zr36057_enable_jpg (struct zoran *zr, jpeg_codec_sleep(zr, 1); zr36057_adjust_vfe(zr, mode); - decoder_call(zr, video, s_stream, 1); - route.input = 0; - encoder_call(zr, video, s_routing, &route); + decoder_command(zr, DECODER_ENABLE_OUTPUT, &one); + encoder_command(zr, ENCODER_SET_INPUT, &zero); dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr)); break; @@ -1121,7 +1132,7 @@ zoran_feed_stat_com (struct zoran *zr) if (!(zr->stat_com[i] & cpu_to_le32(1))) break; zr->stat_com[i] = - cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus); + cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus); } else { /* fill 2 stat_com entries */ i = ((zr->jpg_dma_head - @@ -1129,9 +1140,9 @@ zoran_feed_stat_com (struct zoran *zr) if (!(zr->stat_com[i] & cpu_to_le32(1))) break; zr->stat_com[i] = - cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus); + cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus); zr->stat_com[i + 1] = - cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus); + cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus); } zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA; zr->jpg_dma_head++; @@ -1151,7 +1162,7 @@ zoran_reap_stat_com (struct zoran *zr) u32 stat_com; unsigned int seq; unsigned int dif; - struct zoran_buffer *buffer; + struct zoran_jpg_buffer *buffer; int frame; /* In motion decompress we don't have a hardware frame counter, @@ -1197,52 +1208,22 @@ zoran_reap_stat_com (struct zoran *zr) } } -static void zoran_restart(struct zoran *zr) -{ - /* Now the stat_comm buffer is ready for restart */ - int status = 0, mode; - - if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { - decoder_call(zr, video, g_input_status, &status); - mode = CODEC_DO_COMPRESSION; - } else { - status = V4L2_IN_ST_NO_SIGNAL; - mode = CODEC_DO_EXPANSION; - } - if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || - !(status & V4L2_IN_ST_NO_SIGNAL)) { - /********** RESTART code *************/ - jpeg_codec_reset(zr); - zr->codec->set_mode(zr->codec, mode); - zr36057_set_jpg(zr, zr->codec_mode); - jpeg_start(zr); - - if (zr->num_errors <= 8) - dprintk(2, KERN_INFO "%s: Restart\n", - ZR_DEVNAME(zr)); - - zr->JPEG_missed = 0; - zr->JPEG_error = 2; - /********** End RESTART code ***********/ - } -} - static void error_handler (struct zoran *zr, u32 astat, u32 stat) { - int i, j; - /* This is JPEG error handling part */ - if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS && - zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS) { + if ((zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) && + (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS)) { + //dprintk(1, KERN_ERR "%s: Internal error: error handling request in mode %d\n", ZR_DEVNAME(zr), zr->codec_mode); return; } if ((stat & 1) == 0 && zr->codec_mode == BUZ_MODE_MOTION_COMPRESS && - zr->jpg_dma_tail - zr->jpg_que_tail >= zr->jpg_buffers.num_buffers) { + zr->jpg_dma_tail - zr->jpg_que_tail >= + zr->jpg_buffers.num_buffers) { /* No free buffers... */ zoran_reap_stat_com(zr); zoran_feed_stat_com(zr); @@ -1251,95 +1232,142 @@ error_handler (struct zoran *zr, return; } - if (zr->JPEG_error == 1) { - zoran_restart(zr); - return; - } - - /* - * First entry: error just happened during normal operation - * - * In BUZ_MODE_MOTION_COMPRESS: - * - * Possible glitch in TV signal. In this case we should - * stop the codec and wait for good quality signal before - * restarting it to avoid further problems - * - * In BUZ_MODE_MOTION_DECOMPRESS: - * - * Bad JPEG frame: we have to mark it as processed (codec crashed - * and was not able to do it itself), and to remove it from queue. - */ - btand(~ZR36057_JMC_Go_en, ZR36057_JMC); - udelay(1); - stat = stat | (post_office_read(zr, 7, 0) & 3) << 8; - btwrite(0, ZR36057_JPC); - btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); - jpeg_codec_reset(zr); - jpeg_codec_sleep(zr, 1); - zr->JPEG_error = 1; - zr->num_errors++; - - /* Report error */ - if (zr36067_debug > 1 && zr->num_errors <= 8) { - long frame; + if (zr->JPEG_error != 1) { + /* + * First entry: error just happened during normal operation + * + * In BUZ_MODE_MOTION_COMPRESS: + * + * Possible glitch in TV signal. In this case we should + * stop the codec and wait for good quality signal before + * restarting it to avoid further problems + * + * In BUZ_MODE_MOTION_DECOMPRESS: + * + * Bad JPEG frame: we have to mark it as processed (codec crashed + * and was not able to do it itself), and to remove it from queue. + */ + btand(~ZR36057_JMC_Go_en, ZR36057_JMC); + udelay(1); + stat = stat | (post_office_read(zr, 7, 0) & 3) << 8; + btwrite(0, ZR36057_JPC); + btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); + jpeg_codec_reset(zr); + jpeg_codec_sleep(zr, 1); + zr->JPEG_error = 1; + zr->num_errors++; + + /* Report error */ + if (zr36067_debug > 1 && zr->num_errors <= 8) { + long frame; + frame = + zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; + printk(KERN_ERR + "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ", + ZR_DEVNAME(zr), stat, zr->last_isr, + zr->jpg_que_tail, zr->jpg_dma_tail, + zr->jpg_dma_head, zr->jpg_que_head, + zr->jpg_seq_num, frame); + printk("stat_com frames:"); + { + int i, j; + for (j = 0; j < BUZ_NUM_STAT_COM; j++) { + for (i = 0; + i < zr->jpg_buffers.num_buffers; + i++) { + if (le32_to_cpu(zr->stat_com[j]) == + zr->jpg_buffers. + buffer[i]. + frag_tab_bus) { + printk("% d->%d", + j, i); + } + } + } + printk("\n"); + } + } + /* Find an entry in stat_com and rotate contents */ + { + int i; + + if (zr->jpg_settings.TmpDcm == 1) + i = (zr->jpg_dma_tail - + zr->jpg_err_shift) & BUZ_MASK_STAT_COM; + else + i = ((zr->jpg_dma_tail - + zr->jpg_err_shift) & 1) * 2; + if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { + /* Mimic zr36067 operation */ + zr->stat_com[i] |= cpu_to_le32(1); + if (zr->jpg_settings.TmpDcm != 1) + zr->stat_com[i + 1] |= cpu_to_le32(1); + /* Refill */ + zoran_reap_stat_com(zr); + zoran_feed_stat_com(zr); + wake_up_interruptible(&zr->jpg_capq); + /* Find an entry in stat_com again after refill */ + if (zr->jpg_settings.TmpDcm == 1) + i = (zr->jpg_dma_tail - + zr->jpg_err_shift) & + BUZ_MASK_STAT_COM; + else + i = ((zr->jpg_dma_tail - + zr->jpg_err_shift) & 1) * 2; + } + if (i) { + /* Rotate stat_comm entries to make current entry first */ + int j; + __le32 bus_addr[BUZ_NUM_STAT_COM]; + + /* Here we are copying the stat_com array, which + * is already in little endian format, so + * no endian conversions here + */ + memcpy(bus_addr, zr->stat_com, + sizeof(bus_addr)); + for (j = 0; j < BUZ_NUM_STAT_COM; j++) { + zr->stat_com[j] = + bus_addr[(i + j) & + BUZ_MASK_STAT_COM]; - frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; - printk(KERN_ERR - "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ", - ZR_DEVNAME(zr), stat, zr->last_isr, - zr->jpg_que_tail, zr->jpg_dma_tail, - zr->jpg_dma_head, zr->jpg_que_head, - zr->jpg_seq_num, frame); - printk(KERN_INFO "stat_com frames:"); - for (j = 0; j < BUZ_NUM_STAT_COM; j++) { - for (i = 0; i < zr->jpg_buffers.num_buffers; i++) { - if (le32_to_cpu(zr->stat_com[j]) == zr->jpg_buffers.buffer[i].jpg.frag_tab_bus) - printk(KERN_CONT "% d->%d", j, i); + } + zr->jpg_err_shift += i; + zr->jpg_err_shift &= BUZ_MASK_STAT_COM; } + if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) + zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */ } - printk(KERN_CONT "\n"); - } - /* Find an entry in stat_com and rotate contents */ - if (zr->jpg_settings.TmpDcm == 1) - i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; - else - i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2; - if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { - /* Mimic zr36067 operation */ - zr->stat_com[i] |= cpu_to_le32(1); - if (zr->jpg_settings.TmpDcm != 1) - zr->stat_com[i + 1] |= cpu_to_le32(1); - /* Refill */ - zoran_reap_stat_com(zr); - zoran_feed_stat_com(zr); - wake_up_interruptible(&zr->jpg_capq); - /* Find an entry in stat_com again after refill */ - if (zr->jpg_settings.TmpDcm == 1) - i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; - else - i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2; } - if (i) { - /* Rotate stat_comm entries to make current entry first */ - int j; - __le32 bus_addr[BUZ_NUM_STAT_COM]; - - /* Here we are copying the stat_com array, which - * is already in little endian format, so - * no endian conversions here - */ - memcpy(bus_addr, zr->stat_com, sizeof(bus_addr)); - for (j = 0; j < BUZ_NUM_STAT_COM; j++) - zr->stat_com[j] = bus_addr[(i + j) & BUZ_MASK_STAT_COM]; + /* Now the stat_comm buffer is ready for restart */ + do { + int status, mode; - zr->jpg_err_shift += i; - zr->jpg_err_shift &= BUZ_MASK_STAT_COM; - } - if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) - zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */ - zoran_restart(zr); + if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { + decoder_command(zr, DECODER_GET_STATUS, &status); + mode = CODEC_DO_COMPRESSION; + } else { + status = 0; + mode = CODEC_DO_EXPANSION; + } + if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || + (status & DECODER_STATUS_GOOD)) { + /********** RESTART code *************/ + jpeg_codec_reset(zr); + zr->codec->set_mode(zr->codec, mode); + zr36057_set_jpg(zr, zr->codec_mode); + jpeg_start(zr); + + if (zr->num_errors <= 8) + dprintk(2, KERN_INFO "%s: Restart\n", + ZR_DEVNAME(zr)); + + zr->JPEG_missed = 0; + zr->JPEG_error = 2; + /********** End RESTART code ***********/ + } + } while (0); } irqreturn_t @@ -1397,8 +1425,10 @@ zoran_irq (int irq, * We simply ignore them */ if (zr->v4l_memgrab_active) { + /* A lot more checks should be here ... */ - if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) == 0) + if ((btread(ZR36057_VSSFGR) & + ZR36057_VSSFGR_SnapShot) == 0) dprintk(1, KERN_WARNING "%s: BuzIRQ with SnapShot off ???\n", @@ -1406,7 +1436,10 @@ zoran_irq (int irq, if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) { /* There is a grab on a frame going on, check if it has finished */ - if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FrameGrab) == 0) { + + if ((btread(ZR36057_VSSFGR) & + ZR36057_VSSFGR_FrameGrab) == + 0) { /* it is finished, notify the user */ zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE; @@ -1424,7 +1457,9 @@ zoran_irq (int irq, if (zr->v4l_grab_frame == NO_GRAB_ACTIVE && zr->v4l_pend_tail != zr->v4l_pend_head) { - int frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME]; + + int frame = zr->v4l_pend[zr->v4l_pend_tail & + V4L_MASK_FRAME]; u32 reg; zr->v4l_grab_frame = frame; @@ -1433,17 +1468,27 @@ zoran_irq (int irq, /* Buffer address */ - reg = zr->v4l_buffers.buffer[frame].v4l.fbuffer_bus; + reg = + zr->v4l_buffers.buffer[frame]. + fbuffer_bus; btwrite(reg, ZR36057_VDTR); - if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) - reg += zr->v4l_settings.bytesperline; + if (zr->v4l_settings.height > + BUZ_MAX_HEIGHT / 2) + reg += + zr->v4l_settings. + bytesperline; btwrite(reg, ZR36057_VDBR); /* video stride, status, and frame grab register */ reg = 0; - if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) - reg += zr->v4l_settings.bytesperline; - reg = (reg << ZR36057_VSSFGR_DispStride); + if (zr->v4l_settings.height > + BUZ_MAX_HEIGHT / 2) + reg += + zr->v4l_settings. + bytesperline; + reg = + (reg << + ZR36057_VSSFGR_DispStride); reg |= ZR36057_VSSFGR_VidOvf; reg |= ZR36057_VSSFGR_SnapShot; reg |= ZR36057_VSSFGR_FrameGrab; @@ -1461,66 +1506,77 @@ zoran_irq (int irq, #if (IRQ_MASK & ZR36057_ISR_CodRepIRQ) if (astat & ZR36057_ISR_CodRepIRQ) { zr->intr_counter_CodRepIRQ++; - IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", + IDEBUG(printk + (KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", ZR_DEVNAME(zr))); btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR); } #endif /* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */ #if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) - if ((astat & ZR36057_ISR_JPEGRepIRQ) && - (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || - zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) { - if (zr36067_debug > 1 && (!zr->frame_num || zr->JPEG_error)) { - char sc[] = "0000"; - char sv[5]; - int i; - - printk(KERN_INFO - "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n", - ZR_DEVNAME(zr), stat, - zr->jpg_settings.odd_even, - zr->jpg_settings.field_per_buff, - zr->JPEG_missed); - - strcpy(sv, sc); - for (i = 0; i < 4; i++) { - if (le32_to_cpu(zr->stat_com[i]) & 1) - sv[i] = '1'; - } - sv[4] = 0; - printk(KERN_INFO - "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n", - ZR_DEVNAME(zr), sv, - zr->jpg_que_tail, - zr->jpg_dma_tail, - zr->jpg_dma_head, - zr->jpg_que_head); - } else { - /* Get statistics */ - if (zr->JPEG_missed > zr->JPEG_max_missed) - zr->JPEG_max_missed = zr->JPEG_missed; - if (zr->JPEG_missed < zr->JPEG_min_missed) - zr->JPEG_min_missed = zr->JPEG_missed; - } + if (astat & ZR36057_ISR_JPEGRepIRQ) { - if (zr36067_debug > 2 && zr->frame_num < 6) { - int i; + if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || + zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { + if (zr36067_debug > 1 && + (!zr->frame_num || zr->JPEG_error)) { + printk(KERN_INFO + "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n", + ZR_DEVNAME(zr), stat, + zr->jpg_settings.odd_even, + zr->jpg_settings. + field_per_buff, + zr->JPEG_missed); + { + char sc[] = "0000"; + char sv[5]; + int i; + strcpy(sv, sc); + for (i = 0; i < 4; i++) { + if (le32_to_cpu(zr->stat_com[i]) & 1) + sv[i] = '1'; + } + sv[4] = 0; + printk(KERN_INFO + "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n", + ZR_DEVNAME(zr), sv, + zr->jpg_que_tail, + zr->jpg_dma_tail, + zr->jpg_dma_head, + zr->jpg_que_head); + } + } else { + if (zr->JPEG_missed > zr->JPEG_max_missed) // Get statistics + zr->JPEG_max_missed = + zr->JPEG_missed; + if (zr->JPEG_missed < + zr->JPEG_min_missed) + zr->JPEG_min_missed = + zr->JPEG_missed; + } - printk(KERN_INFO "%s: seq=%ld stat_com:", - ZR_DEVNAME(zr), zr->jpg_seq_num); - for (i = 0; i < 4; i++) { - printk(KERN_CONT " %08x", - le32_to_cpu(zr->stat_com[i])); + if (zr36067_debug > 2 && zr->frame_num < 6) { + int i; + printk("%s: seq=%ld stat_com:", + ZR_DEVNAME(zr), zr->jpg_seq_num); + for (i = 0; i < 4; i++) { + printk(" %08x", + le32_to_cpu(zr->stat_com[i])); + } + printk("\n"); } - printk(KERN_CONT "\n"); - } - zr->frame_num++; - zr->JPEG_missed = 0; - zr->JPEG_error = 0; - zoran_reap_stat_com(zr); - zoran_feed_stat_com(zr); - wake_up_interruptible(&zr->jpg_capq); + zr->frame_num++; + zr->JPEG_missed = 0; + zr->JPEG_error = 0; + zoran_reap_stat_com(zr); + zoran_feed_stat_com(zr); + wake_up_interruptible(&zr->jpg_capq); + } /*else { + dprintk(1, + KERN_ERR + "%s: JPEG interrupt while not in motion (de)compress mode!\n", + ZR_DEVNAME(zr)); + }*/ } #endif /* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */ @@ -1529,7 +1585,8 @@ zoran_irq (int irq, zr->JPEG_missed > 25 || zr->JPEG_error == 1 || ((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) && - (zr->frame_num & (zr->JPEG_missed > zr->jpg_settings.field_per_buff)))) { + (zr->frame_num & (zr->JPEG_missed > + zr->jpg_settings.field_per_buff)))) { error_handler(zr, astat, stat); } @@ -1571,7 +1628,7 @@ zoran_set_pci_master (struct zoran *zr, void zoran_init_hardware (struct zoran *zr) { - struct v4l2_routing route = { 0, 0 }; + int j, zero = 0; /* Enable bus-mastering */ zoran_set_pci_master(zr, 1); @@ -1581,16 +1638,15 @@ zoran_init_hardware (struct zoran *zr) zr->card.init(zr); } - route.input = zr->card.input[zr->input].muxsel; + j = zr->card.input[zr->input].muxsel; - decoder_call(zr, core, init, 0); - decoder_call(zr, tuner, s_std, zr->norm); - decoder_call(zr, video, s_routing, &route); + decoder_command(zr, 0, NULL); + decoder_command(zr, DECODER_SET_NORM, &zr->norm); + decoder_command(zr, DECODER_SET_INPUT, &j); - encoder_call(zr, core, init, 0); - encoder_call(zr, video, s_std_output, zr->norm); - route.input = 0; - encoder_call(zr, video, s_routing, &route); + encoder_command(zr, 0, NULL); + encoder_command(zr, ENCODER_SET_NORM, &zr->norm); + encoder_command(zr, ENCODER_SET_INPUT, &zero); /* toggle JPEG codec sleep to sync PLL */ jpeg_codec_sleep(zr, 1); @@ -1650,3 +1706,42 @@ zr36057_init_vfe (struct zoran *zr) reg |= ZR36057_VDCR_Triton; btwrite(reg, ZR36057_VDCR); } + +/* + * Interface to decoder and encoder chips using i2c bus + */ + +int +decoder_command (struct zoran *zr, + int cmd, + void *data) +{ + if (zr->decoder == NULL) + return -EIO; + + if (zr->card.type == LML33 && + (cmd == DECODER_SET_NORM || cmd == DECODER_SET_INPUT)) { + int res; + + // Bt819 needs to reset its FIFO buffer using #FRST pin and + // LML33 card uses GPIO(7) for that. + GPIO(zr, 7, 0); + res = zr->decoder->driver->command(zr->decoder, cmd, data); + // Pull #FRST high. + GPIO(zr, 7, 1); + return res; + } else + return zr->decoder->driver->command(zr->decoder, cmd, + data); +} + +int +encoder_command (struct zoran *zr, + int cmd, + void *data) +{ + if (zr->encoder == NULL) + return -1; + + return zr->encoder->driver->command(zr->encoder, cmd, data); +} diff --git a/trunk/drivers/media/video/zoran/zoran_device.h b/trunk/drivers/media/video/zoran/zoran_device.h index 07f2c23ff740..74c6c8edb7d0 100644 --- a/trunk/drivers/media/video/zoran/zoran_device.h +++ b/trunk/drivers/media/video/zoran/zoran_device.h @@ -54,8 +54,8 @@ extern int jpeg_codec_reset(struct zoran *zr); /* zr360x7 access to raw capture */ extern void zr36057_overlay(struct zoran *zr, int on); -extern void write_overlay_mask(struct zoran_fh *fh, - struct v4l2_clip *vp, +extern void write_overlay_mask(struct file *file, + struct video_clip *vp, int count); extern void zr36057_set_memgrab(struct zoran *zr, int mode); @@ -87,9 +87,11 @@ extern int jpg_bufsize; extern int pass_through; /* i2c */ -#define decoder_call(zr, o, f, args...) \ - v4l2_subdev_call(zr->decoder, o, f, ##args) -#define encoder_call(zr, o, f, args...) \ - v4l2_subdev_call(zr->encoder, o, f, ##args) +extern int decoder_command(struct zoran *zr, + int cmd, + void *data); +extern int encoder_command(struct zoran *zr, + int cmd, + void *data); #endif /* __ZORAN_DEVICE_H__ */ diff --git a/trunk/drivers/media/video/zoran/zoran_driver.c b/trunk/drivers/media/video/zoran/zoran_driver.c index f16e57cf11e4..120ef235e63d 100644 --- a/trunk/drivers/media/video/zoran/zoran_driver.c +++ b/trunk/drivers/media/video/zoran/zoran_driver.c @@ -58,6 +58,16 @@ #include #include +#define MAP_NR(x) virt_to_page(x) +#define ZORAN_VID_TYPE ( \ + VID_TYPE_CAPTURE | \ + VID_TYPE_OVERLAY | \ + VID_TYPE_CLIPPING | \ + VID_TYPE_FRAMERAM | \ + VID_TYPE_SCALES | \ + VID_TYPE_MJPEG_DECODER | \ + VID_TYPE_MJPEG_ENCODER \ + ) #include #include @@ -69,17 +79,36 @@ #include #include +#include +#include #include #include "zoran.h" #include "zoran_device.h" #include "zoran_card.h" + /* we declare some card type definitions here, they mean + * the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */ +#define ZORAN_V4L2_VID_FLAGS ( \ + V4L2_CAP_STREAMING |\ + V4L2_CAP_VIDEO_CAPTURE |\ + V4L2_CAP_VIDEO_OUTPUT |\ + V4L2_CAP_VIDEO_OVERLAY \ + ) + + +#if defined(CONFIG_VIDEO_V4L1_COMPAT) +#define ZFMT(pal, fcc, cs) \ + .palette = (pal), .fourcc = (fcc), .colorspace = (cs) +#else +#define ZFMT(pal, fcc, cs) \ + .fourcc = (fcc), .colorspace = (cs) +#endif const struct zoran_format zoran_formats[] = { { .name = "15-bit RGB LE", - .fourcc = V4L2_PIX_FMT_RGB555, - .colorspace = V4L2_COLORSPACE_SRGB, + ZFMT(VIDEO_PALETTE_RGB555, + V4L2_PIX_FMT_RGB555, V4L2_COLORSPACE_SRGB), .depth = 15, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, @@ -87,16 +116,16 @@ const struct zoran_format zoran_formats[] = { ZR36057_VFESPFR_LittleEndian, }, { .name = "15-bit RGB BE", - .fourcc = V4L2_PIX_FMT_RGB555X, - .colorspace = V4L2_COLORSPACE_SRGB, + ZFMT(-1, + V4L2_PIX_FMT_RGB555X, V4L2_COLORSPACE_SRGB), .depth = 15, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif, }, { .name = "16-bit RGB LE", - .fourcc = V4L2_PIX_FMT_RGB565, - .colorspace = V4L2_COLORSPACE_SRGB, + ZFMT(VIDEO_PALETTE_RGB565, + V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB), .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, @@ -104,56 +133,56 @@ const struct zoran_format zoran_formats[] = { ZR36057_VFESPFR_LittleEndian, }, { .name = "16-bit RGB BE", - .fourcc = V4L2_PIX_FMT_RGB565X, - .colorspace = V4L2_COLORSPACE_SRGB, + ZFMT(-1, + V4L2_PIX_FMT_RGB565X, V4L2_COLORSPACE_SRGB), .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif, }, { .name = "24-bit RGB", - .fourcc = V4L2_PIX_FMT_BGR24, - .colorspace = V4L2_COLORSPACE_SRGB, + ZFMT(VIDEO_PALETTE_RGB24, + V4L2_PIX_FMT_BGR24, V4L2_COLORSPACE_SRGB), .depth = 24, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24, }, { .name = "32-bit RGB LE", - .fourcc = V4L2_PIX_FMT_BGR32, - .colorspace = V4L2_COLORSPACE_SRGB, + ZFMT(VIDEO_PALETTE_RGB32, + V4L2_PIX_FMT_BGR32, V4L2_COLORSPACE_SRGB), .depth = 32, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian, }, { .name = "32-bit RGB BE", - .fourcc = V4L2_PIX_FMT_RGB32, - .colorspace = V4L2_COLORSPACE_SRGB, + ZFMT(-1, + V4L2_PIX_FMT_RGB32, V4L2_COLORSPACE_SRGB), .depth = 32, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB888, }, { .name = "4:2:2, packed, YUYV", - .fourcc = V4L2_PIX_FMT_YUYV, - .colorspace = V4L2_COLORSPACE_SMPTE170M, + ZFMT(VIDEO_PALETTE_YUV422, + V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_SMPTE170M), .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_YUV422, }, { .name = "4:2:2, packed, UYVY", - .fourcc = V4L2_PIX_FMT_UYVY, - .colorspace = V4L2_COLORSPACE_SMPTE170M, + ZFMT(VIDEO_PALETTE_UYVY, + V4L2_PIX_FMT_UYVY, V4L2_COLORSPACE_SMPTE170M), .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian, }, { .name = "Hardware-encoded Motion-JPEG", - .fourcc = V4L2_PIX_FMT_MJPEG, - .colorspace = V4L2_COLORSPACE_SMPTE170M, + ZFMT(-1, + V4L2_PIX_FMT_MJPEG, V4L2_COLORSPACE_SMPTE170M), .depth = 0, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_PLAYBACK | @@ -162,6 +191,13 @@ const struct zoran_format zoran_formats[] = { }; #define NUM_FORMATS ARRAY_SIZE(zoran_formats) +// RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined + + +static int lock_norm; /* 0 = default 1 = Don't change TV standard (norm) */ +module_param(lock_norm, int, 0644); +MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)"); + /* small helper function for calculating buffersizes for v4l2 * we calculate the nearest higher power-of-two, which * will be the recommended buffersize */ @@ -186,106 +222,221 @@ zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings) } /* forward references */ -static void v4l_fbuffer_free(struct zoran_fh *fh); -static void jpg_fbuffer_free(struct zoran_fh *fh); - -/* Set mapping mode */ -static void map_mode_raw(struct zoran_fh *fh) -{ - fh->map_mode = ZORAN_MAP_MODE_RAW; - fh->buffers.buffer_size = v4l_bufsize; - fh->buffers.num_buffers = v4l_nbufs; -} -static void map_mode_jpg(struct zoran_fh *fh, int play) -{ - fh->map_mode = play ? ZORAN_MAP_MODE_JPG_PLAY : ZORAN_MAP_MODE_JPG_REC; - fh->buffers.buffer_size = jpg_bufsize; - fh->buffers.num_buffers = jpg_nbufs; -} -static inline const char *mode_name(enum zoran_map_mode mode) -{ - return mode == ZORAN_MAP_MODE_RAW ? "V4L" : "JPG"; -} +static void v4l_fbuffer_free(struct file *file); +static void jpg_fbuffer_free(struct file *file); /* * Allocate the V4L grab buffers * * These have to be pysically contiguous. + * If v4l_bufsize <= MAX_KMALLOC_MEM we use kmalloc + * else we try to allocate them with bigphysarea_alloc_pages + * if the bigphysarea patch is present in the kernel, + * else we try to use high memory (if the user has bootet + * Linux with the necessary memory left over). + */ + +static unsigned long +get_high_mem (unsigned long size) +{ +/* + * Check if there is usable memory at the end of Linux memory + * of at least size. Return the physical address of this memory, + * return 0 on failure. + * + * The idea is from Alexandro Rubini's book "Linux device drivers". + * The driver from him which is downloadable from O'Reilly's + * web site misses the "virt_to_phys(high_memory)" part + * (and therefore doesn't work at all - at least with 2.2.x kernels). + * + * It should be unnecessary to mention that THIS IS DANGEROUS, + * if more than one driver at a time has the idea to use this memory!!!! */ -static int v4l_fbuffer_alloc(struct zoran_fh *fh) + volatile unsigned char __iomem *mem; + unsigned char c; + unsigned long hi_mem_ph; + unsigned long i; + + /* Map the high memory to user space */ + + hi_mem_ph = virt_to_phys(high_memory); + + mem = ioremap(hi_mem_ph, size); + if (!mem) { + dprintk(1, + KERN_ERR "%s: get_high_mem() - ioremap failed\n", + ZORAN_NAME); + return 0; + } + + for (i = 0; i < size; i++) { + /* Check if it is memory */ + c = i & 0xff; + writeb(c, mem + i); + if (readb(mem + i) != c) + break; + c = 255 - c; + writeb(c, mem + i); + if (readb(mem + i) != c) + break; + writeb(0, mem + i); /* zero out memory */ + + /* give the kernel air to breath */ + if ((i & 0x3ffff) == 0x3ffff) + schedule(); + } + + iounmap(mem); + + if (i != size) { + dprintk(1, + KERN_ERR + "%s: get_high_mem() - requested %lu, avail %lu\n", + ZORAN_NAME, size, i); + return 0; + } + + return hi_mem_ph; +} + +static int +v4l_fbuffer_alloc (struct file *file) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; int i, off; unsigned char *mem; + unsigned long pmem = 0; - for (i = 0; i < fh->buffers.num_buffers; i++) { - if (fh->buffers.buffer[i].v4l.fbuffer) + /* we might have old buffers lying around... */ + if (fh->v4l_buffers.ready_to_be_freed) { + v4l_fbuffer_free(file); + } + + for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { + if (fh->v4l_buffers.buffer[i].fbuffer) dprintk(2, KERN_WARNING - "%s: %s - buffer %d already allocated!?\n", - ZR_DEVNAME(zr), __func__, i); + "%s: v4l_fbuffer_alloc() - buffer %d allready allocated!?\n", + ZR_DEVNAME(zr), i); //udelay(20); - mem = kmalloc(fh->buffers.buffer_size, - GFP_KERNEL | __GFP_NOWARN); - if (!mem) { - dprintk(1, - KERN_ERR - "%s: %s - kmalloc for V4L buf %d failed\n", - ZR_DEVNAME(zr), __func__, i); - v4l_fbuffer_free(fh); - return -ENOBUFS; + if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) { + /* Use kmalloc */ + + mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL); + if (!mem) { + dprintk(1, + KERN_ERR + "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n", + ZR_DEVNAME(zr), i); + v4l_fbuffer_free(file); + return -ENOBUFS; + } + fh->v4l_buffers.buffer[i].fbuffer = mem; + fh->v4l_buffers.buffer[i].fbuffer_phys = + virt_to_phys(mem); + fh->v4l_buffers.buffer[i].fbuffer_bus = + virt_to_bus(mem); + for (off = 0; off < fh->v4l_buffers.buffer_size; + off += PAGE_SIZE) + SetPageReserved(MAP_NR(mem + off)); + dprintk(4, + KERN_INFO + "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n", + ZR_DEVNAME(zr), i, (unsigned long) mem, + virt_to_bus(mem)); + } else { + + /* Use high memory which has been left at boot time */ + + /* Ok., Ok. this is an evil hack - we make + * the assumption that physical addresses are + * the same as bus addresses (true at least + * for Intel processors). The whole method of + * obtaining and using this memory is not very + * nice - but I hope it saves some poor users + * from kernel hacking, which might have even + * more evil results */ + + if (i == 0) { + int size = + fh->v4l_buffers.num_buffers * + fh->v4l_buffers.buffer_size; + + pmem = get_high_mem(size); + if (pmem == 0) { + dprintk(1, + KERN_ERR + "%s: v4l_fbuffer_alloc() - get_high_mem (size = %d KB) for V4L bufs failed\n", + ZR_DEVNAME(zr), size >> 10); + return -ENOBUFS; + } + fh->v4l_buffers.buffer[0].fbuffer = NULL; + fh->v4l_buffers.buffer[0].fbuffer_phys = pmem; + fh->v4l_buffers.buffer[0].fbuffer_bus = pmem; + dprintk(4, + KERN_INFO + "%s: v4l_fbuffer_alloc() - using %d KB high memory\n", + ZR_DEVNAME(zr), size >> 10); + } else { + fh->v4l_buffers.buffer[i].fbuffer = NULL; + fh->v4l_buffers.buffer[i].fbuffer_phys = + pmem + i * fh->v4l_buffers.buffer_size; + fh->v4l_buffers.buffer[i].fbuffer_bus = + pmem + i * fh->v4l_buffers.buffer_size; + } } - fh->buffers.buffer[i].v4l.fbuffer = mem; - fh->buffers.buffer[i].v4l.fbuffer_phys = virt_to_phys(mem); - fh->buffers.buffer[i].v4l.fbuffer_bus = virt_to_bus(mem); - for (off = 0; off < fh->buffers.buffer_size; - off += PAGE_SIZE) - SetPageReserved(virt_to_page(mem + off)); - dprintk(4, - KERN_INFO - "%s: %s - V4L frame %d mem 0x%lx (bus: 0x%llx)\n", - ZR_DEVNAME(zr), __func__, i, (unsigned long) mem, - (unsigned long long)virt_to_bus(mem)); } - fh->buffers.allocated = 1; + fh->v4l_buffers.allocated = 1; return 0; } /* free the V4L grab buffers */ -static void v4l_fbuffer_free(struct zoran_fh *fh) +static void +v4l_fbuffer_free (struct file *file) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; int i, off; unsigned char *mem; - dprintk(4, KERN_INFO "%s: %s\n", ZR_DEVNAME(zr), __func__); + dprintk(4, KERN_INFO "%s: v4l_fbuffer_free()\n", ZR_DEVNAME(zr)); - for (i = 0; i < fh->buffers.num_buffers; i++) { - if (!fh->buffers.buffer[i].v4l.fbuffer) + for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { + if (!fh->v4l_buffers.buffer[i].fbuffer) continue; - mem = fh->buffers.buffer[i].v4l.fbuffer; - for (off = 0; off < fh->buffers.buffer_size; - off += PAGE_SIZE) - ClearPageReserved(virt_to_page(mem + off)); - kfree(fh->buffers.buffer[i].v4l.fbuffer); - fh->buffers.buffer[i].v4l.fbuffer = NULL; + if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) { + mem = fh->v4l_buffers.buffer[i].fbuffer; + for (off = 0; off < fh->v4l_buffers.buffer_size; + off += PAGE_SIZE) + ClearPageReserved(MAP_NR(mem + off)); + kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); + } + fh->v4l_buffers.buffer[i].fbuffer = NULL; } - fh->buffers.allocated = 0; + fh->v4l_buffers.allocated = 0; + fh->v4l_buffers.ready_to_be_freed = 0; } /* * Allocate the MJPEG grab buffers. * + * If the requested buffer size is smaller than MAX_KMALLOC_MEM, + * kmalloc is used to request a physically contiguous area, + * else we allocate the memory in framgents with get_zeroed_page. + * * If a Natoma chipset is present and this is a revision 1 zr36057, * each MJPEG buffer needs to be physically contiguous. * (RJ: This statement is from Dave Perks' original driver, * I could never check it because I have a zr36067) + * The driver cares about this because it reduces the buffer + * size to MAX_KMALLOC_MEM in that case (which forces contiguous allocation). * * RJ: The contents grab buffers needs never be accessed in the driver. * Therefore there is no need to allocate them with vmalloc in order @@ -307,128 +458,162 @@ static void v4l_fbuffer_free(struct zoran_fh *fh) * and fragment buffers are not little-endian. */ -static int jpg_fbuffer_alloc(struct zoran_fh *fh) +static int +jpg_fbuffer_alloc (struct file *file) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; int i, j, off; - u8 *mem; + unsigned long mem; + + /* we might have old buffers lying around */ + if (fh->jpg_buffers.ready_to_be_freed) { + jpg_fbuffer_free(file); + } - for (i = 0; i < fh->buffers.num_buffers; i++) { - if (fh->buffers.buffer[i].jpg.frag_tab) + for (i = 0; i < fh->jpg_buffers.num_buffers; i++) { + if (fh->jpg_buffers.buffer[i].frag_tab) dprintk(2, KERN_WARNING - "%s: %s - buffer %d already allocated!?\n", - ZR_DEVNAME(zr), __func__, i); + "%s: jpg_fbuffer_alloc() - buffer %d allready allocated!?\n", + ZR_DEVNAME(zr), i); /* Allocate fragment table for this buffer */ - mem = (void *)get_zeroed_page(GFP_KERNEL); + mem = get_zeroed_page(GFP_KERNEL); if (mem == 0) { dprintk(1, KERN_ERR - "%s: %s - get_zeroed_page (frag_tab) failed for buffer %d\n", - ZR_DEVNAME(zr), __func__, i); - jpg_fbuffer_free(fh); + "%s: jpg_fbuffer_alloc() - get_zeroed_page (frag_tab) failed for buffer %d\n", + ZR_DEVNAME(zr), i); + jpg_fbuffer_free(file); return -ENOBUFS; } - fh->buffers.buffer[i].jpg.frag_tab = (__le32 *)mem; - fh->buffers.buffer[i].jpg.frag_tab_bus = virt_to_bus(mem); - - if (fh->buffers.need_contiguous) { - mem = kmalloc(fh->buffers.buffer_size, GFP_KERNEL); - if (mem == NULL) { + fh->jpg_buffers.buffer[i].frag_tab = (__le32 *) mem; + fh->jpg_buffers.buffer[i].frag_tab_bus = + virt_to_bus((void *) mem); + + //if (alloc_contig) { + if (fh->jpg_buffers.need_contiguous) { + mem = + (unsigned long) kmalloc(fh->jpg_buffers. + buffer_size, + GFP_KERNEL); + if (mem == 0) { dprintk(1, KERN_ERR - "%s: %s - kmalloc failed for buffer %d\n", - ZR_DEVNAME(zr), __func__, i); - jpg_fbuffer_free(fh); + "%s: jpg_fbuffer_alloc() - kmalloc failed for buffer %d\n", + ZR_DEVNAME(zr), i); + jpg_fbuffer_free(file); return -ENOBUFS; } - fh->buffers.buffer[i].jpg.frag_tab[0] = - cpu_to_le32(virt_to_bus(mem)); - fh->buffers.buffer[i].jpg.frag_tab[1] = - cpu_to_le32((fh->buffers.buffer_size >> 1) | 1); - for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE) - SetPageReserved(virt_to_page(mem + off)); + fh->jpg_buffers.buffer[i].frag_tab[0] = + cpu_to_le32(virt_to_bus((void *) mem)); + fh->jpg_buffers.buffer[i].frag_tab[1] = + cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1); + for (off = 0; off < fh->jpg_buffers.buffer_size; + off += PAGE_SIZE) + SetPageReserved(MAP_NR(mem + off)); } else { - /* jpg_bufsize is already page aligned */ - for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) { - mem = (void *)get_zeroed_page(GFP_KERNEL); - if (mem == NULL) { + /* jpg_bufsize is allreay page aligned */ + for (j = 0; + j < fh->jpg_buffers.buffer_size / PAGE_SIZE; + j++) { + mem = get_zeroed_page(GFP_KERNEL); + if (mem == 0) { dprintk(1, KERN_ERR - "%s: %s - get_zeroed_page failed for buffer %d\n", - ZR_DEVNAME(zr), __func__, i); - jpg_fbuffer_free(fh); + "%s: jpg_fbuffer_alloc() - get_zeroed_page failed for buffer %d\n", + ZR_DEVNAME(zr), i); + jpg_fbuffer_free(file); return -ENOBUFS; } - fh->buffers.buffer[i].jpg.frag_tab[2 * j] = - cpu_to_le32(virt_to_bus(mem)); - fh->buffers.buffer[i].jpg.frag_tab[2 * j + 1] = - cpu_to_le32((PAGE_SIZE >> 2) << 1); - SetPageReserved(virt_to_page(mem)); + fh->jpg_buffers.buffer[i].frag_tab[2 * j] = + cpu_to_le32(virt_to_bus((void *) mem)); + fh->jpg_buffers.buffer[i].frag_tab[2 * j + + 1] = + cpu_to_le32((PAGE_SIZE / 4) << 1); + SetPageReserved(MAP_NR(mem)); } - fh->buffers.buffer[i].jpg.frag_tab[2 * j - 1] |= cpu_to_le32(1); + fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= cpu_to_le32(1); } } dprintk(4, - KERN_DEBUG "%s: %s - %d KB allocated\n", - ZR_DEVNAME(zr), __func__, - (fh->buffers.num_buffers * fh->buffers.buffer_size) >> 10); + KERN_DEBUG "%s: jpg_fbuffer_alloc() - %d KB allocated\n", + ZR_DEVNAME(zr), + (fh->jpg_buffers.num_buffers * + fh->jpg_buffers.buffer_size) >> 10); - fh->buffers.allocated = 1; + fh->jpg_buffers.allocated = 1; return 0; } /* free the MJPEG grab buffers */ -static void jpg_fbuffer_free(struct zoran_fh *fh) +static void +jpg_fbuffer_free (struct file *file) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; int i, j, off; unsigned char *mem; - __le32 frag_tab; - struct zoran_buffer *buffer; - dprintk(4, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); + dprintk(4, KERN_DEBUG "%s: jpg_fbuffer_free()\n", ZR_DEVNAME(zr)); - for (i = 0, buffer = &fh->buffers.buffer[0]; - i < fh->buffers.num_buffers; i++, buffer++) { - if (!buffer->jpg.frag_tab) + for (i = 0; i < fh->jpg_buffers.num_buffers; i++) { + if (!fh->jpg_buffers.buffer[i].frag_tab) continue; - if (fh->buffers.need_contiguous) { - frag_tab = buffer->jpg.frag_tab[0]; - - if (frag_tab) { - mem = bus_to_virt(le32_to_cpu(frag_tab)); - for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE) - ClearPageReserved(virt_to_page(mem + off)); + //if (alloc_contig) { + if (fh->jpg_buffers.need_contiguous) { + if (fh->jpg_buffers.buffer[i].frag_tab[0]) { + mem = (unsigned char *) bus_to_virt(le32_to_cpu( + fh->jpg_buffers.buffer[i].frag_tab[0])); + for (off = 0; + off < fh->jpg_buffers.buffer_size; + off += PAGE_SIZE) + ClearPageReserved(MAP_NR + (mem + off)); kfree(mem); - buffer->jpg.frag_tab[0] = 0; - buffer->jpg.frag_tab[1] = 0; + fh->jpg_buffers.buffer[i].frag_tab[0] = 0; + fh->jpg_buffers.buffer[i].frag_tab[1] = 0; } } else { - for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) { - frag_tab = buffer->jpg.frag_tab[2 * j]; - - if (!frag_tab) + for (j = 0; + j < fh->jpg_buffers.buffer_size / PAGE_SIZE; + j++) { + if (!fh->jpg_buffers.buffer[i]. + frag_tab[2 * j]) break; - ClearPageReserved(virt_to_page(bus_to_virt(le32_to_cpu(frag_tab)))); - free_page((unsigned long)bus_to_virt(le32_to_cpu(frag_tab))); - buffer->jpg.frag_tab[2 * j] = 0; - buffer->jpg.frag_tab[2 * j + 1] = 0; + ClearPageReserved(MAP_NR + (bus_to_virt + (le32_to_cpu + (fh->jpg_buffers. + buffer[i].frag_tab[2 * + j])))); + free_page((unsigned long) + bus_to_virt + (le32_to_cpu + (fh->jpg_buffers. + buffer[i]. + frag_tab[2 * j]))); + fh->jpg_buffers.buffer[i].frag_tab[2 * j] = + 0; + fh->jpg_buffers.buffer[i].frag_tab[2 * j + + 1] = 0; } } - free_page((unsigned long)buffer->jpg.frag_tab); - buffer->jpg.frag_tab = NULL; + free_page((unsigned long) fh->jpg_buffers.buffer[i]. + frag_tab); + fh->jpg_buffers.buffer[i].frag_tab = NULL; } - fh->buffers.allocated = 0; + fh->jpg_buffers.allocated = 0; + fh->jpg_buffers.ready_to_be_freed = 0; } /* @@ -436,11 +621,12 @@ static void jpg_fbuffer_free(struct zoran_fh *fh) */ static int -zoran_v4l_set_format (struct zoran_fh *fh, +zoran_v4l_set_format (struct file *file, int width, int height, const struct zoran_format *format) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; int bpp; @@ -450,19 +636,19 @@ zoran_v4l_set_format (struct zoran_fh *fh, height > BUZ_MAX_HEIGHT || width > BUZ_MAX_WIDTH) { dprintk(1, KERN_ERR - "%s: %s - wrong frame size (%dx%d)\n", - ZR_DEVNAME(zr), __func__, width, height); + "%s: v4l_set_format() - wrong frame size (%dx%d)\n", + ZR_DEVNAME(zr), width, height); return -EINVAL; } bpp = (format->depth + 7) / 8; /* Check against available buffer size */ - if (height * width * bpp > fh->buffers.buffer_size) { + if (height * width * bpp > fh->v4l_buffers.buffer_size) { dprintk(1, KERN_ERR - "%s: %s - video buffer size (%d kB) is too small\n", - ZR_DEVNAME(zr), __func__, fh->buffers.buffer_size >> 10); + "%s: v4l_set_format() - video buffer size (%d kB) is too small\n", + ZR_DEVNAME(zr), fh->v4l_buffers.buffer_size >> 10); return -EINVAL; } @@ -471,8 +657,8 @@ zoran_v4l_set_format (struct zoran_fh *fh, if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) { dprintk(1, KERN_ERR - "%s: %s - wrong frame alignment\n", - ZR_DEVNAME(zr), __func__); + "%s: v4l_set_format() - wrong frame alingment\n", + ZR_DEVNAME(zr)); return -EINVAL; } @@ -484,40 +670,43 @@ zoran_v4l_set_format (struct zoran_fh *fh, return 0; } -static int zoran_v4l_queue_frame(struct zoran_fh *fh, int num) +static int +zoran_v4l_queue_frame (struct file *file, + int num) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; unsigned long flags; int res = 0; - if (!fh->buffers.allocated) { + if (!fh->v4l_buffers.allocated) { dprintk(1, KERN_ERR - "%s: %s - buffers not yet allocated\n", - ZR_DEVNAME(zr), __func__); + "%s: v4l_queue_frame() - buffers not yet allocated\n", + ZR_DEVNAME(zr)); res = -ENOMEM; } /* No grabbing outside the buffer range! */ - if (num >= fh->buffers.num_buffers || num < 0) { + if (num >= fh->v4l_buffers.num_buffers || num < 0) { dprintk(1, KERN_ERR - "%s: %s - buffer %d is out of range\n", - ZR_DEVNAME(zr), __func__, num); + "%s: v4l_queue_frame() - buffer %d is out of range\n", + ZR_DEVNAME(zr), num); res = -EINVAL; } spin_lock_irqsave(&zr->spinlock, flags); - if (fh->buffers.active == ZORAN_FREE) { + if (fh->v4l_buffers.active == ZORAN_FREE) { if (zr->v4l_buffers.active == ZORAN_FREE) { - zr->v4l_buffers = fh->buffers; - fh->buffers.active = ZORAN_ACTIVE; + zr->v4l_buffers = fh->v4l_buffers; + fh->v4l_buffers.active = ZORAN_ACTIVE; } else { dprintk(1, KERN_ERR - "%s: %s - another session is already capturing\n", - ZR_DEVNAME(zr), __func__); + "%s: v4l_queue_frame() - another session is already capturing\n", + ZR_DEVNAME(zr)); res = -EBUSY; } } @@ -528,7 +717,7 @@ static int zoran_v4l_queue_frame(struct zoran_fh *fh, int num) default: case BUZ_STATE_PEND: if (zr->v4l_buffers.active == ZORAN_FREE) { - fh->buffers.active = ZORAN_FREE; + fh->v4l_buffers.active = ZORAN_FREE; zr->v4l_buffers.allocated = 0; } res = -EBUSY; /* what are you doing? */ @@ -536,17 +725,19 @@ static int zoran_v4l_queue_frame(struct zoran_fh *fh, int num) case BUZ_STATE_DONE: dprintk(2, KERN_WARNING - "%s: %s - queueing buffer %d in state DONE!?\n", - ZR_DEVNAME(zr), __func__, num); + "%s: v4l_queue_frame() - queueing buffer %d in state DONE!?\n", + ZR_DEVNAME(zr), num); case BUZ_STATE_USER: /* since there is at least one unused buffer there's room for at least * one more pend[] entry */ - zr->v4l_pend[zr->v4l_pend_head++ & V4L_MASK_FRAME] = num; + zr->v4l_pend[zr->v4l_pend_head++ & + V4L_MASK_FRAME] = num; zr->v4l_buffers.buffer[num].state = BUZ_STATE_PEND; zr->v4l_buffers.buffer[num].bs.length = fh->v4l_settings.bytesperline * zr->v4l_settings.height; - fh->buffers.buffer[num] = zr->v4l_buffers.buffer[num]; + fh->v4l_buffers.buffer[num] = + zr->v4l_buffers.buffer[num]; break; } } @@ -554,7 +745,65 @@ static int zoran_v4l_queue_frame(struct zoran_fh *fh, int num) spin_unlock_irqrestore(&zr->spinlock, flags); if (!res && zr->v4l_buffers.active == ZORAN_FREE) - zr->v4l_buffers.active = fh->buffers.active; + zr->v4l_buffers.active = fh->v4l_buffers.active; + + return res; +} + +static int +v4l_grab (struct file *file, + struct video_mmap *mp) +{ + struct zoran_fh *fh = file->private_data; + struct zoran *zr = fh->zr; + int res = 0, i; + + for (i = 0; i < NUM_FORMATS; i++) { + if (zoran_formats[i].palette == mp->format && + zoran_formats[i].flags & ZORAN_FORMAT_CAPTURE && + !(zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)) + break; + } + if (i == NUM_FORMATS || zoran_formats[i].depth == 0) { + dprintk(1, + KERN_ERR + "%s: v4l_grab() - wrong bytes-per-pixel format\n", + ZR_DEVNAME(zr)); + return -EINVAL; + } + + /* + * To minimize the time spent in the IRQ routine, we avoid setting up + * the video front end there. + * If this grab has different parameters from a running streaming capture + * we stop the streaming capture and start it over again. + */ + if (zr->v4l_memgrab_active && + (zr->v4l_settings.width != mp->width || + zr->v4l_settings.height != mp->height || + zr->v4l_settings.format->palette != mp->format)) { + res = wait_grab_pending(zr); + if (res) + return res; + } + if ((res = zoran_v4l_set_format(file, + mp->width, + mp->height, + &zoran_formats[i]))) + return res; + zr->v4l_settings = fh->v4l_settings; + + /* queue the frame in the pending queue */ + if ((res = zoran_v4l_queue_frame(file, mp->frame))) { + fh->v4l_buffers.active = ZORAN_FREE; + return res; + } + + /* put the 36057 into frame grabbing mode */ + if (!res && !zr->v4l_memgrab_active) + zr36057_set_memgrab(zr, 1); + + //dprintk(4, KERN_INFO "%s: Frame grab 3...\n", ZR_DEVNAME(zr)); return res; } @@ -563,24 +812,27 @@ static int zoran_v4l_queue_frame(struct zoran_fh *fh, int num) * Sync on a V4L buffer */ -static int v4l_sync(struct zoran_fh *fh, int frame) +static int +v4l_sync (struct file *file, + int frame) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; unsigned long flags; - if (fh->buffers.active == ZORAN_FREE) { + if (fh->v4l_buffers.active == ZORAN_FREE) { dprintk(1, KERN_ERR - "%s: %s - no grab active for this session\n", - ZR_DEVNAME(zr), __func__); + "%s: v4l_sync() - no grab active for this session\n", + ZR_DEVNAME(zr)); return -EINVAL; } /* check passed-in frame number */ - if (frame >= fh->buffers.num_buffers || frame < 0) { + if (frame >= fh->v4l_buffers.num_buffers || frame < 0) { dprintk(1, - KERN_ERR "%s: %s - frame %d is invalid\n", - ZR_DEVNAME(zr), __func__, frame); + KERN_ERR "%s: v4l_sync() - frame %d is invalid\n", + ZR_DEVNAME(zr), frame); return -EINVAL; } @@ -588,14 +840,15 @@ static int v4l_sync(struct zoran_fh *fh, int frame) if (zr->v4l_buffers.buffer[frame].state == BUZ_STATE_USER) { dprintk(1, KERN_ERR - "%s: %s - attempt to sync on a buffer which was not queued?\n", - ZR_DEVNAME(zr), __func__); + "%s: v4l_sync() - attempt to sync on a buffer which was not queued?\n", + ZR_DEVNAME(zr)); return -EPROTO; } /* wait on this buffer to get ready */ if (!wait_event_interruptible_timeout(zr->v4l_capq, - (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND), 10*HZ)) + (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND), + 10*HZ)) return -ETIME; if (signal_pending(current)) return -ERESTARTSYS; @@ -603,11 +856,11 @@ static int v4l_sync(struct zoran_fh *fh, int frame) /* buffer should now be in BUZ_STATE_DONE */ if (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_DONE) dprintk(2, - KERN_ERR "%s: %s - internal state error\n", - ZR_DEVNAME(zr), __func__); + KERN_ERR "%s: v4l_sync() - internal state error\n", + ZR_DEVNAME(zr)); zr->v4l_buffers.buffer[frame].state = BUZ_STATE_USER; - fh->buffers.buffer[frame] = zr->v4l_buffers.buffer[frame]; + fh->v4l_buffers.buffer[frame] = zr->v4l_buffers.buffer[frame]; spin_lock_irqsave(&zr->spinlock, flags); @@ -615,7 +868,8 @@ static int v4l_sync(struct zoran_fh *fh, int frame) if (zr->v4l_pend_tail == zr->v4l_pend_head) { zr36057_set_memgrab(zr, 0); if (zr->v4l_buffers.active == ZORAN_ACTIVE) { - fh->buffers.active = zr->v4l_buffers.active = ZORAN_FREE; + fh->v4l_buffers.active = zr->v4l_buffers.active = + ZORAN_FREE; zr->v4l_buffers.allocated = 0; } } @@ -629,28 +883,31 @@ static int v4l_sync(struct zoran_fh *fh, int frame) * Queue a MJPEG buffer for capture/playback */ -static int zoran_jpg_queue_frame(struct zoran_fh *fh, int num, - enum zoran_codec_mode mode) +static int +zoran_jpg_queue_frame (struct file *file, + int num, + enum zoran_codec_mode mode) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; unsigned long flags; int res = 0; /* Check if buffers are allocated */ - if (!fh->buffers.allocated) { + if (!fh->jpg_buffers.allocated) { dprintk(1, KERN_ERR - "%s: %s - buffers not yet allocated\n", - ZR_DEVNAME(zr), __func__); + "%s: jpg_queue_frame() - buffers not yet allocated\n", + ZR_DEVNAME(zr)); return -ENOMEM; } /* No grabbing outside the buffer range! */ - if (num >= fh->buffers.num_buffers || num < 0) { + if (num >= fh->jpg_buffers.num_buffers || num < 0) { dprintk(1, KERN_ERR - "%s: %s - buffer %d out of range\n", - ZR_DEVNAME(zr), __func__, num); + "%s: jpg_queue_frame() - buffer %d out of range\n", + ZR_DEVNAME(zr), num); return -EINVAL; } @@ -661,20 +918,20 @@ static int zoran_jpg_queue_frame(struct zoran_fh *fh, int num, /* wrong codec mode active - invalid */ dprintk(1, KERN_ERR - "%s: %s - codec in wrong mode\n", - ZR_DEVNAME(zr), __func__); + "%s: jpg_queue_frame() - codec in wrong mode\n", + ZR_DEVNAME(zr)); return -EINVAL; } - if (fh->buffers.active == ZORAN_FREE) { + if (fh->jpg_buffers.active == ZORAN_FREE) { if (zr->jpg_buffers.active == ZORAN_FREE) { - zr->jpg_buffers = fh->buffers; - fh->buffers.active = ZORAN_ACTIVE; + zr->jpg_buffers = fh->jpg_buffers; + fh->jpg_buffers.active = ZORAN_ACTIVE; } else { dprintk(1, KERN_ERR - "%s: %s - another session is already capturing\n", - ZR_DEVNAME(zr), __func__); + "%s: jpg_queue_frame() - another session is already capturing\n", + ZR_DEVNAME(zr)); res = -EBUSY; } } @@ -691,21 +948,23 @@ static int zoran_jpg_queue_frame(struct zoran_fh *fh, int num, case BUZ_STATE_DONE: dprintk(2, KERN_WARNING - "%s: %s - queing frame in BUZ_STATE_DONE state!?\n", - ZR_DEVNAME(zr), __func__); + "%s: jpg_queue_frame() - queing frame in BUZ_STATE_DONE state!?\n", + ZR_DEVNAME(zr)); case BUZ_STATE_USER: /* since there is at least one unused buffer there's room for at *least one more pend[] entry */ - zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = num; + zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = + num; zr->jpg_buffers.buffer[num].state = BUZ_STATE_PEND; - fh->buffers.buffer[num] = zr->jpg_buffers.buffer[num]; + fh->jpg_buffers.buffer[num] = + zr->jpg_buffers.buffer[num]; zoran_feed_stat_com(zr); break; default: case BUZ_STATE_DMA: case BUZ_STATE_PEND: if (zr->jpg_buffers.active == ZORAN_FREE) { - fh->buffers.active = ZORAN_FREE; + fh->jpg_buffers.active = ZORAN_FREE; zr->jpg_buffers.allocated = 0; } res = -EBUSY; /* what are you doing? */ @@ -715,41 +974,47 @@ static int zoran_jpg_queue_frame(struct zoran_fh *fh, int num, spin_unlock_irqrestore(&zr->spinlock, flags); - if (!res && zr->jpg_buffers.active == ZORAN_FREE) - zr->jpg_buffers.active = fh->buffers.active; + if (!res && zr->jpg_buffers.active == ZORAN_FREE) { + zr->jpg_buffers.active = fh->jpg_buffers.active; + } return res; } -static int jpg_qbuf(struct zoran_fh *fh, int frame, enum zoran_codec_mode mode) +static int +jpg_qbuf (struct file *file, + int frame, + enum zoran_codec_mode mode) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; int res = 0; /* Does the user want to stop streaming? */ if (frame < 0) { if (zr->codec_mode == mode) { - if (fh->buffers.active == ZORAN_FREE) { + if (fh->jpg_buffers.active == ZORAN_FREE) { dprintk(1, KERN_ERR - "%s: %s(-1) - session not active\n", - ZR_DEVNAME(zr), __func__); + "%s: jpg_qbuf(-1) - session not active\n", + ZR_DEVNAME(zr)); return -EINVAL; } - fh->buffers.active = zr->jpg_buffers.active = ZORAN_FREE; + fh->jpg_buffers.active = zr->jpg_buffers.active = + ZORAN_FREE; zr->jpg_buffers.allocated = 0; zr36057_enable_jpg(zr, BUZ_MODE_IDLE); return 0; } else { dprintk(1, KERN_ERR - "%s: %s - stop streaming but not in streaming mode\n", - ZR_DEVNAME(zr), __func__); + "%s: jpg_qbuf() - stop streaming but not in streaming mode\n", + ZR_DEVNAME(zr)); return -EINVAL; } } - if ((res = zoran_jpg_queue_frame(fh, frame, mode))) + if ((res = zoran_jpg_queue_frame(file, frame, mode))) return res; /* Start the jpeg codec when the first frame is queued */ @@ -763,25 +1028,28 @@ static int jpg_qbuf(struct zoran_fh *fh, int frame, enum zoran_codec_mode mode) * Sync on a MJPEG buffer */ -static int jpg_sync(struct zoran_fh *fh, struct zoran_sync *bs) +static int +jpg_sync (struct file *file, + struct zoran_sync *bs) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; unsigned long flags; int frame; - if (fh->buffers.active == ZORAN_FREE) { + if (fh->jpg_buffers.active == ZORAN_FREE) { dprintk(1, KERN_ERR - "%s: %s - capture is not currently active\n", - ZR_DEVNAME(zr), __func__); + "%s: jpg_sync() - capture is not currently active\n", + ZR_DEVNAME(zr)); return -EINVAL; } if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS && zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) { dprintk(1, KERN_ERR - "%s: %s - codec not in streaming mode\n", - ZR_DEVNAME(zr), __func__); + "%s: jpg_sync() - codec not in streaming mode\n", + ZR_DEVNAME(zr)); return -EINVAL; } if (!wait_event_interruptible_timeout(zr->jpg_capq, @@ -796,8 +1064,8 @@ static int jpg_sync(struct zoran_fh *fh, struct zoran_sync *bs) sizeof(isr), &isr); dprintk(1, KERN_ERR - "%s: %s - timeout: codec isr=0x%02x\n", - ZR_DEVNAME(zr), __func__, isr); + "%s: jpg_sync() - timeout: codec isr=0x%02x\n", + ZR_DEVNAME(zr), isr); return -ETIME; @@ -815,26 +1083,28 @@ static int jpg_sync(struct zoran_fh *fh, struct zoran_sync *bs) /* buffer should now be in BUZ_STATE_DONE */ if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE) dprintk(2, - KERN_ERR "%s: %s - internal state error\n", - ZR_DEVNAME(zr), __func__); + KERN_ERR "%s: jpg_sync() - internal state error\n", + ZR_DEVNAME(zr)); *bs = zr->jpg_buffers.buffer[frame].bs; bs->frame = frame; zr->jpg_buffers.buffer[frame].state = BUZ_STATE_USER; - fh->buffers.buffer[frame] = zr->jpg_buffers.buffer[frame]; + fh->jpg_buffers.buffer[frame] = zr->jpg_buffers.buffer[frame]; spin_unlock_irqrestore(&zr->spinlock, flags); return 0; } -static void zoran_open_init_session(struct zoran_fh *fh) +static void +zoran_open_init_session (struct file *file) { int i; + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; /* Per default, map the V4L Buffers */ - map_mode_raw(fh); + fh->map_mode = ZORAN_MAP_MODE_RAW; /* take over the card's current settings */ fh->overlay_settings = zr->overlay_settings; @@ -844,21 +1114,40 @@ static void zoran_open_init_session(struct zoran_fh *fh) /* v4l settings */ fh->v4l_settings = zr->v4l_settings; + + /* v4l_buffers */ + memset(&fh->v4l_buffers, 0, sizeof(struct zoran_v4l_struct)); + for (i = 0; i < VIDEO_MAX_FRAME; i++) { + fh->v4l_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ + fh->v4l_buffers.buffer[i].bs.frame = i; + } + fh->v4l_buffers.allocated = 0; + fh->v4l_buffers.ready_to_be_freed = 0; + fh->v4l_buffers.active = ZORAN_FREE; + fh->v4l_buffers.buffer_size = v4l_bufsize; + fh->v4l_buffers.num_buffers = v4l_nbufs; + /* jpg settings */ fh->jpg_settings = zr->jpg_settings; - /* buffers */ - memset(&fh->buffers, 0, sizeof(fh->buffers)); - for (i = 0; i < MAX_FRAME; i++) { - fh->buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ - fh->buffers.buffer[i].bs.frame = i; + /* jpg_buffers */ + memset(&fh->jpg_buffers, 0, sizeof(struct zoran_jpg_struct)); + for (i = 0; i < BUZ_MAX_FRAME; i++) { + fh->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ + fh->jpg_buffers.buffer[i].bs.frame = i; } - fh->buffers.allocated = 0; - fh->buffers.active = ZORAN_FREE; + fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous; + fh->jpg_buffers.allocated = 0; + fh->jpg_buffers.ready_to_be_freed = 0; + fh->jpg_buffers.active = ZORAN_FREE; + fh->jpg_buffers.buffer_size = jpg_bufsize; + fh->jpg_buffers.num_buffers = jpg_nbufs; } -static void zoran_close_end_session(struct zoran_fh *fh) +static void +zoran_close_end_session (struct file *file) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; /* overlay */ @@ -870,32 +1159,36 @@ static void zoran_close_end_session(struct zoran_fh *fh) zr->overlay_mask = NULL; } - if (fh->map_mode == ZORAN_MAP_MODE_RAW) { - /* v4l capture */ - if (fh->buffers.active != ZORAN_FREE) { - unsigned long flags; + /* v4l capture */ + if (fh->v4l_buffers.active != ZORAN_FREE) { + unsigned long flags; - spin_lock_irqsave(&zr->spinlock, flags); - zr36057_set_memgrab(zr, 0); - zr->v4l_buffers.allocated = 0; - zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE; - spin_unlock_irqrestore(&zr->spinlock, flags); - } + spin_lock_irqsave(&zr->spinlock, flags); + zr36057_set_memgrab(zr, 0); + zr->v4l_buffers.allocated = 0; + zr->v4l_buffers.active = fh->v4l_buffers.active = + ZORAN_FREE; + spin_unlock_irqrestore(&zr->spinlock, flags); + } - /* v4l buffers */ - if (fh->buffers.allocated) - v4l_fbuffer_free(fh); - } else { - /* jpg capture */ - if (fh->buffers.active != ZORAN_FREE) { - zr36057_enable_jpg(zr, BUZ_MODE_IDLE); - zr->jpg_buffers.allocated = 0; - zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE; - } + /* v4l buffers */ + if (fh->v4l_buffers.allocated || + fh->v4l_buffers.ready_to_be_freed) { + v4l_fbuffer_free(file); + } + + /* jpg capture */ + if (fh->jpg_buffers.active != ZORAN_FREE) { + zr36057_enable_jpg(zr, BUZ_MODE_IDLE); + zr->jpg_buffers.allocated = 0; + zr->jpg_buffers.active = fh->jpg_buffers.active = + ZORAN_FREE; + } - /* jpg buffers */ - if (fh->buffers.allocated) - jpg_fbuffer_free(fh); + /* jpg buffers */ + if (fh->jpg_buffers.allocated || + fh->jpg_buffers.ready_to_be_freed) { + jpg_fbuffer_free(file); } } @@ -909,11 +1202,15 @@ static int zoran_open(struct file *file) struct zoran_fh *fh; int res, first_open = 0; - dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(-)=%d\n", - ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user + 1); + dprintk(2, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n", + ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user + 1); lock_kernel(); + /* see fs/device.c - the kernel already locks during open(), + * so locking ourselves only causes deadlocks */ + /*mutex_lock(&zr->resource_lock);*/ + if (zr->user >= 2048) { dprintk(1, KERN_ERR "%s: too many users (%d) on device\n", ZR_DEVNAME(zr), zr->user); @@ -921,15 +1218,41 @@ static int zoran_open(struct file *file) goto fail_unlock; } + if (!zr->decoder) { + dprintk(1, + KERN_ERR "%s: no TV decoder loaded for device!\n", + ZR_DEVNAME(zr)); + res = -EIO; + goto fail_unlock; + } + + if (!try_module_get(zr->decoder->driver->driver.owner)) { + dprintk(1, + KERN_ERR + "%s: failed to grab ownership of video decoder\n", + ZR_DEVNAME(zr)); + res = -EIO; + goto fail_unlock; + } + if (zr->encoder && + !try_module_get(zr->encoder->driver->driver.owner)) { + dprintk(1, + KERN_ERR + "%s: failed to grab ownership of video encoder\n", + ZR_DEVNAME(zr)); + res = -EIO; + goto fail_decoder; + } + /* now, create the open()-specific file_ops struct */ fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL); if (!fh) { dprintk(1, KERN_ERR - "%s: %s - allocation of zoran_fh failed\n", - ZR_DEVNAME(zr), __func__); + "%s: zoran_open() - allocation of zoran_fh failed\n", + ZR_DEVNAME(zr)); res = -ENOMEM; - goto fail_unlock; + goto fail_encoder; } /* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows * on norm-change! */ @@ -938,8 +1261,8 @@ static int zoran_open(struct file *file) if (!fh->overlay_mask) { dprintk(1, KERN_ERR - "%s: %s - allocation of overlay_mask failed\n", - ZR_DEVNAME(zr), __func__); + "%s: zoran_open() - allocation of overlay_mask failed\n", + ZR_DEVNAME(zr)); res = -ENOMEM; goto fail_fh; } @@ -961,13 +1284,18 @@ static int zoran_open(struct file *file) /* set file_ops stuff */ file->private_data = fh; fh->zr = zr; - zoran_open_init_session(fh); + zoran_open_init_session(file); unlock_kernel(); return 0; fail_fh: kfree(fh); +fail_encoder: + if (zr->encoder) + module_put(zr->encoder->driver->driver.owner); +fail_decoder: + module_put(zr->decoder->driver->driver.owner); fail_unlock: unlock_kernel(); @@ -983,14 +1311,14 @@ zoran_close(struct file *file) struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; - dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(+)=%d\n", - ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user - 1); + dprintk(2, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n", + ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user - 1); /* kernel locks (fs/device.c), so don't do that ourselves * (prevents deadlocks) */ /*mutex_lock(&zr->resource_lock);*/ - zoran_close_end_session(fh); + zoran_close_end_session(file); if (zr->user-- == 1) { /* Last process */ /* Clean up JPEG process */ @@ -1018,10 +1346,9 @@ zoran_close(struct file *file) zoran_set_pci_master(zr, 0); if (!pass_through) { /* Switch to color bar */ - struct v4l2_routing route = { 2, 0 }; - - decoder_call(zr, video, s_stream, 0); - encoder_call(zr, video, s_routing, &route); + int zero = 0, two = 2; + decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero); + encoder_command(zr, ENCODER_SET_INPUT, &two); } } @@ -1029,7 +1356,14 @@ zoran_close(struct file *file) kfree(fh->overlay_mask); kfree(fh); - dprintk(4, KERN_INFO "%s: %s done\n", ZR_DEVNAME(zr), __func__); + /* release locks on the i2c modules */ + module_put(zr->decoder->driver->driver.owner); + if (zr->encoder) + module_put(zr->encoder->driver->driver.owner); + + /*mutex_unlock(&zr->resource_lock);*/ + + dprintk(4, KERN_INFO "%s: zoran_close() done\n", ZR_DEVNAME(zr)); return 0; } @@ -1057,13 +1391,15 @@ zoran_write (struct file *file, return -EINVAL; } -static int setup_fbuffer(struct zoran_fh *fh, +static int +setup_fbuffer (struct file *file, void *base, const struct zoran_format *fmt, int width, int height, int bytesperline) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; /* (Ronald) v4l/v4l2 guidelines */ @@ -1091,8 +1427,8 @@ static int setup_fbuffer(struct zoran_fh *fh, * friendly and silently do as if nothing went wrong */ dprintk(3, KERN_ERR - "%s: %s - forced overlay turnoff because framebuffer changed\n", - ZR_DEVNAME(zr), __func__); + "%s: setup_fbuffer() - forced overlay turnoff because framebuffer changed\n", + ZR_DEVNAME(zr)); zr36057_overlay(zr, 0); } #endif @@ -1100,31 +1436,31 @@ static int setup_fbuffer(struct zoran_fh *fh, if (!(fmt->flags & ZORAN_FORMAT_OVERLAY)) { dprintk(1, KERN_ERR - "%s: %s - no valid overlay format given\n", - ZR_DEVNAME(zr), __func__); + "%s: setup_fbuffer() - no valid overlay format given\n", + ZR_DEVNAME(zr)); return -EINVAL; } if (height <= 0 || width <= 0 || bytesperline <= 0) { dprintk(1, KERN_ERR - "%s: %s - invalid height/width/bpl value (%d|%d|%d)\n", - ZR_DEVNAME(zr), __func__, width, height, bytesperline); + "%s: setup_fbuffer() - invalid height/width/bpl value (%d|%d|%d)\n", + ZR_DEVNAME(zr), width, height, bytesperline); return -EINVAL; } if (bytesperline & 3) { dprintk(1, KERN_ERR - "%s: %s - bytesperline (%d) must be 4-byte aligned\n", - ZR_DEVNAME(zr), __func__, bytesperline); + "%s: setup_fbuffer() - bytesperline (%d) must be 4-byte aligned\n", + ZR_DEVNAME(zr), bytesperline); return -EINVAL; } - zr->vbuf_base = (void *) ((unsigned long) base & ~3); - zr->vbuf_height = height; - zr->vbuf_width = width; - zr->vbuf_depth = fmt->depth; + zr->buffer.base = (void *) ((unsigned long) base & ~3); + zr->buffer.height = height; + zr->buffer.width = width; + zr->buffer.depth = fmt->depth; zr->overlay_settings.format = fmt; - zr->vbuf_bytesperline = bytesperline; + zr->buffer.bytesperline = bytesperline; /* The user should set new window parameters */ zr->overlay_settings.is_set = 0; @@ -1133,27 +1469,35 @@ static int setup_fbuffer(struct zoran_fh *fh, } -static int setup_window(struct zoran_fh *fh, int x, int y, int width, int height, - struct v4l2_clip __user *clips, int clipcount, void __user *bitmap) +static int +setup_window (struct file *file, + int x, + int y, + int width, + int height, + struct video_clip __user *clips, + int clipcount, + void __user *bitmap) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; - struct v4l2_clip *vcp = NULL; + struct video_clip *vcp = NULL; int on, end; - if (!zr->vbuf_base) { + if (!zr->buffer.base) { dprintk(1, KERN_ERR - "%s: %s - frame buffer has to be set first\n", - ZR_DEVNAME(zr), __func__); + "%s: setup_window() - frame buffer has to be set first\n", + ZR_DEVNAME(zr)); return -EINVAL; } if (!fh->overlay_settings.format) { dprintk(1, KERN_ERR - "%s: %s - no overlay format set\n", - ZR_DEVNAME(zr), __func__); + "%s: setup_window() - no overlay format set\n", + ZR_DEVNAME(zr)); return -EINVAL; } @@ -1161,13 +1505,13 @@ static int setup_window(struct zoran_fh *fh, int x, int y, int width, int height * The video front end needs 4-byte alinged line sizes, we correct that * silently here if necessary */ - if (zr->vbuf_depth == 15 || zr->vbuf_depth == 16) { + if (zr->buffer.depth == 15 || zr->buffer.depth == 16) { end = (x + width) & ~1; /* round down */ x = (x + 1) & ~1; /* round up */ width = end - x; } - if (zr->vbuf_depth == 24) { + if (zr->buffer.depth == 24) { end = (x + width) & ~3; /* round down */ x = (x + 3) & ~3; /* round up */ width = end - x; @@ -1183,8 +1527,8 @@ static int setup_window(struct zoran_fh *fh, int x, int y, int width, int height width > BUZ_MAX_WIDTH || height > BUZ_MAX_HEIGHT) { dprintk(1, KERN_ERR - "%s: %s - width = %d or height = %d invalid\n", - ZR_DEVNAME(zr), __func__, width, height); + "%s: setup_window() - width = %d or height = %d invalid\n", + ZR_DEVNAME(zr), width, height); return -EINVAL; } @@ -1222,20 +1566,20 @@ static int setup_window(struct zoran_fh *fh, int x, int y, int width, int height } } else if (clipcount > 0) { /* write our own bitmap from the clips */ - vcp = vmalloc(sizeof(struct v4l2_clip) * (clipcount + 4)); + vcp = vmalloc(sizeof(struct video_clip) * (clipcount + 4)); if (vcp == NULL) { dprintk(1, KERN_ERR - "%s: %s - Alloc of clip mask failed\n", - ZR_DEVNAME(zr), __func__); + "%s: setup_window() - Alloc of clip mask failed\n", + ZR_DEVNAME(zr)); return -ENOMEM; } if (copy_from_user - (vcp, clips, sizeof(struct v4l2_clip) * clipcount)) { + (vcp, clips, sizeof(struct video_clip) * clipcount)) { vfree(vcp); return -EFAULT; } - write_overlay_mask(fh, vcp, clipcount); + write_overlay_mask(file, vcp, clipcount); vfree(vcp); } @@ -1251,8 +1595,11 @@ static int setup_window(struct zoran_fh *fh, int x, int y, int width, int height return wait_grab_pending(zr); } -static int setup_overlay(struct zoran_fh *fh, int on) +static int +setup_overlay (struct file *file, + int on) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; /* If there is nothing to do, return immediatly */ @@ -1265,16 +1612,16 @@ static int setup_overlay(struct zoran_fh *fh, int on) fh->overlay_active == ZORAN_FREE) { dprintk(1, KERN_ERR - "%s: %s - overlay is already active for another session\n", - ZR_DEVNAME(zr), __func__); + "%s: setup_overlay() - overlay is already active for another session\n", + ZR_DEVNAME(zr)); return -EBUSY; } if (!on && zr->overlay_active != ZORAN_FREE && fh->overlay_active == ZORAN_FREE) { dprintk(1, KERN_ERR - "%s: %s - you cannot cancel someone else's session\n", - ZR_DEVNAME(zr), __func__); + "%s: setup_overlay() - you cannot cancel someone else's session\n", + ZR_DEVNAME(zr)); return -EPERM; } @@ -1287,18 +1634,18 @@ static int setup_overlay(struct zoran_fh *fh, int on) zr36057_overlay(zr, 0); zr->overlay_mask = NULL; } else { - if (!zr->vbuf_base || !fh->overlay_settings.is_set) { + if (!zr->buffer.base || !fh->overlay_settings.is_set) { dprintk(1, KERN_ERR - "%s: %s - buffer or window not set\n", - ZR_DEVNAME(zr), __func__); + "%s: setup_overlay() - buffer or window not set\n", + ZR_DEVNAME(zr)); return -EINVAL; } if (!fh->overlay_settings.format) { dprintk(1, KERN_ERR - "%s: %s - no overlay format set\n", - ZR_DEVNAME(zr), __func__); + "%s: setup_overlay() - no overlay format set\n", + ZR_DEVNAME(zr)); return -EINVAL; } zr->overlay_active = fh->overlay_active = ZORAN_LOCKED; @@ -1315,47 +1662,41 @@ static int setup_overlay(struct zoran_fh *fh, int on) return wait_grab_pending(zr); } -/* get the status of a buffer in the clients buffer queue */ -static int zoran_v4l2_buffer_status(struct zoran_fh *fh, - struct v4l2_buffer *buf, int num) + /* get the status of a buffer in the clients buffer queue */ +static int +zoran_v4l2_buffer_status (struct file *file, + struct v4l2_buffer *buf, + int num) { + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; - unsigned long flags; buf->flags = V4L2_BUF_FLAG_MAPPED; switch (fh->map_mode) { case ZORAN_MAP_MODE_RAW: + /* check range */ - if (num < 0 || num >= fh->buffers.num_buffers || - !fh->buffers.allocated) { + if (num < 0 || num >= fh->v4l_buffers.num_buffers || + !fh->v4l_buffers.allocated) { dprintk(1, KERN_ERR - "%s: %s - wrong number or buffers not allocated\n", - ZR_DEVNAME(zr), __func__); + "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n", + ZR_DEVNAME(zr)); return -EINVAL; } - spin_lock_irqsave(&zr->spinlock, flags); - dprintk(3, - KERN_DEBUG - "%s: %s() - raw active=%c, buffer %d: state=%c, map=%c\n", - ZR_DEVNAME(zr), __func__, - "FAL"[fh->buffers.active], num, - "UPMD"[zr->v4l_buffers.buffer[num].state], - fh->buffers.buffer[num].map ? 'Y' : 'N'); - spin_unlock_irqrestore(&zr->spinlock, flags); - buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf->length = fh->buffers.buffer_size; + buf->length = fh->v4l_buffers.buffer_size; /* get buffer */ - buf->bytesused = fh->buffers.buffer[num].bs.length; - if (fh->buffers.buffer[num].state == BUZ_STATE_DONE || - fh->buffers.buffer[num].state == BUZ_STATE_USER) { - buf->sequence = fh->buffers.buffer[num].bs.seq; + buf->bytesused = fh->v4l_buffers.buffer[num].bs.length; + if (fh->v4l_buffers.buffer[num].state == BUZ_STATE_DONE || + fh->v4l_buffers.buffer[num].state == BUZ_STATE_USER) { + buf->sequence = fh->v4l_buffers.buffer[num].bs.seq; buf->flags |= V4L2_BUF_FLAG_DONE; - buf->timestamp = fh->buffers.buffer[num].bs.timestamp; + buf->timestamp = + fh->v4l_buffers.buffer[num].bs.timestamp; } else { buf->flags |= V4L2_BUF_FLAG_QUEUED; } @@ -1371,26 +1712,28 @@ static int zoran_v4l2_buffer_status(struct zoran_fh *fh, case ZORAN_MAP_MODE_JPG_PLAY: /* check range */ - if (num < 0 || num >= fh->buffers.num_buffers || - !fh->buffers.allocated) { + if (num < 0 || num >= fh->jpg_buffers.num_buffers || + !fh->jpg_buffers.allocated) { dprintk(1, KERN_ERR - "%s: %s - wrong number or buffers not allocated\n", - ZR_DEVNAME(zr), __func__); + "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n", + ZR_DEVNAME(zr)); return -EINVAL; } buf->type = (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ? V4L2_BUF_TYPE_VIDEO_CAPTURE : V4L2_BUF_TYPE_VIDEO_OUTPUT; - buf->length = fh->buffers.buffer_size; + buf->length = fh->jpg_buffers.buffer_size; /* these variables are only written after frame has been captured */ - if (fh->buffers.buffer[num].state == BUZ_STATE_DONE || - fh->buffers.buffer[num].state == BUZ_STATE_USER) { - buf->sequence = fh->buffers.buffer[num].bs.seq; - buf->timestamp = fh->buffers.buffer[num].bs.timestamp; - buf->bytesused = fh->buffers.buffer[num].bs.length; + if (fh->jpg_buffers.buffer[num].state == BUZ_STATE_DONE || + fh->jpg_buffers.buffer[num].state == BUZ_STATE_USER) { + buf->sequence = fh->jpg_buffers.buffer[num].bs.seq; + buf->timestamp = + fh->jpg_buffers.buffer[num].bs.timestamp; + buf->bytesused = + fh->jpg_buffers.buffer[num].bs.length; buf->flags |= V4L2_BUF_FLAG_DONE; } else { buf->flags |= V4L2_BUF_FLAG_QUEUED; @@ -1398,11 +1741,14 @@ static int zoran_v4l2_buffer_status(struct zoran_fh *fh, /* which fields are these? */ if (fh->jpg_settings.TmpDcm != 1) - buf->field = fh->jpg_settings.odd_even ? - V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; + buf->field = + fh->jpg_settings. + odd_even ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; else - buf->field = fh->jpg_settings.odd_even ? - V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT; + buf->field = + fh->jpg_settings. + odd_even ? V4L2_FIELD_SEQ_TB : + V4L2_FIELD_SEQ_BT; break; @@ -1410,8 +1756,8 @@ static int zoran_v4l2_buffer_status(struct zoran_fh *fh, dprintk(5, KERN_ERR - "%s: %s - invalid buffer type|map_mode (%d|%d)\n", - ZR_DEVNAME(zr), __func__, buf->type, fh->map_mode); + "%s: v4l2_buffer_status() - invalid buffer type|map_mode (%d|%d)\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); return -EINVAL; } @@ -1424,55 +1770,81 @@ static int zoran_v4l2_buffer_status(struct zoran_fh *fh, static int zoran_set_norm (struct zoran *zr, - v4l2_std_id norm) + int norm) /* VIDEO_MODE_* */ { - int on; + int norm_encoder, on; if (zr->v4l_buffers.active != ZORAN_FREE || zr->jpg_buffers.active != ZORAN_FREE) { dprintk(1, KERN_WARNING - "%s: %s called while in playback/capture mode\n", - ZR_DEVNAME(zr), __func__); + "%s: set_norm() called while in playback/capture mode\n", + ZR_DEVNAME(zr)); return -EBUSY; } - if (!(norm & zr->card.norms)) { + if (lock_norm && norm != zr->norm) { + if (lock_norm > 1) { + dprintk(1, + KERN_WARNING + "%s: set_norm() - TV standard is locked, can not switch norm\n", + ZR_DEVNAME(zr)); + return -EPERM; + } else { + dprintk(1, + KERN_WARNING + "%s: set_norm() - TV standard is locked, norm was not changed\n", + ZR_DEVNAME(zr)); + norm = zr->norm; + } + } + + if (norm != VIDEO_MODE_AUTO && + (norm < 0 || norm >= zr->card.norms || + !zr->card.tvn[norm])) { dprintk(1, - KERN_ERR "%s: %s - unsupported norm %llx\n", - ZR_DEVNAME(zr), __func__, norm); + KERN_ERR "%s: set_norm() - unsupported norm %d\n", + ZR_DEVNAME(zr), norm); return -EINVAL; } - if (norm == V4L2_STD_ALL) { - int status = 0; - v4l2_std_id std = 0; + if (norm == VIDEO_MODE_AUTO) { + int status; + + /* if we have autodetect, ... */ + struct video_decoder_capability caps; + decoder_command(zr, DECODER_GET_CAPABILITIES, &caps); + if (!(caps.flags & VIDEO_DECODER_AUTO)) { + dprintk(1, KERN_ERR "%s: norm=auto unsupported\n", + ZR_DEVNAME(zr)); + return -EINVAL; + } - decoder_call(zr, video, querystd, &std); - decoder_call(zr, tuner, s_std, std); + decoder_command(zr, DECODER_SET_NORM, &norm); /* let changes come into effect */ ssleep(2); - decoder_call(zr, video, g_input_status, &status); - if (status & V4L2_IN_ST_NO_SIGNAL) { + decoder_command(zr, DECODER_GET_STATUS, &status); + if (!(status & DECODER_STATUS_GOOD)) { dprintk(1, KERN_ERR - "%s: %s - no norm detected\n", - ZR_DEVNAME(zr), __func__); + "%s: set_norm() - no norm detected\n", + ZR_DEVNAME(zr)); /* reset norm */ - decoder_call(zr, tuner, s_std, zr->norm); + decoder_command(zr, DECODER_SET_NORM, &zr->norm); return -EIO; } - norm = std; + if (status & DECODER_STATUS_NTSC) + norm = VIDEO_MODE_NTSC; + else if (status & DECODER_STATUS_SECAM) + norm = VIDEO_MODE_SECAM; + else + norm = VIDEO_MODE_PAL; } - if (norm & V4L2_STD_SECAM) - zr->timing = zr->card.tvn[2]; - else if (norm & V4L2_STD_NTSC) - zr->timing = zr->card.tvn[1]; - else - zr->timing = zr->card.tvn[0]; + zr->timing = zr->card.tvn[norm]; + norm_encoder = norm; /* We switch overlay off and on since a change in the * norm needs different VFE settings */ @@ -1480,8 +1852,8 @@ zoran_set_norm (struct zoran *zr, if (on) zr36057_overlay(zr, 0); - decoder_call(zr, tuner, s_std, norm); - encoder_call(zr, video, s_std_output, norm); + decoder_command(zr, DECODER_SET_NORM, &norm); + encoder_command(zr, ENCODER_SET_NORM, &norm_encoder); if (on) zr36057_overlay(zr, 1); @@ -1496,7 +1868,7 @@ static int zoran_set_input (struct zoran *zr, int input) { - struct v4l2_routing route = { 0, 0 }; + int realinput; if (input == zr->input) { return 0; @@ -1506,23 +1878,23 @@ zoran_set_input (struct zoran *zr, zr->jpg_buffers.active != ZORAN_FREE) { dprintk(1, KERN_WARNING - "%s: %s called while in playback/capture mode\n", - ZR_DEVNAME(zr), __func__); + "%s: set_input() called while in playback/capture mode\n", + ZR_DEVNAME(zr)); return -EBUSY; } if (input < 0 || input >= zr->card.inputs) { dprintk(1, KERN_ERR - "%s: %s - unnsupported input %d\n", - ZR_DEVNAME(zr), __func__, input); + "%s: set_input() - unnsupported input %d\n", + ZR_DEVNAME(zr), input); return -EINVAL; } - route.input = zr->card.input[input].muxsel; + realinput = zr->card.input[input].muxsel; zr->input = input; - decoder_call(zr, video, s_routing, &route); + decoder_command(zr, DECODER_SET_INPUT, &realinput); return 0; } @@ -1531,45 +1903,435 @@ zoran_set_input (struct zoran *zr, * ioctl routine */ -#ifdef CONFIG_VIDEO_V4L1_COMPAT -static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) +static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) { - struct zoran_fh *fh = __fh; + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; + /* CAREFUL: used in multiple places here */ struct zoran_jpg_settings settings; + /* we might have older buffers lying around... We don't want + * to wait, but we do want to try cleaning them up ASAP. So + * we try to obtain the lock and free them. If that fails, we + * don't do anything and wait for the next turn. In the end, + * zoran_close() or a new allocation will still free them... + * This is just a 'the sooner the better' extra 'feature' + * + * We don't free the buffers right on munmap() because that + * causes oopses (kfree() inside munmap() oopses for no + * apparent reason - it's also not reproduceable in any way, + * but moving the free code outside the munmap() handler fixes + * all this... If someone knows why, please explain me (Ronald) + */ + if (mutex_trylock(&zr->resource_lock)) { + /* we obtained it! Let's try to free some things */ + if (fh->jpg_buffers.ready_to_be_freed) + jpg_fbuffer_free(file); + if (fh->v4l_buffers.ready_to_be_freed) + v4l_fbuffer_free(file); + + mutex_unlock(&zr->resource_lock); + } + switch (cmd) { - case BUZIOC_G_PARAMS: + + case VIDIOCGCAP: { - struct zoran_params *bparams = arg; + struct video_capability *vcap = arg; - dprintk(3, KERN_DEBUG "%s: BUZIOC_G_PARAMS\n", ZR_DEVNAME(zr)); + dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr)); - memset(bparams, 0, sizeof(struct zoran_params)); - bparams->major_version = MAJOR_VERSION; - bparams->minor_version = MINOR_VERSION; + memset(vcap, 0, sizeof(struct video_capability)); + strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name)-1); + vcap->type = ZORAN_VID_TYPE; + vcap->channels = zr->card.inputs; + vcap->audios = 0; mutex_lock(&zr->resource_lock); + vcap->maxwidth = BUZ_MAX_WIDTH; + vcap->maxheight = BUZ_MAX_HEIGHT; + vcap->minwidth = BUZ_MIN_WIDTH; + vcap->minheight = BUZ_MIN_HEIGHT; + mutex_unlock(&zr->resource_lock); - if (zr->norm & V4L2_STD_NTSC) - bparams->norm = VIDEO_MODE_NTSC; - else if (zr->norm & V4L2_STD_PAL) - bparams->norm = VIDEO_MODE_PAL; - else - bparams->norm = VIDEO_MODE_SECAM; + return 0; + } + break; - bparams->input = zr->input; + case VIDIOCGCHAN: + { + struct video_channel *vchan = arg; + int channel = vchan->channel; - bparams->decimation = fh->jpg_settings.decimation; - bparams->HorDcm = fh->jpg_settings.HorDcm; - bparams->VerDcm = fh->jpg_settings.VerDcm; - bparams->TmpDcm = fh->jpg_settings.TmpDcm; - bparams->field_per_buff = fh->jpg_settings.field_per_buff; - bparams->img_x = fh->jpg_settings.img_x; - bparams->img_y = fh->jpg_settings.img_y; - bparams->img_width = fh->jpg_settings.img_width; - bparams->img_height = fh->jpg_settings.img_height; - bparams->odd_even = fh->jpg_settings.odd_even; + dprintk(3, KERN_DEBUG "%s: VIDIOCGCHAN - channel=%d\n", + ZR_DEVNAME(zr), vchan->channel); + + memset(vchan, 0, sizeof(struct video_channel)); + if (channel > zr->card.inputs || channel < 0) { + dprintk(1, + KERN_ERR + "%s: VIDIOCGCHAN on not existing channel %d\n", + ZR_DEVNAME(zr), channel); + return -EINVAL; + } + + strcpy(vchan->name, zr->card.input[channel].name); + + vchan->tuners = 0; + vchan->flags = 0; + vchan->type = VIDEO_TYPE_CAMERA; + mutex_lock(&zr->resource_lock); + vchan->norm = zr->norm; + mutex_unlock(&zr->resource_lock); + vchan->channel = channel; + + return 0; + } + break; + + /* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says: + * + * * "The VIDIOCSCHAN ioctl takes an integer argument and switches the capture to this input." + * * ^^^^^^^ + * * The famos BTTV driver has it implemented with a struct video_channel argument + * * and we follow it for compatibility reasons + * * + * * BTW: this is the only way the user can set the norm! + */ + + case VIDIOCSCHAN: + { + struct video_channel *vchan = arg; + int res; + + dprintk(3, + KERN_DEBUG + "%s: VIDIOCSCHAN - channel=%d, norm=%d\n", + ZR_DEVNAME(zr), vchan->channel, vchan->norm); + + mutex_lock(&zr->resource_lock); + if ((res = zoran_set_input(zr, vchan->channel))) + goto schan_unlock_and_return; + if ((res = zoran_set_norm(zr, vchan->norm))) + goto schan_unlock_and_return; + + /* Make sure the changes come into effect */ + res = wait_grab_pending(zr); + schan_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; + } + break; + + case VIDIOCGPICT: + { + struct video_picture *vpict = arg; + + dprintk(3, KERN_DEBUG "%s: VIDIOCGPICT\n", ZR_DEVNAME(zr)); + + memset(vpict, 0, sizeof(struct video_picture)); + mutex_lock(&zr->resource_lock); + vpict->hue = zr->hue; + vpict->brightness = zr->brightness; + vpict->contrast = zr->contrast; + vpict->colour = zr->saturation; + if (fh->overlay_settings.format) { + vpict->depth = fh->overlay_settings.format->depth; + vpict->palette = fh->overlay_settings.format->palette; + } else { + vpict->depth = 0; + } + mutex_unlock(&zr->resource_lock); + + return 0; + } + break; + + case VIDIOCSPICT: + { + struct video_picture *vpict = arg; + int i; + + dprintk(3, + KERN_DEBUG + "%s: VIDIOCSPICT - bri=%d, hue=%d, col=%d, con=%d, dep=%d, pal=%d\n", + ZR_DEVNAME(zr), vpict->brightness, vpict->hue, + vpict->colour, vpict->contrast, vpict->depth, + vpict->palette); + + for (i = 0; i < NUM_FORMATS; i++) { + const struct zoran_format *fmt = &zoran_formats[i]; + + if (fmt->palette != -1 && + fmt->flags & ZORAN_FORMAT_OVERLAY && + fmt->palette == vpict->palette && + fmt->depth == vpict->depth) + break; + } + if (i == NUM_FORMATS) { + dprintk(1, + KERN_ERR + "%s: VIDIOCSPICT - Invalid palette %d\n", + ZR_DEVNAME(zr), vpict->palette); + return -EINVAL; + } + + mutex_lock(&zr->resource_lock); + + decoder_command(zr, DECODER_SET_PICTURE, vpict); + + zr->hue = vpict->hue; + zr->contrast = vpict->contrast; + zr->saturation = vpict->colour; + zr->brightness = vpict->brightness; + + fh->overlay_settings.format = &zoran_formats[i]; + + mutex_unlock(&zr->resource_lock); + + return 0; + } + break; + + case VIDIOCCAPTURE: + { + int *on = arg, res; + + dprintk(3, KERN_DEBUG "%s: VIDIOCCAPTURE - on=%d\n", + ZR_DEVNAME(zr), *on); + + mutex_lock(&zr->resource_lock); + res = setup_overlay(file, *on); + mutex_unlock(&zr->resource_lock); + + return res; + } + break; + + case VIDIOCGWIN: + { + struct video_window *vwin = arg; + + dprintk(3, KERN_DEBUG "%s: VIDIOCGWIN\n", ZR_DEVNAME(zr)); + + memset(vwin, 0, sizeof(struct video_window)); + mutex_lock(&zr->resource_lock); + vwin->x = fh->overlay_settings.x; + vwin->y = fh->overlay_settings.y; + vwin->width = fh->overlay_settings.width; + vwin->height = fh->overlay_settings.height; + mutex_unlock(&zr->resource_lock); + vwin->clipcount = 0; + return 0; + } + break; + + case VIDIOCSWIN: + { + struct video_window *vwin = arg; + int res; + + dprintk(3, + KERN_DEBUG + "%s: VIDIOCSWIN - x=%d, y=%d, w=%d, h=%d, clipcount=%d\n", + ZR_DEVNAME(zr), vwin->x, vwin->y, vwin->width, + vwin->height, vwin->clipcount); + + mutex_lock(&zr->resource_lock); + res = + setup_window(file, vwin->x, vwin->y, vwin->width, + vwin->height, vwin->clips, + vwin->clipcount, NULL); + mutex_unlock(&zr->resource_lock); + + return res; + } + break; + + case VIDIOCGFBUF: + { + struct video_buffer *vbuf = arg; + + dprintk(3, KERN_DEBUG "%s: VIDIOCGFBUF\n", ZR_DEVNAME(zr)); + + mutex_lock(&zr->resource_lock); + *vbuf = zr->buffer; + mutex_unlock(&zr->resource_lock); + return 0; + } + break; + + case VIDIOCSFBUF: + { + struct video_buffer *vbuf = arg; + int i, res = 0; + + dprintk(3, + KERN_DEBUG + "%s: VIDIOCSFBUF - base=%p, w=%d, h=%d, depth=%d, bpl=%d\n", + ZR_DEVNAME(zr), vbuf->base, vbuf->width, + vbuf->height, vbuf->depth, vbuf->bytesperline); + + for (i = 0; i < NUM_FORMATS; i++) + if (zoran_formats[i].depth == vbuf->depth) + break; + if (i == NUM_FORMATS) { + dprintk(1, + KERN_ERR + "%s: VIDIOCSFBUF - invalid fbuf depth %d\n", + ZR_DEVNAME(zr), vbuf->depth); + return -EINVAL; + } + + mutex_lock(&zr->resource_lock); + res = + setup_fbuffer(file, vbuf->base, &zoran_formats[i], + vbuf->width, vbuf->height, + vbuf->bytesperline); + mutex_unlock(&zr->resource_lock); + + return res; + } + break; + + case VIDIOCSYNC: + { + int *frame = arg, res; + + dprintk(3, KERN_DEBUG "%s: VIDIOCSYNC - frame=%d\n", + ZR_DEVNAME(zr), *frame); + + mutex_lock(&zr->resource_lock); + res = v4l_sync(file, *frame); + mutex_unlock(&zr->resource_lock); + if (!res) + zr->v4l_sync_tail++; + return res; + } + break; + + case VIDIOCMCAPTURE: + { + struct video_mmap *vmap = arg; + int res; + + dprintk(3, + KERN_DEBUG + "%s: VIDIOCMCAPTURE - frame=%d, geom=%dx%d, fmt=%d\n", + ZR_DEVNAME(zr), vmap->frame, vmap->width, vmap->height, + vmap->format); + + mutex_lock(&zr->resource_lock); + res = v4l_grab(file, vmap); + mutex_unlock(&zr->resource_lock); + return res; + } + break; + + case VIDIOCGMBUF: + { + struct video_mbuf *vmbuf = arg; + int i, res = 0; + + dprintk(3, KERN_DEBUG "%s: VIDIOCGMBUF\n", ZR_DEVNAME(zr)); + + vmbuf->size = + fh->v4l_buffers.num_buffers * + fh->v4l_buffers.buffer_size; + vmbuf->frames = fh->v4l_buffers.num_buffers; + for (i = 0; i < vmbuf->frames; i++) { + vmbuf->offsets[i] = + i * fh->v4l_buffers.buffer_size; + } + + mutex_lock(&zr->resource_lock); + + if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { + dprintk(1, + KERN_ERR + "%s: VIDIOCGMBUF - buffers already allocated\n", + ZR_DEVNAME(zr)); + res = -EINVAL; + goto v4l1reqbuf_unlock_and_return; + } + + if (v4l_fbuffer_alloc(file)) { + res = -ENOMEM; + goto v4l1reqbuf_unlock_and_return; + } + + /* The next mmap will map the V4L buffers */ + fh->map_mode = ZORAN_MAP_MODE_RAW; + v4l1reqbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); + + return res; + } + break; + + case VIDIOCGUNIT: + { + struct video_unit *vunit = arg; + + dprintk(3, KERN_DEBUG "%s: VIDIOCGUNIT\n", ZR_DEVNAME(zr)); + + vunit->video = zr->video_dev->minor; + vunit->vbi = VIDEO_NO_UNIT; + vunit->radio = VIDEO_NO_UNIT; + vunit->audio = VIDEO_NO_UNIT; + vunit->teletext = VIDEO_NO_UNIT; + + return 0; + } + break; + + /* + * RJ: In principal we could support subcaptures for V4L grabbing. + * Not even the famous BTTV driver has them, however. + * If there should be a strong demand, one could consider + * to implement them. + */ + case VIDIOCGCAPTURE: + { + dprintk(3, KERN_ERR "%s: VIDIOCGCAPTURE not supported\n", + ZR_DEVNAME(zr)); + return -EINVAL; + } + break; + + case VIDIOCSCAPTURE: + { + dprintk(3, KERN_ERR "%s: VIDIOCSCAPTURE not supported\n", + ZR_DEVNAME(zr)); + return -EINVAL; + } + break; + + case BUZIOC_G_PARAMS: + { + struct zoran_params *bparams = arg; + + dprintk(3, KERN_DEBUG "%s: BUZIOC_G_PARAMS\n", ZR_DEVNAME(zr)); + + memset(bparams, 0, sizeof(struct zoran_params)); + bparams->major_version = MAJOR_VERSION; + bparams->minor_version = MINOR_VERSION; + + mutex_lock(&zr->resource_lock); + + bparams->norm = zr->norm; + bparams->input = zr->input; + + bparams->decimation = fh->jpg_settings.decimation; + bparams->HorDcm = fh->jpg_settings.HorDcm; + bparams->VerDcm = fh->jpg_settings.VerDcm; + bparams->TmpDcm = fh->jpg_settings.TmpDcm; + bparams->field_per_buff = fh->jpg_settings.field_per_buff; + bparams->img_x = fh->jpg_settings.img_x; + bparams->img_y = fh->jpg_settings.img_y; + bparams->img_width = fh->jpg_settings.img_width; + bparams->img_height = fh->jpg_settings.img_height; + bparams->odd_even = fh->jpg_settings.odd_even; bparams->quality = fh->jpg_settings.jpg_comp.quality; bparams->APPn = fh->jpg_settings.jpg_comp.APPn; @@ -1590,6 +2352,7 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) return 0; } + break; case BUZIOC_S_PARAMS: { @@ -1632,17 +2395,18 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) /* Check the params first before overwriting our * nternal values */ - if (zoran_check_jpg_settings(zr, &settings, 0)) { + if (zoran_check_jpg_settings(zr, &settings)) { res = -EINVAL; goto sparams_unlock_and_return; } fh->jpg_settings = settings; -sparams_unlock_and_return: + sparams_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; } + break; case BUZIOC_REQBUFS: { @@ -1666,34 +2430,38 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) * tables to a Maximum of 2 MB */ if (breq->size > jpg_bufsize) breq->size = jpg_bufsize; + if (fh->jpg_buffers.need_contiguous && + breq->size > MAX_KMALLOC_MEM) + breq->size = MAX_KMALLOC_MEM; mutex_lock(&zr->resource_lock); - if (fh->buffers.allocated) { + if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { dprintk(1, KERN_ERR - "%s: BUZIOC_REQBUFS - buffers already allocated\n", + "%s: BUZIOC_REQBUFS - buffers allready allocated\n", ZR_DEVNAME(zr)); res = -EBUSY; goto jpgreqbuf_unlock_and_return; } - /* The next mmap will map the MJPEG buffers - could - * also be *_PLAY, but it doesn't matter here */ - map_mode_jpg(fh, 0); - fh->buffers.num_buffers = breq->count; - fh->buffers.buffer_size = breq->size; + fh->jpg_buffers.num_buffers = breq->count; + fh->jpg_buffers.buffer_size = breq->size; - if (jpg_fbuffer_alloc(fh)) { + if (jpg_fbuffer_alloc(file)) { res = -ENOMEM; goto jpgreqbuf_unlock_and_return; } -jpgreqbuf_unlock_and_return: + /* The next mmap will map the MJPEG buffers - could + * also be *_PLAY, but it doesn't matter here */ + fh->map_mode = ZORAN_MAP_MODE_JPG_REC; + jpgreqbuf_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; } + break; case BUZIOC_QBUF_CAPT: { @@ -1703,11 +2471,12 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) ZR_DEVNAME(zr), *frame); mutex_lock(&zr->resource_lock); - res = jpg_qbuf(fh, *frame, BUZ_MODE_MOTION_COMPRESS); + res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_COMPRESS); mutex_unlock(&zr->resource_lock); return res; } + break; case BUZIOC_QBUF_PLAY: { @@ -1717,11 +2486,12 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) ZR_DEVNAME(zr), *frame); mutex_lock(&zr->resource_lock); - res = jpg_qbuf(fh, *frame, BUZ_MODE_MOTION_DECOMPRESS); + res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_DECOMPRESS); mutex_unlock(&zr->resource_lock); return res; } + break; case BUZIOC_SYNC: { @@ -1731,26 +2501,17 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) dprintk(3, KERN_DEBUG "%s: BUZIOC_SYNC\n", ZR_DEVNAME(zr)); mutex_lock(&zr->resource_lock); - - if (fh->map_mode == ZORAN_MAP_MODE_RAW) { - dprintk(2, KERN_WARNING - "%s: %s - not in jpg capture mode\n", - ZR_DEVNAME(zr), __func__); - res = -EINVAL; - } else { - res = jpg_sync(fh, bsync); - } + res = jpg_sync(file, bsync); mutex_unlock(&zr->resource_lock); return res; } + break; case BUZIOC_G_STATUS: { struct zoran_status *bstat = arg; - struct v4l2_routing route = { 0, 0 }; - int status = 0, res = 0; - v4l2_std_id norm; + int norm, input, status, res = 0; dprintk(3, KERN_DEBUG "%s: BUZIOC_G_STATUS\n", ZR_DEVNAME(zr)); @@ -1762,7 +2523,8 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) return -EINVAL; } - route.input = zr->card.input[bstat->input].muxsel; + input = zr->card.input[bstat->input].muxsel; + norm = VIDEO_MODE_AUTO; mutex_lock(&zr->resource_lock); @@ -1775,1262 +2537,1629 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) goto gstat_unlock_and_return; } - decoder_call(zr, video, s_routing, &route); + decoder_command(zr, DECODER_SET_INPUT, &input); + decoder_command(zr, DECODER_SET_NORM, &norm); /* sleep 1 second */ ssleep(1); /* Get status of video decoder */ - decoder_call(zr, video, querystd, &norm); - decoder_call(zr, video, g_input_status, &status); + decoder_command(zr, DECODER_GET_STATUS, &status); /* restore previous input and norm */ - route.input = zr->card.input[zr->input].muxsel; - decoder_call(zr, video, s_routing, &route); -gstat_unlock_and_return: + input = zr->card.input[zr->input].muxsel; + decoder_command(zr, DECODER_SET_INPUT, &input); + decoder_command(zr, DECODER_SET_NORM, &zr->norm); + gstat_unlock_and_return: mutex_unlock(&zr->resource_lock); if (!res) { bstat->signal = - (status & V4L2_IN_ST_NO_SIGNAL) ? 0 : 1; - if (norm & V4L2_STD_NTSC) + (status & DECODER_STATUS_GOOD) ? 1 : 0; + if (status & DECODER_STATUS_NTSC) bstat->norm = VIDEO_MODE_NTSC; - else if (norm & V4L2_STD_SECAM) + else if (status & DECODER_STATUS_SECAM) bstat->norm = VIDEO_MODE_SECAM; else bstat->norm = VIDEO_MODE_PAL; bstat->color = - (status & V4L2_IN_ST_NO_COLOR) ? 0 : 1; + (status & DECODER_STATUS_COLOR) ? 1 : 0; } return res; } + break; - default: - return -EINVAL; - } -} + /* The new video4linux2 capture interface - much nicer than video4linux1, since + * it allows for integrating the JPEG capturing calls inside standard v4l2 + */ -static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *vmbuf) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int i, res = 0; + case VIDIOC_QUERYCAP: + { + struct v4l2_capability *cap = arg; + dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr)); - mutex_lock(&zr->resource_lock); + memset(cap, 0, sizeof(*cap)); + strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1); + strncpy(cap->driver, "zoran", sizeof(cap->driver)-1); + snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", + pci_name(zr->pci_dev)); + cap->version = + KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION, + RELEASE_VERSION); + cap->capabilities = ZORAN_V4L2_VID_FLAGS; - if (fh->buffers.allocated) { - dprintk(1, - KERN_ERR - "%s: VIDIOCGMBUF - buffers already allocated\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto v4l1reqbuf_unlock_and_return; + return 0; } + break; - /* The next mmap will map the V4L buffers */ - map_mode_raw(fh); + case VIDIOC_ENUM_FMT: + { + struct v4l2_fmtdesc *fmt = arg; + int index = fmt->index, num = -1, i, flag = 0, type = + fmt->type; - if (v4l_fbuffer_alloc(fh)) { - res = -ENOMEM; - goto v4l1reqbuf_unlock_and_return; - } + dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUM_FMT - index=%d\n", + ZR_DEVNAME(zr), fmt->index); - vmbuf->size = fh->buffers.num_buffers * fh->buffers.buffer_size; - vmbuf->frames = fh->buffers.num_buffers; - for (i = 0; i < vmbuf->frames; i++) - vmbuf->offsets[i] = i * fh->buffers.buffer_size; + switch (fmt->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + flag = ZORAN_FORMAT_CAPTURE; + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + flag = ZORAN_FORMAT_PLAYBACK; + break; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + flag = ZORAN_FORMAT_OVERLAY; + break; + default: + dprintk(1, + KERN_ERR + "%s: VIDIOC_ENUM_FMT - unknown type %d\n", + ZR_DEVNAME(zr), fmt->type); + return -EINVAL; + } -v4l1reqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); + for (i = 0; i < NUM_FORMATS; i++) { + if (zoran_formats[i].flags & flag) + num++; + if (num == fmt->index) + break; + } + if (fmt->index < 0 /* late, but not too late */ || + i == NUM_FORMATS) + return -EINVAL; - return res; -} -#endif + memset(fmt, 0, sizeof(*fmt)); + fmt->index = index; + fmt->type = type; + strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1); + fmt->pixelformat = zoran_formats[i].fourcc; + if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) + fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; -static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + return 0; + } + break; - memset(cap, 0, sizeof(*cap)); - strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1); - strncpy(cap->driver, "zoran", sizeof(cap->driver)-1); - snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", - pci_name(zr->pci_dev)); - cap->version = KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION, - RELEASE_VERSION); - cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OVERLAY; - return 0; -} + case VIDIOC_G_FMT: + { + struct v4l2_format *fmt = arg; + int type = fmt->type; -static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag) -{ - int num = -1, i; + dprintk(5, KERN_DEBUG "%s: VIDIOC_G_FMT\n", ZR_DEVNAME(zr)); + + memset(fmt, 0, sizeof(*fmt)); + fmt->type = type; + + switch (fmt->type) { + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + + mutex_lock(&zr->resource_lock); + + fmt->fmt.win.w.left = fh->overlay_settings.x; + fmt->fmt.win.w.top = fh->overlay_settings.y; + fmt->fmt.win.w.width = fh->overlay_settings.width; + fmt->fmt.win.w.height = + fh->overlay_settings.height; + if (fh->overlay_settings.width * 2 > + BUZ_MAX_HEIGHT) + fmt->fmt.win.field = V4L2_FIELD_INTERLACED; + else + fmt->fmt.win.field = V4L2_FIELD_TOP; + + mutex_unlock(&zr->resource_lock); - for (i = 0; i < NUM_FORMATS; i++) { - if (zoran_formats[i].flags & flag) - num++; - if (num == fmt->index) break; - } - if (fmt->index < 0 /* late, but not too late */ || i == NUM_FORMATS) - return -EINVAL; - strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1); - fmt->pixelformat = zoran_formats[i].fourcc; - if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) - fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; - return 0; -} + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + + mutex_lock(&zr->resource_lock); + + if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && + fh->map_mode == ZORAN_MAP_MODE_RAW) { + + fmt->fmt.pix.width = + fh->v4l_settings.width; + fmt->fmt.pix.height = + fh->v4l_settings.height; + fmt->fmt.pix.sizeimage = + fh->v4l_settings.bytesperline * + fh->v4l_settings.height; + fmt->fmt.pix.pixelformat = + fh->v4l_settings.format->fourcc; + fmt->fmt.pix.colorspace = + fh->v4l_settings.format->colorspace; + fmt->fmt.pix.bytesperline = + fh->v4l_settings.bytesperline; + if (BUZ_MAX_HEIGHT < + (fh->v4l_settings.height * 2)) + fmt->fmt.pix.field = + V4L2_FIELD_INTERLACED; + else + fmt->fmt.pix.field = + V4L2_FIELD_TOP; + + } else { + + fmt->fmt.pix.width = + fh->jpg_settings.img_width / + fh->jpg_settings.HorDcm; + fmt->fmt.pix.height = + fh->jpg_settings.img_height / + (fh->jpg_settings.VerDcm * + fh->jpg_settings.TmpDcm); + fmt->fmt.pix.sizeimage = + zoran_v4l2_calc_bufsize(&fh-> + jpg_settings); + fmt->fmt.pix.pixelformat = + V4L2_PIX_FMT_MJPEG; + if (fh->jpg_settings.TmpDcm == 1) + fmt->fmt.pix.field = + (fh->jpg_settings. + odd_even ? V4L2_FIELD_SEQ_BT : + V4L2_FIELD_SEQ_BT); + else + fmt->fmt.pix.field = + (fh->jpg_settings. + odd_even ? V4L2_FIELD_TOP : + V4L2_FIELD_BOTTOM); + + fmt->fmt.pix.bytesperline = 0; + fmt->fmt.pix.colorspace = + V4L2_COLORSPACE_SMPTE170M; + } -static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh, - struct v4l2_fmtdesc *f) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + mutex_unlock(&zr->resource_lock); - return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE); -} + break; -static int zoran_enum_fmt_vid_out(struct file *file, void *__fh, - struct v4l2_fmtdesc *f) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + default: + dprintk(1, + KERN_ERR + "%s: VIDIOC_G_FMT - unsupported type %d\n", + ZR_DEVNAME(zr), fmt->type); + return -EINVAL; + } + return 0; + } + break; - return zoran_enum_fmt(zr, f, ZORAN_FORMAT_PLAYBACK); -} + case VIDIOC_S_FMT: + { + struct v4l2_format *fmt = arg; + int i, res = 0; + __le32 printformat; + + dprintk(3, KERN_DEBUG "%s: VIDIOC_S_FMT - type=%d, ", + ZR_DEVNAME(zr), fmt->type); + + switch (fmt->type) { + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + + dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n", + fmt->fmt.win.w.left, fmt->fmt.win.w.top, + fmt->fmt.win.w.width, + fmt->fmt.win.w.height, + fmt->fmt.win.clipcount, + fmt->fmt.win.bitmap); + mutex_lock(&zr->resource_lock); + res = + setup_window(file, fmt->fmt.win.w.left, + fmt->fmt.win.w.top, + fmt->fmt.win.w.width, + fmt->fmt.win.w.height, + (struct video_clip __user *) + fmt->fmt.win.clips, + fmt->fmt.win.clipcount, + fmt->fmt.win.bitmap); + mutex_unlock(&zr->resource_lock); + return res; + break; -static int zoran_enum_fmt_vid_overlay(struct file *file, void *__fh, - struct v4l2_fmtdesc *f) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + + printformat = + __cpu_to_le32(fmt->fmt.pix.pixelformat); + dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n", + fmt->fmt.pix.width, fmt->fmt.pix.height, + fmt->fmt.pix.pixelformat, + (char *) &printformat); + + /* we can be requested to do JPEG/raw playback/capture */ + if (! + (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || + (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && + fmt->fmt.pix.pixelformat == + V4L2_PIX_FMT_MJPEG))) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_S_FMT - unknown type %d/0x%x(%4.4s) combination\n", + ZR_DEVNAME(zr), fmt->type, + fmt->fmt.pix.pixelformat, + (char *) &printformat); + return -EINVAL; + } - return zoran_enum_fmt(zr, f, ZORAN_FORMAT_OVERLAY); -} + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) { + mutex_lock(&zr->resource_lock); -static int zoran_g_fmt_vid_out(struct file *file, void *__fh, - struct v4l2_format *fmt) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + settings = fh->jpg_settings; - mutex_lock(&zr->resource_lock); + if (fh->v4l_buffers.allocated || + fh->jpg_buffers.allocated) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_S_FMT - cannot change capture mode\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto sfmtjpg_unlock_and_return; + } - fmt->fmt.pix.width = fh->jpg_settings.img_width / fh->jpg_settings.HorDcm; - fmt->fmt.pix.height = fh->jpg_settings.img_height * 2 / - (fh->jpg_settings.VerDcm * fh->jpg_settings.TmpDcm); - fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&fh->jpg_settings); - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; - if (fh->jpg_settings.TmpDcm == 1) - fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? - V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); - else - fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? - V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); - fmt->fmt.pix.bytesperline = 0; - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + /* we actually need to set 'real' parameters now */ + if ((fmt->fmt.pix.height * 2) > + BUZ_MAX_HEIGHT) + settings.TmpDcm = 1; + else + settings.TmpDcm = 2; + settings.decimation = 0; + if (fmt->fmt.pix.height <= + fh->jpg_settings.img_height / 2) + settings.VerDcm = 2; + else + settings.VerDcm = 1; + if (fmt->fmt.pix.width <= + fh->jpg_settings.img_width / 4) + settings.HorDcm = 4; + else if (fmt->fmt.pix.width <= + fh->jpg_settings.img_width / 2) + settings.HorDcm = 2; + else + settings.HorDcm = 1; + if (settings.TmpDcm == 1) + settings.field_per_buff = 2; + else + settings.field_per_buff = 1; + + /* check */ + if ((res = + zoran_check_jpg_settings(zr, + &settings))) + goto sfmtjpg_unlock_and_return; + + /* it's ok, so set them */ + fh->jpg_settings = settings; + + /* tell the user what we actually did */ + fmt->fmt.pix.width = + settings.img_width / settings.HorDcm; + fmt->fmt.pix.height = + settings.img_height * 2 / + (settings.TmpDcm * settings.VerDcm); + if (settings.TmpDcm == 1) + fmt->fmt.pix.field = + (fh->jpg_settings. + odd_even ? V4L2_FIELD_SEQ_TB : + V4L2_FIELD_SEQ_BT); + else + fmt->fmt.pix.field = + (fh->jpg_settings. + odd_even ? V4L2_FIELD_TOP : + V4L2_FIELD_BOTTOM); + fh->jpg_buffers.buffer_size = + zoran_v4l2_calc_bufsize(&fh-> + jpg_settings); + fmt->fmt.pix.bytesperline = 0; + fmt->fmt.pix.sizeimage = + fh->jpg_buffers.buffer_size; + fmt->fmt.pix.colorspace = + V4L2_COLORSPACE_SMPTE170M; + + /* we hereby abuse this variable to show that + * we're gonna do mjpeg capture */ + fh->map_mode = + (fmt->type == + V4L2_BUF_TYPE_VIDEO_CAPTURE) ? + ZORAN_MAP_MODE_JPG_REC : + ZORAN_MAP_MODE_JPG_PLAY; + sfmtjpg_unlock_and_return: + mutex_unlock(&zr->resource_lock); + } else { + for (i = 0; i < NUM_FORMATS; i++) + if (fmt->fmt.pix.pixelformat == + zoran_formats[i].fourcc) + break; + if (i == NUM_FORMATS) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x (%4.4s)\n", + ZR_DEVNAME(zr), + fmt->fmt.pix.pixelformat, + (char *) &printformat); + return -EINVAL; + } + mutex_lock(&zr->resource_lock); + if (fh->jpg_buffers.allocated || + (fh->v4l_buffers.allocated && + fh->v4l_buffers.active != + ZORAN_FREE)) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_S_FMT - cannot change capture mode\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto sfmtv4l_unlock_and_return; + } + if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) + fmt->fmt.pix.height = + BUZ_MAX_HEIGHT; + if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) + fmt->fmt.pix.width = BUZ_MAX_WIDTH; + + if ((res = + zoran_v4l_set_format(file, + fmt->fmt.pix. + width, + fmt->fmt.pix. + height, + &zoran_formats + [i]))) + goto sfmtv4l_unlock_and_return; + + /* tell the user the + * results/missing stuff */ + fmt->fmt.pix.bytesperline = + fh->v4l_settings.bytesperline; + fmt->fmt.pix.sizeimage = + fh->v4l_settings.height * + fh->v4l_settings.bytesperline; + fmt->fmt.pix.colorspace = + fh->v4l_settings.format->colorspace; + if (BUZ_MAX_HEIGHT < + (fh->v4l_settings.height * 2)) + fmt->fmt.pix.field = + V4L2_FIELD_INTERLACED; + else + fmt->fmt.pix.field = + V4L2_FIELD_TOP; + + fh->map_mode = ZORAN_MAP_MODE_RAW; + sfmtv4l_unlock_and_return: + mutex_unlock(&zr->resource_lock); + } - mutex_unlock(&zr->resource_lock); - return 0; -} + break; -static int zoran_g_fmt_vid_cap(struct file *file, void *__fh, - struct v4l2_format *fmt) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + default: + dprintk(1, + KERN_ERR + "%s: VIDIOC_S_FMT - unsupported type %d\n", + ZR_DEVNAME(zr), fmt->type); + return -EINVAL; + } - if (fh->map_mode != ZORAN_MAP_MODE_RAW) - return zoran_g_fmt_vid_out(file, fh, fmt); + return res; + } + break; - mutex_lock(&zr->resource_lock); - fmt->fmt.pix.width = fh->v4l_settings.width; - fmt->fmt.pix.height = fh->v4l_settings.height; - fmt->fmt.pix.sizeimage = fh->v4l_settings.bytesperline * - fh->v4l_settings.height; - fmt->fmt.pix.pixelformat = fh->v4l_settings.format->fourcc; - fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace; - fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline; - if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) - fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; - else - fmt->fmt.pix.field = V4L2_FIELD_TOP; - mutex_unlock(&zr->resource_lock); - return 0; -} + case VIDIOC_G_FBUF: + { + struct v4l2_framebuffer *fb = arg; -static int zoran_g_fmt_vid_overlay(struct file *file, void *__fh, - struct v4l2_format *fmt) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + dprintk(3, KERN_DEBUG "%s: VIDIOC_G_FBUF\n", ZR_DEVNAME(zr)); - mutex_lock(&zr->resource_lock); + memset(fb, 0, sizeof(*fb)); + mutex_lock(&zr->resource_lock); + fb->base = zr->buffer.base; + fb->fmt.width = zr->buffer.width; + fb->fmt.height = zr->buffer.height; + if (zr->overlay_settings.format) { + fb->fmt.pixelformat = + fh->overlay_settings.format->fourcc; + } + fb->fmt.bytesperline = zr->buffer.bytesperline; + mutex_unlock(&zr->resource_lock); + fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; + fb->fmt.field = V4L2_FIELD_INTERLACED; + fb->flags = V4L2_FBUF_FLAG_OVERLAY; + fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; - fmt->fmt.win.w.left = fh->overlay_settings.x; - fmt->fmt.win.w.top = fh->overlay_settings.y; - fmt->fmt.win.w.width = fh->overlay_settings.width; - fmt->fmt.win.w.height = fh->overlay_settings.height; - if (fh->overlay_settings.width * 2 > BUZ_MAX_HEIGHT) - fmt->fmt.win.field = V4L2_FIELD_INTERLACED; - else - fmt->fmt.win.field = V4L2_FIELD_TOP; + return 0; + } + break; - mutex_unlock(&zr->resource_lock); - return 0; -} + case VIDIOC_S_FBUF: + { + int i, res = 0; + struct v4l2_framebuffer *fb = arg; + __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat); -static int zoran_try_fmt_vid_overlay(struct file *file, void *__fh, - struct v4l2_format *fmt) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + dprintk(3, + KERN_DEBUG + "%s: VIDIOC_S_FBUF - base=0x%p, size=%dx%d, bpl=%d, fmt=0x%x (%4.4s)\n", + ZR_DEVNAME(zr), fb->base, fb->fmt.width, fb->fmt.height, + fb->fmt.bytesperline, fb->fmt.pixelformat, + (char *) &printformat); - mutex_lock(&zr->resource_lock); + for (i = 0; i < NUM_FORMATS; i++) + if (zoran_formats[i].fourcc == fb->fmt.pixelformat) + break; + if (i == NUM_FORMATS) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n", + ZR_DEVNAME(zr), fb->fmt.pixelformat, + (char *) &printformat); + return -EINVAL; + } - if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH) - fmt->fmt.win.w.width = BUZ_MAX_WIDTH; - if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH) - fmt->fmt.win.w.width = BUZ_MIN_WIDTH; - if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT) - fmt->fmt.win.w.height = BUZ_MAX_HEIGHT; - if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT) - fmt->fmt.win.w.height = BUZ_MIN_HEIGHT; + mutex_lock(&zr->resource_lock); + res = + setup_fbuffer(file, fb->base, &zoran_formats[i], + fb->fmt.width, fb->fmt.height, + fb->fmt.bytesperline); + mutex_unlock(&zr->resource_lock); - mutex_unlock(&zr->resource_lock); - return 0; -} + return res; + } + break; -static int zoran_try_fmt_vid_out(struct file *file, void *__fh, - struct v4l2_format *fmt) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - struct zoran_jpg_settings settings; - int res = 0; + case VIDIOC_OVERLAY: + { + int *on = arg, res; - if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) - return -EINVAL; + dprintk(3, KERN_DEBUG "%s: VIDIOC_PREVIEW - on=%d\n", + ZR_DEVNAME(zr), *on); - mutex_lock(&zr->resource_lock); - settings = fh->jpg_settings; + mutex_lock(&zr->resource_lock); + res = setup_overlay(file, *on); + mutex_unlock(&zr->resource_lock); - /* we actually need to set 'real' parameters now */ - if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT) - settings.TmpDcm = 1; - else - settings.TmpDcm = 2; - settings.decimation = 0; - if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2) - settings.VerDcm = 2; - else - settings.VerDcm = 1; - if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4) - settings.HorDcm = 4; - else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2) - settings.HorDcm = 2; - else - settings.HorDcm = 1; - if (settings.TmpDcm == 1) - settings.field_per_buff = 2; - else - settings.field_per_buff = 1; + return res; + } + break; - if (settings.HorDcm > 1) { - settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; - settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; - } else { - settings.img_x = 0; - settings.img_width = BUZ_MAX_WIDTH; - } - - /* check */ - res = zoran_check_jpg_settings(zr, &settings, 1); - if (res) - goto tryfmt_unlock_and_return; - - /* tell the user what we actually did */ - fmt->fmt.pix.width = settings.img_width / settings.HorDcm; - fmt->fmt.pix.height = settings.img_height * 2 / - (settings.TmpDcm * settings.VerDcm); - if (settings.TmpDcm == 1) - fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? - V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); - else - fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? - V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); + case VIDIOC_REQBUFS: + { + struct v4l2_requestbuffers *req = arg; + int res = 0; - fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings); - fmt->fmt.pix.bytesperline = 0; - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; -tryfmt_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; -} + dprintk(3, KERN_DEBUG "%s: VIDIOC_REQBUFS - type=%d\n", + ZR_DEVNAME(zr), req->type); -static int zoran_try_fmt_vid_cap(struct file *file, void *__fh, - struct v4l2_format *fmt) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int bpp; - int i; + if (req->memory != V4L2_MEMORY_MMAP) { + dprintk(1, + KERN_ERR + "%s: only MEMORY_MMAP capture is supported, not %d\n", + ZR_DEVNAME(zr), req->memory); + return -EINVAL; + } - if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) - return zoran_try_fmt_vid_out(file, fh, fmt); + mutex_lock(&zr->resource_lock); - mutex_lock(&zr->resource_lock); + if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_REQBUFS - buffers allready allocated\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto v4l2reqbuf_unlock_and_return; + } - for (i = 0; i < NUM_FORMATS; i++) - if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat) - break; + if (fh->map_mode == ZORAN_MAP_MODE_RAW && + req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - if (i == NUM_FORMATS) { - mutex_unlock(&zr->resource_lock); - return -EINVAL; - } + /* control user input */ + if (req->count < 2) + req->count = 2; + if (req->count > v4l_nbufs) + req->count = v4l_nbufs; + fh->v4l_buffers.num_buffers = req->count; - bpp = (zoran_formats[i].depth + 7) / 8; - fmt->fmt.pix.width &= ~((bpp == 2) ? 1 : 3); - if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) - fmt->fmt.pix.width = BUZ_MAX_WIDTH; - if (fmt->fmt.pix.width < BUZ_MIN_WIDTH) - fmt->fmt.pix.width = BUZ_MIN_WIDTH; - if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) - fmt->fmt.pix.height = BUZ_MAX_HEIGHT; - if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT) - fmt->fmt.pix.height = BUZ_MIN_HEIGHT; - mutex_unlock(&zr->resource_lock); + if (v4l_fbuffer_alloc(file)) { + res = -ENOMEM; + goto v4l2reqbuf_unlock_and_return; + } - return 0; -} + /* The next mmap will map the V4L buffers */ + fh->map_mode = ZORAN_MAP_MODE_RAW; -static int zoran_s_fmt_vid_overlay(struct file *file, void *__fh, - struct v4l2_format *fmt) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int res; - - dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n", - fmt->fmt.win.w.left, fmt->fmt.win.w.top, - fmt->fmt.win.w.width, - fmt->fmt.win.w.height, - fmt->fmt.win.clipcount, - fmt->fmt.win.bitmap); - mutex_lock(&zr->resource_lock); - res = setup_window(fh, fmt->fmt.win.w.left, fmt->fmt.win.w.top, - fmt->fmt.win.w.width, fmt->fmt.win.w.height, - (struct v4l2_clip __user *)fmt->fmt.win.clips, - fmt->fmt.win.clipcount, fmt->fmt.win.bitmap); - mutex_unlock(&zr->resource_lock); - return res; -} + } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC || + fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { -static int zoran_s_fmt_vid_out(struct file *file, void *__fh, - struct v4l2_format *fmt) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - __le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat); - struct zoran_jpg_settings settings; - int res = 0; + /* we need to calculate size ourselves now */ + if (req->count < 4) + req->count = 4; + if (req->count > jpg_nbufs) + req->count = jpg_nbufs; + fh->jpg_buffers.num_buffers = req->count; + fh->jpg_buffers.buffer_size = + zoran_v4l2_calc_bufsize(&fh->jpg_settings); - dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n", - fmt->fmt.pix.width, fmt->fmt.pix.height, - fmt->fmt.pix.pixelformat, - (char *) &printformat); - if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) - return -EINVAL; + if (jpg_fbuffer_alloc(file)) { + res = -ENOMEM; + goto v4l2reqbuf_unlock_and_return; + } - mutex_lock(&zr->resource_lock); + /* The next mmap will map the MJPEG buffers */ + if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + fh->map_mode = ZORAN_MAP_MODE_JPG_REC; + else + fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY; - if (fh->buffers.allocated) { - dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto sfmtjpg_unlock_and_return; + } else { + dprintk(1, + KERN_ERR + "%s: VIDIOC_REQBUFS - unknown type %d\n", + ZR_DEVNAME(zr), req->type); + res = -EINVAL; + goto v4l2reqbuf_unlock_and_return; + } + v4l2reqbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); + + return 0; } + break; - settings = fh->jpg_settings; + case VIDIOC_QUERYBUF: + { + struct v4l2_buffer *buf = arg; + __u32 type = buf->type; + int index = buf->index, res; - /* we actually need to set 'real' parameters now */ - if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT) - settings.TmpDcm = 1; - else - settings.TmpDcm = 2; - settings.decimation = 0; - if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2) - settings.VerDcm = 2; - else - settings.VerDcm = 1; - if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4) - settings.HorDcm = 4; - else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2) - settings.HorDcm = 2; - else - settings.HorDcm = 1; - if (settings.TmpDcm == 1) - settings.field_per_buff = 2; - else - settings.field_per_buff = 1; + dprintk(3, + KERN_DEBUG + "%s: VIDIOC_QUERYBUF - index=%d, type=%d\n", + ZR_DEVNAME(zr), buf->index, buf->type); - if (settings.HorDcm > 1) { - settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; - settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; - } else { - settings.img_x = 0; - settings.img_width = BUZ_MAX_WIDTH; + memset(buf, 0, sizeof(*buf)); + buf->type = type; + buf->index = index; + + mutex_lock(&zr->resource_lock); + res = zoran_v4l2_buffer_status(file, buf, buf->index); + mutex_unlock(&zr->resource_lock); + + return res; } + break; - /* check */ - res = zoran_check_jpg_settings(zr, &settings, 0); - if (res) - goto sfmtjpg_unlock_and_return; + case VIDIOC_QBUF: + { + struct v4l2_buffer *buf = arg; + int res = 0, codec_mode, buf_type; - /* it's ok, so set them */ - fh->jpg_settings = settings; + dprintk(3, + KERN_DEBUG "%s: VIDIOC_QBUF - type=%d, index=%d\n", + ZR_DEVNAME(zr), buf->type, buf->index); - map_mode_jpg(fh, fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT); - fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings); + mutex_lock(&zr->resource_lock); - /* tell the user what we actually did */ - fmt->fmt.pix.width = settings.img_width / settings.HorDcm; - fmt->fmt.pix.height = settings.img_height * 2 / - (settings.TmpDcm * settings.VerDcm); - if (settings.TmpDcm == 1) - fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? - V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); - else - fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? - V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); - fmt->fmt.pix.bytesperline = 0; - fmt->fmt.pix.sizeimage = fh->buffers.buffer_size; - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); + res = -EINVAL; + goto qbuf_unlock_and_return; + } -sfmtjpg_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; -} + res = zoran_v4l_queue_frame(file, buf->index); + if (res) + goto qbuf_unlock_and_return; + if (!zr->v4l_memgrab_active && + fh->v4l_buffers.active == ZORAN_LOCKED) + zr36057_set_memgrab(zr, 1); + break; -static int zoran_s_fmt_vid_cap(struct file *file, void *__fh, - struct v4l2_format *fmt) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int i; - int res = 0; + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: + if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { + buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + codec_mode = BUZ_MODE_MOTION_DECOMPRESS; + } else { + buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + codec_mode = BUZ_MODE_MOTION_COMPRESS; + } - if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) - return zoran_s_fmt_vid_out(file, fh, fmt); + if (buf->type != buf_type) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); + res = -EINVAL; + goto qbuf_unlock_and_return; + } - for (i = 0; i < NUM_FORMATS; i++) - if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc) + res = + zoran_jpg_queue_frame(file, buf->index, + codec_mode); + if (res != 0) + goto qbuf_unlock_and_return; + if (zr->codec_mode == BUZ_MODE_IDLE && + fh->jpg_buffers.active == ZORAN_LOCKED) { + zr36057_enable_jpg(zr, codec_mode); + } break; - if (i == NUM_FORMATS) { - dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x\n", - ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat); - return -EINVAL; + + default: + dprintk(1, + KERN_ERR + "%s: VIDIOC_QBUF - unsupported type %d\n", + ZR_DEVNAME(zr), buf->type); + res = -EINVAL; + goto qbuf_unlock_and_return; + } + qbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); + + return res; } + break; - mutex_lock(&zr->resource_lock); + case VIDIOC_DQBUF: + { + struct v4l2_buffer *buf = arg; + int res = 0, buf_type, num = -1; /* compiler borks here (?) */ - if ((fh->map_mode != ZORAN_MAP_MODE_RAW && fh->buffers.allocated) || - fh->buffers.active != ZORAN_FREE) { - dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto sfmtv4l_unlock_and_return; - } - if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) - fmt->fmt.pix.height = BUZ_MAX_HEIGHT; - if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) - fmt->fmt.pix.width = BUZ_MAX_WIDTH; - - map_mode_raw(fh); - - res = zoran_v4l_set_format(fh, fmt->fmt.pix.width, fmt->fmt.pix.height, - &zoran_formats[i]); - if (res) - goto sfmtv4l_unlock_and_return; - - /* tell the user the results/missing stuff */ - fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline; - fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline; - fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace; - if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) - fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; - else - fmt->fmt.pix.field = V4L2_FIELD_TOP; + dprintk(3, KERN_DEBUG "%s: VIDIOC_DQBUF - type=%d\n", + ZR_DEVNAME(zr), buf->type); -sfmtv4l_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; -} + mutex_lock(&zr->resource_lock); -static int zoran_g_fbuf(struct file *file, void *__fh, - struct v4l2_framebuffer *fb) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); + res = -EINVAL; + goto dqbuf_unlock_and_return; + } - memset(fb, 0, sizeof(*fb)); - mutex_lock(&zr->resource_lock); - fb->base = zr->vbuf_base; - fb->fmt.width = zr->vbuf_width; - fb->fmt.height = zr->vbuf_height; - if (zr->overlay_settings.format) - fb->fmt.pixelformat = fh->overlay_settings.format->fourcc; - fb->fmt.bytesperline = zr->vbuf_bytesperline; - mutex_unlock(&zr->resource_lock); - fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; - fb->fmt.field = V4L2_FIELD_INTERLACED; - fb->flags = V4L2_FBUF_FLAG_OVERLAY; - fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; + num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; + if (file->f_flags & O_NONBLOCK && + zr->v4l_buffers.buffer[num].state != + BUZ_STATE_DONE) { + res = -EAGAIN; + goto dqbuf_unlock_and_return; + } + res = v4l_sync(file, num); + if (res) + goto dqbuf_unlock_and_return; + else + zr->v4l_sync_tail++; + res = zoran_v4l2_buffer_status(file, buf, num); + break; - return 0; -} + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: + { + struct zoran_sync bs; -static int zoran_s_fbuf(struct file *file, void *__fh, - struct v4l2_framebuffer *fb) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int i, res = 0; - __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat); + if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) + buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + else + buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + if (buf->type != buf_type) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); + res = -EINVAL; + goto dqbuf_unlock_and_return; + } - for (i = 0; i < NUM_FORMATS; i++) - if (zoran_formats[i].fourcc == fb->fmt.pixelformat) + num = + zr->jpg_pend[zr-> + jpg_que_tail & BUZ_MASK_FRAME]; + + if (file->f_flags & O_NONBLOCK && + zr->jpg_buffers.buffer[num].state != + BUZ_STATE_DONE) { + res = -EAGAIN; + goto dqbuf_unlock_and_return; + } + res = jpg_sync(file, &bs); + if (res) + goto dqbuf_unlock_and_return; + res = + zoran_v4l2_buffer_status(file, buf, bs.frame); break; - if (i == NUM_FORMATS) { - dprintk(1, KERN_ERR "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n", - ZR_DEVNAME(zr), fb->fmt.pixelformat, - (char *)&printformat); - return -EINVAL; + } + + default: + dprintk(1, + KERN_ERR + "%s: VIDIOC_DQBUF - unsupported type %d\n", + ZR_DEVNAME(zr), buf->type); + res = -EINVAL; + goto dqbuf_unlock_and_return; + } + dqbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); + + return res; } + break; - mutex_lock(&zr->resource_lock); - res = setup_fbuffer(fh, fb->base, &zoran_formats[i], fb->fmt.width, - fb->fmt.height, fb->fmt.bytesperline); - mutex_unlock(&zr->resource_lock); + case VIDIOC_STREAMON: + { + int res = 0; - return res; -} + dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMON\n", ZR_DEVNAME(zr)); -static int zoran_overlay(struct file *file, void *__fh, unsigned int on) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int res; + mutex_lock(&zr->resource_lock); - mutex_lock(&zr->resource_lock); - res = setup_overlay(fh, on); - mutex_unlock(&zr->resource_lock); + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: /* raw capture */ + if (zr->v4l_buffers.active != ZORAN_ACTIVE || + fh->v4l_buffers.active != ZORAN_ACTIVE) { + res = -EBUSY; + goto strmon_unlock_and_return; + } - return res; -} + zr->v4l_buffers.active = fh->v4l_buffers.active = + ZORAN_LOCKED; + zr->v4l_settings = fh->v4l_settings; -static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type); + zr->v4l_sync_tail = zr->v4l_pend_tail; + if (!zr->v4l_memgrab_active && + zr->v4l_pend_head != zr->v4l_pend_tail) { + zr36057_set_memgrab(zr, 1); + } + break; -static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *req) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int res = 0; + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: + /* what is the codec mode right now? */ + if (zr->jpg_buffers.active != ZORAN_ACTIVE || + fh->jpg_buffers.active != ZORAN_ACTIVE) { + res = -EBUSY; + goto strmon_unlock_and_return; + } - if (req->memory != V4L2_MEMORY_MMAP) { - dprintk(2, - KERN_ERR - "%s: only MEMORY_MMAP capture is supported, not %d\n", - ZR_DEVNAME(zr), req->memory); - return -EINVAL; - } + zr->jpg_buffers.active = fh->jpg_buffers.active = + ZORAN_LOCKED; - if (req->count == 0) - return zoran_streamoff(file, fh, req->type); + if (zr->jpg_que_head != zr->jpg_que_tail) { + /* Start the jpeg codec when the first frame is queued */ + jpeg_start(zr); + } - mutex_lock(&zr->resource_lock); - if (fh->buffers.allocated) { - dprintk(2, + break; + default: + dprintk(1, KERN_ERR - "%s: VIDIOC_REQBUFS - buffers already allocated\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto v4l2reqbuf_unlock_and_return; - } + "%s: VIDIOC_STREAMON - invalid map mode %d\n", + ZR_DEVNAME(zr), fh->map_mode); + res = -EINVAL; + goto strmon_unlock_and_return; + } + strmon_unlock_and_return: + mutex_unlock(&zr->resource_lock); - if (fh->map_mode == ZORAN_MAP_MODE_RAW && - req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - /* control user input */ - if (req->count < 2) - req->count = 2; - if (req->count > v4l_nbufs) - req->count = v4l_nbufs; + return res; + } + break; - /* The next mmap will map the V4L buffers */ - map_mode_raw(fh); - fh->buffers.num_buffers = req->count; + case VIDIOC_STREAMOFF: + { + int i, res = 0; - if (v4l_fbuffer_alloc(fh)) { - res = -ENOMEM; - goto v4l2reqbuf_unlock_and_return; - } - } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC || - fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { - /* we need to calculate size ourselves now */ - if (req->count < 4) - req->count = 4; - if (req->count > jpg_nbufs) - req->count = jpg_nbufs; + dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMOFF\n", ZR_DEVNAME(zr)); - /* The next mmap will map the MJPEG buffers */ - map_mode_jpg(fh, req->type == V4L2_BUF_TYPE_VIDEO_OUTPUT); - fh->buffers.num_buffers = req->count; - fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings); + mutex_lock(&zr->resource_lock); - if (jpg_fbuffer_alloc(fh)) { - res = -ENOMEM; - goto v4l2reqbuf_unlock_and_return; - } - } else { - dprintk(1, - KERN_ERR - "%s: VIDIOC_REQBUFS - unknown type %d\n", - ZR_DEVNAME(zr), req->type); - res = -EINVAL; - goto v4l2reqbuf_unlock_and_return; - } -v4l2reqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: /* raw capture */ + if (fh->v4l_buffers.active == ZORAN_FREE && + zr->v4l_buffers.active != ZORAN_FREE) { + res = -EPERM; /* stay off other's settings! */ + goto strmoff_unlock_and_return; + } + if (zr->v4l_buffers.active == ZORAN_FREE) + goto strmoff_unlock_and_return; - return res; -} + /* unload capture */ + if (zr->v4l_memgrab_active) { + unsigned long flags; -static int zoran_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int res; + spin_lock_irqsave(&zr->spinlock, flags); + zr36057_set_memgrab(zr, 0); + spin_unlock_irqrestore(&zr->spinlock, flags); + } - mutex_lock(&zr->resource_lock); - res = zoran_v4l2_buffer_status(fh, buf, buf->index); - mutex_unlock(&zr->resource_lock); + for (i = 0; i < fh->v4l_buffers.num_buffers; i++) + zr->v4l_buffers.buffer[i].state = + BUZ_STATE_USER; + fh->v4l_buffers = zr->v4l_buffers; - return res; -} + zr->v4l_buffers.active = fh->v4l_buffers.active = + ZORAN_FREE; -static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int res = 0, codec_mode, buf_type; + zr->v4l_grab_seq = 0; + zr->v4l_pend_head = zr->v4l_pend_tail = 0; + zr->v4l_sync_tail = 0; - mutex_lock(&zr->resource_lock); + break; - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - dprintk(1, KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: + if (fh->jpg_buffers.active == ZORAN_FREE && + zr->jpg_buffers.active != ZORAN_FREE) { + res = -EPERM; /* stay off other's settings! */ + goto strmoff_unlock_and_return; + } + if (zr->jpg_buffers.active == ZORAN_FREE) + goto strmoff_unlock_and_return; + + res = + jpg_qbuf(file, -1, + (fh->map_mode == + ZORAN_MAP_MODE_JPG_REC) ? + BUZ_MODE_MOTION_COMPRESS : + BUZ_MODE_MOTION_DECOMPRESS); + if (res) + goto strmoff_unlock_and_return; + break; + default: + dprintk(1, + KERN_ERR + "%s: VIDIOC_STREAMOFF - invalid map mode %d\n", + ZR_DEVNAME(zr), fh->map_mode); res = -EINVAL; - goto qbuf_unlock_and_return; + goto strmoff_unlock_and_return; } + strmoff_unlock_and_return: + mutex_unlock(&zr->resource_lock); - res = zoran_v4l_queue_frame(fh, buf->index); - if (res) - goto qbuf_unlock_and_return; - if (!zr->v4l_memgrab_active && fh->buffers.active == ZORAN_LOCKED) - zr36057_set_memgrab(zr, 1); + return res; + } break; - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { - buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - codec_mode = BUZ_MODE_MOTION_DECOMPRESS; - } else { - buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - codec_mode = BUZ_MODE_MOTION_COMPRESS; + case VIDIOC_QUERYCTRL: + { + struct v4l2_queryctrl *ctrl = arg; + + dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCTRL - id=%d\n", + ZR_DEVNAME(zr), ctrl->id); + + /* we only support hue/saturation/contrast/brightness */ + if (ctrl->id < V4L2_CID_BRIGHTNESS || + ctrl->id > V4L2_CID_HUE) + return -EINVAL; + else { + int id = ctrl->id; + memset(ctrl, 0, sizeof(*ctrl)); + ctrl->id = id; } - if (buf->type != buf_type) { - dprintk(1, KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto qbuf_unlock_and_return; + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1); + break; + case V4L2_CID_CONTRAST: + strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1); + break; + case V4L2_CID_SATURATION: + strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1); + break; + case V4L2_CID_HUE: + strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1); + break; } - res = zoran_jpg_queue_frame(fh, buf->index, codec_mode); - if (res != 0) - goto qbuf_unlock_and_return; - if (zr->codec_mode == BUZ_MODE_IDLE && - fh->buffers.active == ZORAN_LOCKED) - zr36057_enable_jpg(zr, codec_mode); + ctrl->minimum = 0; + ctrl->maximum = 65535; + ctrl->step = 1; + ctrl->default_value = 32768; + ctrl->type = V4L2_CTRL_TYPE_INTEGER; + return 0; + } break; - default: - dprintk(1, KERN_ERR - "%s: VIDIOC_QBUF - unsupported type %d\n", - ZR_DEVNAME(zr), buf->type); - res = -EINVAL; - break; + case VIDIOC_G_CTRL: + { + struct v4l2_control *ctrl = arg; + + dprintk(3, KERN_DEBUG "%s: VIDIOC_G_CTRL - id=%d\n", + ZR_DEVNAME(zr), ctrl->id); + + /* we only support hue/saturation/contrast/brightness */ + if (ctrl->id < V4L2_CID_BRIGHTNESS || + ctrl->id > V4L2_CID_HUE) + return -EINVAL; + + mutex_lock(&zr->resource_lock); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = zr->brightness; + break; + case V4L2_CID_CONTRAST: + ctrl->value = zr->contrast; + break; + case V4L2_CID_SATURATION: + ctrl->value = zr->saturation; + break; + case V4L2_CID_HUE: + ctrl->value = zr->hue; + break; + } + mutex_unlock(&zr->resource_lock); + + return 0; } -qbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); + break; - return res; -} + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl = arg; + struct video_picture pict; -static int zoran_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int res = 0, buf_type, num = -1; /* compiler borks here (?) */ + dprintk(3, KERN_DEBUG "%s: VIDIOC_S_CTRL - id=%d\n", + ZR_DEVNAME(zr), ctrl->id); - mutex_lock(&zr->resource_lock); + /* we only support hue/saturation/contrast/brightness */ + if (ctrl->id < V4L2_CID_BRIGHTNESS || + ctrl->id > V4L2_CID_HUE) + return -EINVAL; - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - dprintk(1, KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto dqbuf_unlock_and_return; + if (ctrl->value < 0 || ctrl->value > 65535) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n", + ZR_DEVNAME(zr), ctrl->value, ctrl->id); + return -EINVAL; } - num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; - if (file->f_flags & O_NONBLOCK && - zr->v4l_buffers.buffer[num].state != BUZ_STATE_DONE) { - res = -EAGAIN; - goto dqbuf_unlock_and_return; + mutex_lock(&zr->resource_lock); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + zr->brightness = ctrl->value; + break; + case V4L2_CID_CONTRAST: + zr->contrast = ctrl->value; + break; + case V4L2_CID_SATURATION: + zr->saturation = ctrl->value; + break; + case V4L2_CID_HUE: + zr->hue = ctrl->value; + break; } - res = v4l_sync(fh, num); - if (res) - goto dqbuf_unlock_and_return; - zr->v4l_sync_tail++; - res = zoran_v4l2_buffer_status(fh, buf, num); + pict.brightness = zr->brightness; + pict.contrast = zr->contrast; + pict.colour = zr->saturation; + pict.hue = zr->hue; + + decoder_command(zr, DECODER_SET_PICTURE, &pict); + + mutex_unlock(&zr->resource_lock); + + return 0; + } break; - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: + case VIDIOC_ENUMSTD: { - struct zoran_sync bs; + struct v4l2_standard *std = arg; - if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) - buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - else - buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMSTD - index=%d\n", + ZR_DEVNAME(zr), std->index); - if (buf->type != buf_type) { - dprintk(1, KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto dqbuf_unlock_and_return; + if (std->index < 0 || std->index >= (zr->card.norms + 1)) + return -EINVAL; + else { + int id = std->index; + memset(std, 0, sizeof(*std)); + std->index = id; } - num = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME]; - - if (file->f_flags & O_NONBLOCK && - zr->jpg_buffers.buffer[num].state != BUZ_STATE_DONE) { - res = -EAGAIN; - goto dqbuf_unlock_and_return; + if (std->index == zr->card.norms) { + /* if we have autodetect, ... */ + struct video_decoder_capability caps; + decoder_command(zr, DECODER_GET_CAPABILITIES, + &caps); + if (caps.flags & VIDEO_DECODER_AUTO) { + std->id = V4L2_STD_ALL; + strncpy(std->name, "Autodetect", sizeof(std->name)-1); + return 0; + } else + return -EINVAL; + } + switch (std->index) { + case 0: + std->id = V4L2_STD_PAL; + strncpy(std->name, "PAL", sizeof(std->name)-1); + std->frameperiod.numerator = 1; + std->frameperiod.denominator = 25; + std->framelines = zr->card.tvn[0]->Ht; + break; + case 1: + std->id = V4L2_STD_NTSC; + strncpy(std->name, "NTSC", sizeof(std->name)-1); + std->frameperiod.numerator = 1001; + std->frameperiod.denominator = 30000; + std->framelines = zr->card.tvn[1]->Ht; + break; + case 2: + std->id = V4L2_STD_SECAM; + strncpy(std->name, "SECAM", sizeof(std->name)-1); + std->frameperiod.numerator = 1; + std->frameperiod.denominator = 25; + std->framelines = zr->card.tvn[2]->Ht; + break; } - res = jpg_sync(fh, &bs); - if (res) - goto dqbuf_unlock_and_return; - res = zoran_v4l2_buffer_status(fh, buf, bs.frame); - break; - } - default: - dprintk(1, KERN_ERR - "%s: VIDIOC_DQBUF - unsupported type %d\n", - ZR_DEVNAME(zr), buf->type); - res = -EINVAL; - break; + return 0; } -dqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); + break; - return res; -} + case VIDIOC_G_STD: + { + v4l2_std_id *std = arg; + int norm; -static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int res = 0; + dprintk(3, KERN_DEBUG "%s: VIDIOC_G_STD\n", ZR_DEVNAME(zr)); - mutex_lock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); + norm = zr->norm; + mutex_unlock(&zr->resource_lock); - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: /* raw capture */ - if (zr->v4l_buffers.active != ZORAN_ACTIVE || - fh->buffers.active != ZORAN_ACTIVE) { - res = -EBUSY; - goto strmon_unlock_and_return; + switch (norm) { + case VIDEO_MODE_PAL: + *std = V4L2_STD_PAL; + break; + case VIDEO_MODE_NTSC: + *std = V4L2_STD_NTSC; + break; + case VIDEO_MODE_SECAM: + *std = V4L2_STD_SECAM; + break; } - zr->v4l_buffers.active = fh->buffers.active = ZORAN_LOCKED; - zr->v4l_settings = fh->v4l_settings; - - zr->v4l_sync_tail = zr->v4l_pend_tail; - if (!zr->v4l_memgrab_active && - zr->v4l_pend_head != zr->v4l_pend_tail) { - zr36057_set_memgrab(zr, 1); - } + return 0; + } break; - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - /* what is the codec mode right now? */ - if (zr->jpg_buffers.active != ZORAN_ACTIVE || - fh->buffers.active != ZORAN_ACTIVE) { - res = -EBUSY; - goto strmon_unlock_and_return; + case VIDIOC_S_STD: + { + int norm = -1, res = 0; + v4l2_std_id *std = arg; + + dprintk(3, KERN_DEBUG "%s: VIDIOC_S_STD - norm=0x%llx\n", + ZR_DEVNAME(zr), (unsigned long long)*std); + + if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL)) + norm = VIDEO_MODE_PAL; + else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC)) + norm = VIDEO_MODE_NTSC; + else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM)) + norm = VIDEO_MODE_SECAM; + else if (*std == V4L2_STD_ALL) + norm = VIDEO_MODE_AUTO; + else { + dprintk(1, + KERN_ERR + "%s: VIDIOC_S_STD - invalid norm 0x%llx\n", + ZR_DEVNAME(zr), (unsigned long long)*std); + return -EINVAL; } - zr->jpg_buffers.active = fh->buffers.active = ZORAN_LOCKED; - - if (zr->jpg_que_head != zr->jpg_que_tail) { - /* Start the jpeg codec when the first frame is queued */ - jpeg_start(zr); - } - break; + mutex_lock(&zr->resource_lock); + if ((res = zoran_set_norm(zr, norm))) + goto sstd_unlock_and_return; - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_STREAMON - invalid map mode %d\n", - ZR_DEVNAME(zr), fh->map_mode); - res = -EINVAL; - break; + res = wait_grab_pending(zr); + sstd_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; } -strmon_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return res; -} + break; -static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int i, res = 0; - unsigned long flags; + case VIDIOC_ENUMINPUT: + { + struct v4l2_input *inp = arg; + int status; - mutex_lock(&zr->resource_lock); + dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMINPUT - index=%d\n", + ZR_DEVNAME(zr), inp->index); - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: /* raw capture */ - if (fh->buffers.active == ZORAN_FREE && - zr->v4l_buffers.active != ZORAN_FREE) { - res = -EPERM; /* stay off other's settings! */ - goto strmoff_unlock_and_return; + if (inp->index < 0 || inp->index >= zr->card.inputs) + return -EINVAL; + else { + int id = inp->index; + memset(inp, 0, sizeof(*inp)); + inp->index = id; } - if (zr->v4l_buffers.active == ZORAN_FREE) - goto strmoff_unlock_and_return; - spin_lock_irqsave(&zr->spinlock, flags); - /* unload capture */ - if (zr->v4l_memgrab_active) { + strncpy(inp->name, zr->card.input[inp->index].name, + sizeof(inp->name) - 1); + inp->type = V4L2_INPUT_TYPE_CAMERA; + inp->std = V4L2_STD_ALL; + + /* Get status of video decoder */ + mutex_lock(&zr->resource_lock); + decoder_command(zr, DECODER_GET_STATUS, &status); + mutex_unlock(&zr->resource_lock); - zr36057_set_memgrab(zr, 0); + if (!(status & DECODER_STATUS_GOOD)) { + inp->status |= V4L2_IN_ST_NO_POWER; + inp->status |= V4L2_IN_ST_NO_SIGNAL; } + if (!(status & DECODER_STATUS_COLOR)) + inp->status |= V4L2_IN_ST_NO_COLOR; - for (i = 0; i < fh->buffers.num_buffers; i++) - zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER; - fh->buffers = zr->v4l_buffers; + return 0; + } + break; - zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE; + case VIDIOC_G_INPUT: + { + int *input = arg; - zr->v4l_grab_seq = 0; - zr->v4l_pend_head = zr->v4l_pend_tail = 0; - zr->v4l_sync_tail = 0; + dprintk(3, KERN_DEBUG "%s: VIDIOC_G_INPUT\n", ZR_DEVNAME(zr)); - spin_unlock_irqrestore(&zr->spinlock, flags); + mutex_lock(&zr->resource_lock); + *input = zr->input; + mutex_unlock(&zr->resource_lock); + return 0; + } break; - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - if (fh->buffers.active == ZORAN_FREE && - zr->jpg_buffers.active != ZORAN_FREE) { - res = -EPERM; /* stay off other's settings! */ - goto strmoff_unlock_and_return; - } - if (zr->jpg_buffers.active == ZORAN_FREE) - goto strmoff_unlock_and_return; + case VIDIOC_S_INPUT: + { + int *input = arg, res = 0; - res = jpg_qbuf(fh, -1, - (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ? - BUZ_MODE_MOTION_COMPRESS : - BUZ_MODE_MOTION_DECOMPRESS); - if (res) - goto strmoff_unlock_and_return; - break; - default: - dprintk(1, KERN_ERR - "%s: VIDIOC_STREAMOFF - invalid map mode %d\n", - ZR_DEVNAME(zr), fh->map_mode); - res = -EINVAL; - break; - } -strmoff_unlock_and_return: - mutex_unlock(&zr->resource_lock); + dprintk(3, KERN_DEBUG "%s: VIDIOC_S_INPUT - input=%d\n", + ZR_DEVNAME(zr), *input); - return res; -} + mutex_lock(&zr->resource_lock); + if ((res = zoran_set_input(zr, *input))) + goto sinput_unlock_and_return; -static int zoran_queryctrl(struct file *file, void *__fh, - struct v4l2_queryctrl *ctrl) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + /* Make sure the changes come into effect */ + res = wait_grab_pending(zr); + sinput_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; + } + break; - /* we only support hue/saturation/contrast/brightness */ - if (ctrl->id < V4L2_CID_BRIGHTNESS || - ctrl->id > V4L2_CID_HUE) - return -EINVAL; + case VIDIOC_ENUMOUTPUT: + { + struct v4l2_output *outp = arg; - decoder_call(zr, core, queryctrl, ctrl); + dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMOUTPUT - index=%d\n", + ZR_DEVNAME(zr), outp->index); - return 0; -} + if (outp->index != 0) + return -EINVAL; -static int zoran_g_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + memset(outp, 0, sizeof(*outp)); + outp->index = 0; + outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; + strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); - /* we only support hue/saturation/contrast/brightness */ - if (ctrl->id < V4L2_CID_BRIGHTNESS || - ctrl->id > V4L2_CID_HUE) - return -EINVAL; + return 0; + } + break; - mutex_lock(&zr->resource_lock); - decoder_call(zr, core, g_ctrl, ctrl); - mutex_unlock(&zr->resource_lock); + case VIDIOC_G_OUTPUT: + { + int *output = arg; - return 0; -} + dprintk(3, KERN_DEBUG "%s: VIDIOC_G_OUTPUT\n", ZR_DEVNAME(zr)); -static int zoran_s_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + *output = 0; - /* we only support hue/saturation/contrast/brightness */ - if (ctrl->id < V4L2_CID_BRIGHTNESS || - ctrl->id > V4L2_CID_HUE) - return -EINVAL; + return 0; + } + break; - mutex_lock(&zr->resource_lock); - decoder_call(zr, core, s_ctrl, ctrl); - mutex_unlock(&zr->resource_lock); + case VIDIOC_S_OUTPUT: + { + int *output = arg; - return 0; -} + dprintk(3, KERN_DEBUG "%s: VIDIOC_S_OUTPUT - output=%d\n", + ZR_DEVNAME(zr), *output); -static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + if (*output != 0) + return -EINVAL; - mutex_lock(&zr->resource_lock); - *std = zr->norm; - mutex_unlock(&zr->resource_lock); - return 0; -} + return 0; + } + break; -static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int res = 0; + /* cropping (sub-frame capture) */ + case VIDIOC_CROPCAP: + { + struct v4l2_cropcap *cropcap = arg; + int type = cropcap->type, res = 0; - mutex_lock(&zr->resource_lock); - res = zoran_set_norm(zr, *std); - if (res) - goto sstd_unlock_and_return; + dprintk(3, KERN_ERR "%s: VIDIOC_CROPCAP - type=%d\n", + ZR_DEVNAME(zr), cropcap->type); - res = wait_grab_pending(zr); -sstd_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; -} + memset(cropcap, 0, sizeof(*cropcap)); + cropcap->type = type; -static int zoran_enum_input(struct file *file, void *__fh, - struct v4l2_input *inp) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + mutex_lock(&zr->resource_lock); - if (inp->index < 0 || inp->index >= zr->card.inputs) - return -EINVAL; - else { - int id = inp->index; - memset(inp, 0, sizeof(*inp)); - inp->index = id; + if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && + (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + fh->map_mode == ZORAN_MAP_MODE_RAW)) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n", + ZR_DEVNAME(zr)); + res = -EINVAL; + goto cropcap_unlock_and_return; + } + + cropcap->bounds.top = cropcap->bounds.left = 0; + cropcap->bounds.width = BUZ_MAX_WIDTH; + cropcap->bounds.height = BUZ_MAX_HEIGHT; + cropcap->defrect.top = cropcap->defrect.left = 0; + cropcap->defrect.width = BUZ_MIN_WIDTH; + cropcap->defrect.height = BUZ_MIN_HEIGHT; + cropcap_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; } + break; - strncpy(inp->name, zr->card.input[inp->index].name, - sizeof(inp->name) - 1); - inp->type = V4L2_INPUT_TYPE_CAMERA; - inp->std = V4L2_STD_ALL; + case VIDIOC_G_CROP: + { + struct v4l2_crop *crop = arg; + int type = crop->type, res = 0; - /* Get status of video decoder */ - mutex_lock(&zr->resource_lock); - decoder_call(zr, video, g_input_status, &inp->status); - mutex_unlock(&zr->resource_lock); - return 0; -} + dprintk(3, KERN_ERR "%s: VIDIOC_G_CROP - type=%d\n", + ZR_DEVNAME(zr), crop->type); -static int zoran_g_input(struct file *file, void *__fh, unsigned int *input) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; + memset(crop, 0, sizeof(*crop)); + crop->type = type; - mutex_lock(&zr->resource_lock); - *input = zr->input; - mutex_unlock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - return 0; -} + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && + (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + fh->map_mode == ZORAN_MAP_MODE_RAW)) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", + ZR_DEVNAME(zr)); + res = -EINVAL; + goto gcrop_unlock_and_return; + } -static int zoran_s_input(struct file *file, void *__fh, unsigned int input) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int res; + crop->c.top = fh->jpg_settings.img_y; + crop->c.left = fh->jpg_settings.img_x; + crop->c.width = fh->jpg_settings.img_width; + crop->c.height = fh->jpg_settings.img_height; - mutex_lock(&zr->resource_lock); - res = zoran_set_input(zr, input); - if (res) - goto sinput_unlock_and_return; + gcrop_unlock_and_return: + mutex_unlock(&zr->resource_lock); - /* Make sure the changes come into effect */ - res = wait_grab_pending(zr); -sinput_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; -} + return res; + } + break; -static int zoran_enum_output(struct file *file, void *__fh, - struct v4l2_output *outp) -{ - if (outp->index != 0) - return -EINVAL; + case VIDIOC_S_CROP: + { + struct v4l2_crop *crop = arg; + int res = 0; - memset(outp, 0, sizeof(*outp)); - outp->index = 0; - outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; - strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); + settings = fh->jpg_settings; - return 0; -} + dprintk(3, + KERN_ERR + "%s: VIDIOC_S_CROP - type=%d, x=%d,y=%d,w=%d,h=%d\n", + ZR_DEVNAME(zr), crop->type, crop->c.left, crop->c.top, + crop->c.width, crop->c.height); -static int zoran_g_output(struct file *file, void *__fh, unsigned int *output) -{ - *output = 0; + mutex_lock(&zr->resource_lock); - return 0; -} + if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_S_CROP - cannot change settings while active\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto scrop_unlock_and_return; + } -static int zoran_s_output(struct file *file, void *__fh, unsigned int output) -{ - if (output != 0) - return -EINVAL; + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && + (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + fh->map_mode == ZORAN_MAP_MODE_RAW)) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", + ZR_DEVNAME(zr)); + res = -EINVAL; + goto scrop_unlock_and_return; + } - return 0; -} + /* move into a form that we understand */ + settings.img_x = crop->c.left; + settings.img_y = crop->c.top; + settings.img_width = crop->c.width; + settings.img_height = crop->c.height; -/* cropping (sub-frame capture) */ -static int zoran_cropcap(struct file *file, void *__fh, - struct v4l2_cropcap *cropcap) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int type = cropcap->type, res = 0; + /* check validity */ + if ((res = zoran_check_jpg_settings(zr, &settings))) + goto scrop_unlock_and_return; - memset(cropcap, 0, sizeof(*cropcap)); - cropcap->type = type; + /* accept */ + fh->jpg_settings = settings; - mutex_lock(&zr->resource_lock); + scrop_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; + } + break; - if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && - (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - fh->map_mode == ZORAN_MAP_MODE_RAW)) { - dprintk(1, KERN_ERR - "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n", + case VIDIOC_G_JPEGCOMP: + { + struct v4l2_jpegcompression *params = arg; + + dprintk(3, KERN_DEBUG "%s: VIDIOC_G_JPEGCOMP\n", ZR_DEVNAME(zr)); - res = -EINVAL; - goto cropcap_unlock_and_return; - } - cropcap->bounds.top = cropcap->bounds.left = 0; - cropcap->bounds.width = BUZ_MAX_WIDTH; - cropcap->bounds.height = BUZ_MAX_HEIGHT; - cropcap->defrect.top = cropcap->defrect.left = 0; - cropcap->defrect.width = BUZ_MIN_WIDTH; - cropcap->defrect.height = BUZ_MIN_HEIGHT; -cropcap_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; -} + memset(params, 0, sizeof(*params)); -static int zoran_g_crop(struct file *file, void *__fh, struct v4l2_crop *crop) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int type = crop->type, res = 0; + mutex_lock(&zr->resource_lock); - memset(crop, 0, sizeof(*crop)); - crop->type = type; + params->quality = fh->jpg_settings.jpg_comp.quality; + params->APPn = fh->jpg_settings.jpg_comp.APPn; + memcpy(params->APP_data, + fh->jpg_settings.jpg_comp.APP_data, + fh->jpg_settings.jpg_comp.APP_len); + params->APP_len = fh->jpg_settings.jpg_comp.APP_len; + memcpy(params->COM_data, + fh->jpg_settings.jpg_comp.COM_data, + fh->jpg_settings.jpg_comp.COM_len); + params->COM_len = fh->jpg_settings.jpg_comp.COM_len; + params->jpeg_markers = + fh->jpg_settings.jpg_comp.jpeg_markers; - mutex_lock(&zr->resource_lock); + mutex_unlock(&zr->resource_lock); - if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && - (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - fh->map_mode == ZORAN_MAP_MODE_RAW)) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto gcrop_unlock_and_return; + return 0; } + break; - crop->c.top = fh->jpg_settings.img_y; - crop->c.left = fh->jpg_settings.img_x; - crop->c.width = fh->jpg_settings.img_width; - crop->c.height = fh->jpg_settings.img_height; + case VIDIOC_S_JPEGCOMP: + { + struct v4l2_jpegcompression *params = arg; + int res = 0; -gcrop_unlock_and_return: - mutex_unlock(&zr->resource_lock); + settings = fh->jpg_settings; - return res; -} + dprintk(3, + KERN_DEBUG + "%s: VIDIOC_S_JPEGCOMP - quality=%d, APPN=%d, APP_len=%d, COM_len=%d\n", + ZR_DEVNAME(zr), params->quality, params->APPn, + params->APP_len, params->COM_len); -static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int res = 0; - struct zoran_jpg_settings settings; + settings.jpg_comp = *params; - settings = fh->jpg_settings; + mutex_lock(&zr->resource_lock); - mutex_lock(&zr->resource_lock); + if (fh->v4l_buffers.active != ZORAN_FREE || + fh->jpg_buffers.active != ZORAN_FREE) { + dprintk(1, + KERN_WARNING + "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto sjpegc_unlock_and_return; + } - if (fh->buffers.allocated) { - dprintk(1, KERN_ERR - "%s: VIDIOC_S_CROP - cannot change settings while active\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto scrop_unlock_and_return; - } + if ((res = zoran_check_jpg_settings(zr, &settings))) + goto sjpegc_unlock_and_return; + if (!fh->jpg_buffers.allocated) + fh->jpg_buffers.buffer_size = + zoran_v4l2_calc_bufsize(&fh->jpg_settings); + fh->jpg_settings.jpg_comp = *params = settings.jpg_comp; + sjpegc_unlock_and_return: + mutex_unlock(&zr->resource_lock); - if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && - (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - fh->map_mode == ZORAN_MAP_MODE_RAW)) { - dprintk(1, KERN_ERR - "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto scrop_unlock_and_return; + return 0; } + break; - /* move into a form that we understand */ - settings.img_x = crop->c.left; - settings.img_y = crop->c.top; - settings.img_width = crop->c.width; - settings.img_height = crop->c.height; + case VIDIOC_QUERYSTD: /* why is this useful? */ + { + v4l2_std_id *std = arg; - /* check validity */ - res = zoran_check_jpg_settings(zr, &settings, 0); - if (res) - goto scrop_unlock_and_return; + dprintk(3, + KERN_DEBUG "%s: VIDIOC_QUERY_STD - std=0x%llx\n", + ZR_DEVNAME(zr), (unsigned long long)*std); - /* accept */ - fh->jpg_settings = settings; + if (*std == V4L2_STD_ALL || *std == V4L2_STD_NTSC || + *std == V4L2_STD_PAL || (*std == V4L2_STD_SECAM && + zr->card.norms == 3)) { + return 0; + } -scrop_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; -} + return -EINVAL; + } + break; -static int zoran_g_jpegcomp(struct file *file, void *__fh, - struct v4l2_jpegcompression *params) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - memset(params, 0, sizeof(*params)); + case VIDIOC_TRY_FMT: + { + struct v4l2_format *fmt = arg; + int res = 0; - mutex_lock(&zr->resource_lock); + dprintk(3, KERN_DEBUG "%s: VIDIOC_TRY_FMT - type=%d\n", + ZR_DEVNAME(zr), fmt->type); - params->quality = fh->jpg_settings.jpg_comp.quality; - params->APPn = fh->jpg_settings.jpg_comp.APPn; - memcpy(params->APP_data, - fh->jpg_settings.jpg_comp.APP_data, - fh->jpg_settings.jpg_comp.APP_len); - params->APP_len = fh->jpg_settings.jpg_comp.APP_len; - memcpy(params->COM_data, - fh->jpg_settings.jpg_comp.COM_data, - fh->jpg_settings.jpg_comp.COM_len); - params->COM_len = fh->jpg_settings.jpg_comp.COM_len; - params->jpeg_markers = - fh->jpg_settings.jpg_comp.jpeg_markers; + switch (fmt->type) { + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + mutex_lock(&zr->resource_lock); - mutex_unlock(&zr->resource_lock); + if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH) + fmt->fmt.win.w.width = BUZ_MAX_WIDTH; + if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH) + fmt->fmt.win.w.width = BUZ_MIN_WIDTH; + if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT) + fmt->fmt.win.w.height = BUZ_MAX_HEIGHT; + if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT) + fmt->fmt.win.w.height = BUZ_MIN_HEIGHT; - return 0; -} + mutex_unlock(&zr->resource_lock); + break; -static int zoran_s_jpegcomp(struct file *file, void *__fh, - struct v4l2_jpegcompression *params) -{ - struct zoran_fh *fh = __fh; - struct zoran *zr = fh->zr; - int res = 0; - struct zoran_jpg_settings settings; + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + if (fmt->fmt.pix.bytesperline > 0) + return -EINVAL; - settings = fh->jpg_settings; + mutex_lock(&zr->resource_lock); + + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) { + settings = fh->jpg_settings; + + /* we actually need to set 'real' parameters now */ + if ((fmt->fmt.pix.height * 2) > + BUZ_MAX_HEIGHT) + settings.TmpDcm = 1; + else + settings.TmpDcm = 2; + settings.decimation = 0; + if (fmt->fmt.pix.height <= + fh->jpg_settings.img_height / 2) + settings.VerDcm = 2; + else + settings.VerDcm = 1; + if (fmt->fmt.pix.width <= + fh->jpg_settings.img_width / 4) + settings.HorDcm = 4; + else if (fmt->fmt.pix.width <= + fh->jpg_settings.img_width / 2) + settings.HorDcm = 2; + else + settings.HorDcm = 1; + if (settings.TmpDcm == 1) + settings.field_per_buff = 2; + else + settings.field_per_buff = 1; + + /* check */ + if ((res = + zoran_check_jpg_settings(zr, + &settings))) + goto tryfmt_unlock_and_return; + + /* tell the user what we actually did */ + fmt->fmt.pix.width = + settings.img_width / settings.HorDcm; + fmt->fmt.pix.height = + settings.img_height * 2 / + (settings.TmpDcm * settings.VerDcm); + if (settings.TmpDcm == 1) + fmt->fmt.pix.field = + (fh->jpg_settings. + odd_even ? V4L2_FIELD_SEQ_TB : + V4L2_FIELD_SEQ_BT); + else + fmt->fmt.pix.field = + (fh->jpg_settings. + odd_even ? V4L2_FIELD_TOP : + V4L2_FIELD_BOTTOM); + + fmt->fmt.pix.sizeimage = + zoran_v4l2_calc_bufsize(&settings); + } else if (fmt->type == + V4L2_BUF_TYPE_VIDEO_CAPTURE) { + int i; + + for (i = 0; i < NUM_FORMATS; i++) + if (zoran_formats[i].fourcc == + fmt->fmt.pix.pixelformat) + break; + if (i == NUM_FORMATS) { + res = -EINVAL; + goto tryfmt_unlock_and_return; + } - settings.jpg_comp = *params; + if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) + fmt->fmt.pix.width = BUZ_MAX_WIDTH; + if (fmt->fmt.pix.width < BUZ_MIN_WIDTH) + fmt->fmt.pix.width = BUZ_MIN_WIDTH; + if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) + fmt->fmt.pix.height = + BUZ_MAX_HEIGHT; + if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT) + fmt->fmt.pix.height = + BUZ_MIN_HEIGHT; + } else { + res = -EINVAL; + goto tryfmt_unlock_and_return; + } + tryfmt_unlock_and_return: + mutex_unlock(&zr->resource_lock); - mutex_lock(&zr->resource_lock); + return res; + break; - if (fh->buffers.active != ZORAN_FREE) { - dprintk(1, KERN_WARNING - "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto sjpegc_unlock_and_return; + default: + return -EINVAL; + } + + return 0; } + break; - res = zoran_check_jpg_settings(zr, &settings, 0); - if (res) - goto sjpegc_unlock_and_return; - if (!fh->buffers.allocated) - fh->buffers.buffer_size = - zoran_v4l2_calc_bufsize(&fh->jpg_settings); - fh->jpg_settings.jpg_comp = *params = settings.jpg_comp; -sjpegc_unlock_and_return: - mutex_unlock(&zr->resource_lock); + default: + dprintk(1, KERN_DEBUG "%s: UNKNOWN ioctl cmd: 0x%x\n", + ZR_DEVNAME(zr), cmd); + return -ENOIOCTLCMD; + break; - return res; + } + return 0; +} + + +static long +zoran_ioctl(struct file *file, + unsigned int cmd, + unsigned long arg) +{ + return video_usercopy(file, cmd, arg, zoran_do_ioctl); } static unsigned int @@ -3062,11 +4191,11 @@ zoran_poll (struct file *file, KERN_DEBUG "%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n", ZR_DEVNAME(zr), __func__, - "FAL"[fh->buffers.active], zr->v4l_sync_tail, + "FAL"[fh->v4l_buffers.active], zr->v4l_sync_tail, "UPMD"[zr->v4l_buffers.buffer[frame].state], zr->v4l_pend_tail, zr->v4l_pend_head); /* Process is the one capturing? */ - if (fh->buffers.active != ZORAN_FREE && + if (fh->v4l_buffers.active != ZORAN_FREE && /* Buffer ready to DQBUF? */ zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE) res = POLLIN | POLLRDNORM; @@ -3084,10 +4213,10 @@ zoran_poll (struct file *file, KERN_DEBUG "%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n", ZR_DEVNAME(zr), __func__, - "FAL"[fh->buffers.active], zr->jpg_que_tail, + "FAL"[fh->jpg_buffers.active], zr->jpg_que_tail, "UPMD"[zr->jpg_buffers.buffer[frame].state], zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head); - if (fh->buffers.active != ZORAN_FREE && + if (fh->jpg_buffers.active != ZORAN_FREE && zr->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) { if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) res = POLLIN | POLLRDNORM; @@ -3101,8 +4230,8 @@ zoran_poll (struct file *file, default: dprintk(1, KERN_ERR - "%s: %s - internal error, unknown map_mode=%d\n", - ZR_DEVNAME(zr), __func__, fh->map_mode); + "%s: zoran_poll() - internal error, unknown map_mode=%d\n", + ZR_DEVNAME(zr), fh->map_mode); res = POLLNVAL; } @@ -3136,53 +4265,98 @@ static void zoran_vm_close (struct vm_area_struct *vma) { struct zoran_mapping *map = vma->vm_private_data; - struct zoran_fh *fh = map->file->private_data; + struct file *file = map->file; + struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; int i; - if (--map->count > 0) - return; + map->count--; + if (map->count == 0) { + switch (fh->map_mode) { + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: - dprintk(3, KERN_INFO "%s: %s - munmap(%s)\n", ZR_DEVNAME(zr), - __func__, mode_name(fh->map_mode)); + dprintk(3, KERN_INFO "%s: munmap(MJPEG)\n", + ZR_DEVNAME(zr)); - for (i = 0; i < fh->buffers.num_buffers; i++) { - if (fh->buffers.buffer[i].map == map) - fh->buffers.buffer[i].map = NULL; - } - kfree(map); + for (i = 0; i < fh->jpg_buffers.num_buffers; i++) { + if (fh->jpg_buffers.buffer[i].map == map) { + fh->jpg_buffers.buffer[i].map = + NULL; + } + } + kfree(map); - /* Any buffers still mapped? */ - for (i = 0; i < fh->buffers.num_buffers; i++) - if (fh->buffers.buffer[i].map) - return; + for (i = 0; i < fh->jpg_buffers.num_buffers; i++) + if (fh->jpg_buffers.buffer[i].map) + break; + if (i == fh->jpg_buffers.num_buffers) { + mutex_lock(&zr->resource_lock); + + if (fh->jpg_buffers.active != ZORAN_FREE) { + jpg_qbuf(file, -1, zr->codec_mode); + zr->jpg_buffers.allocated = 0; + zr->jpg_buffers.active = + fh->jpg_buffers.active = + ZORAN_FREE; + } + //jpg_fbuffer_free(file); + fh->jpg_buffers.allocated = 0; + fh->jpg_buffers.ready_to_be_freed = 1; - dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr), - __func__, mode_name(fh->map_mode)); + mutex_unlock(&zr->resource_lock); + } - mutex_lock(&zr->resource_lock); + break; - if (fh->map_mode == ZORAN_MAP_MODE_RAW) { - if (fh->buffers.active != ZORAN_FREE) { - unsigned long flags; + case ZORAN_MAP_MODE_RAW: + + dprintk(3, KERN_INFO "%s: munmap(V4L)\n", + ZR_DEVNAME(zr)); + + for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { + if (fh->v4l_buffers.buffer[i].map == map) { + /* unqueue/unmap */ + fh->v4l_buffers.buffer[i].map = + NULL; + } + } + kfree(map); + + for (i = 0; i < fh->v4l_buffers.num_buffers; i++) + if (fh->v4l_buffers.buffer[i].map) + break; + if (i == fh->v4l_buffers.num_buffers) { + mutex_lock(&zr->resource_lock); + + if (fh->v4l_buffers.active != ZORAN_FREE) { + unsigned long flags; + + spin_lock_irqsave(&zr->spinlock, flags); + zr36057_set_memgrab(zr, 0); + zr->v4l_buffers.allocated = 0; + zr->v4l_buffers.active = + fh->v4l_buffers.active = + ZORAN_FREE; + spin_unlock_irqrestore(&zr->spinlock, flags); + } + //v4l_fbuffer_free(file); + fh->v4l_buffers.allocated = 0; + fh->v4l_buffers.ready_to_be_freed = 1; + + mutex_unlock(&zr->resource_lock); + } + + break; + + default: + printk(KERN_ERR + "%s: munmap() - internal error - unknown map mode %d\n", + ZR_DEVNAME(zr), fh->map_mode); + break; - spin_lock_irqsave(&zr->spinlock, flags); - zr36057_set_memgrab(zr, 0); - zr->v4l_buffers.allocated = 0; - zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE; - spin_unlock_irqrestore(&zr->spinlock, flags); - } - v4l_fbuffer_free(fh); - } else { - if (fh->buffers.active != ZORAN_FREE) { - jpg_qbuf(fh, -1, zr->codec_mode); - zr->jpg_buffers.allocated = 0; - zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE; } - jpg_fbuffer_free(fh); } - - mutex_unlock(&zr->resource_lock); } static struct vm_operations_struct zoran_vm_ops = { @@ -3205,106 +4379,90 @@ zoran_mmap (struct file *file, int res = 0; dprintk(3, - KERN_INFO "%s: %s(%s) of 0x%08lx-0x%08lx (size=%lu)\n", - ZR_DEVNAME(zr), __func__, - mode_name(fh->map_mode), vma->vm_start, vma->vm_end, size); + KERN_INFO "%s: mmap(%s) of 0x%08lx-0x%08lx (size=%lu)\n", + ZR_DEVNAME(zr), + fh->map_mode == ZORAN_MAP_MODE_RAW ? "V4L" : "MJPEG", + vma->vm_start, vma->vm_end, size); if (!(vma->vm_flags & VM_SHARED) || !(vma->vm_flags & VM_READ) || !(vma->vm_flags & VM_WRITE)) { dprintk(1, KERN_ERR - "%s: %s - no MAP_SHARED/PROT_{READ,WRITE} given\n", - ZR_DEVNAME(zr), __func__); + "%s: mmap() - no MAP_SHARED/PROT_{READ,WRITE} given\n", + ZR_DEVNAME(zr)); return -EINVAL; } - mutex_lock(&zr->resource_lock); + switch (fh->map_mode) { - if (!fh->buffers.allocated) { - dprintk(1, - KERN_ERR - "%s: %s(%s) - buffers not yet allocated\n", - ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode)); - res = -ENOMEM; - goto mmap_unlock_and_return; - } + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: - first = offset / fh->buffers.buffer_size; - last = first - 1 + size / fh->buffers.buffer_size; - if (offset % fh->buffers.buffer_size != 0 || - size % fh->buffers.buffer_size != 0 || first < 0 || - last < 0 || first >= fh->buffers.num_buffers || - last >= fh->buffers.buffer_size) { - dprintk(1, - KERN_ERR - "%s: %s(%s) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n", - ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode), offset, size, - fh->buffers.buffer_size, - fh->buffers.num_buffers); - res = -EINVAL; - goto mmap_unlock_and_return; - } + /* lock */ + mutex_lock(&zr->resource_lock); - /* Check if any buffers are already mapped */ - for (i = first; i <= last; i++) { - if (fh->buffers.buffer[i].map) { + /* Map the MJPEG buffers */ + if (!fh->jpg_buffers.allocated) { dprintk(1, KERN_ERR - "%s: %s(%s) - buffer %d already mapped\n", - ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode), i); - res = -EBUSY; - goto mmap_unlock_and_return; + "%s: zoran_mmap(MJPEG) - buffers not yet allocated\n", + ZR_DEVNAME(zr)); + res = -ENOMEM; + goto jpg_mmap_unlock_and_return; } - } - - /* map these buffers */ - map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL); - if (!map) { - res = -ENOMEM; - goto mmap_unlock_and_return; - } - map->file = file; - map->count = 1; - vma->vm_ops = &zoran_vm_ops; - vma->vm_flags |= VM_DONTEXPAND; - vma->vm_private_data = map; - - if (fh->map_mode == ZORAN_MAP_MODE_RAW) { + first = offset / fh->jpg_buffers.buffer_size; + last = first - 1 + size / fh->jpg_buffers.buffer_size; + if (offset % fh->jpg_buffers.buffer_size != 0 || + size % fh->jpg_buffers.buffer_size != 0 || first < 0 || + last < 0 || first >= fh->jpg_buffers.num_buffers || + last >= fh->jpg_buffers.num_buffers) { + dprintk(1, + KERN_ERR + "%s: mmap(MJPEG) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n", + ZR_DEVNAME(zr), offset, size, + fh->jpg_buffers.buffer_size, + fh->jpg_buffers.num_buffers); + res = -EINVAL; + goto jpg_mmap_unlock_and_return; + } for (i = first; i <= last; i++) { - todo = size; - if (todo > fh->buffers.buffer_size) - todo = fh->buffers.buffer_size; - page = fh->buffers.buffer[i].v4l.fbuffer_phys; - if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, - todo, PAGE_SHARED)) { + if (fh->jpg_buffers.buffer[i].map) { dprintk(1, KERN_ERR - "%s: %s(V4L) - remap_pfn_range failed\n", - ZR_DEVNAME(zr), __func__); - res = -EAGAIN; - goto mmap_unlock_and_return; + "%s: mmap(MJPEG) - buffer %d already mapped\n", + ZR_DEVNAME(zr), i); + res = -EBUSY; + goto jpg_mmap_unlock_and_return; } - size -= todo; - start += todo; - fh->buffers.buffer[i].map = map; - if (size == 0) - break; } - } else { + + /* map these buffers (v4l_buffers[i]) */ + map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL); + if (!map) { + res = -ENOMEM; + goto jpg_mmap_unlock_and_return; + } + map->file = file; + map->count = 1; + + vma->vm_ops = &zoran_vm_ops; + vma->vm_flags |= VM_DONTEXPAND; + vma->vm_private_data = map; + for (i = first; i <= last; i++) { for (j = 0; - j < fh->buffers.buffer_size / PAGE_SIZE; + j < fh->jpg_buffers.buffer_size / PAGE_SIZE; j++) { fraglen = - (le32_to_cpu(fh->buffers.buffer[i].jpg. + (le32_to_cpu(fh->jpg_buffers.buffer[i]. frag_tab[2 * j + 1]) & ~1) << 1; todo = size; if (todo > fraglen) todo = fraglen; pos = - le32_to_cpu(fh->buffers. - buffer[i].jpg.frag_tab[2 * j]); + le32_to_cpu(fh->jpg_buffers. + buffer[i].frag_tab[2 * j]); /* should just be pos on i386 */ page = virt_to_phys(bus_to_virt(pos)) >> PAGE_SHIFT; @@ -3312,82 +4470,123 @@ zoran_mmap (struct file *file, todo, PAGE_SHARED)) { dprintk(1, KERN_ERR - "%s: %s(V4L) - remap_pfn_range failed\n", - ZR_DEVNAME(zr), __func__); + "%s: zoran_mmap(V4L) - remap_pfn_range failed\n", + ZR_DEVNAME(zr)); res = -EAGAIN; - goto mmap_unlock_and_return; + goto jpg_mmap_unlock_and_return; } size -= todo; start += todo; if (size == 0) break; - if (le32_to_cpu(fh->buffers.buffer[i].jpg. + if (le32_to_cpu(fh->jpg_buffers.buffer[i]. frag_tab[2 * j + 1]) & 1) break; /* was last fragment */ } - fh->buffers.buffer[i].map = map; + fh->jpg_buffers.buffer[i].map = map; if (size == 0) break; } - } + jpg_mmap_unlock_and_return: + mutex_unlock(&zr->resource_lock); -mmap_unlock_and_return: - mutex_unlock(&zr->resource_lock); + break; + + case ZORAN_MAP_MODE_RAW: + + mutex_lock(&zr->resource_lock); + + /* Map the V4L buffers */ + if (!fh->v4l_buffers.allocated) { + dprintk(1, + KERN_ERR + "%s: zoran_mmap(V4L) - buffers not yet allocated\n", + ZR_DEVNAME(zr)); + res = -ENOMEM; + goto v4l_mmap_unlock_and_return; + } + + first = offset / fh->v4l_buffers.buffer_size; + last = first - 1 + size / fh->v4l_buffers.buffer_size; + if (offset % fh->v4l_buffers.buffer_size != 0 || + size % fh->v4l_buffers.buffer_size != 0 || first < 0 || + last < 0 || first >= fh->v4l_buffers.num_buffers || + last >= fh->v4l_buffers.buffer_size) { + dprintk(1, + KERN_ERR + "%s: mmap(V4L) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n", + ZR_DEVNAME(zr), offset, size, + fh->v4l_buffers.buffer_size, + fh->v4l_buffers.num_buffers); + res = -EINVAL; + goto v4l_mmap_unlock_and_return; + } + for (i = first; i <= last; i++) { + if (fh->v4l_buffers.buffer[i].map) { + dprintk(1, + KERN_ERR + "%s: mmap(V4L) - buffer %d already mapped\n", + ZR_DEVNAME(zr), i); + res = -EBUSY; + goto v4l_mmap_unlock_and_return; + } + } + + /* map these buffers (v4l_buffers[i]) */ + map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL); + if (!map) { + res = -ENOMEM; + goto v4l_mmap_unlock_and_return; + } + map->file = file; + map->count = 1; + + vma->vm_ops = &zoran_vm_ops; + vma->vm_flags |= VM_DONTEXPAND; + vma->vm_private_data = map; + + for (i = first; i <= last; i++) { + todo = size; + if (todo > fh->v4l_buffers.buffer_size) + todo = fh->v4l_buffers.buffer_size; + page = fh->v4l_buffers.buffer[i].fbuffer_phys; + if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, + todo, PAGE_SHARED)) { + dprintk(1, + KERN_ERR + "%s: zoran_mmap(V4L)i - remap_pfn_range failed\n", + ZR_DEVNAME(zr)); + res = -EAGAIN; + goto v4l_mmap_unlock_and_return; + } + size -= todo; + start += todo; + fh->v4l_buffers.buffer[i].map = map; + if (size == 0) + break; + } + v4l_mmap_unlock_and_return: + mutex_unlock(&zr->resource_lock); + + break; + + default: + dprintk(1, + KERN_ERR + "%s: zoran_mmap() - internal error - unknown map mode %d\n", + ZR_DEVNAME(zr), fh->map_mode); + break; + } return 0; } -static const struct v4l2_ioctl_ops zoran_ioctl_ops = { - .vidioc_querycap = zoran_querycap, - .vidioc_cropcap = zoran_cropcap, - .vidioc_s_crop = zoran_s_crop, - .vidioc_g_crop = zoran_g_crop, - .vidioc_enum_input = zoran_enum_input, - .vidioc_g_input = zoran_g_input, - .vidioc_s_input = zoran_s_input, - .vidioc_enum_output = zoran_enum_output, - .vidioc_g_output = zoran_g_output, - .vidioc_s_output = zoran_s_output, - .vidioc_g_fbuf = zoran_g_fbuf, - .vidioc_s_fbuf = zoran_s_fbuf, - .vidioc_g_std = zoran_g_std, - .vidioc_s_std = zoran_s_std, - .vidioc_g_jpegcomp = zoran_g_jpegcomp, - .vidioc_s_jpegcomp = zoran_s_jpegcomp, - .vidioc_overlay = zoran_overlay, - .vidioc_reqbufs = zoran_reqbufs, - .vidioc_querybuf = zoran_querybuf, - .vidioc_qbuf = zoran_qbuf, - .vidioc_dqbuf = zoran_dqbuf, - .vidioc_streamon = zoran_streamon, - .vidioc_streamoff = zoran_streamoff, - .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap, - .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out, - .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay, - .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap, - .vidioc_g_fmt_vid_out = zoran_g_fmt_vid_out, - .vidioc_g_fmt_vid_overlay = zoran_g_fmt_vid_overlay, - .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap, - .vidioc_s_fmt_vid_out = zoran_s_fmt_vid_out, - .vidioc_s_fmt_vid_overlay = zoran_s_fmt_vid_overlay, - .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap, - .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out, - .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay, - .vidioc_queryctrl = zoran_queryctrl, - .vidioc_s_ctrl = zoran_s_ctrl, - .vidioc_g_ctrl = zoran_g_ctrl, -#ifdef CONFIG_VIDEO_V4L1_COMPAT - .vidioc_default = zoran_default, - .vidiocgmbuf = zoran_vidiocgmbuf, -#endif -}; - static const struct v4l2_file_operations zoran_fops = { .owner = THIS_MODULE, .open = zoran_open, .release = zoran_close, - .ioctl = video_ioctl2, + .ioctl = zoran_ioctl, .read = zoran_read, .write = zoran_write, .mmap = zoran_mmap, @@ -3397,9 +4596,7 @@ static const struct v4l2_file_operations zoran_fops = { struct video_device zoran_template __devinitdata = { .name = ZORAN_NAME, .fops = &zoran_fops, - .ioctl_ops = &zoran_ioctl_ops, .release = &zoran_vdev_release, - .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, .minor = -1 }; diff --git a/trunk/drivers/media/video/zoran/zoran_procfs.c b/trunk/drivers/media/video/zoran/zoran_procfs.c index f1423b777db1..870bc5a70e3f 100644 --- a/trunk/drivers/media/video/zoran/zoran_procfs.c +++ b/trunk/drivers/media/video/zoran/zoran_procfs.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/drivers/media/video/zoran/zr36016.c b/trunk/drivers/media/video/zoran/zr36016.c index 21c088ea9046..00d132bcd1e4 100644 --- a/trunk/drivers/media/video/zoran/zr36016.c +++ b/trunk/drivers/media/video/zoran/zr36016.c @@ -34,10 +34,15 @@ #include #include +/* includes for structures and defines regarding video + #include */ + /* I/O commands, error codes */ #include +//#include /* v4l API */ +#include /* headerfile of this module */ #include"zr36016.h" diff --git a/trunk/drivers/media/video/zoran/zr36050.c b/trunk/drivers/media/video/zoran/zr36050.c index 639dd87c663f..cf8b271a1c8f 100644 --- a/trunk/drivers/media/video/zoran/zr36050.c +++ b/trunk/drivers/media/video/zoran/zr36050.c @@ -34,8 +34,12 @@ #include #include +/* includes for structures and defines regarding video + #include */ + /* I/O commands, error codes */ #include +//#include /* headerfile of this module */ #include "zr36050.h" diff --git a/trunk/drivers/media/video/zoran/zr36060.c b/trunk/drivers/media/video/zoran/zr36060.c index 008746ff7746..8e74054d5ef1 100644 --- a/trunk/drivers/media/video/zoran/zr36060.c +++ b/trunk/drivers/media/video/zoran/zr36060.c @@ -34,8 +34,12 @@ #include #include +/* includes for structures and defines regarding video + #include */ + /* I/O commands, error codes */ #include +//#include /* headerfile of this module */ #include "zr36060.h" diff --git a/trunk/drivers/media/video/zr364xx.c b/trunk/drivers/media/video/zr364xx.c index 221409fe1682..93023560f324 100644 --- a/trunk/drivers/media/video/zr364xx.c +++ b/trunk/drivers/media/video/zr364xx.c @@ -96,7 +96,6 @@ static struct usb_device_id device_table[] = { {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 }, {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 }, {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 }, - {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD2 }, {} /* Terminating entry */ }; @@ -426,6 +425,7 @@ static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t cnt, static int zr364xx_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { + memset(cap, 0, sizeof(*cap)); strcpy(cap->driver, DRIVER_DESC); cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; return 0; @@ -436,6 +436,8 @@ static int zr364xx_vidioc_enum_input(struct file *file, void *priv, { if (i->index != 0) return -EINVAL; + memset(i, 0, sizeof(*i)); + i->index = 0; strcpy(i->name, DRIVER_DESC " Camera"); i->type = V4L2_INPUT_TYPE_CAMERA; return 0; @@ -527,6 +529,11 @@ static int zr364xx_vidioc_enum_fmt_vid_cap(struct file *file, { if (f->index > 0) return -EINVAL; + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + memset(f, 0, sizeof(*f)); + f->index = 0; + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->flags = V4L2_FMT_FLAG_COMPRESSED; strcpy(f->description, "JPEG"); f->pixelformat = V4L2_PIX_FMT_JPEG; @@ -543,6 +550,8 @@ static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv, return -ENODEV; cam = video_get_drvdata(vdev); + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) return -EINVAL; if (f->fmt.pix.field != V4L2_FIELD_ANY && @@ -568,6 +577,10 @@ static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv, return -ENODEV; cam = video_get_drvdata(vdev); + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format)); + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; f->fmt.pix.field = V4L2_FIELD_NONE; f->fmt.pix.width = cam->width; @@ -589,6 +602,8 @@ static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv, return -ENODEV; cam = video_get_drvdata(vdev); + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) return -EINVAL; if (f->fmt.pix.field != V4L2_FIELD_ANY && diff --git a/trunk/drivers/message/i2o/i2o_proc.c b/trunk/drivers/message/i2o/i2o_proc.c index 7045c45da9b1..9a36b5a7de57 100644 --- a/trunk/drivers/message/i2o/i2o_proc.c +++ b/trunk/drivers/message/i2o/i2o_proc.c @@ -2037,6 +2037,8 @@ static int __init i2o_proc_fs_create(void) if (!i2o_proc_dir_root) return -1; + i2o_proc_dir_root->owner = THIS_MODULE; + list_for_each_entry(c, &i2o_controllers, list) i2o_proc_iop_add(i2o_proc_dir_root, c); diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index 0b92b2f6ea68..1c484084ed4f 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -165,7 +165,7 @@ config SGI_XP depends on (IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || X86_UV) && SMP select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2 select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2 - select SGI_GRU if X86_64 && SMP + select SGI_GRU if (IA64_GENERIC || IA64_SGI_UV || X86_64) && SMP ---help--- An SGI machine can be divided into multiple Single System Images which act independently of each other and have @@ -189,7 +189,7 @@ config HP_ILO config SGI_GRU tristate "SGI GRU driver" - depends on X86_UV && SMP + depends on (X86_UV || IA64_SGI_UV || IA64_GENERIC) && SMP default n select MMU_NOTIFIER ---help--- @@ -223,16 +223,6 @@ config DELL_LAPTOP This driver adds support for rfkill and backlight control to Dell laptops. -config ISL29003 - tristate "Intersil ISL29003 ambient light sensor" - depends on I2C && SYSFS - help - If you say yes here you get support for the Intersil ISL29003 - ambient light sensor. - - This driver can also be built as a module. If so, the module - will be called isl29003. - source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" diff --git a/trunk/drivers/misc/Makefile b/trunk/drivers/misc/Makefile index 7871f05dcb9b..bc1199830554 100644 --- a/trunk/drivers/misc/Makefile +++ b/trunk/drivers/misc/Makefile @@ -18,6 +18,5 @@ obj-$(CONFIG_KGDB_TESTS) += kgdbts.o obj-$(CONFIG_SGI_XP) += sgi-xp/ obj-$(CONFIG_SGI_GRU) += sgi-gru/ obj-$(CONFIG_HP_ILO) += hpilo.o -obj-$(CONFIG_ISL29003) += isl29003.o obj-$(CONFIG_C2PORT) += c2port/ obj-y += eeprom/ diff --git a/trunk/drivers/misc/eeprom/at24.c b/trunk/drivers/misc/eeprom/at24.c index d184dfab9631..d4775528abc6 100644 --- a/trunk/drivers/misc/eeprom/at24.c +++ b/trunk/drivers/misc/eeprom/at24.c @@ -53,7 +53,6 @@ struct at24_data { struct at24_platform_data chip; - struct memory_accessor macc; bool use_smbus; /* @@ -226,11 +225,14 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, return status; } -static ssize_t at24_read(struct at24_data *at24, +static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { + struct at24_data *at24; ssize_t retval = 0; + at24 = dev_get_drvdata(container_of(kobj, struct device, kobj)); + if (unlikely(!count)) return count; @@ -260,14 +262,12 @@ static ssize_t at24_read(struct at24_data *at24, return retval; } -static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr, - char *buf, loff_t off, size_t count) -{ - struct at24_data *at24; - at24 = dev_get_drvdata(container_of(kobj, struct device, kobj)); - return at24_read(at24, buf, off, count); -} +/* + * REVISIT: export at24_bin{read,write}() to let other kernel code use + * eeprom data. For example, it might hold a board's Ethernet address, or + * board-specific calibration data generated on the manufacturing floor. + */ /* @@ -347,11 +347,14 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf, return -ETIMEDOUT; } -static ssize_t at24_write(struct at24_data *at24, +static ssize_t at24_bin_write(struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { + struct at24_data *at24; ssize_t retval = 0; + at24 = dev_get_drvdata(container_of(kobj, struct device, kobj)); + if (unlikely(!count)) return count; @@ -381,39 +384,6 @@ static ssize_t at24_write(struct at24_data *at24, return retval; } -static ssize_t at24_bin_write(struct kobject *kobj, struct bin_attribute *attr, - char *buf, loff_t off, size_t count) -{ - struct at24_data *at24; - - at24 = dev_get_drvdata(container_of(kobj, struct device, kobj)); - return at24_write(at24, buf, off, count); -} - -/*-------------------------------------------------------------------------*/ - -/* - * This lets other kernel code access the eeprom data. For example, it - * might hold a board's Ethernet address, or board-specific calibration - * data generated on the manufacturing floor. - */ - -static ssize_t at24_macc_read(struct memory_accessor *macc, char *buf, - off_t offset, size_t count) -{ - struct at24_data *at24 = container_of(macc, struct at24_data, macc); - - return at24_read(at24, buf, offset, count); -} - -static ssize_t at24_macc_write(struct memory_accessor *macc, char *buf, - off_t offset, size_t count) -{ - struct at24_data *at24 = container_of(macc, struct at24_data, macc); - - return at24_write(at24, buf, offset, count); -} - /*-------------------------------------------------------------------------*/ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) @@ -443,9 +413,6 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) * is recommended anyhow. */ chip.page_size = 1; - - chip.setup = NULL; - chip.context = NULL; } if (!is_power_of_2(chip.byte_len)) @@ -496,8 +463,6 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) at24->bin.read = at24_bin_read; at24->bin.size = chip.byte_len; - at24->macc.read = at24_macc_read; - writable = !(chip.flags & AT24_FLAG_READONLY); if (writable) { if (!use_smbus || i2c_check_functionality(client->adapter, @@ -505,8 +470,6 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) unsigned write_max = chip.page_size; - at24->macc.write = at24_macc_write; - at24->bin.write = at24_bin_write; at24->bin.attr.mode |= S_IWUSR; @@ -557,10 +520,6 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) at24->write_max, use_smbus ? ", use_smbus" : ""); - /* export data to kernel code */ - if (chip.setup) - chip.setup(&at24->macc, chip.context); - return 0; err_clients: diff --git a/trunk/drivers/misc/eeprom/at25.c b/trunk/drivers/misc/eeprom/at25.c index 6bc0dac5c1e8..290dbe99647a 100644 --- a/trunk/drivers/misc/eeprom/at25.c +++ b/trunk/drivers/misc/eeprom/at25.c @@ -30,7 +30,6 @@ struct at25_data { struct spi_device *spi; - struct memory_accessor mem; struct mutex lock; struct spi_eeprom chip; struct bin_attribute bin; @@ -76,13 +75,6 @@ at25_ee_read( struct spi_transfer t[2]; struct spi_message m; - if (unlikely(offset >= at25->bin.size)) - return 0; - if ((offset + count) > at25->bin.size) - count = at25->bin.size - offset; - if (unlikely(!count)) - return count; - cp = command; *cp++ = AT25_READ; @@ -135,6 +127,13 @@ at25_bin_read(struct kobject *kobj, struct bin_attribute *bin_attr, dev = container_of(kobj, struct device, kobj); at25 = dev_get_drvdata(dev); + if (unlikely(off >= at25->bin.size)) + return 0; + if ((off + count) > at25->bin.size) + count = at25->bin.size - off; + if (unlikely(!count)) + return count; + return at25_ee_read(at25, buf, off, count); } @@ -147,13 +146,6 @@ at25_ee_write(struct at25_data *at25, char *buf, loff_t off, size_t count) unsigned buf_size; u8 *bounce; - if (unlikely(off >= at25->bin.size)) - return -EFBIG; - if ((off + count) > at25->bin.size) - count = at25->bin.size - off; - if (unlikely(!count)) - return count; - /* Temp buffer starts with command and address */ buf_size = at25->chip.page_size; if (buf_size > io_limit) @@ -261,27 +253,14 @@ at25_bin_write(struct kobject *kobj, struct bin_attribute *bin_attr, dev = container_of(kobj, struct device, kobj); at25 = dev_get_drvdata(dev); - return at25_ee_write(at25, buf, off, count); -} - -/*-------------------------------------------------------------------------*/ - -/* Let in-kernel code access the eeprom data. */ - -static ssize_t at25_mem_read(struct memory_accessor *mem, char *buf, - off_t offset, size_t count) -{ - struct at25_data *at25 = container_of(mem, struct at25_data, mem); - - return at25_ee_read(at25, buf, offset, count); -} - -static ssize_t at25_mem_write(struct memory_accessor *mem, char *buf, - off_t offset, size_t count) -{ - struct at25_data *at25 = container_of(mem, struct at25_data, mem); + if (unlikely(off >= at25->bin.size)) + return -EFBIG; + if ((off + count) > at25->bin.size) + count = at25->bin.size - off; + if (unlikely(!count)) + return count; - return at25_ee_write(at25, buf, offset, count); + return at25_ee_write(at25, buf, off, count); } /*-------------------------------------------------------------------------*/ @@ -338,10 +317,6 @@ static int at25_probe(struct spi_device *spi) at25->addrlen = addrlen; /* Export the EEPROM bytes through sysfs, since that's convenient. - * And maybe to other kernel code; it might hold a board's Ethernet - * address, or board-specific calibration data generated on the - * manufacturing floor. - * * Default to root-only access to the data; EEPROMs often hold data * that's sensitive for read and/or write, like ethernet addresses, * security codes, board-specific manufacturing calibrations, etc. @@ -349,22 +324,17 @@ static int at25_probe(struct spi_device *spi) at25->bin.attr.name = "eeprom"; at25->bin.attr.mode = S_IRUSR; at25->bin.read = at25_bin_read; - at25->mem.read = at25_mem_read; at25->bin.size = at25->chip.byte_len; if (!(chip->flags & EE_READONLY)) { at25->bin.write = at25_bin_write; at25->bin.attr.mode |= S_IWUSR; - at25->mem.write = at25_mem_write; } err = sysfs_create_bin_file(&spi->dev.kobj, &at25->bin); if (err) goto fail; - if (chip->setup) - chip->setup(&at25->mem, chip->context); - dev_info(&spi->dev, "%Zd %s %s eeprom%s, pagesize %u\n", (at25->bin.size < 1024) ? at25->bin.size diff --git a/trunk/drivers/misc/hpilo.c b/trunk/drivers/misc/hpilo.c index 880ccf39e23b..cf991850f01b 100644 --- a/trunk/drivers/misc/hpilo.c +++ b/trunk/drivers/misc/hpilo.c @@ -209,7 +209,7 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data) /* give iLO some time to process stop request */ for (retries = MAX_WAIT; retries > 0; retries--) { doorbell_set(driver_ccb); - udelay(WAIT_TIME); + udelay(1); if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A)) && !(ioread32(&device_ccb->recv_ctrl) & (1 << CTRL_BITPOS_A))) @@ -312,7 +312,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) for (i = MAX_WAIT; i > 0; i--) { if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL)) break; - udelay(WAIT_TIME); + udelay(1); } if (i) { @@ -759,7 +759,7 @@ static void __exit ilo_exit(void) class_destroy(ilo_class); } -MODULE_VERSION("1.1"); +MODULE_VERSION("1.0"); MODULE_ALIAS(ILO_NAME); MODULE_DESCRIPTION(ILO_NAME); MODULE_AUTHOR("David Altobelli "); diff --git a/trunk/drivers/misc/hpilo.h b/trunk/drivers/misc/hpilo.h index 03a14c82aad9..b64a20ef07e3 100644 --- a/trunk/drivers/misc/hpilo.h +++ b/trunk/drivers/misc/hpilo.h @@ -19,12 +19,8 @@ #define MAX_ILO_DEV 1 /* max number of files */ #define MAX_OPEN (MAX_CCB * MAX_ILO_DEV) -/* total wait time in usec */ -#define MAX_WAIT_TIME 10000 -/* per spin wait time in usec */ -#define WAIT_TIME 10 /* spin counter for open/close delay */ -#define MAX_WAIT (MAX_WAIT_TIME / WAIT_TIME) +#define MAX_WAIT 10000 /* * Per device, used to track global memory allocations. diff --git a/trunk/drivers/misc/isl29003.c b/trunk/drivers/misc/isl29003.c deleted file mode 100644 index 2e2a5923d4c2..000000000000 --- a/trunk/drivers/misc/isl29003.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * isl29003.c - Linux kernel module for - * Intersil ISL29003 ambient light sensor - * - * See file:Documentation/misc-devices/isl29003 - * - * Copyright (c) 2009 Daniel Mack - * - * Based on code written by - * Rodolfo Giometti - * Eurotech S.p.A. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include - -#define ISL29003_DRV_NAME "isl29003" -#define DRIVER_VERSION "1.0" - -#define ISL29003_REG_COMMAND 0x00 -#define ISL29003_ADC_ENABLED (1 << 7) -#define ISL29003_ADC_PD (1 << 6) -#define ISL29003_TIMING_INT (1 << 5) -#define ISL29003_MODE_SHIFT (2) -#define ISL29003_MODE_MASK (0x3 << ISL29003_MODE_SHIFT) -#define ISL29003_RES_SHIFT (0) -#define ISL29003_RES_MASK (0x3 << ISL29003_RES_SHIFT) - -#define ISL29003_REG_CONTROL 0x01 -#define ISL29003_INT_FLG (1 << 5) -#define ISL29003_RANGE_SHIFT (2) -#define ISL29003_RANGE_MASK (0x3 << ISL29003_RANGE_SHIFT) -#define ISL29003_INT_PERSISTS_SHIFT (0) -#define ISL29003_INT_PERSISTS_MASK (0xf << ISL29003_INT_PERSISTS_SHIFT) - -#define ISL29003_REG_IRQ_THRESH_HI 0x02 -#define ISL29003_REG_IRQ_THRESH_LO 0x03 -#define ISL29003_REG_LSB_SENSOR 0x04 -#define ISL29003_REG_MSB_SENSOR 0x05 -#define ISL29003_REG_LSB_TIMER 0x06 -#define ISL29003_REG_MSB_TIMER 0x07 - -#define ISL29003_NUM_CACHABLE_REGS 4 - -struct isl29003_data { - struct i2c_client *client; - struct mutex lock; - u8 reg_cache[ISL29003_NUM_CACHABLE_REGS]; -}; - -static int gain_range[] = { - 1000, 4000, 16000, 64000 -}; - -/* - * register access helpers - */ - -static int __isl29003_read_reg(struct i2c_client *client, - u32 reg, u8 mask, u8 shift) -{ - struct isl29003_data *data = i2c_get_clientdata(client); - return (data->reg_cache[reg] & mask) >> shift; -} - -static int __isl29003_write_reg(struct i2c_client *client, - u32 reg, u8 mask, u8 shift, u8 val) -{ - struct isl29003_data *data = i2c_get_clientdata(client); - int ret = 0; - u8 tmp; - - if (reg >= ISL29003_NUM_CACHABLE_REGS) - return -EINVAL; - - mutex_lock(&data->lock); - - tmp = data->reg_cache[reg]; - tmp &= ~mask; - tmp |= val << shift; - - ret = i2c_smbus_write_byte_data(client, reg, tmp); - if (!ret) - data->reg_cache[reg] = tmp; - - mutex_unlock(&data->lock); - return ret; -} - -/* - * internally used functions - */ - -/* range */ -static int isl29003_get_range(struct i2c_client *client) -{ - return __isl29003_read_reg(client, ISL29003_REG_CONTROL, - ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT); -} - -static int isl29003_set_range(struct i2c_client *client, int range) -{ - return __isl29003_write_reg(client, ISL29003_REG_CONTROL, - ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT, range); -} - -/* resolution */ -static int isl29003_get_resolution(struct i2c_client *client) -{ - return __isl29003_read_reg(client, ISL29003_REG_COMMAND, - ISL29003_RES_MASK, ISL29003_RES_SHIFT); -} - -static int isl29003_set_resolution(struct i2c_client *client, int res) -{ - return __isl29003_write_reg(client, ISL29003_REG_COMMAND, - ISL29003_RES_MASK, ISL29003_RES_SHIFT, res); -} - -/* mode */ -static int isl29003_get_mode(struct i2c_client *client) -{ - return __isl29003_read_reg(client, ISL29003_REG_COMMAND, - ISL29003_RES_MASK, ISL29003_RES_SHIFT); -} - -static int isl29003_set_mode(struct i2c_client *client, int mode) -{ - return __isl29003_write_reg(client, ISL29003_REG_COMMAND, - ISL29003_RES_MASK, ISL29003_RES_SHIFT, mode); -} - -/* power_state */ -static int isl29003_set_power_state(struct i2c_client *client, int state) -{ - return __isl29003_write_reg(client, ISL29003_REG_COMMAND, - ISL29003_ADC_ENABLED | ISL29003_ADC_PD, 0, - state ? ISL29003_ADC_ENABLED : ISL29003_ADC_PD); -} - -static int isl29003_get_power_state(struct i2c_client *client) -{ - struct isl29003_data *data = i2c_get_clientdata(client); - u8 cmdreg = data->reg_cache[ISL29003_REG_COMMAND]; - return ~cmdreg & ISL29003_ADC_PD; -} - -static int isl29003_get_adc_value(struct i2c_client *client) -{ - struct isl29003_data *data = i2c_get_clientdata(client); - int lsb, msb, range, bitdepth; - - mutex_lock(&data->lock); - lsb = i2c_smbus_read_byte_data(client, ISL29003_REG_LSB_SENSOR); - - if (lsb < 0) { - mutex_unlock(&data->lock); - return lsb; - } - - msb = i2c_smbus_read_byte_data(client, ISL29003_REG_MSB_SENSOR); - mutex_unlock(&data->lock); - - if (msb < 0) - return msb; - - range = isl29003_get_range(client); - bitdepth = (4 - isl29003_get_resolution(client)) * 4; - return (((msb << 8) | lsb) * gain_range[range]) >> bitdepth; -} - -/* - * sysfs layer - */ - -/* range */ -static ssize_t isl29003_show_range(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%i\n", isl29003_get_range(client)); -} - -static ssize_t isl29003_store_range(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - unsigned long val; - int ret; - - if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3)) - return -EINVAL; - - ret = isl29003_set_range(client, val); - if (ret < 0) - return ret; - - return count; -} - -static DEVICE_ATTR(range, S_IWUSR | S_IRUGO, - isl29003_show_range, isl29003_store_range); - - -/* resolution */ -static ssize_t isl29003_show_resolution(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%d\n", isl29003_get_resolution(client)); -} - -static ssize_t isl29003_store_resolution(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - unsigned long val; - int ret; - - if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3)) - return -EINVAL; - - ret = isl29003_set_resolution(client, val); - if (ret < 0) - return ret; - - return count; -} - -static DEVICE_ATTR(resolution, S_IWUSR | S_IRUGO, - isl29003_show_resolution, isl29003_store_resolution); - -/* mode */ -static ssize_t isl29003_show_mode(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%d\n", isl29003_get_mode(client)); -} - -static ssize_t isl29003_store_mode(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - unsigned long val; - int ret; - - if ((strict_strtoul(buf, 10, &val) < 0) || (val > 2)) - return -EINVAL; - - ret = isl29003_set_mode(client, val); - if (ret < 0) - return ret; - - return count; -} - -static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, - isl29003_show_mode, isl29003_store_mode); - - -/* power state */ -static ssize_t isl29003_show_power_state(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%d\n", isl29003_get_power_state(client)); -} - -static ssize_t isl29003_store_power_state(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - unsigned long val; - int ret; - - if ((strict_strtoul(buf, 10, &val) < 0) || (val > 1)) - return -EINVAL; - - ret = isl29003_set_power_state(client, val); - return ret ? ret : count; -} - -static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO, - isl29003_show_power_state, isl29003_store_power_state); - - -/* lux */ -static ssize_t isl29003_show_lux(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - - /* No LUX data if not operational */ - if (!isl29003_get_power_state(client)) - return -EBUSY; - - return sprintf(buf, "%d\n", isl29003_get_adc_value(client)); -} - -static DEVICE_ATTR(lux, S_IRUGO, isl29003_show_lux, NULL); - -static struct attribute *isl29003_attributes[] = { - &dev_attr_range.attr, - &dev_attr_resolution.attr, - &dev_attr_mode.attr, - &dev_attr_power_state.attr, - &dev_attr_lux.attr, - NULL -}; - -static const struct attribute_group isl29003_attr_group = { - .attrs = isl29003_attributes, -}; - -static int isl29003_init_client(struct i2c_client *client) -{ - struct isl29003_data *data = i2c_get_clientdata(client); - int i; - - /* read all the registers once to fill the cache. - * if one of the reads fails, we consider the init failed */ - for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++) { - int v = i2c_smbus_read_byte_data(client, i); - if (v < 0) - return -ENODEV; - - data->reg_cache[i] = v; - } - - /* set defaults */ - isl29003_set_range(client, 0); - isl29003_set_resolution(client, 0); - isl29003_set_mode(client, 0); - isl29003_set_power_state(client, 0); - - return 0; -} - -/* - * I2C layer - */ - -static int __devinit isl29003_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct isl29003_data *data; - int err = 0; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) - return -EIO; - - data = kzalloc(sizeof(struct isl29003_data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->client = client; - i2c_set_clientdata(client, data); - mutex_init(&data->lock); - - /* initialize the ISL29003 chip */ - err = isl29003_init_client(client); - if (err) - goto exit_kfree; - - /* register sysfs hooks */ - err = sysfs_create_group(&client->dev.kobj, &isl29003_attr_group); - if (err) - goto exit_kfree; - - dev_info(&client->dev, "driver version %s enabled\n", DRIVER_VERSION); - return 0; - -exit_kfree: - kfree(data); - return err; -} - -static int __devexit isl29003_remove(struct i2c_client *client) -{ - sysfs_remove_group(&client->dev.kobj, &isl29003_attr_group); - isl29003_set_power_state(client, 0); - kfree(i2c_get_clientdata(client)); - return 0; -} - -#ifdef CONFIG_PM -static int isl29003_suspend(struct i2c_client *client, pm_message_t mesg) -{ - return isl29003_set_power_state(client, 0); -} - -static int isl29003_resume(struct i2c_client *client) -{ - int i; - struct isl29003_data *data = i2c_get_clientdata(client); - - /* restore registers from cache */ - for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++) - if (!i2c_smbus_write_byte_data(client, i, data->reg_cache[i])) - return -EIO; - - return 0; -} - -#else -#define isl29003_suspend NULL -#define isl29003_resume NULL -#endif /* CONFIG_PM */ - -static const struct i2c_device_id isl29003_id[] = { - { "isl29003", 0 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, isl29003_id); - -static struct i2c_driver isl29003_driver = { - .driver = { - .name = ISL29003_DRV_NAME, - .owner = THIS_MODULE, - }, - .suspend = isl29003_suspend, - .resume = isl29003_resume, - .probe = isl29003_probe, - .remove = __devexit_p(isl29003_remove), - .id_table = isl29003_id, -}; - -static int __init isl29003_init(void) -{ - return i2c_add_driver(&isl29003_driver); -} - -static void __exit isl29003_exit(void) -{ - i2c_del_driver(&isl29003_driver); -} - -MODULE_AUTHOR("Daniel Mack "); -MODULE_DESCRIPTION("ISL29003 ambient light sensor driver"); -MODULE_LICENSE("GPL v2"); -MODULE_VERSION(DRIVER_VERSION); - -module_init(isl29003_init); -module_exit(isl29003_exit); - diff --git a/trunk/drivers/misc/sgi-gru/Makefile b/trunk/drivers/misc/sgi-gru/Makefile index bcd8136d2f98..9e9170b3599a 100644 --- a/trunk/drivers/misc/sgi-gru/Makefile +++ b/trunk/drivers/misc/sgi-gru/Makefile @@ -3,5 +3,5 @@ ifdef CONFIG_SGI_GRU_DEBUG endif obj-$(CONFIG_SGI_GRU) := gru.o -gru-y := grufile.o grumain.o grufault.o grutlbpurge.o gruprocfs.o grukservices.o gruhandles.o +gru-y := grufile.o grumain.o grufault.o grutlbpurge.o gruprocfs.o grukservices.o diff --git a/trunk/drivers/misc/sgi-gru/gru_instructions.h b/trunk/drivers/misc/sgi-gru/gru_instructions.h index 3fde33c1e8f3..48762e7b98be 100644 --- a/trunk/drivers/misc/sgi-gru/gru_instructions.h +++ b/trunk/drivers/misc/sgi-gru/gru_instructions.h @@ -19,11 +19,8 @@ #ifndef __GRU_INSTRUCTIONS_H__ #define __GRU_INSTRUCTIONS_H__ -extern int gru_check_status_proc(void *cb); -extern int gru_wait_proc(void *cb); -extern void gru_wait_abort_proc(void *cb); - - +#define gru_flush_cache_hook(p) +#define gru_emulator_wait_hook(p, w) /* * Architecture dependent functions @@ -32,16 +29,16 @@ extern void gru_wait_abort_proc(void *cb); #if defined(CONFIG_IA64) #include #include -#define __flush_cache(p) ia64_fc((unsigned long)p) +#define __flush_cache(p) ia64_fc(p) /* Use volatile on IA64 to ensure ordering via st4.rel */ -#define gru_ordered_store_int(p, v) \ +#define gru_ordered_store_int(p,v) \ do { \ barrier(); \ *((volatile int *)(p)) = v; /* force st.rel */ \ } while (0) #elif defined(CONFIG_X86_64) #define __flush_cache(p) clflush(p) -#define gru_ordered_store_int(p, v) \ +#define gru_ordered_store_int(p,v) \ do { \ barrier(); \ *(int *)p = v; \ @@ -561,19 +558,20 @@ extern int gru_get_cb_exception_detail(void *cb, #define GRU_EXC_STR_SIZE 256 +extern int gru_check_status_proc(void *cb); +extern int gru_wait_proc(void *cb); +extern void gru_wait_abort_proc(void *cb); /* * Control block definition for checking status */ struct gru_control_block_status { unsigned int icmd :1; - unsigned int ima :3; - unsigned int reserved0 :4; - unsigned int unused1 :24; + unsigned int unused1 :31; unsigned int unused2 :24; unsigned int istatus :2; unsigned int isubstatus :4; - unsigned int unused3 :2; + unsigned int inused3 :2; }; /* Get CB status */ diff --git a/trunk/drivers/misc/sgi-gru/grufault.c b/trunk/drivers/misc/sgi-gru/grufault.c index ab118558552e..3ee698ad8599 100644 --- a/trunk/drivers/misc/sgi-gru/grufault.c +++ b/trunk/drivers/misc/sgi-gru/grufault.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include "gru.h" #include "grutables.h" @@ -267,44 +266,6 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr, return 1; } -static int gru_vtop(struct gru_thread_state *gts, unsigned long vaddr, - int write, int atomic, unsigned long *gpa, int *pageshift) -{ - struct mm_struct *mm = gts->ts_mm; - struct vm_area_struct *vma; - unsigned long paddr; - int ret, ps; - - vma = find_vma(mm, vaddr); - if (!vma) - goto inval; - - /* - * Atomic lookup is faster & usually works even if called in non-atomic - * context. - */ - rmb(); /* Must/check ms_range_active before loading PTEs */ - ret = atomic_pte_lookup(vma, vaddr, write, &paddr, &ps); - if (ret) { - if (atomic) - goto upm; - if (non_atomic_pte_lookup(vma, vaddr, write, &paddr, &ps)) - goto inval; - } - if (is_gru_paddr(paddr)) - goto inval; - paddr = paddr & ~((1UL << ps) - 1); - *gpa = uv_soc_phys_ram_to_gpa(paddr); - *pageshift = ps; - return 0; - -inval: - return -1; -upm: - return -2; -} - - /* * Drop a TLB entry into the GRU. The fault is described by info in an TFH. * Input: @@ -319,8 +280,10 @@ static int gru_try_dropin(struct gru_thread_state *gts, struct gru_tlb_fault_handle *tfh, unsigned long __user *cb) { - int pageshift = 0, asid, write, ret, atomic = !cb; - unsigned long gpa = 0, vaddr = 0; + struct mm_struct *mm = gts->ts_mm; + struct vm_area_struct *vma; + int pageshift, asid, write, ret; + unsigned long paddr, gpa, vaddr; /* * NOTE: The GRU contains magic hardware that eliminates races between @@ -354,19 +317,28 @@ static int gru_try_dropin(struct gru_thread_state *gts, if (atomic_read(>s->ts_gms->ms_range_active)) goto failactive; - ret = gru_vtop(gts, vaddr, write, atomic, &gpa, &pageshift); - if (ret == -1) + vma = find_vma(mm, vaddr); + if (!vma) goto failinval; - if (ret == -2) - goto failupm; - if (!(gts->ts_sizeavail & GRU_SIZEAVAIL(pageshift))) { - gts->ts_sizeavail |= GRU_SIZEAVAIL(pageshift); - if (atomic || !gru_update_cch(gts, 0)) { - gts->ts_force_cch_reload = 1; + /* + * Atomic lookup is faster & usually works even if called in non-atomic + * context. + */ + rmb(); /* Must/check ms_range_active before loading PTEs */ + ret = atomic_pte_lookup(vma, vaddr, write, &paddr, &pageshift); + if (ret) { + if (!cb) goto failupm; - } + if (non_atomic_pte_lookup(vma, vaddr, write, &paddr, + &pageshift)) + goto failinval; } + if (is_gru_paddr(paddr)) + goto failinval; + + paddr = paddr & ~((1UL << pageshift) - 1); + gpa = uv_soc_phys_ram_to_gpa(paddr); gru_cb_set_istatus_active(cb); tfh_write_restart(tfh, gpa, GAA_RAM, vaddr, asid, write, GRU_PAGESIZE(pageshift)); @@ -396,7 +368,6 @@ static int gru_try_dropin(struct gru_thread_state *gts, failfmm: /* FMM state on UPM call */ - gru_flush_cache(tfh); STAT(tlb_dropin_fail_fmm); gru_dbg(grudev, "FAILED fmm tfh: 0x%p, state %d\n", tfh, tfh->state); return 0; @@ -477,7 +448,6 @@ irqreturn_t gru_intr(int irq, void *dev_id) up_read(>s->ts_mm->mmap_sem); } else { tfh_user_polling_mode(tfh); - STAT(intr_mm_lock_failed); } } return IRQ_HANDLED; @@ -527,8 +497,10 @@ int gru_handle_user_call_os(unsigned long cb) if (!gts) return -EINVAL; - if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) + if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) { + ret = -EINVAL; goto exit; + } /* * If force_unload is set, the UPM TLB fault is phony. The task @@ -536,20 +508,6 @@ int gru_handle_user_call_os(unsigned long cb) * unload the context. The task will page fault and assign a new * context. */ - if (gts->ts_tgid_owner == current->tgid && gts->ts_blade >= 0 && - gts->ts_blade != uv_numa_blade_id()) { - STAT(call_os_offnode_reference); - gts->ts_force_unload = 1; - } - - /* - * CCH may contain stale data if ts_force_cch_reload is set. - */ - if (gts->ts_gru && gts->ts_force_cch_reload) { - gru_update_cch(gts, 0); - gts->ts_force_cch_reload = 0; - } - ret = -EAGAIN; cbrnum = thread_cbr_number(gts, ucbnum); if (gts->ts_force_unload) { @@ -583,13 +541,11 @@ int gru_get_exception_detail(unsigned long arg) if (!gts) return -EINVAL; - ucbnum = get_cb_number((void *)excdet.cb); - if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) { - ret = -EINVAL; - } else if (gts->ts_gru) { + if (gts->ts_gru) { + ucbnum = get_cb_number((void *)excdet.cb); cbrnum = thread_cbr_number(gts, ucbnum); cbe = get_cbe_by_index(gts->ts_gru, cbrnum); - prefetchw(cbe);/* Harmless on hardware, required for emulator */ + prefetchw(cbe); /* Harmless on hardware, required for emulator */ excdet.opc = cbe->opccpy; excdet.exopc = cbe->exopccpy; excdet.ecause = cbe->ecause; @@ -611,31 +567,6 @@ int gru_get_exception_detail(unsigned long arg) /* * User request to unload a context. Content is saved for possible reload. */ -static int gru_unload_all_contexts(void) -{ - struct gru_thread_state *gts; - struct gru_state *gru; - int gid, ctxnum; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - foreach_gid(gid) { - gru = GID_TO_GRU(gid); - spin_lock(&gru->gs_lock); - for (ctxnum = 0; ctxnum < GRU_NUM_CCH; ctxnum++) { - gts = gru->gs_gts[ctxnum]; - if (gts && mutex_trylock(>s->ts_ctxlock)) { - spin_unlock(&gru->gs_lock); - gru_unload_context(gts, 1); - gru_unlock_gts(gts); - spin_lock(&gru->gs_lock); - } - } - spin_unlock(&gru->gs_lock); - } - return 0; -} - int gru_user_unload_context(unsigned long arg) { struct gru_thread_state *gts; @@ -647,9 +578,6 @@ int gru_user_unload_context(unsigned long arg) gru_dbg(grudev, "gseg 0x%lx\n", req.gseg); - if (!req.gseg) - return gru_unload_all_contexts(); - gts = gru_find_lock_gts(req.gseg); if (!gts) return -EINVAL; @@ -681,7 +609,7 @@ int gru_user_flush_tlb(unsigned long arg) if (!gts) return -EINVAL; - gru_flush_tlb_range(gts->ts_gms, req.vaddr, req.len); + gru_flush_tlb_range(gts->ts_gms, req.vaddr, req.vaddr + req.len); gru_unlock_gts(gts); return 0; diff --git a/trunk/drivers/misc/sgi-gru/grufile.c b/trunk/drivers/misc/sgi-gru/grufile.c index 3e6e42d2f01b..c67e4e8bd62c 100644 --- a/trunk/drivers/misc/sgi-gru/grufile.c +++ b/trunk/drivers/misc/sgi-gru/grufile.c @@ -45,9 +45,7 @@ #include struct gru_blade_state *gru_base[GRU_MAX_BLADES] __read_mostly; -unsigned long gru_start_paddr __read_mostly; -unsigned long gru_end_paddr __read_mostly; -unsigned int gru_max_gids __read_mostly; +unsigned long gru_start_paddr, gru_end_paddr __read_mostly; struct gru_stats_s gru_stats; /* Guaranteed user available resources on each node */ @@ -103,7 +101,7 @@ static int gru_file_mmap(struct file *file, struct vm_area_struct *vma) return -EPERM; if (vma->vm_start & (GRU_GSEG_PAGESIZE - 1) || - vma->vm_end & (GRU_GSEG_PAGESIZE - 1)) + vma->vm_end & (GRU_GSEG_PAGESIZE - 1)) return -EINVAL; vma->vm_flags |= @@ -275,11 +273,8 @@ static void gru_init_chiplet(struct gru_state *gru, unsigned long paddr, gru->gs_blade_id = bid; gru->gs_cbr_map = (GRU_CBR_AU == 64) ? ~0 : (1UL << GRU_CBR_AU) - 1; gru->gs_dsr_map = (1UL << GRU_DSR_AU) - 1; - gru->gs_asid_limit = MAX_ASID; gru_tgh_flush_init(gru); - if (gru->gs_gid >= gru_max_gids) - gru_max_gids = gru->gs_gid + 1; - gru_dbg(grudev, "bid %d, nid %d, gid %d, vaddr %p (0x%lx)\n", + gru_dbg(grudev, "bid %d, nid %d, gru %x, vaddr %p (0x%lx)\n", bid, nid, gru->gs_gid, gru->gs_gru_base_vaddr, gru->gs_gru_base_paddr); gru_kservices_init(gru); @@ -300,7 +295,7 @@ static int gru_init_tables(unsigned long gru_base_paddr, void *gru_base_vaddr) for_each_online_node(nid) { bid = uv_node_to_blade_id(nid); pnode = uv_node_to_pnode(nid); - if (bid < 0 || gru_base[bid]) + if (gru_base[bid]) continue; page = alloc_pages_node(nid, GFP_KERNEL, order); if (!page) @@ -313,11 +308,11 @@ static int gru_init_tables(unsigned long gru_base_paddr, void *gru_base_vaddr) dsrbytes = 0; cbrs = 0; for (gru = gru_base[bid]->bs_grus, chip = 0; - chip < GRU_CHIPLETS_PER_BLADE; + chip < GRU_CHIPLETS_PER_BLADE; chip++, gru++) { paddr = gru_chiplet_paddr(gru_base_paddr, pnode, chip); vaddr = gru_chiplet_vaddr(gru_base_vaddr, pnode, chip); - gru_init_chiplet(gru, paddr, vaddr, nid, bid, chip); + gru_init_chiplet(gru, paddr, vaddr, bid, nid, chip); n = hweight64(gru->gs_cbr_map) * GRU_CBR_AU_SIZE; cbrs = max(cbrs, n); n = hweight64(gru->gs_dsr_map) * GRU_DSR_AU_BYTES; @@ -375,26 +370,26 @@ static int __init gru_init(void) void *gru_start_vaddr; if (!is_uv_system()) - return -ENODEV; + return 0; #if defined CONFIG_IA64 gru_start_paddr = 0xd000000000UL; /* ZZZZZZZZZZZZZZZZZZZ fixme */ #else gru_start_paddr = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR) & 0x7fffffffffffUL; + #endif gru_start_vaddr = __va(gru_start_paddr); - gru_end_paddr = gru_start_paddr + GRU_MAX_BLADES * GRU_SIZE; + gru_end_paddr = gru_start_paddr + MAX_NUMNODES * GRU_SIZE; printk(KERN_INFO "GRU space: 0x%lx - 0x%lx\n", gru_start_paddr, gru_end_paddr); irq = get_base_irq(); for (chip = 0; chip < GRU_CHIPLETS_PER_BLADE; chip++) { ret = request_irq(irq + chip, gru_intr, 0, id, NULL); - /* TODO: fix irq handling on x86. For now ignore failure because + /* TODO: fix irq handling on x86. For now ignore failures because * interrupts are not required & not yet fully supported */ if (ret) { - printk(KERN_WARNING - "!!!WARNING: GRU ignoring request failure!!!\n"); + printk("!!!WARNING: GRU ignoring request failure!!!\n"); ret = 0; } if (ret) { @@ -440,7 +435,7 @@ static int __init gru_init(void) static void __exit gru_exit(void) { - int i, bid, gid; + int i, bid; int order = get_order(sizeof(struct gru_state) * GRU_CHIPLETS_PER_BLADE); @@ -450,9 +445,6 @@ static void __exit gru_exit(void) for (i = 0; i < GRU_CHIPLETS_PER_BLADE; i++) free_irq(IRQ_GRU + i, NULL); - foreach_gid(gid) - gru_kservices_exit(GID_TO_GRU(gid)); - for (bid = 0; bid < GRU_MAX_BLADES; bid++) free_pages((unsigned long)gru_base[bid], order); @@ -477,11 +469,7 @@ struct vm_operations_struct gru_vm_ops = { .fault = gru_fault, }; -#ifndef MODULE fs_initcall(gru_init); -#else -module_init(gru_init); -#endif module_exit(gru_exit); module_param(gru_options, ulong, 0644); diff --git a/trunk/drivers/misc/sgi-gru/gruhandles.c b/trunk/drivers/misc/sgi-gru/gruhandles.c deleted file mode 100644 index 9b7ccb328697..000000000000 --- a/trunk/drivers/misc/sgi-gru/gruhandles.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * GRU KERNEL MCS INSTRUCTIONS - * - * Copyright (c) 2008 Silicon Graphics, Inc. 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include "gru.h" -#include "grulib.h" -#include "grutables.h" - -/* 10 sec */ -#ifdef CONFIG_IA64 -#include -#define GRU_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10) -#else -#include -#define GRU_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) -#endif - -/* Extract the status field from a kernel handle */ -#define GET_MSEG_HANDLE_STATUS(h) (((*(unsigned long *)(h)) >> 16) & 3) - -struct mcs_op_statistic mcs_op_statistics[mcsop_last]; - -static void update_mcs_stats(enum mcs_op op, unsigned long clks) -{ - atomic_long_inc(&mcs_op_statistics[op].count); - atomic_long_add(clks, &mcs_op_statistics[op].total); - if (mcs_op_statistics[op].max < clks) - mcs_op_statistics[op].max = clks; -} - -static void start_instruction(void *h) -{ - unsigned long *w0 = h; - - wmb(); /* setting CMD bit must be last */ - *w0 = *w0 | 1; - gru_flush_cache(h); -} - -static int wait_instruction_complete(void *h, enum mcs_op opc) -{ - int status; - cycles_t start_time = get_cycles(); - - while (1) { - cpu_relax(); - status = GET_MSEG_HANDLE_STATUS(h); - if (status != CCHSTATUS_ACTIVE) - break; - if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time)) - panic("GRU %p is malfunctioning\n", h); - } - if (gru_options & OPT_STATS) - update_mcs_stats(opc, get_cycles() - start_time); - return status; -} - -int cch_allocate(struct gru_context_configuration_handle *cch, - int asidval, int sizeavail, unsigned long cbrmap, - unsigned long dsrmap) -{ - int i; - - for (i = 0; i < 8; i++) { - cch->asid[i] = (asidval++); - cch->sizeavail[i] = sizeavail; - } - cch->dsr_allocation_map = dsrmap; - cch->cbr_allocation_map = cbrmap; - cch->opc = CCHOP_ALLOCATE; - start_instruction(cch); - return wait_instruction_complete(cch, cchop_allocate); -} - -int cch_start(struct gru_context_configuration_handle *cch) -{ - cch->opc = CCHOP_START; - start_instruction(cch); - return wait_instruction_complete(cch, cchop_start); -} - -int cch_interrupt(struct gru_context_configuration_handle *cch) -{ - cch->opc = CCHOP_INTERRUPT; - start_instruction(cch); - return wait_instruction_complete(cch, cchop_interrupt); -} - -int cch_deallocate(struct gru_context_configuration_handle *cch) -{ - cch->opc = CCHOP_DEALLOCATE; - start_instruction(cch); - return wait_instruction_complete(cch, cchop_deallocate); -} - -int cch_interrupt_sync(struct gru_context_configuration_handle - *cch) -{ - cch->opc = CCHOP_INTERRUPT_SYNC; - start_instruction(cch); - return wait_instruction_complete(cch, cchop_interrupt_sync); -} - -int tgh_invalidate(struct gru_tlb_global_handle *tgh, - unsigned long vaddr, unsigned long vaddrmask, - int asid, int pagesize, int global, int n, - unsigned short ctxbitmap) -{ - tgh->vaddr = vaddr; - tgh->asid = asid; - tgh->pagesize = pagesize; - tgh->n = n; - tgh->global = global; - tgh->vaddrmask = vaddrmask; - tgh->ctxbitmap = ctxbitmap; - tgh->opc = TGHOP_TLBINV; - start_instruction(tgh); - return wait_instruction_complete(tgh, tghop_invalidate); -} - -void tfh_write_only(struct gru_tlb_fault_handle *tfh, - unsigned long pfn, unsigned long vaddr, - int asid, int dirty, int pagesize) -{ - tfh->fillasid = asid; - tfh->fillvaddr = vaddr; - tfh->pfn = pfn; - tfh->dirty = dirty; - tfh->pagesize = pagesize; - tfh->opc = TFHOP_WRITE_ONLY; - start_instruction(tfh); -} - -void tfh_write_restart(struct gru_tlb_fault_handle *tfh, - unsigned long paddr, int gaa, - unsigned long vaddr, int asid, int dirty, - int pagesize) -{ - tfh->fillasid = asid; - tfh->fillvaddr = vaddr; - tfh->pfn = paddr >> GRU_PADDR_SHIFT; - tfh->gaa = gaa; - tfh->dirty = dirty; - tfh->pagesize = pagesize; - tfh->opc = TFHOP_WRITE_RESTART; - start_instruction(tfh); -} - -void tfh_restart(struct gru_tlb_fault_handle *tfh) -{ - tfh->opc = TFHOP_RESTART; - start_instruction(tfh); -} - -void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh) -{ - tfh->opc = TFHOP_USER_POLLING_MODE; - start_instruction(tfh); -} - -void tfh_exception(struct gru_tlb_fault_handle *tfh) -{ - tfh->opc = TFHOP_EXCEPTION; - start_instruction(tfh); -} - diff --git a/trunk/drivers/misc/sgi-gru/gruhandles.h b/trunk/drivers/misc/sgi-gru/gruhandles.h index 1ed74d7508c8..b63018d60fe1 100644 --- a/trunk/drivers/misc/sgi-gru/gruhandles.h +++ b/trunk/drivers/misc/sgi-gru/gruhandles.h @@ -489,28 +489,170 @@ enum gru_cbr_state { * 64m 26 8 * ... */ -#define GRU_PAGESIZE(sh) ((((sh) > 20 ? (sh) + 2 : (sh)) >> 1) - 6) +#define GRU_PAGESIZE(sh) ((((sh) > 20 ? (sh) + 2: (sh)) >> 1) - 6) #define GRU_SIZEAVAIL(sh) (1UL << GRU_PAGESIZE(sh)) /* minimum TLB purge count to ensure a full purge */ #define GRUMAXINVAL 1024UL -int cch_allocate(struct gru_context_configuration_handle *cch, - int asidval, int sizeavail, unsigned long cbrmap, unsigned long dsrmap); - -int cch_start(struct gru_context_configuration_handle *cch); -int cch_interrupt(struct gru_context_configuration_handle *cch); -int cch_deallocate(struct gru_context_configuration_handle *cch); -int cch_interrupt_sync(struct gru_context_configuration_handle *cch); -int tgh_invalidate(struct gru_tlb_global_handle *tgh, unsigned long vaddr, - unsigned long vaddrmask, int asid, int pagesize, int global, int n, - unsigned short ctxbitmap); -void tfh_write_only(struct gru_tlb_fault_handle *tfh, unsigned long pfn, - unsigned long vaddr, int asid, int dirty, int pagesize); -void tfh_write_restart(struct gru_tlb_fault_handle *tfh, unsigned long paddr, - int gaa, unsigned long vaddr, int asid, int dirty, int pagesize); -void tfh_restart(struct gru_tlb_fault_handle *tfh); -void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh); -void tfh_exception(struct gru_tlb_fault_handle *tfh); + +/* Extract the status field from a kernel handle */ +#define GET_MSEG_HANDLE_STATUS(h) (((*(unsigned long *)(h)) >> 16) & 3) + +static inline void start_instruction(void *h) +{ + unsigned long *w0 = h; + + wmb(); /* setting CMD bit must be last */ + *w0 = *w0 | 1; + gru_flush_cache(h); +} + +static inline int wait_instruction_complete(void *h) +{ + int status; + + do { + cpu_relax(); + barrier(); + status = GET_MSEG_HANDLE_STATUS(h); + } while (status == CCHSTATUS_ACTIVE); + return status; +} + +#if defined CONFIG_IA64 +static inline void cch_allocate_set_asids( + struct gru_context_configuration_handle *cch, int asidval) +{ + int i; + + for (i = 0; i <= RGN_HPAGE; i++) { /* assume HPAGE is last region */ + cch->asid[i] = (asidval++); +#if 0 + /* ZZZ hugepages not supported yet */ + if (i == RGN_HPAGE) + cch->sizeavail[i] = GRU_SIZEAVAIL(hpage_shift); + else +#endif + cch->sizeavail[i] = GRU_SIZEAVAIL(PAGE_SHIFT); + } +} +#elif defined CONFIG_X86_64 +static inline void cch_allocate_set_asids( + struct gru_context_configuration_handle *cch, int asidval) +{ + int i; + + for (i = 0; i < 8; i++) { + cch->asid[i] = asidval++; + cch->sizeavail[i] = GRU_SIZEAVAIL(PAGE_SHIFT) | + GRU_SIZEAVAIL(21); + } +} +#endif + +static inline int cch_allocate(struct gru_context_configuration_handle *cch, + int asidval, unsigned long cbrmap, + unsigned long dsrmap) +{ + cch_allocate_set_asids(cch, asidval); + cch->dsr_allocation_map = dsrmap; + cch->cbr_allocation_map = cbrmap; + cch->opc = CCHOP_ALLOCATE; + start_instruction(cch); + return wait_instruction_complete(cch); +} + +static inline int cch_start(struct gru_context_configuration_handle *cch) +{ + cch->opc = CCHOP_START; + start_instruction(cch); + return wait_instruction_complete(cch); +} + +static inline int cch_interrupt(struct gru_context_configuration_handle *cch) +{ + cch->opc = CCHOP_INTERRUPT; + start_instruction(cch); + return wait_instruction_complete(cch); +} + +static inline int cch_deallocate(struct gru_context_configuration_handle *cch) +{ + cch->opc = CCHOP_DEALLOCATE; + start_instruction(cch); + return wait_instruction_complete(cch); +} + +static inline int cch_interrupt_sync(struct gru_context_configuration_handle + *cch) +{ + cch->opc = CCHOP_INTERRUPT_SYNC; + start_instruction(cch); + return wait_instruction_complete(cch); +} + +static inline int tgh_invalidate(struct gru_tlb_global_handle *tgh, + unsigned long vaddr, unsigned long vaddrmask, + int asid, int pagesize, int global, int n, + unsigned short ctxbitmap) +{ + tgh->vaddr = vaddr; + tgh->asid = asid; + tgh->pagesize = pagesize; + tgh->n = n; + tgh->global = global; + tgh->vaddrmask = vaddrmask; + tgh->ctxbitmap = ctxbitmap; + tgh->opc = TGHOP_TLBINV; + start_instruction(tgh); + return wait_instruction_complete(tgh); +} + +static inline void tfh_write_only(struct gru_tlb_fault_handle *tfh, + unsigned long pfn, unsigned long vaddr, + int asid, int dirty, int pagesize) +{ + tfh->fillasid = asid; + tfh->fillvaddr = vaddr; + tfh->pfn = pfn; + tfh->dirty = dirty; + tfh->pagesize = pagesize; + tfh->opc = TFHOP_WRITE_ONLY; + start_instruction(tfh); +} + +static inline void tfh_write_restart(struct gru_tlb_fault_handle *tfh, + unsigned long paddr, int gaa, + unsigned long vaddr, int asid, int dirty, + int pagesize) +{ + tfh->fillasid = asid; + tfh->fillvaddr = vaddr; + tfh->pfn = paddr >> GRU_PADDR_SHIFT; + tfh->gaa = gaa; + tfh->dirty = dirty; + tfh->pagesize = pagesize; + tfh->opc = TFHOP_WRITE_RESTART; + start_instruction(tfh); +} + +static inline void tfh_restart(struct gru_tlb_fault_handle *tfh) +{ + tfh->opc = TFHOP_RESTART; + start_instruction(tfh); +} + +static inline void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh) +{ + tfh->opc = TFHOP_USER_POLLING_MODE; + start_instruction(tfh); +} + +static inline void tfh_exception(struct gru_tlb_fault_handle *tfh) +{ + tfh->opc = TFHOP_EXCEPTION; + start_instruction(tfh); +} #endif /* __GRUHANDLES_H__ */ diff --git a/trunk/drivers/misc/sgi-gru/grukservices.c b/trunk/drivers/misc/sgi-gru/grukservices.c index d8bd7d84a7cf..880c55dfb662 100644 --- a/trunk/drivers/misc/sgi-gru/grukservices.c +++ b/trunk/drivers/misc/sgi-gru/grukservices.c @@ -52,10 +52,8 @@ */ /* Blade percpu resources PERMANENTLY reserved for kernel use */ -#define GRU_NUM_KERNEL_CBR 1 +#define GRU_NUM_KERNEL_CBR 1 #define GRU_NUM_KERNEL_DSR_BYTES 256 -#define GRU_NUM_KERNEL_DSR_CL (GRU_NUM_KERNEL_DSR_BYTES / \ - GRU_CACHE_LINE_BYTES) #define KERNEL_CTXNUM 15 /* GRU instruction attributes for all instructions */ @@ -96,6 +94,7 @@ struct message_header { char fill; }; +#define QLINES(mq) ((mq) + offsetof(struct message_queue, qlines)) #define HSTATUS(mq, h) ((mq) + offsetof(struct message_queue, hstatus[h])) static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr) @@ -123,7 +122,7 @@ int gru_get_cb_exception_detail(void *cb, struct gru_control_block_extended *cbe; cbe = get_cbe(GRUBASE(cb), get_cb_number(cb)); - prefetchw(cbe); /* Harmless on hardware, required for emulator */ + prefetchw(cbe); /* Harmless on hardware, required for emulator */ excdet->opc = cbe->opccpy; excdet->exopc = cbe->exopccpy; excdet->ecause = cbe->ecause; @@ -251,8 +250,7 @@ static inline void restore_present2(void *p, int val) * Create a message queue. * qlines - message queue size in cache lines. Includes 2-line header. */ -int gru_create_message_queue(struct gru_message_queue_desc *mqd, - void *p, unsigned int bytes, int nasid, int vector, int apicid) +int gru_create_message_queue(void *p, unsigned int bytes) { struct message_queue *mq = p; unsigned int qlines; @@ -267,12 +265,6 @@ int gru_create_message_queue(struct gru_message_queue_desc *mqd, mq->hstatus[0] = 0; mq->hstatus[1] = 1; mq->head = gru_mesq_head(2, qlines / 2 + 1); - mqd->mq = mq; - mqd->mq_gpa = uv_gpa(mq); - mqd->qlines = qlines; - mqd->interrupt_pnode = UV_NASID_TO_PNODE(nasid); - mqd->interrupt_vector = vector; - mqd->interrupt_apicid = apicid; return 0; } EXPORT_SYMBOL_GPL(gru_create_message_queue); @@ -285,8 +277,8 @@ EXPORT_SYMBOL_GPL(gru_create_message_queue); * -1 - if mesq sent successfully but queue not full * >0 - unexpected error. MQE_xxx returned */ -static int send_noop_message(void *cb, struct gru_message_queue_desc *mqd, - void *mesg) +static int send_noop_message(void *cb, + unsigned long mq, void *mesg) { const struct message_header noop_header = { .present = MQS_NOOP, .lines = 1}; @@ -297,7 +289,7 @@ static int send_noop_message(void *cb, struct gru_message_queue_desc *mqd, STAT(mesq_noop); save_mhdr = *mhdr; *mhdr = noop_header; - gru_mesq(cb, mqd->mq_gpa, gru_get_tri(mhdr), 1, IMA); + gru_mesq(cb, mq, gru_get_tri(mhdr), 1, IMA); ret = gru_wait(cb); if (ret) { @@ -321,7 +313,7 @@ static int send_noop_message(void *cb, struct gru_message_queue_desc *mqd, break; case CBSS_PUT_NACKED: STAT(mesq_noop_put_nacked); - m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6); + m = mq + (gru_get_amo_value_head(cb) << 6); gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, 1, 1, IMA); if (gru_wait(cb) == CBS_IDLE) @@ -341,20 +333,30 @@ static int send_noop_message(void *cb, struct gru_message_queue_desc *mqd, /* * Handle a gru_mesq full. */ -static int send_message_queue_full(void *cb, struct gru_message_queue_desc *mqd, - void *mesg, int lines) +static int send_message_queue_full(void *cb, + unsigned long mq, void *mesg, int lines) { union gru_mesqhead mqh; unsigned int limit, head; unsigned long avalue; - int half, qlines; + int half, qlines, save; /* Determine if switching to first/second half of q */ avalue = gru_get_amo_value(cb); head = gru_get_amo_value_head(cb); limit = gru_get_amo_value_limit(cb); - qlines = mqd->qlines; + /* + * Fetch "qlines" from the queue header. Since the queue may be + * in memory that can't be accessed using socket addresses, use + * the GRU to access the data. Use DSR space from the message. + */ + save = *(int *)mesg; + gru_vload(cb, QLINES(mq), gru_get_tri(mesg), XTYPE_W, 1, 1, IMA); + if (gru_wait(cb) != CBS_IDLE) + goto cberr; + qlines = *(int *)mesg; + *(int *)mesg = save; half = (limit != qlines); if (half) @@ -363,7 +365,7 @@ static int send_message_queue_full(void *cb, struct gru_message_queue_desc *mqd, mqh = gru_mesq_head(2, qlines / 2 + 1); /* Try to get lock for switching head pointer */ - gru_gamir(cb, EOP_IR_CLR, HSTATUS(mqd->mq_gpa, half), XTYPE_DW, IMA); + gru_gamir(cb, EOP_IR_CLR, HSTATUS(mq, half), XTYPE_DW, IMA); if (gru_wait(cb) != CBS_IDLE) goto cberr; if (!gru_get_amo_value(cb)) { @@ -373,8 +375,8 @@ static int send_message_queue_full(void *cb, struct gru_message_queue_desc *mqd, /* Got the lock. Send optional NOP if queue not full, */ if (head != limit) { - if (send_noop_message(cb, mqd, mesg)) { - gru_gamir(cb, EOP_IR_INC, HSTATUS(mqd->mq_gpa, half), + if (send_noop_message(cb, mq, mesg)) { + gru_gamir(cb, EOP_IR_INC, HSTATUS(mq, half), XTYPE_DW, IMA); if (gru_wait(cb) != CBS_IDLE) goto cberr; @@ -385,16 +387,14 @@ static int send_message_queue_full(void *cb, struct gru_message_queue_desc *mqd, } /* Then flip queuehead to other half of queue. */ - gru_gamer(cb, EOP_ERR_CSWAP, mqd->mq_gpa, XTYPE_DW, mqh.val, avalue, - IMA); + gru_gamer(cb, EOP_ERR_CSWAP, mq, XTYPE_DW, mqh.val, avalue, IMA); if (gru_wait(cb) != CBS_IDLE) goto cberr; /* If not successfully in swapping queue head, clear the hstatus lock */ if (gru_get_amo_value(cb) != avalue) { STAT(mesq_qf_switch_head_failed); - gru_gamir(cb, EOP_IR_INC, HSTATUS(mqd->mq_gpa, half), XTYPE_DW, - IMA); + gru_gamir(cb, EOP_IR_INC, HSTATUS(mq, half), XTYPE_DW, IMA); if (gru_wait(cb) != CBS_IDLE) goto cberr; } @@ -404,25 +404,15 @@ static int send_message_queue_full(void *cb, struct gru_message_queue_desc *mqd, return MQE_UNEXPECTED_CB_ERR; } -/* - * Send a cross-partition interrupt to the SSI that contains the target - * message queue. Normally, the interrupt is automatically delivered by hardware - * but some error conditions require explicit delivery. - */ -static void send_message_queue_interrupt(struct gru_message_queue_desc *mqd) -{ - if (mqd->interrupt_vector) - uv_hub_send_ipi(mqd->interrupt_pnode, mqd->interrupt_apicid, - mqd->interrupt_vector); -} - /* * Handle a gru_mesq failure. Some of these failures are software recoverable * or retryable. */ -static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd, - void *mesg, int lines) +static int send_message_failure(void *cb, + unsigned long mq, + void *mesg, + int lines) { int substatus, ret = 0; unsigned long m; @@ -439,7 +429,7 @@ static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd, break; case CBSS_QLIMIT_REACHED: STAT(mesq_send_qlimit_reached); - ret = send_message_queue_full(cb, mqd, mesg, lines); + ret = send_message_queue_full(cb, mq, mesg, lines); break; case CBSS_AMO_NACKED: STAT(mesq_send_amo_nacked); @@ -447,14 +437,12 @@ static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd, break; case CBSS_PUT_NACKED: STAT(mesq_send_put_nacked); - m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6); + m =mq + (gru_get_amo_value_head(cb) << 6); gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, lines, 1, IMA); - if (gru_wait(cb) == CBS_IDLE) { + if (gru_wait(cb) == CBS_IDLE) ret = MQE_OK; - send_message_queue_interrupt(mqd); - } else { + else ret = MQE_UNEXPECTED_CB_ERR; - } break; default: BUG(); @@ -464,12 +452,12 @@ static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd, /* * Send a message to a message queue - * mqd message queue descriptor + * cb GRU control block to use to send message + * mq message queue * mesg message. ust be vaddr within a GSEG * bytes message size (<= 2 CL) */ -int gru_send_message_gpa(struct gru_message_queue_desc *mqd, void *mesg, - unsigned int bytes) +int gru_send_message_gpa(unsigned long mq, void *mesg, unsigned int bytes) { struct message_header *mhdr; void *cb; @@ -493,10 +481,10 @@ int gru_send_message_gpa(struct gru_message_queue_desc *mqd, void *mesg, do { ret = MQE_OK; - gru_mesq(cb, mqd->mq_gpa, gru_get_tri(mhdr), clines, IMA); + gru_mesq(cb, mq, gru_get_tri(mhdr), clines, IMA); istatus = gru_wait(cb); if (istatus != CBS_IDLE) - ret = send_message_failure(cb, mqd, dsr, clines); + ret = send_message_failure(cb, mq, dsr, clines); } while (ret == MQIE_AGAIN); gru_free_cpu_resources(cb, dsr); @@ -509,9 +497,9 @@ EXPORT_SYMBOL_GPL(gru_send_message_gpa); /* * Advance the receive pointer for the queue to the next message. */ -void gru_free_message(struct gru_message_queue_desc *mqd, void *mesg) +void gru_free_message(void *rmq, void *mesg) { - struct message_queue *mq = mqd->mq; + struct message_queue *mq = rmq; struct message_header *mhdr = mq->next; void *next, *pnext; int half = -1; @@ -541,16 +529,16 @@ EXPORT_SYMBOL_GPL(gru_free_message); * present. User must call next_message() to move to next message. * rmq message queue */ -void *gru_get_next_message(struct gru_message_queue_desc *mqd) +void *gru_get_next_message(void *rmq) { - struct message_queue *mq = mqd->mq; + struct message_queue *mq = rmq; struct message_header *mhdr = mq->next; int present = mhdr->present; /* skip NOOP messages */ STAT(mesq_receive); while (present == MQS_NOOP) { - gru_free_message(mqd, mhdr); + gru_free_message(rmq, mhdr); mhdr = mq->next; present = mhdr->present; } @@ -588,7 +576,7 @@ int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa, if (gru_get_cpu_resources(GRU_NUM_KERNEL_DSR_BYTES, &cb, &dsr)) return MQE_BUG_NO_RESOURCES; gru_bcopy(cb, src_gpa, dest_gpa, gru_get_tri(dsr), - XTYPE_B, bytes, GRU_NUM_KERNEL_DSR_CL, IMA); + XTYPE_B, bytes, GRU_NUM_KERNEL_DSR_BYTES, IMA); ret = gru_wait(cb); gru_free_cpu_resources(cb, dsr); return ret; @@ -623,7 +611,7 @@ static int quicktest(struct gru_state *gru) if (word0 != word1 || word0 != MAGIC) { printk - ("GRU quicktest err: gid %d, found 0x%lx, expected 0x%lx\n", + ("GRU quicktest err: gru %d, found 0x%lx, expected 0x%lx\n", gru->gs_gid, word1, MAGIC); BUG(); /* ZZZ should not be fatal */ } @@ -672,15 +660,15 @@ int gru_kservices_init(struct gru_state *gru) cch->tlb_int_enable = 0; cch->tfm_done_bit_enable = 0; cch->unmap_enable = 1; - err = cch_allocate(cch, 0, 0, cbr_map, dsr_map); + err = cch_allocate(cch, 0, cbr_map, dsr_map); if (err) { gru_dbg(grudev, - "Unable to allocate kernel CCH: gid %d, err %d\n", + "Unable to allocate kernel CCH: gru %d, err %d\n", gru->gs_gid, err); BUG(); } if (cch_start(cch)) { - gru_dbg(grudev, "Unable to start kernel CCH: gid %d, err %d\n", + gru_dbg(grudev, "Unable to start kernel CCH: gru %d, err %d\n", gru->gs_gid, err); BUG(); } @@ -690,22 +678,3 @@ int gru_kservices_init(struct gru_state *gru) quicktest(gru); return 0; } - -void gru_kservices_exit(struct gru_state *gru) -{ - struct gru_context_configuration_handle *cch; - struct gru_blade_state *bs; - - bs = gru->gs_blade; - if (gru != &bs->bs_grus[1]) - return; - - cch = get_cch(gru->gs_gru_base_vaddr, KERNEL_CTXNUM); - lock_cch_handle(cch); - if (cch_interrupt_sync(cch)) - BUG(); - if (cch_deallocate(cch)) - BUG(); - unlock_cch_handle(cch); -} - diff --git a/trunk/drivers/misc/sgi-gru/grukservices.h b/trunk/drivers/misc/sgi-gru/grukservices.h index 747ed315d56f..eb17e0a3ac61 100644 --- a/trunk/drivers/misc/sgi-gru/grukservices.h +++ b/trunk/drivers/misc/sgi-gru/grukservices.h @@ -41,15 +41,6 @@ * - gru_create_message_queue() needs interrupt vector info */ -struct gru_message_queue_desc { - void *mq; /* message queue vaddress */ - unsigned long mq_gpa; /* global address of mq */ - int qlines; /* queue size in CL */ - int interrupt_vector; /* interrupt vector */ - int interrupt_pnode; /* pnode for interrupt */ - int interrupt_apicid; /* lapicid for interrupt */ -}; - /* * Initialize a user allocated chunk of memory to be used as * a message queue. The caller must ensure that the queue is @@ -60,19 +51,14 @@ struct gru_message_queue_desc { * to manage the queue. * * Input: - * mqd pointer to message queue descriptor - * p pointer to user allocated mesq memory. + * p pointer to user allocated memory. * bytes size of message queue in bytes - * vector interrupt vector (zero if no interrupts) - * nasid nasid of blade where interrupt is delivered - * apicid apicid of cpu for interrupt * * Errors: * 0 OK * >0 error */ -extern int gru_create_message_queue(struct gru_message_queue_desc *mqd, - void *p, unsigned int bytes, int nasid, int vector, int apicid); +extern int gru_create_message_queue(void *p, unsigned int bytes); /* * Send a message to a message queue. @@ -82,7 +68,7 @@ extern int gru_create_message_queue(struct gru_message_queue_desc *mqd, * * * Input: - * mqd pointer to message queue descriptor + * xmq message queue - must be a UV global physical address * mesg pointer to message. Must be 64-bit aligned * bytes size of message in bytes * @@ -91,8 +77,8 @@ extern int gru_create_message_queue(struct gru_message_queue_desc *mqd, * >0 Send failure - see error codes below * */ -extern int gru_send_message_gpa(struct gru_message_queue_desc *mqd, - void *mesg, unsigned int bytes); +extern int gru_send_message_gpa(unsigned long mq_gpa, void *mesg, + unsigned int bytes); /* Status values for gru_send_message() */ #define MQE_OK 0 /* message sent successfully */ @@ -108,11 +94,10 @@ extern int gru_send_message_gpa(struct gru_message_queue_desc *mqd, * API extensions may allow for out-of-order freeing. * * Input - * mqd pointer to message queue descriptor + * mq message queue * mesq message being freed */ -extern void gru_free_message(struct gru_message_queue_desc *mqd, - void *mesq); +extern void gru_free_message(void *mq, void *mesq); /* * Get next message from message queue. Returns pointer to @@ -121,13 +106,13 @@ extern void gru_free_message(struct gru_message_queue_desc *mqd, * in order to move the queue pointers to next message. * * Input - * mqd pointer to message queue descriptor + * mq message queue * * Output: * p pointer to message * NULL no message available */ -extern void *gru_get_next_message(struct gru_message_queue_desc *mqd); +extern void *gru_get_next_message(void *mq); /* diff --git a/trunk/drivers/misc/sgi-gru/grumain.c b/trunk/drivers/misc/sgi-gru/grumain.c index ec3f7a17d221..3d2fc216bae5 100644 --- a/trunk/drivers/misc/sgi-gru/grumain.c +++ b/trunk/drivers/misc/sgi-gru/grumain.c @@ -76,9 +76,10 @@ int gru_cpu_fault_map_id(void) /* Hit the asid limit. Start over */ static int gru_wrap_asid(struct gru_state *gru) { - gru_dbg(grudev, "gid %d\n", gru->gs_gid); + gru_dbg(grudev, "gru %p\n", gru); STAT(asid_wrap); gru->gs_asid_gen++; + gru_flush_all_tlb(gru); return MIN_ASID; } @@ -87,21 +88,19 @@ static int gru_reset_asid_limit(struct gru_state *gru, int asid) { int i, gid, inuse_asid, limit; - gru_dbg(grudev, "gid %d, asid 0x%x\n", gru->gs_gid, asid); + gru_dbg(grudev, "gru %p, asid 0x%x\n", gru, asid); STAT(asid_next); limit = MAX_ASID; if (asid >= limit) asid = gru_wrap_asid(gru); - gru_flush_all_tlb(gru); gid = gru->gs_gid; again: for (i = 0; i < GRU_NUM_CCH; i++) { if (!gru->gs_gts[i]) continue; inuse_asid = gru->gs_gts[i]->ts_gms->ms_asids[gid].mt_asid; - gru_dbg(grudev, "gid %d, gts %p, gms %p, inuse 0x%x, cxt %d\n", - gru->gs_gid, gru->gs_gts[i], gru->gs_gts[i]->ts_gms, - inuse_asid, i); + gru_dbg(grudev, "gru %p, inuse_asid 0x%x, cxtnum %d, gts %p\n", + gru, inuse_asid, i, gru->gs_gts[i]); if (inuse_asid == asid) { asid += ASID_INC; if (asid >= limit) { @@ -121,8 +120,8 @@ static int gru_reset_asid_limit(struct gru_state *gru, int asid) } gru->gs_asid_limit = limit; gru->gs_asid = asid; - gru_dbg(grudev, "gid %d, new asid 0x%x, new_limit 0x%x\n", gru->gs_gid, - asid, limit); + gru_dbg(grudev, "gru %p, new asid 0x%x, new_limit 0x%x\n", gru, asid, + limit); return asid; } @@ -131,12 +130,14 @@ static int gru_assign_asid(struct gru_state *gru) { int asid; + spin_lock(&gru->gs_asid_lock); gru->gs_asid += ASID_INC; asid = gru->gs_asid; if (asid >= gru->gs_asid_limit) asid = gru_reset_asid_limit(gru, asid); + spin_unlock(&gru->gs_asid_lock); - gru_dbg(grudev, "gid %d, asid 0x%x\n", gru->gs_gid, asid); + gru_dbg(grudev, "gru %p, asid 0x%x\n", gru, asid); return asid; } @@ -214,20 +215,17 @@ static int check_gru_resources(struct gru_state *gru, int cbr_au_count, * TLB manangment requires tracking all GRU chiplets that have loaded a GSEG * context. */ -static int gru_load_mm_tracker(struct gru_state *gru, - struct gru_thread_state *gts) +static int gru_load_mm_tracker(struct gru_state *gru, struct gru_mm_struct *gms, + int ctxnum) { - struct gru_mm_struct *gms = gts->ts_gms; struct gru_mm_tracker *asids = &gms->ms_asids[gru->gs_gid]; - unsigned short ctxbitmap = (1 << gts->ts_ctxnum); + unsigned short ctxbitmap = (1 << ctxnum); int asid; spin_lock(&gms->ms_asid_lock); asid = asids->mt_asid; - spin_lock(&gru->gs_asid_lock); - if (asid == 0 || (asids->mt_ctxbitmap == 0 && asids->mt_asid_gen != - gru->gs_asid_gen)) { + if (asid == 0 || asids->mt_asid_gen != gru->gs_asid_gen) { asid = gru_assign_asid(gru); asids->mt_asid = asid; asids->mt_asid_gen = gru->gs_asid_gen; @@ -235,7 +233,6 @@ static int gru_load_mm_tracker(struct gru_state *gru, } else { STAT(asid_reuse); } - spin_unlock(&gru->gs_asid_lock); BUG_ON(asids->mt_ctxbitmap & ctxbitmap); asids->mt_ctxbitmap |= ctxbitmap; @@ -244,28 +241,24 @@ static int gru_load_mm_tracker(struct gru_state *gru, spin_unlock(&gms->ms_asid_lock); gru_dbg(grudev, - "gid %d, gts %p, gms %p, ctxnum %d, asid 0x%x, asidmap 0x%lx\n", - gru->gs_gid, gts, gms, gts->ts_ctxnum, asid, - gms->ms_asidmap[0]); + "gru %x, gms %p, ctxnum 0x%d, asid 0x%x, asidmap 0x%lx\n", + gru->gs_gid, gms, ctxnum, asid, gms->ms_asidmap[0]); return asid; } static void gru_unload_mm_tracker(struct gru_state *gru, - struct gru_thread_state *gts) + struct gru_mm_struct *gms, int ctxnum) { - struct gru_mm_struct *gms = gts->ts_gms; struct gru_mm_tracker *asids; unsigned short ctxbitmap; asids = &gms->ms_asids[gru->gs_gid]; - ctxbitmap = (1 << gts->ts_ctxnum); + ctxbitmap = (1 << ctxnum); spin_lock(&gms->ms_asid_lock); - spin_lock(&gru->gs_asid_lock); BUG_ON((asids->mt_ctxbitmap & ctxbitmap) != ctxbitmap); asids->mt_ctxbitmap ^= ctxbitmap; - gru_dbg(grudev, "gid %d, gts %p, gms %p, ctxnum 0x%d, asidmap 0x%lx\n", - gru->gs_gid, gts, gms, gts->ts_ctxnum, gms->ms_asidmap[0]); - spin_unlock(&gru->gs_asid_lock); + gru_dbg(grudev, "gru %x, gms %p, ctxnum 0x%d, asidmap 0x%lx\n", + gru->gs_gid, gms, ctxnum, gms->ms_asidmap[0]); spin_unlock(&gms->ms_asid_lock); } @@ -326,7 +319,6 @@ static struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma, gts->ts_vma = vma; gts->ts_tlb_int_select = -1; gts->ts_gms = gru_register_mmu_notifier(); - gts->ts_sizeavail = GRU_SIZEAVAIL(PAGE_SHIFT); if (!gts->ts_gms) goto err; @@ -407,7 +399,7 @@ static void gru_free_gru_context(struct gru_thread_state *gts) struct gru_state *gru; gru = gts->ts_gru; - gru_dbg(grudev, "gts %p, gid %d\n", gts, gru->gs_gid); + gru_dbg(grudev, "gts %p, gru %p\n", gts, gru); spin_lock(&gru->gs_lock); gru->gs_gts[gts->ts_ctxnum] = NULL; @@ -416,7 +408,6 @@ static void gru_free_gru_context(struct gru_thread_state *gts) __clear_bit(gts->ts_ctxnum, &gru->gs_context_map); gts->ts_ctxnum = NULLCTX; gts->ts_gru = NULL; - gts->ts_blade = -1; spin_unlock(&gru->gs_lock); gts_drop(gts); @@ -441,8 +432,8 @@ static inline long gru_copy_handle(void *d, void *s) return GRU_HANDLE_BYTES; } -static void gru_prefetch_context(void *gseg, void *cb, void *cbe, - unsigned long cbrmap, unsigned long length) +static void gru_prefetch_context(void *gseg, void *cb, void *cbe, unsigned long cbrmap, + unsigned long length) { int i, scr; @@ -509,12 +500,12 @@ void gru_unload_context(struct gru_thread_state *gts, int savestate) zap_vma_ptes(gts->ts_vma, UGRUADDR(gts), GRU_GSEG_PAGESIZE); cch = get_cch(gru->gs_gru_base_vaddr, ctxnum); - gru_dbg(grudev, "gts %p\n", gts); lock_cch_handle(cch); if (cch_interrupt_sync(cch)) BUG(); + gru_dbg(grudev, "gts %p\n", gts); - gru_unload_mm_tracker(gru, gts); + gru_unload_mm_tracker(gru, gts->ts_gms, gts->ts_ctxnum); if (savestate) gru_unload_context_data(gts->ts_gdata, gru->gs_gru_base_vaddr, ctxnum, gts->ts_cbr_map, @@ -543,7 +534,7 @@ static void gru_load_context(struct gru_thread_state *gts) cch = get_cch(gru->gs_gru_base_vaddr, ctxnum); lock_cch_handle(cch); - asid = gru_load_mm_tracker(gru, gts); + asid = gru_load_mm_tracker(gru, gts->ts_gms, gts->ts_ctxnum); cch->tfm_fault_bit_enable = (gts->ts_user_options == GRU_OPT_MISS_FMM_POLL || gts->ts_user_options == GRU_OPT_MISS_FMM_INTR); @@ -553,8 +544,7 @@ static void gru_load_context(struct gru_thread_state *gts) cch->tlb_int_select = gts->ts_tlb_int_select; } cch->tfm_done_bit_enable = 0; - err = cch_allocate(cch, asid, gts->ts_sizeavail, gts->ts_cbr_map, - gts->ts_dsr_map); + err = cch_allocate(cch, asid, gts->ts_cbr_map, gts->ts_dsr_map); if (err) { gru_dbg(grudev, "err %d: cch %p, gts %p, cbr 0x%lx, dsr 0x%lx\n", @@ -575,12 +565,11 @@ static void gru_load_context(struct gru_thread_state *gts) /* * Update fields in an active CCH: * - retarget interrupts on local blade - * - update sizeavail mask * - force a delayed context unload by clearing the CCH asids. This * forces TLB misses for new GRU instructions. The context is unloaded * when the next TLB miss occurs. */ -int gru_update_cch(struct gru_thread_state *gts, int force_unload) +static int gru_update_cch(struct gru_thread_state *gts, int int_select) { struct gru_context_configuration_handle *cch; struct gru_state *gru = gts->ts_gru; @@ -594,11 +583,9 @@ int gru_update_cch(struct gru_thread_state *gts, int force_unload) goto exit; if (cch_interrupt(cch)) BUG(); - if (!force_unload) { - for (i = 0; i < 8; i++) - cch->sizeavail[i] = gts->ts_sizeavail; - gts->ts_tlb_int_select = gru_cpu_fault_map_id(); - cch->tlb_int_select = gru_cpu_fault_map_id(); + if (int_select >= 0) { + gts->ts_tlb_int_select = int_select; + cch->tlb_int_select = int_select; } else { for (i = 0; i < 8; i++) cch->asid[i] = 0; @@ -630,7 +617,7 @@ static int gru_retarget_intr(struct gru_thread_state *gts) gru_dbg(grudev, "retarget from %d to %d\n", gts->ts_tlb_int_select, gru_cpu_fault_map_id()); - return gru_update_cch(gts, 0); + return gru_update_cch(gts, gru_cpu_fault_map_id()); } @@ -701,7 +688,7 @@ static void gru_steal_context(struct gru_thread_state *gts) STAT(steal_context_failed); } gru_dbg(grudev, - "stole gid %d, ctxnum %d from gts %p. Need cb %d, ds %d;" + "stole gru %x, ctxnum %d from gts %p. Need cb %d, ds %d;" " avail cb %ld, ds %ld\n", gru->gs_gid, ctxnum, ngts, cbr, dsr, hweight64(gru->gs_cbr_map), hweight64(gru->gs_dsr_map)); @@ -740,7 +727,6 @@ static struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts) } reserve_gru_resources(gru, gts); gts->ts_gru = gru; - gts->ts_blade = gru->gs_blade_id; gts->ts_ctxnum = find_first_zero_bit(&gru->gs_context_map, GRU_NUM_CCH); BUG_ON(gts->ts_ctxnum == GRU_NUM_CCH); @@ -751,7 +737,7 @@ static struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts) STAT(assign_context); gru_dbg(grudev, - "gseg %p, gts %p, gid %d, ctx %d, cbr %d, dsr %d\n", + "gseg %p, gts %p, gru %x, ctx %d, cbr %d, dsr %d\n", gseg_virtual_address(gts->ts_gru, gts->ts_ctxnum), gts, gts->ts_gru->gs_gid, gts->ts_ctxnum, gts->ts_cbr_au_count, gts->ts_dsr_au_count); @@ -787,8 +773,8 @@ int gru_fault(struct vm_area_struct *vma, struct vm_fault *vmf) return VM_FAULT_SIGBUS; again: - mutex_lock(>s->ts_ctxlock); preempt_disable(); + mutex_lock(>s->ts_ctxlock); if (gts->ts_gru) { if (gts->ts_gru->gs_blade_id != uv_numa_blade_id()) { STAT(migrated_nopfn_unload); diff --git a/trunk/drivers/misc/sgi-gru/gruprocfs.c b/trunk/drivers/misc/sgi-gru/gruprocfs.c index ee74821b171c..73b0ca061bb5 100644 --- a/trunk/drivers/misc/sgi-gru/gruprocfs.c +++ b/trunk/drivers/misc/sgi-gru/gruprocfs.c @@ -62,9 +62,7 @@ static int statistics_show(struct seq_file *s, void *p) printstat(s, asid_wrap); printstat(s, asid_reuse); printstat(s, intr); - printstat(s, intr_mm_lock_failed); printstat(s, call_os); - printstat(s, call_os_offnode_reference); printstat(s, call_os_check_for_bug); printstat(s, call_os_wait_queue); printstat(s, user_flush_tlb); @@ -122,30 +120,6 @@ static ssize_t statistics_write(struct file *file, const char __user *userbuf, return count; } -static int mcs_statistics_show(struct seq_file *s, void *p) -{ - int op; - unsigned long total, count, max; - static char *id[] = {"cch_allocate", "cch_start", "cch_interrupt", - "cch_interrupt_sync", "cch_deallocate", "tgh_invalidate"}; - - for (op = 0; op < mcsop_last; op++) { - count = atomic_long_read(&mcs_op_statistics[op].count); - total = atomic_long_read(&mcs_op_statistics[op].total); - max = mcs_op_statistics[op].max; - seq_printf(s, "%-20s%12ld%12ld%12ld\n", id[op], count, - count ? total / count : 0, max); - } - return 0; -} - -static ssize_t mcs_statistics_write(struct file *file, - const char __user *userbuf, size_t count, loff_t *data) -{ - memset(mcs_op_statistics, 0, sizeof(mcs_op_statistics)); - return count; -} - static int options_show(struct seq_file *s, void *p) { seq_printf(s, "0x%lx\n", gru_options); @@ -161,7 +135,6 @@ static ssize_t options_write(struct file *file, const char __user *userbuf, if (copy_from_user (buf, userbuf, count < sizeof(buf) ? count : sizeof(buf))) return -EFAULT; - buf[count - 1] = '\0'; if (!strict_strtoul(buf, 10, &val)) gru_options = val; @@ -226,7 +199,7 @@ static void seq_stop(struct seq_file *file, void *data) static void *seq_start(struct seq_file *file, loff_t *gid) { - if (*gid < gru_max_gids) + if (*gid < GRU_MAX_GRUS) return gid; return NULL; } @@ -234,7 +207,7 @@ static void *seq_start(struct seq_file *file, loff_t *gid) static void *seq_next(struct seq_file *file, void *data, loff_t *gid) { (*gid)++; - if (*gid < gru_max_gids) + if (*gid < GRU_MAX_GRUS) return gid; return NULL; } @@ -258,11 +231,6 @@ static int statistics_open(struct inode *inode, struct file *file) return single_open(file, statistics_show, NULL); } -static int mcs_statistics_open(struct inode *inode, struct file *file) -{ - return single_open(file, mcs_statistics_show, NULL); -} - static int options_open(struct inode *inode, struct file *file) { return single_open(file, options_show, NULL); @@ -287,14 +255,6 @@ static const struct file_operations statistics_fops = { .release = single_release, }; -static const struct file_operations mcs_statistics_fops = { - .open = mcs_statistics_open, - .read = seq_read, - .write = mcs_statistics_write, - .llseek = seq_lseek, - .release = single_release, -}; - static const struct file_operations options_fops = { .open = options_open, .read = seq_read, @@ -323,7 +283,6 @@ static struct proc_entry { struct proc_dir_entry *entry; } proc_files[] = { {"statistics", 0644, &statistics_fops}, - {"mcs_statistics", 0644, &mcs_statistics_fops}, {"debug_options", 0644, &options_fops}, {"cch_status", 0444, &cch_fops}, {"gru_status", 0444, &gru_fops}, diff --git a/trunk/drivers/misc/sgi-gru/grutables.h b/trunk/drivers/misc/sgi-gru/grutables.h index bf1eeb7553ed..a78f70deeb59 100644 --- a/trunk/drivers/misc/sgi-gru/grutables.h +++ b/trunk/drivers/misc/sgi-gru/grutables.h @@ -153,7 +153,6 @@ extern struct gru_stats_s gru_stats; extern struct gru_blade_state *gru_base[]; extern unsigned long gru_start_paddr, gru_end_paddr; -extern unsigned int gru_max_gids; #define GRU_MAX_BLADES MAX_NUMNODES #define GRU_MAX_GRUS (GRU_MAX_BLADES * GRU_CHIPLETS_PER_BLADE) @@ -185,9 +184,7 @@ struct gru_stats_s { atomic_long_t asid_wrap; atomic_long_t asid_reuse; atomic_long_t intr; - atomic_long_t intr_mm_lock_failed; atomic_long_t call_os; - atomic_long_t call_os_offnode_reference; atomic_long_t call_os_check_for_bug; atomic_long_t call_os_wait_queue; atomic_long_t user_flush_tlb; @@ -240,17 +237,6 @@ struct gru_stats_s { }; -enum mcs_op {cchop_allocate, cchop_start, cchop_interrupt, cchop_interrupt_sync, - cchop_deallocate, tghop_invalidate, mcsop_last}; - -struct mcs_op_statistic { - atomic_long_t count; - atomic_long_t total; - unsigned long max; -}; - -extern struct mcs_op_statistic mcs_op_statistics[mcsop_last]; - #define OPT_DPRINT 1 #define OPT_STATS 2 #define GRU_QUICKLOOK 4 @@ -292,12 +278,13 @@ extern struct mcs_op_statistic mcs_op_statistics[mcsop_last]; /* Generate a GRU asid value from a GRU base asid & a virtual address. */ #if defined CONFIG_IA64 #define VADDR_HI_BIT 64 +#define GRUREGION(addr) ((addr) >> (VADDR_HI_BIT - 3) & 3) #elif defined CONFIG_X86_64 #define VADDR_HI_BIT 48 +#define GRUREGION(addr) (0) /* ZZZ could do better */ #else #error "Unsupported architecture" #endif -#define GRUREGION(addr) ((addr) >> (VADDR_HI_BIT - 3) & 3) #define GRUASID(asid, addr) ((asid) + GRUREGION(addr)) /*------------------------------------------------------------------------------ @@ -310,12 +297,12 @@ struct gru_state; * This structure is pointed to from the mmstruct via the notifier pointer. * There is one of these per address space. */ -struct gru_mm_tracker { /* pack to reduce size */ - unsigned int mt_asid_gen:24; /* ASID wrap count */ - unsigned int mt_asid:24; /* current base ASID for gru */ - unsigned short mt_ctxbitmap:16;/* bitmap of contexts using +struct gru_mm_tracker { + unsigned int mt_asid_gen; /* ASID wrap count */ + int mt_asid; /* current base ASID for gru */ + unsigned short mt_ctxbitmap; /* bitmap of contexts using asid */ -} __attribute__ ((packed)); +}; struct gru_mm_struct { struct mmu_notifier ms_notifier; @@ -361,7 +348,6 @@ struct gru_thread_state { long ts_user_options;/* misc user option flags */ pid_t ts_tgid_owner; /* task that is using the context - for migration */ - unsigned short ts_sizeavail; /* Pagesizes in use */ int ts_tsid; /* thread that owns the structure */ int ts_tlb_int_select;/* target cpu if interrupts @@ -373,9 +359,6 @@ struct gru_thread_state { required for contest */ unsigned char ts_cbr_au_count;/* Number of CBR resources required for contest */ - char ts_blade; /* If >= 0, migrate context if - ref from diferent blade */ - char ts_force_cch_reload; char ts_force_unload;/* force context to be unloaded after migration */ char ts_cbr_idx[GRU_CBR_AU];/* CBR numbers of each @@ -409,12 +392,12 @@ struct gru_state { gru segments (64) */ void *gs_gru_base_vaddr; /* Virtual address of gru segments (64) */ - unsigned short gs_gid; /* unique GRU number */ - unsigned short gs_blade_id; /* blade of GRU */ + unsigned char gs_gid; /* unique GRU number */ unsigned char gs_tgh_local_shift; /* used to pick TGH for local flush */ unsigned char gs_tgh_first_remote; /* starting TGH# for remote flush */ + unsigned short gs_blade_id; /* blade of GRU */ spinlock_t gs_asid_lock; /* lock used for assigning asids */ spinlock_t gs_lock; /* lock used for @@ -509,10 +492,6 @@ struct gru_blade_state { (i) < GRU_CHIPLETS_PER_BLADE; \ (i)++, (gru)++) -/* Scan all GRUs */ -#define foreach_gid(gid) \ - for ((gid) = 0; (gid) < gru_max_gids; (gid)++) - /* Scan all active GTSs on a gru. Note: must hold ss_lock to use this macro. */ #define for_each_gts_on_gru(gts, gru, ctxnum) \ for ((ctxnum) = 0; (ctxnum) < GRU_NUM_CCH; (ctxnum)++) \ @@ -599,11 +578,9 @@ extern struct gru_thread_state *gru_find_thread_state(struct vm_area_struct extern struct gru_thread_state *gru_alloc_thread_state(struct vm_area_struct *vma, int tsid); extern void gru_unload_context(struct gru_thread_state *gts, int savestate); -extern int gru_update_cch(struct gru_thread_state *gts, int force_unload); extern void gts_drop(struct gru_thread_state *gts); extern void gru_tgh_flush_init(struct gru_state *gru); extern int gru_kservices_init(struct gru_state *gru); -extern void gru_kservices_exit(struct gru_state *gru); extern irqreturn_t gru_intr(int irq, void *dev_id); extern int gru_handle_user_call_os(unsigned long address); extern int gru_user_flush_tlb(unsigned long arg); diff --git a/trunk/drivers/misc/sgi-gru/grutlbpurge.c b/trunk/drivers/misc/sgi-gru/grutlbpurge.c index 1d125091f5e7..c84496a77691 100644 --- a/trunk/drivers/misc/sgi-gru/grutlbpurge.c +++ b/trunk/drivers/misc/sgi-gru/grutlbpurge.c @@ -187,7 +187,7 @@ void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start, " FLUSH gruid %d, asid 0x%x, num %ld, cbmap 0x%x\n", gid, asid, num, asids->mt_ctxbitmap); tgh = get_lock_tgh_handle(gru); - tgh_invalidate(tgh, start, ~0, asid, grupagesize, 0, + tgh_invalidate(tgh, start, 0, asid, grupagesize, 0, num - 1, asids->mt_ctxbitmap); get_unlock_tgh_handle(tgh); } else { @@ -210,10 +210,11 @@ void gru_flush_all_tlb(struct gru_state *gru) { struct gru_tlb_global_handle *tgh; - gru_dbg(grudev, "gid %d\n", gru->gs_gid); + gru_dbg(grudev, "gru %p, gid %d\n", gru, gru->gs_gid); tgh = get_lock_tgh_handle(gru); - tgh_invalidate(tgh, 0, ~0, 0, 1, 1, GRUMAXINVAL - 1, 0xffff); + tgh_invalidate(tgh, 0, ~0, 0, 1, 1, GRUMAXINVAL - 1, 0); get_unlock_tgh_handle(tgh); + preempt_enable(); } /* diff --git a/trunk/drivers/misc/sgi-xp/xpc.h b/trunk/drivers/misc/sgi-xp/xpc.h index 114444cfd496..275b78896a73 100644 --- a/trunk/drivers/misc/sgi-xp/xpc.h +++ b/trunk/drivers/misc/sgi-xp/xpc.h @@ -92,9 +92,7 @@ struct xpc_rsvd_page { u8 pad1[3]; /* align to next u64 in 1st 64-byte cacheline */ union { unsigned long vars_pa; /* phys address of struct xpc_vars */ - unsigned long activate_gru_mq_desc_gpa; /* phys addr of */ - /* activate mq's */ - /* gru mq descriptor */ + unsigned long activate_mq_gpa; /* gru phy addr of activate_mq */ } sn; unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */ u64 pad2[10]; /* align to last u64 in 2nd 64-byte cacheline */ @@ -191,9 +189,7 @@ struct xpc_gru_mq_uv { int irq; /* irq raised when message is received in mq */ int mmr_blade; /* blade where watchlist was allocated from */ unsigned long mmr_offset; /* offset of irq mmr located on mmr_blade */ - unsigned long mmr_value; /* value of irq mmr located on mmr_blade */ int watchlist_num; /* number of watchlist allocatd by BIOS */ - void *gru_mq_desc; /* opaque structure used by the GRU driver */ }; /* @@ -201,7 +197,6 @@ struct xpc_gru_mq_uv { * heartbeat, partition active state, and channel state. This is UV only. */ struct xpc_activate_mq_msghdr_uv { - unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */ short partid; /* sender's partid */ u8 act_state; /* sender's act_state at time msg sent */ u8 type; /* message's type */ @@ -237,7 +232,7 @@ struct xpc_activate_mq_msg_heartbeat_req_uv { struct xpc_activate_mq_msg_activate_req_uv { struct xpc_activate_mq_msghdr_uv hdr; unsigned long rp_gpa; - unsigned long activate_gru_mq_desc_gpa; + unsigned long activate_mq_gpa; }; struct xpc_activate_mq_msg_deactivate_req_uv { @@ -268,7 +263,7 @@ struct xpc_activate_mq_msg_chctl_openreply_uv { short ch_number; short remote_nentries; /* ??? Is this needed? What is? */ short local_nentries; /* ??? Is this needed? What is? */ - unsigned long notify_gru_mq_desc_gpa; + unsigned long local_notify_mq_gpa; }; /* @@ -515,8 +510,8 @@ struct xpc_channel_sn2 { }; struct xpc_channel_uv { - void *cached_notify_gru_mq_desc; /* remote partition's notify mq's */ - /* gru mq descriptor */ + unsigned long remote_notify_mq_gpa; /* gru phys address of remote */ + /* partition's notify mq */ struct xpc_send_msg_slot_uv *send_msg_slots; void *recv_msg_slots; /* each slot will hold a xpc_notify_mq_msg_uv */ @@ -687,12 +682,8 @@ struct xpc_partition_sn2 { }; struct xpc_partition_uv { - unsigned long activate_gru_mq_desc_gpa; /* phys addr of parititon's */ - /* activate mq's gru mq */ - /* descriptor */ - void *cached_activate_gru_mq_desc; /* cached copy of partition's */ - /* activate mq's gru mq descriptor */ - struct mutex cached_activate_gru_mq_desc_mutex; + unsigned long remote_activate_mq_gpa; /* gru phys address of remote */ + /* partition's activate mq */ spinlock_t flags_lock; /* protect updating of flags */ unsigned int flags; /* general flags */ u8 remote_act_state; /* remote partition's act_state */ @@ -703,9 +694,8 @@ struct xpc_partition_uv { /* struct xpc_partition_uv flags */ -#define XPC_P_HEARTBEAT_OFFLINE_UV 0x00000001 -#define XPC_P_ENGAGED_UV 0x00000002 -#define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV 0x00000004 +#define XPC_P_HEARTBEAT_OFFLINE_UV 0x00000001 +#define XPC_P_ENGAGED_UV 0x00000002 /* struct xpc_partition_uv act_state change requests */ @@ -814,7 +804,6 @@ extern void xpc_activate_kthreads(struct xpc_channel *, int); extern void xpc_create_kthreads(struct xpc_channel *, int, int); extern void xpc_disconnect_wait(int); extern int (*xpc_setup_partitions_sn) (void); -extern void (*xpc_teardown_partitions_sn) (void); extern enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *, u64 *, unsigned long *, size_t *); @@ -857,8 +846,8 @@ extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *, unsigned long *); extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *); -extern enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *, - unsigned long); +extern void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *, + unsigned long); extern enum xp_retval (*xpc_send_payload) (struct xpc_channel *, u32, void *, u16, u8, xpc_notify_func, void *); diff --git a/trunk/drivers/misc/sgi-xp/xpc_channel.c b/trunk/drivers/misc/sgi-xp/xpc_channel.c index 99a2534c38a1..45fd653dbe31 100644 --- a/trunk/drivers/misc/sgi-xp/xpc_channel.c +++ b/trunk/drivers/misc/sgi-xp/xpc_channel.c @@ -183,7 +183,6 @@ xpc_process_openclose_chctl_flags(struct xpc_partition *part, int ch_number, &part->remote_openclose_args[ch_number]; struct xpc_channel *ch = &part->channels[ch_number]; enum xp_retval reason; - enum xp_retval ret; spin_lock_irqsave(&ch->lock, irq_flags); @@ -400,13 +399,8 @@ xpc_process_openclose_chctl_flags(struct xpc_partition *part, int ch_number, DBUG_ON(args->local_nentries == 0); DBUG_ON(args->remote_nentries == 0); - ret = xpc_save_remote_msgqueue_pa(ch, args->local_msgqueue_pa); - if (ret != xpSuccess) { - XPC_DISCONNECT_CHANNEL(ch, ret, &irq_flags); - spin_unlock_irqrestore(&ch->lock, irq_flags); - return; - } ch->flags |= XPC_C_ROPENREPLY; + xpc_save_remote_msgqueue_pa(ch, args->local_msgqueue_pa); if (args->local_nentries < ch->remote_nentries) { dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY: new " diff --git a/trunk/drivers/misc/sgi-xp/xpc_main.c b/trunk/drivers/misc/sgi-xp/xpc_main.c index 1ab9fda87fab..6576170de962 100644 --- a/trunk/drivers/misc/sgi-xp/xpc_main.c +++ b/trunk/drivers/misc/sgi-xp/xpc_main.c @@ -171,7 +171,6 @@ static struct notifier_block xpc_die_notifier = { }; int (*xpc_setup_partitions_sn) (void); -void (*xpc_teardown_partitions_sn) (void); enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *buf, u64 *cookie, unsigned long *rp_pa, size_t *len); @@ -218,8 +217,8 @@ void (*xpc_send_chctl_openrequest) (struct xpc_channel *ch, void (*xpc_send_chctl_openreply) (struct xpc_channel *ch, unsigned long *irq_flags); -enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch, - unsigned long msgqueue_pa); +void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch, + unsigned long msgqueue_pa); enum xp_retval (*xpc_send_payload) (struct xpc_channel *ch, u32 flags, void *payload, u16 payload_size, @@ -999,7 +998,6 @@ xpc_setup_partitions(void) static void xpc_teardown_partitions(void) { - xpc_teardown_partitions_sn(); kfree(xpc_partitions); } diff --git a/trunk/drivers/misc/sgi-xp/xpc_sn2.c b/trunk/drivers/misc/sgi-xp/xpc_sn2.c index eaaa964942de..2e975762c32b 100644 --- a/trunk/drivers/misc/sgi-xp/xpc_sn2.c +++ b/trunk/drivers/misc/sgi-xp/xpc_sn2.c @@ -66,12 +66,6 @@ xpc_setup_partitions_sn_sn2(void) return 0; } -static void -xpc_teardown_partitions_sn_sn2(void) -{ - /* nothing needs to be done */ -} - /* SH_IPI_ACCESS shub register value on startup */ static u64 xpc_sh1_IPI_access_sn2; static u64 xpc_sh2_IPI_access0_sn2; @@ -442,12 +436,11 @@ xpc_send_chctl_local_msgrequest_sn2(struct xpc_channel *ch) XPC_SEND_LOCAL_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST); } -static enum xp_retval +static void xpc_save_remote_msgqueue_pa_sn2(struct xpc_channel *ch, unsigned long msgqueue_pa) { ch->sn.sn2.remote_msgqueue_pa = msgqueue_pa; - return xpSuccess; } /* @@ -1744,20 +1737,20 @@ xpc_clear_remote_msgqueue_flags_sn2(struct xpc_channel *ch) { struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; struct xpc_msg_sn2 *msg; - s64 put, remote_nentries = ch->remote_nentries; + s64 put; /* flags are zeroed when the buffer is allocated */ - if (ch_sn2->remote_GP.put < remote_nentries) + if (ch_sn2->remote_GP.put < ch->remote_nentries) return; - put = max(ch_sn2->w_remote_GP.put, remote_nentries); + put = max(ch_sn2->w_remote_GP.put, ch->remote_nentries); do { msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue + - (put % remote_nentries) * + (put % ch->remote_nentries) * ch->entry_size); DBUG_ON(!(msg->flags & XPC_M_SN2_READY)); DBUG_ON(!(msg->flags & XPC_M_SN2_DONE)); - DBUG_ON(msg->number != put - remote_nentries); + DBUG_ON(msg->number != put - ch->remote_nentries); msg->flags = 0; } while (++put < ch_sn2->remote_GP.put); } @@ -2322,7 +2315,6 @@ xpc_init_sn2(void) size_t buf_size; xpc_setup_partitions_sn = xpc_setup_partitions_sn_sn2; - xpc_teardown_partitions_sn = xpc_teardown_partitions_sn_sn2; xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2; xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_sn2; xpc_increment_heartbeat = xpc_increment_heartbeat_sn2; diff --git a/trunk/drivers/misc/sgi-xp/xpc_uv.c b/trunk/drivers/misc/sgi-xp/xpc_uv.c index f7fff4727edb..29c0502a96b2 100644 --- a/trunk/drivers/misc/sgi-xp/xpc_uv.c +++ b/trunk/drivers/misc/sgi-xp/xpc_uv.c @@ -31,21 +31,6 @@ #include "../sgi-gru/grukservices.h" #include "xpc.h" -#if defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV -struct uv_IO_APIC_route_entry { - __u64 vector : 8, - delivery_mode : 3, - dest_mode : 1, - delivery_status : 1, - polarity : 1, - __reserved_1 : 1, - trigger : 1, - mask : 1, - __reserved_2 : 15, - dest : 32; -}; -#endif - static atomic64_t xpc_heartbeat_uv; static DECLARE_BITMAP(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV); @@ -71,52 +56,26 @@ xpc_setup_partitions_sn_uv(void) for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) { part_uv = &xpc_partitions[partid].sn.uv; - mutex_init(&part_uv->cached_activate_gru_mq_desc_mutex); spin_lock_init(&part_uv->flags_lock); part_uv->remote_act_state = XPC_P_AS_INACTIVE; } return 0; } -static void -xpc_teardown_partitions_sn_uv(void) -{ - short partid; - struct xpc_partition_uv *part_uv; - unsigned long irq_flags; - - for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) { - part_uv = &xpc_partitions[partid].sn.uv; - - if (part_uv->cached_activate_gru_mq_desc != NULL) { - mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex); - spin_lock_irqsave(&part_uv->flags_lock, irq_flags); - part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV; - spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); - kfree(part_uv->cached_activate_gru_mq_desc); - part_uv->cached_activate_gru_mq_desc = NULL; - mutex_unlock(&part_uv-> - cached_activate_gru_mq_desc_mutex); - } - } -} - static int xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name) { - int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade); - #if defined CONFIG_X86_64 mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset); if (mq->irq < 0) { dev_err(xpc_part, "uv_setup_irq() returned error=%d\n", - -mq->irq); - return mq->irq; + mq->irq); } - mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset); - #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV + int mmr_pnode; + unsigned long mmr_value; + if (strcmp(irq_name, XPC_ACTIVATE_IRQ_NAME) == 0) mq->irq = SGI_XPC_ACTIVATE; else if (strcmp(irq_name, XPC_NOTIFY_IRQ_NAME) == 0) @@ -124,8 +83,10 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name) else return -EINVAL; - mq->mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq; - uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mq->mmr_value); + mmr_pnode = uv_blade_to_pnode(mq->mmr_blade); + mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq; + + uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mmr_value); #else #error not a supported configuration #endif @@ -166,7 +127,7 @@ xpc_gru_mq_watchlist_alloc_uv(struct xpc_gru_mq_uv *mq) return ret; } #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV - ret = sn_mq_watchlist_alloc(mq->mmr_blade, (void *)uv_gpa(mq->address), + ret = sn_mq_watchlist_alloc(mq->mmr_blade, uv_gpa(mq->address), mq->order, &mq->mmr_offset); if (ret < 0) { dev_err(xpc_part, "sn_mq_watchlist_alloc() failed, ret=%d\n", @@ -207,22 +168,12 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, int pg_order; struct page *page; struct xpc_gru_mq_uv *mq; - struct uv_IO_APIC_route_entry *mmr_value; mq = kmalloc(sizeof(struct xpc_gru_mq_uv), GFP_KERNEL); if (mq == NULL) { dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() " "a xpc_gru_mq_uv structure\n"); ret = -ENOMEM; - goto out_0; - } - - mq->gru_mq_desc = kzalloc(sizeof(struct gru_message_queue_desc), - GFP_KERNEL); - if (mq->gru_mq_desc == NULL) { - dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() " - "a gru_message_queue_desc structure\n"); - ret = -ENOMEM; goto out_1; } @@ -243,6 +194,14 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, } mq->address = page_address(page); + ret = gru_create_message_queue(mq->address, mq_size); + if (ret != 0) { + dev_err(xpc_part, "gru_create_message_queue() returned " + "error=%d\n", ret); + ret = -EINVAL; + goto out_3; + } + /* enable generation of irq when GRU mq operation occurs to this mq */ ret = xpc_gru_mq_watchlist_alloc_uv(mq); if (ret != 0) @@ -255,20 +214,10 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, ret = request_irq(mq->irq, irq_handler, 0, irq_name, NULL); if (ret != 0) { dev_err(xpc_part, "request_irq(irq=%d) returned error=%d\n", - mq->irq, -ret); + mq->irq, ret); goto out_5; } - mmr_value = (struct uv_IO_APIC_route_entry *)&mq->mmr_value; - ret = gru_create_message_queue(mq->gru_mq_desc, mq->address, mq_size, - nid, mmr_value->vector, mmr_value->dest); - if (ret != 0) { - dev_err(xpc_part, "gru_create_message_queue() returned " - "error=%d\n", ret); - ret = -EINVAL; - goto out_6; - } - /* allow other partitions to access this GRU mq */ xp_ret = xp_expand_memprotect(xp_pa(mq->address), mq_size); if (xp_ret != xpSuccess) { @@ -288,10 +237,8 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, out_3: free_pages((unsigned long)mq->address, pg_order); out_2: - kfree(mq->gru_mq_desc); -out_1: kfree(mq); -out_0: +out_1: return ERR_PTR(ret); } @@ -321,14 +268,13 @@ xpc_destroy_gru_mq_uv(struct xpc_gru_mq_uv *mq) } static enum xp_retval -xpc_send_gru_msg(struct gru_message_queue_desc *gru_mq_desc, void *msg, - size_t msg_size) +xpc_send_gru_msg(unsigned long mq_gpa, void *msg, size_t msg_size) { enum xp_retval xp_ret; int ret; while (1) { - ret = gru_send_message_gpa(gru_mq_desc, msg, msg_size); + ret = gru_send_message_gpa(mq_gpa, msg, msg_size); if (ret == MQE_OK) { xp_ret = xpSuccess; break; @@ -475,15 +421,7 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV; part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */ part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies; - - if (msg->activate_gru_mq_desc_gpa != - part_uv->activate_gru_mq_desc_gpa) { - spin_lock_irqsave(&part_uv->flags_lock, irq_flags); - part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV; - spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); - part_uv->activate_gru_mq_desc_gpa = - msg->activate_gru_mq_desc_gpa; - } + part_uv->remote_activate_mq_gpa = msg->activate_mq_gpa; spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); (*wakeup_hb_checker)++; @@ -560,7 +498,7 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, args = &part->remote_openclose_args[msg->ch_number]; args->remote_nentries = msg->remote_nentries; args->local_nentries = msg->local_nentries; - args->local_msgqueue_pa = msg->notify_gru_mq_desc_gpa; + args->local_msgqueue_pa = msg->local_notify_mq_gpa; spin_lock_irqsave(&part->chctl_lock, irq_flags); part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENREPLY; @@ -620,10 +558,9 @@ xpc_handle_activate_IRQ_uv(int irq, void *dev_id) short partid; struct xpc_partition *part; int wakeup_hb_checker = 0; - int part_referenced; while (1) { - msg_hdr = gru_get_next_message(xpc_activate_mq_uv->gru_mq_desc); + msg_hdr = gru_get_next_message(xpc_activate_mq_uv->address); if (msg_hdr == NULL) break; @@ -634,15 +571,14 @@ xpc_handle_activate_IRQ_uv(int irq, void *dev_id) partid); } else { part = &xpc_partitions[partid]; - - part_referenced = xpc_part_ref(part); - xpc_handle_activate_mq_msg_uv(part, msg_hdr, - &wakeup_hb_checker); - if (part_referenced) + if (xpc_part_ref(part)) { + xpc_handle_activate_mq_msg_uv(part, msg_hdr, + &wakeup_hb_checker); xpc_part_deref(part); + } } - gru_free_message(xpc_activate_mq_uv->gru_mq_desc, msg_hdr); + gru_free_message(xpc_activate_mq_uv->address, msg_hdr); } if (wakeup_hb_checker) @@ -651,74 +587,22 @@ xpc_handle_activate_IRQ_uv(int irq, void *dev_id) return IRQ_HANDLED; } -static enum xp_retval -xpc_cache_remote_gru_mq_desc_uv(struct gru_message_queue_desc *gru_mq_desc, - unsigned long gru_mq_desc_gpa) -{ - enum xp_retval ret; - - ret = xp_remote_memcpy(uv_gpa(gru_mq_desc), gru_mq_desc_gpa, - sizeof(struct gru_message_queue_desc)); - if (ret == xpSuccess) - gru_mq_desc->mq = NULL; - - return ret; -} - static enum xp_retval xpc_send_activate_IRQ_uv(struct xpc_partition *part, void *msg, size_t msg_size, int msg_type) { struct xpc_activate_mq_msghdr_uv *msg_hdr = msg; - struct xpc_partition_uv *part_uv = &part->sn.uv; - struct gru_message_queue_desc *gru_mq_desc; - unsigned long irq_flags; - enum xp_retval ret; DBUG_ON(msg_size > XPC_ACTIVATE_MSG_SIZE_UV); msg_hdr->type = msg_type; - msg_hdr->partid = xp_partition_id; + msg_hdr->partid = XPC_PARTID(part); msg_hdr->act_state = part->act_state; msg_hdr->rp_ts_jiffies = xpc_rsvd_page->ts_jiffies; - mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex); -again: - if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV)) { - gru_mq_desc = part_uv->cached_activate_gru_mq_desc; - if (gru_mq_desc == NULL) { - gru_mq_desc = kmalloc(sizeof(struct - gru_message_queue_desc), - GFP_KERNEL); - if (gru_mq_desc == NULL) { - ret = xpNoMemory; - goto done; - } - part_uv->cached_activate_gru_mq_desc = gru_mq_desc; - } - - ret = xpc_cache_remote_gru_mq_desc_uv(gru_mq_desc, - part_uv-> - activate_gru_mq_desc_gpa); - if (ret != xpSuccess) - goto done; - - spin_lock_irqsave(&part_uv->flags_lock, irq_flags); - part_uv->flags |= XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV; - spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); - } - /* ??? Is holding a spin_lock (ch->lock) during this call a bad idea? */ - ret = xpc_send_gru_msg(part_uv->cached_activate_gru_mq_desc, msg, - msg_size); - if (ret != xpSuccess) { - smp_rmb(); /* ensure a fresh copy of part_uv->flags */ - if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV)) - goto again; - } -done: - mutex_unlock(&part_uv->cached_activate_gru_mq_desc_mutex); - return ret; + return xpc_send_gru_msg(part->sn.uv.remote_activate_mq_gpa, msg, + msg_size); } static void @@ -736,7 +620,7 @@ static void xpc_send_activate_IRQ_ch_uv(struct xpc_channel *ch, unsigned long *irq_flags, void *msg, size_t msg_size, int msg_type) { - struct xpc_partition *part = &xpc_partitions[ch->partid]; + struct xpc_partition *part = &xpc_partitions[ch->number]; enum xp_retval ret; ret = xpc_send_activate_IRQ_uv(part, msg, msg_size, msg_type); @@ -808,8 +692,7 @@ xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa, static int xpc_setup_rsvd_page_sn_uv(struct xpc_rsvd_page *rp) { - rp->sn.activate_gru_mq_desc_gpa = - uv_gpa(xpc_activate_mq_uv->gru_mq_desc); + rp->sn.activate_mq_gpa = uv_gpa(xpc_activate_mq_uv->address); return 0; } @@ -904,8 +787,7 @@ xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp, part->remote_rp_pa = remote_rp_gpa; /* !!! _pa here is really _gpa */ part->remote_rp_ts_jiffies = remote_rp->ts_jiffies; - part->sn.uv.activate_gru_mq_desc_gpa = - remote_rp->sn.activate_gru_mq_desc_gpa; + part->sn.uv.remote_activate_mq_gpa = remote_rp->sn.activate_mq_gpa; /* * ??? Is it a good idea to make this conditional on what is @@ -913,8 +795,7 @@ xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp, */ if (part->sn.uv.remote_act_state == XPC_P_AS_INACTIVE) { msg.rp_gpa = uv_gpa(xpc_rsvd_page); - msg.activate_gru_mq_desc_gpa = - xpc_rsvd_page->sn.activate_gru_mq_desc_gpa; + msg.activate_mq_gpa = xpc_rsvd_page->sn.activate_mq_gpa; xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV); } @@ -976,8 +857,7 @@ xpc_get_fifo_entry_uv(struct xpc_fifo_head_uv *head) if (head->first == NULL) head->last = NULL; } - head->n_entries--; - BUG_ON(head->n_entries < 0); + head->n_entries++; spin_unlock_irqrestore(&head->lock, irq_flags); first->next = NULL; return first; @@ -996,7 +876,8 @@ xpc_put_fifo_entry_uv(struct xpc_fifo_head_uv *head, else head->first = last; head->last = last; - head->n_entries++; + head->n_entries--; + BUG_ON(head->n_entries < 0); spin_unlock_irqrestore(&head->lock, irq_flags); } @@ -1156,12 +1037,6 @@ xpc_setup_msg_structures_uv(struct xpc_channel *ch) DBUG_ON(ch->flags & XPC_C_SETUP); - ch_uv->cached_notify_gru_mq_desc = kmalloc(sizeof(struct - gru_message_queue_desc), - GFP_KERNEL); - if (ch_uv->cached_notify_gru_mq_desc == NULL) - return xpNoMemory; - ret = xpc_allocate_send_msg_slot_uv(ch); if (ret == xpSuccess) { @@ -1185,8 +1060,7 @@ xpc_teardown_msg_structures_uv(struct xpc_channel *ch) DBUG_ON(!spin_is_locked(&ch->lock)); - kfree(ch_uv->cached_notify_gru_mq_desc); - ch_uv->cached_notify_gru_mq_desc = NULL; + ch_uv->remote_notify_mq_gpa = 0; if (ch->flags & XPC_C_SETUP) { xpc_init_fifo_uv(&ch_uv->msg_slot_free_list); @@ -1237,7 +1111,7 @@ xpc_send_chctl_openreply_uv(struct xpc_channel *ch, unsigned long *irq_flags) msg.ch_number = ch->number; msg.local_nentries = ch->local_nentries; msg.remote_nentries = ch->remote_nentries; - msg.notify_gru_mq_desc_gpa = uv_gpa(xpc_notify_mq_uv->gru_mq_desc); + msg.local_notify_mq_gpa = uv_gpa(xpc_notify_mq_uv); xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV); } @@ -1254,15 +1128,11 @@ xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number) xpc_wakeup_channel_mgr(part); } -static enum xp_retval +static void xpc_save_remote_msgqueue_pa_uv(struct xpc_channel *ch, - unsigned long gru_mq_desc_gpa) + unsigned long msgqueue_pa) { - struct xpc_channel_uv *ch_uv = &ch->sn.uv; - - DBUG_ON(ch_uv->cached_notify_gru_mq_desc == NULL); - return xpc_cache_remote_gru_mq_desc_uv(ch_uv->cached_notify_gru_mq_desc, - gru_mq_desc_gpa); + ch->sn.uv.remote_notify_mq_gpa = msgqueue_pa; } static void @@ -1469,8 +1339,7 @@ xpc_handle_notify_IRQ_uv(int irq, void *dev_id) short partid; struct xpc_partition *part; - while ((msg = gru_get_next_message(xpc_notify_mq_uv->gru_mq_desc)) != - NULL) { + while ((msg = gru_get_next_message(xpc_notify_mq_uv)) != NULL) { partid = msg->hdr.partid; if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) { @@ -1485,7 +1354,7 @@ xpc_handle_notify_IRQ_uv(int irq, void *dev_id) } } - gru_free_message(xpc_notify_mq_uv->gru_mq_desc, msg); + gru_free_message(xpc_notify_mq_uv, msg); } return IRQ_HANDLED; @@ -1569,8 +1438,7 @@ xpc_send_payload_uv(struct xpc_channel *ch, u32 flags, void *payload, msg->hdr.msg_slot_number = msg_slot->msg_slot_number; memcpy(&msg->payload, payload, payload_size); - ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg, - msg_size); + ret = xpc_send_gru_msg(ch->sn.uv.remote_notify_mq_gpa, msg, msg_size); if (ret == xpSuccess) goto out_1; @@ -1661,7 +1529,7 @@ xpc_received_payload_uv(struct xpc_channel *ch, void *payload) msg->hdr.partid = xp_partition_id; msg->hdr.size = 0; /* size of zero indicates this is an ACK */ - ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg, + ret = xpc_send_gru_msg(ch->sn.uv.remote_notify_mq_gpa, msg, sizeof(struct xpc_notify_mq_msghdr_uv)); if (ret != xpSuccess) XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret); @@ -1673,7 +1541,6 @@ int xpc_init_uv(void) { xpc_setup_partitions_sn = xpc_setup_partitions_sn_uv; - xpc_teardown_partitions_sn = xpc_teardown_partitions_sn_uv; xpc_process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv; xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv; xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_uv; diff --git a/trunk/drivers/mmc/card/sdio_uart.c b/trunk/drivers/mmc/card/sdio_uart.c index 36a8d53ad2a2..78ad48718ab0 100644 --- a/trunk/drivers/mmc/card/sdio_uart.c +++ b/trunk/drivers/mmc/card/sdio_uart.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -934,64 +933,67 @@ static int sdio_uart_tiocmset(struct tty_struct *tty, struct file *file, return result; } -static int sdio_uart_proc_show(struct seq_file *m, void *v) +static int sdio_uart_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { - int i; + int i, len = 0; + off_t begin = 0; - seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n", + len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n", "", "", ""); - for (i = 0; i < UART_NR; i++) { + for (i = 0; i < UART_NR && len < PAGE_SIZE - 96; i++) { struct sdio_uart_port *port = sdio_uart_port_get(i); if (port) { - seq_printf(m, "%d: uart:SDIO", i); + len += sprintf(page+len, "%d: uart:SDIO", i); if(capable(CAP_SYS_ADMIN)) { - seq_printf(m, " tx:%d rx:%d", + len += sprintf(page + len, " tx:%d rx:%d", port->icount.tx, port->icount.rx); if (port->icount.frame) - seq_printf(m, " fe:%d", + len += sprintf(page + len, " fe:%d", port->icount.frame); if (port->icount.parity) - seq_printf(m, " pe:%d", + len += sprintf(page + len, " pe:%d", port->icount.parity); if (port->icount.brk) - seq_printf(m, " brk:%d", + len += sprintf(page + len, " brk:%d", port->icount.brk); if (port->icount.overrun) - seq_printf(m, " oe:%d", + len += sprintf(page + len, " oe:%d", port->icount.overrun); if (port->icount.cts) - seq_printf(m, " cts:%d", + len += sprintf(page + len, " cts:%d", port->icount.cts); if (port->icount.dsr) - seq_printf(m, " dsr:%d", + len += sprintf(page + len, " dsr:%d", port->icount.dsr); if (port->icount.rng) - seq_printf(m, " rng:%d", + len += sprintf(page + len, " rng:%d", port->icount.rng); if (port->icount.dcd) - seq_printf(m, " dcd:%d", + len += sprintf(page + len, " dcd:%d", port->icount.dcd); } + strcat(page, "\n"); + len++; sdio_uart_port_put(port); - seq_putc(m, '\n'); + } + + if (len + begin > off + count) + goto done; + if (len + begin < off) { + begin += len; + len = 0; } } - return 0; -} + *eof = 1; -static int sdio_uart_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, sdio_uart_proc_show, NULL); +done: + if (off >= len + begin) + return 0; + *start = page + (off - begin); + return (count < begin + len - off) ? count : (begin + len - off); } -static const struct file_operations sdio_uart_proc_fops = { - .owner = THIS_MODULE, - .open = sdio_uart_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static const struct tty_operations sdio_uart_ops = { .open = sdio_uart_open, .close = sdio_uart_close, @@ -1005,7 +1007,7 @@ static const struct tty_operations sdio_uart_ops = { .break_ctl = sdio_uart_break_ctl, .tiocmget = sdio_uart_tiocmget, .tiocmset = sdio_uart_tiocmset, - .proc_fops = &sdio_uart_proc_fops, + .read_proc = sdio_uart_read_proc, }; static struct tty_driver *sdio_uart_tty_driver; diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index f062b424704e..c99ee38f952e 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -974,7 +974,7 @@ config ENC28J60_WRITEVERIFY config ETHOC tristate "OpenCores 10/100 Mbps Ethernet MAC support" - depends on NET_ETHERNET + depends on NET_ETHERNET && HAS_IOMEM select MII select PHYLIB help diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 99610f358c40..9c326a50a3ee 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -3444,12 +3444,25 @@ static void bond_remove_proc_entry(struct bonding *bond) */ static void bond_create_proc_dir(void) { + int len = strlen(DRV_NAME); + + for (bond_proc_dir = init_net.proc_net->subdir; bond_proc_dir; + bond_proc_dir = bond_proc_dir->next) { + if ((bond_proc_dir->namelen == len) && + !memcmp(bond_proc_dir->name, DRV_NAME, len)) { + break; + } + } + if (!bond_proc_dir) { bond_proc_dir = proc_mkdir(DRV_NAME, init_net.proc_net); - if (!bond_proc_dir) + if (bond_proc_dir) { + bond_proc_dir->owner = THIS_MODULE; + } else { printk(KERN_WARNING DRV_NAME ": Warning: cannot create /proc/net/%s\n", DRV_NAME); + } } } @@ -3458,7 +3471,25 @@ static void bond_create_proc_dir(void) */ static void bond_destroy_proc_dir(void) { - if (bond_proc_dir) { + struct proc_dir_entry *de; + + if (!bond_proc_dir) { + return; + } + + /* verify that the /proc dir is empty */ + for (de = bond_proc_dir->subdir; de; de = de->next) { + /* ignore . and .. */ + if (*(de->name) != '.') { + break; + } + } + + if (de) { + if (bond_proc_dir->owner == THIS_MODULE) { + bond_proc_dir->owner = NULL; + } + } else { remove_proc_entry(DRV_NAME, init_net.proc_net); bond_proc_dir = NULL; } diff --git a/trunk/drivers/net/dm9000.c b/trunk/drivers/net/dm9000.c index d8350860c0f8..254ec62b5f58 100644 --- a/trunk/drivers/net/dm9000.c +++ b/trunk/drivers/net/dm9000.c @@ -559,7 +559,7 @@ static void dm9000_show_carrier(board_info_t *db, static void dm9000_poll_work(struct work_struct *w) { - struct delayed_work *dw = to_delayed_work(w); + struct delayed_work *dw = container_of(w, struct delayed_work, work); board_info_t *db = container_of(dw, board_info_t, phy_poll); struct net_device *ndev = db->ndev; diff --git a/trunk/drivers/net/fec_mpc52xx.c b/trunk/drivers/net/fec_mpc52xx.c index 049b0a7e01f3..cd8e98b45ec5 100644 --- a/trunk/drivers/net/fec_mpc52xx.c +++ b/trunk/drivers/net/fec_mpc52xx.c @@ -1123,9 +1123,9 @@ static int mpc52xx_fec_of_resume(struct of_device *op) #endif static struct of_device_id mpc52xx_fec_match[] = { - { .compatible = "fsl,mpc5200b-fec", }, - { .compatible = "fsl,mpc5200-fec", }, - { .compatible = "mpc5200-fec", }, + { .type = "network", .compatible = "fsl,mpc5200b-fec", }, + { .type = "network", .compatible = "fsl,mpc5200-fec", }, + { .type = "network", .compatible = "mpc5200-fec", }, { } }; diff --git a/trunk/drivers/net/irda/vlsi_ir.c b/trunk/drivers/net/irda/vlsi_ir.c index ac0e4b6b6b66..1243bc8e0035 100644 --- a/trunk/drivers/net/irda/vlsi_ir.c +++ b/trunk/drivers/net/irda/vlsi_ir.c @@ -1871,6 +1871,13 @@ static int __init vlsi_mod_init(void) * without procfs - it's not required for the driver to work. */ vlsi_proc_root = proc_mkdir(PROC_DIR, NULL); + if (vlsi_proc_root) { + /* protect registered procdir against module removal. + * Because we are in the module init path there's no race + * window after create_proc_entry (and no barrier needed). + */ + vlsi_proc_root->owner = THIS_MODULE; + } ret = pci_register_driver(&vlsi_irda_driver); diff --git a/trunk/drivers/net/meth.c b/trunk/drivers/net/meth.c index aa08987f6e81..c336a1f42510 100644 --- a/trunk/drivers/net/meth.c +++ b/trunk/drivers/net/meth.c @@ -398,7 +398,7 @@ static void meth_rx(struct net_device* dev, unsigned long int_status) int len = (status & 0xffff) - 4; /* omit CRC */ /* length sanity check */ if (len < 60 || len > 1518) { - printk(KERN_DEBUG "%s: bogus packet size: %ld, status=%#2Lx.\n", + printk(KERN_DEBUG "%s: bogus packet size: %ld, status=%#2lx.\n", dev->name, priv->rx_write, priv->rx_ring[priv->rx_write]->status.raw); dev->stats.rx_errors++; diff --git a/trunk/drivers/net/mlx4/en_netdev.c b/trunk/drivers/net/mlx4/en_netdev.c index 303c23de6cac..9f6644a44030 100644 --- a/trunk/drivers/net/mlx4/en_netdev.c +++ b/trunk/drivers/net/mlx4/en_netdev.c @@ -505,7 +505,7 @@ static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv) static void mlx4_en_do_get_stats(struct work_struct *work) { - struct delayed_work *delay = to_delayed_work(work); + struct delayed_work *delay = container_of(work, struct delayed_work, work); struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv, stats_task); struct mlx4_en_dev *mdev = priv->mdev; diff --git a/trunk/drivers/net/mlx4/en_rx.c b/trunk/drivers/net/mlx4/en_rx.c index 7e40741fb7d8..a4130e764991 100644 --- a/trunk/drivers/net/mlx4/en_rx.c +++ b/trunk/drivers/net/mlx4/en_rx.c @@ -298,7 +298,7 @@ static void mlx4_en_free_rx_buf(struct mlx4_en_priv *priv, void mlx4_en_rx_refill(struct work_struct *work) { - struct delayed_work *delay = to_delayed_work(work); + struct delayed_work *delay = container_of(work, struct delayed_work, work); struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv, refill_task); struct mlx4_en_dev *mdev = priv->mdev; diff --git a/trunk/drivers/net/mlx4/sense.c b/trunk/drivers/net/mlx4/sense.c index f36ae691cab3..6d5089ecb5af 100644 --- a/trunk/drivers/net/mlx4/sense.c +++ b/trunk/drivers/net/mlx4/sense.c @@ -103,7 +103,7 @@ void mlx4_do_sense_ports(struct mlx4_dev *dev, static void mlx4_sense_port(struct work_struct *work) { - struct delayed_work *delay = to_delayed_work(work); + struct delayed_work *delay = container_of(work, struct delayed_work, work); struct mlx4_sense *sense = container_of(delay, struct mlx4_sense, sense_poll); struct mlx4_dev *dev = sense->dev; diff --git a/trunk/drivers/net/phy/phy.c b/trunk/drivers/net/phy/phy.c index 3ff1f425f1bb..58b73b08dde0 100644 --- a/trunk/drivers/net/phy/phy.c +++ b/trunk/drivers/net/phy/phy.c @@ -757,7 +757,8 @@ EXPORT_SYMBOL(phy_start); */ static void phy_state_machine(struct work_struct *work) { - struct delayed_work *dwork = to_delayed_work(work); + struct delayed_work *dwork = + container_of(work, struct delayed_work, work); struct phy_device *phydev = container_of(dwork, struct phy_device, state_queue); int needs_aneg = 0; diff --git a/trunk/drivers/net/smc91x.h b/trunk/drivers/net/smc91x.h index 912308eec865..6c44f86ae3fd 100644 --- a/trunk/drivers/net/smc91x.h +++ b/trunk/drivers/net/smc91x.h @@ -346,6 +346,38 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, #define RPC_LSA_DEFAULT RPC_LED_TX_RX #define RPC_LSB_DEFAULT RPC_LED_100_10 +#elif defined(CONFIG_SOC_AU1X00) + +#include + +/* We can only do 16-bit reads and writes in the static memory space. */ +#define SMC_CAN_USE_8BIT 0 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 0 +#define SMC_IO_SHIFT 0 +#define SMC_NOWAIT 1 + +#define SMC_inw(a, r) au_readw((unsigned long)((a) + (r))) +#define SMC_insw(a, r, p, l) \ + do { \ + unsigned long _a = (unsigned long)((a) + (r)); \ + int _l = (l); \ + u16 *_p = (u16 *)(p); \ + while (_l-- > 0) \ + *_p++ = au_readw(_a); \ + } while(0) +#define SMC_outw(v, a, r) au_writew(v, (unsigned long)((a) + (r))) +#define SMC_outsw(a, r, p, l) \ + do { \ + unsigned long _a = (unsigned long)((a) + (r)); \ + int _l = (l); \ + const u16 *_p = (const u16 *)(p); \ + while (_l-- > 0) \ + au_writew(*_p++ , _a); \ + } while(0) + +#define SMC_IRQ_FLAGS (0) + #elif defined(CONFIG_ARCH_VERSATILE) #define SMC_CAN_USE_8BIT 1 diff --git a/trunk/drivers/net/wireless/airo.c b/trunk/drivers/net/wireless/airo.c index f21a6171c691..93302c0a36b0 100644 --- a/trunk/drivers/net/wireless/airo.c +++ b/trunk/drivers/net/wireless/airo.c @@ -4492,6 +4492,7 @@ static int setup_proc_entry( struct net_device *dev, goto fail; apriv->proc_entry->uid = proc_uid; apriv->proc_entry->gid = proc_gid; + apriv->proc_entry->owner = THIS_MODULE; /* Setup the StatsDelta */ entry = proc_create_data("StatsDelta", diff --git a/trunk/drivers/of/base.c b/trunk/drivers/of/base.c index 41c5dfd85358..cd17092b82bd 100644 --- a/trunk/drivers/of/base.c +++ b/trunk/drivers/of/base.c @@ -446,7 +446,6 @@ struct of_modalias_table { }; static struct of_modalias_table of_modalias_table[] = { { "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" }, - { "mmc-spi-slot", "mmc_spi" }, }; /** diff --git a/trunk/drivers/oprofile/buffer_sync.c b/trunk/drivers/oprofile/buffer_sync.c index 2c9aa49e43cd..c3ea5fa7d05a 100644 --- a/trunk/drivers/oprofile/buffer_sync.c +++ b/trunk/drivers/oprofile/buffer_sync.c @@ -574,7 +574,7 @@ int __init buffer_sync_init(void) return 0; } -void buffer_sync_cleanup(void) +void __exit buffer_sync_cleanup(void) { free_cpumask_var(marked_cpus); } diff --git a/trunk/drivers/parport/parport_serial.c b/trunk/drivers/parport/parport_serial.c index f3492110b1ad..032db815b0f9 100644 --- a/trunk/drivers/parport/parport_serial.c +++ b/trunk/drivers/parport/parport_serial.c @@ -30,7 +30,6 @@ enum parport_pc_pci_cards { titan_210l, netmos_9xx5_combo, netmos_9855, - netmos_9855_2p, avlab_1s1p, avlab_1s2p, avlab_2s1p, @@ -63,7 +62,7 @@ struct parport_pc_pci { struct parport_pc_pci *card, int failed); }; -static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *par, int autoirq, int autodma) +static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *card, int autoirq, int autodma) { /* the rule described below doesn't hold for this device */ if (dev->device == PCI_DEVICE_ID_NETMOS_9835 && @@ -75,17 +74,9 @@ static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc * and serial ports. The form is 0x00PS, where

is the number of * parallel ports and is the number of serial ports. */ - par->numports = (dev->subsystem_device & 0xf0) >> 4; - if (par->numports > ARRAY_SIZE(par->addr)) - par->numports = ARRAY_SIZE(par->addr); - /* - * This function is currently only called for cards with up to - * one parallel port. - * Parallel port BAR is either before or after serial ports BARS; - * hence, lo should be either 0 or equal to the number of serial ports. - */ - if (par->addr[0].lo != 0) - par->addr[0].lo = dev->subsystem_device & 0xf; + card->numports = (dev->subsystem_device & 0xf0) >> 4; + if (card->numports > ARRAY_SIZE(card->addr)) + card->numports = ARRAY_SIZE(card->addr); return 0; } @@ -93,8 +84,7 @@ static struct parport_pc_pci cards[] __devinitdata = { /* titan_110l */ { 1, { { 3, -1 }, } }, /* titan_210l */ { 1, { { 3, -1 }, } }, /* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init }, - /* netmos_9855 */ { 1, { { 0, -1 }, }, netmos_parallel_init }, - /* netmos_9855_2p */ { 2, { { 0, -1 }, { 2, -1 }, } }, + /* netmos_9855 */ { 1, { { 2, -1 }, }, netmos_parallel_init }, /* avlab_1s1p */ { 1, { { 1, 2}, } }, /* avlab_1s2p */ { 2, { { 1, 2}, { 3, 4 },} }, /* avlab_2s1p */ { 1, { { 2, 3}, } }, @@ -119,10 +109,6 @@ static struct pci_device_id parport_serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845, PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, - { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, - 0x1000, 0x0020, 0, 0, netmos_9855_2p }, - { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, - 0x1000, 0x0022, 0, 0, netmos_9855_2p }, { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 }, /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/ @@ -206,12 +192,6 @@ static struct pciserial_board pci_parport_serial_boards[] __devinitdata = { .uart_offset = 8, }, [netmos_9855] = { - .flags = FL_BASE2 | FL_BASE_BARS, - .num_ports = 1, - .base_baud = 115200, - .uart_offset = 8, - }, - [netmos_9855_2p] = { .flags = FL_BASE4 | FL_BASE_BARS, .num_ports = 1, .base_baud = 115200, diff --git a/trunk/drivers/pci/Kconfig b/trunk/drivers/pci/Kconfig index fdc864f9cf23..2a4501dd2515 100644 --- a/trunk/drivers/pci/Kconfig +++ b/trunk/drivers/pci/Kconfig @@ -59,13 +59,3 @@ config HT_IRQ This allows native hypertransport devices to use interrupts. If unsure say Y. - -config PCI_IOV - bool "PCI IOV support" - depends on PCI - help - I/O Virtualization is a PCI feature supported by some devices - which allows them to create virtual devices which share their - physical resources. - - If unsure, say N. diff --git a/trunk/drivers/pci/Makefile b/trunk/drivers/pci/Makefile index ba6af162fd39..3d07ce24f6a8 100644 --- a/trunk/drivers/pci/Makefile +++ b/trunk/drivers/pci/Makefile @@ -29,8 +29,6 @@ obj-$(CONFIG_DMAR) += dmar.o iova.o intel-iommu.o obj-$(CONFIG_INTR_REMAP) += dmar.o intr_remapping.o -obj-$(CONFIG_PCI_IOV) += iov.o - # # Some architectures use the generic PCI setup functions # diff --git a/trunk/drivers/pci/bus.c b/trunk/drivers/pci/bus.c index 68f91a252595..52b54f053be0 100644 --- a/trunk/drivers/pci/bus.c +++ b/trunk/drivers/pci/bus.c @@ -133,7 +133,7 @@ int pci_bus_add_child(struct pci_bus *bus) * * Call hotplug for each new devices. */ -void pci_bus_add_devices(const struct pci_bus *bus) +void pci_bus_add_devices(struct pci_bus *bus) { struct pci_dev *dev; struct pci_bus *child; @@ -184,10 +184,8 @@ void pci_enable_bridges(struct pci_bus *bus) list_for_each_entry(dev, &bus->devices, bus_list) { if (dev->subordinate) { - if (atomic_read(&dev->enable_cnt) == 0) { - retval = pci_enable_device(dev); - pci_set_master(dev); - } + retval = pci_enable_device(dev); + pci_set_master(dev); pci_enable_bridges(dev->subordinate); } } diff --git a/trunk/drivers/pci/dmar.c b/trunk/drivers/pci/dmar.c index d313039e2fdf..5f333403c2ea 100644 --- a/trunk/drivers/pci/dmar.c +++ b/trunk/drivers/pci/dmar.c @@ -31,8 +31,6 @@ #include #include #include -#include -#include #undef PREFIX #define PREFIX "DMAR:" @@ -511,7 +509,6 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) return -ENOMEM; iommu->seq_id = iommu_allocated++; - sprintf (iommu->name, "dmar%d", iommu->seq_id); iommu->reg = ioremap(drhd->reg_base_addr, VTD_PAGE_SIZE); if (!iommu->reg) { @@ -753,42 +750,6 @@ int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, return qi_submit_sync(&desc, iommu); } -/* - * Disable Queued Invalidation interface. - */ -void dmar_disable_qi(struct intel_iommu *iommu) -{ - unsigned long flags; - u32 sts; - cycles_t start_time = get_cycles(); - - if (!ecap_qis(iommu->ecap)) - return; - - spin_lock_irqsave(&iommu->register_lock, flags); - - sts = dmar_readq(iommu->reg + DMAR_GSTS_REG); - if (!(sts & DMA_GSTS_QIES)) - goto end; - - /* - * Give a chance to HW to complete the pending invalidation requests. - */ - while ((readl(iommu->reg + DMAR_IQT_REG) != - readl(iommu->reg + DMAR_IQH_REG)) && - (DMAR_OPERATION_TIMEOUT > (get_cycles() - start_time))) - cpu_relax(); - - iommu->gcmd &= ~DMA_GCMD_QIE; - - writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG); - - IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, - !(sts & DMA_GSTS_QIES), sts); -end: - spin_unlock_irqrestore(&iommu->register_lock, flags); -} - /* * Enable Queued Invalidation interface. This is a must to support * interrupt-remapping. Also used by DMA-remapping, which replaces @@ -809,20 +770,20 @@ int dmar_enable_qi(struct intel_iommu *iommu) if (iommu->qi) return 0; - iommu->qi = kmalloc(sizeof(*qi), GFP_ATOMIC); + iommu->qi = kmalloc(sizeof(*qi), GFP_KERNEL); if (!iommu->qi) return -ENOMEM; qi = iommu->qi; - qi->desc = (void *)(get_zeroed_page(GFP_ATOMIC)); + qi->desc = (void *)(get_zeroed_page(GFP_KERNEL)); if (!qi->desc) { kfree(qi); iommu->qi = 0; return -ENOMEM; } - qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC); + qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_KERNEL); if (!qi->desc_status) { free_page((unsigned long) qi->desc); kfree(qi); @@ -851,254 +812,3 @@ int dmar_enable_qi(struct intel_iommu *iommu) return 0; } - -/* iommu interrupt handling. Most stuff are MSI-like. */ - -enum faulttype { - DMA_REMAP, - INTR_REMAP, - UNKNOWN, -}; - -static const char *dma_remap_fault_reasons[] = -{ - "Software", - "Present bit in root entry is clear", - "Present bit in context entry is clear", - "Invalid context entry", - "Access beyond MGAW", - "PTE Write access is not set", - "PTE Read access is not set", - "Next page table ptr is invalid", - "Root table address invalid", - "Context table ptr is invalid", - "non-zero reserved fields in RTP", - "non-zero reserved fields in CTP", - "non-zero reserved fields in PTE", -}; - -static const char *intr_remap_fault_reasons[] = -{ - "Detected reserved fields in the decoded interrupt-remapped request", - "Interrupt index exceeded the interrupt-remapping table size", - "Present field in the IRTE entry is clear", - "Error accessing interrupt-remapping table pointed by IRTA_REG", - "Detected reserved fields in the IRTE entry", - "Blocked a compatibility format interrupt request", - "Blocked an interrupt request due to source-id verification failure", -}; - -#define MAX_FAULT_REASON_IDX (ARRAY_SIZE(fault_reason_strings) - 1) - -const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type) -{ - if (fault_reason >= 0x20 && (fault_reason <= 0x20 + - ARRAY_SIZE(intr_remap_fault_reasons))) { - *fault_type = INTR_REMAP; - return intr_remap_fault_reasons[fault_reason - 0x20]; - } else if (fault_reason < ARRAY_SIZE(dma_remap_fault_reasons)) { - *fault_type = DMA_REMAP; - return dma_remap_fault_reasons[fault_reason]; - } else { - *fault_type = UNKNOWN; - return "Unknown"; - } -} - -void dmar_msi_unmask(unsigned int irq) -{ - struct intel_iommu *iommu = get_irq_data(irq); - unsigned long flag; - - /* unmask it */ - spin_lock_irqsave(&iommu->register_lock, flag); - writel(0, iommu->reg + DMAR_FECTL_REG); - /* Read a reg to force flush the post write */ - readl(iommu->reg + DMAR_FECTL_REG); - spin_unlock_irqrestore(&iommu->register_lock, flag); -} - -void dmar_msi_mask(unsigned int irq) -{ - unsigned long flag; - struct intel_iommu *iommu = get_irq_data(irq); - - /* mask it */ - spin_lock_irqsave(&iommu->register_lock, flag); - writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG); - /* Read a reg to force flush the post write */ - readl(iommu->reg + DMAR_FECTL_REG); - spin_unlock_irqrestore(&iommu->register_lock, flag); -} - -void dmar_msi_write(int irq, struct msi_msg *msg) -{ - struct intel_iommu *iommu = get_irq_data(irq); - unsigned long flag; - - spin_lock_irqsave(&iommu->register_lock, flag); - writel(msg->data, iommu->reg + DMAR_FEDATA_REG); - writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG); - writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG); - spin_unlock_irqrestore(&iommu->register_lock, flag); -} - -void dmar_msi_read(int irq, struct msi_msg *msg) -{ - struct intel_iommu *iommu = get_irq_data(irq); - unsigned long flag; - - spin_lock_irqsave(&iommu->register_lock, flag); - msg->data = readl(iommu->reg + DMAR_FEDATA_REG); - msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG); - msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG); - spin_unlock_irqrestore(&iommu->register_lock, flag); -} - -static int dmar_fault_do_one(struct intel_iommu *iommu, int type, - u8 fault_reason, u16 source_id, unsigned long long addr) -{ - const char *reason; - int fault_type; - - reason = dmar_get_fault_reason(fault_reason, &fault_type); - - if (fault_type == INTR_REMAP) - printk(KERN_ERR "INTR-REMAP: Request device [[%02x:%02x.%d] " - "fault index %llx\n" - "INTR-REMAP:[fault reason %02d] %s\n", - (source_id >> 8), PCI_SLOT(source_id & 0xFF), - PCI_FUNC(source_id & 0xFF), addr >> 48, - fault_reason, reason); - else - printk(KERN_ERR - "DMAR:[%s] Request device [%02x:%02x.%d] " - "fault addr %llx \n" - "DMAR:[fault reason %02d] %s\n", - (type ? "DMA Read" : "DMA Write"), - (source_id >> 8), PCI_SLOT(source_id & 0xFF), - PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason); - return 0; -} - -#define PRIMARY_FAULT_REG_LEN (16) -irqreturn_t dmar_fault(int irq, void *dev_id) -{ - struct intel_iommu *iommu = dev_id; - int reg, fault_index; - u32 fault_status; - unsigned long flag; - - spin_lock_irqsave(&iommu->register_lock, flag); - fault_status = readl(iommu->reg + DMAR_FSTS_REG); - if (fault_status) - printk(KERN_ERR "DRHD: handling fault status reg %x\n", - fault_status); - - /* TBD: ignore advanced fault log currently */ - if (!(fault_status & DMA_FSTS_PPF)) - goto clear_rest; - - fault_index = dma_fsts_fault_record_index(fault_status); - reg = cap_fault_reg_offset(iommu->cap); - while (1) { - u8 fault_reason; - u16 source_id; - u64 guest_addr; - int type; - u32 data; - - /* highest 32 bits */ - data = readl(iommu->reg + reg + - fault_index * PRIMARY_FAULT_REG_LEN + 12); - if (!(data & DMA_FRCD_F)) - break; - - fault_reason = dma_frcd_fault_reason(data); - type = dma_frcd_type(data); - - data = readl(iommu->reg + reg + - fault_index * PRIMARY_FAULT_REG_LEN + 8); - source_id = dma_frcd_source_id(data); - - guest_addr = dmar_readq(iommu->reg + reg + - fault_index * PRIMARY_FAULT_REG_LEN); - guest_addr = dma_frcd_page_addr(guest_addr); - /* clear the fault */ - writel(DMA_FRCD_F, iommu->reg + reg + - fault_index * PRIMARY_FAULT_REG_LEN + 12); - - spin_unlock_irqrestore(&iommu->register_lock, flag); - - dmar_fault_do_one(iommu, type, fault_reason, - source_id, guest_addr); - - fault_index++; - if (fault_index > cap_num_fault_regs(iommu->cap)) - fault_index = 0; - spin_lock_irqsave(&iommu->register_lock, flag); - } -clear_rest: - /* clear all the other faults */ - fault_status = readl(iommu->reg + DMAR_FSTS_REG); - writel(fault_status, iommu->reg + DMAR_FSTS_REG); - - spin_unlock_irqrestore(&iommu->register_lock, flag); - return IRQ_HANDLED; -} - -int dmar_set_interrupt(struct intel_iommu *iommu) -{ - int irq, ret; - - /* - * Check if the fault interrupt is already initialized. - */ - if (iommu->irq) - return 0; - - irq = create_irq(); - if (!irq) { - printk(KERN_ERR "IOMMU: no free vectors\n"); - return -EINVAL; - } - - set_irq_data(irq, iommu); - iommu->irq = irq; - - ret = arch_setup_dmar_msi(irq); - if (ret) { - set_irq_data(irq, NULL); - iommu->irq = 0; - destroy_irq(irq); - return 0; - } - - ret = request_irq(irq, dmar_fault, 0, iommu->name, iommu); - if (ret) - printk(KERN_ERR "IOMMU: can't request irq\n"); - return ret; -} - -int __init enable_drhd_fault_handling(void) -{ - struct dmar_drhd_unit *drhd; - - /* - * Enable fault control interrupt. - */ - for_each_drhd_unit(drhd) { - int ret; - struct intel_iommu *iommu = drhd->iommu; - ret = dmar_set_interrupt(iommu); - - if (ret) { - printk(KERN_ERR "DRHD %Lx: failed to enable fault, " - " interrupt, ret %d\n", - (unsigned long long)drhd->reg_base_addr, ret); - return -1; - } - } - - return 0; -} diff --git a/trunk/drivers/pci/hotplug/acpi_pcihp.c b/trunk/drivers/pci/hotplug/acpi_pcihp.c index fbc63d5e459f..1c1141801060 100644 --- a/trunk/drivers/pci/hotplug/acpi_pcihp.c +++ b/trunk/drivers/pci/hotplug/acpi_pcihp.c @@ -30,8 +30,9 @@ #include #include #include -#include #include +#include +#include #define MY_NAME "acpi_pcihp" @@ -332,14 +333,19 @@ acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus, { acpi_status status = AE_NOT_FOUND; acpi_handle handle, phandle; - struct pci_bus *pbus; - - handle = NULL; - for (pbus = bus; pbus; pbus = pbus->parent) { - handle = acpi_pci_get_bridge_handle(pbus); - if (handle) + struct pci_bus *pbus = bus; + struct pci_dev *pdev; + + do { + pdev = pbus->self; + if (!pdev) { + handle = acpi_get_pci_rootbridge_handle( + pci_domain_nr(pbus), pbus->number); break; - } + } + handle = DEVICE_ACPI_HANDLE(&(pdev->dev)); + pbus = pbus->parent; + } while (!handle); /* * _HPP settings apply to all child buses, until another _HPP is @@ -372,10 +378,12 @@ EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware); * * Attempt to take hotplug control from firmware. */ -int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) +int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags) { acpi_status status; acpi_handle chandle, handle; + struct pci_dev *pdev = dev; + struct pci_bus *parent; struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; flags &= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | @@ -400,25 +408,33 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); dbg("Trying to get hotplug control for %s\n", (char *)string.pointer); - status = acpi_pci_osc_control_set(handle, flags); + status = pci_osc_control_set(handle, flags); if (ACPI_SUCCESS(status)) goto got_one; kfree(string.pointer); string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL }; } - handle = DEVICE_ACPI_HANDLE(&pdev->dev); - if (!handle) { + pdev = dev; + handle = DEVICE_ACPI_HANDLE(&dev->dev); + while (!handle) { /* * This hotplug controller was not listed in the ACPI name * space at all. Try to get acpi handle of parent pci bus. */ - struct pci_bus *pbus; - for (pbus = pdev->bus; pbus; pbus = pbus->parent) { - handle = acpi_pci_get_bridge_handle(pbus); - if (handle) - break; - } + if (!pdev || !pdev->bus->parent) + break; + parent = pdev->bus->parent; + dbg("Could not find %s in acpi namespace, trying parent\n", + pci_name(pdev)); + if (!parent->self) + /* Parent must be a host bridge */ + handle = acpi_get_pci_rootbridge_handle( + pci_domain_nr(parent), + parent->number); + else + handle = DEVICE_ACPI_HANDLE(&(parent->self->dev)); + pdev = parent->self; } while (handle) { @@ -437,13 +453,13 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) } dbg("Cannot get control of hotplug hardware for pci %s\n", - pci_name(pdev)); + pci_name(dev)); kfree(string.pointer); return -ENODEV; got_one: - dbg("Gained control for hotplug HW for pci %s (%s)\n", - pci_name(pdev), (char *)string.pointer); + dbg("Gained control for hotplug HW for pci %s (%s)\n", pci_name(dev), + (char *)string.pointer); kfree(string.pointer); return 0; } diff --git a/trunk/drivers/pci/hotplug/fakephp.c b/trunk/drivers/pci/hotplug/fakephp.c index 6151389fd903..d8649e127298 100644 --- a/trunk/drivers/pci/hotplug/fakephp.c +++ b/trunk/drivers/pci/hotplug/fakephp.c @@ -1,163 +1,395 @@ -/* Works like the fakephp driver used to, except a little better. +/* + * Fake PCI Hot Plug Controller Driver * - * - It's possible to remove devices with subordinate busses. - * - New PCI devices that appear via any method, not just a fakephp triggered - * rescan, will be noticed. - * - Devices that are removed via any method, not just a fakephp triggered - * removal, will also be noticed. + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003 IBM Corp. + * Copyright (C) 2003 Rolf Eike Beer * - * Uses nothing from the pci-hotplug subsystem. + * Based on ideas and code from: + * Vladimir Kondratiev + * Rolf Eike Beer * + * 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 of the License. + * + * Send feedback to */ -#include +/* + * + * This driver will "emulate" removing PCI devices from the system. If + * the "power" file is written to with "0" then the specified PCI device + * will be completely removed from the kernel. + * + * WARNING, this does NOT turn off the power to the PCI device. This is + * a "logical" removal, not a physical or electrical removal. + * + * Use this module at your own risk, you have been warned! + * + * Enabling PCI devices is left as an exercise for the reader... + * + */ #include -#include -#include -#include -#include -#include +#include #include -#include +#include +#include +#include +#include +#include #include "../pci.h" -struct legacy_slot { - struct kobject kobj; - struct pci_dev *dev; - struct list_head list; +#if !defined(MODULE) + #define MY_NAME "fakephp" +#else + #define MY_NAME THIS_MODULE->name +#endif + +#define dbg(format, arg...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG "%s: " format, \ + MY_NAME , ## arg); \ + } while (0) +#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg) +#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) + +#define DRIVER_AUTHOR "Greg Kroah-Hartman " +#define DRIVER_DESC "Fake PCI Hot Plug Controller Driver" + +struct dummy_slot { + struct list_head node; + struct hotplug_slot *slot; + struct pci_dev *dev; + struct work_struct remove_work; + unsigned long removed; }; -static LIST_HEAD(legacy_list); +static int debug; +static int dup_slots; +static LIST_HEAD(slot_list); +static struct workqueue_struct *dummyphp_wq; -static ssize_t legacy_show(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj); - strcpy(buf, "1\n"); - return 2; -} +static void pci_rescan_worker(struct work_struct *work); +static DECLARE_WORK(pci_rescan_work, pci_rescan_worker); -static void remove_callback(void *data) +static int enable_slot (struct hotplug_slot *slot); +static int disable_slot (struct hotplug_slot *slot); + +static struct hotplug_slot_ops dummy_hotplug_slot_ops = { + .owner = THIS_MODULE, + .enable_slot = enable_slot, + .disable_slot = disable_slot, +}; + +static void dummy_release(struct hotplug_slot *slot) { - pci_remove_bus_device((struct pci_dev *)data); + struct dummy_slot *dslot = slot->private; + + list_del(&dslot->node); + kfree(dslot->slot->info); + kfree(dslot->slot); + pci_dev_put(dslot->dev); + kfree(dslot); } -static ssize_t legacy_store(struct kobject *kobj, struct attribute *attr, - const char *buf, size_t len) +#define SLOT_NAME_SIZE 8 + +static int add_slot(struct pci_dev *dev) { - struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj); - unsigned long val; + struct dummy_slot *dslot; + struct hotplug_slot *slot; + char name[SLOT_NAME_SIZE]; + int retval = -ENOMEM; + static int count = 1; - if (strict_strtoul(buf, 0, &val) < 0) - return -EINVAL; + slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); + if (!slot) + goto error; + + slot->info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); + if (!slot->info) + goto error_slot; + + slot->info->power_status = 1; + slot->info->max_bus_speed = PCI_SPEED_UNKNOWN; + slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN; - if (val) - pci_rescan_bus(slot->dev->bus); + dslot = kzalloc(sizeof(struct dummy_slot), GFP_KERNEL); + if (!dslot) + goto error_info; + + if (dup_slots) + snprintf(name, SLOT_NAME_SIZE, "fake"); else - sysfs_schedule_callback(&slot->dev->dev.kobj, remove_callback, - slot->dev, THIS_MODULE); - return len; + snprintf(name, SLOT_NAME_SIZE, "fake%d", count++); + dbg("slot->name = %s\n", name); + slot->ops = &dummy_hotplug_slot_ops; + slot->release = &dummy_release; + slot->private = dslot; + + retval = pci_hp_register(slot, dev->bus, PCI_SLOT(dev->devfn), name); + if (retval) { + err("pci_hp_register failed with error %d\n", retval); + goto error_dslot; + } + + dbg("slot->name = %s\n", hotplug_slot_name(slot)); + dslot->slot = slot; + dslot->dev = pci_dev_get(dev); + list_add (&dslot->node, &slot_list); + return retval; + +error_dslot: + kfree(dslot); +error_info: + kfree(slot->info); +error_slot: + kfree(slot); +error: + return retval; } -static struct attribute *legacy_attrs[] = { - &(struct attribute){ .name = "power", .mode = 0644 }, - NULL, -}; +static int __init pci_scan_buses(void) +{ + struct pci_dev *dev = NULL; + int lastslot = 0; -static void legacy_release(struct kobject *kobj) + while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + if (PCI_FUNC(dev->devfn) > 0 && + lastslot == PCI_SLOT(dev->devfn)) + continue; + lastslot = PCI_SLOT(dev->devfn); + add_slot(dev); + } + + return 0; +} + +static void remove_slot(struct dummy_slot *dslot) { - struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj); + int retval; - pci_dev_put(slot->dev); - kfree(slot); + dbg("removing slot %s\n", hotplug_slot_name(dslot->slot)); + retval = pci_hp_deregister(dslot->slot); + if (retval) + err("Problem unregistering a slot %s\n", + hotplug_slot_name(dslot->slot)); } -static struct kobj_type legacy_ktype = { - .sysfs_ops = &(struct sysfs_ops){ - .store = legacy_store, .show = legacy_show - }, - .release = &legacy_release, - .default_attrs = legacy_attrs, -}; +/* called from the single-threaded workqueue handler to remove a slot */ +static void remove_slot_worker(struct work_struct *work) +{ + struct dummy_slot *dslot = + container_of(work, struct dummy_slot, remove_work); + remove_slot(dslot); +} -static int legacy_add_slot(struct pci_dev *pdev) +/** + * pci_rescan_slot - Rescan slot + * @temp: Device template. Should be set: bus and devfn. + * + * Tries hard not to re-enable already existing devices; + * also handles scanning of subfunctions. + */ +static int pci_rescan_slot(struct pci_dev *temp) { - struct legacy_slot *slot = kzalloc(sizeof(*slot), GFP_KERNEL); + struct pci_bus *bus = temp->bus; + struct pci_dev *dev; + int func; + u8 hdr_type; + int count = 0; - if (!slot) - return -ENOMEM; + if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { + temp->hdr_type = hdr_type & 0x7f; + if ((dev = pci_get_slot(bus, temp->devfn)) != NULL) + pci_dev_put(dev); + else { + dev = pci_scan_single_device(bus, temp->devfn); + if (dev) { + dbg("New device on %s function %x:%x\n", + bus->name, temp->devfn >> 3, + temp->devfn & 7); + count++; + } + } + /* multifunction device? */ + if (!(hdr_type & 0x80)) + return count; - if (kobject_init_and_add(&slot->kobj, &legacy_ktype, - &pci_slots_kset->kobj, "%s", - dev_name(&pdev->dev))) { - dev_warn(&pdev->dev, "Failed to created legacy fake slot\n"); - return -EINVAL; - } - slot->dev = pci_dev_get(pdev); + /* continue scanning for other functions */ + for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) { + if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) + continue; + temp->hdr_type = hdr_type & 0x7f; - list_add(&slot->list, &legacy_list); + if ((dev = pci_get_slot(bus, temp->devfn)) != NULL) + pci_dev_put(dev); + else { + dev = pci_scan_single_device(bus, temp->devfn); + if (dev) { + dbg("New device on %s function %x:%x\n", + bus->name, temp->devfn >> 3, + temp->devfn & 7); + count++; + } + } + } + } - return 0; + return count; } -static int legacy_notify(struct notifier_block *nb, - unsigned long action, void *data) + +/** + * pci_rescan_bus - Rescan PCI bus + * @bus: the PCI bus to rescan + * + * Call pci_rescan_slot for each possible function of the bus. + */ +static void pci_rescan_bus(const struct pci_bus *bus) { - struct pci_dev *pdev = to_pci_dev(data); + unsigned int devfn; + struct pci_dev *dev; + int retval; + int found = 0; + dev = alloc_pci_dev(); + if (!dev) + return; - if (action == BUS_NOTIFY_ADD_DEVICE) { - legacy_add_slot(pdev); - } else if (action == BUS_NOTIFY_DEL_DEVICE) { - struct legacy_slot *slot; + dev->bus = (struct pci_bus*)bus; + dev->sysdata = bus->sysdata; + for (devfn = 0; devfn < 0x100; devfn += 8) { + dev->devfn = devfn; + found += pci_rescan_slot(dev); + } - list_for_each_entry(slot, &legacy_list, list) - if (slot->dev == pdev) - goto found; + if (found) { + pci_bus_assign_resources(bus); + list_for_each_entry(dev, &bus->devices, bus_list) { + /* Skip already-added devices */ + if (dev->is_added) + continue; + retval = pci_bus_add_device(dev); + if (retval) + dev_err(&dev->dev, + "Error adding device, continuing\n"); + else + add_slot(dev); + } + pci_bus_add_devices(bus); + } + kfree(dev); +} - dev_warn(&pdev->dev, "Missing legacy fake slot?"); - return -ENODEV; -found: - kobject_del(&slot->kobj); - list_del(&slot->list); - kobject_put(&slot->kobj); +/* recursively scan all buses */ +static void pci_rescan_buses(const struct list_head *list) +{ + const struct list_head *l; + list_for_each(l,list) { + const struct pci_bus *b = pci_bus_b(l); + pci_rescan_bus(b); + pci_rescan_buses(&b->children); } +} - return 0; +/* initiate rescan of all pci buses */ +static inline void pci_rescan(void) { + pci_rescan_buses(&pci_root_buses); } -static struct notifier_block legacy_notifier = { - .notifier_call = legacy_notify -}; +/* called from the single-threaded workqueue handler to rescan all pci buses */ +static void pci_rescan_worker(struct work_struct *work) +{ + pci_rescan(); +} + +static int enable_slot(struct hotplug_slot *hotplug_slot) +{ + /* mis-use enable_slot for rescanning of the pci bus */ + cancel_work_sync(&pci_rescan_work); + queue_work(dummyphp_wq, &pci_rescan_work); + return 0; +} -static int __init init_legacy(void) +static int disable_slot(struct hotplug_slot *slot) { - struct pci_dev *pdev = NULL; + struct dummy_slot *dslot; + struct pci_dev *dev; + int func; + + if (!slot) + return -ENODEV; + dslot = slot->private; + + dbg("%s - physical_slot = %s\n", __func__, hotplug_slot_name(slot)); - /* Add existing devices */ - while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) - legacy_add_slot(pdev); + for (func = 7; func >= 0; func--) { + dev = pci_get_slot(dslot->dev->bus, dslot->dev->devfn + func); + if (!dev) + continue; - /* Be alerted of any new ones */ - bus_register_notifier(&pci_bus_type, &legacy_notifier); + if (test_and_set_bit(0, &dslot->removed)) { + dbg("Slot already scheduled for removal\n"); + pci_dev_put(dev); + return -ENODEV; + } + + /* remove the device from the pci core */ + pci_remove_bus_device(dev); + + /* queue work item to blow away this sysfs entry and other + * parts. + */ + INIT_WORK(&dslot->remove_work, remove_slot_worker); + queue_work(dummyphp_wq, &dslot->remove_work); + + pci_dev_put(dev); + } return 0; } -module_init(init_legacy); -static void __exit remove_legacy(void) +static void cleanup_slots (void) { - struct legacy_slot *slot, *tmp; - - bus_unregister_notifier(&pci_bus_type, &legacy_notifier); + struct list_head *tmp; + struct list_head *next; + struct dummy_slot *dslot; - list_for_each_entry_safe(slot, tmp, &legacy_list, list) { - list_del(&slot->list); - kobject_del(&slot->kobj); - kobject_put(&slot->kobj); + destroy_workqueue(dummyphp_wq); + list_for_each_safe (tmp, next, &slot_list) { + dslot = list_entry (tmp, struct dummy_slot, node); + remove_slot(dslot); } + +} + +static int __init dummyphp_init(void) +{ + info(DRIVER_DESC "\n"); + + dummyphp_wq = create_singlethread_workqueue(MY_NAME); + if (!dummyphp_wq) + return -ENOMEM; + + return pci_scan_buses(); +} + + +static void __exit dummyphp_exit(void) +{ + cleanup_slots(); } -module_exit(remove_legacy); +module_init(dummyphp_init); +module_exit(dummyphp_exit); -MODULE_AUTHOR("Trent Piepho "); -MODULE_DESCRIPTION("Legacy version of the fakephp interface"); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); +module_param(dup_slots, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(dup_slots, "Force duplicate slot names for debugging"); diff --git a/trunk/drivers/pci/hotplug/pciehp.h b/trunk/drivers/pci/hotplug/pciehp.h index 0a368547e633..39ae37589fda 100644 --- a/trunk/drivers/pci/hotplug/pciehp.h +++ b/trunk/drivers/pci/hotplug/pciehp.h @@ -46,10 +46,10 @@ extern int pciehp_force; extern struct workqueue_struct *pciehp_wq; #define dbg(format, arg...) \ -do { \ - if (pciehp_debug) \ - printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); \ -} while (0) + do { \ + if (pciehp_debug) \ + printk("%s: " format, MY_NAME , ## arg); \ + } while (0) #define err(format, arg...) \ printk(KERN_ERR "%s: " format, MY_NAME , ## arg) #define info(format, arg...) \ @@ -60,7 +60,7 @@ do { \ #define ctrl_dbg(ctrl, format, arg...) \ do { \ if (pciehp_debug) \ - dev_printk(KERN_DEBUG, &ctrl->pcie->device, \ + dev_printk(, &ctrl->pcie->device, \ format, ## arg); \ } while (0) #define ctrl_err(ctrl, format, arg...) \ @@ -108,11 +108,10 @@ struct controller { u32 slot_cap; u8 cap_base; struct timer_list poll_timer; - unsigned int cmd_busy:1; + int cmd_busy; unsigned int no_cmd_complete:1; unsigned int link_active_reporting:1; unsigned int notification_enabled:1; - unsigned int power_fault_detected; }; #define INT_BUTTON_IGNORE 0 diff --git a/trunk/drivers/pci/hotplug/pciehp_acpi.c b/trunk/drivers/pci/hotplug/pciehp_acpi.c index 96048010e7d9..438d795f9fe3 100644 --- a/trunk/drivers/pci/hotplug/pciehp_acpi.c +++ b/trunk/drivers/pci/hotplug/pciehp_acpi.c @@ -67,27 +67,37 @@ static int __init parse_detect_mode(void) return PCIEHP_DETECT_DEFAULT; } +static struct pcie_port_service_id __initdata port_pci_ids[] = { + { + .vendor = PCI_ANY_ID, + .device = PCI_ANY_ID, + .port_type = PCIE_ANY_PORT, + .service_type = PCIE_PORT_SERVICE_HP, + .driver_data = 0, + }, { /* end: all zeroes */ } +}; + static int __initdata dup_slot_id; static int __initdata acpi_slot_detected; static struct list_head __initdata dummy_slots = LIST_HEAD_INIT(dummy_slots); /* Dummy driver for dumplicate name detection */ -static int __init dummy_probe(struct pcie_device *dev) +static int __init dummy_probe(struct pcie_device *dev, + const struct pcie_port_service_id *id) { int pos; u32 slot_cap; struct slot *slot, *tmp; struct pci_dev *pdev = dev->port; struct pci_bus *pbus = pdev->subordinate; + if (!(slot = kzalloc(sizeof(*slot), GFP_KERNEL))) + return -ENOMEM; /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ if (pciehp_get_hp_hw_control_from_firmware(pdev)) return -ENODEV; if (!(pos = pci_find_capability(pdev, PCI_CAP_ID_EXP))) return -ENODEV; pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap); - slot = kzalloc(sizeof(*slot), GFP_KERNEL); - if (!slot) - return -ENOMEM; slot->number = slot_cap >> 19; list_for_each_entry(tmp, &dummy_slots, slot_list) { if (tmp->number == slot->number) @@ -101,8 +111,7 @@ static int __init dummy_probe(struct pcie_device *dev) static struct pcie_port_service_driver __initdata dummy_driver = { .name = "pciehp_dummy", - .port_type = PCIE_ANY_PORT, - .service = PCIE_PORT_SERVICE_HP, + .id_table = port_pci_ids, .probe = dummy_probe, }; diff --git a/trunk/drivers/pci/hotplug/pciehp_core.c b/trunk/drivers/pci/hotplug/pciehp_core.c index fb254b2454de..681e3912b821 100644 --- a/trunk/drivers/pci/hotplug/pciehp_core.c +++ b/trunk/drivers/pci/hotplug/pciehp_core.c @@ -401,7 +401,7 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe return 0; } -static int pciehp_probe(struct pcie_device *dev) +static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_id *id) { int rc; struct controller *ctrl; @@ -475,7 +475,7 @@ static void pciehp_remove (struct pcie_device *dev) } #ifdef CONFIG_PM -static int pciehp_suspend (struct pcie_device *dev) +static int pciehp_suspend (struct pcie_device *dev, pm_message_t state) { dev_info(&dev->device, "%s ENTRY\n", __func__); return 0; @@ -503,12 +503,20 @@ static int pciehp_resume (struct pcie_device *dev) } return 0; } -#endif /* PM */ +#endif + +static struct pcie_port_service_id port_pci_ids[] = { { + .vendor = PCI_ANY_ID, + .device = PCI_ANY_ID, + .port_type = PCIE_ANY_PORT, + .service_type = PCIE_PORT_SERVICE_HP, + .driver_data = 0, + }, { /* end: all zeroes */ } +}; static struct pcie_port_service_driver hpdriver_portdrv = { .name = PCIE_MODULE_NAME, - .port_type = PCIE_ANY_PORT, - .service = PCIE_PORT_SERVICE_HP, + .id_table = &port_pci_ids[0], .probe = pciehp_probe, .remove = pciehp_remove, diff --git a/trunk/drivers/pci/hotplug/pciehp_hpc.c b/trunk/drivers/pci/hotplug/pciehp_hpc.c index 07bd32151146..7a16c6897bb9 100644 --- a/trunk/drivers/pci/hotplug/pciehp_hpc.c +++ b/trunk/drivers/pci/hotplug/pciehp_hpc.c @@ -548,21 +548,23 @@ static int hpc_power_on_slot(struct slot * slot) slot_cmd = POWER_ON; cmd_mask = PCI_EXP_SLTCTL_PCC; + /* Enable detection that we turned off at slot power-off time */ if (!pciehp_poll_mode) { - /* Enable power fault detection turned off at power off time */ - slot_cmd |= PCI_EXP_SLTCTL_PFDE; - cmd_mask |= PCI_EXP_SLTCTL_PFDE; + slot_cmd |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE | + PCI_EXP_SLTCTL_PDCE); + cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE | + PCI_EXP_SLTCTL_PDCE); } retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); + if (retval) { ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd); - return retval; + return -1; } ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); - ctrl->power_fault_detected = 0; return retval; } @@ -619,10 +621,18 @@ static int hpc_power_off_slot(struct slot * slot) slot_cmd = POWER_OFF; cmd_mask = PCI_EXP_SLTCTL_PCC; + /* + * If we get MRL or presence detect interrupts now, the isr + * will notice the sticky power-fault bit too and issue power + * indicator change commands. This will lead to an endless loop + * of command completions, since the power-fault bit remains on + * till the slot is powered on again. + */ if (!pciehp_poll_mode) { - /* Disable power fault detection */ - slot_cmd &= ~PCI_EXP_SLTCTL_PFDE; - cmd_mask |= PCI_EXP_SLTCTL_PFDE; + slot_cmd &= ~(PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE | + PCI_EXP_SLTCTL_PDCE); + cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE | + PCI_EXP_SLTCTL_PDCE); } retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); @@ -662,11 +672,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_CC); - detected &= ~intr_loc; intr_loc |= detected; if (!intr_loc) return IRQ_NONE; - if (detected && pciehp_writew(ctrl, PCI_EXP_SLTSTA, intr_loc)) { + if (detected && pciehp_writew(ctrl, PCI_EXP_SLTSTA, detected)) { ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n", __func__); return IRQ_NONE; @@ -700,10 +709,9 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) pciehp_handle_presence_change(p_slot); /* Check Power Fault Detected */ - if ((intr_loc & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) { - ctrl->power_fault_detected = 1; + if (intr_loc & PCI_EXP_SLTSTA_PFD) pciehp_handle_power_fault(p_slot); - } + return IRQ_HANDLED; } diff --git a/trunk/drivers/pci/hotplug/shpchp.h b/trunk/drivers/pci/hotplug/shpchp.h index 974e924ca96d..6aba0b6cf2e0 100644 --- a/trunk/drivers/pci/hotplug/shpchp.h +++ b/trunk/drivers/pci/hotplug/shpchp.h @@ -48,10 +48,10 @@ extern int shpchp_debug; extern struct workqueue_struct *shpchp_wq; #define dbg(format, arg...) \ -do { \ - if (shpchp_debug) \ - printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); \ -} while (0) + do { \ + if (shpchp_debug) \ + printk("%s: " format, MY_NAME , ## arg); \ + } while (0) #define err(format, arg...) \ printk(KERN_ERR "%s: " format, MY_NAME , ## arg) #define info(format, arg...) \ @@ -62,7 +62,7 @@ do { \ #define ctrl_dbg(ctrl, format, arg...) \ do { \ if (shpchp_debug) \ - dev_printk(KERN_DEBUG, &ctrl->pci_dev->dev, \ + dev_printk(, &ctrl->pci_dev->dev, \ format, ## arg); \ } while (0) #define ctrl_err(ctrl, format, arg...) \ diff --git a/trunk/drivers/pci/hotplug/shpchp_pci.c b/trunk/drivers/pci/hotplug/shpchp_pci.c index aa315e52529b..138f161becc0 100644 --- a/trunk/drivers/pci/hotplug/shpchp_pci.c +++ b/trunk/drivers/pci/hotplug/shpchp_pci.c @@ -137,7 +137,7 @@ int __ref shpchp_configure_device(struct slot *p_slot) busnr)) break; } - if (busnr > end) { + if (busnr >= end) { ctrl_err(ctrl, "No free bus for hot-added bridge\n"); pci_dev_put(dev); diff --git a/trunk/drivers/pci/intel-iommu.c b/trunk/drivers/pci/intel-iommu.c index 9dbd5066acaf..f3f686581a90 100644 --- a/trunk/drivers/pci/intel-iommu.c +++ b/trunk/drivers/pci/intel-iommu.c @@ -1004,6 +1004,194 @@ static int iommu_disable_translation(struct intel_iommu *iommu) return 0; } +/* iommu interrupt handling. Most stuff are MSI-like. */ + +static const char *fault_reason_strings[] = +{ + "Software", + "Present bit in root entry is clear", + "Present bit in context entry is clear", + "Invalid context entry", + "Access beyond MGAW", + "PTE Write access is not set", + "PTE Read access is not set", + "Next page table ptr is invalid", + "Root table address invalid", + "Context table ptr is invalid", + "non-zero reserved fields in RTP", + "non-zero reserved fields in CTP", + "non-zero reserved fields in PTE", +}; +#define MAX_FAULT_REASON_IDX (ARRAY_SIZE(fault_reason_strings) - 1) + +const char *dmar_get_fault_reason(u8 fault_reason) +{ + if (fault_reason > MAX_FAULT_REASON_IDX) + return "Unknown"; + else + return fault_reason_strings[fault_reason]; +} + +void dmar_msi_unmask(unsigned int irq) +{ + struct intel_iommu *iommu = get_irq_data(irq); + unsigned long flag; + + /* unmask it */ + spin_lock_irqsave(&iommu->register_lock, flag); + writel(0, iommu->reg + DMAR_FECTL_REG); + /* Read a reg to force flush the post write */ + readl(iommu->reg + DMAR_FECTL_REG); + spin_unlock_irqrestore(&iommu->register_lock, flag); +} + +void dmar_msi_mask(unsigned int irq) +{ + unsigned long flag; + struct intel_iommu *iommu = get_irq_data(irq); + + /* mask it */ + spin_lock_irqsave(&iommu->register_lock, flag); + writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG); + /* Read a reg to force flush the post write */ + readl(iommu->reg + DMAR_FECTL_REG); + spin_unlock_irqrestore(&iommu->register_lock, flag); +} + +void dmar_msi_write(int irq, struct msi_msg *msg) +{ + struct intel_iommu *iommu = get_irq_data(irq); + unsigned long flag; + + spin_lock_irqsave(&iommu->register_lock, flag); + writel(msg->data, iommu->reg + DMAR_FEDATA_REG); + writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG); + writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG); + spin_unlock_irqrestore(&iommu->register_lock, flag); +} + +void dmar_msi_read(int irq, struct msi_msg *msg) +{ + struct intel_iommu *iommu = get_irq_data(irq); + unsigned long flag; + + spin_lock_irqsave(&iommu->register_lock, flag); + msg->data = readl(iommu->reg + DMAR_FEDATA_REG); + msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG); + msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG); + spin_unlock_irqrestore(&iommu->register_lock, flag); +} + +static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type, + u8 fault_reason, u16 source_id, unsigned long long addr) +{ + const char *reason; + + reason = dmar_get_fault_reason(fault_reason); + + printk(KERN_ERR + "DMAR:[%s] Request device [%02x:%02x.%d] " + "fault addr %llx \n" + "DMAR:[fault reason %02d] %s\n", + (type ? "DMA Read" : "DMA Write"), + (source_id >> 8), PCI_SLOT(source_id & 0xFF), + PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason); + return 0; +} + +#define PRIMARY_FAULT_REG_LEN (16) +static irqreturn_t iommu_page_fault(int irq, void *dev_id) +{ + struct intel_iommu *iommu = dev_id; + int reg, fault_index; + u32 fault_status; + unsigned long flag; + + spin_lock_irqsave(&iommu->register_lock, flag); + fault_status = readl(iommu->reg + DMAR_FSTS_REG); + + /* TBD: ignore advanced fault log currently */ + if (!(fault_status & DMA_FSTS_PPF)) + goto clear_overflow; + + fault_index = dma_fsts_fault_record_index(fault_status); + reg = cap_fault_reg_offset(iommu->cap); + while (1) { + u8 fault_reason; + u16 source_id; + u64 guest_addr; + int type; + u32 data; + + /* highest 32 bits */ + data = readl(iommu->reg + reg + + fault_index * PRIMARY_FAULT_REG_LEN + 12); + if (!(data & DMA_FRCD_F)) + break; + + fault_reason = dma_frcd_fault_reason(data); + type = dma_frcd_type(data); + + data = readl(iommu->reg + reg + + fault_index * PRIMARY_FAULT_REG_LEN + 8); + source_id = dma_frcd_source_id(data); + + guest_addr = dmar_readq(iommu->reg + reg + + fault_index * PRIMARY_FAULT_REG_LEN); + guest_addr = dma_frcd_page_addr(guest_addr); + /* clear the fault */ + writel(DMA_FRCD_F, iommu->reg + reg + + fault_index * PRIMARY_FAULT_REG_LEN + 12); + + spin_unlock_irqrestore(&iommu->register_lock, flag); + + iommu_page_fault_do_one(iommu, type, fault_reason, + source_id, guest_addr); + + fault_index++; + if (fault_index > cap_num_fault_regs(iommu->cap)) + fault_index = 0; + spin_lock_irqsave(&iommu->register_lock, flag); + } +clear_overflow: + /* clear primary fault overflow */ + fault_status = readl(iommu->reg + DMAR_FSTS_REG); + if (fault_status & DMA_FSTS_PFO) + writel(DMA_FSTS_PFO, iommu->reg + DMAR_FSTS_REG); + + spin_unlock_irqrestore(&iommu->register_lock, flag); + return IRQ_HANDLED; +} + +int dmar_set_interrupt(struct intel_iommu *iommu) +{ + int irq, ret; + + irq = create_irq(); + if (!irq) { + printk(KERN_ERR "IOMMU: no free vectors\n"); + return -EINVAL; + } + + set_irq_data(irq, iommu); + iommu->irq = irq; + + ret = arch_setup_dmar_msi(irq); + if (ret) { + set_irq_data(irq, NULL); + iommu->irq = 0; + destroy_irq(irq); + return 0; + } + + /* Force fault register is cleared */ + iommu_page_fault(irq, iommu); + + ret = request_irq(irq, iommu_page_fault, 0, iommu->name, iommu); + if (ret) + printk(KERN_ERR "IOMMU: can't request irq\n"); + return ret; +} static int iommu_init_domains(struct intel_iommu *iommu) { @@ -1782,7 +1970,7 @@ static inline void iommu_prepare_isa(void) ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024); if (ret) - printk(KERN_ERR "IOMMU: Failed to create 0-64M identity map, " + printk("IOMMU: Failed to create 0-64M identity map, " "floppy might not work\n"); } @@ -1799,7 +1987,7 @@ static int __init init_dmars(void) struct dmar_rmrr_unit *rmrr; struct pci_dev *pdev; struct intel_iommu *iommu; - int i, ret; + int i, ret, unit = 0; /* * for each drhd @@ -1855,40 +2043,11 @@ static int __init init_dmars(void) } } - /* - * Start from the sane iommu hardware state. - */ for_each_drhd_unit(drhd) { if (drhd->ignored) continue; iommu = drhd->iommu; - - /* - * If the queued invalidation is already initialized by us - * (for example, while enabling interrupt-remapping) then - * we got the things already rolling from a sane state. - */ - if (iommu->qi) - continue; - - /* - * Clear any previous faults. - */ - dmar_fault(-1, iommu); - /* - * Disable queued invalidation if supported and already enabled - * before OS handover. - */ - dmar_disable_qi(iommu); - } - - for_each_drhd_unit(drhd) { - if (drhd->ignored) - continue; - - iommu = drhd->iommu; - if (dmar_enable_qi(iommu)) { /* * Queued Invalidate not enabled, use Register Based @@ -1950,6 +2109,7 @@ static int __init init_dmars(void) if (drhd->ignored) continue; iommu = drhd->iommu; + sprintf (iommu->name, "dmar%d", unit++); iommu_flush_write_buffer(iommu); @@ -2124,13 +2284,11 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, return 0; } -static dma_addr_t intel_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) +dma_addr_t intel_map_single(struct device *hwdev, phys_addr_t paddr, + size_t size, int dir) { - return __intel_map_single(dev, page_to_phys(page) + offset, size, - dir, to_pci_dev(dev)->dma_mask); + return __intel_map_single(hwdev, paddr, size, dir, + to_pci_dev(hwdev)->dma_mask); } static void flush_unmaps(void) @@ -2194,9 +2352,8 @@ static void add_unmap(struct dmar_domain *dom, struct iova *iova) spin_unlock_irqrestore(&async_umap_flush_lock, flags); } -static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr, - size_t size, enum dma_data_direction dir, - struct dma_attrs *attrs) +void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size, + int dir) { struct pci_dev *pdev = to_pci_dev(dev); struct dmar_domain *domain; @@ -2240,14 +2397,8 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr, } } -static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size, - int dir) -{ - intel_unmap_page(dev, dev_addr, size, dir, NULL); -} - -static void *intel_alloc_coherent(struct device *hwdev, size_t size, - dma_addr_t *dma_handle, gfp_t flags) +void *intel_alloc_coherent(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, gfp_t flags) { void *vaddr; int order; @@ -2270,8 +2421,8 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size, return NULL; } -static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr, - dma_addr_t dma_handle) +void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr, + dma_addr_t dma_handle) { int order; @@ -2284,9 +2435,8 @@ static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr, #define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg))) -static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, - int nelems, enum dma_data_direction dir, - struct dma_attrs *attrs) +void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, + int nelems, int dir) { int i; struct pci_dev *pdev = to_pci_dev(hwdev); @@ -2343,8 +2493,8 @@ static int intel_nontranslate_map_sg(struct device *hddev, return nelems; } -static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, - enum dma_data_direction dir, struct dma_attrs *attrs) +int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, + int dir) { void *addr; int i; @@ -2424,19 +2574,13 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne return nelems; } -static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr) -{ - return !dma_addr; -} - -struct dma_map_ops intel_dma_ops = { +static struct dma_mapping_ops intel_dma_ops = { .alloc_coherent = intel_alloc_coherent, .free_coherent = intel_free_coherent, + .map_single = intel_map_single, + .unmap_single = intel_unmap_single, .map_sg = intel_map_sg, .unmap_sg = intel_unmap_sg, - .map_page = intel_map_page, - .unmap_page = intel_unmap_page, - .mapping_error = intel_mapping_error, }; static inline int iommu_domain_cache_init(void) diff --git a/trunk/drivers/pci/intr_remapping.c b/trunk/drivers/pci/intr_remapping.c index b041a409f4a7..9d07a05d26f1 100644 --- a/trunk/drivers/pci/intr_remapping.c +++ b/trunk/drivers/pci/intr_remapping.c @@ -117,22 +117,21 @@ int get_irte(int irq, struct irte *entry) { int index; struct irq_2_iommu *irq_iommu; - unsigned long flags; if (!entry) return -1; - spin_lock_irqsave(&irq_2_ir_lock, flags); + spin_lock(&irq_2_ir_lock); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); return -1; } index = irq_iommu->irte_index + irq_iommu->sub_handle; *entry = *(irq_iommu->iommu->ir_table->base + index); - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); return 0; } @@ -142,7 +141,6 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) struct irq_2_iommu *irq_iommu; u16 index, start_index; unsigned int mask = 0; - unsigned long flags; int i; if (!count) @@ -172,7 +170,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) return -1; } - spin_lock_irqsave(&irq_2_ir_lock, flags); + spin_lock(&irq_2_ir_lock); do { for (i = index; i < index + count; i++) if (table->base[i].present) @@ -184,7 +182,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) index = (index + count) % INTR_REMAP_TABLE_ENTRIES; if (index == start_index) { - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); printk(KERN_ERR "can't allocate an IRTE\n"); return -1; } @@ -195,7 +193,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) irq_iommu = irq_2_iommu_alloc(irq); if (!irq_iommu) { - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); printk(KERN_ERR "can't allocate irq_2_iommu\n"); return -1; } @@ -205,7 +203,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) irq_iommu->sub_handle = 0; irq_iommu->irte_mask = mask; - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); return index; } @@ -225,32 +223,30 @@ int map_irq_to_irte_handle(int irq, u16 *sub_handle) { int index; struct irq_2_iommu *irq_iommu; - unsigned long flags; - spin_lock_irqsave(&irq_2_ir_lock, flags); + spin_lock(&irq_2_ir_lock); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); return -1; } *sub_handle = irq_iommu->sub_handle; index = irq_iommu->irte_index; - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); return index; } int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) { struct irq_2_iommu *irq_iommu; - unsigned long flags; - spin_lock_irqsave(&irq_2_ir_lock, flags); + spin_lock(&irq_2_ir_lock); irq_iommu = irq_2_iommu_alloc(irq); if (!irq_iommu) { - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); printk(KERN_ERR "can't allocate irq_2_iommu\n"); return -1; } @@ -260,7 +256,7 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) irq_iommu->sub_handle = subhandle; irq_iommu->irte_mask = 0; - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); return 0; } @@ -268,12 +264,11 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index) { struct irq_2_iommu *irq_iommu; - unsigned long flags; - spin_lock_irqsave(&irq_2_ir_lock, flags); + spin_lock(&irq_2_ir_lock); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); return -1; } @@ -282,7 +277,7 @@ int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index) irq_iommu->sub_handle = 0; irq_2_iommu(irq)->irte_mask = 0; - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); return 0; } @@ -294,12 +289,11 @@ int modify_irte(int irq, struct irte *irte_modified) struct irte *irte; struct intel_iommu *iommu; struct irq_2_iommu *irq_iommu; - unsigned long flags; - spin_lock_irqsave(&irq_2_ir_lock, flags); + spin_lock(&irq_2_ir_lock); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); return -1; } @@ -308,11 +302,11 @@ int modify_irte(int irq, struct irte *irte_modified) index = irq_iommu->irte_index + irq_iommu->sub_handle; irte = &iommu->ir_table->base[index]; - set_64bit((unsigned long *)irte, irte_modified->low); + set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1)); __iommu_flush_cache(iommu, irte, sizeof(*irte)); rc = qi_flush_iec(iommu, index, 0); - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); return rc; } @@ -323,12 +317,11 @@ int flush_irte(int irq) int index; struct intel_iommu *iommu; struct irq_2_iommu *irq_iommu; - unsigned long flags; - spin_lock_irqsave(&irq_2_ir_lock, flags); + spin_lock(&irq_2_ir_lock); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); return -1; } @@ -337,7 +330,7 @@ int flush_irte(int irq) index = irq_iommu->irte_index + irq_iommu->sub_handle; rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask); - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); return rc; } @@ -370,12 +363,11 @@ int free_irte(int irq) struct irte *irte; struct intel_iommu *iommu; struct irq_2_iommu *irq_iommu; - unsigned long flags; - spin_lock_irqsave(&irq_2_ir_lock, flags); + spin_lock(&irq_2_ir_lock); irq_iommu = valid_irq_2_iommu(irq); if (!irq_iommu) { - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); return -1; } @@ -386,7 +378,7 @@ int free_irte(int irq) if (!irq_iommu->sub_handle) { for (i = 0; i < (1 << irq_iommu->irte_mask); i++) - set_64bit((unsigned long *)(irte + i), 0); + set_64bit((unsigned long *)irte, 0); rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask); } @@ -395,7 +387,7 @@ int free_irte(int irq) irq_iommu->sub_handle = 0; irq_iommu->irte_mask = 0; - spin_unlock_irqrestore(&irq_2_ir_lock, flags); + spin_unlock(&irq_2_ir_lock); return rc; } @@ -447,12 +439,12 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode) struct page *pages; ir_table = iommu->ir_table = kzalloc(sizeof(struct ir_table), - GFP_ATOMIC); + GFP_KERNEL); if (!iommu->ir_table) return -ENOMEM; - pages = alloc_pages(GFP_ATOMIC | __GFP_ZERO, INTR_REMAP_PAGE_ORDER); + pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, INTR_REMAP_PAGE_ORDER); if (!pages) { printk(KERN_ERR "failed to allocate pages of order %d\n", @@ -467,55 +459,11 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode) return 0; } -/* - * Disable Interrupt Remapping. - */ -static void disable_intr_remapping(struct intel_iommu *iommu) -{ - unsigned long flags; - u32 sts; - - if (!ecap_ir_support(iommu->ecap)) - return; - - spin_lock_irqsave(&iommu->register_lock, flags); - - sts = dmar_readq(iommu->reg + DMAR_GSTS_REG); - if (!(sts & DMA_GSTS_IRES)) - goto end; - - iommu->gcmd &= ~DMA_GCMD_IRE; - writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG); - - IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, - readl, !(sts & DMA_GSTS_IRES), sts); - -end: - spin_unlock_irqrestore(&iommu->register_lock, flags); -} - int __init enable_intr_remapping(int eim) { struct dmar_drhd_unit *drhd; int setup = 0; - for_each_drhd_unit(drhd) { - struct intel_iommu *iommu = drhd->iommu; - - /* - * Clear previous faults. - */ - dmar_fault(-1, iommu); - - /* - * Disable intr remapping and queued invalidation, if already - * enabled prior to OS handover. - */ - disable_intr_remapping(iommu); - - dmar_disable_qi(iommu); - } - /* * check for the Interrupt-remapping support */ diff --git a/trunk/drivers/pci/iov.c b/trunk/drivers/pci/iov.c deleted file mode 100644 index 7227efc760db..000000000000 --- a/trunk/drivers/pci/iov.c +++ /dev/null @@ -1,680 +0,0 @@ -/* - * drivers/pci/iov.c - * - * Copyright (C) 2009 Intel Corporation, Yu Zhao - * - * PCI Express I/O Virtualization (IOV) support. - * Single Root IOV 1.0 - */ - -#include -#include -#include -#include -#include "pci.h" - -#define VIRTFN_ID_LEN 16 - -static inline u8 virtfn_bus(struct pci_dev *dev, int id) -{ - return dev->bus->number + ((dev->devfn + dev->sriov->offset + - dev->sriov->stride * id) >> 8); -} - -static inline u8 virtfn_devfn(struct pci_dev *dev, int id) -{ - return (dev->devfn + dev->sriov->offset + - dev->sriov->stride * id) & 0xff; -} - -static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr) -{ - int rc; - struct pci_bus *child; - - if (bus->number == busnr) - return bus; - - child = pci_find_bus(pci_domain_nr(bus), busnr); - if (child) - return child; - - child = pci_add_new_bus(bus, NULL, busnr); - if (!child) - return NULL; - - child->subordinate = busnr; - child->dev.parent = bus->bridge; - rc = pci_bus_add_child(child); - if (rc) { - pci_remove_bus(child); - return NULL; - } - - return child; -} - -static void virtfn_remove_bus(struct pci_bus *bus, int busnr) -{ - struct pci_bus *child; - - if (bus->number == busnr) - return; - - child = pci_find_bus(pci_domain_nr(bus), busnr); - BUG_ON(!child); - - if (list_empty(&child->devices)) - pci_remove_bus(child); -} - -static int virtfn_add(struct pci_dev *dev, int id, int reset) -{ - int i; - int rc; - u64 size; - char buf[VIRTFN_ID_LEN]; - struct pci_dev *virtfn; - struct resource *res; - struct pci_sriov *iov = dev->sriov; - - virtfn = alloc_pci_dev(); - if (!virtfn) - return -ENOMEM; - - mutex_lock(&iov->dev->sriov->lock); - virtfn->bus = virtfn_add_bus(dev->bus, virtfn_bus(dev, id)); - if (!virtfn->bus) { - kfree(virtfn); - mutex_unlock(&iov->dev->sriov->lock); - return -ENOMEM; - } - virtfn->devfn = virtfn_devfn(dev, id); - virtfn->vendor = dev->vendor; - pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_DID, &virtfn->device); - pci_setup_device(virtfn); - virtfn->dev.parent = dev->dev.parent; - - for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { - res = dev->resource + PCI_IOV_RESOURCES + i; - if (!res->parent) - continue; - virtfn->resource[i].name = pci_name(virtfn); - virtfn->resource[i].flags = res->flags; - size = resource_size(res); - do_div(size, iov->total); - virtfn->resource[i].start = res->start + size * id; - virtfn->resource[i].end = virtfn->resource[i].start + size - 1; - rc = request_resource(res, &virtfn->resource[i]); - BUG_ON(rc); - } - - if (reset) - pci_execute_reset_function(virtfn); - - pci_device_add(virtfn, virtfn->bus); - mutex_unlock(&iov->dev->sriov->lock); - - virtfn->physfn = pci_dev_get(dev); - virtfn->is_virtfn = 1; - - rc = pci_bus_add_device(virtfn); - if (rc) - goto failed1; - sprintf(buf, "virtfn%u", id); - rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf); - if (rc) - goto failed1; - rc = sysfs_create_link(&virtfn->dev.kobj, &dev->dev.kobj, "physfn"); - if (rc) - goto failed2; - - kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE); - - return 0; - -failed2: - sysfs_remove_link(&dev->dev.kobj, buf); -failed1: - pci_dev_put(dev); - mutex_lock(&iov->dev->sriov->lock); - pci_remove_bus_device(virtfn); - virtfn_remove_bus(dev->bus, virtfn_bus(dev, id)); - mutex_unlock(&iov->dev->sriov->lock); - - return rc; -} - -static void virtfn_remove(struct pci_dev *dev, int id, int reset) -{ - char buf[VIRTFN_ID_LEN]; - struct pci_bus *bus; - struct pci_dev *virtfn; - struct pci_sriov *iov = dev->sriov; - - bus = pci_find_bus(pci_domain_nr(dev->bus), virtfn_bus(dev, id)); - if (!bus) - return; - - virtfn = pci_get_slot(bus, virtfn_devfn(dev, id)); - if (!virtfn) - return; - - pci_dev_put(virtfn); - - if (reset) { - device_release_driver(&virtfn->dev); - pci_execute_reset_function(virtfn); - } - - sprintf(buf, "virtfn%u", id); - sysfs_remove_link(&dev->dev.kobj, buf); - sysfs_remove_link(&virtfn->dev.kobj, "physfn"); - - mutex_lock(&iov->dev->sriov->lock); - pci_remove_bus_device(virtfn); - virtfn_remove_bus(dev->bus, virtfn_bus(dev, id)); - mutex_unlock(&iov->dev->sriov->lock); - - pci_dev_put(dev); -} - -static int sriov_migration(struct pci_dev *dev) -{ - u16 status; - struct pci_sriov *iov = dev->sriov; - - if (!iov->nr_virtfn) - return 0; - - if (!(iov->cap & PCI_SRIOV_CAP_VFM)) - return 0; - - pci_read_config_word(dev, iov->pos + PCI_SRIOV_STATUS, &status); - if (!(status & PCI_SRIOV_STATUS_VFM)) - return 0; - - schedule_work(&iov->mtask); - - return 1; -} - -static void sriov_migration_task(struct work_struct *work) -{ - int i; - u8 state; - u16 status; - struct pci_sriov *iov = container_of(work, struct pci_sriov, mtask); - - for (i = iov->initial; i < iov->nr_virtfn; i++) { - state = readb(iov->mstate + i); - if (state == PCI_SRIOV_VFM_MI) { - writeb(PCI_SRIOV_VFM_AV, iov->mstate + i); - state = readb(iov->mstate + i); - if (state == PCI_SRIOV_VFM_AV) - virtfn_add(iov->self, i, 1); - } else if (state == PCI_SRIOV_VFM_MO) { - virtfn_remove(iov->self, i, 1); - writeb(PCI_SRIOV_VFM_UA, iov->mstate + i); - state = readb(iov->mstate + i); - if (state == PCI_SRIOV_VFM_AV) - virtfn_add(iov->self, i, 0); - } - } - - pci_read_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, &status); - status &= ~PCI_SRIOV_STATUS_VFM; - pci_write_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, status); -} - -static int sriov_enable_migration(struct pci_dev *dev, int nr_virtfn) -{ - int bir; - u32 table; - resource_size_t pa; - struct pci_sriov *iov = dev->sriov; - - if (nr_virtfn <= iov->initial) - return 0; - - pci_read_config_dword(dev, iov->pos + PCI_SRIOV_VFM, &table); - bir = PCI_SRIOV_VFM_BIR(table); - if (bir > PCI_STD_RESOURCE_END) - return -EIO; - - table = PCI_SRIOV_VFM_OFFSET(table); - if (table + nr_virtfn > pci_resource_len(dev, bir)) - return -EIO; - - pa = pci_resource_start(dev, bir) + table; - iov->mstate = ioremap(pa, nr_virtfn); - if (!iov->mstate) - return -ENOMEM; - - INIT_WORK(&iov->mtask, sriov_migration_task); - - iov->ctrl |= PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR; - pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); - - return 0; -} - -static void sriov_disable_migration(struct pci_dev *dev) -{ - struct pci_sriov *iov = dev->sriov; - - iov->ctrl &= ~(PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR); - pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); - - cancel_work_sync(&iov->mtask); - iounmap(iov->mstate); -} - -static int sriov_enable(struct pci_dev *dev, int nr_virtfn) -{ - int rc; - int i, j; - int nres; - u16 offset, stride, initial; - struct resource *res; - struct pci_dev *pdev; - struct pci_sriov *iov = dev->sriov; - - if (!nr_virtfn) - return 0; - - if (iov->nr_virtfn) - return -EINVAL; - - pci_read_config_word(dev, iov->pos + PCI_SRIOV_INITIAL_VF, &initial); - if (initial > iov->total || - (!(iov->cap & PCI_SRIOV_CAP_VFM) && (initial != iov->total))) - return -EIO; - - if (nr_virtfn < 0 || nr_virtfn > iov->total || - (!(iov->cap & PCI_SRIOV_CAP_VFM) && (nr_virtfn > initial))) - return -EINVAL; - - pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, nr_virtfn); - pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_OFFSET, &offset); - pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_STRIDE, &stride); - if (!offset || (nr_virtfn > 1 && !stride)) - return -EIO; - - nres = 0; - for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { - res = dev->resource + PCI_IOV_RESOURCES + i; - if (res->parent) - nres++; - } - if (nres != iov->nres) { - dev_err(&dev->dev, "not enough MMIO resources for SR-IOV\n"); - return -ENOMEM; - } - - iov->offset = offset; - iov->stride = stride; - - if (virtfn_bus(dev, nr_virtfn - 1) > dev->bus->subordinate) { - dev_err(&dev->dev, "SR-IOV: bus number out of range\n"); - return -ENOMEM; - } - - if (iov->link != dev->devfn) { - pdev = pci_get_slot(dev->bus, iov->link); - if (!pdev) - return -ENODEV; - - pci_dev_put(pdev); - - if (!pdev->is_physfn) - return -ENODEV; - - rc = sysfs_create_link(&dev->dev.kobj, - &pdev->dev.kobj, "dep_link"); - if (rc) - return rc; - } - - iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE; - pci_block_user_cfg_access(dev); - pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); - msleep(100); - pci_unblock_user_cfg_access(dev); - - iov->initial = initial; - if (nr_virtfn < initial) - initial = nr_virtfn; - - for (i = 0; i < initial; i++) { - rc = virtfn_add(dev, i, 0); - if (rc) - goto failed; - } - - if (iov->cap & PCI_SRIOV_CAP_VFM) { - rc = sriov_enable_migration(dev, nr_virtfn); - if (rc) - goto failed; - } - - kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE); - iov->nr_virtfn = nr_virtfn; - - return 0; - -failed: - for (j = 0; j < i; j++) - virtfn_remove(dev, j, 0); - - iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); - pci_block_user_cfg_access(dev); - pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); - ssleep(1); - pci_unblock_user_cfg_access(dev); - - if (iov->link != dev->devfn) - sysfs_remove_link(&dev->dev.kobj, "dep_link"); - - return rc; -} - -static void sriov_disable(struct pci_dev *dev) -{ - int i; - struct pci_sriov *iov = dev->sriov; - - if (!iov->nr_virtfn) - return; - - if (iov->cap & PCI_SRIOV_CAP_VFM) - sriov_disable_migration(dev); - - for (i = 0; i < iov->nr_virtfn; i++) - virtfn_remove(dev, i, 0); - - iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); - pci_block_user_cfg_access(dev); - pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); - ssleep(1); - pci_unblock_user_cfg_access(dev); - - if (iov->link != dev->devfn) - sysfs_remove_link(&dev->dev.kobj, "dep_link"); - - iov->nr_virtfn = 0; -} - -static int sriov_init(struct pci_dev *dev, int pos) -{ - int i; - int rc; - int nres; - u32 pgsz; - u16 ctrl, total, offset, stride; - struct pci_sriov *iov; - struct resource *res; - struct pci_dev *pdev; - - if (dev->pcie_type != PCI_EXP_TYPE_RC_END && - dev->pcie_type != PCI_EXP_TYPE_ENDPOINT) - return -ENODEV; - - pci_read_config_word(dev, pos + PCI_SRIOV_CTRL, &ctrl); - if (ctrl & PCI_SRIOV_CTRL_VFE) { - pci_write_config_word(dev, pos + PCI_SRIOV_CTRL, 0); - ssleep(1); - } - - pci_read_config_word(dev, pos + PCI_SRIOV_TOTAL_VF, &total); - if (!total) - return 0; - - ctrl = 0; - list_for_each_entry(pdev, &dev->bus->devices, bus_list) - if (pdev->is_physfn) - goto found; - - pdev = NULL; - if (pci_ari_enabled(dev->bus)) - ctrl |= PCI_SRIOV_CTRL_ARI; - -found: - pci_write_config_word(dev, pos + PCI_SRIOV_CTRL, ctrl); - pci_write_config_word(dev, pos + PCI_SRIOV_NUM_VF, total); - pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &offset); - pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &stride); - if (!offset || (total > 1 && !stride)) - return -EIO; - - pci_read_config_dword(dev, pos + PCI_SRIOV_SUP_PGSIZE, &pgsz); - i = PAGE_SHIFT > 12 ? PAGE_SHIFT - 12 : 0; - pgsz &= ~((1 << i) - 1); - if (!pgsz) - return -EIO; - - pgsz &= ~(pgsz - 1); - pci_write_config_dword(dev, pos + PCI_SRIOV_SYS_PGSIZE, pgsz); - - nres = 0; - for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { - res = dev->resource + PCI_IOV_RESOURCES + i; - i += __pci_read_base(dev, pci_bar_unknown, res, - pos + PCI_SRIOV_BAR + i * 4); - if (!res->flags) - continue; - if (resource_size(res) & (PAGE_SIZE - 1)) { - rc = -EIO; - goto failed; - } - res->end = res->start + resource_size(res) * total - 1; - nres++; - } - - iov = kzalloc(sizeof(*iov), GFP_KERNEL); - if (!iov) { - rc = -ENOMEM; - goto failed; - } - - iov->pos = pos; - iov->nres = nres; - iov->ctrl = ctrl; - iov->total = total; - iov->offset = offset; - iov->stride = stride; - iov->pgsz = pgsz; - iov->self = dev; - pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap); - pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link); - - if (pdev) - iov->dev = pci_dev_get(pdev); - else { - iov->dev = dev; - mutex_init(&iov->lock); - } - - dev->sriov = iov; - dev->is_physfn = 1; - - return 0; - -failed: - for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { - res = dev->resource + PCI_IOV_RESOURCES + i; - res->flags = 0; - } - - return rc; -} - -static void sriov_release(struct pci_dev *dev) -{ - BUG_ON(dev->sriov->nr_virtfn); - - if (dev == dev->sriov->dev) - mutex_destroy(&dev->sriov->lock); - else - pci_dev_put(dev->sriov->dev); - - kfree(dev->sriov); - dev->sriov = NULL; -} - -static void sriov_restore_state(struct pci_dev *dev) -{ - int i; - u16 ctrl; - struct pci_sriov *iov = dev->sriov; - - pci_read_config_word(dev, iov->pos + PCI_SRIOV_CTRL, &ctrl); - if (ctrl & PCI_SRIOV_CTRL_VFE) - return; - - for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++) - pci_update_resource(dev, i); - - pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz); - pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, iov->nr_virtfn); - pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); - if (iov->ctrl & PCI_SRIOV_CTRL_VFE) - msleep(100); -} - -/** - * pci_iov_init - initialize the IOV capability - * @dev: the PCI device - * - * Returns 0 on success, or negative on failure. - */ -int pci_iov_init(struct pci_dev *dev) -{ - int pos; - - if (!dev->is_pcie) - return -ENODEV; - - pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV); - if (pos) - return sriov_init(dev, pos); - - return -ENODEV; -} - -/** - * pci_iov_release - release resources used by the IOV capability - * @dev: the PCI device - */ -void pci_iov_release(struct pci_dev *dev) -{ - if (dev->is_physfn) - sriov_release(dev); -} - -/** - * pci_iov_resource_bar - get position of the SR-IOV BAR - * @dev: the PCI device - * @resno: the resource number - * @type: the BAR type to be filled in - * - * Returns position of the BAR encapsulated in the SR-IOV capability. - */ -int pci_iov_resource_bar(struct pci_dev *dev, int resno, - enum pci_bar_type *type) -{ - if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END) - return 0; - - BUG_ON(!dev->is_physfn); - - *type = pci_bar_unknown; - - return dev->sriov->pos + PCI_SRIOV_BAR + - 4 * (resno - PCI_IOV_RESOURCES); -} - -/** - * pci_restore_iov_state - restore the state of the IOV capability - * @dev: the PCI device - */ -void pci_restore_iov_state(struct pci_dev *dev) -{ - if (dev->is_physfn) - sriov_restore_state(dev); -} - -/** - * pci_iov_bus_range - find bus range used by Virtual Function - * @bus: the PCI bus - * - * Returns max number of buses (exclude current one) used by Virtual - * Functions. - */ -int pci_iov_bus_range(struct pci_bus *bus) -{ - int max = 0; - u8 busnr; - struct pci_dev *dev; - - list_for_each_entry(dev, &bus->devices, bus_list) { - if (!dev->is_physfn) - continue; - busnr = virtfn_bus(dev, dev->sriov->total - 1); - if (busnr > max) - max = busnr; - } - - return max ? max - bus->number : 0; -} - -/** - * pci_enable_sriov - enable the SR-IOV capability - * @dev: the PCI device - * - * Returns 0 on success, or negative on failure. - */ -int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) -{ - might_sleep(); - - if (!dev->is_physfn) - return -ENODEV; - - return sriov_enable(dev, nr_virtfn); -} -EXPORT_SYMBOL_GPL(pci_enable_sriov); - -/** - * pci_disable_sriov - disable the SR-IOV capability - * @dev: the PCI device - */ -void pci_disable_sriov(struct pci_dev *dev) -{ - might_sleep(); - - if (!dev->is_physfn) - return; - - sriov_disable(dev); -} -EXPORT_SYMBOL_GPL(pci_disable_sriov); - -/** - * pci_sriov_migration - notify SR-IOV core of Virtual Function Migration - * @dev: the PCI device - * - * Returns IRQ_HANDLED if the IRQ is handled, or IRQ_NONE if not. - * - * Physical Function driver is responsible to register IRQ handler using - * VF Migration Interrupt Message Number, and call this function when the - * interrupt is generated by the hardware. - */ -irqreturn_t pci_sriov_migration(struct pci_dev *dev) -{ - if (!dev->is_physfn) - return IRQ_NONE; - - return sriov_migration(dev) ? IRQ_HANDLED : IRQ_NONE; -} -EXPORT_SYMBOL_GPL(pci_sriov_migration); diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index 6f2e6295e773..baba2eb5367d 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -27,53 +27,48 @@ static int pci_msi_enable = 1; /* Arch hooks */ -#ifndef arch_msi_check_device -int arch_msi_check_device(struct pci_dev *dev, int nvec, int type) +int __attribute__ ((weak)) +arch_msi_check_device(struct pci_dev *dev, int nvec, int type) { return 0; } -#endif -#ifndef arch_setup_msi_irqs -int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) +int __attribute__ ((weak)) +arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry) +{ + return 0; +} + +int __attribute__ ((weak)) +arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { struct msi_desc *entry; int ret; - /* - * If an architecture wants to support multiple MSI, it needs to - * override arch_setup_msi_irqs() - */ - if (type == PCI_CAP_ID_MSI && nvec > 1) - return 1; - list_for_each_entry(entry, &dev->msi_list, list) { ret = arch_setup_msi_irq(dev, entry); - if (ret < 0) + if (ret) return ret; - if (ret > 0) - return -ENOSPC; } return 0; } -#endif -#ifndef arch_teardown_msi_irqs -void arch_teardown_msi_irqs(struct pci_dev *dev) +void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq) +{ + return; +} + +void __attribute__ ((weak)) +arch_teardown_msi_irqs(struct pci_dev *dev) { struct msi_desc *entry; list_for_each_entry(entry, &dev->msi_list, list) { - int i, nvec; - if (entry->irq == 0) - continue; - nvec = 1 << entry->msi_attrib.multiple; - for (i = 0; i < nvec; i++) - arch_teardown_msi_irq(entry->irq + i); + if (entry->irq != 0) + arch_teardown_msi_irq(entry->irq); } } -#endif static void __msi_set_enable(struct pci_dev *dev, int pos, int enable) { @@ -116,14 +111,27 @@ static inline __attribute_const__ u32 msi_mask(unsigned x) return (1 << (1 << x)) - 1; } -static inline __attribute_const__ u32 msi_capable_mask(u16 control) +static void msix_flush_writes(struct irq_desc *desc) { - return msi_mask((control >> 1) & 7); -} + struct msi_desc *entry; -static inline __attribute_const__ u32 msi_enabled_mask(u16 control) -{ - return msi_mask((control >> 4) & 7); + entry = get_irq_desc_msi(desc); + BUG_ON(!entry || !entry->dev); + switch (entry->msi_attrib.type) { + case PCI_CAP_ID_MSI: + /* nothing to do */ + break; + case PCI_CAP_ID_MSIX: + { + int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET; + readl(entry->mask_base + offset); + break; + } + default: + BUG(); + break; + } } /* @@ -135,71 +143,49 @@ static inline __attribute_const__ u32 msi_enabled_mask(u16 control) * Returns 1 if it succeeded in masking the interrupt and 0 if the device * doesn't support MSI masking. */ -static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) -{ - u32 mask_bits = desc->masked; - - if (!desc->msi_attrib.maskbit) - return; - - mask_bits &= ~mask; - mask_bits |= flag; - pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits); - desc->masked = mask_bits; -} - -/* - * This internal function does not flush PCI writes to the device. - * All users must ensure that they read from the device before either - * assuming that the device state is up to date, or returning out of this - * file. This saves a few milliseconds when initialising devices with lots - * of MSI-X interrupts. - */ -static void msix_mask_irq(struct msi_desc *desc, u32 flag) -{ - u32 mask_bits = desc->masked; - unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET; - mask_bits &= ~1; - mask_bits |= flag; - writel(mask_bits, desc->mask_base + offset); - desc->masked = mask_bits; -} - -static void msi_set_mask_bit(unsigned irq, u32 flag) +static int msi_set_mask_bits(struct irq_desc *desc, u32 mask, u32 flag) { - struct msi_desc *desc = get_irq_msi(irq); + struct msi_desc *entry; - if (desc->msi_attrib.is_msix) { - msix_mask_irq(desc, flag); - readl(desc->mask_base); /* Flush write to device */ - } else { - unsigned offset = irq - desc->dev->irq; - msi_mask_irq(desc, 1 << offset, flag << offset); + entry = get_irq_desc_msi(desc); + BUG_ON(!entry || !entry->dev); + switch (entry->msi_attrib.type) { + case PCI_CAP_ID_MSI: + if (entry->msi_attrib.maskbit) { + int pos; + u32 mask_bits; + + pos = (long)entry->mask_base; + pci_read_config_dword(entry->dev, pos, &mask_bits); + mask_bits &= ~(mask); + mask_bits |= flag & mask; + pci_write_config_dword(entry->dev, pos, mask_bits); + } else { + return 0; + } + break; + case PCI_CAP_ID_MSIX: + { + int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET; + writel(flag, entry->mask_base + offset); + readl(entry->mask_base + offset); + break; } -} - -void mask_msi_irq(unsigned int irq) -{ - msi_set_mask_bit(irq, 1); -} - -void unmask_msi_irq(unsigned int irq) -{ - msi_set_mask_bit(irq, 0); + default: + BUG(); + break; + } + entry->msi_attrib.masked = !!flag; + return 1; } void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) { struct msi_desc *entry = get_irq_desc_msi(desc); - if (entry->msi_attrib.is_msix) { - void __iomem *base = entry->mask_base + - entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; - - msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); - msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); - msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET); - } else { + switch(entry->msi_attrib.type) { + case PCI_CAP_ID_MSI: + { struct pci_dev *dev = entry->dev; int pos = entry->msi_attrib.pos; u16 data; @@ -215,6 +201,21 @@ void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) pci_read_config_word(dev, msi_data_reg(pos, 0), &data); } msg->data = data; + break; + } + case PCI_CAP_ID_MSIX: + { + void __iomem *base; + base = entry->mask_base + + entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; + + msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); + msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); + msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET); + break; + } + default: + BUG(); } } @@ -228,25 +229,11 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg) void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) { struct msi_desc *entry = get_irq_desc_msi(desc); - if (entry->msi_attrib.is_msix) { - void __iomem *base; - base = entry->mask_base + - entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; - - writel(msg->address_lo, - base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); - writel(msg->address_hi, - base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); - writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET); - } else { + switch (entry->msi_attrib.type) { + case PCI_CAP_ID_MSI: + { struct pci_dev *dev = entry->dev; int pos = entry->msi_attrib.pos; - u16 msgctl; - - pci_read_config_word(dev, msi_control_reg(pos), &msgctl); - msgctl &= ~PCI_MSI_FLAGS_QSIZE; - msgctl |= entry->msi_attrib.multiple << 4; - pci_write_config_word(dev, msi_control_reg(pos), msgctl); pci_write_config_dword(dev, msi_lower_address_reg(pos), msg->address_lo); @@ -259,6 +246,23 @@ void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) pci_write_config_word(dev, msi_data_reg(pos, 0), msg->data); } + break; + } + case PCI_CAP_ID_MSIX: + { + void __iomem *base; + base = entry->mask_base + + entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; + + writel(msg->address_lo, + base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); + writel(msg->address_hi, + base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); + writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET); + break; + } + default: + BUG(); } entry->msg = *msg; } @@ -270,18 +274,37 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg) write_msi_msg_desc(desc, msg); } +void mask_msi_irq(unsigned int irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + + msi_set_mask_bits(desc, 1, 1); + msix_flush_writes(desc); +} + +void unmask_msi_irq(unsigned int irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + + msi_set_mask_bits(desc, 1, 0); + msix_flush_writes(desc); +} + static int msi_free_irqs(struct pci_dev* dev); -static struct msi_desc *alloc_msi_entry(struct pci_dev *dev) +static struct msi_desc* alloc_msi_entry(void) { - struct msi_desc *desc = kzalloc(sizeof(*desc), GFP_KERNEL); - if (!desc) + struct msi_desc *entry; + + entry = kzalloc(sizeof(struct msi_desc), GFP_KERNEL); + if (!entry) return NULL; - INIT_LIST_HEAD(&desc->list); - desc->dev = dev; + INIT_LIST_HEAD(&entry->list); + entry->irq = 0; + entry->dev = NULL; - return desc; + return entry; } static void pci_intx_for_msi(struct pci_dev *dev, int enable) @@ -305,11 +328,15 @@ static void __pci_restore_msi_state(struct pci_dev *dev) pci_intx_for_msi(dev, 0); msi_set_enable(dev, 0); write_msi_msg(dev->irq, &entry->msg); + if (entry->msi_attrib.maskbit) { + struct irq_desc *desc = irq_to_desc(dev->irq); + msi_set_mask_bits(desc, entry->msi_attrib.maskbits_mask, + entry->msi_attrib.masked); + } pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); - msi_mask_irq(entry, msi_capable_mask(control), entry->masked); control &= ~PCI_MSI_FLAGS_QSIZE; - control |= (entry->msi_attrib.multiple << 4) | PCI_MSI_FLAGS_ENABLE; + control |= PCI_MSI_FLAGS_ENABLE; pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); } @@ -327,8 +354,9 @@ static void __pci_restore_msix_state(struct pci_dev *dev) msix_set_enable(dev, 0); list_for_each_entry(entry, &dev->msi_list, list) { + struct irq_desc *desc = irq_to_desc(entry->irq); write_msi_msg(entry->irq, &entry->msg); - msix_mask_irq(entry, entry->masked); + msi_set_mask_bits(desc, 1, entry->msi_attrib.masked); } BUG_ON(list_empty(&dev->msi_list)); @@ -350,48 +378,52 @@ EXPORT_SYMBOL_GPL(pci_restore_msi_state); /** * msi_capability_init - configure device's MSI capability structure * @dev: pointer to the pci_dev data structure of MSI device function - * @nvec: number of interrupts to allocate * - * Setup the MSI capability structure of the device with the requested - * number of interrupts. A return value of zero indicates the successful - * setup of an entry with the new MSI irq. A negative return value indicates - * an error, and a positive return value indicates the number of interrupts - * which could have been allocated. - */ -static int msi_capability_init(struct pci_dev *dev, int nvec) + * Setup the MSI capability structure of device function with a single + * MSI irq, regardless of device function is capable of handling + * multiple messages. A return of zero indicates the successful setup + * of an entry zero with the new MSI irq or non-zero for otherwise. + **/ +static int msi_capability_init(struct pci_dev *dev) { struct msi_desc *entry; int pos, ret; u16 control; - unsigned mask; msi_set_enable(dev, 0); /* Ensure msi is disabled as I set it up */ pos = pci_find_capability(dev, PCI_CAP_ID_MSI); pci_read_config_word(dev, msi_control_reg(pos), &control); /* MSI Entry Initialization */ - entry = alloc_msi_entry(dev); + entry = alloc_msi_entry(); if (!entry) return -ENOMEM; - entry->msi_attrib.is_msix = 0; + entry->msi_attrib.type = PCI_CAP_ID_MSI; entry->msi_attrib.is_64 = is_64bit_address(control); entry->msi_attrib.entry_nr = 0; entry->msi_attrib.maskbit = is_mask_bit_support(control); + entry->msi_attrib.masked = 1; entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ entry->msi_attrib.pos = pos; - - entry->mask_pos = msi_mask_bits_reg(pos, entry->msi_attrib.is_64); - /* All MSIs are unmasked by default, Mask them all */ - if (entry->msi_attrib.maskbit) - pci_read_config_dword(dev, entry->mask_pos, &entry->masked); - mask = msi_capable_mask(control); - msi_mask_irq(entry, mask, mask); - + entry->dev = dev; + if (entry->msi_attrib.maskbit) { + unsigned int base, maskbits, temp; + + base = msi_mask_bits_reg(pos, entry->msi_attrib.is_64); + entry->mask_base = (void __iomem *)(long)base; + + /* All MSIs are unmasked by default, Mask them all */ + pci_read_config_dword(dev, base, &maskbits); + temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1); + maskbits |= temp; + pci_write_config_dword(dev, base, maskbits); + entry->msi_attrib.maskbits_mask = temp; + } list_add_tail(&entry->list, &dev->msi_list); /* Configure MSI capability structure */ - ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI); + ret = arch_setup_msi_irqs(dev, 1, PCI_CAP_ID_MSI); if (ret) { msi_free_irqs(dev); return ret; @@ -444,28 +476,26 @@ static int msix_capability_init(struct pci_dev *dev, /* MSI-X Table Initialization */ for (i = 0; i < nvec; i++) { - entry = alloc_msi_entry(dev); + entry = alloc_msi_entry(); if (!entry) break; j = entries[i].entry; - entry->msi_attrib.is_msix = 1; + entry->msi_attrib.type = PCI_CAP_ID_MSIX; entry->msi_attrib.is_64 = 1; entry->msi_attrib.entry_nr = j; + entry->msi_attrib.maskbit = 1; + entry->msi_attrib.masked = 1; entry->msi_attrib.default_irq = dev->irq; entry->msi_attrib.pos = pos; + entry->dev = dev; entry->mask_base = base; - entry->masked = readl(base + j * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); - msix_mask_irq(entry, 1); list_add_tail(&entry->list, &dev->msi_list); } ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX); - if (ret < 0) { - /* If we had some success report the number of irqs - * we succeeded in setting up. */ + if (ret) { int avail = 0; list_for_each_entry(entry, &dev->msi_list, list) { if (entry->irq != 0) { @@ -473,13 +503,14 @@ static int msix_capability_init(struct pci_dev *dev, } } - if (avail != 0) - ret = avail; - } - - if (ret) { msi_free_irqs(dev); - return ret; + + /* If we had some success report the number of irqs + * we succeeded in setting up. + */ + if (avail == 0) + avail = ret; + return avail; } i = 0; @@ -544,54 +575,39 @@ static int pci_msi_check_device(struct pci_dev* dev, int nvec, int type) } /** - * pci_enable_msi_block - configure device's MSI capability structure - * @dev: device to configure - * @nvec: number of interrupts to configure + * pci_enable_msi - configure device's MSI capability structure + * @dev: pointer to the pci_dev data structure of MSI device function * - * Allocate IRQs for a device with the MSI capability. - * This function returns a negative errno if an error occurs. If it - * is unable to allocate the number of interrupts requested, it returns - * the number of interrupts it might be able to allocate. If it successfully - * allocates at least the number of interrupts requested, it returns 0 and - * updates the @dev's irq member to the lowest new interrupt number; the - * other interrupt numbers allocated to this device are consecutive. - */ -int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) + * Setup the MSI capability structure of device function with + * a single MSI irq upon its software driver call to request for + * MSI mode enabled on its hardware device function. A return of zero + * indicates the successful setup of an entry zero with the new MSI + * irq or non-zero for otherwise. + **/ +int pci_enable_msi(struct pci_dev* dev) { - int status, pos, maxvec; - u16 msgctl; + int status; - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (!pos) - return -EINVAL; - pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); - maxvec = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); - if (nvec > maxvec) - return maxvec; - - status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSI); + status = pci_msi_check_device(dev, 1, PCI_CAP_ID_MSI); if (status) return status; WARN_ON(!!dev->msi_enabled); - /* Check whether driver already requested MSI-X irqs */ + /* Check whether driver already requested for MSI-X irqs */ if (dev->msix_enabled) { dev_info(&dev->dev, "can't enable MSI " "(MSI-X already enabled)\n"); return -EINVAL; } - - status = msi_capability_init(dev, nvec); + status = msi_capability_init(dev); return status; } -EXPORT_SYMBOL(pci_enable_msi_block); +EXPORT_SYMBOL(pci_enable_msi); -void pci_msi_shutdown(struct pci_dev *dev) +void pci_msi_shutdown(struct pci_dev* dev) { - struct msi_desc *desc; - u32 mask; - u16 ctrl; + struct msi_desc *entry; if (!pci_msi_enable || !dev || !dev->msi_enabled) return; @@ -601,15 +617,19 @@ void pci_msi_shutdown(struct pci_dev *dev) dev->msi_enabled = 0; BUG_ON(list_empty(&dev->msi_list)); - desc = list_first_entry(&dev->msi_list, struct msi_desc, list); - pci_read_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS, &ctrl); - mask = msi_capable_mask(ctrl); - msi_mask_irq(desc, mask, ~mask); + entry = list_entry(dev->msi_list.next, struct msi_desc, list); + /* Return the the pci reset with msi irqs unmasked */ + if (entry->msi_attrib.maskbit) { + u32 mask = entry->msi_attrib.maskbits_mask; + struct irq_desc *desc = irq_to_desc(dev->irq); + msi_set_mask_bits(desc, mask, ~mask); + } + if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) + return; /* Restore dev->irq to its default pin-assertion irq */ - dev->irq = desc->msi_attrib.default_irq; + dev->irq = entry->msi_attrib.default_irq; } - void pci_disable_msi(struct pci_dev* dev) { struct msi_desc *entry; @@ -620,7 +640,7 @@ void pci_disable_msi(struct pci_dev* dev) pci_msi_shutdown(dev); entry = list_entry(dev->msi_list.next, struct msi_desc, list); - if (entry->msi_attrib.is_msix) + if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) return; msi_free_irqs(dev); @@ -632,18 +652,14 @@ static int msi_free_irqs(struct pci_dev* dev) struct msi_desc *entry, *tmp; list_for_each_entry(entry, &dev->msi_list, list) { - int i, nvec; - if (!entry->irq) - continue; - nvec = 1 << entry->msi_attrib.multiple; - for (i = 0; i < nvec; i++) - BUG_ON(irq_has_action(entry->irq + i)); + if (entry->irq) + BUG_ON(irq_has_action(entry->irq)); } arch_teardown_msi_irqs(dev); list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) { - if (entry->msi_attrib.is_msix) { + if (entry->msi_attrib.type == PCI_CAP_ID_MSIX) { writel(1, entry->mask_base + entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); @@ -658,23 +674,6 @@ static int msi_free_irqs(struct pci_dev* dev) return 0; } -/** - * pci_msix_table_size - return the number of device's MSI-X table entries - * @dev: pointer to the pci_dev data structure of MSI-X device function - */ -int pci_msix_table_size(struct pci_dev *dev) -{ - int pos; - u16 control; - - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (!pos) - return 0; - - pci_read_config_word(dev, msi_control_reg(pos), &control); - return multi_msix_capable(control); -} - /** * pci_enable_msix - configure device's MSI-X capability structure * @dev: pointer to the pci_dev data structure of MSI-X device function @@ -692,8 +691,9 @@ int pci_msix_table_size(struct pci_dev *dev) **/ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) { - int status, nr_entries; + int status, pos, nr_entries; int i, j; + u16 control; if (!entries) return -EINVAL; @@ -702,7 +702,9 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) if (status) return status; - nr_entries = pci_msix_table_size(dev); + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + pci_read_config_word(dev, msi_control_reg(pos), &control); + nr_entries = multi_msix_capable(control); if (nvec > nr_entries) return -EINVAL; diff --git a/trunk/drivers/pci/msi.h b/trunk/drivers/pci/msi.h index 71f4df2ef654..3898f5237144 100644 --- a/trunk/drivers/pci/msi.h +++ b/trunk/drivers/pci/msi.h @@ -20,8 +20,14 @@ #define msi_mask_bits_reg(base, is64bit) \ ( (is64bit == 1) ? base+PCI_MSI_MASK_BIT : base+PCI_MSI_MASK_BIT-4) #define msi_disable(control) control &= ~PCI_MSI_FLAGS_ENABLE +#define multi_msi_capable(control) \ + (1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1)) +#define multi_msi_enable(control, num) \ + control |= (((num >> 1) << 4) & PCI_MSI_FLAGS_QSIZE); #define is_64bit_address(control) (!!(control & PCI_MSI_FLAGS_64BIT)) #define is_mask_bit_support(control) (!!(control & PCI_MSI_FLAGS_MASKBIT)) +#define msi_enable(control, num) multi_msi_enable(control, num); \ + control |= PCI_MSI_FLAGS_ENABLE #define msix_table_offset_reg(base) (base + 0x04) #define msix_pba_offset_reg(base) (base + 0x08) diff --git a/trunk/drivers/pci/pci-acpi.c b/trunk/drivers/pci/pci-acpi.c index fac5eddcefd2..deea8a187eb8 100644 --- a/trunk/drivers/pci/pci-acpi.c +++ b/trunk/drivers/pci/pci-acpi.c @@ -18,6 +18,221 @@ #include #include "pci.h" +struct acpi_osc_data { + acpi_handle handle; + u32 support_set; + u32 control_set; + u32 control_query; + int is_queried; + struct list_head sibiling; +}; +static LIST_HEAD(acpi_osc_data_list); + +struct acpi_osc_args { + u32 capbuf[3]; +}; + +static DEFINE_MUTEX(pci_acpi_lock); + +static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle) +{ + struct acpi_osc_data *data; + + list_for_each_entry(data, &acpi_osc_data_list, sibiling) { + if (data->handle == handle) + return data; + } + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return NULL; + INIT_LIST_HEAD(&data->sibiling); + data->handle = handle; + list_add_tail(&data->sibiling, &acpi_osc_data_list); + return data; +} + +static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, + 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66}; + +static acpi_status acpi_run_osc(acpi_handle handle, + struct acpi_osc_args *osc_args, u32 *retval) +{ + acpi_status status; + struct acpi_object_list input; + union acpi_object in_params[4]; + struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; + union acpi_object *out_obj; + u32 errors, flags = osc_args->capbuf[OSC_QUERY_TYPE]; + + /* Setting up input parameters */ + input.count = 4; + input.pointer = in_params; + in_params[0].type = ACPI_TYPE_BUFFER; + in_params[0].buffer.length = 16; + in_params[0].buffer.pointer = OSC_UUID; + in_params[1].type = ACPI_TYPE_INTEGER; + in_params[1].integer.value = 1; + in_params[2].type = ACPI_TYPE_INTEGER; + in_params[2].integer.value = 3; + in_params[3].type = ACPI_TYPE_BUFFER; + in_params[3].buffer.length = 12; + in_params[3].buffer.pointer = (u8 *)osc_args->capbuf; + + status = acpi_evaluate_object(handle, "_OSC", &input, &output); + if (ACPI_FAILURE(status)) + return status; + + if (!output.length) + return AE_NULL_OBJECT; + + out_obj = output.pointer; + if (out_obj->type != ACPI_TYPE_BUFFER) { + printk(KERN_DEBUG "Evaluate _OSC returns wrong type\n"); + status = AE_TYPE; + goto out_kfree; + } + /* Need to ignore the bit0 in result code */ + errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); + if (errors) { + if (errors & OSC_REQUEST_ERROR) + printk(KERN_DEBUG "_OSC request fails\n"); + if (errors & OSC_INVALID_UUID_ERROR) + printk(KERN_DEBUG "_OSC invalid UUID\n"); + if (errors & OSC_INVALID_REVISION_ERROR) + printk(KERN_DEBUG "_OSC invalid revision\n"); + if (errors & OSC_CAPABILITIES_MASK_ERROR) { + if (flags & OSC_QUERY_ENABLE) + goto out_success; + printk(KERN_DEBUG "_OSC FW not grant req. control\n"); + status = AE_SUPPORT; + goto out_kfree; + } + status = AE_ERROR; + goto out_kfree; + } +out_success: + *retval = *((u32 *)(out_obj->buffer.pointer + 8)); + status = AE_OK; + +out_kfree: + kfree(output.pointer); + return status; +} + +static acpi_status __acpi_query_osc(u32 flags, struct acpi_osc_data *osc_data) +{ + acpi_status status; + u32 support_set, result; + struct acpi_osc_args osc_args; + + /* do _OSC query for all possible controls */ + support_set = osc_data->support_set | (flags & OSC_SUPPORT_MASKS); + osc_args.capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; + osc_args.capbuf[OSC_SUPPORT_TYPE] = support_set; + osc_args.capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS; + + status = acpi_run_osc(osc_data->handle, &osc_args, &result); + if (ACPI_SUCCESS(status)) { + osc_data->support_set = support_set; + osc_data->control_query = result; + osc_data->is_queried = 1; + } + + return status; +} + +/* + * pci_acpi_osc_support: Invoke _OSC indicating support for the given feature + * @flags: Bitmask of flags to support + * + * See the ACPI spec for the definition of the flags + */ +int pci_acpi_osc_support(acpi_handle handle, u32 flags) +{ + acpi_status status; + acpi_handle tmp; + struct acpi_osc_data *osc_data; + int rc = 0; + + status = acpi_get_handle(handle, "_OSC", &tmp); + if (ACPI_FAILURE(status)) + return -ENOTTY; + + mutex_lock(&pci_acpi_lock); + osc_data = acpi_get_osc_data(handle); + if (!osc_data) { + printk(KERN_ERR "acpi osc data array is full\n"); + rc = -ENOMEM; + goto out; + } + + __acpi_query_osc(flags, osc_data); +out: + mutex_unlock(&pci_acpi_lock); + return rc; +} + +/** + * pci_osc_control_set - commit requested control to Firmware + * @handle: acpi_handle for the target ACPI object + * @flags: driver's requested control bits + * + * Attempt to take control from Firmware on requested control bits. + **/ +acpi_status pci_osc_control_set(acpi_handle handle, u32 flags) +{ + acpi_status status; + u32 control_req, control_set, result; + acpi_handle tmp; + struct acpi_osc_data *osc_data; + struct acpi_osc_args osc_args; + + status = acpi_get_handle(handle, "_OSC", &tmp); + if (ACPI_FAILURE(status)) + return status; + + mutex_lock(&pci_acpi_lock); + osc_data = acpi_get_osc_data(handle); + if (!osc_data) { + printk(KERN_ERR "acpi osc data array is full\n"); + status = AE_ERROR; + goto out; + } + + control_req = (flags & OSC_CONTROL_MASKS); + if (!control_req) { + status = AE_TYPE; + goto out; + } + + /* No need to evaluate _OSC if the control was already granted. */ + if ((osc_data->control_set & control_req) == control_req) + goto out; + + if (!osc_data->is_queried) { + status = __acpi_query_osc(osc_data->support_set, osc_data); + if (ACPI_FAILURE(status)) + goto out; + } + + if ((osc_data->control_query & control_req) != control_req) { + status = AE_SUPPORT; + goto out; + } + + control_set = osc_data->control_set | control_req; + osc_args.capbuf[OSC_QUERY_TYPE] = 0; + osc_args.capbuf[OSC_SUPPORT_TYPE] = osc_data->support_set; + osc_args.capbuf[OSC_CONTROL_TYPE] = control_set; + status = acpi_run_osc(handle, &osc_args, &result); + if (ACPI_SUCCESS(status)) + osc_data->control_set = result; +out: + mutex_unlock(&pci_acpi_lock); + return status; +} +EXPORT_SYMBOL(pci_osc_control_set); + /* * _SxD returns the D-state with the highest power * (lowest D-state number) supported in the S-state "x". diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index c0cbbb5a245e..93eac1423585 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -99,52 +99,6 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) } static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); -/** - * store_remove_id - remove a PCI device ID from this driver - * @driver: target device driver - * @buf: buffer for scanning device ID data - * @count: input size - * - * Removes a dynamic pci device ID to this driver. - */ -static ssize_t -store_remove_id(struct device_driver *driver, const char *buf, size_t count) -{ - struct pci_dynid *dynid, *n; - struct pci_driver *pdrv = to_pci_driver(driver); - __u32 vendor, device, subvendor = PCI_ANY_ID, - subdevice = PCI_ANY_ID, class = 0, class_mask = 0; - int fields = 0; - int retval = -ENODEV; - - fields = sscanf(buf, "%x %x %x %x %x %x", - &vendor, &device, &subvendor, &subdevice, - &class, &class_mask); - if (fields < 2) - return -EINVAL; - - spin_lock(&pdrv->dynids.lock); - list_for_each_entry_safe(dynid, n, &pdrv->dynids.list, node) { - struct pci_device_id *id = &dynid->id; - if ((id->vendor == vendor) && - (id->device == device) && - (subvendor == PCI_ANY_ID || id->subvendor == subvendor) && - (subdevice == PCI_ANY_ID || id->subdevice == subdevice) && - !((id->class ^ class) & class_mask)) { - list_del(&dynid->node); - kfree(dynid); - retval = 0; - break; - } - } - spin_unlock(&pdrv->dynids.lock); - - if (retval) - return retval; - return count; -} -static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id); - static void pci_free_dynids(struct pci_driver *drv) { @@ -171,20 +125,6 @@ static void pci_remove_newid_file(struct pci_driver *drv) { driver_remove_file(&drv->driver, &driver_attr_new_id); } - -static int -pci_create_removeid_file(struct pci_driver *drv) -{ - int error = 0; - if (drv->probe != NULL) - error = driver_create_file(&drv->driver,&driver_attr_remove_id); - return error; -} - -static void pci_remove_removeid_file(struct pci_driver *drv) -{ - driver_remove_file(&drv->driver, &driver_attr_remove_id); -} #else /* !CONFIG_HOTPLUG */ static inline void pci_free_dynids(struct pci_driver *drv) {} static inline int pci_create_newid_file(struct pci_driver *drv) @@ -192,11 +132,6 @@ static inline int pci_create_newid_file(struct pci_driver *drv) return 0; } static inline void pci_remove_newid_file(struct pci_driver *drv) {} -static inline int pci_create_removeid_file(struct pci_driver *drv) -{ - return 0; -} -static inline void pci_remove_removeid_file(struct pci_driver *drv) {} #endif /** @@ -417,60 +352,53 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state) { struct pci_dev * pci_dev = to_pci_dev(dev); struct pci_driver * drv = pci_dev->driver; - - pci_dev->state_saved = false; + int i = 0; if (drv && drv->suspend) { pci_power_t prev = pci_dev->current_state; - int error; - error = drv->suspend(pci_dev, state); - suspend_report_result(drv->suspend, error); - if (error) - return error; + pci_dev->state_saved = false; + + i = drv->suspend(pci_dev, state); + suspend_report_result(drv->suspend, i); + if (i) + return i; + + if (pci_dev->state_saved) + goto Fixup; - if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 + if (pci_dev->current_state != PCI_D0 && pci_dev->current_state != PCI_UNKNOWN) { WARN_ONCE(pci_dev->current_state != prev, "PCI PM: Device state not saved by %pF\n", drv->suspend); + goto Fixup; } } + pci_save_state(pci_dev); + /* + * This is for compatibility with existing code with legacy PM support. + */ + pci_pm_set_unknown_state(pci_dev); + + Fixup: pci_fixup_device(pci_fixup_suspend, pci_dev); - return 0; + return i; } static int pci_legacy_suspend_late(struct device *dev, pm_message_t state) { struct pci_dev * pci_dev = to_pci_dev(dev); struct pci_driver * drv = pci_dev->driver; + int i = 0; if (drv && drv->suspend_late) { - pci_power_t prev = pci_dev->current_state; - int error; - - error = drv->suspend_late(pci_dev, state); - suspend_report_result(drv->suspend_late, error); - if (error) - return error; - - if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 - && pci_dev->current_state != PCI_UNKNOWN) { - WARN_ONCE(pci_dev->current_state != prev, - "PCI PM: Device state not saved by %pF\n", - drv->suspend_late); - return 0; - } + i = drv->suspend_late(pci_dev, state); + suspend_report_result(drv->suspend_late, i); } - - if (!pci_dev->state_saved) - pci_save_state(pci_dev); - - pci_pm_set_unknown_state(pci_dev); - - return 0; + return i; } static int pci_legacy_resume_early(struct device *dev) @@ -495,23 +423,6 @@ static int pci_legacy_resume(struct device *dev) /* Auxiliary functions used by the new power management framework */ -/** - * pci_restore_standard_config - restore standard config registers of PCI device - * @pci_dev: PCI device to handle - */ -static int pci_restore_standard_config(struct pci_dev *pci_dev) -{ - pci_update_current_state(pci_dev, PCI_UNKNOWN); - - if (pci_dev->current_state != PCI_D0) { - int error = pci_set_power_state(pci_dev, PCI_D0); - if (error) - return error; - } - - return pci_dev->state_saved ? pci_restore_state(pci_dev) : 0; -} - static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) { pci_restore_standard_config(pci_dev); @@ -532,6 +443,7 @@ static void pci_pm_default_suspend(struct pci_dev *pci_dev) /* Disable non-bridge devices without PM support */ if (!pci_is_bridge(pci_dev)) pci_disable_enabled_device(pci_dev); + pci_save_state(pci_dev); } static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) @@ -581,13 +493,13 @@ static int pci_pm_suspend(struct device *dev) if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_suspend(dev, PMSG_SUSPEND); - pci_dev->state_saved = false; - if (!pm) { pci_pm_default_suspend(pci_dev); goto Fixup; } + pci_dev->state_saved = false; + if (pm->suspend) { pci_power_t prev = pci_dev->current_state; int error; @@ -597,14 +509,24 @@ static int pci_pm_suspend(struct device *dev) if (error) return error; - if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 + if (pci_dev->state_saved) + goto Fixup; + + if (pci_dev->current_state != PCI_D0 && pci_dev->current_state != PCI_UNKNOWN) { WARN_ONCE(pci_dev->current_state != prev, "PCI PM: State of device not saved by %pF\n", pm->suspend); + goto Fixup; } } + if (!pci_dev->state_saved) { + pci_save_state(pci_dev); + if (!pci_is_bridge(pci_dev)) + pci_prepare_to_sleep(pci_dev); + } + Fixup: pci_fixup_device(pci_fixup_suspend, pci_dev); @@ -614,43 +536,21 @@ static int pci_pm_suspend(struct device *dev) static int pci_pm_suspend_noirq(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); - struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + struct device_driver *drv = dev->driver; + int error = 0; if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_suspend_late(dev, PMSG_SUSPEND); - if (!pm) { - pci_save_state(pci_dev); - return 0; + if (drv && drv->pm && drv->pm->suspend_noirq) { + error = drv->pm->suspend_noirq(dev); + suspend_report_result(drv->pm->suspend_noirq, error); } - if (pm->suspend_noirq) { - pci_power_t prev = pci_dev->current_state; - int error; - - error = pm->suspend_noirq(dev); - suspend_report_result(pm->suspend_noirq, error); - if (error) - return error; + if (!error) + pci_pm_set_unknown_state(pci_dev); - if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 - && pci_dev->current_state != PCI_UNKNOWN) { - WARN_ONCE(pci_dev->current_state != prev, - "PCI PM: State of device not saved by %pF\n", - pm->suspend_noirq); - return 0; - } - } - - if (!pci_dev->state_saved) { - pci_save_state(pci_dev); - if (!pci_is_bridge(pci_dev)) - pci_prepare_to_sleep(pci_dev); - } - - pci_pm_set_unknown_state(pci_dev); - - return 0; + return error; } static int pci_pm_resume_noirq(struct device *dev) @@ -717,13 +617,13 @@ static int pci_pm_freeze(struct device *dev) if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_suspend(dev, PMSG_FREEZE); - pci_dev->state_saved = false; - if (!pm) { pci_pm_default_suspend(pci_dev); return 0; } + pci_dev->state_saved = false; + if (pm->freeze) { int error; @@ -733,6 +633,9 @@ static int pci_pm_freeze(struct device *dev) return error; } + if (!pci_dev->state_saved) + pci_save_state(pci_dev); + return 0; } @@ -740,25 +643,20 @@ static int pci_pm_freeze_noirq(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); struct device_driver *drv = dev->driver; + int error = 0; if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_suspend_late(dev, PMSG_FREEZE); if (drv && drv->pm && drv->pm->freeze_noirq) { - int error; - error = drv->pm->freeze_noirq(dev); suspend_report_result(drv->pm->freeze_noirq, error); - if (error) - return error; } - if (!pci_dev->state_saved) - pci_save_state(pci_dev); + if (!error) + pci_pm_set_unknown_state(pci_dev); - pci_pm_set_unknown_state(pci_dev); - - return 0; + return error; } static int pci_pm_thaw_noirq(struct device *dev) @@ -801,56 +699,46 @@ static int pci_pm_poweroff(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + int error = 0; if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_suspend(dev, PMSG_HIBERNATE); - pci_dev->state_saved = false; - if (!pm) { pci_pm_default_suspend(pci_dev); goto Fixup; } - if (pm->poweroff) { - int error; + pci_dev->state_saved = false; + if (pm->poweroff) { error = pm->poweroff(dev); suspend_report_result(pm->poweroff, error); - if (error) - return error; } + if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) + pci_prepare_to_sleep(pci_dev); + Fixup: pci_fixup_device(pci_fixup_suspend, pci_dev); - return 0; + return error; } static int pci_pm_poweroff_noirq(struct device *dev) { - struct pci_dev *pci_dev = to_pci_dev(dev); struct device_driver *drv = dev->driver; + int error = 0; if (pci_has_legacy_pm_support(to_pci_dev(dev))) return pci_legacy_suspend_late(dev, PMSG_HIBERNATE); - if (!drv || !drv->pm) - return 0; - - if (drv->pm->poweroff_noirq) { - int error; - + if (drv && drv->pm && drv->pm->poweroff_noirq) { error = drv->pm->poweroff_noirq(dev); suspend_report_result(drv->pm->poweroff_noirq, error); - if (error) - return error; } - if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) - pci_prepare_to_sleep(pci_dev); - - return 0; + return error; } static int pci_pm_restore_noirq(struct device *dev) @@ -964,23 +852,13 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner, /* register with core */ error = driver_register(&drv->driver); if (error) - goto out; + return error; error = pci_create_newid_file(drv); if (error) - goto out_newid; + driver_unregister(&drv->driver); - error = pci_create_removeid_file(drv); - if (error) - goto out_removeid; -out: return error; - -out_removeid: - pci_remove_newid_file(drv); -out_newid: - driver_unregister(&drv->driver); - goto out; } /** @@ -996,7 +874,6 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner, void pci_unregister_driver(struct pci_driver *drv) { - pci_remove_removeid_file(drv); pci_remove_newid_file(drv); driver_unregister(&drv->driver); pci_free_dynids(drv); @@ -1096,7 +973,6 @@ struct bus_type pci_bus_type = { .remove = pci_device_remove, .shutdown = pci_device_shutdown, .dev_attrs = pci_dev_attrs, - .bus_attrs = pci_bus_attrs, .pm = PCI_PM_OPS_PTR, }; diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index e9a8706a6401..dfc4e0ddf241 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -219,83 +219,6 @@ msi_bus_store(struct device *dev, struct device_attribute *attr, return count; } -#ifdef CONFIG_HOTPLUG -static DEFINE_MUTEX(pci_remove_rescan_mutex); -static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf, - size_t count) -{ - unsigned long val; - struct pci_bus *b = NULL; - - if (strict_strtoul(buf, 0, &val) < 0) - return -EINVAL; - - if (val) { - mutex_lock(&pci_remove_rescan_mutex); - while ((b = pci_find_next_bus(b)) != NULL) - pci_rescan_bus(b); - mutex_unlock(&pci_remove_rescan_mutex); - } - return count; -} - -struct bus_attribute pci_bus_attrs[] = { - __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, bus_rescan_store), - __ATTR_NULL -}; - -static ssize_t -dev_rescan_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long val; - struct pci_dev *pdev = to_pci_dev(dev); - - if (strict_strtoul(buf, 0, &val) < 0) - return -EINVAL; - - if (val) { - mutex_lock(&pci_remove_rescan_mutex); - pci_rescan_bus(pdev->bus); - mutex_unlock(&pci_remove_rescan_mutex); - } - return count; -} - -static void remove_callback(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - - mutex_lock(&pci_remove_rescan_mutex); - pci_remove_bus_device(pdev); - mutex_unlock(&pci_remove_rescan_mutex); -} - -static ssize_t -remove_store(struct device *dev, struct device_attribute *dummy, - const char *buf, size_t count) -{ - int ret = 0; - unsigned long val; - struct pci_dev *pdev = to_pci_dev(dev); - - if (strict_strtoul(buf, 0, &val) < 0) - return -EINVAL; - - if (pci_is_root_bus(pdev->bus)) - return -EBUSY; - - /* An attribute cannot be unregistered by one of its own methods, - * so we have to use this roundabout approach. - */ - if (val) - ret = device_schedule_callback(dev, remove_callback); - if (ret) - count = ret; - return count; -} -#endif - struct device_attribute pci_dev_attrs[] = { __ATTR_RO(resource), __ATTR_RO(vendor), @@ -314,24 +237,9 @@ struct device_attribute pci_dev_attrs[] = { __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), broken_parity_status_show,broken_parity_status_store), __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store), -#ifdef CONFIG_HOTPLUG - __ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store), - __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store), -#endif __ATTR_NULL, }; -static ssize_t -boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct pci_dev *pdev = to_pci_dev(dev); - - return sprintf(buf, "%u\n", - !!(pdev->resource[PCI_ROM_RESOURCE].flags & - IORESOURCE_ROM_SHADOW)); -} -struct device_attribute vga_attr = __ATTR_RO(boot_vga); - static ssize_t pci_read_config(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) @@ -584,19 +492,6 @@ pci_mmap_legacy_io(struct kobject *kobj, struct bin_attribute *attr, return pci_mmap_legacy_page_range(bus, vma, pci_mmap_io); } -/** - * pci_adjust_legacy_attr - adjustment of legacy file attributes - * @b: bus to create files under - * @mmap_type: I/O port or memory - * - * Stub implementation. Can be overridden by arch if necessary. - */ -void __weak -pci_adjust_legacy_attr(struct pci_bus *b, enum pci_mmap_state mmap_type) -{ - return; -} - /** * pci_create_legacy_files - create legacy I/O port and memory files * @b: bus to create files under @@ -623,7 +518,6 @@ void pci_create_legacy_files(struct pci_bus *b) b->legacy_io->read = pci_read_legacy_io; b->legacy_io->write = pci_write_legacy_io; b->legacy_io->mmap = pci_mmap_legacy_io; - pci_adjust_legacy_attr(b, pci_mmap_io); error = device_create_bin_file(&b->dev, b->legacy_io); if (error) goto legacy_io_err; @@ -634,7 +528,6 @@ void pci_create_legacy_files(struct pci_bus *b) b->legacy_mem->size = 1024*1024; b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; b->legacy_mem->mmap = pci_mmap_legacy_mem; - pci_adjust_legacy_attr(b, pci_mmap_mem); error = device_create_bin_file(&b->dev, b->legacy_mem); if (error) goto legacy_mem_err; @@ -826,8 +719,8 @@ static int pci_create_resource_files(struct pci_dev *pdev) return 0; } #else /* !HAVE_PCI_MMAP */ -int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; } -void __weak pci_remove_resource_files(struct pci_dev *dev) { return; } +static inline int pci_create_resource_files(struct pci_dev *dev) { return 0; } +static inline void pci_remove_resource_files(struct pci_dev *dev) { return; } #endif /* HAVE_PCI_MMAP */ /** @@ -991,27 +884,18 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) pdev->rom_attr = attr; } - if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA) { - retval = device_create_file(&pdev->dev, &vga_attr); - if (retval) - goto err_rom_file; - } - /* add platform-specific attributes */ retval = pcibios_add_platform_entries(pdev); if (retval) - goto err_vga_file; + goto err_rom_file; /* add sysfs entries for various capabilities */ retval = pci_create_capabilities_sysfs(pdev); if (retval) - goto err_vga_file; + goto err_rom_file; return 0; -err_vga_file: - if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA) - device_remove_file(&pdev->dev, &vga_attr); err_rom_file: if (rom_size) { sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index fe7ac2cea7c9..6d6120007af4 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -20,8 +20,6 @@ #include #include #include /* isa_dma_bridge_buggy */ -#include -#include #include "pci.h" unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT; @@ -428,6 +426,7 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) * given PCI device * @dev: PCI device to handle. * @state: PCI power state (D0, D1, D2, D3hot) to put the device into. + * @wait: If 'true', wait for the device to change its power state * * RETURN VALUE: * -EINVAL if the requested state is invalid. @@ -436,15 +435,12 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) * 0 if device already is in the requested state. * 0 if device's power state has been successfully changed. */ -static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) +static int +pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait) { u16 pmcsr; bool need_restore = false; - /* Check if we're already there */ - if (dev->current_state == state) - return 0; - if (!dev->pm_cap) return -EIO; @@ -455,7 +451,10 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) * Can enter D0 from any state, but if we can only go deeper * to sleep if we're already in a low power state */ - if (state != PCI_D0 && dev->current_state <= PCI_D3cold + if (dev->current_state == state) { + /* we're already there */ + return 0; + } else if (state != PCI_D0 && dev->current_state <= PCI_D3cold && dev->current_state > state) { dev_err(&dev->dev, "invalid power transition " "(from state %d to %d)\n", dev->current_state, state); @@ -482,8 +481,10 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) break; case PCI_UNKNOWN: /* Boot-up */ if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot - && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) + && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) { need_restore = true; + wait = true; + } /* Fall-through: force to D0 */ default: pmcsr = 0; @@ -493,6 +494,9 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) /* enter specified state */ pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); + if (!wait) + return 0; + /* Mandatory power management transition delays */ /* see PCI PM 1.1 5.6.1 table 18 */ if (state == PCI_D3hot || dev->current_state == PCI_D3hot) @@ -517,7 +521,7 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) if (need_restore) pci_restore_bars(dev); - if (dev->bus->self) + if (wait && dev->bus->self) pcie_aspm_pm_state_change(dev->bus->self); return 0; @@ -541,53 +545,6 @@ void pci_update_current_state(struct pci_dev *dev, pci_power_t state) } } -/** - * pci_platform_power_transition - Use platform to change device power state - * @dev: PCI device to handle. - * @state: State to put the device into. - */ -static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state) -{ - int error; - - if (platform_pci_power_manageable(dev)) { - error = platform_pci_set_power_state(dev, state); - if (!error) - pci_update_current_state(dev, state); - } else { - error = -ENODEV; - /* Fall back to PCI_D0 if native PM is not supported */ - pci_update_current_state(dev, PCI_D0); - } - - return error; -} - -/** - * __pci_start_power_transition - Start power transition of a PCI device - * @dev: PCI device to handle. - * @state: State to put the device into. - */ -static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state) -{ - if (state == PCI_D0) - pci_platform_power_transition(dev, PCI_D0); -} - -/** - * __pci_complete_power_transition - Complete power transition of a PCI device - * @dev: PCI device to handle. - * @state: State to put the device into. - * - * This function should not be called directly by device drivers. - */ -int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state) -{ - return state > PCI_D0 ? - pci_platform_power_transition(dev, state) : -EINVAL; -} -EXPORT_SYMBOL_GPL(__pci_complete_power_transition); - /** * pci_set_power_state - Set the power state of a PCI device * @dev: PCI device to handle. @@ -620,21 +577,30 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) */ return 0; - /* Check if we're already there */ - if (dev->current_state == state) - return 0; - - __pci_start_power_transition(dev, state); - + if (state == PCI_D0 && platform_pci_power_manageable(dev)) { + /* + * Allow the platform to change the state, for example via ACPI + * _PR0, _PS0 and some such, but do not trust it. + */ + int ret = platform_pci_set_power_state(dev, PCI_D0); + if (!ret) + pci_update_current_state(dev, PCI_D0); + } /* This device is quirked not to be put into D3, so don't put it in D3 */ if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3)) return 0; - error = pci_raw_set_power_state(dev, state); + error = pci_raw_set_power_state(dev, state, true); - if (!__pci_complete_power_transition(dev, state)) - error = 0; + if (state > PCI_D0 && platform_pci_power_manageable(dev)) { + /* Allow the platform to finalize the transition */ + int ret = platform_pci_set_power_state(dev, state); + if (!ret) { + pci_update_current_state(dev, state); + error = 0; + } + } return error; } @@ -679,8 +645,6 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) EXPORT_SYMBOL(pci_choose_state); -#define PCI_EXP_SAVE_REGS 7 - static int pci_save_pcie_state(struct pci_dev *dev) { int pos, i = 0; @@ -693,7 +657,7 @@ static int pci_save_pcie_state(struct pci_dev *dev) save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); if (!save_state) { - dev_err(&dev->dev, "buffer not found in %s\n", __func__); + dev_err(&dev->dev, "buffer not found in %s\n", __FUNCTION__); return -ENOMEM; } cap = (u16 *)&save_state->data[0]; @@ -702,9 +666,6 @@ static int pci_save_pcie_state(struct pci_dev *dev) pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]); pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]); pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]); - pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]); - pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]); - pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]); return 0; } @@ -725,9 +686,6 @@ static void pci_restore_pcie_state(struct pci_dev *dev) pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]); pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]); pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]); - pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]); - pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]); - pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]); } @@ -742,7 +700,7 @@ static int pci_save_pcix_state(struct pci_dev *dev) save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX); if (!save_state) { - dev_err(&dev->dev, "buffer not found in %s\n", __func__); + dev_err(&dev->dev, "buffer not found in %s\n", __FUNCTION__); return -ENOMEM; } @@ -815,7 +773,6 @@ pci_restore_state(struct pci_dev *dev) } pci_restore_pcix_state(dev); pci_restore_msi_state(dev); - pci_restore_iov_state(dev); return 0; } @@ -1274,7 +1231,7 @@ int pci_prepare_to_sleep(struct pci_dev *dev) if (target_state == PCI_POWER_ERROR) return -EIO; - pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev)); + pci_enable_wake(dev, target_state, true); error = pci_set_power_state(dev, target_state); @@ -1412,8 +1369,7 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev) { int error; - error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_EXP, - PCI_EXP_SAVE_REGS * sizeof(u16)); + error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_EXP, 4 * sizeof(u16)); if (error) dev_err(&dev->dev, "unable to preallocate PCI Express save buffer\n"); @@ -1424,6 +1380,50 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev) "unable to preallocate PCI-X save buffer\n"); } +/** + * pci_restore_standard_config - restore standard config registers of PCI device + * @dev: PCI device to handle + * + * This function assumes that the device's configuration space is accessible. + * If the device needs to be powered up, the function will wait for it to + * change the state. + */ +int pci_restore_standard_config(struct pci_dev *dev) +{ + pci_power_t prev_state; + int error; + + pci_update_current_state(dev, PCI_D0); + + prev_state = dev->current_state; + if (prev_state == PCI_D0) + goto Restore; + + error = pci_raw_set_power_state(dev, PCI_D0, false); + if (error) + return error; + + /* + * This assumes that we won't get a bus in B2 or B3 from the BIOS, but + * we've made this assumption forever and it appears to be universally + * satisfied. + */ + switch(prev_state) { + case PCI_D3cold: + case PCI_D3hot: + mdelay(pci_pm_d3_delay); + break; + case PCI_D2: + udelay(PCI_PM_D2_DELAY); + break; + } + + pci_update_current_state(dev, PCI_D0); + + Restore: + return dev->state_saved ? pci_restore_state(dev) : 0; +} + /** * pci_enable_ari - enable ARI forwarding if hardware support it * @dev: the PCI device @@ -1484,7 +1484,7 @@ pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) if (!pin) return -1; - while (dev->bus->parent) { + while (dev->bus->self) { pin = pci_swizzle_interrupt_pin(dev, pin); dev = dev->bus->self; } @@ -1504,7 +1504,7 @@ u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp) { u8 pin = *pinp; - while (dev->bus->parent) { + while (dev->bus->self) { pin = pci_swizzle_interrupt_pin(dev, pin); dev = dev->bus->self; } @@ -2028,24 +2028,18 @@ static int __pcie_flr(struct pci_dev *dev, int probe) pci_block_user_cfg_access(dev); /* Wait for Transaction Pending bit clean */ - pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status); - if (!(status & PCI_EXP_DEVSTA_TRPND)) - goto transaction_done; - msleep(100); pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status); - if (!(status & PCI_EXP_DEVSTA_TRPND)) - goto transaction_done; - - dev_info(&dev->dev, "Busy after 100ms while trying to reset; " + if (status & PCI_EXP_DEVSTA_TRPND) { + dev_info(&dev->dev, "Busy after 100ms while trying to reset; " "sleeping for 1 second\n"); - ssleep(1); - pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status); - if (status & PCI_EXP_DEVSTA_TRPND) - dev_info(&dev->dev, "Still busy after 1s; " + ssleep(1); + pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status); + if (status & PCI_EXP_DEVSTA_TRPND) + dev_info(&dev->dev, "Still busy after 1s; " "proceeding with reset anyway\n"); + } -transaction_done: pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); mdelay(100); @@ -2072,24 +2066,18 @@ static int __pci_af_flr(struct pci_dev *dev, int probe) pci_block_user_cfg_access(dev); /* Wait for Transaction Pending bit clean */ - pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status); - if (!(status & PCI_AF_STATUS_TP)) - goto transaction_done; - msleep(100); pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status); - if (!(status & PCI_AF_STATUS_TP)) - goto transaction_done; - - dev_info(&dev->dev, "Busy after 100ms while trying to" - " reset; sleeping for 1 second\n"); - ssleep(1); - pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status); - if (status & PCI_AF_STATUS_TP) - dev_info(&dev->dev, "Still busy after 1s; " - "proceeding with reset anyway\n"); - -transaction_done: + if (status & PCI_AF_STATUS_TP) { + dev_info(&dev->dev, "Busy after 100ms while trying to" + " reset; sleeping for 1 second\n"); + ssleep(1); + pci_read_config_byte(dev, + cappos + PCI_AF_STATUS, &status); + if (status & PCI_AF_STATUS_TP) + dev_info(&dev->dev, "Still busy after 1s; " + "proceeding with reset anyway\n"); + } pci_write_config_byte(dev, cappos + PCI_AF_CTRL, PCI_AF_CTRL_FLR); mdelay(100); @@ -2358,140 +2346,18 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags) */ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) { - int reg; - if (resno < PCI_ROM_RESOURCE) { *type = pci_bar_unknown; return PCI_BASE_ADDRESS_0 + 4 * resno; } else if (resno == PCI_ROM_RESOURCE) { *type = pci_bar_mem32; return dev->rom_base_reg; - } else if (resno < PCI_BRIDGE_RESOURCES) { - /* device specific resource */ - reg = pci_iov_resource_bar(dev, resno, type); - if (reg) - return reg; } dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno); return 0; } -#define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE -static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; -spinlock_t resource_alignment_lock = SPIN_LOCK_UNLOCKED; - -/** - * pci_specified_resource_alignment - get resource alignment specified by user. - * @dev: the PCI device to get - * - * RETURNS: Resource alignment if it is specified. - * Zero if it is not specified. - */ -resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) -{ - int seg, bus, slot, func, align_order, count; - resource_size_t align = 0; - char *p; - - spin_lock(&resource_alignment_lock); - p = resource_alignment_param; - while (*p) { - count = 0; - if (sscanf(p, "%d%n", &align_order, &count) == 1 && - p[count] == '@') { - p += count + 1; - } else { - align_order = -1; - } - if (sscanf(p, "%x:%x:%x.%x%n", - &seg, &bus, &slot, &func, &count) != 4) { - seg = 0; - if (sscanf(p, "%x:%x.%x%n", - &bus, &slot, &func, &count) != 3) { - /* Invalid format */ - printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n", - p); - break; - } - } - p += count; - if (seg == pci_domain_nr(dev->bus) && - bus == dev->bus->number && - slot == PCI_SLOT(dev->devfn) && - func == PCI_FUNC(dev->devfn)) { - if (align_order == -1) { - align = PAGE_SIZE; - } else { - align = 1 << align_order; - } - /* Found */ - break; - } - if (*p != ';' && *p != ',') { - /* End of param or invalid format */ - break; - } - p++; - } - spin_unlock(&resource_alignment_lock); - return align; -} - -/** - * pci_is_reassigndev - check if specified PCI is target device to reassign - * @dev: the PCI device to check - * - * RETURNS: non-zero for PCI device is a target device to reassign, - * or zero is not. - */ -int pci_is_reassigndev(struct pci_dev *dev) -{ - return (pci_specified_resource_alignment(dev) != 0); -} - -ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) -{ - if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) - count = RESOURCE_ALIGNMENT_PARAM_SIZE - 1; - spin_lock(&resource_alignment_lock); - strncpy(resource_alignment_param, buf, count); - resource_alignment_param[count] = '\0'; - spin_unlock(&resource_alignment_lock); - return count; -} - -ssize_t pci_get_resource_alignment_param(char *buf, size_t size) -{ - size_t count; - spin_lock(&resource_alignment_lock); - count = snprintf(buf, size, "%s", resource_alignment_param); - spin_unlock(&resource_alignment_lock); - return count; -} - -static ssize_t pci_resource_alignment_show(struct bus_type *bus, char *buf) -{ - return pci_get_resource_alignment_param(buf, PAGE_SIZE); -} - -static ssize_t pci_resource_alignment_store(struct bus_type *bus, - const char *buf, size_t count) -{ - return pci_set_resource_alignment_param(buf, count); -} - -BUS_ATTR(resource_alignment, 0644, pci_resource_alignment_show, - pci_resource_alignment_store); - -static int __init pci_resource_alignment_sysfs_init(void) -{ - return bus_create_file(&pci_bus_type, - &bus_attr_resource_alignment); -} - -late_initcall(pci_resource_alignment_sysfs_init); - static void __devinit pci_no_domains(void) { #ifdef CONFIG_PCI_DOMAINS @@ -2540,9 +2406,6 @@ static int __init pci_setup(char *str) pci_cardbus_io_size = memparse(str + 9, &str); } else if (!strncmp(str, "cbmemsize=", 10)) { pci_cardbus_mem_size = memparse(str + 10, &str); - } else if (!strncmp(str, "resource_alignment=", 19)) { - pci_set_resource_alignment_param(str + 19, - strlen(str + 19)); } else { printk(KERN_ERR "PCI: Unknown option `%s'\n", str); diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index d03f6b99f292..07c0aa5275e6 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -1,8 +1,6 @@ #ifndef DRIVERS_PCI_H #define DRIVERS_PCI_H -#include - #define PCI_CFG_SPACE_SIZE 256 #define PCI_CFG_SPACE_EXP_SIZE 4096 @@ -51,6 +49,7 @@ extern void pci_disable_enabled_device(struct pci_dev *dev); extern void pci_pm_init(struct pci_dev *dev); extern void platform_pci_wakeup_init(struct pci_dev *dev); extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); +extern int pci_restore_standard_config(struct pci_dev *dev); static inline bool pci_is_bridge(struct pci_dev *pci_dev) { @@ -137,12 +136,6 @@ extern int pcie_mch_quirk; extern struct device_attribute pci_dev_attrs[]; extern struct device_attribute dev_attr_cpuaffinity; extern struct device_attribute dev_attr_cpulistaffinity; -#ifdef CONFIG_HOTPLUG -extern struct bus_attribute pci_bus_attrs[]; -#else -#define pci_bus_attrs NULL -#endif - /** * pci_match_one_device - Tell if a PCI device structure has a matching @@ -185,7 +178,6 @@ enum pci_bar_type { pci_bar_mem64, /* A 64-bit memory BAR */ }; -extern int pci_setup_device(struct pci_dev *dev); extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, struct resource *res, unsigned int reg); extern int pci_resource_bar(struct pci_dev *dev, int resno, @@ -203,60 +195,4 @@ static inline int pci_ari_enabled(struct pci_bus *bus) return bus->self && bus->self->ari_enabled; } -#ifdef CONFIG_PCI_QUIRKS -extern int pci_is_reassigndev(struct pci_dev *dev); -resource_size_t pci_specified_resource_alignment(struct pci_dev *dev); -extern void pci_disable_bridge_window(struct pci_dev *dev); -#endif - -/* Single Root I/O Virtualization */ -struct pci_sriov { - int pos; /* capability position */ - int nres; /* number of resources */ - u32 cap; /* SR-IOV Capabilities */ - u16 ctrl; /* SR-IOV Control */ - u16 total; /* total VFs associated with the PF */ - u16 initial; /* initial VFs associated with the PF */ - u16 nr_virtfn; /* number of VFs available */ - u16 offset; /* first VF Routing ID offset */ - u16 stride; /* following VF stride */ - u32 pgsz; /* page size for BAR alignment */ - u8 link; /* Function Dependency Link */ - struct pci_dev *dev; /* lowest numbered PF */ - struct pci_dev *self; /* this PF */ - struct mutex lock; /* lock for VF bus */ - struct work_struct mtask; /* VF Migration task */ - u8 __iomem *mstate; /* VF Migration State Array */ -}; - -#ifdef CONFIG_PCI_IOV -extern int pci_iov_init(struct pci_dev *dev); -extern void pci_iov_release(struct pci_dev *dev); -extern int pci_iov_resource_bar(struct pci_dev *dev, int resno, - enum pci_bar_type *type); -extern void pci_restore_iov_state(struct pci_dev *dev); -extern int pci_iov_bus_range(struct pci_bus *bus); -#else -static inline int pci_iov_init(struct pci_dev *dev) -{ - return -ENODEV; -} -static inline void pci_iov_release(struct pci_dev *dev) - -{ -} -static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno, - enum pci_bar_type *type) -{ - return 0; -} -static inline void pci_restore_iov_state(struct pci_dev *dev) -{ -} -static inline int pci_iov_bus_range(struct pci_bus *bus) -{ - return 0; -} -#endif /* CONFIG_PCI_IOV */ - #endif /* DRIVERS_PCI_H */ diff --git a/trunk/drivers/pci/pcie/aer/aerdrv.c b/trunk/drivers/pci/pcie/aer/aerdrv.c index 32ade5af927e..e390707661dd 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv.c @@ -38,13 +38,30 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -static int __devinit aer_probe (struct pcie_device *dev); +static int __devinit aer_probe (struct pcie_device *dev, + const struct pcie_port_service_id *id ); static void aer_remove(struct pcie_device *dev); +static int aer_suspend(struct pcie_device *dev, pm_message_t state) +{return 0;} +static int aer_resume(struct pcie_device *dev) {return 0;} static pci_ers_result_t aer_error_detected(struct pci_dev *dev, enum pci_channel_state error); static void aer_error_resume(struct pci_dev *dev); static pci_ers_result_t aer_root_reset(struct pci_dev *dev); +/* + * PCI Express bus's AER Root service driver data structure + */ +static struct pcie_port_service_id aer_id[] = { + { + .vendor = PCI_ANY_ID, + .device = PCI_ANY_ID, + .port_type = PCIE_RC_PORT, + .service_type = PCIE_PORT_SERVICE_AER, + }, + { /* end: all zeroes */ } +}; + static struct pci_error_handlers aer_error_handlers = { .error_detected = aer_error_detected, .resume = aer_error_resume, @@ -52,12 +69,14 @@ static struct pci_error_handlers aer_error_handlers = { static struct pcie_port_service_driver aerdriver = { .name = "aer", - .port_type = PCIE_ANY_PORT, - .service = PCIE_PORT_SERVICE_AER, + .id_table = &aer_id[0], .probe = aer_probe, .remove = aer_remove, + .suspend = aer_suspend, + .resume = aer_resume, + .err_handler = &aer_error_handlers, .reset_link = aer_root_reset, @@ -188,7 +207,8 @@ static void aer_remove(struct pcie_device *dev) * * Invoked when PCI Express bus loads AER service driver. **/ -static int __devinit aer_probe (struct pcie_device *dev) +static int __devinit aer_probe (struct pcie_device *dev, + const struct pcie_port_service_id *id ) { int status; struct aer_rpc *rpc; diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c b/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c index 8edb2f300e8f..ebce26c37049 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c @@ -38,7 +38,7 @@ int aer_osc_setup(struct pcie_device *pciedev) handle = acpi_find_root_bridge_handle(pdev); if (handle) { - status = acpi_pci_osc_control_set(handle, + status = pci_osc_control_set(handle, OSC_PCI_EXPRESS_AER_CONTROL | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); } diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_core.c b/trunk/drivers/pci/pcie/aer/aerdrv_core.c index 307452f30035..382575007382 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_core.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_core.c @@ -351,21 +351,21 @@ static int find_aer_service_iter(struct device *device, void *data) { struct device_driver *driver; struct pcie_port_service_driver *service_driver; + struct pcie_device *pcie_dev; struct find_aer_service_data *result; result = (struct find_aer_service_data *) data; if (device->bus == &pcie_port_bus_type) { - struct pcie_port_data *port_data; - - port_data = pci_get_drvdata(to_pcie_device(device)->port); - if (port_data->port_type == PCIE_SW_DOWNSTREAM_PORT) + pcie_dev = to_pcie_device(device); + if (pcie_dev->id.port_type == PCIE_SW_DOWNSTREAM_PORT) result->is_downstream = 1; driver = device->driver; if (driver) { service_driver = to_service_driver(driver); - if (service_driver->service == PCIE_PORT_SERVICE_AER) { + if (service_driver->id_table->service_type == + PCIE_PORT_SERVICE_AER) { result->aer_driver = service_driver; return 1; } diff --git a/trunk/drivers/pci/pcie/portdrv.h b/trunk/drivers/pci/pcie/portdrv.h index 17ad53868f9f..2529f3f2ea5a 100644 --- a/trunk/drivers/pci/pcie/portdrv.h +++ b/trunk/drivers/pci/pcie/portdrv.h @@ -25,21 +25,19 @@ #define PCIE_CAPABILITIES_REG 0x2 #define PCIE_SLOT_CAPABILITIES_REG 0x14 #define PCIE_PORT_DEVICE_MAXSERVICES 4 -#define PCIE_PORT_MSI_VECTOR_MASK 0x1f -/* - * According to the PCI Express Base Specification 2.0, the indices of the MSI-X - * table entires used by port services must not exceed 31 - */ -#define PCIE_PORT_MAX_MSIX_ENTRIES 32 #define get_descriptor_id(type, service) (((type - 4) << 4) | service) +struct pcie_port_device_ext { + int interrupt_mode; /* [0:INTx | 1:MSI | 2:MSI-X] */ +}; + extern struct bus_type pcie_port_bus_type; extern int pcie_port_device_probe(struct pci_dev *dev); extern int pcie_port_device_register(struct pci_dev *dev); #ifdef CONFIG_PM -extern int pcie_port_device_suspend(struct device *dev); -extern int pcie_port_device_resume(struct device *dev); +extern int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state); +extern int pcie_port_device_resume(struct pci_dev *dev); #endif extern void pcie_port_device_remove(struct pci_dev *dev); extern int __must_check pcie_port_bus_register(void); diff --git a/trunk/drivers/pci/pcie/portdrv_bus.c b/trunk/drivers/pci/pcie/portdrv_bus.c index ef3a4eeaebb4..eec89b767f9f 100644 --- a/trunk/drivers/pci/pcie/portdrv_bus.c +++ b/trunk/drivers/pci/pcie/portdrv_bus.c @@ -26,22 +26,20 @@ EXPORT_SYMBOL_GPL(pcie_port_bus_type); static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) { struct pcie_device *pciedev; - struct pcie_port_data *port_data; struct pcie_port_service_driver *driver; if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type) return 0; - + pciedev = to_pcie_device(dev); driver = to_service_driver(drv); - - if (driver->service != pciedev->service) - return 0; - - port_data = pci_get_drvdata(pciedev->port); - - if (driver->port_type != PCIE_ANY_PORT - && driver->port_type != port_data->port_type) + if ( (driver->id_table->vendor != PCI_ANY_ID && + driver->id_table->vendor != pciedev->id.vendor) || + (driver->id_table->device != PCI_ANY_ID && + driver->id_table->device != pciedev->id.device) || + (driver->id_table->port_type != PCIE_ANY_PORT && + driver->id_table->port_type != pciedev->id.port_type) || + driver->id_table->service_type != pciedev->id.service_type ) return 0; return 1; diff --git a/trunk/drivers/pci/pcie/portdrv_core.c b/trunk/drivers/pci/pcie/portdrv_core.c index e39982503863..8b3f8c18032f 100644 --- a/trunk/drivers/pci/pcie/portdrv_core.c +++ b/trunk/drivers/pci/pcie/portdrv_core.c @@ -15,9 +15,10 @@ #include #include -#include "../pci.h" #include "portdrv.h" +extern int pcie_mch_quirk; /* MSI-quirk Indicator */ + /** * release_pcie_device - free PCI Express port service device structure * @dev: Port service device to release @@ -30,150 +31,26 @@ static void release_pcie_device(struct device *dev) kfree(to_pcie_device(dev)); } -/** - * pcie_port_msix_add_entry - add entry to given array of MSI-X entries - * @entries: Array of MSI-X entries - * @new_entry: Index of the entry to add to the array - * @nr_entries: Number of entries aleady in the array - * - * Return value: Position of the added entry in the array - */ -static int pcie_port_msix_add_entry( - struct msix_entry *entries, int new_entry, int nr_entries) +static int is_msi_quirked(struct pci_dev *dev) { - int j; - - for (j = 0; j < nr_entries; j++) - if (entries[j].entry == new_entry) - return j; - - entries[j].entry = new_entry; - return j; -} - -/** - * pcie_port_enable_msix - try to set up MSI-X as interrupt mode for given port - * @dev: PCI Express port to handle - * @vectors: Array of interrupt vectors to populate - * @mask: Bitmask of port capabilities returned by get_port_device_capability() - * - * Return value: 0 on success, error code on failure - */ -static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) -{ - struct msix_entry *msix_entries; - int idx[PCIE_PORT_DEVICE_MAXSERVICES]; - int nr_entries, status, pos, i, nvec; + int port_type, quirk = 0; u16 reg16; - u32 reg32; - - nr_entries = pci_msix_table_size(dev); - if (!nr_entries) - return -EINVAL; - if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES) - nr_entries = PCIE_PORT_MAX_MSIX_ENTRIES; - - msix_entries = kzalloc(sizeof(*msix_entries) * nr_entries, GFP_KERNEL); - if (!msix_entries) - return -ENOMEM; - /* - * Allocate as many entries as the port wants, so that we can check - * which of them will be useful. Moreover, if nr_entries is correctly - * equal to the number of entries this port actually uses, we'll happily - * go through without any tricks. - */ - for (i = 0; i < nr_entries; i++) - msix_entries[i].entry = i; - - status = pci_enable_msix(dev, msix_entries, nr_entries); - if (status) - goto Exit; - - for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) - idx[i] = -1; - status = -EIO; - nvec = 0; - - if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP)) { - int entry; - - /* - * The code below follows the PCI Express Base Specification 2.0 - * stating in Section 6.1.6 that "PME and Hot-Plug Event - * interrupts (when both are implemented) always share the same - * MSI or MSI-X vector, as indicated by the Interrupt Message - * Number field in the PCI Express Capabilities register", where - * according to Section 7.8.2 of the specification "For MSI-X, - * the value in this field indicates which MSI-X Table entry is - * used to generate the interrupt message." - */ - pos = pci_find_capability(dev, PCI_CAP_ID_EXP); - pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, ®16); - entry = (reg16 >> 9) & PCIE_PORT_MSI_VECTOR_MASK; - if (entry >= nr_entries) - goto Error; - - i = pcie_port_msix_add_entry(msix_entries, entry, nvec); - if (i == nvec) - nvec++; - - idx[PCIE_PORT_SERVICE_PME_SHIFT] = i; - idx[PCIE_PORT_SERVICE_HP_SHIFT] = i; - } - - if (mask & PCIE_PORT_SERVICE_AER) { - int entry; - - /* - * The code below follows Section 7.10.10 of the PCI Express - * Base Specification 2.0 stating that bits 31-27 of the Root - * Error Status Register contain a value indicating which of the - * MSI/MSI-X vectors assigned to the port is going to be used - * for AER, where "For MSI-X, the value in this register - * indicates which MSI-X Table entry is used to generate the - * interrupt message." - */ - pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); - pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, ®32); - entry = reg32 >> 27; - if (entry >= nr_entries) - goto Error; - - i = pcie_port_msix_add_entry(msix_entries, entry, nvec); - if (i == nvec) - nvec++; - - idx[PCIE_PORT_SERVICE_AER_SHIFT] = i; - } - - /* - * If nvec is equal to the allocated number of entries, we can just use - * what we have. Otherwise, the port has some extra entries not for the - * services we know and we need to work around that. - */ - if (nvec == nr_entries) { - status = 0; - } else { - /* Drop the temporary MSI-X setup */ - pci_disable_msix(dev); - - /* Now allocate the MSI-X vectors for real */ - status = pci_enable_msix(dev, msix_entries, nvec); - if (status) - goto Exit; + pci_read_config_word(dev, + pci_find_capability(dev, PCI_CAP_ID_EXP) + + PCIE_CAPABILITIES_REG, ®16); + port_type = (reg16 >> 4) & PORT_TYPE_MASK; + switch(port_type) { + case PCIE_RC_PORT: + if (pcie_mch_quirk == 1) + quirk = 1; + break; + case PCIE_SW_UPSTREAM_PORT: + case PCIE_SW_DOWNSTREAM_PORT: + default: + break; } - - for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) - vectors[i] = idx[i] >= 0 ? msix_entries[idx[i]].vector : -1; - - Exit: - kfree(msix_entries); - return status; - - Error: - pci_disable_msix(dev); - goto Exit; + return quirk; } /** @@ -187,32 +64,47 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) */ static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask) { - struct pcie_port_data *port_data = pci_get_drvdata(dev); - int irq, interrupt_mode = PCIE_PORT_NO_IRQ; - int i; + int i, pos, nvec, status = -EINVAL; + int interrupt_mode = PCIE_PORT_INTx_MODE; + /* Set INTx as default */ + for (i = 0, nvec = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { + if (mask & (1 << i)) + nvec++; + vectors[i] = dev->irq; + } + /* Check MSI quirk */ - if (port_data->port_type == PCIE_RC_PORT && pcie_mch_quirk) - goto Fallback; - - /* Try to use MSI-X if supported */ - if (!pcie_port_enable_msix(dev, vectors, mask)) - return PCIE_PORT_MSIX_MODE; - - /* We're not going to use MSI-X, so try MSI and fall back to INTx */ - if (!pci_enable_msi(dev)) - interrupt_mode = PCIE_PORT_MSI_MODE; - - Fallback: - if (interrupt_mode == PCIE_PORT_NO_IRQ && dev->pin) - interrupt_mode = PCIE_PORT_INTx_MODE; - - irq = interrupt_mode != PCIE_PORT_NO_IRQ ? dev->irq : -1; - for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) - vectors[i] = irq; - - vectors[PCIE_PORT_SERVICE_VC_SHIFT] = -1; - + if (is_msi_quirked(dev)) + return interrupt_mode; + + /* Select MSI-X over MSI if supported */ + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + if (pos) { + struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] = + {{0, 0}, {0, 1}, {0, 2}, {0, 3}}; + status = pci_enable_msix(dev, msix_entries, nvec); + if (!status) { + int j = 0; + + interrupt_mode = PCIE_PORT_MSIX_MODE; + for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { + if (mask & (1 << i)) + vectors[i] = msix_entries[j++].vector; + } + } + } + if (status) { + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + if (pos) { + status = pci_enable_msi(dev); + if (!status) { + interrupt_mode = PCIE_PORT_MSI_MODE; + for (i = 0;i < PCIE_PORT_DEVICE_MAXSERVICES;i++) + vectors[i] = dev->irq; + } + } + } return interrupt_mode; } @@ -240,11 +132,13 @@ static int get_port_device_capability(struct pci_dev *dev) pos + PCIE_SLOT_CAPABILITIES_REG, ®32); if (reg32 & SLOT_HP_CAPABLE_MASK) services |= PCIE_PORT_SERVICE_HP; - } - /* AER capable */ + } + /* PME Capable - root port capability */ + if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT) + services |= PCIE_PORT_SERVICE_PME; + if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) services |= PCIE_PORT_SERVICE_AER; - /* VC support */ if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) services |= PCIE_PORT_SERVICE_VC; @@ -258,17 +152,20 @@ static int get_port_device_capability(struct pci_dev *dev) * @port_type: Type of the port * @service_type: Type of service to associate with the service device * @irq: Interrupt vector to associate with the service device + * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI) */ static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, - int service_type, int irq) + int port_type, int service_type, int irq, int irq_mode) { - struct pcie_port_data *port_data = pci_get_drvdata(parent); struct device *device; - int port_type = port_data->port_type; dev->port = parent; + dev->interrupt_mode = irq_mode; dev->irq = irq; - dev->service = service_type; + dev->id.vendor = parent->vendor; + dev->id.device = parent->device; + dev->id.port_type = port_type; + dev->id.service_type = (1 << service_type); /* Initialize generic device interface */ device = &dev->device; @@ -288,9 +185,10 @@ static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, * @port_type: Type of the port * @service_type: Type of service to associate with the service device * @irq: Interrupt vector to associate with the service device + * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI) */ static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, - int service_type, int irq) + int port_type, int service_type, int irq, int irq_mode) { struct pcie_device *device; @@ -298,7 +196,7 @@ static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, if (!device) return NULL; - pcie_device_init(parent, device, service_type, irq); + pcie_device_init(parent, device, port_type, service_type, irq,irq_mode); return device; } @@ -332,90 +230,63 @@ int pcie_port_device_probe(struct pci_dev *dev) */ int pcie_port_device_register(struct pci_dev *dev) { - struct pcie_port_data *port_data; - int status, capabilities, irq_mode, i, nr_serv; + struct pcie_port_device_ext *p_ext; + int status, type, capabilities, irq_mode, i; int vectors[PCIE_PORT_DEVICE_MAXSERVICES]; u16 reg16; - port_data = kzalloc(sizeof(*port_data), GFP_KERNEL); - if (!port_data) + /* Allocate port device extension */ + if (!(p_ext = kmalloc(sizeof(struct pcie_port_device_ext), GFP_KERNEL))) return -ENOMEM; - pci_set_drvdata(dev, port_data); + + pci_set_drvdata(dev, p_ext); /* Get port type */ pci_read_config_word(dev, pci_find_capability(dev, PCI_CAP_ID_EXP) + PCIE_CAPABILITIES_REG, ®16); - port_data->port_type = (reg16 >> 4) & PORT_TYPE_MASK; + type = (reg16 >> 4) & PORT_TYPE_MASK; + /* Now get port services */ capabilities = get_port_device_capability(dev); - /* Root ports are capable of generating PME too */ - if (port_data->port_type == PCIE_RC_PORT) - capabilities |= PCIE_PORT_SERVICE_PME; - irq_mode = assign_interrupt_mode(dev, vectors, capabilities); - if (irq_mode == PCIE_PORT_NO_IRQ) { - /* - * Don't use service devices that require interrupts if there is - * no way to generate them. - */ - if (!(capabilities & PCIE_PORT_SERVICE_VC)) { - status = -ENODEV; - goto Error; - } - capabilities = PCIE_PORT_SERVICE_VC; - } - port_data->port_irq_mode = irq_mode; - - status = pci_enable_device(dev); - if (status) - goto Error; - pci_set_master(dev); + p_ext->interrupt_mode = irq_mode; /* Allocate child services if any */ - for (i = 0, nr_serv = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { + for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { struct pcie_device *child; - int service = 1 << i; - - if (!(capabilities & service)) - continue; - child = alloc_pcie_device(dev, service, vectors[i]); - if (!child) - continue; - - status = device_register(&child->device); - if (status) { - kfree(child); - continue; + if (capabilities & (1 << i)) { + child = alloc_pcie_device( + dev, /* parent */ + type, /* port type */ + i, /* service type */ + vectors[i], /* irq */ + irq_mode /* interrupt mode */); + if (child) { + status = device_register(&child->device); + if (status) { + kfree(child); + continue; + } + get_device(&child->device); + } } - - get_device(&child->device); - nr_serv++; - } - if (!nr_serv) { - pci_disable_device(dev); - status = -ENODEV; - goto Error; } - return 0; - - Error: - kfree(port_data); - return status; } #ifdef CONFIG_PM static int suspend_iter(struct device *dev, void *data) { struct pcie_port_service_driver *service_driver; + pm_message_t state = * (pm_message_t *) data; if ((dev->bus == &pcie_port_bus_type) && (dev->driver)) { service_driver = to_service_driver(dev->driver); if (service_driver->suspend) - service_driver->suspend(to_pcie_device(dev)); + service_driver->suspend(to_pcie_device(dev), state); } return 0; } @@ -423,10 +294,11 @@ static int suspend_iter(struct device *dev, void *data) /** * pcie_port_device_suspend - suspend port services associated with a PCIe port * @dev: PCI Express port to handle + * @state: Representation of system power management transition in progress */ -int pcie_port_device_suspend(struct device *dev) +int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state) { - return device_for_each_child(dev, NULL, suspend_iter); + return device_for_each_child(&dev->dev, &state, suspend_iter); } static int resume_iter(struct device *dev, void *data) @@ -446,17 +318,24 @@ static int resume_iter(struct device *dev, void *data) * pcie_port_device_suspend - resume port services associated with a PCIe port * @dev: PCI Express port to handle */ -int pcie_port_device_resume(struct device *dev) +int pcie_port_device_resume(struct pci_dev *dev) { - return device_for_each_child(dev, NULL, resume_iter); + return device_for_each_child(&dev->dev, NULL, resume_iter); } -#endif /* PM */ +#endif static int remove_iter(struct device *dev, void *data) { + struct pcie_port_service_driver *service_driver; + if (dev->bus == &pcie_port_bus_type) { - put_device(dev); - device_unregister(dev); + if (dev->driver) { + service_driver = to_service_driver(dev->driver); + if (service_driver->remove) + service_driver->remove(to_pcie_device(dev)); + } + *(unsigned long*)data = (unsigned long)dev; + return 1; } return 0; } @@ -470,21 +349,25 @@ static int remove_iter(struct device *dev, void *data) */ void pcie_port_device_remove(struct pci_dev *dev) { - struct pcie_port_data *port_data = pci_get_drvdata(dev); - - device_for_each_child(&dev->dev, NULL, remove_iter); - pci_disable_device(dev); + struct device *device; + unsigned long device_addr; + int interrupt_mode = PCIE_PORT_INTx_MODE; + int status; - switch (port_data->port_irq_mode) { - case PCIE_PORT_MSIX_MODE: + do { + status = device_for_each_child(&dev->dev, &device_addr, remove_iter); + if (status) { + device = (struct device*)device_addr; + interrupt_mode = (to_pcie_device(device))->interrupt_mode; + put_device(device); + device_unregister(device); + } + } while (status); + /* Switch to INTx by default if MSI enabled */ + if (interrupt_mode == PCIE_PORT_MSIX_MODE) pci_disable_msix(dev); - break; - case PCIE_PORT_MSI_MODE: + else if (interrupt_mode == PCIE_PORT_MSI_MODE) pci_disable_msi(dev); - break; - } - - kfree(port_data); } /** @@ -509,7 +392,7 @@ static int pcie_port_probe_service(struct device *dev) return -ENODEV; pciedev = to_pcie_device(dev); - status = driver->probe(pciedev); + status = driver->probe(pciedev, driver->id_table); if (!status) { dev_printk(KERN_DEBUG, dev, "service driver %s loaded\n", driver->name); diff --git a/trunk/drivers/pci/pcie/portdrv_pci.c b/trunk/drivers/pci/pcie/portdrv_pci.c index b924e2463f85..5ea566e20b37 100644 --- a/trunk/drivers/pci/pcie/portdrv_pci.c +++ b/trunk/drivers/pci/pcie/portdrv_pci.c @@ -32,6 +32,11 @@ MODULE_LICENSE("GPL"); /* global data */ static const char device_name[] = "pcieport-driver"; +static int pcie_portdrv_save_config(struct pci_dev *dev) +{ + return pci_save_state(dev); +} + static int pcie_portdrv_restore_config(struct pci_dev *dev) { int retval; @@ -44,21 +49,21 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) } #ifdef CONFIG_PM -static struct dev_pm_ops pcie_portdrv_pm_ops = { - .suspend = pcie_port_device_suspend, - .resume = pcie_port_device_resume, - .freeze = pcie_port_device_suspend, - .thaw = pcie_port_device_resume, - .poweroff = pcie_port_device_suspend, - .restore = pcie_port_device_resume, -}; - -#define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) +static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) +{ + return pcie_port_device_suspend(dev, state); -#else /* !PM */ +} -#define PCIE_PORTDRV_PM_OPS NULL -#endif /* !PM */ +static int pcie_portdrv_resume(struct pci_dev *dev) +{ + pci_set_master(dev); + return pcie_port_device_resume(dev); +} +#else +#define pcie_portdrv_suspend NULL +#define pcie_portdrv_resume NULL +#endif /* * pcie_portdrv_probe - Probe PCI-Express port devices @@ -77,15 +82,20 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, if (status) return status; + if (pci_enable_device(dev) < 0) + return -ENODEV; + + pci_set_master(dev); if (!dev->irq && dev->pin) { dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " "check vendor BIOS\n", dev->vendor, dev->device); } - status = pcie_port_device_register(dev); - if (status) - return status; + if (pcie_port_device_register(dev)) { + pci_disable_device(dev); + return -ENOMEM; + } - pci_save_state(dev); + pcie_portdrv_save_config(dev); return 0; } @@ -94,6 +104,7 @@ static void pcie_portdrv_remove (struct pci_dev *dev) { pcie_port_device_remove(dev); pci_disable_device(dev); + kfree(pci_get_drvdata(dev)); } static int error_detected_iter(struct device *device, void *data) @@ -267,9 +278,10 @@ static struct pci_driver pcie_portdriver = { .probe = pcie_portdrv_probe, .remove = pcie_portdrv_remove, - .err_handler = &pcie_portdrv_err_handler, + .suspend = pcie_portdrv_suspend, + .resume = pcie_portdrv_resume, - .driver.pm = PCIE_PORTDRV_PM_OPS, + .err_handler = &pcie_portdrv_err_handler, }; static int __init pcie_portdrv_init(void) diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index e2f3dd098cfa..55ec44a27e89 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -287,7 +287,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) struct resource *res; int i; - if (!child->parent) /* It's a host bus, nothing to read */ + if (!dev) /* It's a host bus, nothing to read */ return; if (dev->transparent) { @@ -511,21 +511,21 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, /* * If we already got to this bus through a different bridge, - * don't re-add it. This can happen with the i450NX chipset. - * - * However, we continue to descend down the hierarchy and - * scan remaining child buses. + * ignore it. This can happen with the i450NX chipset. */ - child = pci_find_bus(pci_domain_nr(bus), busnr); - if (!child) { - child = pci_add_new_bus(bus, dev, busnr); - if (!child) - goto out; - child->primary = buses & 0xFF; - child->subordinate = (buses >> 16) & 0xFF; - child->bridge_ctl = bctl; + if (pci_find_bus(pci_domain_nr(bus), busnr)) { + dev_info(&dev->dev, "bus %04x:%02x already known\n", + pci_domain_nr(bus), busnr); + goto out; } + child = pci_add_new_bus(bus, dev, busnr); + if (!child) + goto out; + child->primary = buses & 0xFF; + child->subordinate = (buses >> 16) & 0xFF; + child->bridge_ctl = bctl; + cmax = pci_scan_child_bus(child); if (cmax > max) max = cmax; @@ -674,19 +674,6 @@ static void pci_read_irq(struct pci_dev *dev) dev->irq = irq; } -static void set_pcie_port_type(struct pci_dev *pdev) -{ - int pos; - u16 reg16; - - pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); - if (!pos) - return; - pdev->is_pcie = 1; - pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); - pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; -} - #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) /** @@ -696,33 +683,12 @@ static void set_pcie_port_type(struct pci_dev *pdev) * Initialize the device structure with information about the device's * vendor,class,memory and IO-space addresses,IRQ lines etc. * Called at initialisation of the PCI subsystem and by CardBus services. - * Returns 0 on success and negative if unknown type of device (not normal, - * bridge or CardBus). + * Returns 0 on success and -1 if unknown type of device (not normal, bridge + * or CardBus). */ -int pci_setup_device(struct pci_dev *dev) +static int pci_setup_device(struct pci_dev * dev) { u32 class; - u8 hdr_type; - struct pci_slot *slot; - - if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) - return -EIO; - - dev->sysdata = dev->bus->sysdata; - dev->dev.parent = dev->bus->bridge; - dev->dev.bus = &pci_bus_type; - dev->hdr_type = hdr_type & 0x7f; - dev->multifunction = !!(hdr_type & 0x80); - dev->error_state = pci_channel_io_normal; - set_pcie_port_type(dev); - - list_for_each_entry(slot, &dev->bus->slots, list) - if (PCI_SLOT(dev->devfn) == slot->number) - dev->slot = slot; - - /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) - set this higher, assuming the system even supports it. */ - dev->dma_mask = 0xffffffff; dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus), dev->bus->number, PCI_SLOT(dev->devfn), @@ -737,14 +703,12 @@ int pci_setup_device(struct pci_dev *dev) dev_dbg(&dev->dev, "found [%04x:%04x] class %06x header type %02x\n", dev->vendor, dev->device, class, dev->hdr_type); - /* need to have dev->class ready */ - dev->cfg_size = pci_cfg_space_size(dev); - /* "Unknown power state" */ dev->current_state = PCI_UNKNOWN; /* Early fixups, before probing the BARs */ pci_fixup_device(pci_fixup_early, dev); + class = dev->class >> 8; switch (dev->hdr_type) { /* header type */ case PCI_HEADER_TYPE_NORMAL: /* standard header */ @@ -806,7 +770,7 @@ int pci_setup_device(struct pci_dev *dev) default: /* unknown header */ dev_err(&dev->dev, "unknown header type %02x, " "ignoring device\n", dev->hdr_type); - return -EIO; + return -1; bad: dev_err(&dev->dev, "ignoring class %02x (doesn't match header " @@ -821,7 +785,6 @@ int pci_setup_device(struct pci_dev *dev) static void pci_release_capabilities(struct pci_dev *dev) { pci_vpd_release(dev); - pci_iov_release(dev); } /** @@ -840,6 +803,19 @@ static void pci_release_dev(struct device *dev) kfree(pci_dev); } +static void set_pcie_port_type(struct pci_dev *pdev) +{ + int pos; + u16 reg16; + + pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); + if (!pos) + return; + pdev->is_pcie = 1; + pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); + pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; +} + /** * pci_cfg_space_size - get the configuration space size of the PCI device. * @dev: PCI device @@ -871,11 +847,6 @@ int pci_cfg_space_size(struct pci_dev *dev) { int pos; u32 status; - u16 class; - - class = dev->class >> 8; - if (class == PCI_CLASS_BRIDGE_HOST) - return pci_cfg_space_size_ext(dev); pos = pci_find_capability(dev, PCI_CAP_ID_EXP); if (!pos) { @@ -920,7 +891,9 @@ EXPORT_SYMBOL(alloc_pci_dev); static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) { struct pci_dev *dev; + struct pci_slot *slot; u32 l; + u8 hdr_type; int delay = 1; if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l)) @@ -947,16 +920,34 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) } } + if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type)) + return NULL; + dev = alloc_pci_dev(); if (!dev) return NULL; dev->bus = bus; + dev->sysdata = bus->sysdata; + dev->dev.parent = bus->bridge; + dev->dev.bus = &pci_bus_type; dev->devfn = devfn; + dev->hdr_type = hdr_type & 0x7f; + dev->multifunction = !!(hdr_type & 0x80); dev->vendor = l & 0xffff; dev->device = (l >> 16) & 0xffff; + dev->cfg_size = pci_cfg_space_size(dev); + dev->error_state = pci_channel_io_normal; + set_pcie_port_type(dev); + + list_for_each_entry(slot, &bus->slots, list) + if (PCI_SLOT(devfn) == slot->number) + dev->slot = slot; - if (pci_setup_device(dev)) { + /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) + set this higher, assuming the system even supports it. */ + dev->dma_mask = 0xffffffff; + if (pci_setup_device(dev) < 0) { kfree(dev); return NULL; } @@ -981,9 +972,6 @@ static void pci_init_capabilities(struct pci_dev *dev) /* Alternative Routing-ID Forwarding */ pci_enable_ari(dev); - - /* Single Root I/O Virtualization */ - pci_iov_init(dev); } void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) @@ -1018,12 +1006,6 @@ struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn) { struct pci_dev *dev; - dev = pci_get_slot(bus, devfn); - if (dev) { - pci_dev_put(dev); - return dev; - } - dev = pci_scan_device(bus, devfn); if (!dev) return NULL; @@ -1042,27 +1024,35 @@ EXPORT_SYMBOL(pci_scan_single_device); * Scan a PCI slot on the specified PCI bus for devices, adding * discovered devices to the @bus->devices list. New devices * will not have is_added set. - * - * Returns the number of new devices found. */ int pci_scan_slot(struct pci_bus *bus, int devfn) { - int fn, nr = 0; - struct pci_dev *dev; + int func, nr = 0; + int scan_all_fns; - dev = pci_scan_single_device(bus, devfn); - if (dev && !dev->is_added) /* new device? */ - nr++; - - if ((dev && dev->multifunction) || - (!dev && pcibios_scan_all_fns(bus, devfn))) { - for (fn = 1; fn < 8; fn++) { - dev = pci_scan_single_device(bus, devfn + fn); - if (dev) { - if (!dev->is_added) - nr++; - dev->multifunction = 1; + scan_all_fns = pcibios_scan_all_fns(bus, devfn); + + for (func = 0; func < 8; func++, devfn++) { + struct pci_dev *dev; + + dev = pci_scan_single_device(bus, devfn); + if (dev) { + nr++; + + /* + * If this is a single function device, + * don't scan past the first function. + */ + if (!dev->multifunction) { + if (func > 0) { + dev->multifunction = 1; + } else { + break; + } } + } else { + if (func == 0 && !scan_all_fns) + break; } } @@ -1084,21 +1074,12 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) for (devfn = 0; devfn < 0x100; devfn += 8) pci_scan_slot(bus, devfn); - /* Reserve buses for SR-IOV capability. */ - max += pci_iov_bus_range(bus); - /* * After performing arch-dependent fixup of the bus, look behind * all PCI-to-PCI bridges on this bus. */ - if (!bus->is_added) { - pr_debug("PCI: Fixups for bus %04x:%02x\n", - pci_domain_nr(bus), bus->number); - pcibios_fixup_bus(bus); - if (pci_is_root_bus(bus)) - bus->is_added = 1; - } - + pr_debug("PCI: Fixups for bus %04x:%02x\n", pci_domain_nr(bus), bus->number); + pcibios_fixup_bus(bus); for (pass=0; pass < 2; pass++) list_for_each_entry(dev, &bus->devices, bus_list) { if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || @@ -1133,7 +1114,7 @@ struct pci_bus * pci_create_bus(struct device *parent, if (!b) return NULL; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kmalloc(sizeof(*dev), GFP_KERNEL); if (!dev){ kfree(b); return NULL; @@ -1152,6 +1133,7 @@ struct pci_bus * pci_create_bus(struct device *parent, list_add_tail(&b->node, &pci_root_buses); up_write(&pci_bus_sem); + memset(dev, 0, sizeof(*dev)); dev->parent = parent; dev->release = pci_release_bus_bridge_dev; dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus); @@ -1211,38 +1193,6 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, EXPORT_SYMBOL(pci_scan_bus_parented); #ifdef CONFIG_HOTPLUG -/** - * pci_rescan_bus - scan a PCI bus for devices. - * @bus: PCI bus to scan - * - * Scan a PCI bus and child buses for new devices, adds them, - * and enables them. - * - * Returns the max number of subordinate bus discovered. - */ -unsigned int __devinit pci_rescan_bus(struct pci_bus *bus) -{ - unsigned int max; - struct pci_dev *dev; - - max = pci_scan_child_bus(bus); - - down_read(&pci_bus_sem); - list_for_each_entry(dev, &bus->devices, bus_list) - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || - dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) - if (dev->subordinate) - pci_bus_size_bridges(dev->subordinate); - up_read(&pci_bus_sem); - - pci_bus_assign_resources(bus); - pci_enable_bridges(bus); - pci_bus_add_devices(bus); - - return max; -} -EXPORT_SYMBOL_GPL(pci_rescan_bus); - EXPORT_SYMBOL(pci_add_new_bus); EXPORT_SYMBOL(pci_scan_slot); EXPORT_SYMBOL(pci_scan_bridge); diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index 9b2f0d96900d..92b9efe9bcaf 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -24,7 +24,6 @@ #include #include #include -#include #include "pci.h" int isa_dma_bridge_buggy; @@ -35,65 +34,6 @@ int pcie_mch_quirk; EXPORT_SYMBOL(pcie_mch_quirk); #ifdef CONFIG_PCI_QUIRKS -/* - * This quirk function disables the device and releases resources - * which is specified by kernel's boot parameter 'pci=resource_alignment='. - * It also rounds up size to specified alignment. - * Later on, the kernel will assign page-aligned memory resource back - * to that device. - */ -static void __devinit quirk_resource_alignment(struct pci_dev *dev) -{ - int i; - struct resource *r; - resource_size_t align, size; - - if (!pci_is_reassigndev(dev)) - return; - - if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL && - (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) { - dev_warn(&dev->dev, - "Can't reassign resources to host bridge.\n"); - return; - } - - dev_info(&dev->dev, "Disabling device and release resources.\n"); - pci_disable_device(dev); - - align = pci_specified_resource_alignment(dev); - for (i=0; i < PCI_BRIDGE_RESOURCES; i++) { - r = &dev->resource[i]; - if (!(r->flags & IORESOURCE_MEM)) - continue; - size = resource_size(r); - if (size < align) { - size = align; - dev_info(&dev->dev, - "Rounding up size of resource #%d to %#llx.\n", - i, (unsigned long long)size); - } - r->end = size - 1; - r->start = 0; - } - /* Need to disable bridge's resource window, - * to enable the kernel to reassign new resource - * window later on. - */ - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && - (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { - for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { - r = &dev->resource[i]; - if (!(r->flags & IORESOURCE_MEM)) - continue; - r->end = resource_size(r) - 1; - r->start = 0; - } - pci_disable_bridge_window(dev); - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment); - /* The Mellanox Tavor device gives false positive parity errors * Mark this device with a broken_parity_status, to allow * PCI scanning code to "skip" this now blacklisted device. @@ -1186,15 +1126,10 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) * its on-board VGA controller */ asus_hides_smbus = 1; } - else if (dev->device == PCI_DEVICE_ID_INTEL_82801DB_2) + else if (dev->device == PCI_DEVICE_ID_INTEL_82845G_IG) switch(dev->subsystem_device) { case 0x00b8: /* Compaq Evo D510 CMT */ case 0x00b9: /* Compaq Evo D510 SFF */ - /* Motherboard doesn't have Host bridge - * subvendor/subdevice IDs and on-board VGA - * controller is disabled if an AGP card is - * inserted, therefore checking USB UHCI - * Controller #1 */ asus_hides_smbus = 1; } else if (dev->device == PCI_DEVICE_ID_INTEL_82815_CGC) @@ -1219,7 +1154,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, as DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3, asus_hides_smbus_hostbridge); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_2, asus_hides_smbus_hostbridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG, asus_hides_smbus_hostbridge); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC, asus_hides_smbus_hostbridge); static void asus_hides_smbus_lpc(struct pci_dev *dev) @@ -1729,13 +1664,9 @@ static void __devinit quirk_netmos(struct pci_dev *dev) * of parallel ports and is the number of serial ports. */ switch (dev->device) { - case PCI_DEVICE_ID_NETMOS_9835: - /* Well, this rule doesn't hold for the following 9835 device */ - if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && - dev->subsystem_device == 0x0299) - return; case PCI_DEVICE_ID_NETMOS_9735: case PCI_DEVICE_ID_NETMOS_9745: + case PCI_DEVICE_ID_NETMOS_9835: case PCI_DEVICE_ID_NETMOS_9845: case PCI_DEVICE_ID_NETMOS_9855: if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_SERIAL && @@ -2147,92 +2078,6 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15, nvenet_msi_disable); -static int __devinit ht_check_msi_mapping(struct pci_dev *dev) -{ - int pos, ttl = 48; - int found = 0; - - /* check if there is HT MSI cap or enabled on this device */ - pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); - while (pos && ttl--) { - u8 flags; - - if (found < 1) - found = 1; - if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, - &flags) == 0) { - if (flags & HT_MSI_FLAGS_ENABLE) { - if (found < 2) { - found = 2; - break; - } - } - } - pos = pci_find_next_ht_capability(dev, pos, - HT_CAPTYPE_MSI_MAPPING); - } - - return found; -} - -static int __devinit host_bridge_with_leaf(struct pci_dev *host_bridge) -{ - struct pci_dev *dev; - int pos; - int i, dev_no; - int found = 0; - - dev_no = host_bridge->devfn >> 3; - for (i = dev_no + 1; i < 0x20; i++) { - dev = pci_get_slot(host_bridge->bus, PCI_DEVFN(i, 0)); - if (!dev) - continue; - - /* found next host bridge ?*/ - pos = pci_find_ht_capability(dev, HT_CAPTYPE_SLAVE); - if (pos != 0) { - pci_dev_put(dev); - break; - } - - if (ht_check_msi_mapping(dev)) { - found = 1; - pci_dev_put(dev); - break; - } - pci_dev_put(dev); - } - - return found; -} - -#define PCI_HT_CAP_SLAVE_CTRL0 4 /* link control */ -#define PCI_HT_CAP_SLAVE_CTRL1 8 /* link control to */ - -static int __devinit is_end_of_ht_chain(struct pci_dev *dev) -{ - int pos, ctrl_off; - int end = 0; - u16 flags, ctrl; - - pos = pci_find_ht_capability(dev, HT_CAPTYPE_SLAVE); - - if (!pos) - goto out; - - pci_read_config_word(dev, pos + PCI_CAP_FLAGS, &flags); - - ctrl_off = ((flags >> 10) & 1) ? - PCI_HT_CAP_SLAVE_CTRL0 : PCI_HT_CAP_SLAVE_CTRL1; - pci_read_config_word(dev, pos + ctrl_off, &ctrl); - - if (ctrl & (1 << 6)) - end = 1; - -out: - return end; -} - static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev) { struct pci_dev *host_bridge; @@ -2257,11 +2102,6 @@ static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev) if (!found) return; - /* don't enable end_device/host_bridge with leaf directly here */ - if (host_bridge == dev && is_end_of_ht_chain(host_bridge) && - host_bridge_with_leaf(host_bridge)) - goto out; - /* root did that ! */ if (msi_ht_cap_enabled(host_bridge)) goto out; @@ -2292,12 +2132,44 @@ static void __devinit ht_disable_msi_mapping(struct pci_dev *dev) } } -static void __devinit __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all) +static int __devinit ht_check_msi_mapping(struct pci_dev *dev) +{ + int pos, ttl = 48; + int found = 0; + + /* check if there is HT MSI cap or enabled on this device */ + pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); + while (pos && ttl--) { + u8 flags; + + if (found < 1) + found = 1; + if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, + &flags) == 0) { + if (flags & HT_MSI_FLAGS_ENABLE) { + if (found < 2) { + found = 2; + break; + } + } + } + pos = pci_find_next_ht_capability(dev, pos, + HT_CAPTYPE_MSI_MAPPING); + } + + return found; +} + +static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) { struct pci_dev *host_bridge; int pos; int found; + /* Enabling HT MSI mapping on this device breaks MCP51 */ + if (dev->device == 0x270) + return; + /* check if there is HT MSI cap or enabled on this device */ found = ht_check_msi_mapping(dev); @@ -2321,10 +2193,7 @@ static void __devinit __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all) /* Host bridge is to HT */ if (found == 1) { /* it is not enabled, try to enable it */ - if (all) - ht_enable_msi_mapping(dev); - else - nv_ht_enable_msi_mapping(dev); + nv_ht_enable_msi_mapping(dev); } return; } @@ -2336,20 +2205,8 @@ static void __devinit __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all) /* Host bridge is not to HT, disable HT MSI mapping on this device */ ht_disable_msi_mapping(dev); } - -static void __devinit nv_msi_ht_cap_quirk_all(struct pci_dev *dev) -{ - return __nv_msi_ht_cap_quirk(dev, 1); -} - -static void __devinit nv_msi_ht_cap_quirk_leaf(struct pci_dev *dev) -{ - return __nv_msi_ht_cap_quirk(dev, 0); -} - -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk_leaf); - -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk_all); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk); static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev) { diff --git a/trunk/drivers/pci/remove.c b/trunk/drivers/pci/remove.c index 86503c14ce7e..042e08924421 100644 --- a/trunk/drivers/pci/remove.c +++ b/trunk/drivers/pci/remove.c @@ -71,9 +71,6 @@ void pci_remove_bus(struct pci_bus *pci_bus) down_write(&pci_bus_sem); list_del(&pci_bus->node); up_write(&pci_bus_sem); - if (!pci_bus->is_added) - return; - pci_remove_legacy_files(pci_bus); device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity); device_remove_file(&pci_bus->dev, &dev_attr_cpulistaffinity); @@ -95,7 +92,6 @@ EXPORT_SYMBOL(pci_remove_bus); */ void pci_remove_bus_device(struct pci_dev *dev) { - pci_stop_bus_device(dev); if (dev->subordinate) { struct pci_bus *b = dev->subordinate; diff --git a/trunk/drivers/pci/search.c b/trunk/drivers/pci/search.c index 710d4ea69568..5af8bd538149 100644 --- a/trunk/drivers/pci/search.c +++ b/trunk/drivers/pci/search.c @@ -29,7 +29,7 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev) if (pdev->is_pcie) return NULL; while (1) { - if (!pdev->bus->parent) + if (!pdev->bus->self) break; pdev = pdev->bus->self; /* a p2p bridge */ diff --git a/trunk/drivers/pci/setup-bus.c b/trunk/drivers/pci/setup-bus.c index 334285a8e237..704608945780 100644 --- a/trunk/drivers/pci/setup-bus.c +++ b/trunk/drivers/pci/setup-bus.c @@ -27,7 +27,7 @@ #include -static void pbus_assign_resources_sorted(const struct pci_bus *bus) +static void pbus_assign_resources_sorted(struct pci_bus *bus) { struct pci_dev *dev; struct resource *res; @@ -144,9 +144,6 @@ static void pci_setup_bridge(struct pci_bus *bus) struct pci_bus_region region; u32 l, bu, lu, io_upper16; - if (!pci_is_root_bus(bus) && bus->is_added) - return; - dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n", pci_domain_nr(bus), bus->number); @@ -498,7 +495,7 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus) } EXPORT_SYMBOL(pci_bus_size_bridges); -void __ref pci_bus_assign_resources(const struct pci_bus *bus) +void __ref pci_bus_assign_resources(struct pci_bus *bus) { struct pci_bus *b; struct pci_dev *dev; diff --git a/trunk/drivers/pci/setup-res.c b/trunk/drivers/pci/setup-res.c index 3039fcb86afc..32e8d88a4619 100644 --- a/trunk/drivers/pci/setup-res.c +++ b/trunk/drivers/pci/setup-res.c @@ -120,21 +120,6 @@ int pci_claim_resource(struct pci_dev *dev, int resource) return err; } -#ifdef CONFIG_PCI_QUIRKS -void pci_disable_bridge_window(struct pci_dev *dev) -{ - dev_dbg(&dev->dev, "Disabling bridge window.\n"); - - /* MMIO Base/Limit */ - pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0); - - /* Prefetchable MMIO Base/Limit */ - pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0); - pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0); - pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff); -} -#endif /* CONFIG_PCI_QUIRKS */ - int pci_assign_resource(struct pci_dev *dev, int resno) { struct pci_bus *bus = dev->bus; diff --git a/trunk/drivers/pci/slot.c b/trunk/drivers/pci/slot.c index 21189447e545..5a8ccb4f604d 100644 --- a/trunk/drivers/pci/slot.c +++ b/trunk/drivers/pci/slot.c @@ -1,8 +1,8 @@ /* * drivers/pci/slot.c * Copyright (C) 2006 Matthew Wilcox - * Copyright (C) 2006-2009 Hewlett-Packard Development Company, L.P. - * Alex Chiang + * Copyright (C) 2006-2008 Hewlett-Packard Development Company, L.P. + * Alex Chiang */ #include @@ -52,8 +52,8 @@ static void pci_slot_release(struct kobject *kobj) struct pci_dev *dev; struct pci_slot *slot = to_pci_slot(kobj); - dev_dbg(&slot->bus->dev, "dev %02x, released physical slot %s\n", - slot->number, pci_slot_name(slot)); + pr_debug("%s: releasing pci_slot on %x:%d\n", __func__, + slot->bus->number, slot->number); list_for_each_entry(dev, &slot->bus->devices, bus_list) if (PCI_SLOT(dev->devfn) == slot->number) @@ -248,8 +248,9 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, if (PCI_SLOT(dev->devfn) == slot_nr) dev->slot = slot; - dev_dbg(&parent->dev, "dev %02x, created physical slot %s\n", - slot_nr, pci_slot_name(slot)); + /* Don't care if debug printk has a -1 for slot_nr */ + pr_debug("%s: created pci_slot on %04x:%02x:%02x\n", + __func__, pci_domain_nr(parent), parent->number, slot_nr); out: kfree(slot_name); @@ -298,8 +299,9 @@ EXPORT_SYMBOL_GPL(pci_renumber_slot); */ void pci_destroy_slot(struct pci_slot *slot) { - dev_dbg(&slot->bus->dev, "dev %02x, dec refcount to %d\n", - slot->number, atomic_read(&slot->kobj.kref.refcount) - 1); + pr_debug("%s: dec refcount to %d on %04x:%02x:%02x\n", __func__, + atomic_read(&slot->kobj.kref.refcount) - 1, + pci_domain_nr(slot->bus), slot->bus->number, slot->number); down_write(&pci_bus_sem); kobject_put(&slot->kobj); diff --git a/trunk/drivers/platform/x86/asus_acpi.c b/trunk/drivers/platform/x86/asus_acpi.c index ba1f7497e4b9..d63f26e666a4 100644 --- a/trunk/drivers/platform/x86/asus_acpi.c +++ b/trunk/drivers/platform/x86/asus_acpi.c @@ -987,6 +987,7 @@ asus_proc_add(char *name, proc_writefunc *writefunc, proc->write_proc = writefunc; proc->read_proc = readfunc; proc->data = acpi_driver_data(device); + proc->owner = THIS_MODULE; proc->uid = asus_uid; proc->gid = asus_gid; return 0; @@ -1019,6 +1020,7 @@ static int asus_hotk_add_fs(struct acpi_device *device) if (proc) { proc->read_proc = proc_read_info; proc->data = acpi_driver_data(device); + proc->owner = THIS_MODULE; proc->uid = asus_uid; proc->gid = asus_gid; } else { @@ -1434,6 +1436,7 @@ static int __init asus_acpi_init(void) printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n"); return -ENODEV; } + asus_proc_dir->owner = THIS_MODULE; result = acpi_bus_register_driver(&asus_hotk_driver); if (result < 0) { diff --git a/trunk/drivers/platform/x86/dell-laptop.c b/trunk/drivers/platform/x86/dell-laptop.c index af9f43021172..16e11c2ee19a 100644 --- a/trunk/drivers/platform/x86/dell-laptop.c +++ b/trunk/drivers/platform/x86/dell-laptop.c @@ -103,7 +103,7 @@ static void parse_da_table(const struct dmi_header *dm) da_num_tokens += tokens; } -static void find_tokens(const struct dmi_header *dm, void *dummy) +static void find_tokens(const struct dmi_header *dm) { switch (dm->type) { case 0xd4: /* Indexed IO */ @@ -356,7 +356,7 @@ static int __init dell_init(void) if (!dmi_check_system(dell_device_table)) return -ENODEV; - dmi_walk(find_tokens, NULL); + dmi_walk(find_tokens); if (!da_tokens) { printk(KERN_INFO "dell-laptop: Unable to find dmi tokens\n"); diff --git a/trunk/drivers/platform/x86/thinkpad_acpi.c b/trunk/drivers/platform/x86/thinkpad_acpi.c index 3dad27a385d3..d2433204a40c 100644 --- a/trunk/drivers/platform/x86/thinkpad_acpi.c +++ b/trunk/drivers/platform/x86/thinkpad_acpi.c @@ -6992,6 +6992,7 @@ static int __init ibm_init(struct ibm_init_struct *iibm) ret = -ENODEV; goto err_out; } + entry->owner = THIS_MODULE; entry->data = ibm; entry->read_proc = &dispatch_procfs_read; if (ibm->write) @@ -7404,6 +7405,7 @@ static int __init thinkpad_acpi_module_init(void) thinkpad_acpi_module_exit(); return -ENODEV; } + proc_dir->owner = THIS_MODULE; ret = platform_driver_register(&tpacpi_pdriver); if (ret) { diff --git a/trunk/drivers/platform/x86/toshiba_acpi.c b/trunk/drivers/platform/x86/toshiba_acpi.c index 9f187265db8e..40e60fc2e596 100644 --- a/trunk/drivers/platform/x86/toshiba_acpi.c +++ b/trunk/drivers/platform/x86/toshiba_acpi.c @@ -679,6 +679,8 @@ static acpi_status __init add_device(void) toshiba_proc_dir, (read_proc_t *) dispatch_read, item); + if (proc) + proc->owner = THIS_MODULE; if (proc && item->write_func) proc->write_proc = (write_proc_t *) dispatch_write; } @@ -770,6 +772,7 @@ static int __init toshiba_acpi_init(void) toshiba_acpi_exit(); return -ENODEV; } else { + toshiba_proc_dir->owner = THIS_MODULE; status = add_device(); if (ACPI_FAILURE(status)) { toshiba_acpi_exit(); diff --git a/trunk/drivers/pnp/pnpbios/core.c b/trunk/drivers/pnp/pnpbios/core.c index cfe86853feb2..996f64838079 100644 --- a/trunk/drivers/pnp/pnpbios/core.c +++ b/trunk/drivers/pnp/pnpbios/core.c @@ -94,6 +94,7 @@ struct pnp_dev_node_info node_info; #ifdef CONFIG_HOTPLUG +static int unloading = 0; static struct completion unload_sem; /* @@ -157,7 +158,7 @@ static int pnp_dock_thread(void *unused) int docked = -1, d = 0; set_freezable(); - while (1) { + while (!unloading) { int status; /* @@ -574,6 +575,8 @@ fs_initcall(pnpbios_init); static int __init pnpbios_thread_init(void) { + struct task_struct *task; + #if defined(CONFIG_PPC) if (check_legacy_ioport(PNPBIOS_BASE)) return 0; @@ -581,13 +584,10 @@ static int __init pnpbios_thread_init(void) if (pnpbios_disabled) return 0; #ifdef CONFIG_HOTPLUG - { - struct task_struct *task; - init_completion(&unload_sem); - task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd"); - if (IS_ERR(task)) - return PTR_ERR(task); - } + init_completion(&unload_sem); + task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd"); + if (!IS_ERR(task)) + unloading = 0; #endif return 0; } diff --git a/trunk/drivers/ps3/ps3av.c b/trunk/drivers/ps3/ps3av.c index 235e87fcb49f..5324978b73fb 100644 --- a/trunk/drivers/ps3/ps3av.c +++ b/trunk/drivers/ps3/ps3av.c @@ -838,7 +838,7 @@ static int ps3av_get_hw_conf(struct ps3av *ps3av) } /* set mode using id */ -int ps3av_set_video_mode(int id) +int ps3av_set_video_mode(u32 id) { int size; u32 option; @@ -940,7 +940,7 @@ EXPORT_SYMBOL_GPL(ps3av_audio_mute); static int ps3av_probe(struct ps3_system_bus_device *dev) { int res; - int id; + u32 id; dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); dev_dbg(&dev->core, " timeout=%d\n", timeout); @@ -962,10 +962,8 @@ static int ps3av_probe(struct ps3_system_bus_device *dev) init_completion(&ps3av->done); complete(&ps3av->done); ps3av->wq = create_singlethread_workqueue("ps3avd"); - if (!ps3av->wq) { - res = -ENOMEM; + if (!ps3av->wq) goto fail; - } switch (ps3_os_area_get_av_multi_out()) { case PS3_PARAM_AV_MULTI_OUT_NTSC: @@ -996,12 +994,6 @@ static int ps3av_probe(struct ps3_system_bus_device *dev) safe_mode = 1; #endif /* CONFIG_FB */ id = ps3av_auto_videomode(&ps3av->av_hw_conf); - if (id < 0) { - printk(KERN_ERR "%s: invalid id :%d\n", __func__, id); - res = -EINVAL; - goto fail; - } - safe_mode = 0; mutex_lock(&ps3av->mutex); @@ -1015,7 +1007,7 @@ static int ps3av_probe(struct ps3_system_bus_device *dev) fail: kfree(ps3av); ps3av = NULL; - return res; + return -ENOMEM; } static int ps3av_remove(struct ps3_system_bus_device *dev) diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index 56002f7d26bd..81450fbd8b12 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -129,14 +129,13 @@ comment "I2C RTC drivers" if I2C config RTC_DRV_DS1307 - tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025" + tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00" help If you say yes here you get support for various compatible RTC chips (often with battery backup) connected with I2C. This driver should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00, - EPSON RX-8025 and probably other chips. In some cases the RTC - must already have been initialized (by manufacturing or a - bootloader). + and probably other chips. In some cases the RTC must already + have been initialized (by manufacturing or a bootloader). The first seven registers on these chips hold an RTC, and other registers may add features such as NVRAM, a trickle charger for @@ -225,11 +224,11 @@ config RTC_DRV_PCF8583 will be called rtc-pcf8583. config RTC_DRV_M41T80 - tristate "ST M41T62/65/M41T80/81/82/83/84/85/87" + tristate "ST M41T65/M41T80/81/82/83/84/85/87" help If you say Y here you will get support for the ST M41T60 and M41T80 RTC chips series. Currently, the following chips are - supported: M41T62, M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84, + supported: M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84, M41ST85, and M41ST87. This driver can also be built as a module. If so, the module @@ -441,16 +440,6 @@ config RTC_DRV_DS1742 This driver can also be built as a module. If so, the module will be called rtc-ds1742. -config RTC_DRV_EFI - tristate "EFI RTC" - depends on IA64 - help - If you say yes here you will get support for the EFI - Real Time Clock. - - This driver can also be built as a module. If so, the module - will be called rtc-efi. - config RTC_DRV_STK17TA8 tristate "Simtek STK17TA8" depends on RTC_CLASS diff --git a/trunk/drivers/rtc/Makefile b/trunk/drivers/rtc/Makefile index e7b09986d26e..0e697aa51caa 100644 --- a/trunk/drivers/rtc/Makefile +++ b/trunk/drivers/rtc/Makefile @@ -36,7 +36,6 @@ obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o -obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o diff --git a/trunk/drivers/rtc/rtc-ds1307.c b/trunk/drivers/rtc/rtc-ds1307.c index 2c4a65302a9d..7e5155e88ac7 100644 --- a/trunk/drivers/rtc/rtc-ds1307.c +++ b/trunk/drivers/rtc/rtc-ds1307.c @@ -3,7 +3,6 @@ * * Copyright (C) 2005 James Chapman (ds1337 core) * Copyright (C) 2006 David Brownell - * Copyright (C) 2009 Matthias Fuchs (rx8025 support) * * 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 @@ -32,7 +31,6 @@ enum ds_type { ds_1339, ds_1340, m41t00, - rx_8025, // rs5c372 too? different address... }; @@ -85,12 +83,6 @@ enum ds_type { #define DS1339_REG_ALARM1_SECS 0x07 #define DS1339_REG_TRICKLE 0x10 -#define RX8025_REG_CTRL1 0x0e -# define RX8025_BIT_2412 0x20 -#define RX8025_REG_CTRL2 0x0f -# define RX8025_BIT_PON 0x10 -# define RX8025_BIT_VDET 0x40 -# define RX8025_BIT_XST 0x20 struct ds1307 { @@ -102,10 +94,6 @@ struct ds1307 { struct i2c_client *client; struct rtc_device *rtc; struct work_struct work; - s32 (*read_block_data)(struct i2c_client *client, u8 command, - u8 length, u8 *values); - s32 (*write_block_data)(struct i2c_client *client, u8 command, - u8 length, const u8 *values); }; struct chip_desc { @@ -129,8 +117,6 @@ static const struct chip_desc chips[] = { [ds_1340] = { }, [m41t00] = { -}, -[rx_8025] = { }, }; static const struct i2c_device_id ds1307_id[] = { @@ -140,86 +126,12 @@ static const struct i2c_device_id ds1307_id[] = { { "ds1339", ds_1339 }, { "ds1340", ds_1340 }, { "m41t00", m41t00 }, - { "rx8025", rx_8025 }, { } }; MODULE_DEVICE_TABLE(i2c, ds1307_id); /*----------------------------------------------------------------------*/ -#define BLOCK_DATA_MAX_TRIES 10 - -static s32 ds1307_read_block_data_once(struct i2c_client *client, u8 command, - u8 length, u8 *values) -{ - s32 i, data; - - for (i = 0; i < length; i++) { - data = i2c_smbus_read_byte_data(client, command + i); - if (data < 0) - return data; - values[i] = data; - } - return i; -} - -static s32 ds1307_read_block_data(struct i2c_client *client, u8 command, - u8 length, u8 *values) -{ - u8 oldvalues[I2C_SMBUS_BLOCK_MAX]; - s32 ret; - int tries = 0; - - dev_dbg(&client->dev, "ds1307_read_block_data (length=%d)\n", length); - ret = ds1307_read_block_data_once(client, command, length, values); - if (ret < 0) - return ret; - do { - if (++tries > BLOCK_DATA_MAX_TRIES) { - dev_err(&client->dev, - "ds1307_read_block_data failed\n"); - return -EIO; - } - memcpy(oldvalues, values, length); - ret = ds1307_read_block_data_once(client, command, length, - values); - if (ret < 0) - return ret; - } while (memcmp(oldvalues, values, length)); - return length; -} - -static s32 ds1307_write_block_data(struct i2c_client *client, u8 command, - u8 length, const u8 *values) -{ - u8 currvalues[I2C_SMBUS_BLOCK_MAX]; - int tries = 0; - - dev_dbg(&client->dev, "ds1307_write_block_data (length=%d)\n", length); - do { - s32 i, ret; - - if (++tries > BLOCK_DATA_MAX_TRIES) { - dev_err(&client->dev, - "ds1307_write_block_data failed\n"); - return -EIO; - } - for (i = 0; i < length; i++) { - ret = i2c_smbus_write_byte_data(client, command + i, - values[i]); - if (ret < 0) - return ret; - } - ret = ds1307_read_block_data_once(client, command, length, - currvalues); - if (ret < 0) - return ret; - } while (memcmp(currvalues, values, length)); - return length; -} - -/*----------------------------------------------------------------------*/ - /* * The IRQ logic includes a "real" handler running in IRQ context just * long enough to schedule this workqueue entry. We need a task context @@ -290,7 +202,7 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) int tmp; /* read the RTC date and time registers all at once */ - tmp = ds1307->read_block_data(ds1307->client, + tmp = i2c_smbus_read_i2c_block_data(ds1307->client, DS1307_REG_SECS, 7, ds1307->regs); if (tmp != 7) { dev_err(dev, "%s error %d\n", "read", tmp); @@ -367,7 +279,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) "write", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); - result = ds1307->write_block_data(ds1307->client, 0, 7, buf); + result = i2c_smbus_write_i2c_block_data(ds1307->client, 0, 7, buf); if (result < 0) { dev_err(dev, "%s error %d\n", "write", result); return result; @@ -385,7 +297,7 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) return -EINVAL; /* read all ALARM1, ALARM2, and status registers at once */ - ret = ds1307->read_block_data(client, + ret = i2c_smbus_read_i2c_block_data(client, DS1339_REG_ALARM1_SECS, 9, ds1307->regs); if (ret != 9) { dev_err(dev, "%s error %d\n", "alarm read", ret); @@ -444,7 +356,7 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) t->enabled, t->pending); /* read current status of both alarms and the chip */ - ret = ds1307->read_block_data(client, + ret = i2c_smbus_read_i2c_block_data(client, DS1339_REG_ALARM1_SECS, 9, buf); if (ret != 9) { dev_err(dev, "%s error %d\n", "alarm write", ret); @@ -479,7 +391,7 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) } buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I); - ret = ds1307->write_block_data(client, + ret = i2c_smbus_write_i2c_block_data(client, DS1339_REG_ALARM1_SECS, 9, buf); if (ret < 0) { dev_err(dev, "can't set alarm time\n"); @@ -567,7 +479,7 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, if (unlikely(!count)) return count; - result = ds1307->read_block_data(client, 8 + off, count, buf); + result = i2c_smbus_read_i2c_block_data(client, 8 + off, count, buf); if (result < 0) dev_err(&client->dev, "%s error %d\n", "nvram read", result); return result; @@ -578,11 +490,9 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct i2c_client *client; - struct ds1307 *ds1307; int result; client = kobj_to_i2c_client(kobj); - ds1307 = i2c_get_clientdata(client); if (unlikely(off >= NVRAM_SIZE)) return -EFBIG; @@ -591,7 +501,7 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, if (unlikely(!count)) return count; - result = ds1307->write_block_data(client, 8 + off, count, buf); + result = i2c_smbus_write_i2c_block_data(client, 8 + off, count, buf); if (result < 0) { dev_err(&client->dev, "%s error %d\n", "nvram write", result); return result; @@ -625,8 +535,9 @@ static int __devinit ds1307_probe(struct i2c_client *client, int want_irq = false; unsigned char *buf; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA) - && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) + if (!i2c_check_functionality(adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) return -EIO; if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) @@ -636,13 +547,6 @@ static int __devinit ds1307_probe(struct i2c_client *client, i2c_set_clientdata(client, ds1307); ds1307->type = id->driver_data; buf = ds1307->regs; - if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { - ds1307->read_block_data = i2c_smbus_read_i2c_block_data; - ds1307->write_block_data = i2c_smbus_write_i2c_block_data; - } else { - ds1307->read_block_data = ds1307_read_block_data; - ds1307->write_block_data = ds1307_write_block_data; - } switch (ds1307->type) { case ds_1337: @@ -653,7 +557,7 @@ static int __devinit ds1307_probe(struct i2c_client *client, want_irq = true; } /* get registers that the "rtc" read below won't read... */ - tmp = ds1307->read_block_data(ds1307->client, + tmp = i2c_smbus_read_i2c_block_data(ds1307->client, DS1337_REG_CONTROL, 2, buf); if (tmp != 2) { pr_debug("read error %d\n", tmp); @@ -685,79 +589,13 @@ static int __devinit ds1307_probe(struct i2c_client *client, dev_warn(&client->dev, "SET TIME!\n"); } break; - - case rx_8025: - tmp = i2c_smbus_read_i2c_block_data(ds1307->client, - RX8025_REG_CTRL1 << 4 | 0x08, 2, buf); - if (tmp != 2) { - pr_debug("read error %d\n", tmp); - err = -EIO; - goto exit_free; - } - - /* oscillator off? turn it on, so clock can tick. */ - if (!(ds1307->regs[1] & RX8025_BIT_XST)) { - ds1307->regs[1] |= RX8025_BIT_XST; - i2c_smbus_write_byte_data(client, - RX8025_REG_CTRL2 << 4 | 0x08, - ds1307->regs[1]); - dev_warn(&client->dev, - "oscillator stop detected - SET TIME!\n"); - } - - if (ds1307->regs[1] & RX8025_BIT_PON) { - ds1307->regs[1] &= ~RX8025_BIT_PON; - i2c_smbus_write_byte_data(client, - RX8025_REG_CTRL2 << 4 | 0x08, - ds1307->regs[1]); - dev_warn(&client->dev, "power-on detected\n"); - } - - if (ds1307->regs[1] & RX8025_BIT_VDET) { - ds1307->regs[1] &= ~RX8025_BIT_VDET; - i2c_smbus_write_byte_data(client, - RX8025_REG_CTRL2 << 4 | 0x08, - ds1307->regs[1]); - dev_warn(&client->dev, "voltage drop detected\n"); - } - - /* make sure we are running in 24hour mode */ - if (!(ds1307->regs[0] & RX8025_BIT_2412)) { - u8 hour; - - /* switch to 24 hour mode */ - i2c_smbus_write_byte_data(client, - RX8025_REG_CTRL1 << 4 | 0x08, - ds1307->regs[0] | - RX8025_BIT_2412); - - tmp = i2c_smbus_read_i2c_block_data(ds1307->client, - RX8025_REG_CTRL1 << 4 | 0x08, 2, buf); - if (tmp != 2) { - pr_debug("read error %d\n", tmp); - err = -EIO; - goto exit_free; - } - - /* correct hour */ - hour = bcd2bin(ds1307->regs[DS1307_REG_HOUR]); - if (hour == 12) - hour = 0; - if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM) - hour += 12; - - i2c_smbus_write_byte_data(client, - DS1307_REG_HOUR << 4 | 0x08, - hour); - } - break; default: break; } read_rtc: /* read RTC registers */ - tmp = ds1307->read_block_data(ds1307->client, 0, 8, buf); + tmp = i2c_smbus_read_i2c_block_data(ds1307->client, 0, 8, buf); if (tmp != 8) { pr_debug("read error %d\n", tmp); err = -EIO; @@ -811,7 +649,6 @@ static int __devinit ds1307_probe(struct i2c_client *client, dev_warn(&client->dev, "SET TIME!\n"); } break; - case rx_8025: case ds_1337: case ds_1339: break; @@ -825,8 +662,6 @@ static int __devinit ds1307_probe(struct i2c_client *client, * systems that will run through year 2100. */ break; - case rx_8025: - break; default: if (!(tmp & DS1307_BIT_12HR)) break; diff --git a/trunk/drivers/rtc/rtc-ds1374.c b/trunk/drivers/rtc/rtc-ds1374.c index 4d32e328f6cd..a5b0fc09f0c6 100644 --- a/trunk/drivers/rtc/rtc-ds1374.c +++ b/trunk/drivers/rtc/rtc-ds1374.c @@ -222,16 +222,16 @@ static int ds1374_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) rtc_tm_to_time(&alarm->time, &new_alarm); rtc_tm_to_time(&now, &itime); + new_alarm -= itime; + /* This can happen due to races, in addition to dates that are * truly in the past. To avoid requiring the caller to check for * races, dates in the past are assumed to be in the recent past * (i.e. not something that we'd rather the caller know about via * an error), and the alarm is set to go off as soon as possible. */ - if (time_before_eq(new_alarm, itime)) + if (new_alarm <= 0) new_alarm = 1; - else - new_alarm -= itime; mutex_lock(&ds1374->mutex); diff --git a/trunk/drivers/rtc/rtc-efi.c b/trunk/drivers/rtc/rtc-efi.c deleted file mode 100644 index 550292304b0f..000000000000 --- a/trunk/drivers/rtc/rtc-efi.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * rtc-efi: RTC Class Driver for EFI-based systems - * - * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. - * - * Author: dann frazier - * Based on efirtc.c by Stephane Eranian - * - * 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 - -#define EFI_ISDST (EFI_TIME_ADJUST_DAYLIGHT|EFI_TIME_IN_DAYLIGHT) -/* - * EFI Epoch is 1/1/1998 - */ -#define EFI_RTC_EPOCH 1998 - -/* - * returns day of the year [0-365] - */ -static inline int -compute_yday(efi_time_t *eft) -{ - /* efi_time_t.month is in the [1-12] so, we need -1 */ - return rtc_year_days(eft->day - 1, eft->month - 1, eft->year); -} -/* - * returns day of the week [0-6] 0=Sunday - * - * Don't try to provide a year that's before 1998, please ! - */ -static int -compute_wday(efi_time_t *eft) -{ - int y; - int ndays = 0; - - if (eft->year < 1998) { - printk(KERN_ERR "efirtc: EFI year < 1998, invalid date\n"); - return -1; - } - - for (y = EFI_RTC_EPOCH; y < eft->year; y++) - ndays += 365 + (is_leap_year(y) ? 1 : 0); - - ndays += compute_yday(eft); - - /* - * 4=1/1/1998 was a Thursday - */ - return (ndays + 4) % 7; -} - -static void -convert_to_efi_time(struct rtc_time *wtime, efi_time_t *eft) -{ - eft->year = wtime->tm_year + 1900; - eft->month = wtime->tm_mon + 1; - eft->day = wtime->tm_mday; - eft->hour = wtime->tm_hour; - eft->minute = wtime->tm_min; - eft->second = wtime->tm_sec; - eft->nanosecond = 0; - eft->daylight = wtime->tm_isdst ? EFI_ISDST : 0; - eft->timezone = EFI_UNSPECIFIED_TIMEZONE; -} - -static void -convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime) -{ - memset(wtime, 0, sizeof(*wtime)); - wtime->tm_sec = eft->second; - wtime->tm_min = eft->minute; - wtime->tm_hour = eft->hour; - wtime->tm_mday = eft->day; - wtime->tm_mon = eft->month - 1; - wtime->tm_year = eft->year - 1900; - - /* day of the week [0-6], Sunday=0 */ - wtime->tm_wday = compute_wday(eft); - - /* day in the year [1-365]*/ - wtime->tm_yday = compute_yday(eft); - - - switch (eft->daylight & EFI_ISDST) { - case EFI_ISDST: - wtime->tm_isdst = 1; - break; - case EFI_TIME_ADJUST_DAYLIGHT: - wtime->tm_isdst = 0; - break; - default: - wtime->tm_isdst = -1; - } -} - -static int efi_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) -{ - efi_time_t eft; - efi_status_t status; - - /* - * As of EFI v1.10, this call always returns an unsupported status - */ - status = efi.get_wakeup_time((efi_bool_t *)&wkalrm->enabled, - (efi_bool_t *)&wkalrm->pending, &eft); - - if (status != EFI_SUCCESS) - return -EINVAL; - - convert_from_efi_time(&eft, &wkalrm->time); - - return rtc_valid_tm(&wkalrm->time); -} - -static int efi_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) -{ - efi_time_t eft; - efi_status_t status; - - convert_to_efi_time(&wkalrm->time, &eft); - - /* - * XXX Fixme: - * As of EFI 0.92 with the firmware I have on my - * machine this call does not seem to work quite - * right - * - * As of v1.10, this call always returns an unsupported status - */ - status = efi.set_wakeup_time((efi_bool_t)wkalrm->enabled, &eft); - - printk(KERN_WARNING "write status is %d\n", (int)status); - - return status == EFI_SUCCESS ? 0 : -EINVAL; -} - -static int efi_read_time(struct device *dev, struct rtc_time *tm) -{ - efi_status_t status; - efi_time_t eft; - efi_time_cap_t cap; - - status = efi.get_time(&eft, &cap); - - if (status != EFI_SUCCESS) { - /* should never happen */ - printk(KERN_ERR "efitime: can't read time\n"); - return -EINVAL; - } - - convert_from_efi_time(&eft, tm); - - return rtc_valid_tm(tm); -} - -static int efi_set_time(struct device *dev, struct rtc_time *tm) -{ - efi_status_t status; - efi_time_t eft; - - convert_to_efi_time(tm, &eft); - - status = efi.set_time(&eft); - - return status == EFI_SUCCESS ? 0 : -EINVAL; -} - -static const struct rtc_class_ops efi_rtc_ops = { - .read_time = efi_read_time, - .set_time = efi_set_time, - .read_alarm = efi_read_alarm, - .set_alarm = efi_set_alarm, -}; - -static int __init efi_rtc_probe(struct platform_device *dev) -{ - struct rtc_device *rtc; - - rtc = rtc_device_register("rtc-efi", &dev->dev, &efi_rtc_ops, - THIS_MODULE); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); - - platform_set_drvdata(dev, rtc); - - return 0; -} - -static int __exit efi_rtc_remove(struct platform_device *dev) -{ - struct rtc_device *rtc = platform_get_drvdata(dev); - - rtc_device_unregister(rtc); - - return 0; -} - -static struct platform_driver efi_rtc_driver = { - .driver = { - .name = "rtc-efi", - .owner = THIS_MODULE, - }, - .probe = efi_rtc_probe, - .remove = __exit_p(efi_rtc_remove), -}; - -static int __init efi_rtc_init(void) -{ - return platform_driver_probe(&efi_rtc_driver, efi_rtc_probe); -} - -static void __exit efi_rtc_exit(void) -{ - platform_driver_unregister(&efi_rtc_driver); -} - -module_init(efi_rtc_init); -module_exit(efi_rtc_exit); - -MODULE_AUTHOR("dann frazier "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("EFI RTC driver"); diff --git a/trunk/drivers/rtc/rtc-lib.c b/trunk/drivers/rtc/rtc-lib.c index 773851f338b8..dd70bf73ce9d 100644 --- a/trunk/drivers/rtc/rtc-lib.c +++ b/trunk/drivers/rtc/rtc-lib.c @@ -26,13 +26,14 @@ static const unsigned short rtc_ydays[2][13] = { }; #define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) +#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) /* * The number of days in the month. */ int rtc_month_days(unsigned int month, unsigned int year) { - return rtc_days_in_month[month] + (is_leap_year(year) && month == 1); + return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1); } EXPORT_SYMBOL(rtc_month_days); @@ -41,7 +42,7 @@ EXPORT_SYMBOL(rtc_month_days); */ int rtc_year_days(unsigned int day, unsigned int month, unsigned int year) { - return rtc_ydays[is_leap_year(year)][month] + day-1; + return rtc_ydays[LEAP_YEAR(year)][month] + day-1; } EXPORT_SYMBOL(rtc_year_days); @@ -65,7 +66,7 @@ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) - LEAPS_THRU_END_OF(1970 - 1); if (days < 0) { year -= 1; - days += 365 + is_leap_year(year); + days += 365 + LEAP_YEAR(year); } tm->tm_year = year - 1900; tm->tm_yday = days + 1; diff --git a/trunk/drivers/rtc/rtc-m41t80.c b/trunk/drivers/rtc/rtc-m41t80.c index 60fe266f0f49..893f7dece239 100644 --- a/trunk/drivers/rtc/rtc-m41t80.c +++ b/trunk/drivers/rtc/rtc-m41t80.c @@ -64,12 +64,10 @@ #define M41T80_FEATURE_BL (1 << 1) /* Battery low indicator */ #define M41T80_FEATURE_SQ (1 << 2) /* Squarewave feature */ #define M41T80_FEATURE_WD (1 << 3) /* Extra watchdog resolution */ -#define M41T80_FEATURE_SQ_ALT (1 << 4) /* RSx bits are in reg 4 */ #define DRV_VERSION "0.05" static const struct i2c_device_id m41t80_id[] = { - { "m41t62", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT }, { "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD }, { "m41t80", M41T80_FEATURE_SQ }, { "m41t81", M41T80_FEATURE_HT | M41T80_FEATURE_SQ}, @@ -395,15 +393,12 @@ static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct m41t80_data *clientdata = i2c_get_clientdata(client); - int val, reg_sqw; + int val; if (!(clientdata->features & M41T80_FEATURE_SQ)) return -EINVAL; - reg_sqw = M41T80_REG_SQW; - if (clientdata->features & M41T80_FEATURE_SQ_ALT) - reg_sqw = M41T80_REG_WDAY; - val = i2c_smbus_read_byte_data(client, reg_sqw); + val = i2c_smbus_read_byte_data(client, M41T80_REG_SQW); if (val < 0) return -EIO; val = (val >> 4) & 0xf; @@ -424,7 +419,7 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct m41t80_data *clientdata = i2c_get_clientdata(client); - int almon, sqw, reg_sqw; + int almon, sqw; int val = simple_strtoul(buf, NULL, 0); if (!(clientdata->features & M41T80_FEATURE_SQ)) @@ -445,16 +440,13 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev, almon = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); if (almon < 0) return -EIO; - reg_sqw = M41T80_REG_SQW; - if (clientdata->features & M41T80_FEATURE_SQ_ALT) - reg_sqw = M41T80_REG_WDAY; - sqw = i2c_smbus_read_byte_data(client, reg_sqw); + sqw = i2c_smbus_read_byte_data(client, M41T80_REG_SQW); if (sqw < 0) return -EIO; sqw = (sqw & 0x0f) | (val << 4); if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, almon & ~M41T80_ALMON_SQWE) < 0 || - i2c_smbus_write_byte_data(client, reg_sqw, sqw) < 0) + i2c_smbus_write_byte_data(client, M41T80_REG_SQW, sqw) < 0) return -EIO; if (val && i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, almon | M41T80_ALMON_SQWE) < 0) diff --git a/trunk/drivers/rtc/rtc-parisc.c b/trunk/drivers/rtc/rtc-parisc.c index b966f56da976..c6bfa6fe1a2a 100644 --- a/trunk/drivers/rtc/rtc-parisc.c +++ b/trunk/drivers/rtc/rtc-parisc.c @@ -7,25 +7,41 @@ #include #include #include -#include #include +/* as simple as can be, and no simpler. */ +struct parisc_rtc { + struct rtc_device *rtc; + spinlock_t lock; +}; + static int parisc_get_time(struct device *dev, struct rtc_time *tm) { - unsigned long ret; + struct parisc_rtc *p = dev_get_drvdata(dev); + unsigned long flags, ret; + spin_lock_irqsave(&p->lock, flags); ret = get_rtc_time(tm); + spin_unlock_irqrestore(&p->lock, flags); if (ret & RTC_BATT_BAD) return -EOPNOTSUPP; - return rtc_valid_tm(tm); + return 0; } static int parisc_set_time(struct device *dev, struct rtc_time *tm) { - if (set_rtc_time(tm) < 0) + struct parisc_rtc *p = dev_get_drvdata(dev); + unsigned long flags; + int ret; + + spin_lock_irqsave(&p->lock, flags); + ret = set_rtc_time(tm); + spin_unlock_irqrestore(&p->lock, flags); + + if (ret < 0) return -EOPNOTSUPP; return 0; @@ -36,25 +52,35 @@ static const struct rtc_class_ops parisc_rtc_ops = { .set_time = parisc_set_time, }; -static int __init parisc_rtc_probe(struct platform_device *dev) +static int __devinit parisc_rtc_probe(struct platform_device *dev) { - struct rtc_device *rtc; + struct parisc_rtc *p; + + p = kzalloc(sizeof (*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + + spin_lock_init(&p->lock); - rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops, - THIS_MODULE); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); + p->rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops, + THIS_MODULE); + if (IS_ERR(p->rtc)) { + int err = PTR_ERR(p->rtc); + kfree(p); + return err; + } - platform_set_drvdata(dev, rtc); + platform_set_drvdata(dev, p); return 0; } -static int __exit parisc_rtc_remove(struct platform_device *dev) +static int __devexit parisc_rtc_remove(struct platform_device *dev) { - struct rtc_device *rtc = platform_get_drvdata(dev); + struct parisc_rtc *p = platform_get_drvdata(dev); - rtc_device_unregister(rtc); + rtc_device_unregister(p->rtc); + kfree(p); return 0; } @@ -70,7 +96,7 @@ static struct platform_driver parisc_rtc_driver = { static int __init parisc_rtc_init(void) { - return platform_driver_probe(&parisc_rtc_driver, parisc_rtc_probe); + return platform_driver_register(&parisc_rtc_driver); } static void __exit parisc_rtc_fini(void) diff --git a/trunk/drivers/rtc/rtc-proc.c b/trunk/drivers/rtc/rtc-proc.c index c086fc30a84c..0c6257a034ff 100644 --- a/trunk/drivers/rtc/rtc-proc.c +++ b/trunk/drivers/rtc/rtc-proc.c @@ -105,8 +105,14 @@ static const struct file_operations rtc_proc_fops = { void rtc_proc_add_device(struct rtc_device *rtc) { - if (rtc->id == 0) - proc_create_data("driver/rtc", 0, NULL, &rtc_proc_fops, rtc); + if (rtc->id == 0) { + struct proc_dir_entry *ent; + + ent = proc_create_data("driver/rtc", 0, NULL, + &rtc_proc_fops, rtc); + if (ent) + ent->owner = rtc->owner; + } } void rtc_proc_del_device(struct rtc_device *rtc) diff --git a/trunk/drivers/rtc/rtc-v3020.c b/trunk/drivers/rtc/rtc-v3020.c index ad164056feb6..14d4f036a768 100644 --- a/trunk/drivers/rtc/rtc-v3020.c +++ b/trunk/drivers/rtc/rtc-v3020.c @@ -27,162 +27,17 @@ #include #include #include -#include -#include +#include #undef DEBUG -struct v3020; - -struct v3020_chip_ops { - int (*map_io)(struct v3020 *chip, struct platform_device *pdev, - struct v3020_platform_data *pdata); - void (*unmap_io)(struct v3020 *chip); - unsigned char (*read_bit)(struct v3020 *chip); - void (*write_bit)(struct v3020 *chip, unsigned char bit); -}; - -#define V3020_CS 0 -#define V3020_WR 1 -#define V3020_RD 2 -#define V3020_IO 3 - -struct v3020_gpio { - const char *name; - unsigned int gpio; -}; - struct v3020 { - /* MMIO access */ void __iomem *ioaddress; int leftshift; - - /* GPIO access */ - struct v3020_gpio *gpio; - - struct v3020_chip_ops *ops; - struct rtc_device *rtc; }; - -static int v3020_mmio_map(struct v3020 *chip, struct platform_device *pdev, - struct v3020_platform_data *pdata) -{ - if (pdev->num_resources != 1) - return -EBUSY; - - if (pdev->resource[0].flags != IORESOURCE_MEM) - return -EBUSY; - - chip->leftshift = pdata->leftshift; - chip->ioaddress = ioremap(pdev->resource[0].start, 1); - if (chip->ioaddress == NULL) - return -EBUSY; - - return 0; -} - -static void v3020_mmio_unmap(struct v3020 *chip) -{ - iounmap(chip->ioaddress); -} - -static void v3020_mmio_write_bit(struct v3020 *chip, unsigned char bit) -{ - writel(bit << chip->leftshift, chip->ioaddress); -} - -static unsigned char v3020_mmio_read_bit(struct v3020 *chip) -{ - return readl(chip->ioaddress) & (1 << chip->leftshift); -} - -static struct v3020_chip_ops v3020_mmio_ops = { - .map_io = v3020_mmio_map, - .unmap_io = v3020_mmio_unmap, - .read_bit = v3020_mmio_read_bit, - .write_bit = v3020_mmio_write_bit, -}; - -static struct v3020_gpio v3020_gpio[] = { - { "RTC CS", 0 }, - { "RTC WR", 0 }, - { "RTC RD", 0 }, - { "RTC IO", 0 }, -}; - -static int v3020_gpio_map(struct v3020 *chip, struct platform_device *pdev, - struct v3020_platform_data *pdata) -{ - int i, err; - - v3020_gpio[V3020_CS].gpio = pdata->gpio_cs; - v3020_gpio[V3020_WR].gpio = pdata->gpio_wr; - v3020_gpio[V3020_RD].gpio = pdata->gpio_rd; - v3020_gpio[V3020_IO].gpio = pdata->gpio_io; - - for (i = 0; i < ARRAY_SIZE(v3020_gpio); i++) { - err = gpio_request(v3020_gpio[i].gpio, v3020_gpio[i].name); - if (err) - goto err_request; - - gpio_direction_output(v3020_gpio[i].gpio, 1); - } - - chip->gpio = v3020_gpio; - - return 0; - -err_request: - while (--i >= 0) - gpio_free(v3020_gpio[i].gpio); - - return err; -} - -static void v3020_gpio_unmap(struct v3020 *chip) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(v3020_gpio); i++) - gpio_free(v3020_gpio[i].gpio); -} - -static void v3020_gpio_write_bit(struct v3020 *chip, unsigned char bit) -{ - gpio_direction_output(chip->gpio[V3020_IO].gpio, bit); - gpio_set_value(chip->gpio[V3020_CS].gpio, 0); - gpio_set_value(chip->gpio[V3020_WR].gpio, 0); - udelay(1); - gpio_set_value(chip->gpio[V3020_WR].gpio, 1); - gpio_set_value(chip->gpio[V3020_CS].gpio, 1); -} - -static unsigned char v3020_gpio_read_bit(struct v3020 *chip) -{ - int bit; - - gpio_direction_input(chip->gpio[V3020_IO].gpio); - gpio_set_value(chip->gpio[V3020_CS].gpio, 0); - gpio_set_value(chip->gpio[V3020_RD].gpio, 0); - udelay(1); - bit = !!gpio_get_value(chip->gpio[V3020_IO].gpio); - udelay(1); - gpio_set_value(chip->gpio[V3020_RD].gpio, 1); - gpio_set_value(chip->gpio[V3020_CS].gpio, 1); - - return bit; -} - -static struct v3020_chip_ops v3020_gpio_ops = { - .map_io = v3020_gpio_map, - .unmap_io = v3020_gpio_unmap, - .read_bit = v3020_gpio_read_bit, - .write_bit = v3020_gpio_write_bit, -}; - static void v3020_set_reg(struct v3020 *chip, unsigned char address, unsigned char data) { @@ -191,7 +46,7 @@ static void v3020_set_reg(struct v3020 *chip, unsigned char address, tmp = address; for (i = 0; i < 4; i++) { - chip->ops->write_bit(chip, (tmp & 1)); + writel((tmp & 1) << chip->leftshift, chip->ioaddress); tmp >>= 1; udelay(1); } @@ -199,7 +54,7 @@ static void v3020_set_reg(struct v3020 *chip, unsigned char address, /* Commands dont have data */ if (!V3020_IS_COMMAND(address)) { for (i = 0; i < 8; i++) { - chip->ops->write_bit(chip, (data & 1)); + writel((data & 1) << chip->leftshift, chip->ioaddress); data >>= 1; udelay(1); } @@ -208,18 +63,18 @@ static void v3020_set_reg(struct v3020 *chip, unsigned char address, static unsigned char v3020_get_reg(struct v3020 *chip, unsigned char address) { - unsigned int data = 0; + unsigned int data=0; int i; for (i = 0; i < 4; i++) { - chip->ops->write_bit(chip, (address & 1)); + writel((address & 1) << chip->leftshift, chip->ioaddress); address >>= 1; udelay(1); } for (i = 0; i < 8; i++) { data >>= 1; - if (chip->ops->read_bit(chip)) + if (readl(chip->ioaddress) & (1 << chip->leftshift)) data |= 0x80; udelay(1); } @@ -251,14 +106,16 @@ static int v3020_read_time(struct device *dev, struct rtc_time *dt) tmp = v3020_get_reg(chip, V3020_YEAR); dt->tm_year = bcd2bin(tmp)+100; - dev_dbg(dev, "\n%s : Read RTC values\n", __func__); - dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour); - dev_dbg(dev, "tm_min : %i\n", dt->tm_min); - dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec); - dev_dbg(dev, "tm_year: %i\n", dt->tm_year); - dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon); - dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday); - dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday); +#ifdef DEBUG + printk("\n%s : Read RTC values\n",__func__); + printk("tm_hour: %i\n",dt->tm_hour); + printk("tm_min : %i\n",dt->tm_min); + printk("tm_sec : %i\n",dt->tm_sec); + printk("tm_year: %i\n",dt->tm_year); + printk("tm_mon : %i\n",dt->tm_mon); + printk("tm_mday: %i\n",dt->tm_mday); + printk("tm_wday: %i\n",dt->tm_wday); +#endif return 0; } @@ -268,13 +125,15 @@ static int v3020_set_time(struct device *dev, struct rtc_time *dt) { struct v3020 *chip = dev_get_drvdata(dev); - dev_dbg(dev, "\n%s : Setting RTC values\n", __func__); - dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec); - dev_dbg(dev, "tm_min : %i\n", dt->tm_min); - dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour); - dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday); - dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday); - dev_dbg(dev, "tm_year: %i\n", dt->tm_year); +#ifdef DEBUG + printk("\n%s : Setting RTC values\n",__func__); + printk("tm_sec : %i\n",dt->tm_sec); + printk("tm_min : %i\n",dt->tm_min); + printk("tm_hour: %i\n",dt->tm_hour); + printk("tm_mday: %i\n",dt->tm_mday); + printk("tm_wday: %i\n",dt->tm_wday); + printk("tm_year: %i\n",dt->tm_year); +#endif /* Write all the values to ram... */ v3020_set_reg(chip, V3020_SECONDS, bin2bcd(dt->tm_sec)); @@ -309,28 +168,30 @@ static int rtc_probe(struct platform_device *pdev) int i; int temp; + if (pdev->num_resources != 1) + return -EBUSY; + + if (pdev->resource[0].flags != IORESOURCE_MEM) + return -EBUSY; + chip = kzalloc(sizeof *chip, GFP_KERNEL); if (!chip) return -ENOMEM; - if (pdata->use_gpio) - chip->ops = &v3020_gpio_ops; - else - chip->ops = &v3020_mmio_ops; - - retval = chip->ops->map_io(chip, pdev, pdata); - if (retval) + chip->leftshift = pdata->leftshift; + chip->ioaddress = ioremap(pdev->resource[0].start, 1); + if (chip->ioaddress == NULL) goto err_chip; /* Make sure the v3020 expects a communication cycle * by reading 8 times */ for (i = 0; i < 8; i++) - temp = chip->ops->read_bit(chip); + temp = readl(chip->ioaddress); /* Test chip by doing a write/read sequence * to the chip ram */ v3020_set_reg(chip, V3020_SECONDS, 0x33); - if (v3020_get_reg(chip, V3020_SECONDS) != 0x33) { + if(v3020_get_reg(chip, V3020_SECONDS) != 0x33) { retval = -ENODEV; goto err_io; } @@ -339,17 +200,10 @@ static int rtc_probe(struct platform_device *pdev) * are all disabled */ v3020_set_reg(chip, V3020_STATUS_0, 0x0); - if (pdata->use_gpio) - dev_info(&pdev->dev, "Chip available at GPIOs " - "%d, %d, %d, %d\n", - chip->gpio[V3020_CS].gpio, chip->gpio[V3020_WR].gpio, - chip->gpio[V3020_RD].gpio, chip->gpio[V3020_IO].gpio); - else - dev_info(&pdev->dev, "Chip available at " - "physical address 0x%llx," - "data connected to D%d\n", - (unsigned long long)pdev->resource[0].start, - chip->leftshift); + dev_info(&pdev->dev, "Chip available at physical address 0x%llx," + "data connected to D%d\n", + (unsigned long long)pdev->resource[0].start, + chip->leftshift); platform_set_drvdata(pdev, chip); @@ -364,7 +218,7 @@ static int rtc_probe(struct platform_device *pdev) return 0; err_io: - chip->ops->unmap_io(chip); + iounmap(chip->ioaddress); err_chip: kfree(chip); @@ -379,7 +233,7 @@ static int rtc_remove(struct platform_device *dev) if (rtc) rtc_device_unregister(rtc); - chip->ops->unmap_io(chip); + iounmap(chip->ioaddress); kfree(chip); return 0; diff --git a/trunk/drivers/rtc/rtc-wm8350.c b/trunk/drivers/rtc/rtc-wm8350.c index c91edc572eb6..5c5e3aa91385 100644 --- a/trunk/drivers/rtc/rtc-wm8350.c +++ b/trunk/drivers/rtc/rtc-wm8350.c @@ -122,7 +122,7 @@ static int wm8350_rtc_settime(struct device *dev, struct rtc_time *tm) do { rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); schedule_timeout_uninterruptible(msecs_to_jiffies(1)); - } while (--retries && !(rtc_ctrl & WM8350_RTC_STS)); + } while (retries-- && !(rtc_ctrl & WM8350_RTC_STS)); if (!retries) { dev_err(dev, "timed out on set confirmation\n"); @@ -236,17 +236,6 @@ static int wm8350_rtc_start_alarm(struct wm8350 *wm8350) return 0; } -static int wm8350_rtc_alarm_irq_enable(struct device *dev, - unsigned int enabled) -{ - struct wm8350 *wm8350 = dev_get_drvdata(dev); - - if (enabled) - return wm8350_rtc_start_alarm(wm8350); - else - return wm8350_rtc_stop_alarm(wm8350); -} - static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) { struct wm8350 *wm8350 = dev_get_drvdata(dev); @@ -302,15 +291,30 @@ static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) return ret; } -static int wm8350_rtc_update_irq_enable(struct device *dev, - unsigned int enabled) +/* + * Handle commands from user-space + */ +static int wm8350_rtc_ioctl(struct device *dev, unsigned int cmd, + unsigned long arg) { struct wm8350 *wm8350 = dev_get_drvdata(dev); - if (enabled) - wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); - else + switch (cmd) { + case RTC_AIE_OFF: + return wm8350_rtc_stop_alarm(wm8350); + case RTC_AIE_ON: + return wm8350_rtc_start_alarm(wm8350); + + case RTC_UIE_OFF: wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); + break; + case RTC_UIE_ON: + wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); + break; + + default: + return -ENOIOCTLCMD; + } return 0; } @@ -341,12 +345,11 @@ static void wm8350_rtc_update_handler(struct wm8350 *wm8350, int irq, } static const struct rtc_class_ops wm8350_rtc_ops = { + .ioctl = wm8350_rtc_ioctl, .read_time = wm8350_rtc_readtime, .set_time = wm8350_rtc_settime, .read_alarm = wm8350_rtc_readalarm, .set_alarm = wm8350_rtc_setalarm, - .alarm_irq_enable = wm8350_rtc_alarm_irq_enable, - .update_irq_enable = wm8350_rtc_update_irq_enable, }; #ifdef CONFIG_PM @@ -437,7 +440,7 @@ static int wm8350_rtc_probe(struct platform_device *pdev) do { timectl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); - } while (timectl & WM8350_RTC_STS && --retries); + } while (timectl & WM8350_RTC_STS && retries--); if (retries == 0) { dev_err(&pdev->dev, "failed to start: timeout\n"); diff --git a/trunk/drivers/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index 0570794ccf1c..2fd64e5a9ab2 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -2363,7 +2363,6 @@ int dasd_generic_notify(struct ccw_device *cdev, int event) ret = 0; switch (event) { case CIO_GONE: - case CIO_BOXED: case CIO_NO_PATH: /* First of all call extended error reporting. */ dasd_eer_write(device, NULL, DASD_EER_NOPATH); diff --git a/trunk/drivers/s390/block/dasd_proc.c b/trunk/drivers/s390/block/dasd_proc.c index 654daa3cdfda..2080ba6a69b0 100644 --- a/trunk/drivers/s390/block/dasd_proc.c +++ b/trunk/drivers/s390/block/dasd_proc.c @@ -320,6 +320,7 @@ dasd_proc_init(void) dasd_proc_root_entry = proc_mkdir("dasd", NULL); if (!dasd_proc_root_entry) goto out_nodasd; + dasd_proc_root_entry->owner = THIS_MODULE; dasd_devices_entry = proc_create("devices", S_IFREG | S_IRUGO | S_IWUSR, dasd_proc_root_entry, @@ -333,6 +334,7 @@ dasd_proc_init(void) goto out_nostatistics; dasd_statistics_entry->read_proc = dasd_statistics_read; dasd_statistics_entry->write_proc = dasd_statistics_write; + dasd_statistics_entry->owner = THIS_MODULE; return 0; out_nostatistics: diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index 35441fa16be1..c4d2f667a2f6 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -310,6 +310,8 @@ static void ccw_device_remove_orphan_cb(struct work_struct *work) put_device(&cdev->dev); } +static void ccw_device_call_sch_unregister(struct work_struct *work); + static void ccw_device_remove_disconnected(struct ccw_device *cdev) { @@ -333,10 +335,11 @@ ccw_device_remove_disconnected(struct ccw_device *cdev) spin_unlock_irqrestore(cdev->ccwlock, flags); PREPARE_WORK(&cdev->private->kick_work, ccw_device_remove_orphan_cb); - queue_work(slow_path_wq, &cdev->private->kick_work); } else /* Deregister subchannel, which will kill the ccw device. */ - ccw_device_schedule_sch_unregister(cdev); + PREPARE_WORK(&cdev->private->kick_work, + ccw_device_call_sch_unregister); + queue_work(slow_path_wq, &cdev->private->kick_work); } /** @@ -468,7 +471,7 @@ static int online_store_recog_and_online(struct ccw_device *cdev) int ret; /* Do device recognition, if needed. */ - if (cdev->private->state == DEV_STATE_BOXED) { + if (cdev->id.cu_type == 0) { ret = ccw_device_recognition(cdev); if (ret) { CIO_MSG_EVENT(0, "Couldn't start recognition " @@ -479,21 +482,17 @@ static int online_store_recog_and_online(struct ccw_device *cdev) } wait_event(cdev->private->wait_q, cdev->private->flags.recog_done); - if (cdev->private->state != DEV_STATE_OFFLINE) - /* recognition failed */ - return -EAGAIN; } if (cdev->drv && cdev->drv->set_online) ccw_device_set_online(cdev); return 0; } - static int online_store_handle_online(struct ccw_device *cdev, int force) { int ret; ret = online_store_recog_and_online(cdev); - if (ret && !force) + if (ret) return ret; if (force && cdev->private->state == DEV_STATE_BOXED) { ret = ccw_device_stlck(cdev); @@ -501,9 +500,7 @@ static int online_store_handle_online(struct ccw_device *cdev, int force) return ret; if (cdev->id.cu_type == 0) cdev->private->state = DEV_STATE_NOT_OPER; - ret = online_store_recog_and_online(cdev); - if (ret) - return ret; + online_store_recog_and_online(cdev); } return 0; } @@ -515,11 +512,7 @@ static ssize_t online_store (struct device *dev, struct device_attribute *attr, int force, ret; unsigned long i; - if ((cdev->private->state != DEV_STATE_OFFLINE && - cdev->private->state != DEV_STATE_ONLINE && - cdev->private->state != DEV_STATE_BOXED && - cdev->private->state != DEV_STATE_DISCONNECTED) || - atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0) + if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0) return -EAGAIN; if (cdev->drv && !try_module_get(cdev->drv->owner)) { @@ -1021,13 +1014,6 @@ static void ccw_device_call_sch_unregister(struct work_struct *work) put_device(&sch->dev); } -void ccw_device_schedule_sch_unregister(struct ccw_device *cdev) -{ - PREPARE_WORK(&cdev->private->kick_work, - ccw_device_call_sch_unregister); - queue_work(slow_path_wq, &cdev->private->kick_work); -} - /* * subchannel recognition done. Called from the state machine. */ @@ -1039,17 +1025,19 @@ io_subchannel_recog_done(struct ccw_device *cdev) return; } switch (cdev->private->state) { - case DEV_STATE_BOXED: - /* Device did not respond in time. */ case DEV_STATE_NOT_OPER: cdev->private->flags.recog_done = 1; /* Remove device found not operational. */ if (!get_device(&cdev->dev)) break; - ccw_device_schedule_sch_unregister(cdev); + PREPARE_WORK(&cdev->private->kick_work, + ccw_device_call_sch_unregister); + queue_work(slow_path_wq, &cdev->private->kick_work); if (atomic_dec_and_test(&ccw_device_init_count)) wake_up(&ccw_device_init_wq); break; + case DEV_STATE_BOXED: + /* Device did not respond in time. */ case DEV_STATE_OFFLINE: /* * We can't register the device in interrupt context so @@ -1563,7 +1551,8 @@ static int purge_fn(struct device *dev, void *data) goto out; CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", priv->dev_id.ssid, priv->dev_id.devno); - ccw_device_schedule_sch_unregister(cdev); + PREPARE_WORK(&cdev->private->kick_work, ccw_device_call_sch_unregister); + queue_work(slow_path_wq, &cdev->private->kick_work); out: /* Abort loop in case of pending signal. */ diff --git a/trunk/drivers/s390/cio/device.h b/trunk/drivers/s390/cio/device.h index f1cbbd94ad4e..85e01846ca65 100644 --- a/trunk/drivers/s390/cio/device.h +++ b/trunk/drivers/s390/cio/device.h @@ -87,7 +87,6 @@ int ccw_device_is_orphan(struct ccw_device *); int ccw_device_recognition(struct ccw_device *); int ccw_device_online(struct ccw_device *); int ccw_device_offline(struct ccw_device *); -void ccw_device_schedule_sch_unregister(struct ccw_device *); int ccw_purge_blacklisted(void); /* Function prototypes for device status and basic sense stuff. */ diff --git a/trunk/drivers/s390/cio/device_fsm.c b/trunk/drivers/s390/cio/device_fsm.c index e46049261561..87b4bfca080f 100644 --- a/trunk/drivers/s390/cio/device_fsm.c +++ b/trunk/drivers/s390/cio/device_fsm.c @@ -256,12 +256,13 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) old_lpm = 0; if (sch->lpm != old_lpm) __recover_lost_chpids(sch, old_lpm); - if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID && - (state == DEV_STATE_NOT_OPER || state == DEV_STATE_BOXED)) { - cdev->private->flags.recog_done = 1; - cdev->private->state = DEV_STATE_DISCONNECTED; - wake_up(&cdev->private->wait_q); - return; + if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) { + if (state == DEV_STATE_NOT_OPER) { + cdev->private->flags.recog_done = 1; + cdev->private->state = DEV_STATE_DISCONNECTED; + return; + } + /* Boxed devices don't need extra treatment. */ } notify = 0; same_dev = 0; /* Keep the compiler quiet... */ @@ -273,7 +274,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) sch->schid.ssid, sch->schid.sch_no); break; case DEV_STATE_OFFLINE: - if (cdev->online) { + if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) { same_dev = ccw_device_handle_oper(cdev); notify = 1; } @@ -306,17 +307,12 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) " subchannel 0.%x.%04x\n", cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no); - if (cdev->id.cu_type != 0) { /* device was recognized before */ - cdev->private->flags.recog_done = 1; - cdev->private->state = DEV_STATE_BOXED; - wake_up(&cdev->private->wait_q); - return; - } break; } cdev->private->state = state; io_subchannel_recog_done(cdev); - wake_up(&cdev->private->wait_q); + if (state != DEV_STATE_NOT_OPER) + wake_up(&cdev->private->wait_q); } /* @@ -394,13 +390,10 @@ ccw_device_done(struct ccw_device *cdev, int state) cdev->private->state = state; - if (state == DEV_STATE_BOXED) { + + if (state == DEV_STATE_BOXED) CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n", cdev->private->dev_id.devno, sch->schid.sch_no); - if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED)) - ccw_device_schedule_sch_unregister(cdev); - cdev->private->flags.donotify = 0; - } if (cdev->private->flags.donotify) { cdev->private->flags.donotify = 0; diff --git a/trunk/drivers/s390/net/qeth_core_offl.c b/trunk/drivers/s390/net/qeth_core_offl.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/trunk/drivers/s390/net/qeth_core_offl.h b/trunk/drivers/s390/net/qeth_core_offl.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/trunk/drivers/s390/scsi/zfcp_ccw.c b/trunk/drivers/s390/scsi/zfcp_ccw.c index cfb0dcb6e3ff..1fe1e2eda512 100644 --- a/trunk/drivers/s390/scsi/zfcp_ccw.c +++ b/trunk/drivers/s390/scsi/zfcp_ccw.c @@ -176,11 +176,6 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event) zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, "ccnoti4", NULL); break; - case CIO_BOXED: - dev_warn(&adapter->ccw_device->dev, - "The ccw device did not respond in time.\n"); - zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL); - break; } return 1; } diff --git a/trunk/drivers/s390/scsi/zfcp_fc.c b/trunk/drivers/s390/scsi/zfcp_fc.c index e8d032b9dfbd..aab8123c5966 100644 --- a/trunk/drivers/s390/scsi/zfcp_fc.c +++ b/trunk/drivers/s390/scsi/zfcp_fc.c @@ -94,7 +94,7 @@ static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port) static void zfcp_wka_port_offline(struct work_struct *work) { - struct delayed_work *dw = to_delayed_work(work); + struct delayed_work *dw = container_of(work, struct delayed_work, work); struct zfcp_wka_port *wka_port = container_of(dw, struct zfcp_wka_port, work); diff --git a/trunk/drivers/scsi/scsi_devinfo.c b/trunk/drivers/scsi/scsi_devinfo.c index b13481369642..099b5455bbce 100644 --- a/trunk/drivers/scsi/scsi_devinfo.c +++ b/trunk/drivers/scsi/scsi_devinfo.c @@ -596,6 +596,8 @@ int __init scsi_init_devinfo(void) error = -ENOMEM; goto out; } + + p->owner = THIS_MODULE; #endif /* CONFIG_SCSI_PROC_FS */ out: diff --git a/trunk/drivers/scsi/scsi_proc.c b/trunk/drivers/scsi/scsi_proc.c index 77fbddb507fd..82f7b2dd08a2 100644 --- a/trunk/drivers/scsi/scsi_proc.c +++ b/trunk/drivers/scsi/scsi_proc.c @@ -115,6 +115,8 @@ void scsi_proc_hostdir_add(struct scsi_host_template *sht) if (!sht->proc_dir) printk(KERN_ERR "%s: proc_mkdir failed for %s\n", __func__, sht->proc_name); + else + sht->proc_dir->owner = sht->module; } mutex_unlock(&global_host_template_mutex); } @@ -161,6 +163,7 @@ void scsi_proc_host_add(struct Scsi_Host *shost) } p->write_proc = proc_scsi_write_proc; + p->owner = sht->module; } /** diff --git a/trunk/drivers/serial/cpm_uart/cpm_uart_core.c b/trunk/drivers/serial/cpm_uart/cpm_uart_core.c index 5c6ef51da274..bde4b4b0b80f 100644 --- a/trunk/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/trunk/drivers/serial/cpm_uart/cpm_uart_core.c @@ -406,18 +406,6 @@ static int cpm_uart_startup(struct uart_port *port) pr_debug("CPM uart[%d]:startup\n", port->line); - /* If the port is not the console, make sure rx is disabled. */ - if (!(pinfo->flags & FLAG_CONSOLE)) { - /* Disable UART rx */ - if (IS_SMC(pinfo)) { - clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN); - clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX); - } else { - clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR); - clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX); - } - cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); - } /* Install interrupt handler. */ retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port); if (retval) @@ -432,6 +420,8 @@ static int cpm_uart_startup(struct uart_port *port) setbits32(&pinfo->sccp->scc_gsmrl, (SCC_GSMRL_ENR | SCC_GSMRL_ENT)); } + if (!(pinfo->flags & FLAG_CONSOLE)) + cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); return 0; } diff --git a/trunk/drivers/serial/mpc52xx_uart.c b/trunk/drivers/serial/mpc52xx_uart.c index 7f72f8ceaa6f..0c3a2ab1612c 100644 --- a/trunk/drivers/serial/mpc52xx_uart.c +++ b/trunk/drivers/serial/mpc52xx_uart.c @@ -50,8 +50,8 @@ /* OF Platform device Usage : * * This driver is only used for PSCs configured in uart mode. The device - * tree will have a node for each PSC with "mpc52xx-psc-uart" in the compatible - * list. + * tree will have a node for each PSC in uart mode w/ device_type = "serial" + * and "mpc52xx-psc-uart" in the compatible string * * By default, PSC devices are enumerated in the order they are found. However * a particular PSC number can be forces by adding 'device_no = ' @@ -522,7 +522,7 @@ mpc52xx_uart_startup(struct uart_port *port) /* Request IRQ */ ret = request_irq(port->irq, mpc52xx_uart_int, - IRQF_DISABLED | IRQF_SAMPLE_RANDOM, + IRQF_DISABLED | IRQF_SAMPLE_RANDOM | IRQF_SHARED, "mpc52xx_psc_uart", port); if (ret) return ret; @@ -1212,18 +1212,30 @@ mpc52xx_uart_of_resume(struct of_device *op) #endif static void -mpc52xx_uart_of_assign(struct device_node *np) +mpc52xx_uart_of_assign(struct device_node *np, int idx) { + int free_idx = -1; int i; - /* Find the first free PSC number */ + /* Find the first free node */ for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) { if (mpc52xx_uart_nodes[i] == NULL) { - of_node_get(np); - mpc52xx_uart_nodes[i] = np; - return; + free_idx = i; + break; } } + + if ((idx < 0) || (idx >= MPC52xx_PSC_MAXNUM)) + idx = free_idx; + + if (idx < 0) + return; /* No free slot; abort */ + + of_node_get(np); + /* If the slot is already occupied, then swap slots */ + if (mpc52xx_uart_nodes[idx] && (free_idx != -1)) + mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx]; + mpc52xx_uart_nodes[idx] = np; } static void @@ -1231,17 +1243,23 @@ mpc52xx_uart_of_enumerate(void) { static int enum_done; struct device_node *np; + const unsigned int *devno; const struct of_device_id *match; int i; if (enum_done) return; - /* Assign index to each PSC in device tree */ - for_each_matching_node(np, mpc52xx_uart_of_match) { + for_each_node_by_type(np, "serial") { match = of_match_node(mpc52xx_uart_of_match, np); + if (!match) + continue; + psc_ops = match->data; - mpc52xx_uart_of_assign(np); + + /* Is a particular device number requested? */ + devno = of_get_property(np, "port-number", NULL); + mpc52xx_uart_of_assign(np, devno ? *devno : -1); } enum_done = 1; diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c index b0bb29d804ae..42f4e66fccaf 100644 --- a/trunk/drivers/serial/serial_core.c +++ b/trunk/drivers/serial/serial_core.c @@ -27,8 +27,6 @@ #include #include #include -#include -#include #include #include #include @@ -1684,20 +1682,20 @@ static const char *uart_type(struct uart_port *port) #ifdef CONFIG_PROC_FS -static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) +static int uart_line_info(char *buf, struct uart_driver *drv, int i) { struct uart_state *state = drv->state + i; int pm_state; struct uart_port *port = state->port; char stat_buf[32]; unsigned int status; - int mmio; + int mmio, ret; if (!port) - return; + return 0; mmio = port->iotype >= UPIO_MEM; - seq_printf(m, "%d: uart:%s %s%08llX irq:%d", + ret = sprintf(buf, "%d: uart:%s %s%08llX irq:%d", port->line, uart_type(port), mmio ? "mmio:0x" : "port:", mmio ? (unsigned long long)port->mapbase @@ -1705,8 +1703,8 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) port->irq); if (port->type == PORT_UNKNOWN) { - seq_putc(m, '\n'); - return; + strcat(buf, "\n"); + return ret + 1; } if (capable(CAP_SYS_ADMIN)) { @@ -1721,19 +1719,19 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) uart_change_pm(state, pm_state); mutex_unlock(&state->mutex); - seq_printf(m, " tx:%d rx:%d", + ret += sprintf(buf + ret, " tx:%d rx:%d", port->icount.tx, port->icount.rx); if (port->icount.frame) - seq_printf(m, " fe:%d", + ret += sprintf(buf + ret, " fe:%d", port->icount.frame); if (port->icount.parity) - seq_printf(m, " pe:%d", + ret += sprintf(buf + ret, " pe:%d", port->icount.parity); if (port->icount.brk) - seq_printf(m, " brk:%d", + ret += sprintf(buf + ret, " brk:%d", port->icount.brk); if (port->icount.overrun) - seq_printf(m, " oe:%d", + ret += sprintf(buf + ret, " oe:%d", port->icount.overrun); #define INFOBIT(bit, str) \ @@ -1755,39 +1753,45 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) STATBIT(TIOCM_RNG, "|RI"); if (stat_buf[0]) stat_buf[0] = ' '; + strcat(stat_buf, "\n"); - seq_puts(m, stat_buf); + ret += sprintf(buf + ret, stat_buf); + } else { + strcat(buf, "\n"); + ret++; } - seq_putc(m, '\n'); #undef STATBIT #undef INFOBIT + return ret; } -static int uart_proc_show(struct seq_file *m, void *v) +static int uart_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { - struct tty_driver *ttydrv = m->private; + struct tty_driver *ttydrv = data; struct uart_driver *drv = ttydrv->driver_state; - int i; + int i, len = 0, l; + off_t begin = 0; - seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n", + len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n", "", "", ""); - for (i = 0; i < drv->nr; i++) - uart_line_info(m, drv, i); - return 0; -} - -static int uart_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, uart_proc_show, PDE(inode)->data); + for (i = 0; i < drv->nr && len < PAGE_SIZE - 96; i++) { + l = uart_line_info(page + len, drv, i); + len += l; + if (len + begin > off + count) + goto done; + if (len + begin < off) { + begin += len; + len = 0; + } + } + *eof = 1; + done: + if (off >= len + begin) + return 0; + *start = page + (off - begin); + return (count < begin + len - off) ? count : (begin + len - off); } - -static const struct file_operations uart_proc_fops = { - .owner = THIS_MODULE, - .open = uart_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; #endif #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL) @@ -2295,7 +2299,7 @@ static const struct tty_operations uart_ops = { .break_ctl = uart_break_ctl, .wait_until_sent= uart_wait_until_sent, #ifdef CONFIG_PROC_FS - .proc_fops = &uart_proc_fops, + .read_proc = uart_read_proc, #endif .tiocmget = uart_tiocmget, .tiocmset = uart_tiocmset, diff --git a/trunk/drivers/sh/maple/maple.c b/trunk/drivers/sh/maple/maple.c index 93c20e135ee1..cab1ab7cfb78 100644 --- a/trunk/drivers/sh/maple/maple.c +++ b/trunk/drivers/sh/maple/maple.c @@ -776,7 +776,7 @@ static struct maple_driver maple_unsupported_device = { .bus = &maple_bus_type, }, }; -/* +/** * maple_bus_type - core maple bus structure */ struct bus_type maple_bus_type = { diff --git a/trunk/drivers/spi/spi_gpio.c b/trunk/drivers/spi/spi_gpio.c index 26bd03e61855..d2866c293dee 100644 --- a/trunk/drivers/spi/spi_gpio.c +++ b/trunk/drivers/spi/spi_gpio.c @@ -178,10 +178,8 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active) if (is_active) setsck(spi, spi->mode & SPI_CPOL); - if (cs != SPI_GPIO_NO_CHIPSELECT) { - /* SPI is normally active-low */ - gpio_set_value(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active); - } + /* SPI is normally active-low */ + gpio_set_value(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active); } static int spi_gpio_setup(struct spi_device *spi) @@ -193,17 +191,15 @@ static int spi_gpio_setup(struct spi_device *spi) return -EINVAL; if (!spi->controller_state) { - if (cs != SPI_GPIO_NO_CHIPSELECT) { - status = gpio_request(cs, dev_name(&spi->dev)); - if (status) - return status; - status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH); - } + status = gpio_request(cs, dev_name(&spi->dev)); + if (status) + return status; + status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH); } if (!status) status = spi_bitbang_setup(spi); if (status) { - if (!spi->controller_state && cs != SPI_GPIO_NO_CHIPSELECT) + if (!spi->controller_state) gpio_free(cs); } return status; @@ -213,8 +209,7 @@ static void spi_gpio_cleanup(struct spi_device *spi) { unsigned long cs = (unsigned long) spi->controller_data; - if (cs != SPI_GPIO_NO_CHIPSELECT) - gpio_free(cs); + gpio_free(cs); spi_bitbang_cleanup(spi); } diff --git a/trunk/drivers/spi/spi_mpc83xx.c b/trunk/drivers/spi/spi_mpc83xx.c index f4573a96af24..44a2b46ccb79 100644 --- a/trunk/drivers/spi/spi_mpc83xx.c +++ b/trunk/drivers/spi/spi_mpc83xx.c @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include #include @@ -25,13 +23,7 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #include @@ -87,7 +79,7 @@ struct mpc83xx_spi { u32(*get_tx) (struct mpc83xx_spi *); unsigned int count; - unsigned int irq; + int irq; unsigned nsecs; /* (clock cycle time)/2 */ @@ -97,6 +89,9 @@ struct mpc83xx_spi { bool qe_mode; + void (*activate_cs) (u8 cs, u8 polarity); + void (*deactivate_cs) (u8 cs, u8 polarity); + u8 busy; struct workqueue_struct *workqueue; @@ -128,7 +123,6 @@ static inline u32 mpc83xx_spi_read_reg(__be32 __iomem * reg) } #define MPC83XX_SPI_RX_BUF(type) \ -static \ void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \ { \ type * rx = mpc83xx_spi->rx; \ @@ -137,7 +131,6 @@ void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \ } #define MPC83XX_SPI_TX_BUF(type) \ -static \ u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi) \ { \ u32 data; \ @@ -158,14 +151,15 @@ MPC83XX_SPI_TX_BUF(u32) static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) { - struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master); - struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data; - bool pol = spi->mode & SPI_CS_HIGH; + struct mpc83xx_spi *mpc83xx_spi; + u8 pol = spi->mode & SPI_CS_HIGH ? 1 : 0; struct spi_mpc83xx_cs *cs = spi->controller_state; + mpc83xx_spi = spi_master_get_devdata(spi->master); + if (value == BITBANG_CS_INACTIVE) { - if (pdata->cs_control) - pdata->cs_control(spi, !pol); + if (mpc83xx_spi->deactivate_cs) + mpc83xx_spi->deactivate_cs(spi->chip_select, pol); } if (value == BITBANG_CS_ACTIVE) { @@ -178,7 +172,7 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) if (cs->hw_mode != regval) { unsigned long flags; - __be32 __iomem *mode = &mpc83xx_spi->base->mode; + void *tmp_ptr = &mpc83xx_spi->base->mode; regval = cs->hw_mode; /* Turn off IRQs locally to minimize time that @@ -186,12 +180,12 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) */ local_irq_save(flags); /* Turn off SPI unit prior changing mode */ - mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE); - mpc83xx_spi_write_reg(mode, regval); + mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE); + mpc83xx_spi_write_reg(tmp_ptr, regval); local_irq_restore(flags); } - if (pdata->cs_control) - pdata->cs_control(spi, pol); + if (mpc83xx_spi->activate_cs) + mpc83xx_spi->activate_cs(spi->chip_select, pol); } } @@ -290,7 +284,7 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); if (cs->hw_mode != regval) { unsigned long flags; - __be32 __iomem *mode = &mpc83xx_spi->base->mode; + void *tmp_ptr = &mpc83xx_spi->base->mode; regval = cs->hw_mode; /* Turn off IRQs locally to minimize time @@ -298,8 +292,8 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) */ local_irq_save(flags); /* Turn off SPI unit prior changing mode */ - mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE); - mpc83xx_spi_write_reg(mode, regval); + mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE); + mpc83xx_spi_write_reg(tmp_ptr, regval); local_irq_restore(flags); } return 0; @@ -489,7 +483,7 @@ static int mpc83xx_spi_setup(struct spi_device *spi) return 0; } -static irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data) +irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data) { struct mpc83xx_spi *mpc83xx_spi = context_data; u32 event; @@ -551,28 +545,43 @@ static void mpc83xx_spi_cleanup(struct spi_device *spi) kfree(spi->controller_state); } -static struct spi_master * __devinit -mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) +static int __init mpc83xx_spi_probe(struct platform_device *dev) { - struct fsl_spi_platform_data *pdata = dev->platform_data; struct spi_master *master; struct mpc83xx_spi *mpc83xx_spi; + struct fsl_spi_platform_data *pdata; + struct resource *r; u32 regval; int ret = 0; - master = spi_alloc_master(dev, sizeof(struct mpc83xx_spi)); + /* Get resources(memory, IRQ) associated with the device */ + master = spi_alloc_master(&dev->dev, sizeof(struct mpc83xx_spi)); + if (master == NULL) { ret = -ENOMEM; goto err; } - dev_set_drvdata(dev, master); + platform_set_drvdata(dev, master); + pdata = dev->dev.platform_data; + if (pdata == NULL) { + ret = -ENODEV; + goto free_master; + } + + r = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (r == NULL) { + ret = -ENODEV; + goto free_master; + } master->setup = mpc83xx_spi_setup; master->transfer = mpc83xx_spi_transfer; master->cleanup = mpc83xx_spi_cleanup; mpc83xx_spi = spi_master_get_devdata(master); + mpc83xx_spi->activate_cs = pdata->activate_cs; + mpc83xx_spi->deactivate_cs = pdata->deactivate_cs; mpc83xx_spi->qe_mode = pdata->qe_mode; mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8; mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8; @@ -587,13 +596,18 @@ mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) init_completion(&mpc83xx_spi->done); - mpc83xx_spi->base = ioremap(mem->start, mem->end - mem->start + 1); + mpc83xx_spi->base = ioremap(r->start, r->end - r->start + 1); if (mpc83xx_spi->base == NULL) { ret = -ENOMEM; goto put_master; } - mpc83xx_spi->irq = irq; + mpc83xx_spi->irq = platform_get_irq(dev, 0); + + if (mpc83xx_spi->irq < 0) { + ret = -ENXIO; + goto unmap_io; + } /* Register for SPI Interrupt */ ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq, @@ -635,9 +649,9 @@ mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) printk(KERN_INFO "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n", - dev_name(dev), mpc83xx_spi->base, mpc83xx_spi->irq); + dev_name(&dev->dev), mpc83xx_spi->base, mpc83xx_spi->irq); - return master; + return ret; unreg_master: destroy_workqueue(mpc83xx_spi->workqueue); @@ -647,16 +661,18 @@ mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) iounmap(mpc83xx_spi->base); put_master: spi_master_put(master); +free_master: + kfree(master); err: - return ERR_PTR(ret); + return ret; } -static int __devexit mpc83xx_spi_remove(struct device *dev) +static int __exit mpc83xx_spi_remove(struct platform_device *dev) { struct mpc83xx_spi *mpc83xx_spi; struct spi_master *master; - master = dev_get_drvdata(dev); + master = platform_get_drvdata(dev); mpc83xx_spi = spi_master_get_devdata(master); flush_workqueue(mpc83xx_spi->workqueue); @@ -669,293 +685,23 @@ static int __devexit mpc83xx_spi_remove(struct device *dev) return 0; } -struct mpc83xx_spi_probe_info { - struct fsl_spi_platform_data pdata; - int *gpios; - bool *alow_flags; -}; - -static struct mpc83xx_spi_probe_info * -to_of_pinfo(struct fsl_spi_platform_data *pdata) -{ - return container_of(pdata, struct mpc83xx_spi_probe_info, pdata); -} - -static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on) -{ - struct device *dev = spi->dev.parent; - struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data); - u16 cs = spi->chip_select; - int gpio = pinfo->gpios[cs]; - bool alow = pinfo->alow_flags[cs]; - - gpio_set_value(gpio, on ^ alow); -} - -static int of_mpc83xx_spi_get_chipselects(struct device *dev) -{ - struct device_node *np = dev_archdata_get_node(&dev->archdata); - struct fsl_spi_platform_data *pdata = dev->platform_data; - struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata); - unsigned int ngpios; - int i = 0; - int ret; - - ngpios = of_gpio_count(np); - if (!ngpios) { - /* - * SPI w/o chip-select line. One SPI device is still permitted - * though. - */ - pdata->max_chipselect = 1; - return 0; - } - - pinfo->gpios = kmalloc(ngpios * sizeof(pinfo->gpios), GFP_KERNEL); - if (!pinfo->gpios) - return -ENOMEM; - memset(pinfo->gpios, -1, ngpios * sizeof(pinfo->gpios)); - - pinfo->alow_flags = kzalloc(ngpios * sizeof(pinfo->alow_flags), - GFP_KERNEL); - if (!pinfo->alow_flags) { - ret = -ENOMEM; - goto err_alloc_flags; - } - - for (; i < ngpios; i++) { - int gpio; - enum of_gpio_flags flags; - - gpio = of_get_gpio_flags(np, i, &flags); - if (!gpio_is_valid(gpio)) { - dev_err(dev, "invalid gpio #%d: %d\n", i, gpio); - goto err_loop; - } - - ret = gpio_request(gpio, dev_name(dev)); - if (ret) { - dev_err(dev, "can't request gpio #%d: %d\n", i, ret); - goto err_loop; - } - - pinfo->gpios[i] = gpio; - pinfo->alow_flags[i] = flags & OF_GPIO_ACTIVE_LOW; - - ret = gpio_direction_output(pinfo->gpios[i], - pinfo->alow_flags[i]); - if (ret) { - dev_err(dev, "can't set output direction for gpio " - "#%d: %d\n", i, ret); - goto err_loop; - } - } - - pdata->max_chipselect = ngpios; - pdata->cs_control = mpc83xx_spi_cs_control; - - return 0; - -err_loop: - while (i >= 0) { - if (gpio_is_valid(pinfo->gpios[i])) - gpio_free(pinfo->gpios[i]); - i--; - } - - kfree(pinfo->alow_flags); - pinfo->alow_flags = NULL; -err_alloc_flags: - kfree(pinfo->gpios); - pinfo->gpios = NULL; - return ret; -} - -static int of_mpc83xx_spi_free_chipselects(struct device *dev) -{ - struct fsl_spi_platform_data *pdata = dev->platform_data; - struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata); - int i; - - if (!pinfo->gpios) - return 0; - - for (i = 0; i < pdata->max_chipselect; i++) { - if (gpio_is_valid(pinfo->gpios[i])) - gpio_free(pinfo->gpios[i]); - } - - kfree(pinfo->gpios); - kfree(pinfo->alow_flags); - return 0; -} - -static int __devinit of_mpc83xx_spi_probe(struct of_device *ofdev, - const struct of_device_id *ofid) -{ - struct device *dev = &ofdev->dev; - struct device_node *np = ofdev->node; - struct mpc83xx_spi_probe_info *pinfo; - struct fsl_spi_platform_data *pdata; - struct spi_master *master; - struct resource mem; - struct resource irq; - const void *prop; - int ret = -ENOMEM; - - pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL); - if (!pinfo) - return -ENOMEM; - - pdata = &pinfo->pdata; - dev->platform_data = pdata; - - /* Allocate bus num dynamically. */ - pdata->bus_num = -1; - - /* SPI controller is either clocked from QE or SoC clock. */ - pdata->sysclk = get_brgfreq(); - if (pdata->sysclk == -1) { - pdata->sysclk = fsl_get_sys_freq(); - if (pdata->sysclk == -1) { - ret = -ENODEV; - goto err_clk; - } - } - - prop = of_get_property(np, "mode", NULL); - if (prop && !strcmp(prop, "cpu-qe")) - pdata->qe_mode = 1; - - ret = of_mpc83xx_spi_get_chipselects(dev); - if (ret) - goto err; - - ret = of_address_to_resource(np, 0, &mem); - if (ret) - goto err; - - ret = of_irq_to_resource(np, 0, &irq); - if (!ret) { - ret = -EINVAL; - goto err; - } - - master = mpc83xx_spi_probe(dev, &mem, irq.start); - if (IS_ERR(master)) { - ret = PTR_ERR(master); - goto err; - } - - of_register_spi_devices(master, np); - - return 0; - -err: - of_mpc83xx_spi_free_chipselects(dev); -err_clk: - kfree(pinfo); - return ret; -} - -static int __devexit of_mpc83xx_spi_remove(struct of_device *ofdev) -{ - int ret; - - ret = mpc83xx_spi_remove(&ofdev->dev); - if (ret) - return ret; - of_mpc83xx_spi_free_chipselects(&ofdev->dev); - return 0; -} - -static const struct of_device_id of_mpc83xx_spi_match[] = { - { .compatible = "fsl,spi" }, - {}, -}; -MODULE_DEVICE_TABLE(of, of_mpc83xx_spi_match); - -static struct of_platform_driver of_mpc83xx_spi_driver = { - .name = "mpc83xx_spi", - .match_table = of_mpc83xx_spi_match, - .probe = of_mpc83xx_spi_probe, - .remove = __devexit_p(of_mpc83xx_spi_remove), -}; - -#ifdef CONFIG_MPC832x_RDB -/* - * XXX XXX XXX - * This is "legacy" platform driver, was used by the MPC8323E-RDB boards - * only. The driver should go away soon, since newer MPC8323E-RDB's device - * tree can work with OpenFirmware driver. But for now we support old trees - * as well. - */ -static int __devinit plat_mpc83xx_spi_probe(struct platform_device *pdev) -{ - struct resource *mem; - unsigned int irq; - struct spi_master *master; - - if (!pdev->dev.platform_data) - return -EINVAL; - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) - return -EINVAL; - - irq = platform_get_irq(pdev, 0); - if (!irq) - return -EINVAL; - - master = mpc83xx_spi_probe(&pdev->dev, mem, irq); - if (IS_ERR(master)) - return PTR_ERR(master); - return 0; -} - -static int __devexit plat_mpc83xx_spi_remove(struct platform_device *pdev) -{ - return mpc83xx_spi_remove(&pdev->dev); -} - MODULE_ALIAS("platform:mpc83xx_spi"); static struct platform_driver mpc83xx_spi_driver = { - .probe = plat_mpc83xx_spi_probe, - .remove = __exit_p(plat_mpc83xx_spi_remove), + .remove = __exit_p(mpc83xx_spi_remove), .driver = { .name = "mpc83xx_spi", .owner = THIS_MODULE, }, }; -static bool legacy_driver_failed; - -static void __init legacy_driver_register(void) -{ - legacy_driver_failed = platform_driver_register(&mpc83xx_spi_driver); -} - -static void __exit legacy_driver_unregister(void) -{ - if (legacy_driver_failed) - return; - platform_driver_unregister(&mpc83xx_spi_driver); -} -#else -static void __init legacy_driver_register(void) {} -static void __exit legacy_driver_unregister(void) {} -#endif /* CONFIG_MPC832x_RDB */ - static int __init mpc83xx_spi_init(void) { - legacy_driver_register(); - return of_register_platform_driver(&of_mpc83xx_spi_driver); + return platform_driver_probe(&mpc83xx_spi_driver, mpc83xx_spi_probe); } static void __exit mpc83xx_spi_exit(void) { - of_unregister_platform_driver(&of_mpc83xx_spi_driver); - legacy_driver_unregister(); + platform_driver_unregister(&mpc83xx_spi_driver); } module_init(mpc83xx_spi_init); diff --git a/trunk/drivers/spi/xilinx_spi.c b/trunk/drivers/spi/xilinx_spi.c index 494d3f756e29..fe7e5f35e5d0 100644 --- a/trunk/drivers/spi/xilinx_spi.c +++ b/trunk/drivers/spi/xilinx_spi.c @@ -354,7 +354,7 @@ static int __init xilinx_spi_of_probe(struct of_device *ofdev, if (xspi->regs == NULL) { rc = -ENOMEM; dev_warn(&ofdev->dev, "ioremap failure\n"); - goto release_mem; + goto put_master; } xspi->irq = r_irq->start; @@ -365,7 +365,7 @@ static int __init xilinx_spi_of_probe(struct of_device *ofdev, prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len); if (!prop || len < sizeof(*prop)) { dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n"); - goto unmap_io; + goto put_master; } master->num_chipselect = *prop; @@ -397,8 +397,6 @@ static int __init xilinx_spi_of_probe(struct of_device *ofdev, free_irq(xspi->irq, xspi); unmap_io: iounmap(xspi->regs); -release_mem: - release_mem_region(r_mem->start, resource_size(r_mem)); put_master: spi_master_put(master); return rc; @@ -408,7 +406,6 @@ static int __devexit xilinx_spi_remove(struct of_device *ofdev) { struct xilinx_spi *xspi; struct spi_master *master; - struct resource r_mem; master = platform_get_drvdata(ofdev); xspi = spi_master_get_devdata(master); @@ -416,8 +413,6 @@ static int __devexit xilinx_spi_remove(struct of_device *ofdev) spi_bitbang_stop(&xspi->bitbang); free_irq(xspi->irq, xspi); iounmap(xspi->regs); - if (!of_address_to_resource(ofdev->node, 0, &r_mem)) - release_mem_region(r_mem.start, resource_size(&r_mem)); dev_set_drvdata(&ofdev->dev, 0); spi_master_put(xspi->bitbang.master); diff --git a/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 80f9cc7137c2..e5752f615e09 100644 --- a/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -719,7 +719,7 @@ void ieee80211_softmac_scan(struct ieee80211_device *ieee) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) void ieee80211_softmac_scan_wq(struct work_struct *work) { - struct delayed_work *dwork = to_delayed_work(work); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq); #else void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee) @@ -777,7 +777,7 @@ void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) void ieee80211_softmac_scan_wq(struct work_struct *work) { - struct delayed_work *dwork = to_delayed_work(work); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, softmac_scan_wq); #else void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee) @@ -2980,7 +2980,7 @@ void ieee80211_start_monitor_mode(struct ieee80211_device *ieee) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) void ieee80211_start_ibss_wq(struct work_struct *work) { - struct delayed_work *dwork = to_delayed_work(work); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq); #else void ieee80211_start_ibss_wq(struct ieee80211_device *ieee) @@ -3162,7 +3162,7 @@ void ieee80211_disassociate(struct ieee80211_device *ieee) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) void ieee80211_associate_retry_wq(struct work_struct *work) { - struct delayed_work *dwork = to_delayed_work(work); + struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq); #else void ieee80211_associate_retry_wq(struct ieee80211_device *ieee) diff --git a/trunk/drivers/staging/rtl8187se/r8180_core.c b/trunk/drivers/staging/rtl8187se/r8180_core.c index ff1f23f99f27..66de5cc8ddf1 100644 --- a/trunk/drivers/staging/rtl8187se/r8180_core.c +++ b/trunk/drivers/staging/rtl8187se/r8180_core.c @@ -5438,7 +5438,7 @@ void rtl8180_hw_wakeup_wq (struct work_struct *work) // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq); // struct ieee80211_device * ieee = (struct ieee80211_device*) // container_of(work, struct ieee80211_device, watch_dog_wq); - struct delayed_work *dwork = to_delayed_work(work); + struct delayed_work *dwork = container_of(work,struct delayed_work,work); struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq); struct net_device *dev = ieee->dev; #else @@ -5459,7 +5459,7 @@ void rtl8180_hw_sleep_wq (struct work_struct *work) // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq); // struct ieee80211_device * ieee = (struct ieee80211_device*) // container_of(work, struct ieee80211_device, watch_dog_wq); - struct delayed_work *dwork = to_delayed_work(work); + struct delayed_work *dwork = container_of(work,struct delayed_work,work); struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq); struct net_device *dev = ieee->dev; #else @@ -6407,7 +6407,7 @@ priv->txnpring)/8); void rtl8180_tx_irq_wq(struct work_struct *work) { //struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq); - struct delayed_work *dwork = to_delayed_work(work); + struct delayed_work *dwork = container_of(work,struct delayed_work,work); struct ieee80211_device * ieee = (struct ieee80211_device*) container_of(dwork, struct ieee80211_device, watch_dog_wq); struct net_device *dev = ieee->dev; @@ -6691,7 +6691,7 @@ lizhaoming--------------------------- RF power on/power off ----------------- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) void GPIOChangeRFWorkItemCallBack(struct work_struct *work) { - //struct delayed_work *dwork = to_delayed_work(work); + //struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, GPIOChangeRFWorkItem.work); struct net_device *dev = ieee->dev; struct r8180_priv *priv = ieee80211_priv(dev); diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index 2a70563bbee1..742a5bc44be8 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -422,52 +421,57 @@ static int serial_break(struct tty_struct *tty, int break_state) return 0; } -static int serial_proc_show(struct seq_file *m, void *v) +static int serial_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) { struct usb_serial *serial; + int length = 0; int i; + off_t begin = 0; char tmp[40]; dbg("%s", __func__); - seq_puts(m, "usbserinfo:1.0 driver:2.0\n"); - for (i = 0; i < SERIAL_TTY_MINORS; ++i) { + length += sprintf(page, "usbserinfo:1.0 driver:2.0\n"); + for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) { serial = usb_serial_get_by_index(i); if (serial == NULL) continue; - seq_printf(m, "%d:", i); + length += sprintf(page+length, "%d:", i); if (serial->type->driver.owner) - seq_printf(m, " module:%s", + length += sprintf(page+length, " module:%s", module_name(serial->type->driver.owner)); - seq_printf(m, " name:\"%s\"", + length += sprintf(page+length, " name:\"%s\"", serial->type->description); - seq_printf(m, " vendor:%04x product:%04x", + length += sprintf(page+length, " vendor:%04x product:%04x", le16_to_cpu(serial->dev->descriptor.idVendor), le16_to_cpu(serial->dev->descriptor.idProduct)); - seq_printf(m, " num_ports:%d", serial->num_ports); - seq_printf(m, " port:%d", i - serial->minor + 1); + length += sprintf(page+length, " num_ports:%d", + serial->num_ports); + length += sprintf(page+length, " port:%d", + i - serial->minor + 1); usb_make_path(serial->dev, tmp, sizeof(tmp)); - seq_printf(m, " path:%s", tmp); + length += sprintf(page+length, " path:%s", tmp); - seq_putc(m, '\n'); + length += sprintf(page+length, "\n"); + if ((length + begin) > (off + count)) { + usb_serial_put(serial); + goto done; + } + if ((length + begin) < off) { + begin += length; + length = 0; + } usb_serial_put(serial); } - return 0; -} - -static int serial_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, serial_proc_show, NULL); + *eof = 1; +done: + if (off >= (length + begin)) + return 0; + *start = page + (off-begin); + return (count < begin+length-off) ? count : begin+length-off; } -static const struct file_operations serial_proc_fops = { - .owner = THIS_MODULE, - .open = serial_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static int serial_tiocmget(struct tty_struct *tty, struct file *file) { struct usb_serial_port *port = tty->driver_data; @@ -1109,9 +1113,9 @@ static const struct tty_operations serial_ops = { .unthrottle = serial_unthrottle, .break_ctl = serial_break, .chars_in_buffer = serial_chars_in_buffer, + .read_proc = serial_read_proc, .tiocmget = serial_tiocmget, .tiocmset = serial_tiocmset, - .proc_fops = &serial_proc_fops, }; struct tty_driver *usb_serial_tty_driver; diff --git a/trunk/drivers/usb/wusbcore/devconnect.c b/trunk/drivers/usb/wusbcore/devconnect.c index 386eaa22d215..f0aac0cf315a 100644 --- a/trunk/drivers/usb/wusbcore/devconnect.c +++ b/trunk/drivers/usb/wusbcore/devconnect.c @@ -471,7 +471,7 @@ static void __wusbhc_keep_alive(struct wusbhc *wusbhc) */ static void wusbhc_keep_alive_run(struct work_struct *ws) { - struct delayed_work *dw = to_delayed_work(ws); + struct delayed_work *dw = container_of(ws, struct delayed_work, work); struct wusbhc *wusbhc = container_of(dw, struct wusbhc, keep_alive_timer); mutex_lock(&wusbhc->mutex); diff --git a/trunk/drivers/video/68328fb.c b/trunk/drivers/video/68328fb.c index 0b17824b0eb5..7f907fb23b8a 100644 --- a/trunk/drivers/video/68328fb.c +++ b/trunk/drivers/video/68328fb.c @@ -471,11 +471,9 @@ int __init mc68x328fb_init(void) fb_info.pseudo_palette = &mc68x328fb_pseudo_palette; fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; - if (fb_alloc_cmap(&fb_info.cmap, 256, 0)) - return -ENOMEM; + fb_alloc_cmap(&fb_info.cmap, 256, 0); if (register_framebuffer(&fb_info) < 0) { - fb_dealloc_cmap(&fb_info.cmap); return -EINVAL; } @@ -496,7 +494,6 @@ module_init(mc68x328fb_init); static void __exit mc68x328fb_cleanup(void) { unregister_framebuffer(&fb_info); - fb_dealloc_cmap(&fb_info.cmap); } module_exit(mc68x328fb_cleanup); diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index ffe2f2796e29..41c27a44bd82 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -1597,8 +1597,32 @@ config FB_VT8623 Driver for CastleRock integrated graphics core in the VIA VT8623 [Apollo CLE266] chipset. +config FB_CYBLA + tristate "Cyberblade/i1 support" + depends on FB && PCI && X86_32 && !64BIT + select FB_CFB_IMAGEBLIT + ---help--- + This driver is supposed to support the Trident Cyberblade/i1 + graphics core integrated in the VIA VT8601A North Bridge, + also known as VIA Apollo PLE133. + + Status: + - Developed, tested and working on EPIA 5000 and EPIA 800. + - Does work reliable on all systems with CRT/LCD connected to + normal VGA ports. + - Should work on systems that do use the internal LCD port, but + this is absolutely not tested. + + Character imageblit, copyarea and rectangle fill are hw accelerated, + ypan scrolling is used by default. + + Please do read . + + To compile this driver as a module, choose M here: the + module will be called cyblafb. + config FB_TRIDENT - tristate "Trident/CyberXXX/CyberBlade support" + tristate "Trident support" depends on FB && PCI select FB_CFB_FILLRECT select FB_CFB_COPYAREA @@ -1609,14 +1633,21 @@ config FB_TRIDENT and Blade XP. There are also integrated versions of these chips called CyberXXXX, CyberImage or CyberBlade. These chips are mostly found in laptops - but also on some motherboards including early VIA EPIA motherboards. - For more information, read + but also on some motherboards. For more information, read + Say Y if you have such a graphics board. To compile this driver as a module, choose M here: the module will be called tridentfb. +config FB_TRIDENT_ACCEL + bool "Trident Acceleration functions (EXPERIMENTAL)" + depends on FB_TRIDENT && EXPERIMENTAL + ---help--- + This will compile the Trident frame buffer device with + acceleration functions. + config FB_ARK tristate "ARK 2000PV support" depends on FB && PCI @@ -1889,30 +1920,6 @@ config FB_TMIO_ACCELL depends on FB_TMIO default y -config FB_S3C - tristate "Samsung S3C framebuffer support" - depends on FB && ARCH_S3C64XX - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Frame buffer driver for the built-in FB controller in the Samsung - SoC line from the S3C2443 onwards, including the S3C2416, S3C2450, - and the S3C64XX series such as the S3C6400 and S3C6410. - - These chips all have the same basic framebuffer design with the - actual capabilities depending on the chip. For instance the S3C6400 - and S3C6410 support 4 hardware windows whereas the S3C24XX series - currently only have two. - - Currently the support is only for the S3C6400 and S3C6410 SoCs. - -config FB_S3C_DEBUG_REGWRITE - bool "Debug register writes" - depends on FB_S3C - ---help--- - Show all register writes via printk(KERN_DEBUG) - config FB_S3C2410 tristate "S3C2410 LCD framebuffer support" depends on FB && ARCH_S3C2410 diff --git a/trunk/drivers/video/Makefile b/trunk/drivers/video/Makefile index 0dbd6c68d76b..bb265eca7d57 100644 --- a/trunk/drivers/video/Makefile +++ b/trunk/drivers/video/Makefile @@ -76,7 +76,6 @@ obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \ atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o obj-$(CONFIG_FB_MAC) += macfb.o obj-$(CONFIG_FB_HECUBA) += hecubafb.o -obj-$(CONFIG_FB_N411) += n411.o obj-$(CONFIG_FB_HGA) += hgafb.o obj-$(CONFIG_FB_XVR500) += sunxvr500.o obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o @@ -111,7 +110,6 @@ obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o obj-$(CONFIG_FB_SH7760) += sh7760fb.o obj-$(CONFIG_FB_IMX) += imxfb.o -obj-$(CONFIG_FB_S3C) += s3c-fb.o obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o diff --git a/trunk/drivers/video/amba-clcd.c b/trunk/drivers/video/amba-clcd.c index 61050ab14128..4e046fed1380 100644 --- a/trunk/drivers/video/amba-clcd.c +++ b/trunk/drivers/video/amba-clcd.c @@ -408,9 +408,7 @@ static int clcdfb_register(struct clcd_fb *fb) /* * Allocate colourmap. */ - ret = fb_alloc_cmap(&fb->fb.cmap, 256, 0); - if (ret) - goto unmap; + fb_alloc_cmap(&fb->fb.cmap, 256, 0); /* * Ensure interrupts are disabled. @@ -428,8 +426,6 @@ static int clcdfb_register(struct clcd_fb *fb) printk(KERN_ERR "CLCD: cannot register framebuffer (%d)\n", ret); - fb_dealloc_cmap(&fb->fb.cmap); - unmap: iounmap(fb->regs); free_clk: clk_put(fb->clk); @@ -489,8 +485,6 @@ static int clcdfb_remove(struct amba_device *dev) clcdfb_disable(fb); unregister_framebuffer(&fb->fb); - if (fb->fb.cmap.len) - fb_dealloc_cmap(&fb->fb.cmap); iounmap(fb->regs); clk_put(fb->clk); diff --git a/trunk/drivers/video/amifb.c b/trunk/drivers/video/amifb.c index 82bedd7f7789..100f23661465 100644 --- a/trunk/drivers/video/amifb.c +++ b/trunk/drivers/video/amifb.c @@ -2437,9 +2437,7 @@ static int __init amifb_init(void) goto amifb_error; } - err = fb_alloc_cmap(&fb_info.cmap, 1<fix = asiliantfb_fix; p->fix.smem_start = addr; p->var = asiliantfb_var; p->fbops = &asiliantfb_ops; p->flags = FBINFO_DEFAULT; - err = fb_alloc_cmap(&p->cmap, 256, 0); - if (err) { - printk(KERN_ERR "C&T 69000 fb failed to alloc cmap memory\n"); - return err; - } + fb_alloc_cmap(&p->cmap, 256, 0); - err = register_framebuffer(p); - if (err < 0) { + if (register_framebuffer(p) < 0) { printk(KERN_ERR "C&T 69000 framebuffer failed to register\n"); - fb_dealloc_cmap(&p->cmap); - return err; + return; } printk(KERN_INFO "fb%d: Asiliant 69000 frame buffer (%dK RAM detected)\n", @@ -540,7 +532,6 @@ asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) { unsigned long addr, size; struct fb_info *p; - int err; if ((dp->resource[0].flags & IORESOURCE_MEM) == 0) return -ENODEV; @@ -569,13 +560,7 @@ asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) pci_write_config_dword(dp, 4, 0x02800083); writeb(3, p->screen_base + 0x400784); - err = init_asiliant(p, addr); - if (err) { - iounmap(p->screen_base); - release_mem_region(addr, size); - framebuffer_release(p); - return err; - } + init_asiliant(p, addr); pci_set_drvdata(dp, p); return 0; @@ -586,7 +571,6 @@ static void __devexit asiliantfb_remove(struct pci_dev *dp) struct fb_info *p = pci_get_drvdata(dp); unregister_framebuffer(p); - fb_dealloc_cmap(&p->cmap); iounmap(p->screen_base); release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0)); pci_set_drvdata(dp, NULL); diff --git a/trunk/drivers/video/aty/mach64_accel.c b/trunk/drivers/video/aty/mach64_accel.c index 0cc9724e61a2..a8f60c33863c 100644 --- a/trunk/drivers/video/aty/mach64_accel.c +++ b/trunk/drivers/video/aty/mach64_accel.c @@ -39,8 +39,7 @@ void aty_reset_engine(const struct atyfb_par *par) { /* reset engine */ aty_st_le32(GEN_TEST_CNTL, - aty_ld_le32(GEN_TEST_CNTL, par) & - ~(GUI_ENGINE_ENABLE | HWCURSOR_ENABLE), par); + aty_ld_le32(GEN_TEST_CNTL, par) & ~GUI_ENGINE_ENABLE, par); /* enable engine */ aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) | GUI_ENGINE_ENABLE, par); diff --git a/trunk/drivers/video/aty/mach64_cursor.c b/trunk/drivers/video/aty/mach64_cursor.c index 04c710804bb0..faf95da8fcbc 100644 --- a/trunk/drivers/video/aty/mach64_cursor.c +++ b/trunk/drivers/video/aty/mach64_cursor.c @@ -77,13 +77,9 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) if (par->asleep) return -EPERM; + /* Hide cursor */ wait_for_fifo(1, par); - if (cursor->enable) - aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) - | HWCURSOR_ENABLE, par); - else - aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) - & ~HWCURSOR_ENABLE, par); + aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) & ~HWCURSOR_ENABLE, par); /* set position */ if (cursor->set & FB_CUR_SETPOS) { @@ -113,7 +109,7 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) y<<=1; h<<=1; } - wait_for_fifo(3, par); + wait_for_fifo(4, par); aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1), par); aty_st_le32(CUR_HORZ_VERT_OFF, ((u32) (64 - h + yoff) << 16) | xoff, par); @@ -181,6 +177,11 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) } } + if (cursor->enable) { + wait_for_fifo(1, par); + aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) + | HWCURSOR_ENABLE, par); + } return 0; } diff --git a/trunk/drivers/video/aty/radeon_pm.c b/trunk/drivers/video/aty/radeon_pm.c index 97a1f095f327..c6d7cc76516f 100644 --- a/trunk/drivers/video/aty/radeon_pm.c +++ b/trunk/drivers/video/aty/radeon_pm.c @@ -89,9 +89,6 @@ static struct radeon_device_id radeon_workaround_list[] = { BUGFIX("Acer Aspire 2010", PCI_VENDOR_ID_AI, 0x0061, radeon_pm_off, radeon_reinitialize_M10), - BUGFIX("Acer Travelmate 290D/292LMi", - PCI_VENDOR_ID_AI, 0x005a, - radeon_pm_off, radeon_reinitialize_M10), { .ident = NULL } }; @@ -2585,7 +2582,7 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) * calling pci_set_power_state() */ radeonfb_whack_power_state(rinfo, PCI_D2); - __pci_complete_power_transition(rinfo->pdev, PCI_D2); + pci_set_power_state(rinfo->pdev, PCI_D2); } else { printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n", pci_name(rinfo->pdev)); diff --git a/trunk/drivers/video/backlight/backlight.c b/trunk/drivers/video/backlight/backlight.c index dd37cbcaf8ce..157057c79ca3 100644 --- a/trunk/drivers/video/backlight/backlight.c +++ b/trunk/drivers/video/backlight/backlight.c @@ -35,8 +35,6 @@ static int fb_notifier_callback(struct notifier_block *self, return 0; bd = container_of(self, struct backlight_device, fb_notif); - if (!lock_fb_info(evdata->info)) - return -ENODEV; mutex_lock(&bd->ops_lock); if (bd->ops) if (!bd->ops->check_fb || @@ -49,7 +47,6 @@ static int fb_notifier_callback(struct notifier_block *self, backlight_update_status(bd); } mutex_unlock(&bd->ops_lock); - unlock_fb_info(evdata->info); return 0; } diff --git a/trunk/drivers/video/backlight/lcd.c b/trunk/drivers/video/backlight/lcd.c index 0bb13df0fa89..b6449470106c 100644 --- a/trunk/drivers/video/backlight/lcd.c +++ b/trunk/drivers/video/backlight/lcd.c @@ -40,8 +40,6 @@ static int fb_notifier_callback(struct notifier_block *self, if (!ld->ops) return 0; - if (!lock_fb_info(evdata->info)) - return -ENODEV; mutex_lock(&ld->ops_lock); if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) { if (event == FB_EVENT_BLANK) { @@ -53,7 +51,6 @@ static int fb_notifier_callback(struct notifier_block *self, } } mutex_unlock(&ld->ops_lock); - unlock_fb_info(evdata->info); return 0; } diff --git a/trunk/drivers/video/cirrusfb.c b/trunk/drivers/video/cirrusfb.c index d42e385f091c..a2aa6ddffbe2 100644 --- a/trunk/drivers/video/cirrusfb.c +++ b/trunk/drivers/video/cirrusfb.c @@ -34,6 +34,8 @@ * */ +#define CIRRUSFB_VERSION "2.0-pre2" + #include #include #include @@ -70,9 +72,20 @@ * */ +/* enable debug output? */ +/* #define CIRRUSFB_DEBUG 1 */ + /* disable runtime assertions? */ /* #define CIRRUSFB_NDEBUG */ +/* debug output */ +#ifdef CIRRUSFB_DEBUG +#define DPRINTK(fmt, args...) \ + printk(KERN_DEBUG "%s: " fmt, __func__ , ## args) +#else +#define DPRINTK(fmt, args...) +#endif + /* debugging assertions */ #ifndef CIRRUSFB_NDEBUG #define assert(expr) \ @@ -95,15 +108,14 @@ /* board types */ enum cirrus_board { BT_NONE = 0, - BT_SD64, /* GD5434 */ - BT_PICCOLO, /* GD5426 */ - BT_PICASSO, /* GD5426 or GD5428 */ - BT_SPECTRUM, /* GD5426 or GD5428 */ + BT_SD64, + BT_PICCOLO, + BT_PICASSO, + BT_SPECTRUM, BT_PICASSO4, /* GD5446 */ BT_ALPINE, /* GD543x/4x */ BT_GD5480, - BT_LAGUNA, /* GD5462/64 */ - BT_LAGUNAB, /* GD5465 */ + BT_LAGUNA, /* GD546x */ }; /* @@ -138,17 +150,15 @@ static const struct cirrusfb_board_info_rec { .maxclock = { /* guess */ /* the SD64/P4 have a higher max. videoclock */ - 135100, 135100, 85500, 85500, 0 + 140000, 140000, 140000, 140000, 140000, }, .init_sr07 = true, .init_sr1f = true, .scrn_start_bit19 = true, .sr07 = 0xF0, .sr07_1bpp = 0xF0, - .sr07_1bpp_mux = 0xF6, .sr07_8bpp = 0xF1, - .sr07_8bpp_mux = 0xF7, - .sr1f = 0x1E + .sr1f = 0x20 }, [BT_PICCOLO] = { .name = "CL Piccolo", @@ -200,11 +210,9 @@ static const struct cirrusfb_board_info_rec { .init_sr07 = true, .init_sr1f = false, .scrn_start_bit19 = true, - .sr07 = 0xA0, - .sr07_1bpp = 0xA0, - .sr07_1bpp_mux = 0xA6, - .sr07_8bpp = 0xA1, - .sr07_8bpp_mux = 0xA7, + .sr07 = 0x20, + .sr07_1bpp = 0x20, + .sr07_8bpp = 0x21, .sr1f = 0 }, [BT_ALPINE] = { @@ -217,8 +225,8 @@ static const struct cirrusfb_board_info_rec { .init_sr1f = true, .scrn_start_bit19 = true, .sr07 = 0xA0, - .sr07_1bpp = 0xA0, - .sr07_1bpp_mux = 0xA6, + .sr07_1bpp = 0xA1, + .sr07_1bpp_mux = 0xA7, .sr07_8bpp = 0xA1, .sr07_8bpp_mux = 0xA7, .sr1f = 0x1C @@ -239,18 +247,8 @@ static const struct cirrusfb_board_info_rec { [BT_LAGUNA] = { .name = "CL Laguna", .maxclock = { - /* taken from X11 code */ - 170000, 170000, 170000, 170000, 135100, - }, - .init_sr07 = false, - .init_sr1f = false, - .scrn_start_bit19 = true, - }, - [BT_LAGUNAB] = { - .name = "CL Laguna AGP", - .maxclock = { - /* taken from X11 code */ - 170000, 250000, 170000, 170000, 135100, + /* guess */ + 135100, 135100, 135100, 135100, 135100, }, .init_sr07 = false, .init_sr1f = false, @@ -264,8 +262,8 @@ static const struct cirrusfb_board_info_rec { static struct pci_device_id cirrusfb_pci_table[] = { CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE), - CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64), - CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64), + CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE), + CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE), CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */ CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE), CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE), @@ -273,7 +271,7 @@ static struct pci_device_id cirrusfb_pci_table[] = { CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */ CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */ CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */ - CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNAB), /* CL Laguna 3DA*/ + CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA), /* CL Laguna 3DA*/ { 0, } }; MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table); @@ -328,6 +326,10 @@ static const struct { }; #endif /* CONFIG_ZORRO */ +struct cirrusfb_regs { + int multiplexing; +}; + #ifdef CIRRUSFB_DEBUG enum cirrusfb_dbg_reg_class { CRT, @@ -338,12 +340,10 @@ enum cirrusfb_dbg_reg_class { /* info about board */ struct cirrusfb_info { u8 __iomem *regbase; - u8 __iomem *laguna_mmio; enum cirrus_board btype; unsigned char SFR; /* Shadow of special function register */ - int multiplexing; - int doubleVCLK; + struct cirrusfb_regs currentmode; int blank_mode; u32 pseudo_palette[16]; @@ -357,8 +357,43 @@ static char *mode_option __devinitdata = "640x480@60"; /**** BEGIN PROTOTYPES ******************************************************/ /*--- Interface used by the world ------------------------------------------*/ +static int cirrusfb_init(void); +#ifndef MODULE +static int cirrusfb_setup(char *options); +#endif + +static int cirrusfb_open(struct fb_info *info, int user); +static int cirrusfb_release(struct fb_info *info, int user); +static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info); +static int cirrusfb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info); +static int cirrusfb_set_par(struct fb_info *info); static int cirrusfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); +static int cirrusfb_blank(int blank_mode, struct fb_info *info); +static void cirrusfb_fillrect(struct fb_info *info, + const struct fb_fillrect *region); +static void cirrusfb_copyarea(struct fb_info *info, + const struct fb_copyarea *area); +static void cirrusfb_imageblit(struct fb_info *info, + const struct fb_image *image); + +/* function table of the above functions */ +static struct fb_ops cirrusfb_ops = { + .owner = THIS_MODULE, + .fb_open = cirrusfb_open, + .fb_release = cirrusfb_release, + .fb_setcolreg = cirrusfb_setcolreg, + .fb_check_var = cirrusfb_check_var, + .fb_set_par = cirrusfb_set_par, + .fb_pan_display = cirrusfb_pan_display, + .fb_blank = cirrusfb_blank, + .fb_fillrect = cirrusfb_fillrect, + .fb_copyarea = cirrusfb_copyarea, + .fb_imageblit = cirrusfb_imageblit, +}; /*--- Internal routines ----------------------------------------------------*/ static void init_vgachip(struct fb_info *info); @@ -386,27 +421,22 @@ static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, u_short x, u_short y, u_short width, u_short height, - u32 fg_color, u32 bg_color, - u_short line_length, u_char blitmode); + u_char color, u_short line_length); static void bestclock(long freq, int *nom, int *den, int *div); #ifdef CIRRUSFB_DEBUG -static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase); -static void cirrusfb_dbg_print_regs(struct fb_info *info, - caddr_t regbase, +static void cirrusfb_dump(void); +static void cirrusfb_dbg_reg_dump(caddr_t regbase); +static void cirrusfb_dbg_print_regs(caddr_t regbase, enum cirrusfb_dbg_reg_class reg_class, ...); +static void cirrusfb_dbg_print_byte(const char *name, unsigned char val); #endif /* CIRRUSFB_DEBUG */ /*** END PROTOTYPES ********************************************************/ /*****************************************************************************/ /*** BEGIN Interface Used by the World ***************************************/ -static inline int is_laguna(const struct cirrusfb_info *cinfo) -{ - return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB; -} - static int opencount; /*--- Open /dev/fbx ---------------------------------------------------------*/ @@ -430,94 +460,85 @@ static int cirrusfb_release(struct fb_info *info, int user) /**** BEGIN Hardware specific Routines **************************************/ /* Check if the MCLK is not a better clock source */ -static int cirrusfb_check_mclk(struct fb_info *info, long freq) +static int cirrusfb_check_mclk(struct cirrusfb_info *cinfo, long freq) { - struct cirrusfb_info *cinfo = info->par; long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f; /* Read MCLK value */ mclk = (14318 * mclk) >> 3; - dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk); + DPRINTK("Read MCLK of %ld kHz\n", mclk); /* Determine if we should use MCLK instead of VCLK, and if so, what we * should divide it by to get VCLK */ if (abs(freq - mclk) < 250) { - dev_dbg(info->device, "Using VCLK = MCLK\n"); + DPRINTK("Using VCLK = MCLK\n"); return 1; } else if (abs(freq - (mclk / 2)) < 250) { - dev_dbg(info->device, "Using VCLK = MCLK/2\n"); + DPRINTK("Using VCLK = MCLK/2\n"); return 2; } return 0; } -static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var, - struct fb_info *info) +static int cirrusfb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) { - long freq; - long maxclock; - struct cirrusfb_info *cinfo = info->par; - unsigned maxclockidx = var->bits_per_pixel >> 3; - - /* convert from ps to kHz */ - freq = PICOS2KHZ(var->pixclock); - - dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq); - - maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx]; - cinfo->multiplexing = 0; + int yres; + /* memory size in pixels */ + unsigned pixels = info->screen_size * 8 / var->bits_per_pixel; - /* If the frequency is greater than we can support, we might be able - * to use multiplexing for the video mode */ - if (freq > maxclock) { - dev_err(info->device, - "Frequency greater than maxclock (%ld kHz)\n", - maxclock); + switch (var->bits_per_pixel) { + case 1: + pixels /= 4; + break; /* 8 pixel per byte, only 1/4th of mem usable */ + case 8: + case 16: + case 32: + break; /* 1 pixel == 1 byte */ + default: + printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..." + "color depth not supported.\n", + var->xres, var->yres, var->bits_per_pixel); + DPRINTK("EXIT - EINVAL error\n"); return -EINVAL; } - /* - * Additional constraint: 8bpp uses DAC clock doubling to allow maximum - * pixel clock - */ - if (var->bits_per_pixel == 8) { - switch (cinfo->btype) { - case BT_ALPINE: - case BT_SD64: - case BT_PICASSO4: - if (freq > 85500) - cinfo->multiplexing = 1; - break; - case BT_GD5480: - if (freq > 135100) - cinfo->multiplexing = 1; - break; - default: - break; - } + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + /* use highest possible virtual resolution */ + if (var->yres_virtual == -1) { + var->yres_virtual = pixels / var->xres_virtual; + + printk(KERN_INFO "cirrusfb: virtual resolution set to " + "maximum of %dx%d\n", var->xres_virtual, + var->yres_virtual); } + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; - /* If we have a 1MB 5434, we need to put ourselves in a mode where - * the VCLK is double the pixel clock. */ - cinfo->doubleVCLK = 0; - if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ && - var->bits_per_pixel == 16) { - cinfo->doubleVCLK = 1; + if (var->xres_virtual * var->yres_virtual > pixels) { + printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected... " + "virtual resolution too high to fit into video memory!\n", + var->xres_virtual, var->yres_virtual, + var->bits_per_pixel); + DPRINTK("EXIT - EINVAL error\n"); + return -EINVAL; } - return 0; -} -static int cirrusfb_check_var(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - int yres; - /* memory size in pixels */ - unsigned pixels = info->screen_size * 8 / var->bits_per_pixel; - struct cirrusfb_info *cinfo = info->par; + if (var->xoffset < 0) + var->xoffset = 0; + if (var->yoffset < 0) + var->yoffset = 0; + + /* truncate xoffset and yoffset to maximum if too high */ + if (var->xoffset > var->xres_virtual - var->xres) + var->xoffset = var->xres_virtual - var->xres - 1; + if (var->yoffset > var->yres_virtual - var->yres) + var->yoffset = var->yres_virtual - var->yres - 1; switch (var->bits_per_pixel) { case 1: @@ -529,7 +550,7 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, case 8: var->red.offset = 0; - var->red.length = 8; + var->red.length = 6; var->green = var->red; var->blue = var->red; break; @@ -540,20 +561,20 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, var->green.offset = -3; var->blue.offset = 8; } else { - var->red.offset = 11; + var->red.offset = 10; var->green.offset = 5; var->blue.offset = 0; } var->red.length = 5; - var->green.length = 6; + var->green.length = 5; var->blue.length = 5; break; - case 24: + case 32: if (isPReP) { - var->red.offset = 0; - var->green.offset = 8; - var->blue.offset = 16; + var->red.offset = 8; + var->green.offset = 16; + var->blue.offset = 24; } else { var->red.offset = 16; var->green.offset = 8; @@ -565,45 +586,12 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, break; default: - dev_dbg(info->device, - "Unsupported bpp size: %d\n", var->bits_per_pixel); + DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel); assert(false); /* should never occur */ break; } - if (var->xres_virtual < var->xres) - var->xres_virtual = var->xres; - /* use highest possible virtual resolution */ - if (var->yres_virtual == -1) { - var->yres_virtual = pixels / var->xres_virtual; - - dev_info(info->device, - "virtual resolution set to maximum of %dx%d\n", - var->xres_virtual, var->yres_virtual); - } - if (var->yres_virtual < var->yres) - var->yres_virtual = var->yres; - - if (var->xres_virtual * var->yres_virtual > pixels) { - dev_err(info->device, "mode %dx%dx%d rejected... " - "virtual resolution too high to fit into video memory!\n", - var->xres_virtual, var->yres_virtual, - var->bits_per_pixel); - return -EINVAL; - } - - if (var->xoffset < 0) - var->xoffset = 0; - if (var->yoffset < 0) - var->yoffset = 0; - - /* truncate xoffset and yoffset to maximum if too high */ - if (var->xoffset > var->xres_virtual - var->xres) - var->xoffset = var->xres_virtual - var->xres - 1; - if (var->yoffset > var->yres_virtual - var->yres) - var->yoffset = var->yres_virtual - var->yres - 1; - var->red.msb_right = var->green.msb_right = var->blue.msb_right = @@ -618,31 +606,99 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, yres = (yres + 1) / 2; if (yres >= 1280) { - dev_err(info->device, "ERROR: VerticalTotal >= 1280; " + printk(KERN_ERR "cirrusfb: ERROR: VerticalTotal >= 1280; " "special treatment required! (TODO)\n"); + DPRINTK("EXIT - EINVAL error\n"); return -EINVAL; } - if (cirrusfb_check_pixclock(var, info)) - return -EINVAL; + return 0; +} + +static int cirrusfb_decode_var(const struct fb_var_screeninfo *var, + struct cirrusfb_regs *regs, + struct fb_info *info) +{ + long freq; + long maxclock; + int maxclockidx = var->bits_per_pixel >> 3; + struct cirrusfb_info *cinfo = info->par; + + switch (var->bits_per_pixel) { + case 1: + info->fix.line_length = var->xres_virtual / 8; + info->fix.visual = FB_VISUAL_MONO10; + break; + + case 8: + info->fix.line_length = var->xres_virtual; + info->fix.visual = FB_VISUAL_PSEUDOCOLOR; + break; + + case 16: + case 32: + info->fix.line_length = var->xres_virtual * maxclockidx; + info->fix.visual = FB_VISUAL_TRUECOLOR; + break; + + default: + DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel); + assert(false); + /* should never occur */ + break; + } + + info->fix.type = FB_TYPE_PACKED_PIXELS; + + /* convert from ps to kHz */ + freq = PICOS2KHZ(var->pixclock); + + DPRINTK("desired pixclock: %ld kHz\n", freq); + + maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx]; + regs->multiplexing = 0; - if (!is_laguna(cinfo)) - var->accel_flags = FB_ACCELF_TEXT; + /* If the frequency is greater than we can support, we might be able + * to use multiplexing for the video mode */ + if (freq > maxclock) { + switch (cinfo->btype) { + case BT_ALPINE: + case BT_GD5480: + regs->multiplexing = 1; + break; + default: + printk(KERN_ERR "cirrusfb: Frequency greater " + "than maxclock (%ld kHz)\n", maxclock); + DPRINTK("EXIT - return -EINVAL\n"); + return -EINVAL; + } + } +#if 0 + /* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where + * the VCLK is double the pixel clock. */ + switch (var->bits_per_pixel) { + case 16: + case 32: + if (var->xres <= 800) + /* Xbh has this type of clock for 32-bit */ + freq /= 2; + break; + } +#endif return 0; } -static void cirrusfb_set_mclk_as_source(const struct fb_info *info, int div) +static void cirrusfb_set_mclk_as_source(const struct cirrusfb_info *cinfo, + int div) { - struct cirrusfb_info *cinfo = info->par; unsigned char old1f, old1e; - assert(cinfo != NULL); old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40; if (div) { - dev_dbg(info->device, "Set %s as pixclock source.\n", - (div == 2) ? "MCLK/2" : "MCLK"); + DPRINTK("Set %s as pixclock source.\n", + (div == 2) ? "MCLK/2" : "MCLK"); old1f |= 0x40; old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1; if (div == 2) @@ -662,119 +718,101 @@ static int cirrusfb_set_par_foo(struct fb_info *info) { struct cirrusfb_info *cinfo = info->par; struct fb_var_screeninfo *var = &info->var; + struct cirrusfb_regs regs; u8 __iomem *regbase = cinfo->regbase; unsigned char tmp; - int pitch; + int offset = 0, err; const struct cirrusfb_board_info_rec *bi; int hdispend, hsyncstart, hsyncend, htotal; int yres, vdispend, vsyncstart, vsyncend, vtotal; long freq; int nom, den, div; - unsigned int control = 0, format = 0, threshold = 0; - dev_dbg(info->device, "Requested mode: %dx%dx%d\n", + DPRINTK("ENTER\n"); + DPRINTK("Requested mode: %dx%dx%d\n", var->xres, var->yres, var->bits_per_pixel); + DPRINTK("pixclock: %d\n", var->pixclock); - switch (var->bits_per_pixel) { - case 1: - info->fix.line_length = var->xres_virtual / 8; - info->fix.visual = FB_VISUAL_MONO10; - break; - - case 8: - info->fix.line_length = var->xres_virtual; - info->fix.visual = FB_VISUAL_PSEUDOCOLOR; - break; + init_vgachip(info); - case 16: - case 24: - info->fix.line_length = var->xres_virtual * - var->bits_per_pixel >> 3; - info->fix.visual = FB_VISUAL_TRUECOLOR; - break; + err = cirrusfb_decode_var(var, ®s, info); + if (err) { + /* should never happen */ + DPRINTK("mode change aborted. invalid var.\n"); + return -EINVAL; } - info->fix.type = FB_TYPE_PACKED_PIXELS; - - init_vgachip(info); bi = &cirrusfb_board_info[cinfo->btype]; hsyncstart = var->xres + var->right_margin; hsyncend = hsyncstart + var->hsync_len; - htotal = (hsyncend + var->left_margin) / 8; - hdispend = var->xres / 8; - hsyncstart = hsyncstart / 8; - hsyncend = hsyncend / 8; + htotal = (hsyncend + var->left_margin) / 8 - 5; + hdispend = var->xres / 8 - 1; + hsyncstart = hsyncstart / 8 + 1; + hsyncend = hsyncend / 8 + 1; - vdispend = var->yres; - vsyncstart = vdispend + var->lower_margin; + yres = var->yres; + vsyncstart = yres + var->lower_margin; vsyncend = vsyncstart + var->vsync_len; vtotal = vsyncend + var->upper_margin; + vdispend = yres - 1; if (var->vmode & FB_VMODE_DOUBLE) { - vdispend *= 2; + yres *= 2; vsyncstart *= 2; vsyncend *= 2; vtotal *= 2; } else if (var->vmode & FB_VMODE_INTERLACED) { - vdispend = (vdispend + 1) / 2; + yres = (yres + 1) / 2; vsyncstart = (vsyncstart + 1) / 2; vsyncend = (vsyncend + 1) / 2; vtotal = (vtotal + 1) / 2; } - yres = vdispend; + + vtotal -= 2; + vsyncstart -= 1; + vsyncend -= 1; + if (yres >= 1024) { vtotal /= 2; vsyncstart /= 2; vsyncend /= 2; vdispend /= 2; } - - vdispend -= 1; - vsyncstart -= 1; - vsyncend -= 1; - vtotal -= 2; - - if (cinfo->multiplexing) { + if (regs.multiplexing) { htotal /= 2; hsyncstart /= 2; hsyncend /= 2; hdispend /= 2; } - - htotal -= 5; - hdispend -= 1; - hsyncstart += 1; - hsyncend += 1; - /* unlock register VGA_CRTC_H_TOTAL..CRT7 */ vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */ /* if debugging is enabled, all parameters get output before writing */ - dev_dbg(info->device, "CRT0: %d\n", htotal); + DPRINTK("CRT0: %d\n", htotal); vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal); - dev_dbg(info->device, "CRT1: %d\n", hdispend); + DPRINTK("CRT1: %d\n", hdispend); vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend); - dev_dbg(info->device, "CRT2: %d\n", var->xres / 8); + DPRINTK("CRT2: %d\n", var->xres / 8); vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8); /* + 128: Compatible read */ - dev_dbg(info->device, "CRT3: 128+%d\n", (htotal + 5) % 32); + DPRINTK("CRT3: 128+%d\n", (htotal + 5) % 32); vga_wcrt(regbase, VGA_CRTC_H_BLANK_END, 128 + ((htotal + 5) % 32)); - dev_dbg(info->device, "CRT4: %d\n", hsyncstart); + DPRINTK("CRT4: %d\n", hsyncstart); vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart); tmp = hsyncend % 32; if ((htotal + 5) & 32) tmp += 128; - dev_dbg(info->device, "CRT5: %d\n", tmp); + DPRINTK("CRT5: %d\n", tmp); vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp); - dev_dbg(info->device, "CRT6: %d\n", vtotal & 0xff); + DPRINTK("CRT6: %d\n", vtotal & 0xff); vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff); tmp = 16; /* LineCompare bit #9 */ @@ -792,7 +830,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) tmp |= 64; if (vsyncstart & 512) tmp |= 128; - dev_dbg(info->device, "CRT7: %d\n", tmp); + DPRINTK("CRT7: %d\n", tmp); vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp); tmp = 0x40; /* LineCompare bit #8 */ @@ -800,25 +838,25 @@ static int cirrusfb_set_par_foo(struct fb_info *info) tmp |= 0x20; if (var->vmode & FB_VMODE_DOUBLE) tmp |= 0x80; - dev_dbg(info->device, "CRT9: %d\n", tmp); + DPRINTK("CRT9: %d\n", tmp); vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp); - dev_dbg(info->device, "CRT10: %d\n", vsyncstart & 0xff); + DPRINTK("CRT10: %d\n", vsyncstart & 0xff); vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff); - dev_dbg(info->device, "CRT11: 64+32+%d\n", vsyncend % 16); + DPRINTK("CRT11: 64+32+%d\n", vsyncend % 16); vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32); - dev_dbg(info->device, "CRT12: %d\n", vdispend & 0xff); + DPRINTK("CRT12: %d\n", vdispend & 0xff); vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff); - dev_dbg(info->device, "CRT15: %d\n", (vdispend + 1) & 0xff); + DPRINTK("CRT15: %d\n", (vdispend + 1) & 0xff); vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff); - dev_dbg(info->device, "CRT16: %d\n", vtotal & 0xff); + DPRINTK("CRT16: %d\n", vtotal & 0xff); vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff); - dev_dbg(info->device, "CRT18: 0xff\n"); + DPRINTK("CRT18: 0xff\n"); vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff); tmp = 0; @@ -833,75 +871,41 @@ static int cirrusfb_set_par_foo(struct fb_info *info) if (vtotal & 512) tmp |= 128; - dev_dbg(info->device, "CRT1a: %d\n", tmp); + DPRINTK("CRT1a: %d\n", tmp); vga_wcrt(regbase, CL_CRT1A, tmp); freq = PICOS2KHZ(var->pixclock); - if (var->bits_per_pixel == 24) - if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) - freq *= 3; - if (cinfo->multiplexing) - freq /= 2; - if (cinfo->doubleVCLK) - freq *= 2; - bestclock(freq, &nom, &den, &div); - dev_dbg(info->device, "VCLK freq: %ld kHz nom: %d den: %d div: %d\n", - freq, nom, den, div); - /* set VCLK0 */ /* hardware RefClock: 14.31818 MHz */ /* formula: VClk = (OSC * N) / (D * (1+P)) */ /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */ - if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_PICASSO4 || - cinfo->btype == BT_SD64) { + if (cinfo->btype == BT_ALPINE) { /* if freq is close to mclk or mclk/2 select mclk * as clock source */ - int divMCLK = cirrusfb_check_mclk(info, freq); - if (divMCLK) + int divMCLK = cirrusfb_check_mclk(cinfo, freq); + if (divMCLK) { nom = 0; - cirrusfb_set_mclk_as_source(info, divMCLK); - } - if (is_laguna(cinfo)) { - long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc); - unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407); - unsigned short tile_control; - - if (cinfo->btype == BT_LAGUNAB) { - tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4); - tile_control &= ~0x80; - fb_writew(tile_control, cinfo->laguna_mmio + 0x2c4); + cirrusfb_set_mclk_as_source(cinfo, divMCLK); } - - fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc); - fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407); - control = fb_readw(cinfo->laguna_mmio + 0x402); - threshold = fb_readw(cinfo->laguna_mmio + 0xea); - control &= ~0x6800; - format = 0; - threshold &= 0xffc0 & 0x3fbf; } if (nom) { + vga_wseq(regbase, CL_SEQRB, nom); tmp = den << 1; if (div != 0) tmp |= 1; + /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */ if ((cinfo->btype == BT_SD64) || (cinfo->btype == BT_ALPINE) || (cinfo->btype == BT_GD5480)) tmp |= 0x80; - /* Laguna chipset has reversed clock registers */ - if (is_laguna(cinfo)) { - vga_wseq(regbase, CL_SEQRE, tmp); - vga_wseq(regbase, CL_SEQR1E, nom); - } else { - vga_wseq(regbase, CL_SEQRE, nom); - vga_wseq(regbase, CL_SEQR1E, tmp); - } + DPRINTK("CL_SEQR1B: %ld\n", (long) tmp); + vga_wseq(regbase, CL_SEQR1B, tmp); } if (yres >= 1024) @@ -912,6 +916,9 @@ static int cirrusfb_set_par_foo(struct fb_info *info) * address wrap, no compat. */ vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3); +/* HAEH? vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); + * previously: 0x00 unlock VGA_CRTC_H_TOTAL..CRT7 */ + /* don't know if it would hurt to also program this if no interlaced */ /* mode is used, but I feel better this way.. :-) */ if (var->vmode & FB_VMODE_INTERLACED) @@ -919,15 +926,19 @@ static int cirrusfb_set_par_foo(struct fb_info *info) else vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */ - /* adjust horizontal/vertical sync type (low/high), use VCLK3 */ + vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0); + + /* adjust horizontal/vertical sync type (low/high) */ /* enable display memory & CRTC I/O address for color mode */ - tmp = 0x03 | 0xc; + tmp = 0x03; if (var->sync & FB_SYNC_HOR_HIGH_ACT) tmp |= 0x40; if (var->sync & FB_SYNC_VERT_HIGH_ACT) tmp |= 0x80; WGen(cinfo, VGA_MIS_W, tmp); + /* Screen A Preset Row-Scan register */ + vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0); /* text cursor on and start line */ vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0); /* text cursor end line */ @@ -941,7 +952,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) /* programming for different color depths */ if (var->bits_per_pixel == 1) { - dev_dbg(info->device, "preparing for 1 bit deep display\n"); + DPRINTK("cirrusfb: preparing for 1 bit deep display\n"); vga_wgfx(regbase, VGA_GFX_MODE, 0); /* mode register */ /* SR07 */ @@ -953,53 +964,68 @@ static int cirrusfb_set_par_foo(struct fb_info *info) case BT_PICASSO4: case BT_ALPINE: case BT_GD5480: + DPRINTK(" (for GD54xx)\n"); vga_wseq(regbase, CL_SEQR7, - cinfo->multiplexing ? + regs.multiplexing ? bi->sr07_1bpp_mux : bi->sr07_1bpp); break; case BT_LAGUNA: - case BT_LAGUNAB: + DPRINTK(" (for GD546x)\n"); vga_wseq(regbase, CL_SEQR7, vga_rseq(regbase, CL_SEQR7) & ~0x01); break; default: - dev_warn(info->device, "unknown Board\n"); + printk(KERN_WARNING "cirrusfb: unknown Board\n"); break; } /* Extended Sequencer Mode */ switch (cinfo->btype) { + case BT_SD64: + /* setting the SEQRF on SD64 is not necessary + * (only during init) + */ + DPRINTK("(for SD64)\n"); + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x1a); + break; case BT_PICCOLO: case BT_SPECTRUM: + DPRINTK("(for Piccolo/Spectrum)\n"); + /* ### ueberall 0x22? */ + /* ##vorher 1c MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x22); /* evtl d0 bei 1 bit? avoid FIFO underruns..? */ vga_wseq(regbase, CL_SEQRF, 0xb0); break; case BT_PICASSO: + DPRINTK("(for Picasso)\n"); + /* ##vorher 22 MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x22); /* ## vorher d0 avoid FIFO underruns..? */ vga_wseq(regbase, CL_SEQRF, 0xd0); break; - case BT_SD64: case BT_PICASSO4: case BT_ALPINE: case BT_GD5480: case BT_LAGUNA: - case BT_LAGUNAB: + DPRINTK(" (for GD54xx)\n"); /* do nothing */ break; default: - dev_warn(info->device, "unknown Board\n"); + printk(KERN_WARNING "cirrusfb: unknown Board\n"); break; } /* pixel mask: pass-through for first plane */ WGen(cinfo, VGA_PEL_MSK, 0x01); - if (cinfo->multiplexing) + if (regs.multiplexing) /* hidden dac reg: 1280x1024 */ WHDR(cinfo, 0x4a); else @@ -1009,6 +1035,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06); /* plane mask: only write to first plane */ vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01); + offset = var->xres_virtual / 16; } /****************************************************** @@ -1018,7 +1045,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) */ else if (var->bits_per_pixel == 8) { - dev_dbg(info->device, "preparing for 8 bit deep display\n"); + DPRINTK("cirrusfb: preparing for 8 bit deep display\n"); switch (cinfo->btype) { case BT_SD64: case BT_PICCOLO: @@ -1027,27 +1054,34 @@ static int cirrusfb_set_par_foo(struct fb_info *info) case BT_PICASSO4: case BT_ALPINE: case BT_GD5480: + DPRINTK(" (for GD54xx)\n"); vga_wseq(regbase, CL_SEQR7, - cinfo->multiplexing ? + regs.multiplexing ? bi->sr07_8bpp_mux : bi->sr07_8bpp); break; case BT_LAGUNA: - case BT_LAGUNAB: + DPRINTK(" (for GD546x)\n"); vga_wseq(regbase, CL_SEQR7, vga_rseq(regbase, CL_SEQR7) | 0x01); - threshold |= 0x10; break; default: - dev_warn(info->device, "unknown Board\n"); + printk(KERN_WARNING "cirrusfb: unknown Board\n"); break; } switch (cinfo->btype) { + case BT_SD64: + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x1d); + break; + case BT_PICCOLO: case BT_PICASSO: case BT_SPECTRUM: + /* ### vorher 1c MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x22); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); break; @@ -1057,27 +1091,40 @@ static int cirrusfb_set_par_foo(struct fb_info *info) /* ### INCOMPLETE!! */ vga_wseq(regbase, CL_SEQRF, 0xb8); #endif +/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */ + break; + case BT_ALPINE: - case BT_SD64: + DPRINTK(" (for GD543x)\n"); + /* We already set SRF and SR1F */ + break; + case BT_GD5480: case BT_LAGUNA: - case BT_LAGUNAB: + DPRINTK(" (for GD54xx)\n"); /* do nothing */ break; default: - dev_warn(info->device, "unknown board\n"); + printk(KERN_WARNING "cirrusfb: unknown Board\n"); break; } /* mode register: 256 color mode */ vga_wgfx(regbase, VGA_GFX_MODE, 64); - if (cinfo->multiplexing) + /* pixel mask: pass-through all planes */ + WGen(cinfo, VGA_PEL_MSK, 0xff); + if (regs.multiplexing) /* hidden dac reg: 1280x1024 */ WHDR(cinfo, 0x4a); else /* hidden dac: nothing */ WHDR(cinfo, 0); + /* memory mode: chain4, ext. memory */ + vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a); + /* plane mask: enable writing to all 4 planes */ + vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff); + offset = var->xres_virtual / 8; } /****************************************************** @@ -1087,110 +1134,147 @@ static int cirrusfb_set_par_foo(struct fb_info *info) */ else if (var->bits_per_pixel == 16) { - dev_dbg(info->device, "preparing for 16 bit deep display\n"); + DPRINTK("cirrusfb: preparing for 16 bit deep display\n"); switch (cinfo->btype) { + case BT_SD64: + /* Extended Sequencer Mode: 256c col. mode */ + vga_wseq(regbase, CL_SEQR7, 0xf7); + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x1e); + break; + case BT_PICCOLO: case BT_SPECTRUM: vga_wseq(regbase, CL_SEQR7, 0x87); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x22); break; case BT_PICASSO: vga_wseq(regbase, CL_SEQR7, 0x27); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x22); break; - case BT_SD64: case BT_PICASSO4: + vga_wseq(regbase, CL_SEQR7, 0x27); +/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */ + break; + case BT_ALPINE: - /* Extended Sequencer Mode: 256c col. mode */ - vga_wseq(regbase, CL_SEQR7, - cinfo->doubleVCLK ? 0xa3 : 0xa7); + DPRINTK(" (for GD543x)\n"); + vga_wseq(regbase, CL_SEQR7, 0xa7); break; case BT_GD5480: + DPRINTK(" (for GD5480)\n"); vga_wseq(regbase, CL_SEQR7, 0x17); /* We already set SRF and SR1F */ break; case BT_LAGUNA: - case BT_LAGUNAB: + DPRINTK(" (for GD546x)\n"); vga_wseq(regbase, CL_SEQR7, vga_rseq(regbase, CL_SEQR7) & ~0x01); - control |= 0x2000; - format |= 0x1400; - threshold |= 0x10; break; default: - dev_warn(info->device, "unknown Board\n"); + printk(KERN_WARNING "CIRRUSFB: unknown Board\n"); break; } /* mode register: 256 color mode */ vga_wgfx(regbase, VGA_GFX_MODE, 64); + /* pixel mask: pass-through all planes */ + WGen(cinfo, VGA_PEL_MSK, 0xff); #ifdef CONFIG_PCI - WHDR(cinfo, cinfo->doubleVCLK ? 0xe1 : 0xc1); + WHDR(cinfo, 0xc0); /* Copy Xbh */ #elif defined(CONFIG_ZORRO) /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */ WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */ #endif + /* memory mode: chain4, ext. memory */ + vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a); + /* plane mask: enable writing to all 4 planes */ + vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff); + offset = var->xres_virtual / 4; } /****************************************************** * - * 24 bpp + * 32 bpp * */ - else if (var->bits_per_pixel == 24) { - dev_dbg(info->device, "preparing for 24 bit deep display\n"); + else if (var->bits_per_pixel == 32) { + DPRINTK("cirrusfb: preparing for 32 bit deep display\n"); switch (cinfo->btype) { + case BT_SD64: + /* Extended Sequencer Mode: 256c col. mode */ + vga_wseq(regbase, CL_SEQR7, 0xf9); + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x1e); + break; + case BT_PICCOLO: case BT_SPECTRUM: vga_wseq(regbase, CL_SEQR7, 0x85); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x22); break; case BT_PICASSO: vga_wseq(regbase, CL_SEQR7, 0x25); /* Fast Page-Mode writes */ vga_wseq(regbase, CL_SEQRF, 0xb0); + /* MCLK select */ + vga_wseq(regbase, CL_SEQR1F, 0x22); break; - case BT_SD64: case BT_PICASSO4: + vga_wseq(regbase, CL_SEQR7, 0x25); +/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */ + break; + case BT_ALPINE: - /* Extended Sequencer Mode: 256c col. mode */ - vga_wseq(regbase, CL_SEQR7, 0xa5); + DPRINTK(" (for GD543x)\n"); + vga_wseq(regbase, CL_SEQR7, 0xa9); break; case BT_GD5480: - vga_wseq(regbase, CL_SEQR7, 0x15); + DPRINTK(" (for GD5480)\n"); + vga_wseq(regbase, CL_SEQR7, 0x19); /* We already set SRF and SR1F */ break; case BT_LAGUNA: - case BT_LAGUNAB: + DPRINTK(" (for GD546x)\n"); vga_wseq(regbase, CL_SEQR7, vga_rseq(regbase, CL_SEQR7) & ~0x01); - control |= 0x4000; - format |= 0x2400; - threshold |= 0x20; break; default: - dev_warn(info->device, "unknown Board\n"); + printk(KERN_WARNING "cirrusfb: unknown Board\n"); break; } /* mode register: 256 color mode */ vga_wgfx(regbase, VGA_GFX_MODE, 64); + /* pixel mask: pass-through all planes */ + WGen(cinfo, VGA_PEL_MSK, 0xff); /* hidden dac reg: 8-8-8 mode (24 or 32) */ WHDR(cinfo, 0xc5); + /* memory mode: chain4, ext. memory */ + vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a); + /* plane mask: enable writing to all 4 planes */ + vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff); + offset = var->xres_virtual / 4; } /****************************************************** @@ -1200,55 +1284,67 @@ static int cirrusfb_set_par_foo(struct fb_info *info) */ else - dev_err(info->device, - "What's this? requested color depth == %d.\n", + printk(KERN_ERR "cirrusfb: What's this?? " + " requested color depth == %d.\n", var->bits_per_pixel); - pitch = info->fix.line_length >> 3; - vga_wcrt(regbase, VGA_CRTC_OFFSET, pitch & 0xff); + vga_wcrt(regbase, VGA_CRTC_OFFSET, offset & 0xff); tmp = 0x22; - if (pitch & 0x100) + if (offset & 0x100) tmp |= 0x10; /* offset overflow bit */ /* screen start addr #16-18, fastpagemode cycles */ vga_wcrt(regbase, CL_CRT1B, tmp); - /* screen start address bit 19 */ - if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) - vga_wcrt(regbase, CL_CRT1D, (pitch >> 9) & 1); - - if (is_laguna(cinfo)) { - tmp = 0; - if ((htotal + 5) & 256) - tmp |= 128; - if (hdispend & 256) - tmp |= 64; - if (hsyncstart & 256) - tmp |= 48; - if (vtotal & 1024) - tmp |= 8; - if (vdispend & 1024) - tmp |= 4; - if (vsyncstart & 1024) - tmp |= 3; - - vga_wcrt(regbase, CL_CRT1E, tmp); - dev_dbg(info->device, "CRT1e: %d\n", tmp); - } - + if (cinfo->btype == BT_SD64 || + cinfo->btype == BT_PICASSO4 || + cinfo->btype == BT_ALPINE || + cinfo->btype == BT_GD5480) + /* screen start address bit 19 */ + vga_wcrt(regbase, CL_CRT1D, 0x00); + + /* text cursor location high */ + vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0); + /* text cursor location low */ + vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0); + /* underline row scanline = at very bottom */ + vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0); + + /* controller mode */ + vga_wattr(regbase, VGA_ATC_MODE, 1); + /* overscan (border) color */ + vga_wattr(regbase, VGA_ATC_OVERSCAN, 0); + /* color plane enable */ + vga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 15); /* pixel panning */ vga_wattr(regbase, CL_AR33, 0); + /* color select */ + vga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0); /* [ EGS: SetOffset(); ] */ /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */ AttrOn(cinfo); - if (is_laguna(cinfo)) { - /* no tiles */ - fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402); - fb_writew(format, cinfo->laguna_mmio + 0xc0); - fb_writew(threshold, cinfo->laguna_mmio + 0xea); - } + /* set/reset register */ + vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0); + /* set/reset enable */ + vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0); + /* color compare */ + vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0); + /* data rotate */ + vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0); + /* read map select */ + vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0); + /* miscellaneous register */ + vga_wgfx(regbase, VGA_GFX_MISC, 1); + /* color don't care */ + vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 15); + /* bit mask */ + vga_wgfx(regbase, VGA_GFX_BIT_MASK, 255); + + /* graphics cursor attributes: nothing special */ + vga_wseq(regbase, CL_SEQR12, 0x0); + /* finally, turn on everything - turn off "FullBandwidth" bit */ /* also, set "DotClock%2" bit where requested */ tmp = 0x01; @@ -1259,12 +1355,18 @@ static int cirrusfb_set_par_foo(struct fb_info *info) */ vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp); - dev_dbg(info->device, "CL_SEQR1: %d\n", tmp); + DPRINTK("CL_SEQR1: %d\n", tmp); + + cinfo->currentmode = regs; + + /* pan to requested offset */ + cirrusfb_pan_display(var, info); #ifdef CIRRUSFB_DEBUG - cirrusfb_dbg_reg_dump(info, NULL); + cirrusfb_dump(); #endif + DPRINTK("EXIT\n"); return 0; } @@ -1316,19 +1418,27 @@ static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green, static int cirrusfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - int xoffset; + int xoffset = 0; + int yoffset = 0; unsigned long base; - unsigned char tmp, xpix; + unsigned char tmp = 0, tmp2 = 0, xpix; struct cirrusfb_info *cinfo = info->par; + DPRINTK("ENTER\n"); + DPRINTK("virtual offset: (%d,%d)\n", var->xoffset, var->yoffset); + /* no range checks for xoffset and yoffset, */ /* as fb_pan_display has already done this */ if (var->vmode & FB_VMODE_YWRAP) return -EINVAL; + info->var.xoffset = var->xoffset; + info->var.yoffset = var->yoffset; + xoffset = var->xoffset * info->var.bits_per_pixel / 8; + yoffset = var->yoffset; - base = var->yoffset * info->fix.line_length + xoffset; + base = yoffset * info->fix.line_length + xoffset; if (info->var.bits_per_pixel == 1) { /* base is already correct */ @@ -1338,15 +1448,14 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var, xpix = (unsigned char) ((xoffset % 4) * 2); } - if (!is_laguna(cinfo)) - cirrusfb_WaitBLT(cinfo->regbase); + cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */ /* lower 8 + 8 bits of screen start address */ - vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, base & 0xff); - vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, (base >> 8) & 0xff); + vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, + (unsigned char) (base & 0xff)); + vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, + (unsigned char) (base >> 8)); - /* 0xf2 is %11110010, exclude tmp bits */ - tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2; /* construct bits 16, 17 and 18 of screen start address */ if (base & 0x10000) tmp |= 0x01; @@ -1355,17 +1464,13 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var, if (base & 0x40000) tmp |= 0x08; - vga_wcrt(cinfo->regbase, CL_CRT1B, tmp); + /* 0xf2 is %11110010, exclude tmp bits */ + tmp2 = (vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2) | tmp; + vga_wcrt(cinfo->regbase, CL_CRT1B, tmp2); /* construct bit 19 of screen start address */ - if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) { - tmp = vga_rcrt(cinfo->regbase, CL_CRT1D); - if (is_laguna(cinfo)) - tmp = (tmp & ~0x18) | ((base >> 16) & 0x18); - else - tmp = (tmp & ~0x80) | ((base >> 12) & 0x80); - vga_wcrt(cinfo->regbase, CL_CRT1D, tmp); - } + if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) + vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80); /* write pixel panning value to AR33; this does not quite work in 8bpp * @@ -1374,6 +1479,9 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var, if (info->var.bits_per_pixel == 1) vga_wattr(cinfo->regbase, CL_AR33, xpix); + cirrusfb_WaitBLT(cinfo->regbase); + + DPRINTK("EXIT\n"); return 0; } @@ -1394,54 +1502,57 @@ static int cirrusfb_blank(int blank_mode, struct fb_info *info) struct cirrusfb_info *cinfo = info->par; int current_mode = cinfo->blank_mode; - dev_dbg(info->device, "ENTER, blank mode = %d\n", blank_mode); + DPRINTK("ENTER, blank mode = %d\n", blank_mode); if (info->state != FBINFO_STATE_RUNNING || current_mode == blank_mode) { - dev_dbg(info->device, "EXIT, returning 0\n"); + DPRINTK("EXIT, returning 0\n"); return 0; } /* Undo current */ if (current_mode == FB_BLANK_NORMAL || - current_mode == FB_BLANK_UNBLANK) + current_mode == FB_BLANK_UNBLANK) { + /* unblank the screen */ + val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE); /* clear "FullBandwidth" bit */ - val = 0; - else - /* set "FullBandwidth" bit */ - val = 0x20; + vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf); + /* and undo VESA suspend trickery */ + vga_wgfx(cinfo->regbase, CL_GRE, 0x00); + } - val |= vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE) & 0xdf; - vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val); + /* set new */ + if (blank_mode > FB_BLANK_NORMAL) { + /* blank the screen */ + val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE); + /* set "FullBandwidth" bit */ + vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20); + } switch (blank_mode) { case FB_BLANK_UNBLANK: case FB_BLANK_NORMAL: - val = 0x00; break; case FB_BLANK_VSYNC_SUSPEND: - val = 0x04; + vga_wgfx(cinfo->regbase, CL_GRE, 0x04); break; case FB_BLANK_HSYNC_SUSPEND: - val = 0x02; + vga_wgfx(cinfo->regbase, CL_GRE, 0x02); break; case FB_BLANK_POWERDOWN: - val = 0x06; + vga_wgfx(cinfo->regbase, CL_GRE, 0x06); break; default: - dev_dbg(info->device, "EXIT, returning 1\n"); + DPRINTK("EXIT, returning 1\n"); return 1; } - vga_wgfx(cinfo->regbase, CL_GRE, val); - cinfo->blank_mode = blank_mode; - dev_dbg(info->device, "EXIT, returning 0\n"); + DPRINTK("EXIT, returning 0\n"); /* Let fbcon do a soft blank for us */ return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0; } - /**** END Hardware specific Routines **************************************/ /****************************************************************************/ /**** BEGIN Internal Routines ***********************************************/ @@ -1451,6 +1562,8 @@ static void init_vgachip(struct fb_info *info) struct cirrusfb_info *cinfo = info->par; const struct cirrusfb_board_info_rec *bi; + DPRINTK("ENTER\n"); + assert(cinfo != NULL); bi = &cirrusfb_board_info[cinfo->btype]; @@ -1478,23 +1591,25 @@ static void init_vgachip(struct fb_info *info) /* disable flickerfixer */ vga_wcrt(cinfo->regbase, CL_CRT51, 0x00); mdelay(100); - /* mode */ - vga_wgfx(cinfo->regbase, CL_GR31, 0x00); - case BT_GD5480: /* fall through */ /* from Klaus' NetBSD driver: */ vga_wgfx(cinfo->regbase, CL_GR2F, 0x00); - case BT_ALPINE: /* fall through */ /* put blitter into 542x compat */ vga_wgfx(cinfo->regbase, CL_GR33, 0x00); + /* mode */ + vga_wgfx(cinfo->regbase, CL_GR31, 0x00); + break; + + case BT_GD5480: + /* from Klaus' NetBSD driver: */ + vga_wgfx(cinfo->regbase, CL_GR2F, 0x00); break; - case BT_LAGUNA: - case BT_LAGUNAB: + case BT_ALPINE: /* Nothing to do to reset the board. */ break; default: - dev_err(info->device, "Warning: Unknown board type\n"); + printk(KERN_ERR "cirrusfb: Warning: Unknown board type\n"); break; } @@ -1514,28 +1629,31 @@ static void init_vgachip(struct fb_info *info) WGen(cinfo, CL_VSSM2, 0x01); /* reset sequencer logic */ - vga_wseq(cinfo->regbase, VGA_SEQ_RESET, 0x03); + vga_wseq(cinfo->regbase, CL_SEQR0, 0x03); /* FullBandwidth (video off) and 8/9 dot clock */ vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21); + /* polarity (-/-), disable access to display memory, + * VGA_CRTC_START_HI base address: color + */ + WGen(cinfo, VGA_MIS_W, 0xc1); /* "magic cookie" - doesn't make any sense to me.. */ /* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */ /* unlock all extension registers */ vga_wseq(cinfo->regbase, CL_SEQR6, 0x12); + /* reset blitter */ + vga_wgfx(cinfo->regbase, CL_GR31, 0x04); + switch (cinfo->btype) { case BT_GD5480: vga_wseq(cinfo->regbase, CL_SEQRF, 0x98); break; case BT_ALPINE: - case BT_LAGUNA: - case BT_LAGUNAB: break; case BT_SD64: -#ifdef CONFIG_ZORRO vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8); -#endif break; default: vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f); @@ -1547,8 +1665,8 @@ static void init_vgachip(struct fb_info *info) vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff); /* character map select: doesn't even matter in gx mode */ vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00); - /* memory mode: chain4, ext. memory */ - vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a); + /* memory mode: chain-4, no odd/even, ext. memory */ + vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e); /* controller-internal base address of video memory */ if (bi->init_sr07) @@ -1574,12 +1692,20 @@ static void init_vgachip(struct fb_info *info) vga_wseq(cinfo->regbase, CL_SEQR18, 0x02); } + /* MCLK select etc. */ + if (bi->init_sr1f) + vga_wseq(cinfo->regbase, CL_SEQR1F, bi->sr1f); + /* Screen A preset row scan: none */ vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00); /* Text cursor start: disable text cursor */ vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20); /* Text cursor end: - */ vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00); + /* Screen start address high: 0 */ + vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, 0x00); + /* Screen start address low: 0 */ + vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 0x00); /* text cursor location high: 0 */ vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00); /* text cursor location low: 0 */ @@ -1587,6 +1713,10 @@ static void init_vgachip(struct fb_info *info) /* Underline Row scanline: - */ vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00); + /* mode control: timing enable, byte mode, no compat modes */ + vga_wcrt(cinfo->regbase, VGA_CRTC_MODE, 0xc3); + /* Line Compare: not needed */ + vga_wcrt(cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00); /* ### add 0x40 for text modes with > 30 MHz pixclock */ /* ext. display controls: ext.adr. wrap */ vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02); @@ -1609,9 +1739,7 @@ static void init_vgachip(struct fb_info *info) vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f); /* Bit Mask: no mask at all */ vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff); - - if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 || - is_laguna(cinfo)) + if (cinfo->btype == BT_ALPINE) /* (5434 can't have bit 3 set for bitblt) */ vga_wgfx(cinfo->regbase, CL_GRB, 0x20); else @@ -1651,11 +1779,18 @@ static void init_vgachip(struct fb_info *info) vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00); /* Color Plane enable: Enable all 4 planes */ vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f); +/* ### vga_wattr(cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */ /* Color Select: - */ vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00); WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */ + if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480) + /* polarity (-/-), enable display mem, + * VGA_CRTC_START_HI i/o base = color + */ + WGen(cinfo, VGA_MIS_W, 0xc3); + /* BLT Start/status: Blitter reset */ vga_wgfx(cinfo->regbase, CL_GR31, 0x04); /* - " - : "end-of-reset" */ @@ -1663,6 +1798,8 @@ static void init_vgachip(struct fb_info *info) /* misc... */ WHDR(cinfo, 0); /* Hidden DAC register: - */ + + DPRINTK("EXIT\n"); return; } @@ -1671,6 +1808,8 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on) #ifdef CONFIG_ZORRO /* only works on Zorro boards */ static int IsOn = 0; /* XXX not ok for multiple boards */ + DPRINTK("ENTER\n"); + if (cinfo->btype == BT_PICASSO4) return; /* nothing to switch */ if (cinfo->btype == BT_ALPINE) @@ -1680,6 +1819,8 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on) if (cinfo->btype == BT_PICASSO) { if ((on && !IsOn) || (!on && IsOn)) WSFR(cinfo, 0xff); + + DPRINTK("EXIT\n"); return; } if (on) { @@ -1706,10 +1847,11 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on) case BT_SPECTRUM: WSFR(cinfo, 0x4f); break; - default: /* do nothing */ - break; + default: /* do nothing */ break; } } + + DPRINTK("EXIT\n"); #endif /* CONFIG_ZORRO */ } @@ -1717,17 +1859,6 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on) /* Linux 2.6-style accelerated functions */ /******************************************/ -static int cirrusfb_sync(struct fb_info *info) -{ - struct cirrusfb_info *cinfo = info->par; - - if (!is_laguna(cinfo)) { - while (vga_rgfx(cinfo->regbase, CL_GR31) & 0x03) - cpu_relax(); - } - return 0; -} - static void cirrusfb_fillrect(struct fb_info *info, const struct fb_fillrect *region) { @@ -1763,8 +1894,8 @@ static void cirrusfb_fillrect(struct fb_info *info, info->var.bits_per_pixel, (region->dx * m) / 8, region->dy, (region->width * m) / 8, region->height, - color, color, - info->fix.line_length, 0x40); + color, + info->fix.line_length); } static void cirrusfb_copyarea(struct fb_info *info, @@ -1812,46 +1943,9 @@ static void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image) { struct cirrusfb_info *cinfo = info->par; - unsigned char op = (info->var.bits_per_pixel == 24) ? 0xc : 0x4; - if (info->state != FBINFO_STATE_RUNNING) - return; - /* Alpine/SD64 does not work at 24bpp ??? */ - if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1) - cfb_imageblit(info, image); - else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) && - op == 0xc) - cfb_imageblit(info, image); - else { - unsigned size = ((image->width + 7) >> 3) * image->height; - int m = info->var.bits_per_pixel; - u32 fg, bg; - - if (info->var.bits_per_pixel == 8) { - fg = image->fg_color; - bg = image->bg_color; - } else { - fg = ((u32 *)(info->pseudo_palette))[image->fg_color]; - bg = ((u32 *)(info->pseudo_palette))[image->bg_color]; - } - if (info->var.bits_per_pixel == 24) { - /* clear background first */ - cirrusfb_RectFill(cinfo->regbase, - info->var.bits_per_pixel, - (image->dx * m) / 8, image->dy, - (image->width * m) / 8, - image->height, - bg, bg, - info->fix.line_length, 0x40); - } - cirrusfb_RectFill(cinfo->regbase, - info->var.bits_per_pixel, - (image->dx * m) / 8, image->dy, - (image->width * m) / 8, image->height, - fg, bg, - info->fix.line_length, op); - memcpy(info->screen_base, image->data, size); - } + cirrusfb_WaitBLT(cinfo->regbase); + cfb_imageblit(info, image); } #ifdef CONFIG_PPC_PREP @@ -1859,8 +1953,12 @@ static void cirrusfb_imageblit(struct fb_info *info, #define PREP_IO_BASE ((volatile unsigned char *) 0x80000000) static void get_prep_addrs(unsigned long *display, unsigned long *registers) { + DPRINTK("ENTER\n"); + *display = PREP_VIDEO_BASE; *registers = (unsigned long) PREP_IO_BASE; + + DPRINTK("EXIT\n"); } #endif /* CONFIG_PPC_PREP */ @@ -1872,43 +1970,40 @@ static int release_io_ports; * based on the DRAM bandwidth bit and DRAM bank switching bit. This * works with 1MB, 2MB and 4MB configurations (which the Motorola boards * seem to have. */ -static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info, - u8 __iomem *regbase) +static unsigned int __devinit cirrusfb_get_memsize(u8 __iomem *regbase) { unsigned long mem; - struct cirrusfb_info *cinfo = info->par; + unsigned char SRF; - if (is_laguna(cinfo)) { - unsigned char SR14 = vga_rseq(regbase, CL_SEQR14); + DPRINTK("ENTER\n"); - mem = ((SR14 & 7) + 1) << 20; - } else { - unsigned char SRF = vga_rseq(regbase, CL_SEQRF); - switch ((SRF & 0x18)) { - case 0x08: - mem = 512 * 1024; - break; - case 0x10: - mem = 1024 * 1024; - break; - /* 64-bit DRAM data bus width; assume 2MB. - * Also indicates 2MB memory on the 5430. - */ - case 0x18: - mem = 2048 * 1024; - break; - default: - dev_warn(info->device, "Unknown memory size!\n"); - mem = 1024 * 1024; - } - /* If DRAM bank switching is enabled, there must be - * twice as much memory installed. (4MB on the 5434) - */ - if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0) - mem *= 2; + SRF = vga_rseq(regbase, CL_SEQRF); + switch ((SRF & 0x18)) { + case 0x08: + mem = 512 * 1024; + break; + case 0x10: + mem = 1024 * 1024; + break; + /* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory + * on the 5430. + */ + case 0x18: + mem = 2048 * 1024; + break; + default: + printk(KERN_WARNING "CLgenfb: Unknown memory size!\n"); + mem = 1024 * 1024; } + if (SRF & 0x80) + /* If DRAM bank switching is enabled, there must be twice as much + * memory installed. (4MB on the 5434) + */ + mem *= 2; /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */ + + DPRINTK("EXIT\n"); return mem; } @@ -1919,6 +2014,8 @@ static void get_pci_addrs(const struct pci_dev *pdev, assert(display != NULL); assert(registers != NULL); + DPRINTK("ENTER\n"); + *display = 0; *registers = 0; @@ -1933,15 +2030,14 @@ static void get_pci_addrs(const struct pci_dev *pdev, } assert(*display != 0); + + DPRINTK("EXIT\n"); } static void cirrusfb_pci_unmap(struct fb_info *info) { struct pci_dev *pdev = to_pci_dev(info->device); - struct cirrusfb_info *cinfo = info->par; - if (cinfo->laguna_mmio == NULL) - iounmap(cinfo->laguna_mmio); iounmap(info->screen_base); #if 0 /* if system didn't claim this region, we would... */ release_mem_region(0xA0000, 65535); @@ -1971,22 +2067,6 @@ static void cirrusfb_zorro_unmap(struct fb_info *info) } #endif /* CONFIG_ZORRO */ -/* function table of the above functions */ -static struct fb_ops cirrusfb_ops = { - .owner = THIS_MODULE, - .fb_open = cirrusfb_open, - .fb_release = cirrusfb_release, - .fb_setcolreg = cirrusfb_setcolreg, - .fb_check_var = cirrusfb_check_var, - .fb_set_par = cirrusfb_set_par, - .fb_pan_display = cirrusfb_pan_display, - .fb_blank = cirrusfb_blank, - .fb_fillrect = cirrusfb_fillrect, - .fb_copyarea = cirrusfb_copyarea, - .fb_sync = cirrusfb_sync, - .fb_imageblit = cirrusfb_imageblit, -}; - static int __devinit cirrusfb_set_fbinfo(struct fb_info *info) { struct cirrusfb_info *cinfo = info->par; @@ -1997,16 +2077,10 @@ static int __devinit cirrusfb_set_fbinfo(struct fb_info *info) | FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN | FBINFO_HWACCEL_FILLRECT - | FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_COPYAREA; - if (noaccel || is_laguna(cinfo)) { + if (noaccel) info->flags |= FBINFO_HWACCEL_DISABLED; - info->fix.accel = FB_ACCEL_NONE; - } else - info->fix.accel = FB_ACCEL_CIRRUS_ALPINE; - info->fbops = &cirrusfb_ops; - if (cinfo->btype == BT_GD5480) { if (var->bits_per_pixel == 16) info->screen_base += 1 * MB_; @@ -2030,6 +2104,7 @@ static int __devinit cirrusfb_set_fbinfo(struct fb_info *info) /* FIXME: map region at 0xB8000 if available, fill in here */ info->fix.mmio_len = 0; + info->fix.accel = FB_ACCEL_NONE; fb_alloc_cmap(&info->cmap, 256, 0); @@ -2040,56 +2115,70 @@ static int __devinit cirrusfb_register(struct fb_info *info) { struct cirrusfb_info *cinfo = info->par; int err; + enum cirrus_board btype; + + DPRINTK("ENTER\n"); + + printk(KERN_INFO "cirrusfb: Driver for Cirrus Logic based " + "graphic boards, v" CIRRUSFB_VERSION "\n"); + + btype = cinfo->btype; /* sanity checks */ - assert(cinfo->btype != BT_NONE); + assert(btype != BT_NONE); /* set all the vital stuff */ cirrusfb_set_fbinfo(info); - dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base); + DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base); err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8); if (!err) { - dev_dbg(info->device, "wrong initial video mode\n"); + DPRINTK("wrong initial video mode\n"); err = -EINVAL; goto err_dealloc_cmap; } info->var.activate = FB_ACTIVATE_NOW; - err = cirrusfb_check_var(&info->var, info); + err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info); if (err < 0) { /* should never happen */ - dev_dbg(info->device, - "choking on default var... umm, no good.\n"); + DPRINTK("choking on default var... umm, no good.\n"); goto err_dealloc_cmap; } err = register_framebuffer(info); if (err < 0) { - dev_err(info->device, - "could not register fb device; err = %d!\n", err); + printk(KERN_ERR "cirrusfb: could not register " + "fb device; err = %d!\n", err); goto err_dealloc_cmap; } + DPRINTK("EXIT, returning 0\n"); return 0; err_dealloc_cmap: fb_dealloc_cmap(&info->cmap); + cinfo->unmap(info); + framebuffer_release(info); return err; } static void __devexit cirrusfb_cleanup(struct fb_info *info) { struct cirrusfb_info *cinfo = info->par; + DPRINTK("ENTER\n"); switch_monitor(cinfo, 0); + unregister_framebuffer(info); fb_dealloc_cmap(&info->cmap); - dev_dbg(info->device, "Framebuffer unregistered\n"); + printk("Framebuffer unregistered\n"); cinfo->unmap(info); framebuffer_release(info); + + DPRINTK("EXIT\n"); } #ifdef CONFIG_PCI @@ -2098,6 +2187,7 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, { struct cirrusfb_info *cinfo; struct fb_info *info; + enum cirrus_board btype; unsigned long board_addr, board_size; int ret; @@ -2111,17 +2201,15 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, if (!info) { printk(KERN_ERR "cirrusfb: could not allocate memory\n"); ret = -ENOMEM; - goto err_out; + goto err_disable; } cinfo = info->par; - cinfo->btype = (enum cirrus_board) ent->driver_data; + cinfo->btype = btype = (enum cirrus_board) ent->driver_data; - dev_dbg(info->device, - " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n", - (unsigned long long)pdev->resource[0].start, cinfo->btype); - dev_dbg(info->device, " base address 1 is 0x%Lx\n", - (unsigned long long)pdev->resource[1].start); + DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n", + pdev->resource[0].start, btype); + DPRINTK(" base address 1 is 0x%x\n", pdev->resource[1].start); if (isPReP) { pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000); @@ -2131,30 +2219,30 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, /* PReP dies if we ioremap the IO registers, but it works w/out... */ cinfo->regbase = (char __iomem *) info->fix.mmio_start; } else { - dev_dbg(info->device, - "Attempt to get PCI info for Cirrus Graphics Card\n"); + DPRINTK("Attempt to get PCI info for Cirrus Graphics Card\n"); get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start); /* FIXME: this forces VGA. alternatives? */ cinfo->regbase = NULL; - cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000); } - dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n", + DPRINTK("Board address: 0x%lx, register address: 0x%lx\n", board_addr, info->fix.mmio_start); - board_size = (cinfo->btype == BT_GD5480) ? - 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase); + board_size = (btype == BT_GD5480) ? + 32 * MB_ : cirrusfb_get_memsize(cinfo->regbase); ret = pci_request_regions(pdev, "cirrusfb"); if (ret < 0) { - dev_err(info->device, "cannot reserve region 0x%lx, abort\n", - board_addr); + printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, " + "abort\n", + board_addr); goto err_release_fb; } #if 0 /* if the system didn't claim this region, we would... */ if (!request_mem_region(0xA0000, 65535, "cirrusfb")) { - dev_err(info->device, "cannot reserve region 0x%lx, abort\n", - 0xA0000L); + printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n" +, + 0xA0000L); ret = -EBUSY; goto err_release_regions; } @@ -2172,17 +2260,16 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, info->screen_size = board_size; cinfo->unmap = cirrusfb_pci_unmap; - dev_info(info->device, - "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n", - info->screen_size >> 10, board_addr); + printk(KERN_INFO "RAM (%lu kB) at 0x%lx, Cirrus " + "Logic chipset on PCI bus\n", + info->screen_size >> 10, board_addr); pci_set_drvdata(pdev, info); ret = cirrusfb_register(info); - if (!ret) - return 0; + if (ret) + iounmap(info->screen_base); + return ret; - pci_set_drvdata(pdev, NULL); - iounmap(info->screen_base); err_release_legacy: if (release_io_ports) release_region(0x3C0, 32); @@ -2192,9 +2279,8 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, #endif pci_release_regions(pdev); err_release_fb: - if (cinfo->laguna_mmio != NULL) - iounmap(cinfo->laguna_mmio); framebuffer_release(info); +err_disable: err_out: return ret; } @@ -2202,8 +2288,11 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev, static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); + DPRINTK("ENTER\n"); cirrusfb_cleanup(info); + + DPRINTK("EXIT\n"); } static struct pci_driver cirrusfb_pci_driver = { @@ -2235,6 +2324,8 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, if (cirrusfb_zorro_table2[btype].id2) z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL); size = cirrusfb_zorro_table2[btype].size; + printk(KERN_INFO "cirrusfb: %s board detected; ", + cirrusfb_board_info[btype].name); info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev); if (!info) { @@ -2243,9 +2334,6 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, goto err_out; } - dev_info(info->device, "%s board detected\n", - cirrusfb_board_info[btype].name); - cinfo = info->par; cinfo->btype = btype; @@ -2257,16 +2345,19 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, info->screen_size = size; if (!zorro_request_device(z, "cirrusfb")) { - dev_err(info->device, "cannot reserve region 0x%lx, abort\n", - board_addr); + printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, " + "abort\n", + board_addr); ret = -EBUSY; goto err_release_fb; } + printk(" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr); + ret = -EIO; if (btype == BT_PICASSO4) { - dev_info(info->device, " REG at $%lx\n", board_addr + 0x600000); + printk(KERN_INFO " REG at $%lx\n", board_addr + 0x600000); /* To be precise, for the P4 this is not the */ /* begin of the board, but the begin of RAM. */ @@ -2276,7 +2367,7 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, if (!cinfo->regbase) goto err_release_region; - dev_dbg(info->device, "Virtual address for board set to: $%p\n", + DPRINTK("cirrusfb: Virtual address for board set to: $%p\n", cinfo->regbase); cinfo->regbase += 0x600000; info->fix.mmio_start = board_addr + 0x600000; @@ -2286,8 +2377,8 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, if (!info->screen_base) goto err_unmap_regbase; } else { - dev_info(info->device, " REG at $%lx\n", - (unsigned long) z2->resource.start); + printk(KERN_INFO " REG at $%lx\n", + (unsigned long) z2->resource.start); info->fix.smem_start = board_addr; if (board_addr > 0x01000000) @@ -2301,32 +2392,27 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start); info->fix.mmio_start = z2->resource.start; - dev_dbg(info->device, "Virtual address for board set to: $%p\n", + DPRINTK("cirrusfb: Virtual address for board set to: $%p\n", cinfo->regbase); } cinfo->unmap = cirrusfb_zorro_unmap; - dev_info(info->device, - "Cirrus Logic chipset on Zorro bus, RAM (%lu MB) at $%lx\n", - board_size / MB_, board_addr); - + printk(KERN_INFO "Cirrus Logic chipset on Zorro bus\n"); zorro_set_drvdata(z, info); - /* MCLK select etc. */ - if (cirrusfb_board_info[btype].init_sr1f) - vga_wseq(cinfo->regbase, CL_SEQR1F, - cirrusfb_board_info[btype].sr1f); - ret = cirrusfb_register(info); - if (!ret) - return 0; - - if (btype == BT_PICASSO4 || board_addr > 0x01000000) - iounmap(info->screen_base); + if (ret) { + if (btype == BT_PICASSO4) { + iounmap(info->screen_base); + iounmap(cinfo->regbase - 0x600000); + } else if (board_addr > 0x01000000) + iounmap(info->screen_base); + } + return ret; err_unmap_regbase: - if (btype == BT_PICASSO4) - iounmap(cinfo->regbase - 0x600000); + /* Parental advisory: explicit hack */ + iounmap(cinfo->regbase - 0x600000); err_release_region: release_region(board_addr, board_size); err_release_fb: @@ -2338,8 +2424,11 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z, void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z) { struct fb_info *info = zorro_get_drvdata(z); + DPRINTK("ENTER\n"); cirrusfb_cleanup(info); + + DPRINTK("EXIT\n"); } static struct zorro_driver cirrusfb_zorro_driver = { @@ -2350,11 +2439,33 @@ static struct zorro_driver cirrusfb_zorro_driver = { }; #endif /* CONFIG_ZORRO */ -#ifndef MODULE -static int __init cirrusfb_setup(char *options) +static int __init cirrusfb_init(void) { + int error = 0; + +#ifndef MODULE + char *option = NULL; + + if (fb_get_options("cirrusfb", &option)) + return -ENODEV; + cirrusfb_setup(option); +#endif + +#ifdef CONFIG_ZORRO + error |= zorro_register_driver(&cirrusfb_zorro_driver); +#endif +#ifdef CONFIG_PCI + error |= pci_register_driver(&cirrusfb_pci_driver); +#endif + return error; +} + +#ifndef MODULE +static int __init cirrusfb_setup(char *options) { char *this_opt; + DPRINTK("ENTER\n"); + if (!options || !*options) return 0; @@ -2362,6 +2473,8 @@ static int __init cirrusfb_setup(char *options) if (!*this_opt) continue; + DPRINTK("cirrusfb_setup: option '%s'\n", this_opt); + if (!strcmp(this_opt, "noaccel")) noaccel = 1; else if (!strncmp(this_opt, "mode:", 5)) @@ -2381,27 +2494,6 @@ MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik "); MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips"); MODULE_LICENSE("GPL"); -static int __init cirrusfb_init(void) -{ - int error = 0; - -#ifndef MODULE - char *option = NULL; - - if (fb_get_options("cirrusfb", &option)) - return -ENODEV; - cirrusfb_setup(option); -#endif - -#ifdef CONFIG_ZORRO - error |= zorro_register_driver(&cirrusfb_zorro_driver); -#endif -#ifdef CONFIG_PCI - error |= pci_register_driver(&cirrusfb_pci_driver); -#endif - return error; -} - static void __exit cirrusfb_exit(void) { #ifdef CONFIG_PCI @@ -2468,6 +2560,8 @@ static void AttrOn(const struct cirrusfb_info *cinfo) { assert(cinfo != NULL); + DPRINTK("ENTER\n"); + if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) { /* if we're just in "write value" mode, write back the */ /* same value as before to not modify anything */ @@ -2480,6 +2574,8 @@ static void AttrOn(const struct cirrusfb_info *cinfo) /* dummy write on Reg0 to be on "write index" mode next time */ vga_w(cinfo->regbase, VGA_ATT_IW, 0x00); + + DPRINTK("EXIT\n"); } /*** WHDR() - write into the Hidden DAC register ***/ @@ -2492,8 +2588,6 @@ static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val) { unsigned char dummy; - if (is_laguna(cinfo)) - return; if (cinfo->btype == BT_PICASSO) { /* Klaus' hint for correct access to HDR on some boards */ /* first write 0 to pixel mask (3c6) */ @@ -2561,8 +2655,7 @@ static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned ch vga_w(cinfo->regbase, VGA_PEL_IW, regnum); if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || - cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 || - cinfo->btype == BT_SD64 || is_laguna(cinfo)) { + cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) { /* but DAC data register IS, at least for Picasso II */ if (cinfo->btype == BT_PICASSO) data += 0xfff; @@ -2609,8 +2702,9 @@ static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned ch /* FIXME: use interrupts instead */ static void cirrusfb_WaitBLT(u8 __iomem *regbase) { + /* now busy-wait until we're done */ while (vga_rgfx(regbase, CL_GR31) & 0x08) - cpu_relax(); + /* do nothing */ ; } /******************************************************************* @@ -2619,12 +2713,60 @@ static void cirrusfb_WaitBLT(u8 __iomem *regbase) perform accelerated "scrolling" ********************************************************************/ -static void cirrusfb_set_blitter(u8 __iomem *regbase, - u_short nwidth, u_short nheight, - u_long nsrc, u_long ndest, - u_short bltmode, u_short line_length) - +static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, + u_short curx, u_short cury, + u_short destx, u_short desty, + u_short width, u_short height, + u_short line_length) { + u_short nwidth, nheight; + u_long nsrc, ndest; + u_char bltmode; + + DPRINTK("ENTER\n"); + + nwidth = width - 1; + nheight = height - 1; + + bltmode = 0x00; + /* if source adr < dest addr, do the Blt backwards */ + if (cury <= desty) { + if (cury == desty) { + /* if src and dest are on the same line, check x */ + if (curx < destx) + bltmode |= 0x01; + } else + bltmode |= 0x01; + } + if (!bltmode) { + /* standard case: forward blitting */ + nsrc = (cury * line_length) + curx; + ndest = (desty * line_length) + destx; + } else { + /* this means start addresses are at the end, + * counting backwards + */ + nsrc = cury * line_length + curx + + nheight * line_length + nwidth; + ndest = desty * line_length + destx + + nheight * line_length + nwidth; + } + + /* + run-down of registers to be programmed: + destination pitch + source pitch + BLT width/height + source start + destination start + BLT mode + BLT ROP + VGA_GFX_SR_VALUE / VGA_GFX_SR_ENABLE: "fill color" + start/stop + */ + + cirrusfb_WaitBLT(regbase); + /* pitch: set to line_length */ /* dest pitch low */ vga_wgfx(regbase, CL_GR24, line_length & 0xff); @@ -2671,50 +2813,8 @@ static void cirrusfb_set_blitter(u8 __iomem *regbase, /* and finally: GO! */ vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */ -} - -/******************************************************************* - cirrusfb_BitBLT() - - perform accelerated "scrolling" -********************************************************************/ - -static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, - u_short curx, u_short cury, - u_short destx, u_short desty, - u_short width, u_short height, - u_short line_length) -{ - u_short nwidth = width - 1; - u_short nheight = height - 1; - u_long nsrc, ndest; - u_char bltmode; - - bltmode = 0x00; - /* if source adr < dest addr, do the Blt backwards */ - if (cury <= desty) { - if (cury == desty) { - /* if src and dest are on the same line, check x */ - if (curx < destx) - bltmode |= 0x01; - } else - bltmode |= 0x01; - } - /* standard case: forward blitting */ - nsrc = (cury * line_length) + curx; - ndest = (desty * line_length) + destx; - if (bltmode) { - /* this means start addresses are at the end, - * counting backwards - */ - nsrc += nheight * line_length + nwidth; - ndest += nheight * line_length + nwidth; - } - - cirrusfb_WaitBLT(regbase); - cirrusfb_set_blitter(regbase, nwidth, nheight, - nsrc, ndest, bltmode, line_length); + DPRINTK("EXIT\n"); } /******************************************************************* @@ -2725,37 +2825,79 @@ static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, u_short x, u_short y, u_short width, u_short height, - u32 fg_color, u32 bg_color, u_short line_length, - u_char blitmode) + u_char color, u_short line_length) { - u_long ndest = (y * line_length) + x; + u_short nwidth, nheight; + u_long ndest; u_char op; + DPRINTK("ENTER\n"); + + nwidth = width - 1; + nheight = height - 1; + + ndest = (y * line_length) + x; + cirrusfb_WaitBLT(regbase); + /* pitch: set to line_length */ + vga_wgfx(regbase, CL_GR24, line_length & 0xff); /* dest pitch low */ + vga_wgfx(regbase, CL_GR25, line_length >> 8); /* dest pitch hi */ + vga_wgfx(regbase, CL_GR26, line_length & 0xff); /* source pitch low */ + vga_wgfx(regbase, CL_GR27, line_length >> 8); /* source pitch hi */ + + /* BLT width: actual number of pixels - 1 */ + vga_wgfx(regbase, CL_GR20, nwidth & 0xff); /* BLT width low */ + vga_wgfx(regbase, CL_GR21, nwidth >> 8); /* BLT width hi */ + + /* BLT height: actual number of lines -1 */ + vga_wgfx(regbase, CL_GR22, nheight & 0xff); /* BLT height low */ + vga_wgfx(regbase, CL_GR23, nheight >> 8); /* BLT width hi */ + + /* BLT destination */ + /* BLT dest low */ + vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff)); + /* BLT dest mid */ + vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8)); + /* BLT dest hi */ + vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16)); + + /* BLT source: set to 0 (is a dummy here anyway) */ + vga_wgfx(regbase, CL_GR2C, 0x00); /* BLT src low */ + vga_wgfx(regbase, CL_GR2D, 0x00); /* BLT src mid */ + vga_wgfx(regbase, CL_GR2E, 0x00); /* BLT src hi */ + /* This is a ColorExpand Blt, using the */ /* same color for foreground and background */ - vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color); - vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color); - - op = 0x80; - if (bits_per_pixel >= 16) { - vga_wgfx(regbase, CL_GR10, bg_color >> 8); - vga_wgfx(regbase, CL_GR11, fg_color >> 8); - op = 0x90; - } - if (bits_per_pixel >= 24) { - vga_wgfx(regbase, CL_GR12, bg_color >> 16); - vga_wgfx(regbase, CL_GR13, fg_color >> 16); - op = 0xa0; - } - if (bits_per_pixel == 32) { - vga_wgfx(regbase, CL_GR14, bg_color >> 24); - vga_wgfx(regbase, CL_GR15, fg_color >> 24); - op = 0xb0; - } - cirrusfb_set_blitter(regbase, width - 1, height - 1, - 0, ndest, op | blitmode, line_length); + vga_wgfx(regbase, VGA_GFX_SR_VALUE, color); /* foreground color */ + vga_wgfx(regbase, VGA_GFX_SR_ENABLE, color); /* background color */ + + op = 0xc0; + if (bits_per_pixel == 16) { + vga_wgfx(regbase, CL_GR10, color); /* foreground color */ + vga_wgfx(regbase, CL_GR11, color); /* background color */ + op = 0x50; + op = 0xd0; + } else if (bits_per_pixel == 32) { + vga_wgfx(regbase, CL_GR10, color); /* foreground color */ + vga_wgfx(regbase, CL_GR11, color); /* background color */ + vga_wgfx(regbase, CL_GR12, color); /* foreground color */ + vga_wgfx(regbase, CL_GR13, color); /* background color */ + vga_wgfx(regbase, CL_GR14, 0); /* foreground color */ + vga_wgfx(regbase, CL_GR15, 0); /* background color */ + op = 0x50; + op = 0xf0; + } + /* BLT mode: color expand, Enable 8x8 copy (faster?) */ + vga_wgfx(regbase, CL_GR30, op); /* BLT mode */ + + /* BLT ROP: SrcCopy */ + vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */ + + /* and finally: GO! */ + vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */ + + DPRINTK("EXIT\n"); } /************************************************************************** @@ -2775,6 +2917,8 @@ static void bestclock(long freq, int *nom, int *den, int *div) *den = 0; *div = 0; + DPRINTK("ENTER\n"); + if (freq < 8000) freq = 8000; @@ -2816,6 +2960,12 @@ static void bestclock(long freq, int *nom, int *den, int *div) } } } + + DPRINTK("Best possible values for given frequency:\n"); + DPRINTK(" freq: %ld kHz nom: %d den: %d div: %d\n", + freq, *nom, *den, *div); + + DPRINTK("EXIT\n"); } /* ------------------------------------------------------------------------- @@ -2827,6 +2977,32 @@ static void bestclock(long freq, int *nom, int *den, int *div) #ifdef CIRRUSFB_DEBUG +/** + * cirrusfb_dbg_print_byte + * @name: name associated with byte value to be displayed + * @val: byte value to be displayed + * + * DESCRIPTION: + * Display an indented string, along with a hexidecimal byte value, and + * its decoded bits. Bits 7 through 0 are listed in left-to-right + * order. + */ + +static +void cirrusfb_dbg_print_byte(const char *name, unsigned char val) +{ + DPRINTK("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n", + name, val, + val & 0x80 ? '1' : '0', + val & 0x40 ? '1' : '0', + val & 0x20 ? '1' : '0', + val & 0x10 ? '1' : '0', + val & 0x08 ? '1' : '0', + val & 0x04 ? '1' : '0', + val & 0x02 ? '1' : '0', + val & 0x01 ? '1' : '0'); +} + /** * cirrusfb_dbg_print_regs * @base: If using newmmio, the newmmio base address, otherwise %NULL @@ -2838,9 +3014,9 @@ static void bestclock(long freq, int *nom, int *den, int *div) * used at the given @base address to query the information. */ -static void cirrusfb_dbg_print_regs(struct fb_info *info, - caddr_t regbase, - enum cirrusfb_dbg_reg_class reg_class, ...) +static +void cirrusfb_dbg_print_regs(caddr_t regbase, + enum cirrusfb_dbg_reg_class reg_class, ...) { va_list list; unsigned char val = 0; @@ -2866,7 +3042,7 @@ static void cirrusfb_dbg_print_regs(struct fb_info *info, break; } - dev_dbg(info->device, "%8s = 0x%02X\n", name, val); + cirrusfb_dbg_print_byte(name, val); name = va_arg(list, char *); } @@ -2874,6 +3050,18 @@ static void cirrusfb_dbg_print_regs(struct fb_info *info, va_end(list); } +/** + * cirrusfb_dump + * @cirrusfbinfo: + * + * DESCRIPTION: + */ + +static void cirrusfb_dump(void) +{ + cirrusfb_dbg_reg_dump(NULL); +} + /** * cirrusfb_dbg_reg_dump * @base: If using newmmio, the newmmio base address, otherwise %NULL @@ -2884,11 +3072,12 @@ static void cirrusfb_dbg_print_regs(struct fb_info *info, * used at the given @base address to query the information. */ -static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase) +static +void cirrusfb_dbg_reg_dump(caddr_t regbase) { - dev_dbg(info->device, "VGA CRTC register dump:\n"); + DPRINTK("CIRRUSFB VGA CRTC register dump:\n"); - cirrusfb_dbg_print_regs(info, regbase, CRT, + cirrusfb_dbg_print_regs(regbase, CRT, "CR00", 0x00, "CR01", 0x01, "CR02", 0x02, @@ -2938,11 +3127,11 @@ static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase) "CR3F", 0x3F, NULL); - dev_dbg(info->device, "\n"); + DPRINTK("\n"); - dev_dbg(info->device, "VGA SEQ register dump:\n"); + DPRINTK("CIRRUSFB VGA SEQ register dump:\n"); - cirrusfb_dbg_print_regs(info, regbase, SEQ, + cirrusfb_dbg_print_regs(regbase, SEQ, "SR00", 0x00, "SR01", 0x01, "SR02", 0x02, @@ -2971,7 +3160,7 @@ static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase) "SR1F", 0x1F, NULL); - dev_dbg(info->device, "\n"); + DPRINTK("\n"); } #endif /* CIRRUSFB_DEBUG */ diff --git a/trunk/drivers/video/console/fbcon.c b/trunk/drivers/video/console/fbcon.c index 2cd500a304f2..1657b9608b04 100644 --- a/trunk/drivers/video/console/fbcon.c +++ b/trunk/drivers/video/console/fbcon.c @@ -2954,11 +2954,8 @@ static int fbcon_fb_unbind(int idx) static int fbcon_fb_unregistered(struct fb_info *info) { - int i, idx; + int i, idx = info->node; - if (!lock_fb_info(info)) - return -ENODEV; - idx = info->node; for (i = first_fb_vc; i <= last_fb_vc; i++) { if (con2fb_map[i] == idx) con2fb_map[i] = -1; @@ -2982,14 +2979,13 @@ static int fbcon_fb_unregistered(struct fb_info *info) } } - if (primary_device == idx) - primary_device = -1; - - unlock_fb_info(info); - if (!num_registered_fb) unregister_con_driver(&fb_con); + + if (primary_device == idx) + primary_device = -1; + return 0; } @@ -3025,13 +3021,9 @@ static inline void fbcon_select_primary(struct fb_info *info) static int fbcon_fb_registered(struct fb_info *info) { - int ret = 0, i, idx; + int ret = 0, i, idx = info->node; - if (!lock_fb_info(info)) - return -ENODEV; - idx = info->node; fbcon_select_primary(info); - unlock_fb_info(info); if (info_idx == -1) { for (i = first_fb_vc; i <= last_fb_vc; i++) { @@ -3132,7 +3124,7 @@ static void fbcon_get_requirement(struct fb_info *info, } } -static int fbcon_event_notify(struct notifier_block *self, +static int fbcon_event_notify(struct notifier_block *self, unsigned long action, void *data) { struct fb_event *event = data; @@ -3140,7 +3132,7 @@ static int fbcon_event_notify(struct notifier_block *self, struct fb_videomode *mode; struct fb_con2fbmap *con2fb; struct fb_blit_caps *caps; - int idx, ret = 0; + int ret = 0; /* * ignore all events except driver registration and deregistration @@ -3152,54 +3144,23 @@ static int fbcon_event_notify(struct notifier_block *self, switch(action) { case FB_EVENT_SUSPEND: - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } fbcon_suspended(info); - unlock_fb_info(info); break; case FB_EVENT_RESUME: - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } fbcon_resumed(info); - unlock_fb_info(info); break; case FB_EVENT_MODE_CHANGE: - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } fbcon_modechanged(info); - unlock_fb_info(info); break; case FB_EVENT_MODE_CHANGE_ALL: - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } fbcon_set_all_vcs(info); - unlock_fb_info(info); break; case FB_EVENT_MODE_DELETE: mode = event->data; - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } ret = fbcon_mode_deleted(info, mode); - unlock_fb_info(info); break; case FB_EVENT_FB_UNBIND: - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } - idx = info->node; - unlock_fb_info(info); - ret = fbcon_fb_unbind(idx); + ret = fbcon_fb_unbind(info->node); break; case FB_EVENT_FB_REGISTERED: ret = fbcon_fb_registered(info); @@ -3217,31 +3178,17 @@ static int fbcon_event_notify(struct notifier_block *self, con2fb->framebuffer = con2fb_map[con2fb->console - 1]; break; case FB_EVENT_BLANK: - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } fbcon_fb_blanked(info, *(int *)event->data); - unlock_fb_info(info); break; case FB_EVENT_NEW_MODELIST: - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } fbcon_new_modelist(info); - unlock_fb_info(info); break; case FB_EVENT_GET_REQ: caps = event->data; - if (!lock_fb_info(info)) { - ret = -ENODEV; - goto done; - } fbcon_get_requirement(info, caps); - unlock_fb_info(info); break; } + done: return ret; } diff --git a/trunk/drivers/video/cyblafb.c b/trunk/drivers/video/cyblafb.c new file mode 100644 index 000000000000..9704b73135f5 --- /dev/null +++ b/trunk/drivers/video/cyblafb.c @@ -0,0 +1,1683 @@ +/* + * Frame buffer driver for Trident Cyberblade/i1 graphics core + * + * Copyright 2005 Knut Petersen + * + * CREDITS: + * tridentfb.c by Jani Monoses + * see files above for further credits + * + */ + +#define CYBLAFB_DEBUG 0 +#define CYBLAFB_KD_GRAPHICS_QUIRK 1 + +#define CYBLAFB_PIXMAPSIZE 8192 + +#include +#include +#include +#include +#include +#include +#include