]> nv-tegra.nvidia Code Review - linux-2.6.git/commitdiff
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
authorLinus Torvalds <torvalds@ppc970.osdl.org>
Wed, 29 Jun 2005 04:24:32 +0000 (21:24 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Wed, 29 Jun 2005 04:24:32 +0000 (21:24 -0700)
144 files changed:
Documentation/SubmittingDrivers
Documentation/SubmittingPatches
Documentation/kernel-parameters.txt
Documentation/video4linux/API.html
Documentation/video4linux/CARDLIST.cx88
Documentation/video4linux/CARDLIST.saa7134
Documentation/video4linux/CARDLIST.tuner
Documentation/video4linux/README.saa7134
MAINTAINERS
arch/arm/Kconfig
arch/arm/mach-s3c2410/irq.c
arch/arm/oprofile/Makefile
arch/arm/oprofile/backtrace.c [new file with mode: 0644]
arch/arm/oprofile/init.c
arch/arm/oprofile/op_arm_model.h
arch/i386/boot/tools/build.c
arch/i386/kernel/acpi/boot.c
arch/i386/pci/common.c
arch/i386/pci/irq.c
arch/i386/pci/legacy.c
arch/i386/pci/mmconfig.c
arch/i386/pci/numa.c
arch/i386/pci/pci.h
arch/ia64/kernel/acpi.c
arch/ia64/kernel/iosapic.c
arch/ia64/pci/pci.c
arch/ppc/kernel/pci.c
arch/ppc64/kernel/irq.c
arch/ppc64/kernel/pci.c
arch/sparc/Kconfig
arch/x86_64/pci/mmconfig.c
drivers/acpi/container.c
drivers/acpi/pci_bind.c
drivers/acpi/pci_root.c
drivers/acpi/processor_core.c
drivers/acpi/scan.c
drivers/base/firmware_class.c
drivers/block/cciss.c
drivers/block/ll_rw_blk.c
drivers/char/agp/amd64-agp.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/moxa.c
drivers/char/rio/rio_linux.c
drivers/char/rtc.c
drivers/char/tipar.c
drivers/char/tty_ioctl.c
drivers/char/vt_ioctl.c
drivers/char/watchdog/ixp2000_wdt.c
drivers/char/watchdog/ixp4xx_wdt.c
drivers/isdn/hardware/eicon/dadapter.c
drivers/isdn/hisax/hfc4s8s_l1.c
drivers/isdn/hysdn/hycapi.c
drivers/isdn/hysdn/hysdn_boot.c
drivers/isdn/hysdn/hysdn_defs.h
drivers/isdn/hysdn/hysdn_init.c
drivers/isdn/hysdn/hysdn_proclog.c
drivers/md/md.c
drivers/media/video/Makefile
drivers/media/video/bttv-driver.c
drivers/media/video/bttvp.h
drivers/media/video/mt20xx.c
drivers/media/video/tda8290.c
drivers/media/video/tda9887.c
drivers/media/video/tea5767.c [new file with mode: 0644]
drivers/media/video/tuner-core.c
drivers/media/video/tuner-simple.c
drivers/message/fusion/mptfc.c
drivers/message/fusion/mptscsih.c
drivers/message/fusion/mptscsih.h
drivers/message/fusion/mptspi.c
drivers/net/e100.c
drivers/net/via-rhine.c
drivers/parisc/dino.c
drivers/parisc/lba_pci.c
drivers/pci/bus.c
drivers/pci/hotplug/Makefile
drivers/pci/hotplug/acpiphp.h
drivers/pci/hotplug/acpiphp_core.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/acpiphp_pci.c [deleted file]
drivers/pci/hotplug/acpiphp_res.c [deleted file]
drivers/pci/hotplug/cpqphp_core.c
drivers/pci/msi.c
drivers/pci/msi.h
drivers/pci/pci-sysfs.c
drivers/pci/probe.c
drivers/pci/proc.c
drivers/pci/remove.c
drivers/pci/setup-bus.c
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-xxxx.c
drivers/scsi/ipr.c
drivers/scsi/megaraid.c
drivers/scsi/scsi_lib.c
fs/aio.c
fs/buffer.c
fs/char_dev.c
fs/ext3/balloc.c
fs/ext3/file.c
fs/ext3/super.c
fs/nfs/nfs3acl.c
fs/nfsd/vfs.c
fs/udf/namei.c
include/acpi/acpi_bus.h
include/acpi/acpi_drivers.h
include/asm-alpha/pci.h
include/asm-arm/arch-s3c2410/audio.h [new file with mode: 0644]
include/asm-arm/pci.h
include/asm-frv/pci.h
include/asm-i386/pci.h
include/asm-ia64/iosapic.h
include/asm-ia64/pci.h
include/asm-mips/pci.h
include/asm-parisc/pci.h
include/asm-ppc/pci.h
include/asm-ppc64/byteorder.h
include/asm-ppc64/pci.h
include/asm-sh/pci.h
include/asm-sh64/pci.h
include/asm-sparc/pci.h
include/asm-sparc64/pci.h
include/asm-v850/pci.h
include/asm-x86_64/pci.h
include/linux/acpi.h
include/linux/blkdev.h
include/linux/byteorder/swabb.h
include/linux/i2c-dev.h
include/linux/irq.h
include/linux/pci.h
include/linux/pci_ids.h
include/linux/usb_ch9.h
include/linux/videodev2.h
include/linux/writeback.h
include/linux/xattr_acl.h [deleted file]
include/media/tuner.h
init/main.c
kernel/irq/autoprobe.c
kernel/irq/handle.c
kernel/irq/spurious.c
kernel/itimer.c
kernel/kexec.c
kernel/sched.c
mm/page-writeback.c
mm/vmscan.c

index de3b252e717d0f0f10c4259cb1cbf7624073de6f..c3cca924e94b4accf6848e9338d12c1ca863bb36 100644 (file)
@@ -13,13 +13,14 @@ Allocating Device Numbers
 -------------------------
 
 Major and minor numbers for block and character devices are allocated
-by the Linux assigned name and number authority (currently better
-known as H Peter Anvin). The site is http://www.lanana.org/. This
+by the Linux assigned name and number authority (currently this is
+Torben Mathiasen). The site is http://www.lanana.org/. This
 also deals with allocating numbers for devices that are not going to
 be submitted to the mainstream kernel.
+See Documentation/devices.txt for more information on this.
 
-If you don't use assigned numbers then when you device is submitted it will
-get given an assigned number even if that is different from values you may
+If you don't use assigned numbers then when your device is submitted it will
+be given an assigned number even if that is different from values you may
 have shipped to customers before.
 
 Who To Submit Drivers To
@@ -32,7 +33,8 @@ Linux 2.2:
        If the code area has a general maintainer then please submit it to
        the maintainer listed in MAINTAINERS in the kernel file. If the
        maintainer does not respond or you cannot find the appropriate
-       maintainer then please contact Alan Cox <alan@lxorguk.ukuu.org.uk>
+       maintainer then please contact the 2.2 kernel maintainer:
+       Marc-Christian Petersen <m.c.p@wolk-project.de>.
 
 Linux 2.4:
        The same rules apply as 2.2. The final contact point for Linux 2.4
@@ -48,7 +50,7 @@ What Criteria Determine Acceptance
 
 Licensing:     The code must be released to us under the
                GNU General Public License. We don't insist on any kind
-               of exclusively GPL licensing, and if you wish the driver
+               of exclusive GPL licensing, and if you wish the driver
                to be useful to other communities such as BSD you may well
                wish to release under multiple licenses.
 
index 4d1f41b84ebca707ffdb5da8211da04091ee078d..6761a7b241a5fafbe77c69d09e23b1dd56781f06 100644 (file)
@@ -35,7 +35,7 @@ not in any lower subdirectory.
 
 To create a patch for a single file, it is often sufficient to do:
 
-       SRCTREE= linux-2.4
+       SRCTREE= linux-2.6
        MYFILE=  drivers/net/mydriver.c
 
        cd $SRCTREE
@@ -48,17 +48,18 @@ To create a patch for multiple files, you should unpack a "vanilla",
 or unmodified kernel source tree, and generate a diff against your
 own source tree.  For example:
 
-       MYSRC= /devel/linux-2.4
+       MYSRC= /devel/linux-2.6
 
-       tar xvfz linux-2.4.0-test11.tar.gz
-       mv linux linux-vanilla
-       wget http://www.moses.uklinux.net/patches/dontdiff
-       diff -uprN -X dontdiff linux-vanilla $MYSRC > /tmp/patch
-       rm -f dontdiff
+       tar xvfz linux-2.6.12.tar.gz
+       mv linux-2.6.12 linux-2.6.12-vanilla
+       diff -uprN -X linux-2.6.12-vanilla/Documentation/dontdiff \
+               linux-2.6.12-vanilla $MYSRC > /tmp/patch
 
 "dontdiff" is a list of files which are generated by the kernel during
 the build process, and should be ignored in any diff(1)-generated
-patch.  dontdiff is maintained by Tigran Aivazian <tigran@veritas.com>
+patch.  The "dontdiff" file is included in the kernel tree in
+2.6.12 and later.  For earlier kernel versions, you can get it
+from <http://www.xenotime.net/linux/doc/dontdiff>.
 
 Make sure your patch does not include any extra files which do not
 belong in a patch submission.  Make sure to review your patch -after-
@@ -66,18 +67,20 @@ generated it with diff(1), to ensure accuracy.
 
 If your changes produce a lot of deltas, you may want to look into
 splitting them into individual patches which modify things in
-logical stages, this will facilitate easier reviewing by other
+logical stages.  This will facilitate easier reviewing by other
 kernel developers, very important if you want your patch accepted.
-There are a number of scripts which can aid in this;
+There are a number of scripts which can aid in this:
 
 Quilt:
 http://savannah.nongnu.org/projects/quilt
 
 Randy Dunlap's patch scripts:
-http://developer.osdl.org/rddunlap/scripts/patching-scripts.tgz
+http://www.xenotime.net/linux/scripts/patching-scripts-002.tar.gz
 
 Andrew Morton's patch scripts:
-http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.16
+http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.20
+
+
 
 2) Describe your changes.
 
@@ -163,6 +166,8 @@ patches. Trivial patches must qualify for one of the following rules:
  since people copy, as long as it's trivial)
  Any fix by the author/maintainer of the file. (ie. patch monkey
  in re-transmission mode)
+URL: <http://www.kernel.org/pub/linux/kernel/people/rusty/trivial/>
+
 
 
 
@@ -291,6 +296,17 @@ now, but you can do this to mark internal company procedures or just
 point out some special detail about the sign-off. 
 
 
+
+12) More references for submitting patches
+
+Andrew Morton, "The perfect patch" (tpp).
+  <http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt>
+
+Jeff Garzik, "Linux kernel patch submission format."
+  <http://linux.yyz.us/patch-format.html>
+
+
+
 -----------------------------------
 SECTION 2 - HINTS, TIPS, AND TRICKS
 -----------------------------------
@@ -359,7 +375,5 @@ and 'extern __inline__'.
 4) Don't over-design.
 
 Don't try to anticipate nebulous future cases which may or may not
-be useful:  "Make it as simple as you can, and no simpler"
-
-
+be useful:  "Make it as simple as you can, and no simpler."
 
index 89cd417651e07bbf099cb217f5adfbfec618dd04..67e99f144199242d69df27f3e43a72aa2518b42f 100644 (file)
@@ -437,6 +437,10 @@ running once the system is up.
                        Format: {"of[f]" | "sk[ipmbr]"}
                        See comment in arch/i386/boot/edd.S
 
+       edd             [EDD]
+                       Format: {"of[f]" | "sk[ipmbr]"}
+                       See comment in arch/i386/boot/edd.S
+
        eicon=          [HW,ISDN] 
                        Format: <id>,<membase>,<irq>
 
@@ -622,6 +626,17 @@ running once the system is up.
        ips=            [HW,SCSI] Adaptec / IBM ServeRAID controller
                        See header of drivers/scsi/ips.c.
 
+       irqfixup        [HW]
+                       When an interrupt is not handled search all handlers
+                       for it. Intended to get systems with badly broken
+                       firmware running.
+
+       irqpoll         [HW]
+                       When an interrupt is not handled search all handlers
+                       for it. Also check all handlers each timer
+                       interrupt. Intended to get systems with badly broken
+                       firmware running.
+
        isapnp=         [ISAPNP]
                        Format: <RDP>, <reset>, <pci_scan>, <verbosity>
 
@@ -1030,6 +1045,10 @@ running once the system is up.
                irqmask=0xMMMM          [IA-32] Set a bit mask of IRQs allowed to be assigned
                                        automatically to PCI devices. You can make the kernel
                                        exclude IRQs of your ISA cards this way.
+               pirqaddr=0xAAAAA        [IA-32] Specify the physical address
+                                       of the PIRQ table (normally generated
+                                       by the BIOS) if it is outside the
+                                       F0000h-100000h range.
                lastbus=N               [IA-32] Scan all buses till bus #N. Can be useful
                                        if the kernel is unable to find your secondary buses
                                        and you want to tell it explicitly which ones they are.
index 4b3d8f640a4a37a308788234f1506e755607e8fc..441407b12a9f49563f9132a44dbf830739041428 100644 (file)
-<HTML><HEAD>
-<TITLE>Video4Linux Kernel API Reference v0.1:19990430</TITLE>
-</HEAD>
-<! Revision History: >
-<!   4/30/1999 - Fred Gleason (fredg@wava.com)>
-<! Documented extensions for the Radio Data System (RDS) extensions >
-<BODY bgcolor="#ffffff">
-<H3>Devices</H3>
-Video4Linux provides the following sets of device files. These live on the
-character device formerly known as "/dev/bttv". /dev/bttv should be a
-symlink to /dev/video0 for most people. 
-<P>
-<TABLE>
-<TR><TH>Device Name</TH><TH>Minor Range</TH><TH>Function</TH>
-<TR><TD>/dev/video</TD><TD>0-63</TD><TD>Video Capture Interface</TD>
-<TR><TD>/dev/radio</TD><TD>64-127</TD><TD>AM/FM Radio Devices</TD>
-<TR><TD>/dev/vtx</TD><TD>192-223</TD><TD>Teletext Interface Chips</TD>
-<TR><TD>/dev/vbi</TD><TD>224-239</TD><TD>Raw VBI Data (Intercast/teletext)</TD>
-</TABLE>
-<P>
-Video4Linux programs open and scan the devices to find what they are looking
-for. Capability queries define what each interface supports. The 
-described API is only defined for video capture cards. The relevant subset
-applies to radio cards. Teletext interfaces talk the existing VTX API.
-<P>
-<H3>Capability Query Ioctl</H3>
-The <B>VIDIOCGCAP</B> ioctl call is used to obtain the capability
-information for a video device. The <b>struct video_capability</b> object
-passed to the ioctl is completed and returned. It contains the following
-information
-<P>
-<TABLE>
-<TR><TD><b>name[32]</b><TD>Canonical name for this interface</TD>
-<TR><TD><b>type</b><TD>Type of interface</TD>
-<TR><TD><b>channels</b><TD>Number of radio/tv channels if appropriate</TD>
-<TR><TD><b>audios</b><TD>Number of audio devices if appropriate</TD>
-<TR><TD><b>maxwidth</b><TD>Maximum capture width in pixels</TD>
-<TR><TD><b>maxheight</b><TD>Maximum capture height in pixels</TD>
-<TR><TD><b>minwidth</b><TD>Minimum capture width in pixels</TD>
-<TR><TD><b>minheight</b><TD>Minimum capture height in pixels</TD>
-</TABLE>
-<P>
-The type field lists the capability flags for the device. These are
-as follows
-<P>
-<TABLE>
-<TR><TH>Name</TH><TH>Description</TH>
-<TR><TD><b>VID_TYPE_CAPTURE</b><TD>Can capture to memory</TD>
-<TR><TD><b>VID_TYPE_TUNER</b><TD>Has a tuner of some form</TD>
-<TR><TD><b>VID_TYPE_TELETEXT</b><TD>Has teletext capability</TD>
-<TR><TD><b>VID_TYPE_OVERLAY</b><TD>Can overlay its image onto the frame buffer</TD>
-<TR><TD><b>VID_TYPE_CHROMAKEY</b><TD>Overlay is Chromakeyed</TD>
-<TR><TD><b>VID_TYPE_CLIPPING</b><TD>Overlay clipping is supported</TD>
-<TR><TD><b>VID_TYPE_FRAMERAM</b><TD>Overlay overwrites frame buffer memory</TD>
-<TR><TD><b>VID_TYPE_SCALES</b><TD>The hardware supports image scaling</TD>
-<TR><TD><b>VID_TYPE_MONOCHROME</b><TD>Image capture is grey scale only</TD>
-<TR><TD><b>VID_TYPE_SUBCAPTURE</b><TD>Capture can be of only part of the image</TD>
-</TABLE>
-<P>
-The minimum and maximum sizes listed for a capture device do not imply all
-that all height/width ratios or sizes within the range are possible. A
-request to set a size will be honoured by the largest available capture
-size whose capture is no large than the requested rectangle in either
-direction. For example the quickcam has 3 fixed settings. 
-<P>
-<H3>Frame Buffer</H3>
-Capture cards that drop data directly onto the frame buffer must be told the
-base address of the frame buffer, its size and organisation. This is a 
-privileged ioctl and one that eventually X itself should set.
-<P>
-The <b>VIDIOCSFBUF</b> ioctl sets the frame buffer parameters for a capture
-card. If the card does not do direct writes to the frame buffer then this
-ioctl will be unsupported. The <b>VIDIOCGFBUF</b> ioctl returns the
-currently used parameters. The structure used in both cases is a 
-<b>struct video_buffer</b>.
-<P>
-<TABLE>
-<TR><TD><b>void *base</b></TD><TD>Base physical address of the buffer</TD>
-<TR><TD><b>int height</b></TD><TD>Height of the frame buffer</TD>
-<TR><TD><b>int width</b></TD><TD>Width of the frame buffer</TD>
-<TR><TD><b>int depth</b></TD><TD>Depth of the frame buffer</TD>
-<TR><TD><b>int bytesperline</b></TD><TD>Number of bytes of memory between the start of two adjacent lines</TD>
-</TABLE>
-<P>
-Note that these values reflect the physical layout of the frame buffer. 
-The visible area may be smaller. In fact under XFree86 this is commonly the
-case. XFree86 DGA can provide the parameters required to set up this ioctl.
-Setting the base address to NULL indicates there is no physical frame buffer
-access.
-<P>
-<H3>Capture Windows</H3>
-The capture area is described by a <b>struct video_window</b>. This defines
-a capture area and the clipping information if relevant. The 
-<b>VIDIOCGWIN</b> ioctl recovers the current settings and the 
-<b>VIDIOCSWIN</b> sets new values. A successful call to <b>VIDIOCSWIN</b> 
-indicates that a suitable set of parameters have been chosen. They do not
-indicate that exactly what was requested was granted. The program should
-call <b>VIDIOCGWIN</b> to check if the nearest match was suitable. The
-<b>struct video_window</b> contains the following fields.
-<P>
-<TABLE>
-<TR><TD><b>x</b><TD>The X co-ordinate specified in X windows format.</TD>
-<TR><TD><b>y</b><TD>The Y co-ordinate specified in X windows format.</TD>
-<TR><TD><b>width</b><TD>The width of the image capture.</TD>
-<TR><TD><b>height</b><TD>The height of the image capture.</TD>
-<TR><TD><b>chromakey</b><TD>A host order RGB32 value for the chroma key.</TD>
-<TR><TD><b>flags</b><TD>Additional capture flags.</TD>
-<TR><TD><b>clips</b><TD>A list of clipping rectangles. <em>(Set only)</em></TD>
-<TR><TD><b>clipcount</b><TD>The number of clipping rectangles. <em>(Set only)</em></TD>
-</TABLE>
-<P>
-Clipping rectangles are passed as an array. Each clip consists of the following
-fields available to the user.
-<P>
-<TABLE>
-<TR><TD><b>x</b></TD><TD>X co-ordinate of rectangle to skip</TD>
-<TR><TD><b>y</b></TD><TD>Y co-ordinate of rectangle to skip</TD>
-<TR><TD><b>width</b></TD><TD>Width of rectangle to skip</TD>
-<TR><TD><b>height</b></TD><TD>Height of rectangle to skip</TD>
-</TABLE>
-<P>
-Merely setting the window does not enable capturing. Overlay capturing
-(i.e. PCI-PCI transfer to the frame buffer of the video card)
-is activated by passing the <b>VIDIOCCAPTURE</b> ioctl a value of 1, and
-disabled by passing it a value of 0. 
-<P>
-Some capture devices can capture a subfield of the image they actually see.
-This is indicated when VIDEO_TYPE_SUBCAPTURE is defined.
-The video_capture describes the time and special subfields to capture.
-The video_capture structure contains the following fields.
-<P>
-<TABLE>
-<TR><TD><b>x</b></TD><TD>X co-ordinate of source rectangle to grab</TD>
-<TR><TD><b>y</b></TD><TD>Y co-ordinate of source rectangle to grab</TD>
-<TR><TD><b>width</b></TD><TD>Width of source rectangle to grab</TD>
-<TR><TD><b>height</b></TD><TD>Height of source rectangle to grab</TD>
-<TR><TD><b>decimation</b></TD><TD>Decimation to apply</TD>
-<TR><TD><b>flags</b></TD><TD>Flag settings for grabbing</TD>
-</TABLE>
-The available flags are
-<P>
-<TABLE>
-<TR><TH>Name</TH><TH>Description</TH>
-<TR><TD><b>VIDEO_CAPTURE_ODD</b><TD>Capture only odd frames</TD>
-<TR><TD><b>VIDEO_CAPTURE_EVEN</b><TD>Capture only even frames</TD>
-</TABLE>
-<P>
-<H3>Video Sources</H3>
-Each video4linux video or audio device captures from one or more 
-source <b>channels</b>. Each channel can be queries with the 
-<b>VDIOCGCHAN</b> ioctl call. Before invoking this function the caller
-must set the channel field to the channel that is being queried. On return
-the <b>struct video_channel</b> is filled in with information about the
-nature of the channel itself.
-<P>
-The <b>VIDIOCSCHAN</b> ioctl takes an integer argument and switches the
-capture to this input. It is not defined whether parameters such as colour
-settings or tuning are maintained across a channel switch. The caller should
-maintain settings as desired for each channel. (This is reasonable as 
-different video inputs may have different properties).
-<P>
-The <b>struct video_channel</b> consists of the following
-<P>
-<TABLE>
-<TR><TD><b>channel</b></TD><TD>The channel number</TD>
-<TR><TD><b>name</b></TD><TD>The input name - preferably reflecting the label
-on the card input itself</TD>
-<TR><TD><b>tuners</b></TD><TD>Number of tuners for this input</TD>
-<TR><TD><b>flags</b></TD><TD>Properties the tuner has</TD>
-<TR><TD><b>type</b></TD><TD>Input type (if known)</TD>
-<TR><TD><b>norm</b><TD>The norm for this channel</TD>
-</TABLE>
-<P>
-The flags defined are
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_VC_TUNER</b><TD>Channel has tuners.</TD>
-<TR><TD><b>VIDEO_VC_AUDIO</b><TD>Channel has audio.</TD>
-<TR><TD><b>VIDEO_VC_NORM</b><TD>Channel has norm setting.</TD>
-</TABLE>
-<P>
-The types defined are
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_TYPE_TV</b><TD>The input is a TV input.</TD>
-<TR><TD><b>VIDEO_TYPE_CAMERA</b><TD>The input is a camera.</TD>
-</TABLE>
-<P>
-<H3>Image Properties</H3>
-The image properties of the picture can be queried with the <b>VIDIOCGPICT</b>
-ioctl which fills in a <b>struct video_picture</b>. The <b>VIDIOCSPICT</b> 
-ioctl allows values to be changed. All values except for the palette type
-are scaled between 0-65535. 
-<P>
-The <b>struct video_picture</b> consists of the following fields
-<P>
-<TABLE>
-<TR><TD><b>brightness</b><TD>Picture brightness</TD>
-<TR><TD><b>hue</b><TD>Picture hue (colour only)</TD>
-<TR><TD><b>colour</b><TD>Picture colour (colour only)</TD>
-<TR><TD><b>contrast</b><TD>Picture contrast</TD>
-<TR><TD><b>whiteness</b><TD>The whiteness (greyscale only)</TD>
-<TR><TD><b>depth</b><TD>The capture depth (may need to match the frame buffer depth)</TD>
-<TR><TD><b>palette</b><TD>Reports the palette that should be used for this image</TD>
-</TABLE>
-<P>
-The following palettes are defined
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_PALETTE_GREY</b><TD>Linear intensity grey scale (255 is brightest).</TD>
-<TR><TD><b>VIDEO_PALETTE_HI240</b><TD>The BT848 8bit colour cube.</TD>
-<TR><TD><b>VIDEO_PALETTE_RGB565</b><TD>RGB565 packed into 16 bit words.</TD>
-<TR><TD><b>VIDEO_PALETTE_RGB555</b><TD>RGV555 packed into 16 bit words, top bit undefined.</TD>
-<TR><TD><b>VIDEO_PALETTE_RGB24</b><TD>RGB888 packed into 24bit words.</TD>
-<TR><TD><b>VIDEO_PALETTE_RGB32</b><TD>RGB888 packed into the low 3 bytes of 32bit words. The top 8bits are undefined.</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV422</b><TD>Video style YUV422 - 8bits packed 4bits Y 2bits U 2bits V</TD>
-<TR><TD><b>VIDEO_PALETTE_YUYV</b><TD>Describe me</TD>
-<TR><TD><b>VIDEO_PALETTE_UYVY</b><TD>Describe me</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV420</b><TD>YUV420 capture</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV411</b><TD>YUV411 capture</TD>
-<TR><TD><b>VIDEO_PALETTE_RAW</b><TD>RAW capture (BT848)</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV422P</b><TD>YUV 4:2:2 Planar</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV411P</b><TD>YUV 4:1:1 Planar</TD>
-</TABLE>
-<P>
-<H3>Tuning</H3>
-Each video input channel can have one or more tuners associated with it. Many
-devices will not have tuners. TV cards and radio cards will have one or more
-tuners attached.
-<P>
-Tuners are described by a <b>struct video_tuner</b> which can be obtained by
-the <b>VIDIOCGTUNER</b> ioctl. Fill in the tuner number in the structure
-then pass the structure to the ioctl to have the data filled in. The 
-tuner can be switched using <b>VIDIOCSTUNER</b> which takes an integer argument
-giving the tuner to use. A struct tuner has the following fields
-<P>
-<TABLE>
-<TR><TD><b>tuner</b><TD>Number of the tuner</TD>
-<TR><TD><b>name</b><TD>Canonical name for this tuner (eg FM/AM/TV)</TD>
-<TR><TD><b>rangelow</b><TD>Lowest tunable frequency</TD>
-<TR><TD><b>rangehigh</b><TD>Highest tunable frequency</TD>
-<TR><TD><b>flags</b><TD>Flags describing the tuner</TD>
-<TR><TD><b>mode</b><TD>The video signal mode if relevant</TD>
-<TR><TD><b>signal</b><TD>Signal strength if known - between 0-65535</TD>
-</TABLE>
-<P>
-The following flags exist
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_TUNER_PAL</b><TD>PAL tuning is supported</TD>
-<TR><TD><b>VIDEO_TUNER_NTSC</b><TD>NTSC tuning is supported</TD>
-<TR><TD><b>VIDEO_TUNER_SECAM</b><TD>SECAM tuning is supported</TD>
-<TR><TD><b>VIDEO_TUNER_LOW</b><TD>Frequency is in a lower range</TD>
-<TR><TD><b>VIDEO_TUNER_NORM</b><TD>The norm for this tuner is settable</TD>
-<TR><TD><b>VIDEO_TUNER_STEREO_ON</b><TD>The tuner is seeing stereo audio</TD>
-<TR><TD><b>VIDEO_TUNER_RDS_ON</b><TD>The tuner is seeing a RDS datastream</TD>
-<TR><TD><b>VIDEO_TUNER_MBS_ON</b><TD>The tuner is seeing a MBS datastream</TD>
-</TABLE>
-<P>
-The following modes are defined
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_MODE_PAL</b><TD>The tuner is in PAL mode</TD>
-<TR><TD><b>VIDEO_MODE_NTSC</b><TD>The tuner is in NTSC mode</TD>
-<TR><TD><b>VIDEO_MODE_SECAM</b><TD>The tuner is in SECAM mode</TD>
-<TR><TD><b>VIDEO_MODE_AUTO</b><TD>The tuner auto switches, or mode does not apply</TD>
-</TABLE>
-<P>
-Tuning frequencies are an unsigned 32bit value in 1/16th MHz or if the
-<b>VIDEO_TUNER_LOW</b> flag is set they are in 1/16th KHz. The current
-frequency is obtained as an unsigned long via the <b>VIDIOCGFREQ</b> ioctl and
-set by the <b>VIDIOCSFREQ</b> ioctl.
-<P>
-<H3>Audio</H3>
-TV and Radio devices have one or more audio inputs that may be selected. 
-The audio properties are queried by passing a <b>struct video_audio</b> to <b>VIDIOCGAUDIO</b> ioctl. The
-<b>VIDIOCSAUDIO</b> ioctl sets audio properties.
-<P>
-The structure contains the following fields
-<P>
-<TABLE>
-<TR><TD><b>audio</b><TD>The channel number</TD>
-<TR><TD><b>volume</b><TD>The volume level</TD>
-<TR><TD><b>bass</b><TD>The bass level</TD>
-<TR><TD><b>treble</b><TD>The treble level</TD>
-<TR><TD><b>flags</b><TD>Flags describing the audio channel</TD>
-<TR><TD><b>name</b><TD>Canonical name for the audio input</TD>
-<TR><TD><b>mode</b><TD>The mode the audio input is in</TD>
-<TR><TD><b>balance</b><TD>The left/right balance</TD>
-<TR><TD><b>step</b><TD>Actual step used by the hardware</TD>
-</TABLE>
-<P>
-The following flags are defined
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_AUDIO_MUTE</b><TD>The audio is muted</TD>
-<TR><TD><b>VIDEO_AUDIO_MUTABLE</b><TD>Audio muting is supported</TD>
-<TR><TD><b>VIDEO_AUDIO_VOLUME</b><TD>The volume is controllable</TD>
-<TR><TD><b>VIDEO_AUDIO_BASS</b><TD>The bass is controllable</TD>
-<TR><TD><b>VIDEO_AUDIO_TREBLE</b><TD>The treble is controllable</TD>
-<TR><TD><b>VIDEO_AUDIO_BALANCE</b><TD>The balance is controllable</TD>
-</TABLE>
-<P>
-The following decoding modes are defined
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_SOUND_MONO</b><TD>Mono signal</TD>
-<TR><TD><b>VIDEO_SOUND_STEREO</b><TD>Stereo signal (NICAM for TV)</TD>
-<TR><TD><b>VIDEO_SOUND_LANG1</b><TD>European TV alternate language 1</TD>
-<TR><TD><b>VIDEO_SOUND_LANG2</b><TD>European TV alternate language 2</TD>
-</TABLE>
-<P>
-<H3>Reading Images</H3>
-Each call to the <b>read</b> syscall returns the next available image
-from the device. It is up to the caller to set format and size (using
-the VIDIOCSPICT and VIDIOCSWIN ioctls) and then to pass a suitable
-size buffer and length to the function. Not all devices will support
-read operations.
-<P>
-A second way to handle image capture is via the mmap interface if supported.
-To use the mmap interface a user first sets the desired image size and depth
-properties. Next the VIDIOCGMBUF ioctl is issued. This reports the size
-of buffer to mmap and the offset within the buffer for each frame. The
-number of frames supported is device dependent and may only be one. 
-<P>
-The video_mbuf structure contains the following fields
-<P>
-<TABLE>
-<TR><TD><b>size</b><TD>The number of bytes to map</TD>
-<TR><TD><b>frames</b><TD>The number of frames</TD>
-<TR><TD><b>offsets</b><TD>The offset of each frame</TD>
-</TABLE>
-<P>
-Once the mmap has been made the VIDIOCMCAPTURE ioctl starts the
-capture to a frame using the format and image size specified in the
-video_mmap (which should match or be below the initial query size).
-When the VIDIOCMCAPTURE ioctl returns the frame is <em>not</em>
-captured yet, the driver just instructed the hardware to start the
-capture.  The application has to use the VIDIOCSYNC ioctl to wait
-until the capture of a frame is finished.  VIDIOCSYNC takes the frame
-number you want to wait for as argument.
-<p>
-It is allowed to call VIDIOCMCAPTURE multiple times (with different
-frame numbers in video_mmap->frame of course) and thus have multiple
-outstanding capture requests.  A simple way do to double-buffering
-using this feature looks like this:
-<pre>
-/* setup everything */
-VIDIOCMCAPTURE(0)
-while (whatever) {
-   VIDIOCMCAPTURE(1)
-   VIDIOCSYNC(0)
-   /* process frame 0 while the hardware captures frame 1 */
-   VIDIOCMCAPTURE(0)
-   VIDIOCSYNC(1)
-   /* process frame 1 while the hardware captures frame 0 */
-}
-</pre>
-Note that you are <em>not</em> limited to only two frames.  The API
-allows up to 32 frames, the VIDIOCGMBUF ioctl returns the number of
-frames the driver granted.  Thus it is possible to build deeper queues
-to avoid loosing frames on load peaks.
-<p>
-While capturing to memory the driver will make a "best effort" attempt
-to capture to screen as well if requested. This normally means all
-frames that "miss" memory mapped capture will go to the display.
-<P>
-A final ioctl exists to allow a device to obtain related devices if a
-driver has multiple components (for example video0 may not be associated
-with vbi0 which would cause an intercast display program to make a bad
-mistake). The VIDIOCGUNIT ioctl reports the unit numbers of the associated
-devices if any exist. The video_unit structure has the following fields.
-<P>
-<TABLE>
-<TR><TD><b>video</b><TD>Video capture device</TD>
-<TR><TD><b>vbi</b><TD>VBI capture device</TD>
-<TR><TD><b>radio</b><TD>Radio device</TD>
-<TR><TD><b>audio</b><TD>Audio mixer</TD>
-<TR><TD><b>teletext</b><TD>Teletext device</TD>
-</TABLE>
-<P>
-<H3>RDS Datastreams</H3>
-For radio devices that support it, it is possible to receive Radio Data
-System (RDS) data by means of a read() on the device.  The data is packed in
-groups of three, as follows:
-<TABLE>
-<TR><TD>First Octet</TD><TD>Least Significant Byte of RDS Block</TD></TR>
-<TR><TD>Second Octet</TD><TD>Most Significant Byte of RDS Block
-<TR><TD>Third Octet</TD><TD>Bit 7:</TD><TD>Error bit.  Indicates that
-an uncorrectable error occurred during reception of this block.</TD></TR>
-<TR><TD>&nbsp;</TD><TD>Bit 6:</TD><TD>Corrected bit.  Indicates that  
-an error was corrected for this data block.</TD></TR>
-<TR><TD>&nbsp;</TD><TD>Bits 5-3:</TD><TD>Received Offset.  Indicates the  
-offset received by the sync system.</TD></TR>
-<TR><TD>&nbsp;</TD><TD>Bits 2-0:</TD><TD>Offset Name.  Indicates the  
-offset applied to this data.</TD></TR>
-</TABLE>
-</BODY>
-</HTML>
+<TITLE>V4L API</TITLE>
+<H1>Video For Linux APIs</H1>
+<table border=0>
+<tr>
+<td>
+<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L1_API.html>
+V4L original API</a>
+</td><td>
+Obsoleted by V4L2 API
+</td></tr><tr><td>
+<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L2_API.html>
+V4L2 API</a>
+</td><td>
+Should be used for new projects
+</td></tr>
+</table>
index 216f705495ccd07c6a323158dd89429b05645b9c..4377aa11f567a2f17f0a3ade5fdc58c57b662294 100644 (file)
@@ -13,17 +13,17 @@ card=11 - Prolink PlayTV PVR
 card=12 - ASUS PVR-416
 card=13 - MSI TV-@nywhere
 card=14 - KWorld/VStream XPert DVB-T
-card=15 - DVICO FusionHDTV DVB-T1
+card=15 - DViCO FusionHDTV DVB-T1
 card=16 - KWorld LTV883RF
-card=17 - DViCO - FusionHDTV 3 Gold
+card=17 - DViCO FusionHDTV 3 Gold-Q
 card=18 - Hauppauge Nova-T DVB-T
 card=19 - Conexant DVB-T reference design
 card=20 - Provideo PV259
-card=21 - DVICO FusionHDTV DVB-T Plus
+card=21 - DViCO FusionHDTV DVB-T Plus
 card=22 - digitalnow DNTV Live! DVB-T
 card=23 - pcHDTV HD3000 HDTV
 card=24 - Hauppauge WinTV 28xxx (Roslyn) models
 card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC)
 card=26 - IODATA GV/BCTV7E
 card=27 - PixelView PlayTV Ultra Pro (Stereo)
-card=28 - DViCO FusionHDTV 3 Gold-T
+card=28 - DViCO FusionHDTV 3 Gold-T
index d5ed95d285006947eff14624de06dc1682e00c9f..735e8ba02d9fe42650c22ea05a3df45a432104f1 100644 (file)
@@ -54,3 +54,9 @@
  55 -> LifeView FlyDVB-T DUO                    [5168:0306]
  56 -> Avermedia AVerTV 307                     [1461:a70a]
  57 -> Avermedia AVerTV GO 007 FM               [1461:f31f]
+ 58 -> ADS Tech Instant TV (saa7135)            [1421:0350,1421:0370]
+ 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134
+ 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus
+ 61 -> Philips TOUGH DVB-T reference design
+ 62 -> Compro VideoMate TV Gold+II
+ 63 -> Kworld Xpert TV PVR7134
index aeb8df8ce8909fedf195283bb7cc78187f0ac90a..e78020f68b2e5ffb8382d4f309cf3b48187f4821 100644 (file)
@@ -59,3 +59,6 @@ tuner=57 - Philips FQ1236A MK4
 tuner=58 - Ymec TVision TVF-8531MF
 tuner=59 - Ymec TVision TVF-5533MF
 tuner=60 - Thomson DDT 7611 (ATSC/NTSC)
+tuner=61 - Tena TNF9533-D/IF
+tuner=62 - Philips TEA5767HN FM Radio
+tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner
index 1a446c65365e8792a6c496ff2216b8416fa0d426..1f788e498effe392cd48d0a907a88a6601bdea72 100644 (file)
@@ -57,6 +57,15 @@ Cards can use either of these two crystals (xtal):
  - 24.576MHz -> .audio_clock=0x200000
 (xtal * .audio_clock = 51539600)
 
+Some details about 30/34/35:
+
+ - saa7130 - low-price chip, doesn't have mute, that is why all those
+ cards should have .mute field defined in their tuner structure.
+
+ - saa7134 - usual chip
+
+ - saa7133/35 - saa7135 is probably a marketing decision, since all those
+ chips identifies itself as 33 on pci.
 
 Credits
 =======
index 4db63de9652a31ca8c83a25d562cacd8329072f4..19a9a1c530371a9328af010d96d2544e88289378 100644 (file)
@@ -512,11 +512,11 @@ W:        http://linuxppc64.org
 S:     Supported
 
 BTTV VIDEO4LINUX DRIVER
-P:     Gerd Knorr
-M:     kraxel@bytesex.org
+P:     Mauro Carvalho Chehab
+M:     mchehab@brturbo.com.br
 L:     video4linux-list@redhat.com
-W:     http://bytesex.org/bttv/
-S:     Orphan
+W:     http://linuxtv.org
+S:     Maintained
 
 BUSLOGIC SCSI DRIVER
 P:     Leonard N. Zubkoff
@@ -2625,10 +2625,11 @@ W:      http://rio500.sourceforge.net
 S:     Maintained
 
 VIDEO FOR LINUX
-P:     Gerd Knorr
-M:     kraxel@bytesex.org
+P:     Mauro Carvalho Chehab
+M:     mchehab@brturbo.com.br
 L:     video4linux-list@redhat.com
-S:     Orphan
+W:     http://linuxtv.org
+S:     Maintained
 
 W1 DALLAS'S 1-WIRE BUS
 P:     Evgeniy Polyakov
index c8d94dcd8ef7daed544f14d5ac2db98c0236c952..620f2ca94ed27390640abe911f0ab4a4bca20a1e 100644 (file)
@@ -361,6 +361,11 @@ config NO_IDLE_HZ
          Alternatively, if you want dynamic tick automatically enabled
          during boot, pass "dyntick=enable" via the kernel command string.
 
+         Please note that dynamic tick may affect the accuracy of
+         timekeeping on some platforms depending on the implementation.
+         Currently at least OMAP platform is known to have accurate
+         timekeeping with dynamic tick.
+
 config ARCH_DISCONTIGMEM_ENABLE
        bool
        default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
index b668c48f43990f3648f248f8c17399f884568b4f..cf9f46d88061819432925c4097673b8d458a9350 100644 (file)
  *   04-Nov-2004  Ben Dooks
  *               Fix standard IRQ wake for EINT0..4 and RTC
  *
- *   22-Feb-2004  Ben Dooks
+ *   22-Feb-2005  Ben Dooks
  *               Fixed edge-triggering on ADC IRQ
+ *
+ *   28-Jun-2005  Ben Dooks
+ *               Mark IRQ_LCD valid
 */
 
 #include <linux/init.h>
@@ -366,7 +369,6 @@ static struct irqchip s3c_irq_eint0t4 = {
 #define INTMSK_UART1    (1UL << (IRQ_UART1 - IRQ_EINT0))
 #define INTMSK_UART2    (1UL << (IRQ_UART2 - IRQ_EINT0))
 #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
-#define INTMSK_LCD      (1UL << (IRQ_LCD - IRQ_EINT0))
 
 static inline void
 s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
@@ -716,7 +718,6 @@ void __init s3c24xx_init_irq(void)
                case IRQ_UART0:
                case IRQ_UART1:
                case IRQ_UART2:
-               case IRQ_LCD:
                case IRQ_ADCPARENT:
                        set_irq_chip(irqno, &s3c_irq_level_chip);
                        set_irq_handler(irqno, do_level_IRQ);
index ba1a6e9f2b28a2f7315a707c975e03f6a38ccdc9..8ffb523e6c77345c097da32221aa5fdf3f34a58e 100644 (file)
@@ -6,6 +6,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
                oprofilefs.o oprofile_stats.o \
                timer_int.o )
 
-oprofile-y                             := $(DRIVER_OBJS) init.o
+oprofile-y                             := $(DRIVER_OBJS) init.o backtrace.o
 oprofile-$(CONFIG_CPU_XSCALE)          += common.o op_model_xscale.o
 
diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c
new file mode 100644 (file)
index 0000000..ec58d3e
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Arm specific backtracing code for oprofile
+ *
+ * Copyright 2005 Openedhand Ltd.
+ *
+ * Author: Richard Purdie <rpurdie@openedhand.com>
+ *
+ * Based on i386 oprofile backtrace code by John Levon, David Smith
+ *
+ * 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 <linux/oprofile.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+
+
+/*
+ * The registers we're interested in are at the end of the variable
+ * length saved register structure. The fp points at the end of this
+ * structure so the address of this struct is:
+ * (struct frame_tail *)(xxx->fp)-1
+ */
+struct frame_tail {
+       struct frame_tail *fp;
+       unsigned long sp;
+       unsigned long lr;
+} __attribute__((packed));
+
+
+#ifdef CONFIG_FRAME_POINTER
+static struct frame_tail* kernel_backtrace(struct frame_tail *tail)
+{
+       oprofile_add_trace(tail->lr);
+
+       /* frame pointers should strictly progress back up the stack
+        * (towards higher addresses) */
+       if (tail >= tail->fp)
+               return NULL;
+
+       return tail->fp-1;
+}
+#endif
+
+static struct frame_tail* user_backtrace(struct frame_tail *tail)
+{
+       struct frame_tail buftail;
+
+       /* hardware pte might not be valid due to dirty/accessed bit emulation
+        * so we use copy_from_user and benefit from exception fixups */
+       if (copy_from_user(&buftail, tail, sizeof(struct frame_tail)))
+               return NULL;
+
+       oprofile_add_trace(buftail.lr);
+
+       /* frame pointers should strictly progress back up the stack
+        * (towards higher addresses) */
+       if (tail >= buftail.fp)
+               return NULL;
+
+       return buftail.fp-1;
+}
+
+/* Compare two addresses and see if they're on the same page */
+#define CMP_ADDR_EQUAL(x,y,offset) ((((unsigned long) x) >> PAGE_SHIFT) \
+       == ((((unsigned long) y) + offset) >> PAGE_SHIFT))
+
+/* check that the page(s) containing the frame tail are present */
+static int pages_present(struct frame_tail *tail)
+{
+       struct mm_struct * mm = current->mm;
+
+       if (!check_user_page_readable(mm, (unsigned long)tail))
+               return 0;
+
+       if (CMP_ADDR_EQUAL(tail, tail, 8))
+               return 1;
+
+       if (!check_user_page_readable(mm, ((unsigned long)tail) + 8))
+               return 0;
+
+       return 1;
+}
+
+/*
+ * |             | /\ Higher addresses
+ * |             |
+ * --------------- stack base (address of current_thread_info)
+ * | thread info |
+ * .             .
+ * |    stack    |
+ * --------------- saved regs->ARM_fp value if valid (frame_tail address)
+ * .             .
+ * --------------- struct pt_regs stored on stack (struct pt_regs *)
+ * |             |
+ * .             .
+ * |             |
+ * --------------- %esp
+ * |             |
+ * |             | \/ Lower addresses
+ *
+ * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values
+ */
+static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs)
+{
+       unsigned long tailaddr = (unsigned long)tail;
+       unsigned long stack = (unsigned long)regs;
+       unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
+
+       return (tailaddr > stack) && (tailaddr < stack_base);
+}
+
+void arm_backtrace(struct pt_regs const *regs, unsigned int depth)
+{
+       struct frame_tail *tail;
+       unsigned long last_address = 0;
+
+       tail = ((struct frame_tail *) regs->ARM_fp) - 1;
+
+       if (!user_mode(regs)) {
+
+#ifdef CONFIG_FRAME_POINTER
+               while (depth-- && tail && valid_kernel_stack(tail, regs)) {
+                       tail = kernel_backtrace(tail);
+               }
+#endif
+               return;
+       }
+
+       while (depth-- && tail && !((unsigned long) tail & 3)) {
+               if ((!CMP_ADDR_EQUAL(last_address, tail, 0)
+                       || !CMP_ADDR_EQUAL(last_address, tail, 8))
+                               && !pages_present(tail))
+                       return;
+               last_address = (unsigned long) tail;
+               tail = user_backtrace(tail);
+       }
+}
+
index cce3d3015eb7999d79143d72eaa061ff98337e29..d315a3a86c8635aebe60c2508dab60e44394e63b 100644 (file)
@@ -20,6 +20,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
        ret = pmu_init(ops, &op_xscale_spec);
 #endif
 
+       ops->backtrace = arm_backtrace;
+
        return ret;
 }
 
index 2d4caf4781ad466d0f539878bc1462ecb730630d..2148d07484b7b5999b7f5402bef5aa1a5d9e24c4 100644 (file)
@@ -24,6 +24,8 @@ struct op_arm_model_spec {
 extern struct op_arm_model_spec op_xscale_spec;
 #endif
 
+extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth);
+
 extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
 extern void pmu_exit(void);
 #endif /* OP_ARM_MODEL_H */
index 4a17956512e1a279d1ea28f4209748df509b151a..6835f6d47c31e8f5913a670c6bd7bdd57f1e7b7c 100644 (file)
@@ -70,7 +70,8 @@ void usage(void)
 
 int main(int argc, char ** argv)
 {
-       unsigned int i, c, sz, setup_sectors;
+       unsigned int i, sz, setup_sectors;
+       int c;
        u32 sys_size;
        byte major_root, minor_root;
        struct stat sb;
index 9f63ae0f404b2586f4c24182b408b9fc1f944dba..b7808a89d94507fd41abf6c24bd471d5d9099209 100644 (file)
@@ -159,9 +159,15 @@ char *__acpi_map_table(unsigned long phys, unsigned long size)
 #endif
 
 #ifdef CONFIG_PCI_MMCONFIG
-static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
+/* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
+struct acpi_table_mcfg_config *pci_mmcfg_config;
+int pci_mmcfg_config_num;
+
+int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
 {
        struct acpi_table_mcfg *mcfg;
+       unsigned long i;
+       int config_size;
 
        if (!phys_addr || !size)
                return -EINVAL;
@@ -172,18 +178,38 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
                return -ENODEV;
        }
 
-       if (mcfg->base_reserved) {
-               printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n");
+       /* how many config structures do we have */
+       pci_mmcfg_config_num = 0;
+       i = size - sizeof(struct acpi_table_mcfg);
+       while (i >= sizeof(struct acpi_table_mcfg_config)) {
+               ++pci_mmcfg_config_num;
+               i -= sizeof(struct acpi_table_mcfg_config);
+       };
+       if (pci_mmcfg_config_num == 0) {
+               printk(KERN_ERR PREFIX "MMCONFIG has no entries\n");
                return -ENODEV;
        }
 
-       pci_mmcfg_base_addr = mcfg->base_address;
+       config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config);
+       pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL);
+       if (!pci_mmcfg_config) {
+               printk(KERN_WARNING PREFIX
+                      "No memory for MCFG config tables\n");
+               return -ENOMEM;
+       }
+
+       memcpy(pci_mmcfg_config, &mcfg->config, config_size);
+       for (i = 0; i < pci_mmcfg_config_num; ++i) {
+               if (mcfg->config[i].base_reserved) {
+                       printk(KERN_ERR PREFIX
+                              "MMCONFIG not in low 4GB of memory\n");
+                       return -ENODEV;
+               }
+       }
 
        return 0;
 }
-#else
-#define        acpi_parse_mcfg NULL
-#endif /* !CONFIG_PCI_MMCONFIG */
+#endif /* CONFIG_PCI_MMCONFIG */
 
 #ifdef CONFIG_X86_LOCAL_APIC
 static int __init
@@ -507,6 +533,22 @@ acpi_unmap_lsapic(int cpu)
 EXPORT_SYMBOL(acpi_unmap_lsapic);
 #endif /* CONFIG_ACPI_HOTPLUG_CPU */
 
+int
+acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
+{
+       /* TBD */
+       return -EINVAL;
+}
+EXPORT_SYMBOL(acpi_register_ioapic);
+
+int
+acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
+{
+       /* TBD */
+       return -EINVAL;
+}
+EXPORT_SYMBOL(acpi_unregister_ioapic);
+
 static unsigned long __init
 acpi_scan_rsdp (
        unsigned long           start,
@@ -1123,7 +1165,6 @@ int __init acpi_boot_init(void)
        acpi_process_madt();
 
        acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
-       acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
 
        return 0;
 }
index 720975e1af5046cdcef151f57e68e94fd2378d82..87325263cd4fbcdeb29994e69e96550b39981621 100644 (file)
@@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
 
 int pci_routeirq;
 int pcibios_last_bus = -1;
-struct pci_bus *pci_root_bus = NULL;
+unsigned long pirq_table_addr;
+struct pci_bus *pci_root_bus;
 struct pci_raw_ops *raw_pci_ops;
 
 static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
@@ -133,7 +134,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
 
        printk("PCI: Probing PCI hardware (bus %02x)\n", busnum);
 
-       return pci_scan_bus(busnum, &pci_root_ops, NULL);
+       return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL);
 }
 
 extern u8 pci_cache_line_size;
@@ -188,6 +189,9 @@ char * __devinit  pcibios_setup(char *str)
        } else if (!strcmp(str, "biosirq")) {
                pci_probe |= PCI_BIOS_IRQ_SCAN;
                return NULL;
+       } else if (!strncmp(str, "pirqaddr=", 9)) {
+               pirq_table_addr = simple_strtoul(str+9, NULL, 0);
+               return NULL;
        }
 #endif
 #ifdef CONFIG_PCI_DIRECT
index 83458f81e661ef7283936565e396f594780137e6..78ca1ecbb90728dad8e56b199550bfca66ac9d35 100644 (file)
@@ -57,6 +57,35 @@ struct irq_router_handler {
 
 int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
 
+/*
+ *  Check passed address for the PCI IRQ Routing Table signature
+ *  and perform checksum verification.
+ */
+
+static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr)
+{
+       struct irq_routing_table *rt;
+       int i;
+       u8 sum;
+
+       rt = (struct irq_routing_table *) addr;
+       if (rt->signature != PIRQ_SIGNATURE ||
+           rt->version != PIRQ_VERSION ||
+           rt->size % 16 ||
+           rt->size < sizeof(struct irq_routing_table))
+               return NULL;
+       sum = 0;
+       for (i=0; i < rt->size; i++)
+               sum += addr[i];
+       if (!sum) {
+               DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+               return rt;
+       }
+       return NULL;
+}
+
+
+
 /*
  *  Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
  */
@@ -65,23 +94,17 @@ static struct irq_routing_table * __init pirq_find_routing_table(void)
 {
        u8 *addr;
        struct irq_routing_table *rt;
-       int i;
-       u8 sum;
 
+       if (pirq_table_addr) {
+               rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
+               if (rt)
+                       return rt;
+               printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
+       }
        for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
-               rt = (struct irq_routing_table *) addr;
-               if (rt->signature != PIRQ_SIGNATURE ||
-                   rt->version != PIRQ_VERSION ||
-                   rt->size % 16 ||
-                   rt->size < sizeof(struct irq_routing_table))
-                       continue;
-               sum = 0;
-               for(i=0; i<rt->size; i++)
-                       sum += addr[i];
-               if (!sum) {
-                       DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+               rt = pirq_check_routing_table(addr);
+               if (rt)
                        return rt;
-               }
        }
        return NULL;
 }
index 1492e375386908fd350ed50f52879ce6f5b853b6..149a9588c256797c1032c6f6cc1b1fa9645b2b3b 100644 (file)
@@ -45,6 +45,8 @@ static int __init pci_legacy_init(void)
 
        printk("PCI: Probing PCI hardware\n");
        pci_root_bus = pcibios_scan_root(0);
+       if (pci_root_bus)
+               pci_bus_add_devices(pci_root_bus);
 
        pcibios_fixup_peer_bridges();
 
index 021a50aa51f432020f23dcb27f6c927d6a3d639f..60f0e7a1162aafa3be94b2806384106dc1aee172 100644 (file)
 
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/acpi.h>
 #include "pci.h"
 
-/* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
-u32 pci_mmcfg_base_addr;
-
 #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
 
 /* The base address of the last MMCONFIG device accessed */
@@ -24,10 +22,31 @@ static u32 mmcfg_last_accessed_device;
 /*
  * Functions for accessing PCI configuration space with MMCONFIG accesses
  */
+static u32 get_base_addr(unsigned int seg, int bus)
+{
+       int cfg_num = -1;
+       struct acpi_table_mcfg_config *cfg;
+
+       while (1) {
+               ++cfg_num;
+               if (cfg_num >= pci_mmcfg_config_num) {
+                       /* something bad is going on, no cfg table is found. */
+                       /* so we fall back to the old way we used to do this */
+                       /* and just rely on the first entry to be correct. */
+                       return pci_mmcfg_config[0].base_address;
+               }
+               cfg = &pci_mmcfg_config[cfg_num];
+               if (cfg->pci_segment_group_number != seg)
+                       continue;
+               if ((cfg->start_bus_number <= bus) &&
+                   (cfg->end_bus_number >= bus))
+                       return cfg->base_address;
+       }
+}
 
-static inline void pci_exp_set_dev_base(int bus, int devfn)
+static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn)
 {
-       u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12);
+       u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12);
        if (dev_base != mmcfg_last_accessed_device) {
                mmcfg_last_accessed_device = dev_base;
                set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);
@@ -44,7 +63,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
 
        spin_lock_irqsave(&pci_config_lock, flags);
 
-       pci_exp_set_dev_base(bus, devfn);
+       pci_exp_set_dev_base(seg, bus, devfn);
 
        switch (len) {
        case 1:
@@ -73,7 +92,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 
        spin_lock_irqsave(&pci_config_lock, flags);
 
-       pci_exp_set_dev_base(bus, devfn);
+       pci_exp_set_dev_base(seg, bus, devfn);
 
        switch (len) {
        case 1:
@@ -101,7 +120,11 @@ static int __init pci_mmcfg_init(void)
 {
        if ((pci_probe & PCI_PROBE_MMCONF) == 0)
                goto out;
-       if (!pci_mmcfg_base_addr)
+
+       acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
+       if ((pci_mmcfg_config_num == 0) ||
+           (pci_mmcfg_config == NULL) ||
+           (pci_mmcfg_config[0].base_address == 0))
                goto out;
 
        /* Kludge for now. Don't use mmconfig on AMD systems because
index 9e3695461899b1c5498d25a3006b23cfd40aec89..adbe17a38f6f932cb8e238767f85eab12632a2d6 100644 (file)
@@ -115,6 +115,8 @@ static int __init pci_numa_init(void)
                return 0;
 
        pci_root_bus = pcibios_scan_root(0);
+       if (pci_root_bus)
+               pci_bus_add_devices(pci_root_bus);
        if (num_online_nodes() > 1)
                for_each_online_node(quad) {
                        if (quad == 0)
index a8fc80ca69f309205371940dc35be6ddebb0d797..a80f0f55ff51b0dcea1c1d33670c5baae924a541 100644 (file)
@@ -27,6 +27,7 @@
 #define PCI_ASSIGN_ALL_BUSSES  0x4000
 
 extern unsigned int pci_probe;
+extern unsigned long pirq_table_addr;
 
 /* pci-i386.c */
 
index 72dfd9e7de0ffc470e3922fab11927b8e3fd0916..cda06f88c66eb9ae28c79973f4882deda9545205 100644 (file)
@@ -236,9 +236,7 @@ acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end)
        if (BAD_MADT_ENTRY(iosapic, end))
                return -EINVAL;
 
-       iosapic_init(iosapic->address, iosapic->global_irq_base);
-
-       return 0;
+       return iosapic_init(iosapic->address, iosapic->global_irq_base);
 }
 
 
@@ -772,7 +770,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic);
  
 
 #ifdef CONFIG_ACPI_NUMA
-acpi_status __init
+acpi_status __devinit
 acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
 {
        struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
@@ -825,4 +823,28 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
        return AE_OK;
 }
 #endif /* CONFIG_NUMA */
+
+int
+acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base)
+{
+       int err;
+
+       if ((err = iosapic_init(phys_addr, gsi_base)))
+               return err;
+
+#if CONFIG_ACPI_NUMA
+       acpi_map_iosapic(handle, 0, NULL, NULL);
+#endif /* CONFIG_ACPI_NUMA */
+
+       return 0;
+}
+EXPORT_SYMBOL(acpi_register_ioapic);
+
+int
+acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base)
+{
+       return iosapic_remove(gsi_base);
+}
+EXPORT_SYMBOL(acpi_unregister_ioapic);
+
 #endif /* CONFIG_ACPI_BOOT */
index 88b014381df5f8b11a73e8652d88757b0692cdf0..c170be095ccdcd56ea16aa0b3cfd087c949a26df 100644 (file)
@@ -129,14 +129,13 @@ static struct iosapic {
        char __iomem    *addr;          /* base address of IOSAPIC */
        unsigned int    gsi_base;       /* first GSI assigned to this IOSAPIC */
        unsigned short  num_rte;        /* number of RTE in this IOSAPIC */
+       int             rtes_inuse;     /* # of RTEs in use on this IOSAPIC */
 #ifdef CONFIG_NUMA
        unsigned short  node;           /* numa node association via pxm */
 #endif
 } iosapic_lists[NR_IOSAPICS];
 
-static int num_iosapic;
-
-static unsigned char pcat_compat __initdata;   /* 8259 compatibility flag */
+static unsigned char pcat_compat __devinitdata;        /* 8259 compatibility flag */
 
 static int iosapic_kmalloc_ok;
 static LIST_HEAD(free_rte_list);
@@ -149,7 +148,7 @@ find_iosapic (unsigned int gsi)
 {
        int i;
 
-       for (i = 0; i < num_iosapic; i++) {
+       for (i = 0; i < NR_IOSAPICS; i++) {
                if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte)
                        return i;
        }
@@ -598,6 +597,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
                rte->refcnt++;
                list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes);
                iosapic_intr_info[vector].count++;
+               iosapic_lists[index].rtes_inuse++;
        }
        else if (vector_is_shared(vector)) {
                struct iosapic_intr_info *info = &iosapic_intr_info[vector];
@@ -778,7 +778,7 @@ void
 iosapic_unregister_intr (unsigned int gsi)
 {
        unsigned long flags;
-       int irq, vector;
+       int irq, vector, index;
        irq_desc_t *idesc;
        u32 low32;
        unsigned long trigger, polarity;
@@ -819,6 +819,9 @@ iosapic_unregister_intr (unsigned int gsi)
                list_del(&rte->rte_list);
                iosapic_intr_info[vector].count--;
                iosapic_free_rte(rte);
+               index = find_iosapic(gsi);
+               iosapic_lists[index].rtes_inuse--;
+               WARN_ON(iosapic_lists[index].rtes_inuse < 0);
 
                trigger  = iosapic_intr_info[vector].trigger;
                polarity = iosapic_intr_info[vector].polarity;
@@ -952,30 +955,86 @@ iosapic_system_init (int system_pcat_compat)
        }
 }
 
-void __init
+static inline int
+iosapic_alloc (void)
+{
+       int index;
+
+       for (index = 0; index < NR_IOSAPICS; index++)
+               if (!iosapic_lists[index].addr)
+                       return index;
+
+       printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__);
+       return -1;
+}
+
+static inline void
+iosapic_free (int index)
+{
+       memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0]));
+}
+
+static inline int
+iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver)
+{
+       int index;
+       unsigned int gsi_end, base, end;
+
+       /* check gsi range */
+       gsi_end = gsi_base + ((ver >> 16) & 0xff);
+       for (index = 0; index < NR_IOSAPICS; index++) {
+               if (!iosapic_lists[index].addr)
+                       continue;
+
+               base = iosapic_lists[index].gsi_base;
+               end  = base + iosapic_lists[index].num_rte - 1;
+
+               if (gsi_base < base && gsi_end < base)
+                       continue;/* OK */
+
+               if (gsi_base > end && gsi_end > end)
+                       continue; /* OK */
+
+               return -EBUSY;
+       }
+       return 0;
+}
+
+int __devinit
 iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
 {
-       int num_rte;
+       int num_rte, err, index;
        unsigned int isa_irq, ver;
        char __iomem *addr;
+       unsigned long flags;
+
+       spin_lock_irqsave(&iosapic_lock, flags);
+       {
+               addr = ioremap(phys_addr, 0);
+               ver = iosapic_version(addr);
 
-       addr = ioremap(phys_addr, 0);
-       ver = iosapic_version(addr);
+               if ((err = iosapic_check_gsi_range(gsi_base, ver))) {
+                       iounmap(addr);
+                       spin_unlock_irqrestore(&iosapic_lock, flags);
+                       return err;
+               }
 
-       /*
-        * The MAX_REDIR register holds the highest input pin
-        * number (starting from 0).
-        * We add 1 so that we can use it for number of pins (= RTEs)
-        */
-       num_rte = ((ver >> 16) & 0xff) + 1;
+               /*
+                * The MAX_REDIR register holds the highest input pin
+                * number (starting from 0).
+                * We add 1 so that we can use it for number of pins (= RTEs)
+                */
+               num_rte = ((ver >> 16) & 0xff) + 1;
 
-       iosapic_lists[num_iosapic].addr = addr;
-       iosapic_lists[num_iosapic].gsi_base = gsi_base;
-       iosapic_lists[num_iosapic].num_rte = num_rte;
+               index = iosapic_alloc();
+               iosapic_lists[index].addr = addr;
+               iosapic_lists[index].gsi_base = gsi_base;
+               iosapic_lists[index].num_rte = num_rte;
 #ifdef CONFIG_NUMA
-       iosapic_lists[num_iosapic].node = MAX_NUMNODES;
+               iosapic_lists[index].node = MAX_NUMNODES;
 #endif
-       num_iosapic++;
+       }
+       spin_unlock_irqrestore(&iosapic_lock, flags);
 
        if ((gsi_base == 0) && pcat_compat) {
                /*
@@ -986,10 +1045,43 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
                for (isa_irq = 0; isa_irq < 16; ++isa_irq)
                        iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
        }
+       return 0;
+}
+
+#ifdef CONFIG_HOTPLUG
+int
+iosapic_remove (unsigned int gsi_base)
+{
+       int index, err = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&iosapic_lock, flags);
+       {
+               index = find_iosapic(gsi_base);
+               if (index < 0) {
+                       printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n",
+                              __FUNCTION__, gsi_base);
+                       goto out;
+               }
+
+               if (iosapic_lists[index].rtes_inuse) {
+                       err = -EBUSY;
+                       printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n",
+                              __FUNCTION__, gsi_base);
+                       goto out;
+               }
+
+               iounmap(iosapic_lists[index].addr);
+               iosapic_free(index);
+       }
+ out:
+       spin_unlock_irqrestore(&iosapic_lock, flags);
+       return err;
 }
+#endif /* CONFIG_HOTPLUG */
 
 #ifdef CONFIG_NUMA
-void __init
+void __devinit
 map_iosapic_to_node(unsigned int gsi_base, int node)
 {
        int index;
index e3fc4edea113a89855b8024acb4a8446b62e1674..720a861f88be283675a5b568bbf8837950e31d72 100644 (file)
@@ -312,7 +312,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
        acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window,
                        &info);
 
-       pbus = pci_scan_bus(bus, &pci_root_ops, controller);
+       pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);
        if (pbus)
                pcibios_setup_root_windows(pbus, controller);
 
@@ -373,6 +373,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev,
        res->end = region->end + offset;
 }
 
+static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
+{
+       unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
+       struct resource *devr = &dev->resource[idx];
+
+       if (!dev->bus)
+               return 0;
+       for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
+               struct resource *busr = dev->bus->resource[i];
+
+               if (!busr || ((busr->flags ^ devr->flags) & type_mask))
+                       continue;
+               if ((devr->start) && (devr->start >= busr->start) &&
+                               (devr->end <= busr->end))
+                       return 1;
+       }
+       return 0;
+}
+
 static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
 {
        struct pci_bus_region region;
@@ -386,7 +405,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
                region.start = dev->resource[i].start;
                region.end = dev->resource[i].end;
                pcibios_bus_to_resource(dev, &dev->resource[i], &region);
-               pci_claim_resource(dev, i);
+               if ((is_valid_resource(dev, i)))
+                       pci_claim_resource(dev, i);
        }
 }
 
@@ -398,6 +418,10 @@ pcibios_fixup_bus (struct pci_bus *b)
 {
        struct pci_dev *dev;
 
+       if (b->self) {
+               pci_read_bridge_bases(b);
+               pcibios_fixup_device_resources(b->self);
+       }
        list_for_each_entry(dev, &b->devices, bus_list)
                pcibios_fixup_device_resources(dev);
 
@@ -418,18 +442,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
        u16 cmd, old_cmd;
        int idx;
        struct resource *r;
+       unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
 
        if (!dev)
                return -EINVAL;
 
        pci_read_config_word(dev, PCI_COMMAND, &cmd);
        old_cmd = cmd;
-       for (idx=0; idx<6; idx++) {
+       for (idx=0; idx<PCI_NUM_RESOURCES; idx++) {
                /* Only set up the desired resources.  */
                if (!(mask & (1 << idx)))
                        continue;
 
                r = &dev->resource[idx];
+               if (!(r->flags & type_mask))
+                       continue;
+               if ((idx == PCI_ROM_RESOURCE) &&
+                               (!(r->flags & IORESOURCE_ROM_ENABLE)))
+                       continue;
                if (!r->start && r->end) {
                        printk(KERN_ERR
                               "PCI: Device %s not available because of resource collisions\n",
@@ -441,8 +471,6 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
                if (r->flags & IORESOURCE_MEM)
                        cmd |= PCI_COMMAND_MEMORY;
        }
-       if (dev->resource[PCI_ROM_RESOURCE].start)
-               cmd |= PCI_COMMAND_MEMORY;
        if (cmd != old_cmd) {
                printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
                pci_write_config_word(dev, PCI_COMMAND, cmd);
index 6d7b92d724582c87b9bd23b7e54752191c269666..70cfb6ffd877d8a9007abc859d0f4e87d40dd3f5 100644 (file)
@@ -1495,7 +1495,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
                *offset += hose->pci_mem_offset;
                res_bit = IORESOURCE_MEM;
        } else {
-               io_offset = (unsigned long)hose->io_base_virt;
+               io_offset = hose->io_base_virt - ___IO_BASE;
                *offset += io_offset;
                res_bit = IORESOURCE_IO;
        }
@@ -1522,7 +1522,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
 
                /* found it! construct the final physical address */
                if (mmap_state == pci_mmap_io)
-                       *offset += hose->io_base_phys - _IO_BASE;
+                       *offset += hose->io_base_phys - io_offset;
                return rp;
        }
 
@@ -1739,6 +1739,23 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
        return result;
 }
 
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+                         const struct resource *rsrc,
+                         u64 *start, u64 *end)
+{
+       struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
+       unsigned long offset = 0;
+
+       if (hose == NULL)
+               return;
+
+       if (rsrc->flags & IORESOURCE_IO)
+               offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys;
+
+       *start = rsrc->start + offset;
+       *end = rsrc->end + offset;
+}
+
 void __init
 pci_init_resource(struct resource *res, unsigned long start, unsigned long end,
                  int flags, char *name)
index 3defc8c33adf567ad95988ec077174c992dc6ac3..ffe300611f0042891498d08b458a2978437985a9 100644 (file)
@@ -245,7 +245,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
 
                spin_lock(&desc->lock);
                if (!noirqdebug)
-                       note_interrupt(irq, desc, action_ret);
+                       note_interrupt(irq, desc, action_ret, regs);
                if (likely(!(desc->status & IRQ_PENDING)))
                        break;
                desc->status &= ~IRQ_PENDING;
index 580676f87d23a11a33a85f0b0f21417c52803d84..ae6f579d3fa0f0f41cffa6e5c78c439ac430723b 100644 (file)
@@ -351,7 +351,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
                *offset += hose->pci_mem_offset;
                res_bit = IORESOURCE_MEM;
        } else {
-               io_offset = (unsigned long)hose->io_base_virt;
+               io_offset = (unsigned long)hose->io_base_virt - pci_io_base;
                *offset += io_offset;
                res_bit = IORESOURCE_IO;
        }
@@ -378,7 +378,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
 
                /* found it! construct the final physical address */
                if (mmap_state == pci_mmap_io)
-                       *offset += hose->io_base_phys - io_offset;
+                       *offset += hose->io_base_phys - io_offset;
                return rp;
        }
 
@@ -944,4 +944,22 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
 }
 EXPORT_SYMBOL(pci_read_irq_line);
 
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+                         const struct resource *rsrc,
+                         u64 *start, u64 *end)
+{
+       struct pci_controller *hose = pci_bus_to_host(dev->bus);
+       unsigned long offset = 0;
+
+       if (hose == NULL)
+               return;
+
+       if (rsrc->flags & IORESOURCE_IO)
+               offset = pci_io_base - (unsigned long)hose->io_base_virt +
+                       hose->io_base_phys;
+
+       *start = rsrc->start + offset;
+       *end = rsrc->end + offset;
+}
+
 #endif /* CONFIG_PPC_MULTIPLATFORM */
index 262e13d086fefdb23c63e73ac89c28fb619b2e82..7a117ef473c5f46c64d711a2753c1e7a1abf5327 100644 (file)
@@ -270,66 +270,10 @@ endmenu
 
 source "drivers/Kconfig"
 
-config PRINTER
-       tristate "Parallel printer support"
-       depends on PARPORT
-       ---help---
-         If you intend to attach a printer to the parallel port of your Linux
-         box (as opposed to using a serial printer; if the connector at the
-         printer has 9 or 25 holes ["female"], then it's serial), say Y.
-         Also read the Printing-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         It is possible to share one parallel port among several devices
-         (e.g. printer and ZIP drive) and it is safe to compile the
-         corresponding drivers into the kernel.  If you want to compile this
-         driver as a module however, choose M here and read
-         <file:Documentation/parport.txt>.  The module will be called lp.
-
-         If you have several parallel ports, you can specify which ports to
-         use with the "lp" kernel command line option.  (Try "man bootparam"
-         or see the documentation of your boot loader (silo) about how to pass
-         options to the kernel at boot time.)  The syntax of the "lp" command
-         line option can be found in <file:drivers/char/lp.c>.
-
-         If you have more than 8 printers, you need to increase the LP_NO
-         macro in lp.c and the PARPORT_MAX macro in parport.h.
-
-source "mm/Kconfig"
-
-endmenu
-
-source "drivers/base/Kconfig"
-
-source "drivers/video/Kconfig"
-
-source "drivers/mtd/Kconfig"
-
-source "drivers/serial/Kconfig"
-
 if !SUN4
 source "drivers/sbus/char/Kconfig"
 endif
 
-source "drivers/block/Kconfig"
-
-# Don't frighten a common SBus user
-if PCI
-
-source "drivers/ide/Kconfig"
-
-endif
-
-source "drivers/isdn/Kconfig"
-
-source "drivers/scsi/Kconfig"
-
-source "drivers/fc4/Kconfig"
-
-source "drivers/md/Kconfig"
-
-source "net/Kconfig"
-
 # This one must be before the filesystem configs. -DaveM
 
 menu "Unix98 PTY support"
index b693c232fd0737c18af22dae138dfb93754f040e..657e88aa09022ba67df0fcc8dca7d20e44ecef53 100644 (file)
@@ -7,25 +7,50 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/acpi.h>
 #include "pci.h"
 
 #define MMCONFIG_APER_SIZE (256*1024*1024)
 
-/* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
-u32 pci_mmcfg_base_addr;
-
 /* Static virtual mapping of the MMCONFIG aperture */
-char *pci_mmcfg_virt;
+struct mmcfg_virt {
+       struct acpi_table_mcfg_config *cfg;
+       char *virt;
+};
+static struct mmcfg_virt *pci_mmcfg_virt;
 
-static inline char *pci_dev_base(unsigned int bus, unsigned int devfn)
+static char *get_virt(unsigned int seg, int bus)
 {
-       return pci_mmcfg_virt + ((bus << 20) | (devfn << 12));
+       int cfg_num = -1;
+       struct acpi_table_mcfg_config *cfg;
+
+       while (1) {
+               ++cfg_num;
+               if (cfg_num >= pci_mmcfg_config_num) {
+                       /* something bad is going on, no cfg table is found. */
+                       /* so we fall back to the old way we used to do this */
+                       /* and just rely on the first entry to be correct. */
+                       return pci_mmcfg_virt[0].virt;
+               }
+               cfg = pci_mmcfg_virt[cfg_num].cfg;
+               if (cfg->pci_segment_group_number != seg)
+                       continue;
+               if ((cfg->start_bus_number <= bus) &&
+                   (cfg->end_bus_number >= bus))
+                       return pci_mmcfg_virt[cfg_num].virt;
+       }
+}
+
+static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
+{
+
+       return get_virt(seg, bus) + ((bus << 20) | (devfn << 12));
 }
 
 static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
                          unsigned int devfn, int reg, int len, u32 *value)
 {
-       char *addr = pci_dev_base(bus, devfn); 
+       char *addr = pci_dev_base(seg, bus, devfn);
 
        if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
                return -EINVAL;
@@ -48,7 +73,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
 static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
                           unsigned int devfn, int reg, int len, u32 value)
 {
-       char *addr = pci_dev_base(bus,devfn);
+       char *addr = pci_dev_base(seg, bus, devfn);
 
        if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
                return -EINVAL;
@@ -75,9 +100,15 @@ static struct pci_raw_ops pci_mmcfg = {
 
 static int __init pci_mmcfg_init(void)
 {
+       int i;
+
        if ((pci_probe & PCI_PROBE_MMCONF) == 0)
                return 0;
-       if (!pci_mmcfg_base_addr)
+
+       acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
+       if ((pci_mmcfg_config_num == 0) ||
+           (pci_mmcfg_config == NULL) ||
+           (pci_mmcfg_config[0].base_address == 0))
                return 0;
 
        /* Kludge for now. Don't use mmconfig on AMD systems because
@@ -88,13 +119,22 @@ static int __init pci_mmcfg_init(void)
                return 0; 
 
        /* RED-PEN i386 doesn't do _nocache right now */
-       pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE);
-       if (!pci_mmcfg_virt) { 
-               printk("PCI: Cannot map mmconfig aperture\n");
+       pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
+       if (pci_mmcfg_virt == NULL) {
+               printk("PCI: Can not allocate memory for mmconfig structures\n");
                return 0;
-       }       
+       }
+       for (i = 0; i < pci_mmcfg_config_num; ++i) {
+               pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
+               pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE);
+               if (!pci_mmcfg_virt[i].virt) {
+                       printk("PCI: Cannot map mmconfig aperture for segment %d\n",
+                              pci_mmcfg_config[i].pci_segment_group_number);
+                       return 0;
+               }
+               printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address);
+       }
 
-       printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr);
        raw_pci_ops = &pci_mmcfg;
        pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
 
index 5a0adbf8bc04545c51139156ae5eb5caad772691..97013ddfa202b5d01678778d8443b0eba6cbfe64 100644 (file)
@@ -153,7 +153,7 @@ container_device_add(struct acpi_device **device, acpi_handle handle)
                return_VALUE(-ENODEV);
        }
 
-       result = acpi_bus_scan(*device);
+       result = acpi_bus_start(*device);
 
        return_VALUE(result);
 }
index 5d19b39e9e2b1b94226aa58b50c4550cccc1ac35..5148f3c10b5cf268d56fd0562f59ab7c538937f0 100644 (file)
@@ -61,15 +61,14 @@ acpi_pci_data_handler (
 
 
 /**
- * acpi_os_get_pci_id
+ * acpi_get_pci_id
  * ------------------
  * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem)
  * to resolve PCI information for ACPI-PCI devices defined in the namespace.
  * This typically occurs when resolving PCI operation region information.
  */
-#ifdef ACPI_FUTURE_USAGE
 acpi_status
-acpi_os_get_pci_id (
+acpi_get_pci_id (
        acpi_handle             handle,
        struct acpi_pci_id      *id)
 {
@@ -78,7 +77,7 @@ acpi_os_get_pci_id (
        struct acpi_device      *device = NULL;
        struct acpi_pci_data    *data = NULL;
 
-       ACPI_FUNCTION_TRACE("acpi_os_get_pci_id");
+       ACPI_FUNCTION_TRACE("acpi_get_pci_id");
 
        if (!id)
                return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -92,7 +91,7 @@ acpi_os_get_pci_id (
        }
 
        status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data);
-       if (ACPI_FAILURE(status) || !data || !data->dev) {
+       if (ACPI_FAILURE(status) || !data) {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
                        "Invalid ACPI-PCI context for device %s\n",
                        acpi_device_bid(device)));
@@ -115,7 +114,7 @@ acpi_os_get_pci_id (
 
        return_ACPI_STATUS(AE_OK);
 }
-#endif  /*  ACPI_FUTURE_USAGE  */
+EXPORT_SYMBOL(acpi_get_pci_id);
 
        
 int
@@ -129,6 +128,8 @@ acpi_pci_bind (
        char                    *pathname = NULL;
        struct acpi_buffer      buffer = {0, NULL};
        acpi_handle             handle = NULL;
+       struct pci_dev          *dev;
+       struct pci_bus          *bus;
 
        ACPI_FUNCTION_TRACE("acpi_pci_bind");
 
@@ -193,8 +194,20 @@ acpi_pci_bind (
         * Locate matching device in PCI namespace.  If it doesn't exist
         * this typically means that the device isn't currently inserted
         * (e.g. docking station, port replicator, etc.).
+        * We cannot simply search the global pci device list, since
+        * PCI devices are added to the global pci list when the root
+        * bridge start ops are run, which may not have happened yet.
         */
-       data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function));
+       bus = pci_find_bus(data->id.segment, data->id.bus);
+       if (bus) {
+               list_for_each_entry(dev, &bus->devices, bus_list) {
+                       if (dev->devfn == PCI_DEVFN(data->id.device,
+                                               data->id.function)) {
+                               data->dev = dev;
+                               break;
+                       }
+               }
+       }
        if (!data->dev) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
                        "Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
index 7e6b8e3b2ed418e15af1c0cad4eabb6b01e02031..5d2f77fcd50c7a2992a3f7957a1862ac33da1f8d 100644 (file)
@@ -46,6 +46,7 @@ ACPI_MODULE_NAME              ("pci_root")
 
 static int acpi_pci_root_add (struct acpi_device *device);
 static int acpi_pci_root_remove (struct acpi_device *device, int type);
+static int acpi_pci_root_start (struct acpi_device *device);
 
 static struct acpi_driver acpi_pci_root_driver = {
        .name =         ACPI_PCI_ROOT_DRIVER_NAME,
@@ -54,6 +55,7 @@ static struct acpi_driver acpi_pci_root_driver = {
        .ops =          {
                                .add =    acpi_pci_root_add,
                                .remove = acpi_pci_root_remove,
+                               .start =  acpi_pci_root_start,
                        },
 };
 
@@ -169,6 +171,7 @@ acpi_pci_root_add (
        if (!root)
                return_VALUE(-ENOMEM);
        memset(root, 0, sizeof(struct acpi_pci_root));
+       INIT_LIST_HEAD(&root->node);
 
        root->handle = device->handle;
        strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
@@ -298,12 +301,31 @@ acpi_pci_root_add (
                        root->id.bus);
 
 end:
-       if (result)
+       if (result) {
+               if (!list_empty(&root->node))
+                       list_del(&root->node);
                kfree(root);
+       }
 
        return_VALUE(result);
 }
 
+static int
+acpi_pci_root_start (
+       struct acpi_device      *device)
+{
+       struct acpi_pci_root    *root;
+
+       ACPI_FUNCTION_TRACE("acpi_pci_root_start");
+
+       list_for_each_entry(root, &acpi_pci_roots, node) {
+               if (root->handle == device->handle) {
+                       pci_bus_add_devices(root->bus);
+                       return_VALUE(0);
+               }
+       }
+       return_VALUE(-ENODEV);
+}
 
 static int
 acpi_pci_root_remove (
index f4778747e889bd6dae32f77287b3580a042081b1..76156ac91bd36b49b62a7232b48432254e71be50 100644 (file)
@@ -723,7 +723,7 @@ int acpi_processor_device_add(
                return_VALUE(-ENODEV);
        }
 
-       acpi_bus_scan(*device);
+       acpi_bus_start(*device);
 
        pr = acpi_driver_data(*device);
        if (!pr)
index e85885593280dde6313df7ac701785c23511ecb0..337d49b5564bb6130a712d84eb854d5d586aba06 100644 (file)
@@ -553,20 +553,29 @@ acpi_bus_driver_init (
         * upon possible configuration and currently allocated resources.
         */
 
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
+       return_VALUE(0);
+}
+
+int
+acpi_start_single_object (
+               struct acpi_device *device)
+{
+       int result = 0;
+       struct acpi_driver *driver;
+
+       ACPI_FUNCTION_TRACE("acpi_start_single_object");
+
+       if (!(driver = device->driver))
+               return_VALUE(0);
+
        if (driver->ops.start) {
                result = driver->ops.start(device);
                if (result && driver->ops.remove)
                        driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
-               return_VALUE(result);
        }
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
-
-       if (driver->ops.scan) {
-               driver->ops.scan(device);
-       }
-
-       return_VALUE(0);
+       return_VALUE(result);
 }
 
 static int acpi_driver_attach(struct acpi_driver * drv)
@@ -586,6 +595,7 @@ static int acpi_driver_attach(struct acpi_driver * drv)
 
                if (!acpi_bus_match(dev, drv)) {
                        if (!acpi_bus_driver_init(dev, drv)) {
+                               acpi_start_single_object(dev);
                                atomic_inc(&drv->references);
                                count++;
                                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
@@ -1009,8 +1019,8 @@ acpi_bus_remove (
 }
 
 
-int
-acpi_bus_add (
+static int
+acpi_add_single_object (
        struct acpi_device      **child,
        struct acpi_device      *parent,
        acpi_handle             handle,
@@ -1019,7 +1029,7 @@ acpi_bus_add (
        int                     result = 0;
        struct acpi_device      *device = NULL;
 
-       ACPI_FUNCTION_TRACE("acpi_bus_add");
+       ACPI_FUNCTION_TRACE("acpi_add_single_object");
 
        if (!child)
                return_VALUE(-EINVAL);
@@ -1140,7 +1150,7 @@ acpi_bus_add (
         *
         * TBD: Assumes LDM provides driver hot-plug capability.
         */
-       acpi_bus_find_driver(device);
+       result = acpi_bus_find_driver(device);
 
 end:
        if (!result)
@@ -1153,10 +1163,10 @@ end:
 
        return_VALUE(result);
 }
-EXPORT_SYMBOL(acpi_bus_add);
 
 
-int acpi_bus_scan (struct acpi_device  *start)
+static int acpi_bus_scan (struct acpi_device   *start,
+               struct acpi_bus_ops *ops)
 {
        acpi_status             status = AE_OK;
        struct acpi_device      *parent = NULL;
@@ -1229,9 +1239,20 @@ int acpi_bus_scan (struct acpi_device    *start)
                        continue;
                }
 
-               status = acpi_bus_add(&child, parent, chandle, type);
-               if (ACPI_FAILURE(status))
-                       continue;
+               if (ops->acpi_op_add)
+                       status = acpi_add_single_object(&child, parent,
+                                       chandle, type);
+                else
+                       status = acpi_bus_get_device(chandle, &child);
+
+                if (ACPI_FAILURE(status))
+                        continue;
+
+               if (ops->acpi_op_start) {
+                       status = acpi_start_single_object(child);
+                       if (ACPI_FAILURE(status))
+                               continue;
+               }
 
                /*
                 * If the device is present, enabled, and functioning then
@@ -1257,8 +1278,50 @@ int acpi_bus_scan (struct acpi_device    *start)
 
        return_VALUE(0);
 }
-EXPORT_SYMBOL(acpi_bus_scan);
 
+int
+acpi_bus_add (
+       struct acpi_device      **child,
+       struct acpi_device      *parent,
+       acpi_handle             handle,
+       int                     type)
+{
+       int result;
+       struct acpi_bus_ops ops;
+
+       ACPI_FUNCTION_TRACE("acpi_bus_add");
+
+       result = acpi_add_single_object(child, parent, handle, type);
+       if (!result) {
+               memset(&ops, 0, sizeof(ops));
+               ops.acpi_op_add = 1;
+               result = acpi_bus_scan(*child, &ops);
+       }
+       return_VALUE(result);
+}
+EXPORT_SYMBOL(acpi_bus_add);
+
+int
+acpi_bus_start (
+       struct acpi_device *device)
+{
+       int result;
+       struct acpi_bus_ops ops;
+
+       ACPI_FUNCTION_TRACE("acpi_bus_start");
+
+       if (!device)
+               return_VALUE(-EINVAL);
+
+       result = acpi_start_single_object(device);
+       if (!result) {
+               memset(&ops, 0, sizeof(ops));
+               ops.acpi_op_start = 1;
+               result = acpi_bus_scan(device, &ops);
+       }
+       return_VALUE(result);
+}
+EXPORT_SYMBOL(acpi_bus_start);
 
 static int
 acpi_bus_trim(struct acpi_device       *start,
@@ -1331,13 +1394,19 @@ acpi_bus_scan_fixed (
        /*
         * Enumerate all fixed-feature devices.
         */
-       if (acpi_fadt.pwr_button == 0)
-               result = acpi_bus_add(&device, acpi_root, 
+       if (acpi_fadt.pwr_button == 0) {
+               result = acpi_add_single_object(&device, acpi_root,
                        NULL, ACPI_BUS_TYPE_POWER_BUTTON);
+               if (!result)
+                       result = acpi_start_single_object(device);
+       }
 
-       if (acpi_fadt.sleep_button == 0)
-               result = acpi_bus_add(&device, acpi_root, 
+       if (acpi_fadt.sleep_button == 0) {
+               result = acpi_add_single_object(&device, acpi_root,
                        NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
+               if (!result)
+                       result = acpi_start_single_object(device);
+       }
 
        return_VALUE(result);
 }
@@ -1346,6 +1415,7 @@ acpi_bus_scan_fixed (
 static int __init acpi_scan_init(void)
 {
        int result;
+       struct acpi_bus_ops ops;
 
        ACPI_FUNCTION_TRACE("acpi_scan_init");
 
@@ -1357,17 +1427,23 @@ static int __init acpi_scan_init(void)
        /*
         * Create the root device in the bus's device tree
         */
-       result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, 
+       result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
                ACPI_BUS_TYPE_SYSTEM);
        if (result)
                goto Done;
 
+       result = acpi_start_single_object(acpi_root);
+
        /*
         * Enumerate devices in the ACPI namespace.
         */
        result = acpi_bus_scan_fixed(acpi_root);
-       if (!result) 
-               result = acpi_bus_scan(acpi_root);
+       if (!result) {
+               memset(&ops, 0, sizeof(ops));
+               ops.acpi_op_add = 1;
+               ops.acpi_op_start = 1;
+               result = acpi_bus_scan(acpi_root, &ops);
+       }
 
        if (result)
                acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
index 97fe13f7f07c85d6fa2d07efd3f04afab932ec46..652281402c923860d449ec7a652ff81fa6903447 100644 (file)
@@ -74,6 +74,8 @@ static ssize_t
 firmware_timeout_store(struct class *class, const char *buf, size_t count)
 {
        loading_timeout = simple_strtol(buf, NULL, 10);
+       if (loading_timeout < 0)
+               loading_timeout = 0;
        return count;
 }
 
@@ -138,6 +140,10 @@ firmware_loading_store(struct class_device *class_dev,
        switch (loading) {
        case 1:
                down(&fw_lock);
+               if (!fw_priv->fw) {
+                       up(&fw_lock);
+                       break;
+               }
                vfree(fw_priv->fw->data);
                fw_priv->fw->data = NULL;
                fw_priv->fw->size = 0;
@@ -178,7 +184,7 @@ firmware_data_read(struct kobject *kobj,
 
        down(&fw_lock);
        fw = fw_priv->fw;
-       if (test_bit(FW_STATUS_DONE, &fw_priv->status)) {
+       if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) {
                ret_count = -ENODEV;
                goto out;
        }
@@ -238,9 +244,10 @@ firmware_data_write(struct kobject *kobj,
 
        if (!capable(CAP_SYS_RAWIO))
                return -EPERM;
+
        down(&fw_lock);
        fw = fw_priv->fw;
-       if (test_bit(FW_STATUS_DONE, &fw_priv->status)) {
+       if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) {
                retval = -ENODEV;
                goto out;
        }
@@ -418,7 +425,7 @@ request_firmware(const struct firmware **firmware_p, const char *name,
 
        fw_priv = class_get_devdata(class_dev);
 
-       if (loading_timeout) {
+       if (loading_timeout > 0) {
                fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
                add_timer(&fw_priv->timeout);
        }
index 653512b775703a8bcb37dc83b8276d3e850fd034..3e9fb6e4a52a39f433e04c1a2f8a672823224215 100644 (file)
@@ -786,7 +786,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
 
        case CCISS_GETLUNINFO: {
                LogvolInfo_struct luninfo;
-               int i;
                
                luninfo.LunID = drv->LunID;
                luninfo.num_opens = drv->usage_count;
index 234fdcfbdf01105e9337e164f34a07dd7dfede5b..1197462bb6bae32d2f50d0091abe20e6bfbd7cb2 100644 (file)
@@ -1867,19 +1867,20 @@ static void freed_request(request_queue_t *q, int rw)
 
 #define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
 /*
- * Get a free request, queue_lock must not be held
+ * Get a free request, queue_lock must be held.
+ * Returns NULL on failure, with queue_lock held.
+ * Returns !NULL on success, with queue_lock *not held*.
  */
 static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
                                   int gfp_mask)
 {
        struct request *rq = NULL;
        struct request_list *rl = &q->rq;
-       struct io_context *ioc = get_io_context(gfp_mask);
+       struct io_context *ioc = current_io_context(GFP_ATOMIC);
 
        if (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)))
                goto out;
 
-       spin_lock_irq(q->queue_lock);
        if (rl->count[rw]+1 >= q->nr_requests) {
                /*
                 * The queue will fill after this allocation, so set it as
@@ -1907,11 +1908,19 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
                 * The queue is full and the allocating process is not a
                 * "batcher", and not exempted by the IO scheduler
                 */
-               spin_unlock_irq(q->queue_lock);
                goto out;
        }
 
 get_rq:
+       /*
+        * Only allow batching queuers to allocate up to 50% over the defined
+        * limit of requests, otherwise we could have thousands of requests
+        * allocated with any setting of ->nr_requests
+        */
+       if (rl->count[rw] >= (3 * q->nr_requests / 2)) {
+               spin_unlock_irq(q->queue_lock);
+               goto out;
+       }
        rl->count[rw]++;
        rl->starved[rw] = 0;
        if (rl->count[rw] >= queue_congestion_on_threshold(q))
@@ -1941,7 +1950,6 @@ rq_starved:
                if (unlikely(rl->count[rw] == 0))
                        rl->starved[rw] = 1;
 
-               spin_unlock_irq(q->queue_lock);
                goto out;
        }
 
@@ -1951,21 +1959,23 @@ rq_starved:
        rq_init(q, rq);
        rq->rl = rl;
 out:
-       put_io_context(ioc);
        return rq;
 }
 
 /*
  * No available requests for this queue, unplug the device and wait for some
  * requests to become available.
+ *
+ * Called with q->queue_lock held, and returns with it unlocked.
  */
 static struct request *get_request_wait(request_queue_t *q, int rw,
                                        struct bio *bio)
 {
-       DEFINE_WAIT(wait);
        struct request *rq;
 
-       do {
+       rq = get_request(q, rw, bio, GFP_NOIO);
+       while (!rq) {
+               DEFINE_WAIT(wait);
                struct request_list *rl = &q->rq;
 
                prepare_to_wait_exclusive(&rl->wait[rw], &wait,
@@ -1976,7 +1986,8 @@ static struct request *get_request_wait(request_queue_t *q, int rw,
                if (!rq) {
                        struct io_context *ioc;
 
-                       generic_unplug_device(q);
+                       __generic_unplug_device(q);
+                       spin_unlock_irq(q->queue_lock);
                        io_schedule();
 
                        /*
@@ -1985,12 +1996,13 @@ static struct request *get_request_wait(request_queue_t *q, int rw,
                         * up to a big batch of them for a small period time.
                         * See ioc_batching, ioc_set_batching
                         */
-                       ioc = get_io_context(GFP_NOIO);
+                       ioc = current_io_context(GFP_NOIO);
                        ioc_set_batching(q, ioc);
-                       put_io_context(ioc);
+
+                       spin_lock_irq(q->queue_lock);
                }
                finish_wait(&rl->wait[rw], &wait);
-       } while (!rq);
+       }
 
        return rq;
 }
@@ -2001,14 +2013,18 @@ struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask)
 
        BUG_ON(rw != READ && rw != WRITE);
 
-       if (gfp_mask & __GFP_WAIT)
+       spin_lock_irq(q->queue_lock);
+       if (gfp_mask & __GFP_WAIT) {
                rq = get_request_wait(q, rw, NULL);
-       else
+       } else {
                rq = get_request(q, rw, NULL, gfp_mask);
+               if (!rq)
+                       spin_unlock_irq(q->queue_lock);
+       }
+       /* q->queue_lock is unlocked at this point */
 
        return rq;
 }
-
 EXPORT_SYMBOL(blk_get_request);
 
 /**
@@ -2512,7 +2528,7 @@ EXPORT_SYMBOL(blk_attempt_remerge);
 
 static int __make_request(request_queue_t *q, struct bio *bio)
 {
-       struct request *req, *freereq = NULL;
+       struct request *req;
        int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync;
        unsigned short prio;
        sector_t sector;
@@ -2540,14 +2556,9 @@ static int __make_request(request_queue_t *q, struct bio *bio)
                goto end_io;
        }
 
-again:
        spin_lock_irq(q->queue_lock);
 
-       if (elv_queue_empty(q)) {
-               blk_plug_device(q);
-               goto get_rq;
-       }
-       if (barrier)
+       if (unlikely(barrier) || elv_queue_empty(q))
                goto get_rq;
 
        el_ret = elv_merge(q, &req, bio);
@@ -2592,40 +2603,24 @@ again:
                                elv_merged_request(q, req);
                        goto out;
 
-               /*
-                * elevator says don't/can't merge. get new request
-                */
-               case ELEVATOR_NO_MERGE:
-                       break;
-
+               /* ELV_NO_MERGE: elevator says don't/can't merge. */
                default:
-                       printk("elevator returned crap (%d)\n", el_ret);
-                       BUG();
+                       ;
        }
 
+get_rq:
        /*
-        * Grab a free request from the freelist - if that is empty, check
-        * if we are doing read ahead and abort instead of blocking for
-        * a free slot.
+        * Grab a free request. This is might sleep but can not fail.
+        * Returns with the queue unlocked.
+        */
+       req = get_request_wait(q, rw, bio);
+
+       /*
+        * After dropping the lock and possibly sleeping here, our request
+        * may now be mergeable after it had proven unmergeable (above).
+        * We don't worry about that case for efficiency. It won't happen
+        * often, and the elevators are able to handle it.
         */
-get_rq:
-       if (freereq) {
-               req = freereq;
-               freereq = NULL;
-       } else {
-               spin_unlock_irq(q->queue_lock);
-               if ((freereq = get_request(q, rw, bio, GFP_ATOMIC)) == NULL) {
-                       /*
-                        * READA bit set
-                        */
-                       err = -EWOULDBLOCK;
-                       if (bio_rw_ahead(bio))
-                               goto end_io;
-       
-                       freereq = get_request_wait(q, rw, bio);
-               }
-               goto again;
-       }
 
        req->flags |= REQ_CMD;
 
@@ -2654,10 +2649,11 @@ get_rq:
        req->rq_disk = bio->bi_bdev->bd_disk;
        req->start_time = jiffies;
 
+       spin_lock_irq(q->queue_lock);
+       if (elv_queue_empty(q))
+               blk_plug_device(q);
        add_request(q, req);
 out:
-       if (freereq)
-               __blk_put_request(q, freereq);
        if (sync)
                __generic_unplug_device(q);
 
@@ -3284,24 +3280,20 @@ void exit_io_context(void)
 
 /*
  * If the current task has no IO context then create one and initialise it.
- * If it does have a context, take a ref on it.
+ * Otherwise, return its existing IO context.
  *
- * This is always called in the context of the task which submitted the I/O.
- * But weird things happen, so we disable local interrupts to ensure exclusive
- * access to *current.
+ * This returned IO context doesn't have a specifically elevated refcount,
+ * but since the current task itself holds a reference, the context can be
+ * used in general code, so long as it stays within `current` context.
  */
-struct io_context *get_io_context(int gfp_flags)
+struct io_context *current_io_context(int gfp_flags)
 {
        struct task_struct *tsk = current;
-       unsigned long flags;
        struct io_context *ret;
 
-       local_irq_save(flags);
        ret = tsk->io_context;
-       if (ret)
-               goto out;
-
-       local_irq_restore(flags);
+       if (likely(ret))
+               return ret;
 
        ret = kmem_cache_alloc(iocontext_cachep, gfp_flags);
        if (ret) {
@@ -3312,25 +3304,25 @@ struct io_context *get_io_context(int gfp_flags)
                ret->nr_batch_requests = 0; /* because this is 0 */
                ret->aic = NULL;
                ret->cic = NULL;
+               tsk->io_context = ret;
+       }
 
-               local_irq_save(flags);
-
-               /*
-                * very unlikely, someone raced with us in setting up the task
-                * io context. free new context and just grab a reference.
-                */
-               if (!tsk->io_context)
-                       tsk->io_context = ret;
-               else {
-                       kmem_cache_free(iocontext_cachep, ret);
-                       ret = tsk->io_context;
-               }
+       return ret;
+}
+EXPORT_SYMBOL(current_io_context);
 
-out:
+/*
+ * If the current task has no IO context then create one and initialise it.
+ * If it does have a context, take a ref on it.
+ *
+ * This is always called in the context of the task which submitted the I/O.
+ */
+struct io_context *get_io_context(int gfp_flags)
+{
+       struct io_context *ret;
+       ret = current_io_context(gfp_flags);
+       if (likely(ret))
                atomic_inc(&ret->refcount);
-               local_irq_restore(flags);
-       }
-
        return ret;
 }
 EXPORT_SYMBOL(get_io_context);
index 1407945a5892887565219b6594dde1444a6e30ea..59f589d733f929d12639eab6852622a618a1796f 100644 (file)
@@ -686,6 +686,15 @@ static struct pci_device_id agp_amd64_pci_table[] = {
        .subvendor      = PCI_ANY_ID,
        .subdevice      = PCI_ANY_ID,
        },
+       /* SIS 760 */
+       {
+       .class          = (PCI_CLASS_BRIDGE_HOST << 8),
+       .class_mask     = ~0,
+       .vendor         = PCI_VENDOR_ID_SI,
+       .device         = PCI_DEVICE_ID_SI_760,
+       .subvendor      = PCI_ANY_ID,
+       .subdevice      = PCI_ANY_ID,
+       },
        { }
 };
 
index 1813d0d198f12bee356b29dfb05d051d0878ef34..e16c13fe698dff7c71ad27508d64904f84be80be 100644 (file)
@@ -1088,8 +1088,8 @@ static inline int i_ipmi_request(ipmi_user_t          user,
                long                  seqid;
                int                   broadcast = 0;
 
-               if (addr->channel > IPMI_NUM_CHANNELS) {
-                       spin_lock_irqsave(&intf->counter_lock, flags);
+               if (addr->channel >= IPMI_MAX_CHANNELS) {
+                       spin_lock_irqsave(&intf->counter_lock, flags);
                        intf->sent_invalid_commands++;
                        spin_unlock_irqrestore(&intf->counter_lock, flags);
                        rv = -EINVAL;
index 7c24fbe831f83847df9eb859ec8d4983305b6fc7..95f7046ff059184c5c7b8024e83881c922c25289 100644 (file)
@@ -451,7 +451,7 @@ static int __init moxa_init(void)
                int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1;
                i = 0;
                while (i < n) {
-                       while ((p = pci_find_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)
+                       while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)
                        {
                                if (pci_enable_device(p))
                                        continue;
index 7db3370f4972701c674739feeab4f8ecb156d38b..d7d484024e2bf224b6fd3243f85b59bdc299df3b 100644 (file)
@@ -1095,7 +1095,7 @@ static int __init rio_init(void)
 
 #ifdef CONFIG_PCI
     /* First look for the JET devices: */
-    while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
+    while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,
                                     PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, 
                                     pdev))) {
        if (pci_enable_device(pdev)) continue;
@@ -1169,7 +1169,7 @@ static int __init rio_init(void)
   */
 
     /* Then look for the older RIO/PCI devices: */
-    while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
+    while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,
                                     PCI_DEVICE_ID_SPECIALIX_RIO, 
                                     pdev))) {
        if (pci_enable_device(pdev)) continue;
index ff4f09804865546527ca6926dc5c4f1ab1317605..d8f9e94ae475703465300750258fbf984a3101a0 100644 (file)
@@ -78,6 +78,7 @@
 #include <linux/sysctl.h>
 #include <linux/wait.h>
 #include <linux/bcd.h>
+#include <linux/delay.h>
 
 #include <asm/current.h>
 #include <asm/uaccess.h>
@@ -894,7 +895,6 @@ static int __init rtc_init(void)
        struct proc_dir_entry *ent;
 #if defined(__alpha__) || defined(__mips__)
        unsigned int year, ctrl;
-       unsigned long uip_watchdog;
        char *guess = NULL;
 #endif
 #ifdef __sparc__
@@ -1000,12 +1000,8 @@ no_irq:
        /* Each operating system on an Alpha uses its own epoch.
           Let's try to guess which one we are using now. */
        
-       uip_watchdog = jiffies;
        if (rtc_is_updating() != 0)
-               while (jiffies - uip_watchdog < 2*HZ/100) { 
-                       barrier();
-                       cpu_relax();
-               }
+               msleep(20);
        
        spin_lock_irq(&rtc_lock);
        year = CMOS_READ(RTC_YEAR);
@@ -1213,7 +1209,6 @@ static int rtc_proc_open(struct inode *inode, struct file *file)
 
 void rtc_get_rtc_time(struct rtc_time *rtc_tm)
 {
-       unsigned long uip_watchdog = jiffies;
        unsigned char ctrl;
 #ifdef CONFIG_MACH_DECSTATION
        unsigned int real_year;
@@ -1221,7 +1216,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
 
        /*
         * read RTC once any update in progress is done. The update
-        * can take just over 2ms. We wait 10 to 20ms. There is no need to
+        * can take just over 2ms. We wait 20ms. There is no need to
         * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
         * If you need to know *exactly* when a second has started, enable
         * periodic update complete interrupts, (via ioctl) and then 
@@ -1230,10 +1225,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
         */
 
        if (rtc_is_updating() != 0)
-               while (jiffies - uip_watchdog < 2*HZ/100) {
-                       barrier();
-                       cpu_relax();
-               }
+               msleep(20);
 
        /*
         * Only the values that we read from the RTC are set. We leave
index 659335d80ee73703b6c56b7653e454a34332402a..ec78d2f161f75363b5d971e7ba1713ef3aa4899f 100644 (file)
@@ -396,7 +396,7 @@ static struct file_operations tipar_fops = {
 static int __init
 tipar_setup(char *str)
 {
-       int ints[2];
+       int ints[3];
 
        str = get_options(str, ARRAY_SIZE(ints), ints);
 
index 58597993954f7e8fea638d065afdc7a5362e2ed5..f19cf9d7792d57816b53cf0e697bda80fe07a50e 100644 (file)
@@ -476,11 +476,11 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
                        ld = tty_ldisc_ref(tty);
                        switch (arg) {
                        case TCIFLUSH:
-                               if (ld->flush_buffer)
+                               if (ld && ld->flush_buffer)
                                        ld->flush_buffer(tty);
                                break;
                        case TCIOFLUSH:
-                               if (ld->flush_buffer)
+                               if (ld && ld->flush_buffer)
                                        ld->flush_buffer(tty);
                                /* fall through */
                        case TCOFLUSH:
index 8971484b956b11c8b6072ab163aaeb87d5945117..1d44f69e1fda12bfb0abd092435d53ab04d9c610 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/fs.h>
 #include <linux/console.h>
 #include <linux/signal.h>
+#include <linux/timex.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -386,7 +387,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                if (!perm)
                        return -EPERM;
                if (arg)
-                       arg = 1193182 / arg;
+                       arg = CLOCK_TICK_RATE / arg;
                kd_mksound(arg, 0);
                return 0;
 
@@ -403,7 +404,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
                count = ticks ? (arg & 0xffff) : 0;
                if (count)
-                       count = 1193182 / count;
+                       count = CLOCK_TICK_RATE / count;
                kd_mksound(count, ticks);
                return 0;
        }
index 4e98c215e5b1bd63788ff031638191e0024045e8..4b039516cc866c9f03f5fe82a964faf7cc995af1 100644 (file)
@@ -162,7 +162,7 @@ ixp2000_wdt_release(struct inode *inode, struct file *file)
        if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
                wdt_disable();
        } else {
-               printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - "
+               printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
                                        "timer will not stop\n");
        }
 
index 82396e06c8a89fffbf812cd1fc0edb0e9d6e1b0a..83df369113a42e3ead7a5bb43bbf013dc5a1b473 100644 (file)
@@ -156,7 +156,7 @@ ixp4xx_wdt_release(struct inode *inode, struct file *file)
        if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
                wdt_disable();
        } else {
-               printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - "
+               printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
                                        "timer will not stop\n");
        }
 
index 6e548a222ef12c3ce9fdfa80fc410e0d1e02841c..89497890158d9fad084828551a0d3b1db57b8b90 100644 (file)
@@ -44,7 +44,7 @@ static didd_adapter_change_notification_t\
   Array to held adapter information
    -------------------------------------------------------------------------- */
 static DESCRIPTOR  HandleTable[NEW_MAX_DESCRIPTORS];
-dword Adapters = 0; /* Number of adapters */
+static dword Adapters = 0; /* Number of adapters */
 /* --------------------------------------------------------------------------
   Shadow IDI_DIMAINT
   and 'shadow' debug stuff
index 6e7e060716b7b071a478f9f62c3774d767f8778a..7333377ab31de0cc9e7d866626c9c9dd8cd9de88 100644 (file)
@@ -312,7 +312,7 @@ wait_busy(hfc4s8s_hw * a)
 /* function to read critical counter registers that   */
 /* may be udpated by the chip during read             */
 /******************************************************/
-static volatile u_char
+static u_char
 Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
 {
        u_char ref8;
@@ -324,7 +324,7 @@ Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
        return in8;
 }
 
-static volatile int
+static int
 Read_hfc16_stable(hfc4s8s_hw * hw, int reg)
 {
        int ref16;
@@ -1465,7 +1465,7 @@ hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode)
 /******************************************/
 /* disable memory mapped ports / io ports */
 /******************************************/
-void
+static void
 release_pci_ports(hfc4s8s_hw * hw)
 {
        pci_write_config_word(hw->pdev, PCI_COMMAND, 0);
@@ -1481,7 +1481,7 @@ release_pci_ports(hfc4s8s_hw * hw)
 /*****************************************/
 /* enable memory mapped ports / io ports */
 /*****************************************/
-void
+static void
 enable_pci_ports(hfc4s8s_hw * hw)
 {
 #ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
index 8ee25b2ccce1b8fb354d1f99088a577d866ed32f..1fd3d4e5f2849b5e9eb699c75cdb6374654d203a 100644 (file)
@@ -42,6 +42,8 @@ typedef struct _hycapi_appl {
 
 static hycapi_appl hycapi_applications[CAPI_MAXAPPL];
 
+static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
+
 static inline int _hycapi_appCheck(int app_id, int ctrl_no)
 {
        if((ctrl_no <= 0) || (ctrl_no > CAPI_MAXCONTR) || (app_id <= 0) ||
@@ -57,7 +59,7 @@ static inline int _hycapi_appCheck(int app_id, int ctrl_no)
 Kernel-Capi callback reset_ctr
 ******************************/     
 
-void 
+static void
 hycapi_reset_ctr(struct capi_ctr *ctrl)
 {
        hycapictrl_info *cinfo = ctrl->driverdata;
@@ -73,7 +75,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl)
 Kernel-Capi callback remove_ctr
 ******************************/     
 
-void 
+static void
 hycapi_remove_ctr(struct capi_ctr *ctrl)
 {
        int i;
@@ -215,7 +217,7 @@ Error-checking is done for CAPI-compliance.
 The application is recorded in the internal list.
 *************************************************************/
 
-void 
+static void
 hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl, 
                     capi_register_params *rp)
 {
@@ -291,7 +293,7 @@ Release the application from the internal list an remove it's
 registration at controller-level
 ******************************************************************/
 
-void 
+static void
 hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl)
 {
        int chk;
@@ -364,7 +366,7 @@ firmware-releases that do not check the MsgLen-Indication!
 
 ***************************************************************/
 
-u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
+static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
 {
        __u16 appl_id;
        int _len, _len2;
@@ -437,8 +439,8 @@ Informations provided in the /proc/capi-entries.
 
 *********************************************************************/
 
-int hycapi_read_proc(char *page, char **start, off_t off,
-                    int count, int *eof, struct capi_ctr *ctrl)
+static int hycapi_read_proc(char *page, char **start, off_t off,
+                           int count, int *eof, struct capi_ctr *ctrl)
 {
        hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
        hysdn_card *card = cinfo->card;
@@ -485,7 +487,7 @@ on capi-interface registration.
 
 **************************************************************/
 
-int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
+static int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 {
 #ifdef HYCAPI_PRINTFNAMES
        printk(KERN_NOTICE "hycapi_load_firmware\n");    
@@ -494,7 +496,7 @@ int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 }
 
 
-char *hycapi_procinfo(struct capi_ctr *ctrl)
+static char *hycapi_procinfo(struct capi_ctr *ctrl)
 {
        hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
 #ifdef HYCAPI_PRINTFNAMES
index 6c04281e57b850a4432bc2b4e4cc841f9e8b5a9c..7bfba196f3155a9db17137fcab48e5195f3e9bdc 100644 (file)
@@ -53,7 +53,7 @@ struct boot_data {
 /*  to be called at start of POF file reading,       */
 /*  before starting any decryption on any POF record. */
 /*****************************************************/
-void
+static void
 StartDecryption(struct boot_data *boot)
 {
        boot->Cryptor = CRYPT_STARTTERM;
@@ -66,7 +66,7 @@ StartDecryption(struct boot_data *boot)
 /*       to HI and LO boot loader and (all) seq tags, because  */
 /*       global Cryptor is started for whole POF.              */
 /***************************************************************/
-void
+static void
 DecryptBuf(struct boot_data *boot, int cnt)
 {
        uchar *bufp = boot->buf.BootBuf;
index 4cee26e558eedad031f528451ae9414f954d28a9..432f6f99089e5dd5109bcb6b828a8336301eeaf1 100644 (file)
@@ -227,7 +227,6 @@ typedef struct hycapictrl_info hycapictrl_info;
 /*****************/
 /* exported vars */
 /*****************/
-extern int cardmax;            /* number of found cards */
 extern hysdn_card *card_root;  /* pointer to first card */
 
 
@@ -244,7 +243,6 @@ extern void hysdn_procconf_release(void);   /* deinit proc config filesys */
 /* hysdn_proclog.c */
 extern int hysdn_proclog_init(hysdn_card *);   /* init proc log entry */
 extern void hysdn_proclog_release(hysdn_card *);       /* deinit proc log entry */
-extern void put_log_buffer(hysdn_card *, char *);      /* output log data */
 extern void hysdn_addlog(hysdn_card *, char *,...);    /* output data to log */
 extern void hysdn_card_errlog(hysdn_card *, tErrLogEntry *, int);      /* output card log */
 
@@ -278,16 +276,6 @@ extern unsigned int hycapi_enable;
 extern int hycapi_capi_create(hysdn_card *);   /* create a new capi device */
 extern int hycapi_capi_release(hysdn_card *);  /* delete the device */
 extern int hycapi_capi_stop(hysdn_card *card);   /* suspend */
-extern int hycapi_load_firmware(struct capi_ctr *, capiloaddata *);
-extern void hycapi_reset_ctr(struct capi_ctr *);
-extern void hycapi_remove_ctr(struct capi_ctr *);
-extern void hycapi_register_appl(struct capi_ctr *, __u16 appl,
-                                capi_register_params *);
-extern void hycapi_release_appl(struct capi_ctr *, __u16 appl);
-extern u16  hycapi_send_message(struct capi_ctr *, struct sk_buff *skb);
-extern char *hycapi_procinfo(struct capi_ctr *);
-extern int hycapi_read_proc(char *page, char **start, off_t off,
-                           int count, int *eof, struct capi_ctr *card);
 extern void hycapi_rx_capipkt(hysdn_card * card, uchar * buf, word len);
 extern void hycapi_tx_capiack(hysdn_card * card);
 extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card);
index 5cac2bf5f4b06f98030455666e6a018afb2f3f7d..12c8137b5161427eef3c8c85305d584da00de24c 100644 (file)
@@ -34,7 +34,7 @@ MODULE_AUTHOR("Werner Cornelius");
 MODULE_LICENSE("GPL");
 
 static char *hysdn_init_revision = "$Revision: 1.6.6.6 $";
-int cardmax;                   /* number of found cards */
+static int cardmax;            /* number of found cards */
 hysdn_card *card_root = NULL;  /* pointer to first card */
 
 /**********************************************/
index 8ef2b7c952a67d5e7d2195024f739e52bdab0223..4d57011c5737646025e5844820065acce465a364 100644 (file)
@@ -22,6 +22,8 @@
 /* the proc subdir for the interface is defined in the procconf module */
 extern struct proc_dir_entry *hysdn_proc_entry;
 
+static void put_log_buffer(hysdn_card * card, char *cp);
+
 /*************************************************/
 /* structure keeping ascii log for device output */
 /*************************************************/
@@ -93,7 +95,7 @@ hysdn_addlog(hysdn_card * card, char *fmt,...)
 /* opened for read got the contents.        */
 /* Flushes buffers not longer in use.       */
 /********************************************/
-void
+static void
 put_log_buffer(hysdn_card * card, char *cp)
 {
        struct log_data *ib;
index 3802f7a17f1635c17f2bcd6fe426e994e0871cf4..4a0c57db2b67657b8c09cfbe67f5d2cfb487ed95 100644 (file)
@@ -338,6 +338,7 @@ static int super_written(struct bio *bio, unsigned int bytes_done, int error)
 
        if (atomic_dec_and_test(&rdev->mddev->pending_writes))
                wake_up(&rdev->mddev->sb_wait);
+       bio_put(bio);
        return 0;
 }
 
index 2dc906fdfa550948caf23f528119401b7de22f9f..810e7aac0a535edeed845e2c435d3d8f5cbb9d8f 100644 (file)
@@ -7,8 +7,7 @@ bttv-objs       :=      bttv-driver.o bttv-cards.o bttv-if.o \
 zoran-objs      :=     zr36120.o zr36120_i2c.o zr36120_mem.o
 zr36067-objs   :=      zoran_procfs.o zoran_device.o \
                        zoran_driver.o zoran_card.o
-tuner-objs     :=      tuner-core.o tuner-simple.o mt20xx.o tda8290.o
-
+tuner-objs     :=      tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o
 obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o
 
 obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
index 290289a9975717a9d7cdab86eb8b188044bb7d2e..7d62b394c5092d9269781c45b5a342bf60291b0c 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    $Id: bttv-driver.c,v 1.38 2005/06/10 17:20:24 mchehab Exp $
+    $Id: bttv-driver.c,v 1.40 2005/06/16 21:38:45 nsh Exp $
 
     bttv - Bt848 frame grabber driver
 
@@ -76,6 +76,9 @@ static unsigned int whitecrush_upper = 0xCF;
 static unsigned int whitecrush_lower = 0x7F;
 static unsigned int vcr_hack    = 0;
 static unsigned int irq_iswitch = 0;
+static unsigned int uv_ratio    = 50;
+static unsigned int full_luma_range = 0;
+static unsigned int coring      = 0;
 
 /* API features (turn on/off stuff for testing) */
 static unsigned int v4l2        = 1;
@@ -106,6 +109,9 @@ module_param(adc_crush,         int, 0444);
 module_param(whitecrush_upper,  int, 0444);
 module_param(whitecrush_lower,  int, 0444);
 module_param(vcr_hack,          int, 0444);
+module_param(uv_ratio,          int, 0444);
+module_param(full_luma_range,   int, 0444);
+module_param(coring,            int, 0444);
 
 module_param_array(radio, int, NULL, 0444);
 
@@ -124,6 +130,9 @@ MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is
 MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127");
 MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)");
 MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler");
+MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50");
+MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)");
+MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)");
 
 MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");
 MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
@@ -484,7 +493,10 @@ static const unsigned int BTTV_FORMATS = ARRAY_SIZE(bttv_formats);
 #define V4L2_CID_PRIVATE_VCR_HACK    (V4L2_CID_PRIVATE_BASE + 5)
 #define V4L2_CID_PRIVATE_WHITECRUSH_UPPER   (V4L2_CID_PRIVATE_BASE + 6)
 #define V4L2_CID_PRIVATE_WHITECRUSH_LOWER   (V4L2_CID_PRIVATE_BASE + 7)
-#define V4L2_CID_PRIVATE_LASTP1      (V4L2_CID_PRIVATE_BASE + 8)
+#define V4L2_CID_PRIVATE_UV_RATIO    (V4L2_CID_PRIVATE_BASE + 8)
+#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE    (V4L2_CID_PRIVATE_BASE + 9)
+#define V4L2_CID_PRIVATE_CORING      (V4L2_CID_PRIVATE_BASE + 10)
+#define V4L2_CID_PRIVATE_LASTP1      (V4L2_CID_PRIVATE_BASE + 11)
 
 static const struct v4l2_queryctrl no_ctl = {
        .name  = "42",
@@ -618,8 +630,32 @@ static const struct v4l2_queryctrl bttv_ctls[] = {
                .step          = 1,
                .default_value = 0x7F,
                .type          = V4L2_CTRL_TYPE_INTEGER,
+       },{
+               .id            = V4L2_CID_PRIVATE_UV_RATIO,
+               .name          = "uv ratio",
+               .minimum       = 0,
+               .maximum       = 100,
+               .step          = 1,
+               .default_value = 50,
+               .type          = V4L2_CTRL_TYPE_INTEGER,
+       },{
+               .id            = V4L2_CID_PRIVATE_FULL_LUMA_RANGE,
+               .name          = "full luma range",
+               .minimum       = 0,
+               .maximum       = 1,
+               .type          = V4L2_CTRL_TYPE_BOOLEAN,
+       },{
+               .id            = V4L2_CID_PRIVATE_CORING,
+               .name          = "coring",
+               .minimum       = 0,
+               .maximum       = 3,
+               .step          = 1,
+               .default_value = 0,
+               .type          = V4L2_CTRL_TYPE_INTEGER,
        }
 
+
+
 };
 static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls);
 
@@ -833,8 +869,8 @@ static void bt848_sat(struct bttv *btv, int color)
        btv->saturation = color;
 
        /* 0-511 for the color */
-       val_u   = color >> 7;
-       val_v   = ((color>>7)*180L)/254;
+       val_u   = ((color * btv->opt_uv_ratio) / 50) >> 7;
+       val_v   = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254;
         hibits  = (val_u >> 7) & 2;
        hibits |= (val_v >> 8) & 1;
         btwrite(val_u & 0xff, BT848_SAT_U_LO);
@@ -1151,6 +1187,15 @@ static int get_control(struct bttv *btv, struct v4l2_control *c)
        case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
                c->value = btv->opt_whitecrush_lower;
                break;
+       case V4L2_CID_PRIVATE_UV_RATIO:
+               c->value = btv->opt_uv_ratio;
+               break;
+       case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
+               c->value = btv->opt_full_luma_range;
+               break;
+       case V4L2_CID_PRIVATE_CORING:
+               c->value = btv->opt_coring;
+               break;
        default:
                return -EINVAL;
        }
@@ -1247,6 +1292,18 @@ static int set_control(struct bttv *btv, struct v4l2_control *c)
                btv->opt_whitecrush_lower = c->value;
                btwrite(c->value, BT848_WC_DOWN);
                break;
+       case V4L2_CID_PRIVATE_UV_RATIO:
+               btv->opt_uv_ratio = c->value;
+               bt848_sat(btv, btv->saturation);
+               break;
+       case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
+               btv->opt_full_luma_range = c->value;
+               btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM);
+               break;
+       case V4L2_CID_PRIVATE_CORING:
+               btv->opt_coring = c->value;
+               btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM);
+               break;
        default:
                return -EINVAL;
        }
@@ -3117,11 +3174,6 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
                         return -EINVAL;
                memset(v,0,sizeof(*v));
                 strcpy(v->name, "Radio");
-                /* japan:          76.0 MHz -  89.9 MHz
-                   western europe: 87.5 MHz - 108.0 MHz
-                   russia:         65.0 MHz - 108.0 MHz */
-                v->rangelow=(int)(65*16);
-                v->rangehigh=(int)(108*16);
                 bttv_call_i2c_clients(btv,cmd,v);
                 return 0;
         }
@@ -3876,6 +3928,9 @@ static int __devinit bttv_probe(struct pci_dev *dev,
        btv->opt_vcr_hack   = vcr_hack;
        btv->opt_whitecrush_upper  = whitecrush_upper;
        btv->opt_whitecrush_lower  = whitecrush_lower;
+       btv->opt_uv_ratio   = uv_ratio;
+       btv->opt_full_luma_range   = full_luma_range;
+       btv->opt_coring     = coring;
 
        /* fill struct bttv with some useful defaults */
        btv->init.btv         = btv;
index 7b6f1e8560289c8c42d171aaf651edf181b5a487..f3293e4a15ad3f6137a06d03120dc76d73eb68dc 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    $Id: bttvp.h,v 1.17 2005/02/16 12:14:10 kraxel Exp $
+    $Id: bttvp.h,v 1.19 2005/06/16 21:38:45 nsh Exp $
 
     bttv - Bt848 frame grabber driver
 
@@ -326,6 +326,9 @@ struct bttv {
        int opt_vcr_hack;
        int opt_whitecrush_upper;
        int opt_whitecrush_lower;
+       int opt_uv_ratio;
+       int opt_full_luma_range;
+       int opt_coring;
 
        /* radio data/state */
        int has_radio;
index 95ad17b7f38e3b41a36f96d441ffcd36741f7de4..9c005cb128d7cbeb6d1327fe6845fb797791b30e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: mt20xx.c,v 1.4 2005/03/04 09:24:56 kraxel Exp $
+ * $Id: mt20xx.c,v 1.5 2005/06/16 08:29:49 nsh Exp $
  *
  * i2c tv tuner chip device driver
  * controls microtune tuners, mt2032 + mt2050 at the moment.
@@ -295,8 +295,8 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
        int if2 = t->radio_if2;
 
        // per Manual for FM tuning: first if center freq. 1085 MHz
-        mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
-                          1085*1000*1000,if2,if2,if2);
+        mt2032_set_if_freq(c, freq * 1000 / 16,
+                             1085*1000*1000,if2,if2,if2);
 }
 
 // Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
index b27cc348d95ce40f3076150868c25e14415c220d..f59d4601cc6311118f10774445173f7ec69d6c29 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: tda8290.c,v 1.7 2005/03/07 12:01:51 kraxel Exp $
+ * $Id: tda8290.c,v 1.11 2005/06/18 06:09:06 nsh Exp $
  *
  * i2c tv tuner chip device driver
  * controls the philips tda8290+75 tuner chip combo.
@@ -69,7 +69,7 @@ static __u8 get_freq_entry( struct freq_entry* table, __u16 freq)
 static unsigned char i2c_enable_bridge[2] =    { 0x21, 0xC0 };
 static unsigned char i2c_disable_bridge[2] =   { 0x21, 0x80 };
 static unsigned char i2c_init_tda8275[14] =    { 0x00, 0x00, 0x00, 0x00,
-                                                 0x7C, 0x04, 0xA3, 0x3F,
+                                                 0xfC, 0x04, 0xA3, 0x3F,
                                                  0x2A, 0x04, 0xFF, 0x00,
                                                  0x00, 0x40 };
 static unsigned char i2c_set_VS[2] =           { 0x30, 0x6F };
@@ -138,16 +138,24 @@ static int tda8290_tune(struct i2c_client *c)
 
 static void set_frequency(struct tuner *t, u16 ifc)
 {
-       u32 N = (((t->freq<<3)+ifc)&0x3fffc);
+       u32 freq;
+       u32 N;
 
-       N = N >> get_freq_entry(div_table, t->freq);
+       if (t->mode == V4L2_TUNER_RADIO)
+               freq = t->freq / 1000;
+       else
+               freq = t->freq;
+
+       N = (((freq<<3)+ifc)&0x3fffc);
+
+       N = N >> get_freq_entry(div_table, freq);
        t->i2c_set_freq[0] = 0;
        t->i2c_set_freq[1] = (unsigned char)(N>>8);
        t->i2c_set_freq[2] = (unsigned char) N;
        t->i2c_set_freq[3] = 0x40;
        t->i2c_set_freq[4] = 0x52;
-       t->i2c_set_freq[5] = get_freq_entry(band_table, t->freq);
-       t->i2c_set_freq[6] = get_freq_entry(agc_table,  t->freq);
+       t->i2c_set_freq[5] = get_freq_entry(band_table, freq);
+       t->i2c_set_freq[6] = get_freq_entry(agc_table,  freq);
        t->i2c_set_freq[7] = 0x8f;
 }
 
index 39773633cc3c3a6cc5d7d6f1ade5a6206a5c2d43..ee35562f4d1a1e4aa682cf23223f2a0071436641 100644 (file)
@@ -368,7 +368,7 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
                if (t->radio_mode == V4L2_TUNER_MODE_MONO)
                        norm = &radio_mono;
                else
-                       norm = &radio_stereo;
+                       norm = &radio_stereo;
        } else {
                for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
                        if (tvnorms[i].std & t->std) {
@@ -566,7 +566,6 @@ static int tda9887_configure(struct tda9887 *t)
        if (UNSET != t->pinnacle_id) {
                tda9887_set_pinnacle(t,buf);
        }
-
        tda9887_set_config(t,buf);
        tda9887_set_insmod(t,buf);
 
@@ -615,8 +614,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
        t->pinnacle_id = UNSET;
        t->radio_mode = V4L2_TUNER_MODE_STEREO;
 
-        i2c_set_clientdata(&t->client, t);
-        i2c_attach_client(&t->client);
+       i2c_set_clientdata(&t->client, t);
+       i2c_attach_client(&t->client);
 
        return 0;
 }
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
new file mode 100644 (file)
index 0000000..a29f08f
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
+ * I2C address is allways 0xC0.
+ *
+ * $Id: tea5767.c,v 1.11 2005/06/21 15:40:33 mchehab Exp $
+ *
+ * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
+ * This code is placed under the terms of the GNU General Public License
+ *
+ * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
+ * from their contributions on DScaler.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/videodev.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+#include <media/tuner.h>
+
+/* Declared at tuner-core.c */
+extern unsigned int tuner_debug;
+
+#define PREFIX "TEA5767 "
+
+/*****************************************************************************/
+
+/******************************
+ * Write mode register values *
+ ******************************/
+
+/* First register */
+#define TEA5767_MUTE           0x80 /* Mutes output */
+#define TEA5767_SEARCH         0x40 /* Activates station search */
+/* Bits 0-5 for divider MSB */
+
+/* Second register */
+/* Bits 0-7 for divider LSB */
+
+/* Third register */
+
+/* Station search from botton to up */
+#define TEA5767_SEARCH_UP      0x80
+
+/* Searches with ADC output = 10 */
+#define TEA5767_SRCH_HIGH_LVL  0x60
+
+/* Searches with ADC output = 10 */
+#define TEA5767_SRCH_MID_LVL   0x40
+
+/* Searches with ADC output = 5 */
+#define TEA5767_SRCH_LOW_LVL   0x20
+
+/* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */
+#define TEA5767_HIGH_LO_INJECT 0x10
+
+/* Disable stereo */
+#define TEA5767_MONO           0x08
+
+/* Disable right channel and turns to mono */
+#define TEA5767_MUTE_RIGHT     0x04
+
+/* Disable left channel and turns to mono */
+#define TEA5767_MUTE_LEFT      0x02
+
+#define TEA5767_PORT1_HIGH     0x01
+
+/* Forth register */
+#define TEA5767_PORT2_HIGH     0x80
+/* Chips stops working. Only I2C bus remains on */
+#define TEA5767_STDBY          0x40
+
+/* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */
+#define TEA5767_JAPAN_BAND     0x20
+
+/* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */
+#define TEA5767_XTAL_32768     0x10
+
+/* Cuts weak signals */
+#define TEA5767_SOFT_MUTE      0x08
+
+/* Activates high cut control */
+#define TEA5767_HIGH_CUT_CTRL  0x04
+
+/* Activates stereo noise control */
+#define TEA5767_ST_NOISE_CTL   0x02
+
+/* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */
+#define TEA5767_SRCH_IND       0x01
+
+/* Fiveth register */
+
+/* By activating, it will use Xtal at 13 MHz as reference for divider */
+#define TEA5767_PLLREF_ENABLE  0x80
+
+/* By activating, deemphasis=50, or else, deemphasis of 50us */
+#define TEA5767_DEEMPH_75      0X40
+
+/*****************************
+ * Read mode register values *
+ *****************************/
+
+/* First register */
+#define TEA5767_READY_FLAG_MASK        0x80
+#define TEA5767_BAND_LIMIT_MASK        0X40
+/* Bits 0-5 for divider MSB after search or preset */
+
+/* Second register */
+/* Bits 0-7 for divider LSB after search or preset */
+
+/* Third register */
+#define TEA5767_STEREO_MASK    0x80
+#define TEA5767_IF_CNTR_MASK   0x7f
+
+/* Four register */
+#define TEA5767_ADC_LEVEL_MASK 0xf0
+
+/* should be 0 */
+#define TEA5767_CHIP_ID_MASK   0x0f
+
+/* Fiveth register */
+/* Reserved for future extensions */
+#define TEA5767_RESERVED_MASK  0xff
+
+/*****************************************************************************/
+
+static void set_tv_freq(struct i2c_client *c, unsigned int freq)
+{
+       struct tuner *t = i2c_get_clientdata(c);
+
+       tuner_warn("This tuner doesn't support TV freq.\n");
+}
+
+static void tea5767_status_dump(unsigned char *buffer)
+{
+       unsigned int div, frq;
+
+       if (TEA5767_READY_FLAG_MASK & buffer[0])
+               printk(PREFIX "Ready Flag ON\n");
+       else
+               printk(PREFIX "Ready Flag OFF\n");
+
+       if (TEA5767_BAND_LIMIT_MASK & buffer[0])
+               printk(PREFIX "Tuner at band limit\n");
+       else
+               printk(PREFIX "Tuner not at band limit\n");
+
+       div=((buffer[0]&0x3f)<<8) | buffer[1];
+
+       switch (TEA5767_HIGH_LO_32768) {
+       case TEA5767_HIGH_LO_13MHz:
+               frq = 1000*(div*50-700-225)/4; /* Freq in KHz */
+               break;
+       case TEA5767_LOW_LO_13MHz:
+               frq = 1000*(div*50+700+225)/4; /* Freq in KHz */
+               break;
+       case TEA5767_LOW_LO_32768:
+               frq = 1000*(div*32768/1000+700+225)/4; /* Freq in KHz */
+               break;
+       case TEA5767_HIGH_LO_32768:
+       default:
+               frq = 1000*(div*32768/1000-700-225)/4; /* Freq in KHz */
+               break;
+       }
+        buffer[0] = (div>>8) & 0x3f;
+        buffer[1] = div      & 0xff;
+
+       printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n",
+                                               frq/1000,frq%1000,div);
+
+       if (TEA5767_STEREO_MASK & buffer[2])
+               printk(PREFIX "Stereo\n");
+       else
+               printk(PREFIX "Mono\n");
+
+       printk(PREFIX "IF Counter = %d\n",buffer[2] & TEA5767_IF_CNTR_MASK);
+
+       printk(PREFIX "ADC Level = %d\n",(buffer[3] & TEA5767_ADC_LEVEL_MASK)>>4);
+
+       printk(PREFIX "Chip ID = %d\n",(buffer[3] & TEA5767_CHIP_ID_MASK));
+
+       printk(PREFIX "Reserved = 0x%02x\n",(buffer[4] & TEA5767_RESERVED_MASK));
+}
+
+/* Freq should be specifyed at 62.5 Hz */
+static void set_radio_freq(struct i2c_client *c, unsigned int frq)
+{
+       struct tuner *t = i2c_get_clientdata(c);
+        unsigned char buffer[5];
+       unsigned div;
+       int rc;
+
+       if ( tuner_debug )
+               printk(PREFIX "radio freq counter %d\n",frq);
+
+       /* Rounds freq to next decimal value - for 62.5 KHz step */
+       /* frq = 20*(frq/16)+radio_frq[frq%16]; */
+
+       buffer[2] = TEA5767_PORT1_HIGH;
+       buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL | TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND;
+       buffer[4]=0;
+
+       if (t->audmode == V4L2_TUNER_MODE_MONO) {
+               tuner_dbg("TEA5767 set to mono\n");
+               buffer[2] |= TEA5767_MONO;
+       } else
+               tuner_dbg("TEA5767 set to stereo\n");
+
+       switch (t->type) {
+       case TEA5767_HIGH_LO_13MHz:
+               tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n");
+               buffer[2] |= TEA5767_HIGH_LO_INJECT;
+               buffer[4] |= TEA5767_PLLREF_ENABLE;
+               div = (frq*4/16+700+225+25)/50;
+               break;
+       case TEA5767_LOW_LO_13MHz:
+               tuner_dbg("TEA5767 radio LOW LO inject xtal @ 13 MHz\n");
+
+               buffer[4] |= TEA5767_PLLREF_ENABLE;
+               div = (frq*4/16-700-225+25)/50;
+               break;
+       case TEA5767_LOW_LO_32768:
+               tuner_dbg("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n");
+               buffer[3] |= TEA5767_XTAL_32768;
+               /* const 700=4000*175 Khz - to adjust freq to right value */
+               div = (1000*(frq*4/16-700-225)+16384)>>15;
+               break;
+       case TEA5767_HIGH_LO_32768:
+       default:
+               tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 32,768 MHz\n");
+
+               buffer[2] |= TEA5767_HIGH_LO_INJECT;
+               buffer[3] |= TEA5767_XTAL_32768;
+               div = (1000*(frq*4/16+700+225)+16384)>>15;
+               break;
+       }
+        buffer[0] = (div>>8) & 0x3f;
+        buffer[1] = div      & 0xff;
+
+       if ( tuner_debug )
+               tea5767_status_dump(buffer);
+
+        if (5 != (rc = i2c_master_send(c,buffer,5)))
+               tuner_warn("i2c i/o error: rc == %d (should be 5)\n",rc);
+}
+
+static int tea5767_signal(struct i2c_client *c)
+{
+       unsigned char buffer[5];
+       int rc;
+       struct tuner *t = i2c_get_clientdata(c);
+
+       memset(buffer,0,sizeof(buffer));
+        if (5 != (rc = i2c_master_recv(c,buffer,5)))
+                tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc);
+
+       return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) <<(13-4));
+}
+
+static int tea5767_stereo(struct i2c_client *c)
+{
+       unsigned char buffer[5];
+       int rc;
+       struct tuner *t = i2c_get_clientdata(c);
+
+       memset(buffer,0,sizeof(buffer));
+        if (5 != (rc = i2c_master_recv(c,buffer,5)))
+                tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc);
+
+       rc = buffer[2] & TEA5767_STEREO_MASK;
+
+       if ( tuner_debug )
+               tuner_dbg("TEA5767 radio ST GET = %02x\n", rc);
+
+       return ( (buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO: 0);
+}
+
+int tea_detection(struct i2c_client *c)
+{
+       unsigned char buffer[5]= { 0xff, 0xff, 0xff, 0xff, 0xff };
+       int rc;
+       struct tuner *t = i2c_get_clientdata(c);
+
+        if (5 != (rc = i2c_master_recv(c,buffer,5))) {
+                tuner_warn ( "it is not a TEA5767. Received %i chars.\n",rc );
+               return EINVAL;
+       }
+
+       /* If all bytes are the same then it's a TV tuner and not a tea5767 chip. */
+       if (buffer[0] == buffer[1] &&  buffer[0] == buffer[2] &&
+           buffer[0] == buffer[3] &&  buffer[0] == buffer[4]) {
+                tuner_warn ( "All bytes are equal. It is not a TEA5767\n" );
+               return EINVAL;
+       }
+
+       /*  Status bytes:
+        *  Byte 4: bit 3:1 : CI (Chip Identification) == 0
+        *          bit 0   : internally set to 0
+        *  Byte 5: bit 7:0 : == 0
+        */
+
+       if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) {
+                tuner_warn ( "Chip ID is not zero. It is not a TEA5767\n" );
+               return EINVAL;
+       }
+       tuner_warn ( "TEA5767 detected.\n" );
+       return 0;
+}
+
+int tea5767_tuner_init(struct i2c_client *c)
+{
+       struct tuner *t = i2c_get_clientdata(c);
+
+       if (tea_detection(c)==EINVAL) return EINVAL;
+
+        tuner_info("type set to %d (%s)\n",
+                   t->type, TEA5767_TUNER_NAME);
+        strlcpy(c->name, TEA5767_TUNER_NAME, sizeof(c->name));
+
+       t->tv_freq    = set_tv_freq;
+       t->radio_freq = set_radio_freq;
+       t->has_signal = tea5767_signal;
+       t->is_stereo  = tea5767_stereo;
+
+       return (0);
+}
index eaabfc85870368f1f9b25127a8de054cefe73387..6f6bf4a633fc7449a774031a158b431163ba91c5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: tuner-core.c,v 1.15 2005/06/12 01:36:14 mchehab Exp $
+ * $Id: tuner-core.c,v 1.29 2005/06/21 15:40:33 mchehab Exp $
  *
  * i2c tv tuner chip device driver
  * core core, i.e. kernel interfaces, registering and so on
@@ -26,7 +26,6 @@
 /*
  * comment line bellow to return to old behavor, where only one I2C device is supported
  */
-#define CONFIG_TUNER_MULTI_I2C /**/
 
 #define UNSET (-1U)
 
@@ -58,9 +57,7 @@ MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
 MODULE_LICENSE("GPL");
 
 static int this_adap;
-#ifdef CONFIG_TUNER_MULTI_I2C
 static unsigned short first_tuner, tv_tuner, radio_tuner;
-#endif
 
 static struct i2c_driver driver;
 static struct i2c_client client_template;
@@ -81,26 +78,9 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
                return;
        }
        if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
-
-               if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) {
-                       /* V4L2_TUNER_CAP_LOW frequency */
-
-                       tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for TV. Tuners yet doesn't support converting it to valid freq.\n");
-
-                       t->tv_freq(c,freq>>10);
-
-                       return;
-                } else {
-                       /* FIXME: better do that chip-specific, but
-                          right now we don't have that in the config
-                          struct and this way is still better than no
-                          check at all */
                        tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n",
                                   freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
-                       return;
-               }
        }
-       tuner_dbg("62.5 Khz freq step selected for TV.\n");
        t->tv_freq(c,freq);
 }
 
@@ -116,31 +96,18 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
                tuner_info("no radio tuning for this one, sorry.\n");
                return;
        }
-       if (freq < radio_range[0]*16 || freq > radio_range[1]*16) {
-               if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) {
-                       /* V4L2_TUNER_CAP_LOW frequency */
-                       if (t->type == TUNER_TEA5767) {
-                               tuner_info("radio freq step 62.5Hz (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000);
-                               t->radio_freq(c,freq>>10);
-                               return;
-                       }
-
-                       tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for Radio. Tuners yet doesn't support converting it to valid freq.\n");
-
-                       tuner_info("radio freq (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000);
-
-                       t->radio_freq(c,freq>>10);
-                       return;
-
-                } else {
-                       tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
-                          freq/16,freq%16*100/16,
-                                  radio_range[0],radio_range[1]);
-                       return;
-               }
+       if (freq >= radio_range[0]*16000 && freq <= radio_range[1]*16000) {
+               if (tuner_debug)
+                       tuner_info("radio freq step 62.5Hz (%d.%06d)\n",
+                                           freq/16000,freq%16000*1000/16);
+               t->radio_freq(c,freq);
+        } else {
+               tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
+                           freq/16,freq%16*100/16,
+                           radio_range[0],radio_range[1]);
        }
-       tuner_dbg("62.5 Khz freq step selected for Radio.\n");
-       t->radio_freq(c,freq);
+
+       return;
 }
 
 static void set_freq(struct i2c_client *c, unsigned long freq)
@@ -166,8 +133,8 @@ static void set_freq(struct i2c_client *c, unsigned long freq)
 static void set_type(struct i2c_client *c, unsigned int type)
 {
        struct tuner *t = i2c_get_clientdata(c);
+       unsigned char buffer[4];
 
-       tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type);
        /* sanity check */
        if (type == UNSET || type == TUNER_ABSENT)
                return;
@@ -179,8 +146,8 @@ static void set_type(struct i2c_client *c, unsigned int type)
                t->type = type;
                return;
        }
-       if (t->initialized)
-               /* run only once */
+       if ((t->initialized) && (t->type == type))
+               /* run only once except type change  Hac 04/05*/
                return;
 
        t->initialized = 1;
@@ -193,25 +160,42 @@ static void set_type(struct i2c_client *c, unsigned int type)
        case TUNER_PHILIPS_TDA8290:
                tda8290_init(c);
                break;
+       case TUNER_TEA5767:
+               if (tea5767_tuner_init(c)==EINVAL) t->type=TUNER_ABSENT;
+               break;
+       case TUNER_PHILIPS_FMD1216ME_MK3:
+               buffer[0] = 0x0b;
+               buffer[1] = 0xdc;
+               buffer[2] = 0x9c;
+               buffer[3] = 0x60;
+               i2c_master_send(c,buffer,4);
+               mdelay(1);
+               buffer[2] = 0x86;
+               buffer[3] = 0x54;
+               i2c_master_send(c,buffer,4);
+               default_tuner_init(c);
+               break;
        default:
+               /* TEA5767 autodetection code */
+                       if (tea5767_tuner_init(c)!=EINVAL) {
+                               t->type = TUNER_TEA5767;
+                               if (first_tuner == 0x60)
+                                       first_tuner++;
+                               break;
+                       }
+
                default_tuner_init(c);
                break;
        }
+       tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type);
 }
 
-#ifdef CONFIG_TUNER_MULTI_I2C
 #define CHECK_ADDR(tp,cmd,tun) if (client->addr!=tp) { \
-                         return 0; } else \
+                         return 0; } else if (tuner_debug) \
                          tuner_info ("Cmd %s accepted to "tun"\n",cmd);
 #define CHECK_MODE(cmd)        if (t->mode == V4L2_TUNER_RADIO) { \
                        CHECK_ADDR(radio_tuner,cmd,"radio") } else \
                        { CHECK_ADDR(tv_tuner,cmd,"TV"); }
-#else
-#define CHECK_ADDR(tp,cmd,tun) tuner_info ("Cmd %s accepted to "tun"\n",cmd);
-#define CHECK_MODE(cmd) tuner_info ("Cmd %s accepted\n",cmd);
-#endif
-
-#ifdef CONFIG_TUNER_MULTI_I2C
 
 static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr)
 {
@@ -242,9 +226,6 @@ static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr)
        }
        set_type(c,tun_addr->type);
 }
-#else
-#define set_addr(c,tun_addr) set_type(c,(tun_addr)->type)
-#endif
 
 static char pal[] = "-";
 module_param_string(pal, pal, sizeof(pal), 0644);
@@ -284,17 +265,12 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
 {
        struct tuner *t;
 
-#ifndef CONFIG_TUNER_MULTI_I2C
-       if (this_adap > 0)
-               return -1;
-#else
        /* by default, first I2C card is both tv and radio tuner */
        if (this_adap == 0) {
                first_tuner = addr;
                tv_tuner = addr;
                radio_tuner = addr;
        }
-#endif
        this_adap++;
 
         client_template.adapter = adap;
@@ -308,6 +284,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
        i2c_set_clientdata(&t->i2c, t);
        t->type       = UNSET;
        t->radio_if2  = 10700*1000; /* 10.7MHz - FM radio */
+       t->audmode    = V4L2_TUNER_MODE_STEREO;
 
         i2c_attach_client(&t->i2c);
        tuner_info("chip found @ 0x%x (%s)\n",
@@ -325,11 +302,9 @@ static int tuner_probe(struct i2c_adapter *adap)
        }
        this_adap = 0;
 
-#ifdef CONFIG_TUNER_MULTI_I2C
        first_tuner = 0;
        tv_tuner = 0;
        radio_tuner = 0;
-#endif
 
        if (adap->class & I2C_CLASS_TV_ANALOG)
                return i2c_probe(adap, &addr_data, tuner_attach);
@@ -392,8 +367,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                        t->radio_if2 = 41300 * 1000;
                        break;
                }
-                break;
-
+               break;
        /* --- v4l ioctls --- */
        /* take care: bttv does userspace copying, we'll get a
           kernel pointer here... */
@@ -440,11 +414,18 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                                vt->signal = t->has_signal(client);
                        if (t->is_stereo) {
                                if (t->is_stereo(client))
-                                       vt-> flags |= VIDEO_TUNER_STEREO_ON;
+                                       vt->flags |= VIDEO_TUNER_STEREO_ON;
                                else
-                                       vt-> flags &= 0xffff ^ VIDEO_TUNER_STEREO_ON;
+                                       vt->flags &= ~VIDEO_TUNER_STEREO_ON;
                        }
                        vt->flags |= V4L2_TUNER_CAP_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;
@@ -510,20 +491,46 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                                tuner -> signal = t->has_signal(client);
                        if (t->is_stereo) {
                                if (t->is_stereo(client)) {
-                                       tuner -> capability |= V4L2_TUNER_CAP_STEREO;
-                                       tuner -> rxsubchans |= V4L2_TUNER_SUB_STEREO;
+                                       tuner -> rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
                                } else {
-                                       tuner -> rxsubchans &= 0xffff ^ V4L2_TUNER_SUB_STEREO;
+                                       tuner -> rxsubchans = V4L2_TUNER_SUB_MONO;
                                }
                        }
+                       tuner->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
+                       tuner->audmode = t->audmode;
+
+                       tuner->rangelow = radio_range[0] * 16000;
+                       tuner->rangehigh = radio_range[1] * 16000;
+               } else {
+                       tuner->rangelow = tv_range[0] * 16;
+                       tuner->rangehigh = tv_range[1] * 16;
                }
-               /* Wow to deal with V4L2_TUNER_CAP_LOW ? For now, it accepts from low at 62.5KHz step  to high at 62.5 Hz */
-               tuner->rangelow = tv_range[0] * 16;
-//             tuner->rangehigh = tv_range[1] * 16;
-//             tuner->rangelow = tv_range[0] * 16384;
-               tuner->rangehigh = tv_range[1] * 16384;
                break;
        }
+       case VIDIOC_S_TUNER: /* Allow changing radio range and audio mode */
+       {
+               struct v4l2_tuner *tuner = arg;
+
+               CHECK_ADDR(radio_tuner,"VIDIOC_S_TUNER","radio");
+               SWITCH_V4L2;
+
+               /* To switch the audio mode, applications initialize the
+                  index and audmode fields and the reserved array and
+                  call the VIDIOC_S_TUNER ioctl. */
+               /* rxsubchannels: V4L2_TUNER_MODE_MONO, V4L2_TUNER_MODE_STEREO,
+                  V4L2_TUNER_MODE_LANG1, V4L2_TUNER_MODE_LANG2,
+                  V4L2_TUNER_MODE_SAP */
+
+               if (tuner->audmode == V4L2_TUNER_MODE_MONO)
+                       t->audmode = V4L2_TUNER_MODE_MONO;
+               else
+                       t->audmode = V4L2_TUNER_MODE_STEREO;
+
+               set_radio_freq(client, t->freq);
+               break;
+       }
+       case TDA9887_SET_CONFIG: /* Nothing to do on tuner-core */
+               break;
        default:
                tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd);
                /* nothing */
index 539f305573170661664b4b1795f1a8e68b763135..c39ed6226ee090c9f1c80051763246142242b659 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: tuner-simple.c,v 1.21 2005/06/10 19:53:26 nsh Exp $
+ * $Id: tuner-simple.c,v 1.31 2005/06/21 16:02:25 mkrufky Exp $
  *
  * i2c tv tuner chip device driver
  * controls all those simple 4-control-bytes style tuners.
@@ -207,28 +207,27 @@ static struct tunertype tuners[] = {
        { "LG PAL (TAPE series)", LGINNOTEK, PAL,
           16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
 
-        { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
-          16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
-        { "Philips FQ1236A MK4", Philips, NTSC,
-          16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
+       { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
+         16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
+       { "Philips FQ1236A MK4", Philips, NTSC,
+         16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
 
        /* Should work for TVF8531MF, TVF8831MF, TVF8731MF */
        { "Ymec TVision TVF-8531MF", Philips, NTSC,
          16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
        { "Ymec TVision TVF-5533MF", Philips, NTSC,
          16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
-
        { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
          16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
-       { "Tena TNF9533-D/IF", LGINNOTEK, PAL,
-         16*160.25, 16*464.25, 0x01,0x02,0x08,0x8e,623},
+       /* Should work for TNF9533-D/IF, TNF9533-B/DF */
+       { "Tena TNF9533-D/IF", Philips, PAL,
+          16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623},
 
-       /*
-        * This entry is for TEA5767 FM radio only chip used on several boards
-        * w/TV tuner
-        */
+       /* This entry is for TEA5767 FM radio only chip used on several boards w/TV tuner */
        { TEA5767_TUNER_NAME, Philips, RADIO,
-         -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0},
+          -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0},
+       { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
+         16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
 };
 
 unsigned const int tuner_count = ARRAY_SIZE(tuners);
@@ -455,24 +454,24 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
        int rc;
 
        tun=&tuners[t->type];
-       div = freq + (int)(16*10.7);
+       div = (freq / 1000) + (int)(16*10.7);
        buffer[2] = tun->config;
 
        switch (t->type) {
        case TUNER_TENA_9533_DI:
        case TUNER_YMEC_TVF_5533MF:
-
                /*These values are empirically determinated */
-               div = (freq*122)/16 - 20;
+               div = (freq * 122) / 16000 - 20;
                buffer[2] = 0x88; /* could be also 0x80 */
                buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */
                break;
        case TUNER_PHILIPS_FM1216ME_MK3:
        case TUNER_PHILIPS_FM1236_MK3:
+       case TUNER_PHILIPS_FMD1216ME_MK3:
                buffer[3] = 0x19;
                break;
        case TUNER_PHILIPS_FM1256_IH3:
-               div = (20 * freq)/16 + 333 * 2;
+               div = (20 * freq) / 16000 + 333 * 2;
                buffer[2] = 0x80;
                buffer[3] = 0x19;
                break;
@@ -505,6 +504,7 @@ int default_tuner_init(struct i2c_client *c)
        t->radio_freq = default_set_radio_freq;
        t->has_signal = tuner_signal;
        t->is_stereo  = tuner_stereo;
+
        return 0;
 }
 
index d8d65397e06e668be27cebf001e6681ddfd253c4..353deb25e3978bb300865be18affdbb455545e4a 100644 (file)
@@ -364,9 +364,7 @@ static struct pci_driver mptfc_driver = {
        .id_table       = mptfc_pci_table,
        .probe          = mptfc_probe,
        .remove         = __devexit_p(mptscsih_remove),
-       .driver         = {
-               .shutdown = mptscsih_shutdown,
-        },
+       .shutdown       = mptscsih_shutdown,
 #ifdef CONFIG_PM
        .suspend        = mptscsih_suspend,
        .resume         = mptscsih_resume,
index a0078ae5b9b84587a0d8ed0de8f78f71755d5fc6..4f973a49be4c125e8634dcd29db4ec5649ecc520 100644 (file)
@@ -170,7 +170,7 @@ static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
 #endif
 
 void           mptscsih_remove(struct pci_dev *);
-void           mptscsih_shutdown(struct device *);
+void           mptscsih_shutdown(struct pci_dev *);
 #ifdef CONFIG_PM
 int            mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
 int            mptscsih_resume(struct pci_dev *pdev);
@@ -988,7 +988,7 @@ mptscsih_remove(struct pci_dev *pdev)
 #endif
 #endif
 
-       mptscsih_shutdown(&pdev->dev);
+       mptscsih_shutdown(pdev);
 
        sz1=0;
 
@@ -1026,9 +1026,9 @@ mptscsih_remove(struct pci_dev *pdev)
  *
  */
 void
-mptscsih_shutdown(struct device * dev)
+mptscsih_shutdown(struct pci_dev *pdev)
 {
-       MPT_ADAPTER             *ioc = pci_get_drvdata(to_pci_dev(dev));
+       MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
        struct Scsi_Host        *host = ioc->sh;
        MPT_SCSI_HOST           *hd;
 
@@ -1054,7 +1054,7 @@ mptscsih_shutdown(struct device * dev)
 int
 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-       mptscsih_shutdown(&pdev->dev);
+       mptscsih_shutdown(pdev);
        return mpt_suspend(pdev,state);
 }
 
index d73aec33e16a35ee3bac0b3109d8a6ae4739b706..5ea89bf0df199862e26c1398f006818b852ea66d 100644 (file)
@@ -82,7 +82,7 @@
 #endif
 
 extern void mptscsih_remove(struct pci_dev *);
-extern void mptscsih_shutdown(struct device *);
+extern void mptscsih_shutdown(struct pci_dev *);
 #ifdef CONFIG_PM
 extern int mptscsih_suspend(struct pci_dev *pdev, u32 state);
 extern int mptscsih_resume(struct pci_dev *pdev);
index 5f9a61b85b3b6c3b0c65c1f0581f21fe09769b22..e0c0ee5bc9662386e73c79af9ceded98d9623a72 100644 (file)
@@ -419,9 +419,7 @@ static struct pci_driver mptspi_driver = {
        .id_table       = mptspi_pci_table,
        .probe          = mptspi_probe,
        .remove         = __devexit_p(mptscsih_remove),
-       .driver         = {
-               .shutdown = mptscsih_shutdown,
-        },
+       .shutdown       = mptscsih_shutdown,
 #ifdef CONFIG_PM
        .suspend        = mptscsih_suspend,
        .resume         = mptscsih_resume,
index 1e56c8eea35fdfa41f39b0e0372cd9ee15873c65..d0fa2448761d0fdb1dcebae2b23de9b9c23d0b25 100644 (file)
@@ -2447,9 +2447,8 @@ static int e100_resume(struct pci_dev *pdev)
 #endif
 
 
-static void e100_shutdown(struct device *dev)
+static void e100_shutdown(struct pci_dev *pdev)
 {
-       struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct nic *nic = netdev_priv(netdev);
 
@@ -2470,11 +2469,7 @@ static struct pci_driver e100_driver = {
        .suspend =      e100_suspend,
        .resume =       e100_resume,
 #endif
-
-       .driver = {
-               .shutdown = e100_shutdown,
-       }
-
+       .shutdown =     e100_shutdown,
 };
 
 static int __init e100_init_module(void)
index a56ef0df203ad223ca0575407bb9d0bc37c0cad3..fc7738ffbfffeb1ffd17c7724426169b65531372 100644 (file)
@@ -507,7 +507,7 @@ static struct net_device_stats *rhine_get_stats(struct net_device *dev);
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static struct ethtool_ops netdev_ethtool_ops;
 static int  rhine_close(struct net_device *dev);
-static void rhine_shutdown (struct device *gdev);
+static void rhine_shutdown (struct pci_dev *pdev);
 
 #define RHINE_WAIT_FOR(condition) do {                                 \
        int i=1024;                                                     \
@@ -1895,9 +1895,8 @@ static void __devexit rhine_remove_one(struct pci_dev *pdev)
        pci_set_drvdata(pdev, NULL);
 }
 
-static void rhine_shutdown (struct device *gendev)
+static void rhine_shutdown (struct pci_dev *pdev)
 {
-       struct pci_dev *pdev = to_pci_dev(gendev);
        struct net_device *dev = pci_get_drvdata(pdev);
        struct rhine_private *rp = netdev_priv(dev);
        void __iomem *ioaddr = rp->base;
@@ -1956,7 +1955,7 @@ static int rhine_suspend(struct pci_dev *pdev, pm_message_t state)
        pci_save_state(pdev);
 
        spin_lock_irqsave(&rp->lock, flags);
-       rhine_shutdown(&pdev->dev);
+       rhine_shutdown(pdev);
        spin_unlock_irqrestore(&rp->lock, flags);
 
        free_irq(dev->irq, dev);
@@ -2010,9 +2009,7 @@ static struct pci_driver rhine_driver = {
        .suspend        = rhine_suspend,
        .resume         = rhine_resume,
 #endif /* CONFIG_PM */
-       .driver = {
-               .shutdown = rhine_shutdown,
-       }
+       .shutdown =     rhine_shutdown,
 };
 
 
index b0d2a73d1d473407ff7b7c25ec7b12f7c8ba55ff..2f2dbef2c3b7bf46df13309aa74e3446c32ab695 100644 (file)
@@ -993,6 +993,7 @@ dino_driver_callback(struct parisc_device *dev)
        bus = pci_scan_bus_parented(&dev->dev, dino_current_bus,
                                    &dino_cfg_ops, NULL);
        if(bus) {
+               pci_bus_add_devices(bus);
                /* This code *depends* on scanning being single threaded
                 * if it isn't, this global bus number count will fail
                 */
index dc838804c0dda41363e0529fffeaf9b0955e210b..7fdd80b7eb479b801cfccdb511ae7730f588abaf 100644 (file)
@@ -1570,6 +1570,8 @@ lba_driver_probe(struct parisc_device *dev)
        lba_bus = lba_dev->hba.hba_bus =
                pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,
                                cfg_ops, NULL);
+       if (lba_bus)
+               pci_bus_add_devices(lba_bus);
 
        /* This is in lieu of calling pci_assign_unassigned_resources() */
        if (is_pdc_pat()) {
index dbd33605cc107c058e028ab447ca39eb1c814001..fedae89d8f7d5678b7b7126a084b8a49a9939858 100644 (file)
@@ -121,10 +121,13 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus)
                 * If there is an unattached subordinate bus, attach
                 * it and then scan for unattached PCI devices.
                 */
-               if (dev->subordinate && list_empty(&dev->subordinate->node)) {
-                       spin_lock(&pci_bus_lock);
-                       list_add_tail(&dev->subordinate->node, &dev->bus->children);
-                       spin_unlock(&pci_bus_lock);
+               if (dev->subordinate) {
+                      if (list_empty(&dev->subordinate->node)) {
+                              spin_lock(&pci_bus_lock);
+                              list_add_tail(&dev->subordinate->node,
+                                              &dev->bus->children);
+                              spin_unlock(&pci_bus_lock);
+                      }
                        pci_bus_add_devices(dev->subordinate);
 
                        sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge");
index 93c120ddbd395f5ddeddcc3cc5d52bd31a47dcc4..3e632ff8c717116d0dca075a6ec969e2b1acf31f 100644 (file)
@@ -36,9 +36,7 @@ ibmphp-objs           :=      ibmphp_core.o   \
                                ibmphp_hpc.o
 
 acpiphp-objs           :=      acpiphp_core.o  \
-                               acpiphp_glue.o  \
-                               acpiphp_pci.o   \
-                               acpiphp_res.o
+                               acpiphp_glue.o
 
 rpaphp-objs            :=      rpaphp_core.o   \
                                rpaphp_pci.o    \
index d9499874c8a90e84cfa5df3f33732c0b03c5604d..293603e1b7c3b10f64f281087f26a51d32da47a1 100644 (file)
@@ -7,6 +7,8 @@
  * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
  * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
  * Copyright (C) 2002,2003 NEC Corporation
+ * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
+ * Copyright (C) 2003-2005 Hewlett Packard
  *
  * All rights reserved.
  *
@@ -52,7 +54,6 @@
 
 struct acpiphp_bridge;
 struct acpiphp_slot;
-struct pci_resource;
 
 /*
  * struct slot - slot information for each *physical* slot
@@ -65,15 +66,6 @@ struct slot {
        struct acpiphp_slot     *acpi_slot;
 };
 
-/*
- * struct pci_resource - describes pci resource (mem, pfmem, io, bus)
- */
-struct pci_resource {
-       struct pci_resource * next;
-       u64 base;
-       u32 length;
-};
-
 /**
  * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters
  * @cache_line_size in DWORD
@@ -101,10 +93,6 @@ struct acpiphp_bridge {
        int type;
        int nr_slots;
 
-       u8 seg;
-       u8 bus;
-       u8 sub;
-
        u32 flags;
 
        /* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */
@@ -117,12 +105,6 @@ struct acpiphp_bridge {
        struct hpp_param hpp;
 
        spinlock_t res_lock;
-
-       /* available resources on this bus */
-       struct pci_resource *mem_head;
-       struct pci_resource *p_mem_head;
-       struct pci_resource *io_head;
-       struct pci_resource *bus_head;
 };
 
 
@@ -163,12 +145,6 @@ struct acpiphp_func {
 
        u8              function;       /* pci function# */
        u32             flags;          /* see below */
-
-       /* resources used for this function */
-       struct pci_resource *mem_head;
-       struct pci_resource *p_mem_head;
-       struct pci_resource *io_head;
-       struct pci_resource *bus_head;
 };
 
 /**
@@ -243,25 +219,6 @@ extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
 extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
 extern u32 acpiphp_get_address (struct acpiphp_slot *slot);
 
-/* acpiphp_pci.c */
-extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn);
-extern int acpiphp_configure_slot (struct acpiphp_slot *slot);
-extern int acpiphp_configure_function (struct acpiphp_func *func);
-extern void acpiphp_unconfigure_function (struct acpiphp_func *func);
-extern int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge);
-extern int acpiphp_init_func_resource (struct acpiphp_func *func);
-
-/* acpiphp_res.c */
-extern struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size);
-extern struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size);
-extern struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size);
-extern int acpiphp_resource_sort_and_combine (struct pci_resource **head);
-extern struct pci_resource *acpiphp_make_resource (u64 base, u32 length);
-extern void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to);
-extern void acpiphp_free_resource (struct pci_resource **res);
-extern void acpiphp_dump_resource (struct acpiphp_bridge *bridge); /* debug */
-extern void acpiphp_dump_func_resource (struct acpiphp_func *func); /* debug */
-
 /* variables */
 extern int acpiphp_debug;
 
index 4539e61a3dc1f07cfb2797b08a0d00c68cfb7ad0..60c4c38047a3a63f4b308d269ddbb520c171a9e2 100644 (file)
@@ -7,6 +7,8 @@
  * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
  * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
  * Copyright (C) 2002,2003 NEC Corporation
+ * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
+ * Copyright (C) 2003-2005 Hewlett Packard
  *
  * All rights reserved.
  *
@@ -53,8 +55,8 @@ int acpiphp_debug;
 static int num_slots;
 static struct acpiphp_attention_info *attention_info;
 
-#define DRIVER_VERSION "0.4"
-#define DRIVER_AUTHOR  "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>"
+#define DRIVER_VERSION "0.5"
+#define DRIVER_AUTHOR  "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>, Matthew Wilcox <willy@hp.com>"
 #define DRIVER_DESC    "ACPI Hot Plug PCI Controller Driver"
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
@@ -281,8 +283,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
 /**
  * get_address - get pci address of a slot
  * @hotplug_slot: slot to get status
- * @busdev: pointer to struct pci_busdev (seg, bus, dev)
- *
+ * @value: pointer to struct pci_busdev (seg, bus, dev)
  */
 static int get_address(struct hotplug_slot *hotplug_slot, u32 *value)
 {
index e7f41294f81130bf65f90b6448f1bd4121df04dc..424e7de181aed457457374830ea059c3be1833fa 100644 (file)
@@ -4,6 +4,10 @@
  * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
  * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
  * Copyright (C) 2002,2003 NEC Corporation
+ * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
+ * Copyright (C) 2003-2005 Hewlett Packard
+ * Copyright (C) 2005 Rajesh Shah (rajesh.shah@intel.com)
+ * Copyright (C) 2005 Intel Corporation
  *
  * All rights reserved.
  *
  *
  */
 
+/*
+ * Lifetime rules for pci_dev:
+ *  - The one in acpiphp_func has its refcount elevated by pci_get_slot()
+ *    when the driver is loaded or when an insertion event occurs.  It loses
+ *    a refcount when its ejected or the driver unloads.
+ *  - The one in acpiphp_bridge has its refcount elevated by pci_get_slot()
+ *    when the bridge is scanned and it loses a refcount when the bridge
+ *    is removed.
+ */
+
 #include <linux/init.h>
 #include <linux/module.h>
 
@@ -178,21 +192,18 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 
                bridge->nr_slots++;
 
-               dbg("found ACPI PCI Hotplug slot at PCI %02x:%02x Slot:%d\n",
-                   slot->bridge->bus, slot->device, slot->sun);
+               dbg("found ACPI PCI Hotplug slot %d at PCI %04x:%02x:%02x\n",
+                               slot->sun, pci_domain_nr(bridge->pci_bus),
+                               bridge->pci_bus->number, slot->device);
        }
 
        newfunc->slot = slot;
        list_add_tail(&newfunc->sibling, &slot->funcs);
 
        /* associate corresponding pci_dev */
-       newfunc->pci_dev = pci_find_slot(bridge->bus,
+       newfunc->pci_dev = pci_get_slot(bridge->pci_bus,
                                         PCI_DEVFN(device, function));
        if (newfunc->pci_dev) {
-               if (acpiphp_init_func_resource(newfunc) < 0) {
-                       kfree(newfunc);
-                       return AE_ERROR;
-               }
                slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
        }
 
@@ -227,62 +238,6 @@ static int detect_ejectable_slots(acpi_handle *bridge_handle)
 }
 
 
-/* decode ACPI _CRS data and convert into our internal resource list
- * TBD: _TRA, etc.
- */
-static acpi_status
-decode_acpi_resource(struct acpi_resource *resource, void *context)
-{
-       struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context;
-       struct acpi_resource_address64 address;
-       struct pci_resource *res;
-
-       if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
-           resource->id != ACPI_RSTYPE_ADDRESS32 &&
-           resource->id != ACPI_RSTYPE_ADDRESS64)
-               return AE_OK;
-
-       acpi_resource_to_address64(resource, &address);
-
-       if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) {
-               dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type,
-                   (unsigned long long)address.min_address_range,
-                   (unsigned long long)address.max_address_range);
-               res = acpiphp_make_resource(address.min_address_range,
-                                   address.address_length);
-               if (!res) {
-                       err("out of memory\n");
-                       return AE_OK;
-               }
-
-               switch (address.resource_type) {
-               case ACPI_MEMORY_RANGE:
-                       if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
-                               res->next = bridge->p_mem_head;
-                               bridge->p_mem_head = res;
-                       } else {
-                               res->next = bridge->mem_head;
-                               bridge->mem_head = res;
-                       }
-                       break;
-               case ACPI_IO_RANGE:
-                       res->next = bridge->io_head;
-                       bridge->io_head = res;
-                       break;
-               case ACPI_BUS_NUMBER_RANGE:
-                       res->next = bridge->bus_head;
-                       bridge->bus_head = res;
-                       break;
-               default:
-                       /* invalid type */
-                       kfree(res);
-                       break;
-               }
-       }
-
-       return AE_OK;
-}
-
 /* decode ACPI 2.0 _HPP hot plug parameters */
 static void decode_hpp(struct acpiphp_bridge *bridge)
 {
@@ -346,34 +301,29 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge)
        /* decode ACPI 2.0 _HPP (hot plug parameters) */
        decode_hpp(bridge);
 
-       /* subtract all resources already allocated */
-       acpiphp_detect_pci_resource(bridge);
-
        /* register all slot objects under this bridge */
        status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
                                     register_slot, bridge, NULL);
 
        /* install notify handler */
-       status = acpi_install_notify_handler(bridge->handle,
+       if (bridge->type != BRIDGE_TYPE_HOST) {
+               status = acpi_install_notify_handler(bridge->handle,
                                             ACPI_SYSTEM_NOTIFY,
                                             handle_hotplug_event_bridge,
                                             bridge);
 
-       if (ACPI_FAILURE(status)) {
-               err("failed to register interrupt notify handler\n");
+               if (ACPI_FAILURE(status)) {
+                       err("failed to register interrupt notify handler\n");
+               }
        }
 
        list_add(&bridge->list, &bridge_list);
-
-       dbg("Bridge resource:\n");
-       acpiphp_dump_resource(bridge);
 }
 
 
 /* allocate and initialize host bridge data structure */
-static void add_host_bridge(acpi_handle *handle, int seg, int bus)
+static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
 {
-       acpi_status status;
        struct acpiphp_bridge *bridge;
 
        bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
@@ -384,52 +334,19 @@ static void add_host_bridge(acpi_handle *handle, int seg, int bus)
 
        bridge->type = BRIDGE_TYPE_HOST;
        bridge->handle = handle;
-       bridge->seg = seg;
-       bridge->bus = bus;
 
-       bridge->pci_bus = pci_find_bus(seg, bus);
+       bridge->pci_bus = pci_bus;
 
        spin_lock_init(&bridge->res_lock);
 
-       /* to be overridden when we decode _CRS */
-       bridge->sub = bridge->bus;
-
-       /* decode resources */
-
-       status = acpi_walk_resources(handle, METHOD_NAME__CRS,
-               decode_acpi_resource, bridge);
-
-       if (ACPI_FAILURE(status)) {
-               err("failed to decode bridge resources\n");
-               kfree(bridge);
-               return;
-       }
-
-       acpiphp_resource_sort_and_combine(&bridge->io_head);
-       acpiphp_resource_sort_and_combine(&bridge->mem_head);
-       acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
-       acpiphp_resource_sort_and_combine(&bridge->bus_head);
-
-       dbg("ACPI _CRS resource:\n");
-       acpiphp_dump_resource(bridge);
-
-       if (bridge->bus_head) {
-               bridge->bus = bridge->bus_head->base;
-               bridge->sub = bridge->bus_head->base + bridge->bus_head->length - 1;
-       }
-
        init_bridge_misc(bridge);
 }
 
 
 /* allocate and initialize PCI-to-PCI bridge data structure */
-static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int fn)
+static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
 {
        struct acpiphp_bridge *bridge;
-       u8 tmp8;
-       u16 tmp16;
-       u64 base64, limit64;
-       u32 base, limit, base32u, limit32u;
 
        bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
        if (bridge == NULL) {
@@ -441,133 +358,22 @@ static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int f
 
        bridge->type = BRIDGE_TYPE_P2P;
        bridge->handle = handle;
-       bridge->seg = seg;
-
-       bridge->pci_dev = pci_find_slot(bus, PCI_DEVFN(dev, fn));
-       if (!bridge->pci_dev) {
-               err("Can't get pci_dev\n");
-               kfree(bridge);
-               return;
-       }
 
-       bridge->pci_bus = bridge->pci_dev->subordinate;
+       bridge->pci_dev = pci_dev_get(pci_dev);
+       bridge->pci_bus = pci_dev->subordinate;
        if (!bridge->pci_bus) {
                err("This is not a PCI-to-PCI bridge!\n");
-               kfree(bridge);
-               return;
+               goto err;
        }
 
        spin_lock_init(&bridge->res_lock);
 
-       bridge->bus = bridge->pci_bus->number;
-       bridge->sub = bridge->pci_bus->subordinate;
-
-       /*
-        * decode resources under this P2P bridge
-        */
-
-       /* I/O resources */
-       pci_read_config_byte(bridge->pci_dev, PCI_IO_BASE, &tmp8);
-       base = tmp8;
-       pci_read_config_byte(bridge->pci_dev, PCI_IO_LIMIT, &tmp8);
-       limit = tmp8;
-
-       switch (base & PCI_IO_RANGE_TYPE_MASK) {
-       case PCI_IO_RANGE_TYPE_16:
-               base = (base << 8) & 0xf000;
-               limit = ((limit << 8) & 0xf000) + 0xfff;
-               bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
-               if (!bridge->io_head) {
-                       err("out of memory\n");
-                       kfree(bridge);
-                       return;
-               }
-               dbg("16bit I/O range: %04x-%04x\n",
-                   (u32)bridge->io_head->base,
-                   (u32)(bridge->io_head->base + bridge->io_head->length - 1));
-               break;
-       case PCI_IO_RANGE_TYPE_32:
-               pci_read_config_word(bridge->pci_dev, PCI_IO_BASE_UPPER16, &tmp16);
-               base = ((u32)tmp16 << 16) | ((base << 8) & 0xf000);
-               pci_read_config_word(bridge->pci_dev, PCI_IO_LIMIT_UPPER16, &tmp16);
-               limit = (((u32)tmp16 << 16) | ((limit << 8) & 0xf000)) + 0xfff;
-               bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
-               if (!bridge->io_head) {
-                       err("out of memory\n");
-                       kfree(bridge);
-                       return;
-               }
-               dbg("32bit I/O range: %08x-%08x\n",
-                   (u32)bridge->io_head->base,
-                   (u32)(bridge->io_head->base + bridge->io_head->length - 1));
-               break;
-       case 0x0f:
-               dbg("I/O space unsupported\n");
-               break;
-       default:
-               warn("Unknown I/O range type\n");
-       }
-
-       /* Memory resources (mandatory for P2P bridge) */
-       pci_read_config_word(bridge->pci_dev, PCI_MEMORY_BASE, &tmp16);
-       base = (tmp16 & 0xfff0) << 16;
-       pci_read_config_word(bridge->pci_dev, PCI_MEMORY_LIMIT, &tmp16);
-       limit = ((tmp16 & 0xfff0) << 16) | 0xfffff;
-       bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
-       if (!bridge->mem_head) {
-               err("out of memory\n");
-               kfree(bridge);
-               return;
-       }
-       dbg("32bit Memory range: %08x-%08x\n",
-           (u32)bridge->mem_head->base,
-           (u32)(bridge->mem_head->base + bridge->mem_head->length-1));
-
-       /* Prefetchable Memory resources (optional) */
-       pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_BASE, &tmp16);
-       base = tmp16;
-       pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_LIMIT, &tmp16);
-       limit = tmp16;
-
-       switch (base & PCI_MEMORY_RANGE_TYPE_MASK) {
-       case PCI_PREF_RANGE_TYPE_32:
-               base = (base & 0xfff0) << 16;
-               limit = ((limit & 0xfff0) << 16) | 0xfffff;
-               bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
-               if (!bridge->p_mem_head) {
-                       err("out of memory\n");
-                       kfree(bridge);
-                       return;
-               }
-               dbg("32bit Prefetchable memory range: %08x-%08x\n",
-                   (u32)bridge->p_mem_head->base,
-                   (u32)(bridge->p_mem_head->base + bridge->p_mem_head->length - 1));
-               break;
-       case PCI_PREF_RANGE_TYPE_64:
-               pci_read_config_dword(bridge->pci_dev, PCI_PREF_BASE_UPPER32, &base32u);
-               pci_read_config_dword(bridge->pci_dev, PCI_PREF_LIMIT_UPPER32, &limit32u);
-               base64 = ((u64)base32u << 32) | ((base & 0xfff0) << 16);
-               limit64 = (((u64)limit32u << 32) | ((limit & 0xfff0) << 16)) + 0xfffff;
-
-               bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1);
-               if (!bridge->p_mem_head) {
-                       err("out of memory\n");
-                       kfree(bridge);
-                       return;
-               }
-               dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n",
-                   (u32)(bridge->p_mem_head->base >> 32),
-                   (u32)(bridge->p_mem_head->base & 0xffffffff),
-                   (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) >> 32),
-                   (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) & 0xffffffff));
-               break;
-       case 0x0f:
-               break;
-       default:
-               warn("Unknown prefetchale memory type\n");
-       }
-
        init_bridge_misc(bridge);
+       return;
+ err:
+       pci_dev_put(pci_dev);
+       kfree(bridge);
+       return;
 }
 
 
@@ -577,14 +383,10 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
        acpi_status status;
        acpi_handle dummy_handle;
-       unsigned long *segbus = context;
        unsigned long tmp;
-       int seg, bus, device, function;
+       int device, function;
        struct pci_dev *dev;
-
-       /* get PCI address */
-       seg = (*segbus >> 8) & 0xff;
-       bus = *segbus & 0xff;
+       struct pci_bus *pci_bus = context;
 
        status = acpi_get_handle(handle, "_ADR", &dummy_handle);
        if (ACPI_FAILURE(status))
@@ -599,20 +401,19 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
        device = (tmp >> 16) & 0xffff;
        function = tmp & 0xffff;
 
-       dev = pci_find_slot(bus, PCI_DEVFN(device, function));
+       dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function));
 
-       if (!dev)
-               return AE_OK;
-
-       if (!dev->subordinate)
-               return AE_OK;
+       if (!dev || !dev->subordinate)
+               goto out;
 
        /* check if this bridge has ejectable slots */
        if (detect_ejectable_slots(handle) > 0) {
                dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
-               add_p2p_bridge(handle, seg, bus, device, function);
+               add_p2p_bridge(handle, dev);
        }
 
+ out:
+       pci_dev_put(dev);
        return AE_OK;
 }
 
@@ -624,6 +425,7 @@ static int add_bridge(acpi_handle handle)
        unsigned long tmp;
        int seg, bus;
        acpi_handle dummy_handle;
+       struct pci_bus *pci_bus;
 
        /* if the bridge doesn't have _STA, we assume it is always there */
        status = acpi_get_handle(handle, "_STA", &dummy_handle);
@@ -653,18 +455,22 @@ static int add_bridge(acpi_handle handle)
                bus = 0;
        }
 
+       pci_bus = pci_find_bus(seg, bus);
+       if (!pci_bus) {
+               err("Can't find bus %04x:%02x\n", seg, bus);
+               return 0;
+       }
+
        /* check if this bridge has ejectable slots */
        if (detect_ejectable_slots(handle) > 0) {
                dbg("found PCI host-bus bridge with hot-pluggable slots\n");
-               add_host_bridge(handle, seg, bus);
+               add_host_bridge(handle, pci_bus);
                return 0;
        }
 
-       tmp = seg << 8 | bus;
-
        /* search P2P bridges under this host bridge */
        status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-                                    find_p2p_bridge, &tmp, NULL);
+                                    find_p2p_bridge, pci_bus, NULL);
 
        if (ACPI_FAILURE(status))
                warn("find_p2p_bridge faied (error code = 0x%x)\n",status);
@@ -672,12 +478,205 @@ static int add_bridge(acpi_handle handle)
        return 0;
 }
 
+static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
+{
+       struct list_head *head;
+       list_for_each(head, &bridge_list) {
+               struct acpiphp_bridge *bridge = list_entry(head,
+                                               struct acpiphp_bridge, list);
+               if (bridge->handle == handle)
+                       return bridge;
+       }
+
+       return NULL;
+}
+
+static void cleanup_bridge(struct acpiphp_bridge *bridge)
+{
+       struct list_head *list, *tmp;
+       struct acpiphp_slot *slot;
+       acpi_status status;
+       acpi_handle handle = bridge->handle;
+
+       status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+                                           handle_hotplug_event_bridge);
+       if (ACPI_FAILURE(status))
+               err("failed to remove notify handler\n");
+
+       slot = bridge->slots;
+       while (slot) {
+               struct acpiphp_slot *next = slot->next;
+               list_for_each_safe (list, tmp, &slot->funcs) {
+                       struct acpiphp_func *func;
+                       func = list_entry(list, struct acpiphp_func, sibling);
+                       status = acpi_remove_notify_handler(func->handle,
+                                               ACPI_SYSTEM_NOTIFY,
+                                               handle_hotplug_event_func);
+                       if (ACPI_FAILURE(status))
+                               err("failed to remove notify handler\n");
+                       pci_dev_put(func->pci_dev);
+                       list_del(list);
+                       kfree(func);
+               }
+               kfree(slot);
+               slot = next;
+       }
+
+       pci_dev_put(bridge->pci_dev);
+       list_del(&bridge->list);
+       kfree(bridge);
+}
+
+static acpi_status
+cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+       struct acpiphp_bridge *bridge;
+
+       if (!(bridge = acpiphp_handle_to_bridge(handle)))
+               return AE_OK;
+       cleanup_bridge(bridge);
+       return AE_OK;
+}
 
 static void remove_bridge(acpi_handle handle)
 {
-       /* No-op for now .. */
+       struct acpiphp_bridge *bridge;
+
+       bridge = acpiphp_handle_to_bridge(handle);
+       if (bridge) {
+               cleanup_bridge(bridge);
+       } else {
+               /* clean-up p2p bridges under this host bridge */
+               acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
+                               (u32)1, cleanup_p2p_bridge, NULL, NULL);
+       }
+}
+
+static struct pci_dev * get_apic_pci_info(acpi_handle handle)
+{
+       struct acpi_pci_id id;
+       struct pci_bus *bus;
+       struct pci_dev *dev;
+
+       if (ACPI_FAILURE(acpi_get_pci_id(handle, &id)))
+               return NULL;
+
+       bus = pci_find_bus(id.segment, id.bus);
+       if (!bus)
+               return NULL;
+
+       dev = pci_get_slot(bus, PCI_DEVFN(id.device, id.function));
+       if (!dev)
+               return NULL;
+
+       if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) &&
+           (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC))
+       {
+               pci_dev_put(dev);
+               return NULL;
+       }
+
+       return dev;
+}
+
+static int get_gsi_base(acpi_handle handle, u32 *gsi_base)
+{
+       acpi_status status;
+       int result = -1;
+       unsigned long gsb;
+       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+       union acpi_object *obj;
+       void *table;
+
+       status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb);
+       if (ACPI_SUCCESS(status)) {
+               *gsi_base = (u32)gsb;
+               return 0;
+       }
+
+       status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer);
+       if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer)
+               return -1;
+
+       obj = buffer.pointer;
+       if (obj->type != ACPI_TYPE_BUFFER)
+               goto out;
+
+       table = obj->buffer.pointer;
+       switch (((acpi_table_entry_header *)table)->type) {
+       case ACPI_MADT_IOSAPIC:
+               *gsi_base = ((struct acpi_table_iosapic *)table)->global_irq_base;
+               result = 0;
+               break;
+       case ACPI_MADT_IOAPIC:
+               *gsi_base = ((struct acpi_table_ioapic *)table)->global_irq_base;
+               result = 0;
+               break;
+       default:
+               break;
+       }
+ out:
+       acpi_os_free(buffer.pointer);
+       return result;
+}
+
+static acpi_status
+ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+       acpi_status status;
+       unsigned long sta;
+       acpi_handle tmp;
+       struct pci_dev *pdev;
+       u32 gsi_base;
+       u64 phys_addr;
+
+       /* Evaluate _STA if present */
+       status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+       if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL)
+               return AE_CTRL_DEPTH;
+
+       /* Scan only PCI bus scope */
+       status = acpi_get_handle(handle, "_HID", &tmp);
+       if (ACPI_SUCCESS(status))
+               return AE_CTRL_DEPTH;
+
+       if (get_gsi_base(handle, &gsi_base))
+               return AE_OK;
+
+       pdev = get_apic_pci_info(handle);
+       if (!pdev)
+               return AE_OK;
+
+       if (pci_enable_device(pdev)) {
+               pci_dev_put(pdev);
+               return AE_OK;
+       }
+
+       pci_set_master(pdev);
+
+       if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) {
+               pci_disable_device(pdev);
+               pci_dev_put(pdev);
+               return AE_OK;
+       }
+
+       phys_addr = pci_resource_start(pdev, 0);
+       if (acpi_register_ioapic(handle, phys_addr, gsi_base)) {
+               pci_release_region(pdev, 0);
+               pci_disable_device(pdev);
+               pci_dev_put(pdev);
+               return AE_OK;
+       }
+
+       return AE_OK;
 }
 
+static int acpiphp_configure_ioapics(acpi_handle handle)
+{
+       acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
+                           ACPI_UINT32_MAX, ioapic_add, NULL, NULL);
+       return 0;
+}
 
 static int power_on_slot(struct acpiphp_slot *slot)
 {
@@ -719,8 +718,6 @@ static int power_off_slot(struct acpiphp_slot *slot)
        acpi_status status;
        struct acpiphp_func *func;
        struct list_head *l;
-       struct acpi_object_list arg_list;
-       union acpi_object arg;
 
        int retval = 0;
 
@@ -731,7 +728,7 @@ static int power_off_slot(struct acpiphp_slot *slot)
        list_for_each (l, &slot->funcs) {
                func = list_entry(l, struct acpiphp_func, sibling);
 
-               if (func->pci_dev && (func->flags & FUNC_HAS_PS3)) {
+               if (func->flags & FUNC_HAS_PS3) {
                        status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
                        if (ACPI_FAILURE(status)) {
                                warn("%s: _PS3 failed\n", __FUNCTION__);
@@ -742,27 +739,6 @@ static int power_off_slot(struct acpiphp_slot *slot)
                }
        }
 
-       list_for_each (l, &slot->funcs) {
-               func = list_entry(l, struct acpiphp_func, sibling);
-
-               /* We don't want to call _EJ0 on non-existing functions. */
-               if (func->pci_dev && (func->flags & FUNC_HAS_EJ0)) {
-                       /* _EJ0 method take one argument */
-                       arg_list.count = 1;
-                       arg_list.pointer = &arg;
-                       arg.type = ACPI_TYPE_INTEGER;
-                       arg.integer.value = 1;
-
-                       status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
-                       if (ACPI_FAILURE(status)) {
-                               warn("%s: _EJ0 failed\n", __FUNCTION__);
-                               retval = -1;
-                               goto err_exit;
-                       } else
-                               break;
-               }
-       }
-
        /* TBD: evaluate _STA to check if the slot is disabled */
 
        slot->flags &= (~SLOT_POWEREDON);
@@ -782,70 +758,56 @@ static int power_off_slot(struct acpiphp_slot *slot)
  */
 static int enable_device(struct acpiphp_slot *slot)
 {
-       u8 bus;
        struct pci_dev *dev;
-       struct pci_bus *child;
+       struct pci_bus *bus = slot->bridge->pci_bus;
        struct list_head *l;
        struct acpiphp_func *func;
        int retval = 0;
-       int num;
+       int num, max, pass;
 
        if (slot->flags & SLOT_ENABLED)
                goto err_exit;
 
        /* sanity check: dev should be NULL when hot-plugged in */
-       dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
+       dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));
        if (dev) {
                /* This case shouldn't happen */
                err("pci_dev structure already exists.\n");
+               pci_dev_put(dev);
                retval = -1;
                goto err_exit;
        }
 
-       /* allocate resources to device */
-       retval = acpiphp_configure_slot(slot);
-       if (retval)
-               goto err_exit;
-
-       /* returned `dev' is the *first function* only! */
-       num = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0));
-       if (num)
-               pci_bus_add_devices(slot->bridge->pci_bus);
-       dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
-
-       if (!dev) {
+       num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0));
+       if (num == 0) {
                err("No new device found\n");
                retval = -1;
                goto err_exit;
        }
 
-       if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-               pci_read_config_byte(dev, PCI_SECONDARY_BUS, &bus);
-               child = (struct pci_bus*) pci_add_new_bus(dev->bus, dev, bus);
-               pci_do_scan_bus(child);
+       max = bus->secondary;
+       for (pass = 0; pass < 2; pass++) {
+               list_for_each_entry(dev, &bus->devices, bus_list) {
+                       if (PCI_SLOT(dev->devfn) != slot->device)
+                               continue;
+                       if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+                           dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+                               max = pci_scan_bridge(bus, dev, max, pass);
+               }
        }
 
+       pci_bus_assign_resources(bus);
+       pci_bus_add_devices(bus);
+
        /* associate pci_dev to our representation */
        list_for_each (l, &slot->funcs) {
                func = list_entry(l, struct acpiphp_func, sibling);
-
-               func->pci_dev = pci_find_slot(slot->bridge->bus,
-                                             PCI_DEVFN(slot->device,
+               func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
                                                        func->function));
-               if (!func->pci_dev)
-                       continue;
-
-               /* configure device */
-               retval = acpiphp_configure_function(func);
-               if (retval)
-                       goto err_exit;
        }
 
        slot->flags |= SLOT_ENABLED;
 
-       dbg("Available resources:\n");
-       acpiphp_dump_resource(slot->bridge);
-
  err_exit:
        return retval;
 }
@@ -866,9 +828,12 @@ static int disable_device(struct acpiphp_slot *slot)
 
        list_for_each (l, &slot->funcs) {
                func = list_entry(l, struct acpiphp_func, sibling);
+               if (!func->pci_dev)
+                       continue;
 
-               if (func->pci_dev)
-                       acpiphp_unconfigure_function(func);
+               pci_remove_bus_device(func->pci_dev);
+               pci_dev_put(func->pci_dev);
+               func->pci_dev = NULL;
        }
 
        slot->flags &= (~SLOT_ENABLED);
@@ -919,6 +884,39 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot)
        return (unsigned int)sta;
 }
 
+/**
+ * acpiphp_eject_slot - physically eject the slot
+ */
+static int acpiphp_eject_slot(struct acpiphp_slot *slot)
+{
+       acpi_status status;
+       struct acpiphp_func *func;
+       struct list_head *l;
+       struct acpi_object_list arg_list;
+       union acpi_object arg;
+
+       list_for_each (l, &slot->funcs) {
+               func = list_entry(l, struct acpiphp_func, sibling);
+
+               /* We don't want to call _EJ0 on non-existing functions. */
+               if ((func->flags & FUNC_HAS_EJ0)) {
+                       /* _EJ0 method take one argument */
+                       arg_list.count = 1;
+                       arg_list.pointer = &arg;
+                       arg.type = ACPI_TYPE_INTEGER;
+                       arg.integer.value = 1;
+
+                       status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
+                       if (ACPI_FAILURE(status)) {
+                               warn("%s: _EJ0 failed\n", __FUNCTION__);
+                               return -1;
+                       } else
+                               break;
+               }
+       }
+       return 0;
+}
+
 /**
  * acpiphp_check_bridge - re-enumerate devices
  *
@@ -942,6 +940,8 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge)
                        if (retval) {
                                err("Error occurred in disabling\n");
                                goto err_exit;
+                       } else {
+                               acpiphp_eject_slot(slot);
                        }
                        disabled++;
                } else {
@@ -962,6 +962,144 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge)
        return retval;
 }
 
+static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
+{
+       u16 pci_cmd, pci_bctl;
+       struct pci_dev *cdev;
+
+       /* Program hpp values for this device */
+       if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
+                       (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
+                       (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
+               return;
+       pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
+                       bridge->hpp.cache_line_size);
+       pci_write_config_byte(dev, PCI_LATENCY_TIMER,
+                       bridge->hpp.latency_timer);
+       pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
+       if (bridge->hpp.enable_SERR)
+               pci_cmd |= PCI_COMMAND_SERR;
+       else
+               pci_cmd &= ~PCI_COMMAND_SERR;
+       if (bridge->hpp.enable_PERR)
+               pci_cmd |= PCI_COMMAND_PARITY;
+       else
+               pci_cmd &= ~PCI_COMMAND_PARITY;
+       pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
+
+       /* Program bridge control value and child devices */
+       if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+               pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
+                               bridge->hpp.latency_timer);
+               pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
+               if (bridge->hpp.enable_SERR)
+                       pci_bctl |= PCI_BRIDGE_CTL_SERR;
+               else
+                       pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
+               if (bridge->hpp.enable_PERR)
+                       pci_bctl |= PCI_BRIDGE_CTL_PARITY;
+               else
+                       pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
+               pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
+               if (dev->subordinate) {
+                       list_for_each_entry(cdev, &dev->subordinate->devices,
+                                       bus_list)
+                               program_hpp(cdev, bridge);
+               }
+       }
+}
+
+static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus)
+{
+       struct acpiphp_bridge bridge;
+       struct pci_dev *dev;
+
+       memset(&bridge, 0, sizeof(bridge));
+       bridge.handle = handle;
+       decode_hpp(&bridge);
+       list_for_each_entry(dev, &bus->devices, bus_list)
+               program_hpp(dev, &bridge);
+
+}
+
+/*
+ * Remove devices for which we could not assign resources, call
+ * arch specific code to fix-up the bus
+ */
+static void acpiphp_sanitize_bus(struct pci_bus *bus)
+{
+       struct pci_dev *dev;
+       int i;
+       unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
+
+       list_for_each_entry(dev, &bus->devices, bus_list) {
+               for (i=0; i<PCI_BRIDGE_RESOURCES; i++) {
+                       struct resource *res = &dev->resource[i];
+                       if ((res->flags & type_mask) && !res->start &&
+                                       res->end) {
+                               /* Could not assign a required resources
+                                * for this device, remove it */
+                               pci_remove_bus_device(dev);
+                               break;
+                       }
+               }
+       }
+}
+
+/* Program resources in newly inserted bridge */
+static int acpiphp_configure_bridge (acpi_handle handle)
+{
+       struct acpi_pci_id pci_id;
+       struct pci_bus *bus;
+
+       if (ACPI_FAILURE(acpi_get_pci_id(handle, &pci_id))) {
+               err("cannot get PCI domain and bus number for bridge\n");
+               return -EINVAL;
+       }
+       bus = pci_find_bus(pci_id.segment, pci_id.bus);
+       if (!bus) {
+               err("cannot find bus %d:%d\n",
+                               pci_id.segment, pci_id.bus);
+               return -EINVAL;
+       }
+
+       pci_bus_size_bridges(bus);
+       pci_bus_assign_resources(bus);
+       acpiphp_sanitize_bus(bus);
+       acpiphp_set_hpp_values(handle, bus);
+       pci_enable_bridges(bus);
+       acpiphp_configure_ioapics(handle);
+       return 0;
+}
+
+static void handle_bridge_insertion(acpi_handle handle, u32 type)
+{
+       struct acpi_device *device, *pdevice;
+       acpi_handle phandle;
+
+       if ((type != ACPI_NOTIFY_BUS_CHECK) &&
+                       (type != ACPI_NOTIFY_DEVICE_CHECK)) {
+               err("unexpected notification type %d\n", type);
+               return;
+       }
+
+       acpi_get_parent(handle, &phandle);
+       if (acpi_bus_get_device(phandle, &pdevice)) {
+               dbg("no parent device, assuming NULL\n");
+               pdevice = NULL;
+       }
+       if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) {
+               err("cannot add bridge to acpi list\n");
+               return;
+       }
+       if (!acpiphp_configure_bridge(handle) &&
+               !acpi_bus_start(device))
+               add_bridge(handle);
+       else
+               err("cannot configure and start bridge\n");
+
+}
+
 /*
  * ACPI event handlers
  */
@@ -982,8 +1120,19 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
        char objname[64];
        struct acpi_buffer buffer = { .length = sizeof(objname),
                                      .pointer = objname };
+       struct acpi_device *device;
 
-       bridge = (struct acpiphp_bridge *)context;
+       if (acpi_bus_get_device(handle, &device)) {
+               /* This bridge must have just been physically inserted */
+               handle_bridge_insertion(handle, type);
+               return;
+       }
+
+       bridge = acpiphp_handle_to_bridge(handle);
+       if (!bridge) {
+               err("cannot get bridge info\n");
+               return;
+       }
 
        acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 
@@ -1031,7 +1180,6 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
        }
 }
 
-
 /**
  * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots)
  *
@@ -1074,7 +1222,8 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex
        case ACPI_NOTIFY_EJECT_REQUEST:
                /* request device eject */
                dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
-               acpiphp_disable_slot(func->slot);
+               if (!(acpiphp_disable_slot(func->slot)))
+                       acpiphp_eject_slot(func->slot);
                break;
 
        default:
@@ -1083,6 +1232,47 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex
        }
 }
 
+static int is_root_bridge(acpi_handle handle)
+{
+       acpi_status status;
+       struct acpi_device_info *info;
+       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+       int i;
+
+       status = acpi_get_object_info(handle, &buffer);
+       if (ACPI_SUCCESS(status)) {
+               info = buffer.pointer;
+               if ((info->valid & ACPI_VALID_HID) &&
+                       !strcmp(PCI_ROOT_HID_STRING,
+                                       info->hardware_id.value)) {
+                       acpi_os_free(buffer.pointer);
+                       return 1;
+               }
+               if (info->valid & ACPI_VALID_CID) {
+                       for (i=0; i < info->compatibility_id.count; i++) {
+                               if (!strcmp(PCI_ROOT_HID_STRING,
+                                       info->compatibility_id.id[i].value)) {
+                                       acpi_os_free(buffer.pointer);
+                                       return 1;
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
+static acpi_status
+find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+       int *count = (int *)context;
+
+       if (is_root_bridge(handle)) {
+               acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+                               handle_hotplug_event_bridge, NULL);
+                       (*count)++;
+       }
+       return AE_OK ;
+}
 
 static struct acpi_pci_driver acpi_pci_hp_driver = {
        .add =          add_bridge,
@@ -1095,15 +1285,15 @@ static struct acpi_pci_driver acpi_pci_hp_driver = {
  */
 int __init acpiphp_glue_init(void)
 {
-       int num;
-
-       if (list_empty(&pci_root_buses))
-               return -1;
+       int num = 0;
 
-       num = acpi_pci_register_driver(&acpi_pci_hp_driver);
+       acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+                       ACPI_UINT32_MAX, find_root_bridges, &num, NULL);
 
        if (num <= 0)
                return -1;
+       else
+               acpi_pci_register_driver(&acpi_pci_hp_driver);
 
        return 0;
 }
@@ -1116,46 +1306,6 @@ int __init acpiphp_glue_init(void)
  */
 void __exit acpiphp_glue_exit(void)
 {
-       struct list_head *l1, *l2, *n1, *n2;
-       struct acpiphp_bridge *bridge;
-       struct acpiphp_slot *slot, *next;
-       struct acpiphp_func *func;
-       acpi_status status;
-
-       list_for_each_safe (l1, n1, &bridge_list) {
-               bridge = (struct acpiphp_bridge *)l1;
-               slot = bridge->slots;
-               while (slot) {
-                       next = slot->next;
-                       list_for_each_safe (l2, n2, &slot->funcs) {
-                               func = list_entry(l2, struct acpiphp_func, sibling);
-                               acpiphp_free_resource(&func->io_head);
-                               acpiphp_free_resource(&func->mem_head);
-                               acpiphp_free_resource(&func->p_mem_head);
-                               acpiphp_free_resource(&func->bus_head);
-                               status = acpi_remove_notify_handler(func->handle,
-                                                                   ACPI_SYSTEM_NOTIFY,
-                                                                   handle_hotplug_event_func);
-                               if (ACPI_FAILURE(status))
-                                       err("failed to remove notify handler\n");
-                               kfree(func);
-                       }
-                       kfree(slot);
-                       slot = next;
-               }
-               status = acpi_remove_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY,
-                                                   handle_hotplug_event_bridge);
-               if (ACPI_FAILURE(status))
-                       err("failed to remove notify handler\n");
-
-               acpiphp_free_resource(&bridge->io_head);
-               acpiphp_free_resource(&bridge->mem_head);
-               acpiphp_free_resource(&bridge->p_mem_head);
-               acpiphp_free_resource(&bridge->bus_head);
-
-               kfree(bridge);
-       }
-
        acpi_pci_unregister_driver(&acpi_pci_hp_driver);
 }
 
@@ -1173,11 +1323,14 @@ int __init acpiphp_get_num_slots(void)
 
        list_for_each (node, &bridge_list) {
                bridge = (struct acpiphp_bridge *)node;
-               dbg("Bus%d %dslot(s)\n", bridge->bus, bridge->nr_slots);
+               dbg("Bus %04x:%02x has %d slot%s\n",
+                               pci_domain_nr(bridge->pci_bus),
+                               bridge->pci_bus->number, bridge->nr_slots,
+                               bridge->nr_slots == 1 ? "" : "s");
                num_slots += bridge->nr_slots;
        }
 
-       dbg("Total %dslots\n", num_slots);
+       dbg("Total %d slots\n", num_slots);
        return num_slots;
 }
 
@@ -1254,7 +1407,6 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot)
        return retval;
 }
 
-
 /**
  * acpiphp_disable_slot - power off slot
  */
@@ -1274,13 +1426,6 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot)
        if (retval)
                goto err_exit;
 
-       acpiphp_resource_sort_and_combine(&slot->bridge->io_head);
-       acpiphp_resource_sort_and_combine(&slot->bridge->mem_head);
-       acpiphp_resource_sort_and_combine(&slot->bridge->p_mem_head);
-       acpiphp_resource_sort_and_combine(&slot->bridge->bus_head);
-       dbg("Available resources:\n");
-       acpiphp_dump_resource(slot->bridge);
-
  err_exit:
        up(&slot->crit_sect);
        return retval;
@@ -1293,11 +1438,7 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot)
  */
 u8 acpiphp_get_power_status(struct acpiphp_slot *slot)
 {
-       unsigned int sta;
-
-       sta = get_slot_status(slot);
-
-       return (sta & ACPI_STA_ENABLED) ? 1 : 0;
+       return (slot->flags & SLOT_POWEREDON);
 }
 
 
@@ -1335,9 +1476,10 @@ u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot)
 u32 acpiphp_get_address(struct acpiphp_slot *slot)
 {
        u32 address;
+       struct pci_bus *pci_bus = slot->bridge->pci_bus;
 
-       address = ((slot->bridge->seg) << 16) |
-                 ((slot->bridge->bus) << 8) |
+       address = (pci_domain_nr(pci_bus) << 16) |
+                 (pci_bus->number << 8) |
                  slot->device;
 
        return address;
diff --git a/drivers/pci/hotplug/acpiphp_pci.c b/drivers/pci/hotplug/acpiphp_pci.c
deleted file mode 100644 (file)
index 54d97c9..0000000
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * ACPI PCI HotPlug PCI configuration space management
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001,2002 IBM Corp.
- * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
- * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (C) 2002 NEC Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; 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, GOOD TITLE or
- * NON INFRINGEMENT.  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.
- *
- * Send feedback to <t-kochi@bq.jp.nec.com>
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/acpi.h>
-#include "../pci.h"
-#include "pci_hotplug.h"
-#include "acpiphp.h"
-
-#define MY_NAME "acpiphp_pci"
-
-
-/* allocate mem/pmem/io resource to a new function */
-static int init_config_space (struct acpiphp_func *func)
-{
-       u32 bar, len;
-       u32 address[] = {
-               PCI_BASE_ADDRESS_0,
-               PCI_BASE_ADDRESS_1,
-               PCI_BASE_ADDRESS_2,
-               PCI_BASE_ADDRESS_3,
-               PCI_BASE_ADDRESS_4,
-               PCI_BASE_ADDRESS_5,
-               0
-       };
-       int count;
-       struct acpiphp_bridge *bridge;
-       struct pci_resource *res;
-       struct pci_bus *pbus;
-       int bus, device, function;
-       unsigned int devfn;
-       u16 tmp;
-
-       bridge = func->slot->bridge;
-       pbus = bridge->pci_bus;
-       bus = bridge->bus;
-       device = func->slot->device;
-       function = func->function;
-       devfn = PCI_DEVFN(device, function);
-
-       for (count = 0; address[count]; count++) {      /* for 6 BARs */
-               pci_bus_write_config_dword(pbus, devfn,
-                                          address[count], 0xFFFFFFFF);
-               pci_bus_read_config_dword(pbus, devfn, address[count], &bar);
-
-               if (!bar)       /* This BAR is not implemented */
-                       continue;
-
-               dbg("Device %02x.%02x BAR %d wants %x\n", device, function, count, bar);
-
-               if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
-                       /* This is IO */
-
-                       len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
-                       len = len & ~(len - 1);
-
-                       dbg("len in IO %x, BAR %d\n", len, count);
-
-                       spin_lock(&bridge->res_lock);
-                       res = acpiphp_get_io_resource(&bridge->io_head, len);
-                       spin_unlock(&bridge->res_lock);
-
-                       if (!res) {
-                               err("cannot allocate requested io for %02x:%02x.%d len %x\n",
-                                   bus, device, function, len);
-                               return -1;
-                       }
-                       pci_bus_write_config_dword(pbus, devfn,
-                                                  address[count],
-                                                  (u32)res->base);
-                       res->next = func->io_head;
-                       func->io_head = res;
-
-               } else {
-                       /* This is Memory */
-                       if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-                               /* pfmem */
-
-                               len = bar & 0xFFFFFFF0;
-                               len = ~len + 1;
-
-                               dbg("len in PFMEM %x, BAR %d\n", len, count);
-
-                               spin_lock(&bridge->res_lock);
-                               res = acpiphp_get_resource(&bridge->p_mem_head, len);
-                               spin_unlock(&bridge->res_lock);
-
-                               if (!res) {
-                                       err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
-                                           bus, device, function, len);
-                                       return -1;
-                               }
-
-                               pci_bus_write_config_dword(pbus, devfn,
-                                                          address[count],
-                                                          (u32)res->base);
-
-                               if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {       /* takes up another dword */
-                                       dbg("inside the pfmem 64 case, count %d\n", count);
-                                       count += 1;
-                                       pci_bus_write_config_dword(pbus, devfn,
-                                                                  address[count],
-                                                                  (u32)(res->base >> 32));
-                               }
-
-                               res->next = func->p_mem_head;
-                               func->p_mem_head = res;
-
-                       } else {
-                               /* regular memory */
-
-                               len = bar & 0xFFFFFFF0;
-                               len = ~len + 1;
-
-                               dbg("len in MEM %x, BAR %d\n", len, count);
-
-                               spin_lock(&bridge->res_lock);
-                               res = acpiphp_get_resource(&bridge->mem_head, len);
-                               spin_unlock(&bridge->res_lock);
-
-                               if (!res) {
-                                       err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
-                                           bus, device, function, len);
-                                       return -1;
-                               }
-
-                               pci_bus_write_config_dword(pbus, devfn,
-                                                          address[count],
-                                                          (u32)res->base);
-
-                               if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-                                       /* takes up another dword */
-                                       dbg("inside mem 64 case, reg. mem, count %d\n", count);
-                                       count += 1;
-                                       pci_bus_write_config_dword(pbus, devfn,
-                                                                  address[count],
-                                                                  (u32)(res->base >> 32));
-                               }
-
-                               res->next = func->mem_head;
-                               func->mem_head = res;
-
-                       }
-               }
-       }
-
-       /* disable expansion rom */
-       pci_bus_write_config_dword(pbus, devfn, PCI_ROM_ADDRESS, 0x00000000);
-
-       /* set PCI parameters from _HPP */
-       pci_bus_write_config_byte(pbus, devfn, PCI_CACHE_LINE_SIZE,
-                                 bridge->hpp.cache_line_size);
-       pci_bus_write_config_byte(pbus, devfn, PCI_LATENCY_TIMER,
-                                 bridge->hpp.latency_timer);
-
-       pci_bus_read_config_word(pbus, devfn, PCI_COMMAND, &tmp);
-       if (bridge->hpp.enable_SERR)
-               tmp |= PCI_COMMAND_SERR;
-       if (bridge->hpp.enable_PERR)
-               tmp |= PCI_COMMAND_PARITY;
-       pci_bus_write_config_word(pbus, devfn, PCI_COMMAND, tmp);
-
-       return 0;
-}
-
-/* detect_used_resource - subtract resource under dev from bridge */
-static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)
-{
-       int count;
-
-       dbg("Device %s\n", pci_name(dev));
-
-       for (count = 0; count < DEVICE_COUNT_RESOURCE; count++) {
-               struct pci_resource *res;
-               struct pci_resource **head;
-               unsigned long base = dev->resource[count].start;
-               unsigned long len = dev->resource[count].end - base + 1;
-               unsigned long flags = dev->resource[count].flags;
-
-               if (!flags)
-                       continue;
-
-               dbg("BAR[%d] 0x%lx - 0x%lx (0x%lx)\n", count, base,
-                               base + len - 1, flags);
-
-               if (flags & IORESOURCE_IO) {
-                       head = &bridge->io_head;
-               } else if (flags & IORESOURCE_PREFETCH) {
-                       head = &bridge->p_mem_head;
-               } else {
-                       head = &bridge->mem_head;
-               }
-
-               spin_lock(&bridge->res_lock);
-               res = acpiphp_get_resource_with_base(head, base, len);
-               spin_unlock(&bridge->res_lock);
-               if (res)
-                       kfree(res);
-       }
-
-       return 0;
-}
-
-
-/**
- * acpiphp_detect_pci_resource - detect resources under bridge
- * @bridge: detect all resources already used under this bridge
- *
- * collect all resources already allocated for all devices under a bridge.
- */
-int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge)
-{
-       struct list_head *l;
-       struct pci_dev *dev;
-
-       list_for_each (l, &bridge->pci_bus->devices) {
-               dev = pci_dev_b(l);
-               detect_used_resource(bridge, dev);
-       }
-
-       return 0;
-}
-
-
-/**
- * acpiphp_init_slot_resource - gather resource usage information of a slot
- * @slot: ACPI slot object to be checked, should have valid pci_dev member
- *
- * TBD: PCI-to-PCI bridge case
- *      use pci_dev->resource[]
- */
-int acpiphp_init_func_resource (struct acpiphp_func *func)
-{
-       u64 base;
-       u32 bar, len;
-       u32 address[] = {
-               PCI_BASE_ADDRESS_0,
-               PCI_BASE_ADDRESS_1,
-               PCI_BASE_ADDRESS_2,
-               PCI_BASE_ADDRESS_3,
-               PCI_BASE_ADDRESS_4,
-               PCI_BASE_ADDRESS_5,
-               0
-       };
-       int count;
-       struct pci_resource *res;
-       struct pci_dev *dev;
-
-       dev = func->pci_dev;
-       dbg("Hot-pluggable device %s\n", pci_name(dev));
-
-       for (count = 0; address[count]; count++) {      /* for 6 BARs */
-               pci_read_config_dword(dev, address[count], &bar);
-
-               if (!bar)       /* This BAR is not implemented */
-                       continue;
-
-               pci_write_config_dword(dev, address[count], 0xFFFFFFFF);
-               pci_read_config_dword(dev, address[count], &len);
-
-               if (len & PCI_BASE_ADDRESS_SPACE_IO) {
-                       /* This is IO */
-                       base = bar & 0xFFFFFFFC;
-                       len = len & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
-                       len = len & ~(len - 1);
-
-                       dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1);
-
-                       res = acpiphp_make_resource(base, len);
-                       if (!res)
-                               goto no_memory;
-
-                       res->next = func->io_head;
-                       func->io_head = res;
-
-               } else {
-                       /* This is Memory */
-                       base = bar & 0xFFFFFFF0;
-                       if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-                               /* pfmem */
-
-                               len &= 0xFFFFFFF0;
-                               len = ~len + 1;
-
-                               if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {       /* takes up another dword */
-                                       dbg("prefetch mem 64\n");
-                                       count += 1;
-                               }
-                               dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1);
-                               res = acpiphp_make_resource(base, len);
-                               if (!res)
-                                       goto no_memory;
-
-                               res->next = func->p_mem_head;
-                               func->p_mem_head = res;
-
-                       } else {
-                               /* regular memory */
-
-                               len &= 0xFFFFFFF0;
-                               len = ~len + 1;
-
-                               if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-                                       /* takes up another dword */
-                                       dbg("mem 64\n");
-                                       count += 1;
-                               }
-                               dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1);
-                               res = acpiphp_make_resource(base, len);
-                               if (!res)
-                                       goto no_memory;
-
-                               res->next = func->mem_head;
-                               func->mem_head = res;
-
-                       }
-               }
-
-               pci_write_config_dword(dev, address[count], bar);
-       }
-#if 1
-       acpiphp_dump_func_resource(func);
-#endif
-
-       return 0;
-
- no_memory:
-       err("out of memory\n");
-       acpiphp_free_resource(&func->io_head);
-       acpiphp_free_resource(&func->mem_head);
-       acpiphp_free_resource(&func->p_mem_head);
-
-       return -1;
-}
-
-
-/**
- * acpiphp_configure_slot - allocate PCI resources
- * @slot: slot to be configured
- *
- * initializes a PCI functions on a device inserted
- * into the slot
- *
- */
-int acpiphp_configure_slot (struct acpiphp_slot *slot)
-{
-       struct acpiphp_func *func;
-       struct list_head *l;
-       u8 hdr;
-       u32 dvid;
-       int retval = 0;
-       int is_multi = 0;
-
-       pci_bus_read_config_byte(slot->bridge->pci_bus,
-                                PCI_DEVFN(slot->device, 0),
-                                PCI_HEADER_TYPE, &hdr);
-
-       if (hdr & 0x80)
-               is_multi = 1;
-
-       list_for_each (l, &slot->funcs) {
-               func = list_entry(l, struct acpiphp_func, sibling);
-               if (is_multi || func->function == 0) {
-                       pci_bus_read_config_dword(slot->bridge->pci_bus,
-                                                 PCI_DEVFN(slot->device,
-                                                           func->function),
-                                                 PCI_VENDOR_ID, &dvid);
-                       if (dvid != 0xffffffff) {
-                               retval = init_config_space(func);
-                               if (retval)
-                                       break;
-                       }
-               }
-       }
-
-       return retval;
-}
-
-/**
- * acpiphp_configure_function - configure PCI function
- * @func: function to be configured
- *
- * initializes a PCI functions on a device inserted
- * into the slot
- *
- */
-int acpiphp_configure_function (struct acpiphp_func *func)
-{
-       /* all handled by the pci core now */
-       return 0;
-}
-
-/**
- * acpiphp_unconfigure_function - unconfigure PCI function
- * @func: function to be unconfigured
- *
- */
-void acpiphp_unconfigure_function (struct acpiphp_func *func)
-{
-       struct acpiphp_bridge *bridge;
-
-       /* if pci_dev is NULL, ignore it */
-       if (!func->pci_dev)
-               return;
-
-       pci_remove_bus_device(func->pci_dev);
-
-       /* free all resources */
-       bridge = func->slot->bridge;
-
-       spin_lock(&bridge->res_lock);
-       acpiphp_move_resource(&func->io_head, &bridge->io_head);
-       acpiphp_move_resource(&func->mem_head, &bridge->mem_head);
-       acpiphp_move_resource(&func->p_mem_head, &bridge->p_mem_head);
-       acpiphp_move_resource(&func->bus_head, &bridge->bus_head);
-       spin_unlock(&bridge->res_lock);
-}
diff --git a/drivers/pci/hotplug/acpiphp_res.c b/drivers/pci/hotplug/acpiphp_res.c
deleted file mode 100644 (file)
index f54b1fa..0000000
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
- * ACPI PCI HotPlug Utility functions
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001 IBM Corp.
- * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
- * Copyright (C) 2002 NEC Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; 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, GOOD TITLE or
- * NON INFRINGEMENT.  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.
- *
- * Send feedback to <gregkh@us.ibm.com>, <t-kochi@bq.jp.nec.com>
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/sysctl.h>
-#include <linux/pci.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-
-#include <linux/ioctl.h>
-#include <linux/fcntl.h>
-
-#include <linux/list.h>
-
-#include "pci_hotplug.h"
-#include "acpiphp.h"
-
-#define MY_NAME "acpiphp_res"
-
-
-/*
- * sort_by_size - sort nodes by their length, smallest first
- */
-static int sort_by_size(struct pci_resource **head)
-{
-       struct pci_resource *current_res;
-       struct pci_resource *next_res;
-       int out_of_order = 1;
-
-       if (!(*head))
-               return 1;
-
-       if (!((*head)->next))
-               return 0;
-
-       while (out_of_order) {
-               out_of_order = 0;
-
-               /* Special case for swapping list head */
-               if (((*head)->next) &&
-                   ((*head)->length > (*head)->next->length)) {
-                       out_of_order++;
-                       current_res = *head;
-                       *head = (*head)->next;
-                       current_res->next = (*head)->next;
-                       (*head)->next = current_res;
-               }
-
-               current_res = *head;
-
-               while (current_res->next && current_res->next->next) {
-                       if (current_res->next->length > current_res->next->next->length) {
-                               out_of_order++;
-                               next_res = current_res->next;
-                               current_res->next = current_res->next->next;
-                               current_res = current_res->next;
-                               next_res->next = current_res->next;
-                               current_res->next = next_res;
-                       } else
-                               current_res = current_res->next;
-               }
-       }  /* End of out_of_order loop */
-
-       return 0;
-}
-
-#if 0
-/*
- * sort_by_max_size - sort nodes by their length, largest first
- */
-static int sort_by_max_size(struct pci_resource **head)
-{
-       struct pci_resource *current_res;
-       struct pci_resource *next_res;
-       int out_of_order = 1;
-
-       if (!(*head))
-               return 1;
-
-       if (!((*head)->next))
-               return 0;
-
-       while (out_of_order) {
-               out_of_order = 0;
-
-               /* Special case for swapping list head */
-               if (((*head)->next) &&
-                   ((*head)->length < (*head)->next->length)) {
-                       out_of_order++;
-                       current_res = *head;
-                       *head = (*head)->next;
-                       current_res->next = (*head)->next;
-                       (*head)->next = current_res;
-               }
-
-               current_res = *head;
-
-               while (current_res->next && current_res->next->next) {
-                       if (current_res->next->length < current_res->next->next->length) {
-                               out_of_order++;
-                               next_res = current_res->next;
-                               current_res->next = current_res->next->next;
-                               current_res = current_res->next;
-                               next_res->next = current_res->next;
-                               current_res->next = next_res;
-                       } else
-                               current_res = current_res->next;
-               }
-       }  /* End of out_of_order loop */
-
-       return 0;
-}
-#endif
-
-/**
- * get_io_resource - get resource for I/O ports
- *
- * this function sorts the resource list by size and then
- * returns the first node of "size" length that is not in the
- * ISA aliasing window.  If it finds a node larger than "size"
- * it will split it up.
- *
- * size must be a power of two.
- *
- * difference from get_resource is handling of ISA aliasing space.
- *
- */
-struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size)
-{
-       struct pci_resource *prevnode;
-       struct pci_resource *node;
-       struct pci_resource *split_node;
-       u64 temp_qword;
-
-       if (!(*head))
-               return NULL;
-
-       if (acpiphp_resource_sort_and_combine(head))
-               return NULL;
-
-       if (sort_by_size(head))
-               return NULL;
-
-       for (node = *head; node; node = node->next) {
-               if (node->length < size)
-                       continue;
-
-               if (node->base & (size - 1)) {
-                       /* this one isn't base aligned properly
-                          so we'll make a new entry and split it up */
-                       temp_qword = (node->base | (size-1)) + 1;
-
-                       /* Short circuit if adjusted size is too small */
-                       if ((node->length - (temp_qword - node->base)) < size)
-                               continue;
-
-                       split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
-
-                       if (!split_node)
-                               return NULL;
-
-                       node->base = temp_qword;
-                       node->length -= split_node->length;
-
-                       /* Put it in the list */
-                       split_node->next = node->next;
-                       node->next = split_node;
-               } /* End of non-aligned base */
-
-               /* Don't need to check if too small since we already did */
-               if (node->length > size) {
-                       /* this one is longer than we need
-                          so we'll make a new entry and split it up */
-                       split_node = acpiphp_make_resource(node->base + size, node->length - size);
-
-                       if (!split_node)
-                               return NULL;
-
-                       node->length = size;
-
-                       /* Put it in the list */
-                       split_node->next = node->next;
-                       node->next = split_node;
-               }  /* End of too big on top end */
-
-               /* For IO make sure it's not in the ISA aliasing space */
-               if ((node->base & 0x300L) && !(node->base & 0xfffff000))
-                       continue;
-
-               /* If we got here, then it is the right size
-                  Now take it out of the list */
-               if (*head == node) {
-                       *head = node->next;
-               } else {
-                       prevnode = *head;
-                       while (prevnode->next != node)
-                               prevnode = prevnode->next;
-
-                       prevnode->next = node->next;
-               }
-               node->next = NULL;
-               /* Stop looping */
-               break;
-       }
-
-       return node;
-}
-
-
-#if 0
-/**
- * get_max_resource - get the largest resource
- *
- * Gets the largest node that is at least "size" big from the
- * list pointed to by head.  It aligns the node on top and bottom
- * to "size" alignment before returning it.
- */
-static struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size)
-{
-       struct pci_resource *max;
-       struct pci_resource *temp;
-       struct pci_resource *split_node;
-       u64 temp_qword;
-
-       if (!(*head))
-