Merge git://git.kernel.org/pub/scm/linux/kernel/git/bunk/trivial
authorLinus Torvalds <torvalds@woody.osdl.org>
Wed, 13 Dec 2006 02:51:51 +0000 (18:51 -0800)
committerLinus Torvalds <torvalds@woody.osdl.org>
Wed, 13 Dec 2006 02:51:51 +0000 (18:51 -0800)
* git://git.kernel.org/pub/scm/linux/kernel/git/bunk/trivial:
  Fix inotify maintainers entry
  Fix typo in new debug options.
  Jon needs a new shift key.
  fs: Convert kmalloc() + memset() to kzalloc() in fs/.
  configfs.h: Remove dead macro definitions.
  kconfig: Standardize "depends" -> "depends on" in Kconfig files
  e100: replace kmalloc with kcalloc
  um: replace kmalloc+memset with kzalloc
  fix typo in net/ipv4/ip_fragment.c
  include/linux/compiler.h: reject gcc 3 < gcc 3.2
  Kconfig: fix spelling error in config KALLSYMS help text
  Remove duplicate "have to" in comment
  Fix small typo in drivers/serial/icom.c
  Use consistent casing in help message
  EXT{2,3,4}_FS: remove outdated part of the help text

189 files changed:
Documentation/cpu-freq/core.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/ocfs2.txt
Documentation/i2c/busses/i2c-amd8111
Documentation/i2c/busses/i2c-i801
Documentation/i2c/busses/i2c-nforce2
MAINTAINERS
arch/arm/mach-pnx4008/Makefile
arch/arm/mach-pnx4008/i2c.c [new file with mode: 0644]
arch/arm/mach-realview/core.c
arch/arm/mach-realview/core.h
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-versatile/core.c
arch/i386/kernel/cpu/cpufreq/Kconfig
arch/i386/kernel/cpu/cpufreq/Makefile
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
arch/i386/kernel/cpu/cpufreq/longhaul.c
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
arch/i386/kernel/cpu/cpufreq/sc520_freq.c
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
arch/sh/Kconfig
arch/sh/Kconfig.debug
arch/sh/Makefile
arch/sh/boards/landisk/irq.c
arch/sh/boards/se/7206/irq.c
arch/sh/boards/se/7619/Makefile
arch/sh/boards/se/7619/io.c [deleted file]
arch/sh/boards/se/7619/setup.c
arch/sh/boot/Makefile
arch/sh/boot/compressed/Makefile
arch/sh/boot/compressed/head.S
arch/sh/boot/compressed/misc.c
arch/sh/configs/landisk_defconfig
arch/sh/configs/se7206_defconfig
arch/sh/configs/se7619_defconfig [new file with mode: 0644]
arch/sh/drivers/push-switch.c
arch/sh/kernel/cpu/Makefile
arch/sh/kernel/cpu/sh2/entry.S
arch/sh/kernel/cpu/sh2/setup-sh7619.c
arch/sh/kernel/cpu/sh2a/setup-sh7206.c
arch/sh/kernel/cpu/sh4/Makefile
arch/sh/kernel/cpu/sh4/probe.c
arch/sh/kernel/cpu/sh4/setup-sh7750.c
arch/sh/kernel/cpu/sh4/sq.c
arch/sh/kernel/cpu/sh4a/Makefile [new file with mode: 0644]
arch/sh/kernel/cpu/sh4a/clock-sh73180.c [moved from arch/sh/kernel/cpu/sh4/clock-sh73180.c with 100% similarity]
arch/sh/kernel/cpu/sh4a/clock-sh7343.c [new file with mode: 0644]
arch/sh/kernel/cpu/sh4a/clock-sh7770.c [moved from arch/sh/kernel/cpu/sh4/clock-sh7770.c with 100% similarity]
arch/sh/kernel/cpu/sh4a/clock-sh7780.c [moved from arch/sh/kernel/cpu/sh4/clock-sh7780.c with 100% similarity]
arch/sh/kernel/cpu/sh4a/setup-sh73180.c [moved from arch/sh/kernel/cpu/sh4/setup-sh73180.c with 100% similarity]
arch/sh/kernel/cpu/sh4a/setup-sh7343.c [moved from arch/sh/kernel/cpu/sh4/setup-sh7343.c with 100% similarity]
arch/sh/kernel/cpu/sh4a/setup-sh7722.c [new file with mode: 0644]
arch/sh/kernel/cpu/sh4a/setup-sh7770.c [moved from arch/sh/kernel/cpu/sh4/setup-sh7770.c with 100% similarity]
arch/sh/kernel/cpu/sh4a/setup-sh7780.c [moved from arch/sh/kernel/cpu/sh4/setup-sh7780.c with 100% similarity]
arch/sh/kernel/early_printk.c
arch/sh/kernel/entry-common.S
arch/sh/kernel/head.S
arch/sh/kernel/process.c
arch/sh/kernel/setup.c
arch/sh/kernel/sh_ksyms.c
arch/sh/kernel/signal.c
arch/sh/kernel/sys_sh.c
arch/sh/kernel/traps.c
arch/sh/kernel/vmlinux.lds.S
arch/sh/mm/Kconfig
arch/sh/mm/cache-sh4.c
arch/sh/mm/init.c
arch/x86_64/kernel/cpufreq/Kconfig
arch/x86_64/kernel/cpufreq/Makefile
drivers/acorn/char/i2c.c
drivers/char/watchdog/at91rm9200_wdt.c
drivers/char/watchdog/mpcore_wdt.c
drivers/char/watchdog/omap_wdt.c
drivers/char/watchdog/pcwd_usb.c
drivers/char/watchdog/rm9k_wdt.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/cpufreq_performance.c
drivers/cpufreq/cpufreq_powersave.c
drivers/cpufreq/cpufreq_stats.c
drivers/cpufreq/cpufreq_userspace.c
drivers/cpufreq/freq_table.c
drivers/i2c/algos/Kconfig
drivers/i2c/algos/Makefile
drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/algos/i2c-algo-ite.c [deleted file]
drivers/i2c/algos/i2c-algo-ite.h [deleted file]
drivers/i2c/algos/i2c-algo-pca.c
drivers/i2c/algos/i2c-algo-pcf.c
drivers/i2c/algos/i2c-algo-sgi.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-at91.c [new file with mode: 0644]
drivers/i2c/busses/i2c-elektor.c
drivers/i2c/busses/i2c-hydra.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-i810.c
drivers/i2c/busses/i2c-ibm_iic.c
drivers/i2c/busses/i2c-ite.c [deleted file]
drivers/i2c/busses/i2c-ixp2000.c
drivers/i2c/busses/i2c-ixp4xx.c
drivers/i2c/busses/i2c-nforce2.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-parport-light.c
drivers/i2c/busses/i2c-parport.c
drivers/i2c/busses/i2c-pca-isa.c
drivers/i2c/busses/i2c-pnx.c [new file with mode: 0644]
drivers/i2c/busses/i2c-prosavage.c
drivers/i2c/busses/i2c-savage4.c
drivers/i2c/busses/i2c-versatile.c [new file with mode: 0644]
drivers/i2c/busses/i2c-via.c
drivers/i2c/busses/i2c-voodoo3.c
drivers/i2c/busses/scx200_i2c.c
drivers/i2c/chips/ds1337.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-dev.c
drivers/ieee1394/pcilynx.c
drivers/input/touchscreen/Kconfig
drivers/media/dvb/pluto2/pluto2.c
drivers/media/video/bt8xx/bttv-i2c.c
drivers/media/video/cx88/cx88-core.c
drivers/media/video/cx88/cx88-vp3054-i2c.c
drivers/media/video/usbvision/usbvision-i2c.c
drivers/media/video/vino.c
drivers/media/video/zoran_card.c
drivers/net/8139too.c
drivers/rtc/rtc-sh.c
drivers/serial/sh-sci.c
drivers/serial/sh-sci.h
drivers/video/aty/radeon_i2c.c
drivers/video/i810/i810-i2c.c
drivers/video/intelfb/intelfb_i2c.c
drivers/video/matrox/i2c-matroxfb.c
drivers/video/nvidia/nv_i2c.c
drivers/video/riva/rivafb-i2c.c
drivers/video/savage/savagefb-i2c.c
fs/ocfs2/cluster/nodemanager.c
fs/ocfs2/cluster/nodemanager.h
fs/ocfs2/cluster/tcp.c
fs/ocfs2/cluster/tcp.h
fs/ocfs2/cluster/tcp_internal.h
fs/ocfs2/dlmglue.c
fs/ocfs2/heartbeat.c
fs/ocfs2/inode.c
fs/ocfs2/journal.c
fs/ocfs2/journal.h
fs/ocfs2/mmap.c
fs/ocfs2/namei.c
fs/ocfs2/ocfs2.h
fs/ocfs2/ocfs2_fs.h
fs/ocfs2/super.c
fs/ocfs2/vote.c
include/asm-arm/arch-pnx4008/i2c.h [new file with mode: 0644]
include/asm-i386/msr.h
include/asm-sh/atomic-irq.h [new file with mode: 0644]
include/asm-sh/atomic-llsc.h [new file with mode: 0644]
include/asm-sh/atomic.h
include/asm-sh/bug.h
include/asm-sh/bugs.h
include/asm-sh/checksum.h
include/asm-sh/cpu-sh4/cache.h
include/asm-sh/cpu-sh4/freq.h
include/asm-sh/dma-mapping.h
include/asm-sh/irq.h
include/asm-sh/pgtable.h
include/asm-sh/processor.h
include/asm-sh/push-switch.h
include/asm-x86_64/msr.h
include/linux/cpufreq.h
include/linux/i2c-algo-bit.h
include/linux/i2c-algo-ite.h [deleted file]
include/linux/i2c-algo-pca.h
include/linux/i2c-algo-pcf.h
include/linux/i2c-algo-sgi.h
include/linux/i2c-id.h
include/linux/i2c-pnx.h [new file with mode: 0644]
include/linux/i2c.h
include/linux/seqlock.h
net/core/netpoll.c
sound/Kconfig
sound/Makefile
sound/ac97_bus.c [moved from sound/pci/ac97/ac97_bus.c with 100% similarity]
sound/drivers/Kconfig
sound/pci/ac97/Makefile

index 29b3f9f..ce0666e 100644 (file)
@@ -24,7 +24,7 @@ Contents:
 1. General Information
 =======================
 
-The CPUFreq core code is located in linux/kernel/cpufreq.c. This
+The CPUFreq core code is located in drivers/cpufreq/cpufreq.c. This
 cpufreq code offers a standardized interface for the CPUFreq
 architecture drivers (those pieces of code that do actual
 frequency transitions), as well as to "notifiers". These are device
index 46f2a55..64ce44d 100644 (file)
@@ -216,17 +216,6 @@ Who:       Thomas Gleixner <tglx@linutronix.de>
 
 ---------------------------
 
-What:  i2c-ite and i2c-algo-ite drivers
-When:  September 2006
-Why:   These drivers never compiled since they were added to the kernel
-       tree 5 years ago. This feature removal can be reevaluated if
-       someone shows interest in the drivers, fixes them and takes over
-       maintenance.
-       http://marc.theaimsgroup.com/?l=linux-mips&m=115040510817448
-Who:   Jean Delvare <khali@linux-fr.org>
-
----------------------------
-
 What:  Bridge netfilter deferred IPv4/IPv6 output hook calling
 When:  January 2007
 Why:   The deferred output hooks are a layering violation causing unusual
@@ -270,3 +259,25 @@ Why:       The new layer 3 independant connection tracking replaces the old
 Who:   Patrick McHardy <kaber@trash.net>
 
 ---------------------------
+
+What:  ACPI hooks (X86_SPEEDSTEP_CENTRINO_ACPI) in speedstep-centrino driver
+When:  December 2006
+Why:   Speedstep-centrino driver with ACPI hooks and acpi-cpufreq driver are
+       functionally very much similar. They talk to ACPI in same way. Only
+       difference between them is the way they do frequency transitions.
+       One uses MSRs and the other one uses IO ports. Functionaliy of
+       speedstep_centrino with ACPI hooks is now merged into acpi-cpufreq.
+       That means one common driver will support all Intel Enhanced Speedstep
+       capable CPUs. That means less confusion over name of
+       speedstep-centrino driver (with that driver supposed to be used on
+       non-centrino platforms). That means less duplication of code and
+       less maintenance effort and no possibility of these two drivers
+       going out of sync.
+       Current users of speedstep_centrino with ACPI hooks are requested to
+       switch over to acpi-cpufreq driver. speedstep-centrino will continue
+       to work using older non-ACPI static table based scheme even after this
+       date.
+
+Who:   Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+
+---------------------------
index af6defd..8ccf0c1 100644 (file)
@@ -54,3 +54,6 @@ errors=panic          Panic and halt the machine if an error occurs.
 intr           (*)     Allow signals to interrupt cluster operations.
 nointr                 Do not allow signals to interrupt cluster
                        operations.
+atime_quantum=60(*)    OCFS2 will not update atime unless this number
+                       of seconds has passed since the last update.
+                       Set to zero to always update atime.
index db294ee..460dd66 100644 (file)
@@ -5,7 +5,7 @@ Supported adapters:
 
 Datasheets:
        AMD datasheet not yet available, but almost everything can be found
-       in publically available ACPI 2.0 specification, which the adapter 
+       in the publicly available ACPI 2.0 specification, which the adapter
        follows.
 
 Author: Vojtech Pavlik <vojtech@suse.cz>
index e46c234..3db69a0 100644 (file)
@@ -9,7 +9,10 @@ Supported adapters:
   * Intel 82801EB/ER (ICH5) (HW PEC supported, 32 byte buffer not supported)
   * Intel 6300ESB
   * Intel 82801FB/FR/FW/FRW (ICH6)
-  * Intel ICH7
+  * Intel 82801G (ICH7)
+  * Intel 631xESB/632xESB (ESB2)
+  * Intel 82801H (ICH8)
+  * Intel ICH9
     Datasheets: Publicly available at the Intel website
 
 Authors: 
index cd49c42..7f61fbc 100644 (file)
@@ -10,11 +10,11 @@ Supported adapters:
   * nForce4 MCP51              10de:0264
   * nForce4 MCP55              10de:0368
 
-Datasheet: not publically available, but seems to be similar to the
+Datasheet: not publicly available, but seems to be similar to the
            AMD-8111 SMBus 2.0 adapter.
 
 Authors:
-       Hans-Frieder Vogt <hfvogt@arcor.de>, 
+       Hans-Frieder Vogt <hfvogt@gmx.net>,
        Thomas Leibold <thomas@plx.com>, 
         Patrick Dreker <patrick@dreker.de>
        
@@ -38,7 +38,7 @@ Notes
 -----
 
 The SMBus adapter in the nForce2 chipset seems to be very similar to the
-SMBus 2.0 adapter in the AMD-8111 southbridge. However, I could only get
+SMBus 2.0 adapter in the AMD-8111 south bridge. However, I could only get
 the driver to work with direct I/O access, which is different to the EC
 interface of the AMD-8111. Tested on Asus A7N8X. The ACPI DSDT table of the
 Asus A7N8X lists two SMBuses, both of which are supported by this driver.
index 9649ed9..8a0bfec 100644 (file)
@@ -740,7 +740,7 @@ P:  Dave Jones
 M:     davej@codemonkey.org.uk
 L:     cpufreq@lists.linux.org.uk
 W:     http://www.codemonkey.org.uk/projects/cpufreq/
-T:     git kernel.org/pub/scm/linux/kernel/davej/cpufreq.git
+T:     git kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git
 S:     Maintained
 
 CPUID/MSR DRIVER
index b457ca0..777564c 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-obj-y                  := core.o irq.o time.o clock.o gpio.o serial.o dma.o
+obj-y                  := core.o irq.o time.o clock.o gpio.o serial.o dma.o i2c.o
 obj-m                  :=
 obj-n                  :=
 obj-                   :=
diff --git a/arch/arm/mach-pnx4008/i2c.c b/arch/arm/mach-pnx4008/i2c.c
new file mode 100644 (file)
index 0000000..6f30882
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * I2C initialization for PNX4008.
+ *
+ * Author: Vitaly Wool <vitalywool@gmail.com>
+ *
+ * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/i2c-pnx.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <asm/arch/platform.h>
+#include <asm/arch/i2c.h>
+
+static int set_clock_run(struct platform_device *pdev)
+{
+       struct clk *clk;
+       char name[10];
+       int retval = 0;
+
+       snprintf(name, 10, "i2c%d_ck", pdev->id);
+       clk = clk_get(&pdev->dev, name);
+       if (!IS_ERR(clk)) {
+               clk_set_rate(clk, 1);
+               clk_put(clk);
+       } else
+               retval = -ENOENT;
+
+       return retval;
+}
+
+static int set_clock_stop(struct platform_device *pdev)
+{
+       struct clk *clk;
+       char name[10];
+       int retval = 0;
+
+       snprintf(name, 10, "i2c%d_ck", pdev->id);
+       clk = clk_get(&pdev->dev, name);
+       if (!IS_ERR(clk)) {
+               clk_set_rate(clk, 0);
+               clk_put(clk);
+       } else
+               retval = -ENOENT;
+
+       return retval;
+}
+
+static int i2c_pnx_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       int retval = 0;
+#ifdef CONFIG_PM
+       retval = set_clock_run(pdev);
+#endif
+       return retval;
+}
+
+static int i2c_pnx_resume(struct platform_device *pdev)
+{
+       int retval = 0;
+#ifdef CONFIG_PM
+       retval = set_clock_run(pdev);
+#endif
+       return retval;
+}
+
+static u32 calculate_input_freq(struct platform_device *pdev)
+{
+       return HCLK_MHZ;
+}
+
+
+static struct i2c_pnx_algo_data pnx_algo_data0 = {
+       .base = PNX4008_I2C1_BASE,
+       .irq = I2C_1_INT,
+};
+
+static struct i2c_pnx_algo_data pnx_algo_data1 = {
+       .base = PNX4008_I2C2_BASE,
+       .irq = I2C_2_INT,
+};
+
+static struct i2c_pnx_algo_data pnx_algo_data2 = {
+       .base = (PNX4008_USB_CONFIG_BASE + 0x300),
+       .irq = USB_I2C_INT,
+};
+
+static struct i2c_adapter pnx_adapter0 = {
+       .name = I2C_CHIP_NAME "0",
+       .algo_data = &pnx_algo_data0,
+};
+static struct i2c_adapter pnx_adapter1 = {
+       .name = I2C_CHIP_NAME "1",
+       .algo_data = &pnx_algo_data1,
+};
+
+static struct i2c_adapter pnx_adapter2 = {
+       .name = "USB-I2C",
+       .algo_data = &pnx_algo_data2,
+};
+
+static struct i2c_pnx_data i2c0_data = {
+       .suspend = i2c_pnx_suspend,
+       .resume = i2c_pnx_resume,
+       .calculate_input_freq = calculate_input_freq,
+       .set_clock_run = set_clock_run,
+       .set_clock_stop = set_clock_stop,
+       .adapter = &pnx_adapter0,
+};
+
+static struct i2c_pnx_data i2c1_data = {
+       .suspend = i2c_pnx_suspend,
+       .resume = i2c_pnx_resume,
+       .calculate_input_freq = calculate_input_freq,
+       .set_clock_run = set_clock_run,
+       .set_clock_stop = set_clock_stop,
+       .adapter = &pnx_adapter1,
+};
+
+static struct i2c_pnx_data i2c2_data = {
+       .suspend = i2c_pnx_suspend,
+       .resume = i2c_pnx_resume,
+       .calculate_input_freq = calculate_input_freq,
+       .set_clock_run = set_clock_run,
+       .set_clock_stop = set_clock_stop,
+       .adapter = &pnx_adapter2,
+};
+
+static struct platform_device i2c0_device = {
+       .name = "pnx-i2c",
+       .id = 0,
+       .dev = {
+               .platform_data = &i2c0_data,
+       },
+};
+
+static struct platform_device i2c1_device = {
+       .name = "pnx-i2c",
+       .id = 1,
+       .dev = {
+               .platform_data = &i2c1_data,
+       },
+};
+
+static struct platform_device i2c2_device = {
+       .name = "pnx-i2c",
+       .id = 2,
+       .dev = {
+               .platform_data = &i2c2_data,
+       },
+};
+
+static struct platform_device *devices[] __initdata = {
+       &i2c0_device,
+       &i2c1_device,
+       &i2c2_device,
+};
+
+void __init pnx4008_register_i2c_devices(void)
+{
+       platform_add_devices(devices, ARRAY_SIZE(devices));
+}
index 68c6705..84d3fe7 100644 (file)
@@ -141,6 +141,19 @@ struct platform_device realview_smc91x_device = {
        .resource       = realview_smc91x_resources,
 };
 
+static struct resource realview_i2c_resource = {
+       .start          = REALVIEW_I2C_BASE,
+       .end            = REALVIEW_I2C_BASE + SZ_4K - 1,
+       .flags          = IORESOURCE_MEM,
+};
+
+struct platform_device realview_i2c_device = {
+       .name           = "versatile-i2c",
+       .id             = -1,
+       .num_resources  = 1,
+       .resource       = &realview_i2c_resource,
+};
+
 #define REALVIEW_SYSMCI        (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET)
 
 static unsigned int realview_mmc_status(struct device *dev)
index 93e86d9..2b53420 100644 (file)
@@ -108,6 +108,7 @@ static struct amba_device name##_device = {                 \
 
 extern struct platform_device realview_flash_device;
 extern struct platform_device realview_smc91x_device;
+extern struct platform_device realview_i2c_device;
 extern struct mmc_platform_data realview_mmc0_plat_data;
 extern struct mmc_platform_data realview_mmc1_plat_data;
 extern struct clk realview_clcd_clk;
index 84a9595..9741b4d 100644 (file)
@@ -155,6 +155,7 @@ static void __init realview_eb_init(void)
 
        platform_device_register(&realview_flash_device);
        platform_device_register(&realview_smc91x_device);
+       platform_device_register(&realview_i2c_device);
 
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
                struct amba_device *d = amba_devs[i];
index 5719694..bf71507 100644 (file)
@@ -325,6 +325,19 @@ static struct platform_device smc91x_device = {
        .resource       = smc91x_resources,
 };
 
+static struct resource versatile_i2c_resource = {
+       .start                  = VERSATILE_I2C_BASE,
+       .end                    = VERSATILE_I2C_BASE + SZ_4K - 1,
+       .flags                  = IORESOURCE_MEM,
+};
+
+static struct platform_device versatile_i2c_device = {
+       .name                   = "versatile-i2c",
+       .id                     = -1,
+       .num_resources          = 1,
+       .resource               = &versatile_i2c_resource,
+};
+
 #define VERSATILE_SYSMCI       (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)
 
 unsigned int mmc_status(struct device *dev)
@@ -775,6 +788,7 @@ void __init versatile_init(void)
        clk_register(&versatile_clcd_clk);
 
        platform_device_register(&versatile_flash_device);
+       platform_device_register(&versatile_i2c_device);
        platform_device_register(&smc91x_device);
 
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
index ccc1edf..5299c5b 100644 (file)
@@ -17,6 +17,7 @@ config X86_ACPI_CPUFREQ
        help
          This driver adds a CPUFreq driver which utilizes the ACPI
          Processor Performance States.
+         This driver also supports Intel Enhanced Speedstep.
 
          For details, take a look at <file:Documentation/cpu-freq/>.
 
@@ -121,11 +122,14 @@ config X86_SPEEDSTEP_CENTRINO
          If in doubt, say N.
 
 config X86_SPEEDSTEP_CENTRINO_ACPI
-       bool "Use ACPI tables to decode valid frequency/voltage pairs"
+       bool "Use ACPI tables to decode valid frequency/voltage (deprecated)"
        depends on X86_SPEEDSTEP_CENTRINO && ACPI_PROCESSOR
        depends on !(X86_SPEEDSTEP_CENTRINO = y && ACPI_PROCESSOR = m)
        default y
        help
+         This is deprecated and this functionality is now merged into
+         acpi_cpufreq (X86_ACPI_CPUFREQ). Use that driver instead of
+         speedstep_centrino.
          Use primarily the information provided in the BIOS ACPI tables
          to determine valid CPU frequency and voltage pairings. It is
          required for the driver to work on non-Banias CPUs.
index 2e894f1..8de3abe 100644 (file)
@@ -7,9 +7,9 @@ obj-$(CONFIG_SC520_CPUFREQ)             += sc520_freq.o
 obj-$(CONFIG_X86_LONGRUN)              += longrun.o  
 obj-$(CONFIG_X86_GX_SUSPMOD)           += gx-suspmod.o
 obj-$(CONFIG_X86_SPEEDSTEP_ICH)                += speedstep-ich.o
-obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO)   += speedstep-centrino.o
 obj-$(CONFIG_X86_SPEEDSTEP_LIB)                += speedstep-lib.o
 obj-$(CONFIG_X86_SPEEDSTEP_SMI)                += speedstep-smi.o
 obj-$(CONFIG_X86_ACPI_CPUFREQ)         += acpi-cpufreq.o
+obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO)   += speedstep-centrino.o
 obj-$(CONFIG_X86_P4_CLOCKMOD)          += p4-clockmod.o
 obj-$(CONFIG_X86_CPUFREQ_NFORCE2)      += cpufreq-nforce2.o
index 57c880b..18f4715 100644 (file)
@@ -1,9 +1,10 @@
 /*
- * acpi-cpufreq.c - ACPI Processor P-States Driver ($Revision: 1.3 $)
+ * acpi-cpufreq.c - ACPI Processor P-States Driver ($Revision: 1.4 $)
  *
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
  *  Copyright (C) 2002 - 2004 Dominik Brodowski <linux@brodo.de>
+ *  Copyright (C) 2006       Denis Sadykov <denis.m.sadykov@intel.com>
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
 #include <linux/cpufreq.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
 #include <linux/compiler.h>
-#include <linux/sched.h>       /* current */
 #include <linux/dmi.h>
-#include <asm/io.h>
-#include <asm/delay.h>
-#include <asm/uaccess.h>
 
 #include <linux/acpi.h>
 #include <acpi/processor.h>
 
+#include <asm/io.h>
+#include <asm/msr.h>
+#include <asm/processor.h>
+#include <asm/cpufeature.h>
+#include <asm/delay.h>
+#include <asm/uaccess.h>
+
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg)
 
 MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
 MODULE_DESCRIPTION("ACPI Processor P-States Driver");
 MODULE_LICENSE("GPL");
 
+enum {
+       UNDEFINED_CAPABLE = 0,
+       SYSTEM_INTEL_MSR_CAPABLE,
+       SYSTEM_IO_CAPABLE,
+};
+
+#define INTEL_MSR_RANGE                (0xffff)
+#define CPUID_6_ECX_APERFMPERF_CAPABILITY      (0x1)
 
-struct cpufreq_acpi_io {
-       struct acpi_processor_performance       *acpi_data;
-       struct cpufreq_frequency_table          *freq_table;
-       unsigned int                            resume;
+struct acpi_cpufreq_data {
+       struct acpi_processor_performance *acpi_data;
+       struct cpufreq_frequency_table *freq_table;
+       unsigned int max_freq;
+       unsigned int resume;
+       unsigned int cpu_feature;
 };
 
-static struct cpufreq_acpi_io  *acpi_io_data[NR_CPUS];
-static struct acpi_processor_performance       *acpi_perf_data[NR_CPUS];
+static struct acpi_cpufreq_data *drv_data[NR_CPUS];
+static struct acpi_processor_performance *acpi_perf_data[NR_CPUS];
 
 static struct cpufreq_driver acpi_cpufreq_driver;
 
 static unsigned int acpi_pstate_strict;
 
-static int
-acpi_processor_write_port(
-       u16     port,
-       u8      bit_width,
-       u32     value)
+static int check_est_cpu(unsigned int cpuid)
+{
+       struct cpuinfo_x86 *cpu = &cpu_data[cpuid];
+
+       if (cpu->x86_vendor != X86_VENDOR_INTEL ||
+           !cpu_has(cpu, X86_FEATURE_EST))
+               return 0;
+
+       return 1;
+}
+
+static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data)
+{
+       struct acpi_processor_performance *perf;
+       int i;
+
+       perf = data->acpi_data;
+
+       for (i=0; i<perf->state_count; i++) {
+               if (value == perf->states[i].status)
+                       return data->freq_table[i].frequency;
+       }
+       return 0;
+}
+
+static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
 {
-       if (bit_width <= 8) {
+       int i;
+       struct acpi_processor_performance *perf;
+
+       msr &= INTEL_MSR_RANGE;
+       perf = data->acpi_data;
+
+       for (i=0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+               if (msr == perf->states[data->freq_table[i].index].status)
+                       return data->freq_table[i].frequency;
+       }
+       return data->freq_table[0].frequency;
+}
+
+static unsigned extract_freq(u32 val, struct acpi_cpufreq_data *data)
+{
+       switch (data->cpu_feature) {
+       case SYSTEM_INTEL_MSR_CAPABLE:
+               return extract_msr(val, data);
+       case SYSTEM_IO_CAPABLE:
+               return extract_io(val, data);
+       default:
+               return 0;
+       }
+}
+
+static void wrport(u16 port, u8 bit_width, u32 value)
+{
+       if (bit_width <= 8)
                outb(value, port);
-       } else if (bit_width <= 16) {
+       else if (bit_width <= 16)
                outw(value, port);
-       } else if (bit_width <= 32) {
+       else if (bit_width <= 32)
                outl(value, port);
-       } else {
-               return -ENODEV;
-       }
-       return 0;
 }
 
-static int
-acpi_processor_read_port(
-       u16     port,
-       u8      bit_width,
-       u32     *ret)
+static void rdport(u16 port, u8 bit_width, u32 * ret)
 {
        *ret = 0;
-       if (bit_width <= 8) {
+       if (bit_width <= 8)
                *ret = inb(port);
-       } else if (bit_width <= 16) {
+       else if (bit_width <= 16)
                *ret = inw(port);
-       } else if (bit_width <= 32) {
+       else if (bit_width <= 32)
                *ret = inl(port);
-       } else {
-               return -ENODEV;
+}
+
+struct msr_addr {
+       u32 reg;
+};
+
+struct io_addr {
+       u16 port;
+       u8 bit_width;
+};
+
+typedef union {
+       struct msr_addr msr;
+       struct io_addr io;
+} drv_addr_union;
+
+struct drv_cmd {
+       unsigned int type;
+       cpumask_t mask;
+       drv_addr_union addr;
+       u32 val;
+};
+
+static void do_drv_read(struct drv_cmd *cmd)
+{
+       u32 h;
+
+       switch (cmd->type) {
+       case SYSTEM_INTEL_MSR_CAPABLE:
+               rdmsr(cmd->addr.msr.reg, cmd->val, h);
+               break;
+       case SYSTEM_IO_CAPABLE:
+               rdport(cmd->addr.io.port, cmd->addr.io.bit_width, &cmd->val);
+               break;
+       default:
+               break;
        }
-       return 0;
 }
 
-static int
-acpi_processor_set_performance (
-       struct cpufreq_acpi_io  *data,
-       unsigned int            cpu,
-       int                     state)
+static void do_drv_write(struct drv_cmd *cmd)
 {
-       u16                     port = 0;
-       u8                      bit_width = 0;
-       int                     i = 0;
-       int                     ret = 0;
-       u32                     value = 0;
-       int                     retval;
-       struct acpi_processor_performance       *perf;
-
-       dprintk("acpi_processor_set_performance\n");
-
-       retval = 0;
-       perf = data->acpi_data; 
-       if (state == perf->state) {
-               if (unlikely(data->resume)) {
-                       dprintk("Called after resume, resetting to P%d\n", state);
-                       data->resume = 0;
-               } else {
-                       dprintk("Already at target state (P%d)\n", state);
-                       return (retval);
-               }
+       u32 h = 0;
+
+       switch (cmd->type) {
+       case SYSTEM_INTEL_MSR_CAPABLE:
+               wrmsr(cmd->addr.msr.reg, cmd->val, h);
+               break;
+       case SYSTEM_IO_CAPABLE:
+               wrport(cmd->addr.io.port, cmd->addr.io.bit_width, cmd->val);
+               break;
+       default:
+               break;
        }
+}
 
-       dprintk("Transitioning from P%d to P%d\n", perf->state, state);
+static void drv_read(struct drv_cmd *cmd)
+{
+       cpumask_t saved_mask = current->cpus_allowed;
+       cmd->val = 0;
 
-       /*
-        * First we write the target state's 'control' value to the
-        * control_register.
-        */
+       set_cpus_allowed(current, cmd->mask);
+       do_drv_read(cmd);
+       set_cpus_allowed(current, saved_mask);
+}
+
+static void drv_write(struct drv_cmd *cmd)
+{
+       cpumask_t saved_mask = current->cpus_allowed;
+       unsigned int i;
+
+       for_each_cpu_mask(i, cmd->mask) {
+               set_cpus_allowed(current, cpumask_of_cpu(i));
+               do_drv_write(cmd);
+       }
+
+       set_cpus_allowed(current, saved_mask);
+       return;
+}
+
+static u32 get_cur_val(cpumask_t mask)
+{
+       struct acpi_processor_performance *perf;
+       struct drv_cmd cmd;
+
+       if (unlikely(cpus_empty(mask)))
+               return 0;
+
+       switch (drv_data[first_cpu(mask)]->cpu_feature) {
+       case SYSTEM_INTEL_MSR_CAPABLE:
+               cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
+               cmd.addr.msr.reg = MSR_IA32_PERF_STATUS;
+               break;
+       case SYSTEM_IO_CAPABLE:
+               cmd.type = SYSTEM_IO_CAPABLE;
+               perf = drv_data[first_cpu(mask)]->acpi_data;
+               cmd.addr.io.port = perf->control_register.address;
+               cmd.addr.io.bit_width = perf->control_register.bit_width;
+               break;
+       default:
+               return 0;
+       }
+
+       cmd.mask = mask;
 
-       port = perf->control_register.address;
-       bit_width = perf->control_register.bit_width;
-       value = (u32) perf->states[state].control;
+       drv_read(&cmd);
 
-       dprintk("Writing 0x%08x to port 0x%04x\n", value, port);
+       dprintk("get_cur_val = %u\n", cmd.val);
 
-       ret = acpi_processor_write_port(port, bit_width, value);
-       if (ret) {
-               dprintk("Invalid port width 0x%04x\n", bit_width);
-               return (ret);
+       return cmd.val;
+}
+
+/*
+ * Return the measured active (C0) frequency on this CPU since last call
+ * to this function.
+ * Input: cpu number
+ * Return: Average CPU frequency in terms of max frequency (zero on error)
+ *
+ * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance
+ * over a period of time, while CPU is in C0 state.
+ * IA32_MPERF counts at the rate of max advertised frequency
+ * IA32_APERF counts at the rate of actual CPU frequency
+ * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
+ * no meaning should be associated with absolute values of these MSRs.
+ */
+static unsigned int get_measured_perf(unsigned int cpu)
+{
+       union {
+               struct {
+                       u32 lo;
+                       u32 hi;
+               } split;
+               u64 whole;
+       } aperf_cur, mperf_cur;
+
+       cpumask_t saved_mask;
+       unsigned int perf_percent;
+       unsigned int retval;
+
+       saved_mask = current->cpus_allowed;
+       set_cpus_allowed(current, cpumask_of_cpu(cpu));
+       if (get_cpu() != cpu) {
+               /* We were not able to run on requested processor */
+               put_cpu();
+               return 0;
        }
 
+       rdmsr(MSR_IA32_APERF, aperf_cur.split.lo, aperf_cur.split.hi);
+       rdmsr(MSR_IA32_MPERF, mperf_cur.split.lo, mperf_cur.split.hi);
+
+       wrmsr(MSR_IA32_APERF, 0,0);
+       wrmsr(MSR_IA32_MPERF, 0,0);
+
+#ifdef __i386__
        /*
-        * Assume the write went through when acpi_pstate_strict is not used.
-        * As read status_register is an expensive operation and there 
-        * are no specific error cases where an IO port write will fail.
+        * We dont want to do 64 bit divide with 32 bit kernel
+        * Get an approximate value. Return failure in case we cannot get
+        * an approximate value.
         */
-       if (acpi_pstate_strict) {
-               /* Then we read the 'status_register' and compare the value 
-                * with the target state's 'status' to make sure the 
-                * transition was successful.
-                * Note that we'll poll for up to 1ms (100 cycles of 10us) 
-                * before giving up.
-                */
-
-               port = perf->status_register.address;
-               bit_width = perf->status_register.bit_width;
-
-               dprintk("Looking for 0x%08x from port 0x%04x\n",
-                       (u32) perf->states[state].status, port);
-
-               for (i = 0; i < 100; i++) {
-                       ret = acpi_processor_read_port(port, bit_width, &value);
-                       if (ret) {      
-                               dprintk("Invalid port width 0x%04x\n", bit_width);
-                               return (ret);
-                       }
-                       if (value == (u32) perf->states[state].status)
-                               break;
-                       udelay(10);
-               }
-       } else {
-               value = (u32) perf->states[state].status;
+       if (unlikely(aperf_cur.split.hi || mperf_cur.split.hi)) {
+               int shift_count;
+               u32 h;
+
+               h = max_t(u32, aperf_cur.split.hi, mperf_cur.split.hi);
+               shift_count = fls(h);
+
+               aperf_cur.whole >>= shift_count;
+               mperf_cur.whole >>= shift_count;
+       }
+
+       if (((unsigned long)(-1) / 100) < aperf_cur.split.lo) {
+               int shift_count = 7;
+               aperf_cur.split.lo >>= shift_count;
+               mperf_cur.split.lo >>= shift_count;
+       }
+
+       if (aperf_cur.split.lo && mperf_cur.split.lo)
+               perf_percent = (aperf_cur.split.lo * 100) / mperf_cur.split.lo;
+       else
+               perf_percent = 0;
+
+#else
+       if (unlikely(((unsigned long)(-1) / 100) < aperf_cur.whole)) {
+               int shift_count = 7;
+               aperf_cur.whole >>= shift_count;
+               mperf_cur.whole >>= shift_count;
        }
 
-       if (unlikely(value != (u32) perf->states[state].status)) {
-               printk(KERN_WARNING "acpi-cpufreq: Transition failed\n");
-               retval = -ENODEV;
-               return (retval);
+       if (aperf_cur.whole && mperf_cur.whole)
+               perf_percent = (aperf_cur.whole * 100) / mperf_cur.whole;
+       else
+               perf_percent = 0;
+
+#endif
+
+       retval = drv_data[cpu]->max_freq * perf_percent / 100;
+
+       put_cpu();
+       set_cpus_allowed(current, saved_mask);
+
+       dprintk("cpu %d: performance percent %d\n", cpu, perf_percent);
+       return retval;
+}
+
+static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
+{
+       struct acpi_cpufreq_data *data = drv_data[cpu];
+       unsigned int freq;
+
+       dprintk("get_cur_freq_on_cpu (%d)\n", cpu);
+
+       if (unlikely(data == NULL ||
+                    data->acpi_data == NULL || data->freq_table == NULL)) {
+               return 0;
        }
 
-       dprintk("Transition successful after %d microseconds\n", i * 10);
+       freq = extract_freq(get_cur_val(cpumask_of_cpu(cpu)), data);
+       dprintk("cur freq = %u\n", freq);
 
-       perf->state = state;
-       return (retval);
+       return freq;
 }
 
+static unsigned int check_freqs(cpumask_t mask, unsigned int freq,
+                               struct acpi_cpufreq_data *data)
+{
+       unsigned int cur_freq;
+       unsigned int i;
+
+       for (i=0; i<100; i++) {
+               cur_freq = extract_freq(get_cur_val(mask), data);
+               if (cur_freq == freq)
+                       return 1;
+               udelay(10);
+       }
+       return 0;
+}
 
-static int
-acpi_cpufreq_target (
-       struct cpufreq_policy   *policy,
-       unsigned int target_freq,
-       unsigned int relation)
+static int acpi_cpufreq_target(struct cpufreq_policy *policy,
+                              unsigned int target_freq, unsigned int relation)
 {
-       struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
+       struct acpi_cpufreq_data *data = drv_data[policy->cpu];
        struct acpi_processor_performance *perf;
        struct cpufreq_freqs freqs;
        cpumask_t online_policy_cpus;
-       cpumask_t saved_mask;
-       cpumask_t set_mask;
-       cpumask_t covered_cpus;
-       unsigned int cur_state = 0;
+       struct drv_cmd cmd;
+       unsigned int msr;
        unsigned int next_state = 0;
-       unsigned int result = 0;
-       unsigned int j;
-       unsigned int tmp;
+       unsigned int next_perf_state = 0;
+       unsigned int i;
+       int result = 0;
 
-       dprintk("acpi_cpufreq_setpolicy\n");
+       dprintk("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu);
 
-       result = cpufreq_frequency_table_target(policy,
-                       data->freq_table,
-                       target_freq,
-                       relation,
-                       &next_state);
-       if (unlikely(result))
-               return (result);
+       if (unlikely(data == NULL ||
+            data->acpi_data == NULL || data->freq_table == NULL)) {
+               return -ENODEV;
+       }
 
        perf = data->acpi_data;
-       cur_state = perf->state;
-       freqs.old = data->freq_table[cur_state].frequency;
-       freqs.new = data->freq_table[next_state].frequency;
+       result = cpufreq_frequency_table_target(policy,
+                                               data->freq_table,
+                                               target_freq,
+                                               relation, &next_state);
+       if (unlikely(result))
+               return -ENODEV;
 
 #ifdef CONFIG_HOTPLUG_CPU
        /* cpufreq holds the hotplug lock, so we are safe from here on */
@@ -231,106 +417,84 @@ acpi_cpufreq_target (
        online_policy_cpus = policy->cpus;
 #endif
 
-       for_each_cpu_mask(j, online_policy_cpus) {
-               freqs.cpu = j;
-               cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+       next_perf_state = data->freq_table[next_state].index;
+       if (perf->state == next_perf_state) {
+               if (unlikely(data->resume)) {
+                       dprintk("Called after resume, resetting to P%d\n",
+                               next_perf_state);
+                       data->resume = 0;
+               } else {
+                       dprintk("Already at target state (P%d)\n",
+                               next_perf_state);
+                       return 0;
+               }
        }
 
-       /*
-        * We need to call driver->target() on all or any CPU in
-        * policy->cpus, depending on policy->shared_type.
-        */
-       saved_mask = current->cpus_allowed;
-       cpus_clear(covered_cpus);
-       for_each_cpu_mask(j, online_policy_cpus) {
-               /*
-                * Support for SMP systems.
-                * Make sure we are running on CPU that wants to change freq
-                */
-               cpus_clear(set_mask);
-               if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
-                       cpus_or(set_mask, set_mask, online_policy_cpus);
-               else
-                       cpu_set(j, set_mask);
-
-               set_cpus_allowed(current, set_mask);
-               if (unlikely(!cpu_isset(smp_processor_id(), set_mask))) {
-                       dprintk("couldn't limit to CPUs in this domain\n");
-                       result = -EAGAIN;
-                       break;
-               }
+       switch (data->cpu_feature) {
+       case SYSTEM_INTEL_MSR_CAPABLE:
+               cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
+               cmd.addr.msr.reg = MSR_IA32_PERF_CTL;
+               msr =
+                   (u32) perf->states[next_perf_state].
+                   control & INTEL_MSR_RANGE;
+               cmd.val = (cmd.val & ~INTEL_MSR_RANGE) | msr;
+               break;
+       case SYSTEM_IO_CAPABLE:
+               cmd.type = SYSTEM_IO_CAPABLE;
+               cmd.addr.io.port = perf->control_register.address;
+               cmd.addr.io.bit_width = perf->control_register.bit_width;
+               cmd.val = (u32) perf->states[next_perf_state].control;
+               break;
+       default:
+               return -ENODEV;
+       }
 
-               result = acpi_processor_set_performance (data, j, next_state);
-               if (result) {
-                       result = -EAGAIN;
-                       break;
-               }
+       cpus_clear(cmd.mask);
 
-               if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
-                       break;
-               cpu_set(j, covered_cpus);
-       }
+       if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY)
+               cmd.mask = online_policy_cpus;
+       else
+               cpu_set(policy->cpu, cmd.mask);
 
-       for_each_cpu_mask(j, online_policy_cpus) {
-               freqs.cpu = j;
-               cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+       freqs.old = data->freq_table[perf->state].frequency;
+       freqs.new = data->freq_table[next_perf_state].frequency;
+       for_each_cpu_mask(i, cmd.mask) {
+               freqs.cpu = i;
+               cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
        }
 
-       if (unlikely(result)) {
-               /*
-                * We have failed halfway through the frequency change.
-                * We have sent callbacks to online_policy_cpus and
-                * acpi_processor_set_performance() has been called on 
-                * coverd_cpus. Best effort undo..
-                */
-
-               if (!cpus_empty(covered_cpus)) {
-                       for_each_cpu_mask(j, covered_cpus) {
-                               policy->cpu = j;
-                               acpi_processor_set_performance (data, 
-                                               j, 
-                                               cur_state);
-                       }
-               }
+       drv_write(&cmd);
 
-               tmp = freqs.new;
-               freqs.new = freqs.old;
-               freqs.old = tmp;
-               for_each_cpu_mask(j, online_policy_cpus) {
-                       freqs.cpu = j;
-                       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-                       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+       if (acpi_pstate_strict) {
+               if (!check_freqs(cmd.mask, freqs.new, data)) {
+                       dprintk("acpi_cpufreq_target failed (%d)\n",
+                               policy->cpu);
+                       return -EAGAIN;
                }
        }
 
-       set_cpus_allowed(current, saved_mask);
-       return (result);
-}
+       for_each_cpu_mask(i, cmd.mask) {
+               freqs.cpu = i;
+               cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+       }
+       perf->state = next_perf_state;
 
+       return result;
+}
 
-static int
-acpi_cpufreq_verify (
-       struct cpufreq_policy   *policy)
+static int acpi_cpufreq_verify(struct cpufreq_policy *policy)
 {
-       unsigned int result = 0;
-       struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
+       struct acpi_cpufreq_data *data = drv_data[policy->cpu];
 
        dprintk("acpi_cpufreq_verify\n");
 
-       result = cpufreq_frequency_table_verify(policy, 
-                       data->freq_table);
-
-       return (result);
+       return cpufreq_frequency_table_verify(policy, data->freq_table);
 }
 
-
 static unsigned long
-acpi_cpufreq_guess_freq (
-       struct cpufreq_acpi_io  *data,
-       unsigned int            cpu)
+acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu)
 {
-       struct acpi_processor_performance       *perf = data->acpi_data;
+       struct acpi_processor_performance *perf = data->acpi_data;
 
        if (cpu_khz) {
                /* search the closest match to cpu_khz */
@@ -338,16 +502,16 @@ acpi_cpufreq_guess_freq (
                unsigned long freq;
                unsigned long freqn = perf->states[0].core_frequency * 1000;
 
-               for (i = 0; i < (perf->state_count - 1); i++) {
+               for (i=0; i<(perf->state_count-1); i++) {
                        freq = freqn;
                        freqn = perf->states[i+1].core_frequency * 1000;
                        if ((2 * cpu_khz) > (freqn + freq)) {
                                perf->state = i;
-                               return (freq);
+                               return freq;
                        }
                }
-               perf->state = perf->state_count - 1;
-               return (freqn);
+               perf->state = perf->state_count-1;
+               return freqn;
        } else {
                /* assume CPU is at P0... */
                perf->state = 0;
@@ -355,7 +519,6 @@ acpi_cpufreq_guess_freq (
        }
 }
 
-
 /*
  * acpi_cpufreq_early_init - initialize ACPI P-States library
  *
@@ -364,30 +527,34 @@ acpi_cpufreq_guess_freq (
  * do _PDC and _PSD and find out the processor dependency for the
  * actual init that will happen later...
  */
-static int acpi_cpufreq_early_init_acpi(void)
+static int acpi_cpufreq_early_init(void)
 {
-       struct acpi_processor_performance       *data;
-       unsigned int                            i, j;
+       struct acpi_processor_performance *data;
+       cpumask_t covered;
+       unsigned int i, j;
 
        dprintk("acpi_cpufreq_early_init\n");
 
        for_each_possible_cpu(i) {
-               data = kzalloc(sizeof(struct acpi_processor_performance), 
-                       GFP_KERNEL);
+               data = kzalloc(sizeof(struct acpi_processor_performance),
+                              GFP_KERNEL);
                if (!data) {
-                       for_each_possible_cpu(j) {
+                       for_each_cpu_mask(j, covered) {
                                kfree(acpi_perf_data[j]);
                                acpi_perf_data[j] = NULL;
                        }
-                       return (-ENOMEM);
+                       return -ENOMEM;
                }
                acpi_perf_data[i] = data;
+               cpu_set(i, covered);
        }
 
        /* Do initialization in ACPI core */
-       return acpi_processor_preregister_performance(acpi_perf_data);
+       acpi_processor_preregister_performance(acpi_perf_data);
+       return 0;
 }
 
+#ifdef CONFIG_SMP
 /*
  * Some BIOSes do SW_ANY coordination internally, either set it up in hw
  * or do it in BIOS firmware and won't inform about it to OS. If not
@@ -414,39 +581,42 @@ static struct dmi_system_id sw_any_bug_dmi_table[] = {
        },
        { }
 };
+#endif
 
-static int
-acpi_cpufreq_cpu_init (
-       struct cpufreq_policy   *policy)
+static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
 {
-       unsigned int            i;
-       unsigned int            cpu = policy->cpu;
-       struct cpufreq_acpi_io  *data;
-       unsigned int            result = 0;
+       unsigned int i;
+       unsigned int valid_states = 0;
+       unsigned int cpu = policy->cpu;
+       struct acpi_cpufreq_data *data;
+       unsigned int result = 0;
        struct cpuinfo_x86 *c = &cpu_data[policy->cpu];
-       struct acpi_processor_performance       *perf;
+       struct acpi_processor_performance *perf;
 
        dprintk("acpi_cpufreq_cpu_init\n");
 
        if (!acpi_perf_data[cpu])
-               return (-ENODEV);
+               return -ENODEV;
 
-       data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
+       data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
        if (!data)
-               return (-ENOMEM);
+               return -ENOMEM;
 
        data->acpi_data = acpi_perf_data[cpu];
-       acpi_io_data[cpu] = data;
+       drv_data[cpu] = data;
 
-       result = acpi_processor_register_performance(data->acpi_data, cpu);
+       if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
+               acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
 
+       result = acpi_processor_register_performance(data->acpi_data, cpu);
        if (result)
                goto err_free;
 
        perf = data->acpi_data;
        policy->shared_type = perf->shared_type;
+
        /*
-        * Will let policy->cpus know about dependency only when software 
+        * Will let policy->cpus know about dependency only when software
         * coordination is required.
         */
        if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
@@ -462,10 +632,6 @@ acpi_cpufreq_cpu_init (
        }
 #endif
 
-       if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
-               acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
-       }
-
        /* capability check */
        if (perf->state_count <= 1) {
                dprintk("No P-States\n");
@@ -473,17 +639,33 @@ acpi_cpufreq_cpu_init (
                goto err_unreg;
        }
 
-       if ((perf->control_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO) ||
-           (perf->status_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO)) {
-               dprintk("Unsupported address space [%d, %d]\n",
-                       (u32) (perf->control_register.space_id),
-                       (u32) (perf->status_register.space_id));
+       if (perf->control_register.space_id != perf->status_register.space_id) {
+               result = -ENODEV;
+               goto err_unreg;
+       }
+
+       switch (perf->control_register.space_id) {
+       case ACPI_ADR_SPACE_SYSTEM_IO:
+               dprintk("SYSTEM IO addr space\n");
+               data->cpu_feature = SYSTEM_IO_CAPABLE;
+               break;
+       case ACPI_ADR_SPACE_FIXED_HARDWARE:
+               dprintk("HARDWARE addr space\n");
+               if (!check_est_cpu(cpu)) {
+                       result = -ENODEV;
+                       goto err_unreg;
+               }
+               data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE;
+               break;
+       default:
+               dprintk("Unknown addr space %d\n",
+                       (u32) (perf->control_register.space_id));
                result = -ENODEV;
                goto err_unreg;
        }
 
-       /* alloc freq_table */
-       data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * (perf->state_count + 1), GFP_KERNEL);
+       data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) *
+                   (perf->state_count+1), GFP_KERNEL);
        if (!data->freq_table) {
                result = -ENOMEM;
                goto err_unreg;
@@ -492,129 +674,140 @@ acpi_cpufreq_cpu_init (
        /* detect transition latency */
        policy->cpuinfo.transition_latency = 0;
        for (i=0; i<perf->state_count; i++) {
-               if ((perf->states[i].transition_latency * 1000) > policy->cpuinfo.transition_latency)
-                       policy->cpuinfo.transition_latency = perf->states[i].transition_latency * 1000;
+               if ((perf->states[i].transition_latency * 1000) >
+                   policy->cpuinfo.transition_latency)
+                       policy->cpuinfo.transition_latency =
+                           perf->states[i].transition_latency * 1000;
        }
        policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
 
-       /* The current speed is unknown and not detectable by ACPI...  */
-       policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu);
-
+       data->max_freq = perf->states[0].core_frequency * 1000;
        /* table init */
-       for (i=0; i<=perf->state_count; i++)
-       {
-               data->freq_table[i].index = i;
-               if (i<perf->state_count)
-                       data->freq_table[i].frequency = perf->states[i].core_frequency * 1000;
-               else
-                       data->freq_table[i].frequency = CPUFREQ_TABLE_END;
+       for (i=0; i<perf->state_count; i++) {
+               if (i>0 && perf->states[i].core_frequency ==
+                   perf->states[i-1].core_frequency)
+                       continue;
+
+               data->freq_table[valid_states].index = i;
+               data->freq_table[valid_states].frequency =
+                   perf->states[i].core_frequency * 1000;
+               valid_states++;
        }
+       data->freq_table[valid_states].frequency = CPUFREQ_TABLE_END;
 
        result = cpufreq_frequency_table_cpuinfo(policy, data->freq_table);
-       if (result) {
+       if (result)
                goto err_freqfree;
+
+       switch (data->cpu_feature) {
+       case ACPI_ADR_SPACE_SYSTEM_IO:
+               /* Current speed is unknown and not detectable by IO port */
+               policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu);
+               break;
+       case ACPI_ADR_SPACE_FIXED_HARDWARE:
+               acpi_cpufreq_driver.get = get_cur_freq_on_cpu;
+               get_cur_freq_on_cpu(cpu);
+               break;
+       default:
+               break;
        }
 
        /* notify BIOS that we exist */
        acpi_processor_notify_smm(THIS_MODULE);
 
-       printk(KERN_INFO "acpi-cpufreq: CPU%u - ACPI performance management activated.\n",
-              cpu);
+       /* Check for APERF/MPERF support in hardware */
+       if (c->x86_vendor == X86_VENDOR_INTEL && c->cpuid_level >= 6) {
+               unsigned int ecx;
+               ecx = cpuid_ecx(6);
+               if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY)
+                       acpi_cpufreq_driver.getavg = get_measured_perf;
+       }
+
+       dprintk("CPU%u - ACPI performance management activated.\n", cpu);
        for (i = 0; i < perf->state_count; i++)
                dprintk("     %cP%d: %d MHz, %d mW, %d uS\n",
-                       (i == perf->state?'*':' '), i,
+                       (i == perf->state ? '*' : ' '), i,
                        (u32) perf->states[i].core_frequency,
                        (u32) perf->states[i].power,
                        (u32) perf->states[i].transition_latency);
 
        cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu);
-       
+
        /*
         * the first call to ->target() should result in us actually
         * writing something to the appropriate registers.
         */
        data->resume = 1;
-       
-       return (result);
 
- err_freqfree:
+       return result;
+
+err_freqfree:
        kfree(data->freq_table);
- err_unreg:
+err_unreg:
        acpi_processor_unregister_performance(perf, cpu);
- err_free:
+err_free:
        kfree(data);
-       acpi_io_data[cpu] = NULL;
+       drv_data[cpu] = NULL;
 
-       return (result);
+       return result;
 }
 
-
-static int
-acpi_cpufreq_cpu_exit (
-       struct cpufreq_policy   *policy)
+static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 {
-       struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
-
+       struct acpi_cpufreq_data *data = drv_data[policy->cpu];
 
        dprintk("acpi_cpufreq_cpu_exit\n");
 
        if (data) {
                cpufreq_frequency_table_put_attr(policy->cpu);
-               acpi_io_data[policy->cpu] = NULL;
-               acpi_processor_unregister_performance(data->acpi_data, policy->cpu);
+               drv_data[policy->cpu] = NULL;
+               acpi_processor_unregister_performance(data->acpi_data,
+                                                     policy->cpu);
                kfree(data);
        }
 
-       return (0);
+       return 0;
 }
 
-static int
-acpi_cpufreq_resume (
-       struct cpufreq_policy   *policy)
+static int acpi_cpufreq_resume(struct cpufreq_policy *policy)
 {
-       struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
-
+       struct acpi_cpufreq_data *data = drv_data[policy->cpu];
 
        dprintk("acpi_cpufreq_resume\n");
 
        data->resume = 1;
 
-       return (0);
+       return 0;
 }
 
-
-static struct freq_attr* acpi_cpufreq_attr[] = {
+static struct freq_attr *acpi_cpufreq_attr[] = {
        &cpufreq_freq_attr_scaling_available_freqs,
        NULL,
 };
 
 static struct cpufreq_driver acpi_cpufreq_driver = {
-       .verify = acpi_cpufreq_verify,
-       .target = acpi_cpufreq_target,
-       .init   = acpi_cpufreq_cpu_init,
-       .exit   = acpi_cpufreq_cpu_exit,
-       .resume = acpi_cpufreq_resume,
-       .name   = "acpi-cpufreq",
-       .owner  = THIS_MODULE,
-       .attr   = acpi_cpufreq_attr,
+       .verify = acpi_cpufreq_verify,
+       .target = acpi_cpufreq_target,
+       .init = acpi_cpufreq_cpu_init,
+       .exit = acpi_cpufreq_cpu_exit,
+       .resume = acpi_cpufreq_resume,
+       .name = "acpi-cpufreq",
+       .owner = THIS_MODULE,
+       .attr = acpi_cpufreq_attr,
 };
 
-
-static int __init
-acpi_cpufreq_init (void)
+static int __init acpi_cpufreq_init(void)
 {
        dprintk("acpi_cpufreq_init\n");
 
-       acpi_cpufreq_early_init_acpi();
+       acpi_cpufreq_early_init();
 
        return cpufreq_register_driver(&acpi_cpufreq_driver);
 }
 
-
-static void __exit
-acpi_cpufreq_exit (void)
+static void __exit acpi_cpufreq_exit(void)
 {
-       unsigned int    i;
+       unsigned int i;
        dprintk("acpi_cpufreq_exit\n");
 
        cpufreq_unregister_driver(&acpi_cpufreq_driver);
@@ -627,7 +820,9 @@ acpi_cpufreq_exit (void)
 }
 
 module_param(acpi_pstate_strict, uint, 0644);
-MODULE_PARM_DESC(acpi_pstate_strict, "value 0 or non-zero. non-zero -> strict ACPI checks are performed during frequency changes.");
+MODULE_PARM_DESC(acpi_pstate_strict,
+       "value 0 or non-zero. non-zero -> strict ACPI checks are "
+       "performed during frequency changes.");
 
 late_initcall(acpi_cpufreq_init);
 module_exit(acpi_cpufreq_exit);
index 92afa3b..6667e9c 100644 (file)
@@ -447,7 +447,6 @@ static int __init cpufreq_gx_init(void)
        int ret;
        struct gxfreq_params *params;
        struct pci_dev *gx_pci;
-       u32 class_rev;
 
        /* Test if we have the right hardware */
        if ((gx_pci = gx_detect_chipset()) == NULL)
@@ -472,8 +471,7 @@ static int __init cpufreq_gx_init(void)
        pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2));
        pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration));
        pci_read_config_byte(params->cs55x0, PCI_MODOFF, &(params->off_duration));
-        pci_read_config_dword(params->cs55x0, PCI_CLASS_REVISION, &class_rev);
-       params->pci_rev = class_rev && 0xff;
+       pci_read_config_byte(params->cs55x0, PCI_REVISION_ID, &params->pci_rev);
 
        if ((ret = cpufreq_register_driver(&gx_suspmod_driver))) {
                kfree(params);
index 7233abe..c548daa 100644 (file)
@@ -410,7 +410,7 @@ static int __init longhaul_get_ranges(void)
                        maxmult=longhaul_get_cpu_mult();
 
                        /* Starting with the 1.2GHz parts, theres a 200MHz bus. */
-                       if ((cpu_khz/1000) > 1200)
+                       if ((cpu_khz/maxmult) > 13400)
                                fsb = 200;
                        else
                                fsb = eblcr_fsb_table_v2[longhaul.bits.MaxMHzFSB];
@@ -583,6 +583,10 @@ static int enable_arbiter_disable(void)
        if (dev == NULL) {
                reg = 0x76;
                dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_862X_0, NULL);
+               /* Find CN400 V-Link host bridge */
+               if (dev == NULL)
+                       dev = pci_find_device(PCI_VENDOR_ID_VIA, 0x7259, NULL);
+
        }
        if (dev != NULL) {
                /* Enable access to port 0x22 */
@@ -734,7 +738,7 @@ print_support_type:
        return 0;
 
 err_acpi:
-       printk(KERN_ERR PFX "No ACPI support. No VT8601 or VT8623 northbridge. Aborting.\n");
+       printk(KERN_ERR PFX "No ACPI support. Unsupported northbridge. Aborting.\n");
        return -ENODEV;
 }
 
index 304d2ea..bec5017 100644 (file)
@@ -163,29 +163,27 @@ static int cpufreq_p4_verify(struct cpufreq_policy *policy)
 
 static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
 {
-       if ((c->x86 == 0x06) && (c->x86_model == 0x09)) {
-               /* Pentium M (Banias) */
-               printk(KERN_WARNING PFX "Warning: Pentium M detected. "
-                      "The speedstep_centrino module offers voltage scaling"
-                      " in addition of frequency scaling. You should use "
-                      "that instead of p4-clockmod, if possible.\n");
-               return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PM);
-       }
-
-       if ((c->x86 == 0x06) && (c->x86_model == 0x0D)) {
-               /* Pentium M (Dothan) */
-               printk(KERN_WARNING PFX "Warning: Pentium M detected. "
-                      "The speedstep_centrino module offers voltage scaling"
-                      " in addition of frequency scaling. You should use "
-                      "that instead of p4-clockmod, if possible.\n");
-               /* on P-4s, the TSC runs with constant frequency independent whether
-                * throttling is active or not. */
-               p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
-               return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PM);
+       if (c->x86 == 0x06) {
+               if (cpu_has(c, X86_FEATURE_EST))
+                       printk(KERN_WARNING PFX "Warning: EST-capable CPU detected. "
+                              "The acpi-cpufreq module offers voltage scaling"
+                              " in addition of frequency scaling. You should use "
+                              "that instead of p4-clockmod, if possible.\n");
+               switch (c->x86_model) {
+               case 0x0E: /* Core */
+               case 0x0F: /* Core Duo */
+                       p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
+                       return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PCORE);
+               case 0x0D: /* Pentium M (Dothan) */
+                       p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
+                       /* fall through */
+               case 0x09: /* Pentium M (Banias) */
+                       return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PM);
+               }
        }
 
        if (c->x86 != 0xF) {
-               printk(KERN_WARNING PFX "Unknown p4-clockmod-capable CPU. Please send an e-mail to <linux@brodo.de>\n");
+               printk(KERN_WARNING PFX "Unknown p4-clockmod-capable CPU. Please send an e-mail to <cpufreq@lists.linux.org.uk>\n");
                return 0;
        }
 
index ef457d5..b8fb4b5 100644 (file)
@@ -153,6 +153,7 @@ static struct cpufreq_driver sc520_freq_driver = {
 static int __init sc520_freq_init(void)
 {
        struct cpuinfo_x86 *c = cpu_data;
+       int err;
 
        /* Test if we have the right hardware */
        if(c->x86_vendor != X86_VENDOR_AMD ||
@@ -166,7 +167,11 @@ static int __init sc520_freq_init(void)
                return -ENOMEM;
        }
 
-       return cpufreq_register_driver(&sc520_freq_driver);
+       err = cpufreq_register_driver(&sc520_freq_driver);
+       if (err)
+               iounmap(cpuctl);
+
+       return err;
 }
 
 
index e8993ba..5113e92 100644 (file)
@@ -36,6 +36,7 @@
 
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)
 
+#define INTEL_MSR_RANGE        (0xffff)
 
 struct cpu_id
 {
@@ -379,6 +380,7 @@ static int centrino_cpu_early_init_acpi(void)
 }
 
 
+#ifdef CONFIG_SMP
 /*
  * Some BIOSes do SW_ANY coordination internally, either set it up in hw
  * or do it in BIOS firmware and won't inform about it to OS. If not
@@ -392,7 +394,6 @@ static int sw_any_bug_found(struct dmi_system_id *d)
        return 0;
 }
 
-
 static struct dmi_system_id sw_any_bug_dmi_table[] = {
        {
                .callback = sw_any_bug_found,
@@ -405,7 +406,7 @@ static struct dmi_system_id sw_any_bug_dmi_table[] = {
        },
        { }
 };
-
+#endif
 
 /*
  * centrino_cpu_init_acpi - register with ACPI P-States library
@@ -463,8 +464,9 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
        }
 
        for (i=0; i<p->state_count; i++) {
-               if (p->states[i].control != p->states[i].status) {
-                       dprintk("Different control (%llu) and status values (%llu)\n",
+               if ((p->states[i].control & INTEL_MSR_RANGE) !=
+                   (p->states[i].status & INTEL_MSR_RANGE)) {
+                       dprintk("Different MSR bits in control (%llu) and status (%llu)\n",
                                p->states[i].control, p->states[i].status);
                        result = -EINVAL;
                        goto err_unreg;
@@ -500,7 +502,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
         }
 
         for (i=0; i<p->state_count; i++) {
-               centrino_model[cpu]->op_points[i].index = p->states[i].control;
+               centrino_model[cpu]->op_points[i].index = p->states[i].control & INTEL_MSR_RANGE;
                centrino_model[cpu]->op_points[i].frequency = p->states[i].core_frequency * 1000;
                dprintk("adding state %i with frequency %u and control value %04x\n", 
                        i, centrino_model[cpu]->op_points[i].frequency, centrino_model[cpu]->op_points[i].index);
@@ -531,6 +533,9 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
 
        /* notify BIOS that we exist */
        acpi_processor_notify_smm(THIS_MODULE);
+       printk("speedstep-centrino with X86_SPEEDSTEP_CENTRINO_ACPI"
+                       "config is deprecated.\n "
+                       "Use X86_ACPI_CPUFREQ (acpi-cpufreq instead.\n" );
 
        return 0;
 
index 4f46cac..d59277c 100644 (file)
@@ -123,6 +123,36 @@ static unsigned int pentiumM_get_frequency(void)
        return (msr_tmp * 100 * 1000);
 }
 
+static unsigned int pentium_core_get_frequency(void)
+{
+       u32 fsb = 0;
+       u32 msr_lo, msr_tmp;
+
+       rdmsr(MSR_FSB_FREQ, msr_lo, msr_tmp);
+       /* see table B-2 of 25366920.pdf */
+       switch (msr_lo & 0x07) {
+       case 5:
+               fsb = 100000;
+               break;
+       case 1:
+               fsb = 133333;
+               break;
+       case 3:
+               fsb = 166667;
+               break;
+       default:
+               printk(KERN_ERR "PCORE - MSR_FSB_FREQ undefined value");
+       }
+
+       rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
+       dprintk("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
+
+       msr_tmp = (msr_lo >> 22) & 0x1f;
+       dprintk("bits 22-26 are 0x%x, speed is %u\n", msr_tmp, (msr_tmp * fsb));
+
+       return (msr_tmp * fsb);
+}
+
 
 static unsigned int pentium4_get_frequency(void)
 {
@@ -174,6 +204,8 @@ static unsigned int pentium4_get_frequency(void)
 unsigned int speedstep_get_processor_frequency(unsigned int processor)
 {
        switch (processor) {
+       case SPEEDSTEP_PROCESSOR_PCORE:
+               return pentium_core_get_frequency();
        case SPEEDSTEP_PROCESSOR_PM:
                return pentiumM_get_frequency();
        case SPEEDSTEP_PROCESSOR_P4D:
index b735429..b11bcc6 100644 (file)
@@ -22,6 +22,7 @@
  * the speedstep_get_processor_frequency() call. */
 #define SPEEDSTEP_PROCESSOR_PM                 0xFFFFFF03  /* Pentium M  */
 #define SPEEDSTEP_PROCESSOR_P4D                        0xFFFFFF04  /* desktop P4  */
+#define SPEEDSTEP_PROCESSOR_PCORE              0xFFFFFF05  /* Core */
 
 /* speedstep states -- only two of them */
 
index c28333d..ff0d898 100644 (file)
@@ -360,9 +360,6 @@ static int __init speedstep_init(void)
        case SPEEDSTEP_PROCESSOR_PIII_C:
        case SPEEDSTEP_PROCESSOR_PIII_C_EARLY:
                break;
-       case SPEEDSTEP_PROCESSOR_P4M:
-               printk(KERN_INFO "speedstep-smi: you're trying to use this cpufreq driver on a Pentium 4-based CPU. Most likely it will not work.\n");
-               break;
        default:
                speedstep_processor = 0;
        }
index 8e24c40..3aa3b88 100644 (file)
@@ -479,7 +479,7 @@ config SH_CLK_MD
        int "CPU Mode Pin Setting"
        depends on CPU_SUBTYPE_SH7619 || CPU_SUBTYPE_SH7206
        help
-         MD2 - MD0 Setting.
+         MD2 - MD0 pin setting.
 
 menu "CPU Frequency scaling"
 
@@ -580,18 +580,6 @@ config NR_CPUS
 
 source "kernel/Kconfig.preempt"
 
-config CPU_HAS_SR_RB
-       bool "CPU has SR.RB"
-       depends on CPU_SH3 || CPU_SH4
-       default y
-       help
-         This will enable the use of SR.RB register bank usage. Processors
-         that are lacking this bit must have another method in place for
-         accomplishing what is taken care of by the banked registers.
-
-         See <file:Documentation/sh/register-banks.txt> for further
-         information on SR.RB and register banking in the kernel in general.
-
 config NODES_SHIFT
        int
        default "1"
index 66a25ef..87902e0 100644 (file)
@@ -31,7 +31,8 @@ config EARLY_SCIF_CONSOLE_PORT
        hex "SCIF port for early console"
        depends on EARLY_SCIF_CONSOLE
        default "0xffe00000" if CPU_SUBTYPE_SH7780
-       default "0xfffe9800" if CPU_SUBTYPE_SH72060
+       default "0xfffe9800" if CPU_SUBTYPE_SH7206
+       default "0xf8420000" if CPU_SUBTYPE_SH7619
        default "0xffe80000" if CPU_SH4
 
 config EARLY_PRINTK
index d10bba5..c1dbef2 100644 (file)
@@ -179,7 +179,7 @@ maketools:  include/linux/version.h FORCE
 
 all: zImage
 
-zImage: vmlinux
+zImage uImage uImage.srec vmlinux.srec: vmlinux
        $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 compressed: zImage
@@ -190,5 +190,8 @@ archclean:
 CLEAN_FILES += include/asm-sh/machtypes.h
 
 define archhelp
-       @echo '  zImage                    - Compressed kernel image (arch/sh/boot/zImage)'
+       @echo '* zImage                    - Compressed kernel image'
+       @echo '  vmlinux.srec              - Create an ELF S-record'
+       @echo '  uImage                    - Create a bootable image for U-Boot'
+       @echo '  uImage.srec               - Create an S-record for U-Boot'
 endef
index 8f2e1c6..3eba6d0 100644 (file)
@@ -16,8 +16,8 @@
  */
 #include <linux/init.h>
 #include <linux/irq.h>
-#include <asm/io.h>
-#include <asm/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
 #include <asm/landisk/iodata_landisk.h>
 
 static void enable_landisk_irq(unsigned int irq);
index 3fb0c5f..27da884 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <asm/se7206.h>
 
 #define INTSTS0 0x31800000
 #define INTMSK1 0x31800006
 #define INTSEL  0x31800008
 
+#define IRQ0_IRQ 64
+#define IRQ1_IRQ 65
+#define IRQ3_IRQ 67
+
+#define INTC_IPR01 0xfffe0818
+#define INTC_ICR1  0xfffe0802
+
 static void disable_se7206_irq(unsigned int irq)
 {
        unsigned short val;
@@ -39,7 +47,7 @@ static void disable_se7206_irq(unsigned int irq)
        case IRQ1_IRQ:
                msk0 |= 0x000f;
                break;
-       case IRQ2_IRQ:
+       case IRQ3_IRQ:
                msk0 |= 0x0f00;
                msk1 |= 0x00ff;
                break;
@@ -70,7 +78,7 @@ static void enable_se7206_irq(unsigned int irq)
        case IRQ1_IRQ:
                msk0 &= ~0x000f;
                break;
-       case IRQ2_IRQ:
+       case IRQ3_IRQ:
                msk0 &= ~0x0f00;
                msk1 &= ~0x00ff;
                break;
@@ -96,7 +104,7 @@ static void eoi_se7206_irq(unsigned int irq)
        case IRQ1_IRQ:
                sts0 &= ~0x000f;
                break;
-       case IRQ2_IRQ:
+       case IRQ3_IRQ:
                sts0 &= ~0x0f00;
                sts1 &= ~0x00ff;
                break;
@@ -106,7 +114,7 @@ static void eoi_se7206_irq(unsigned int irq)
 }
 
 static struct irq_chip se7206_irq_chip __read_mostly = {
-       .name           = "SE7206-FPGA-IRQ",
+       .name           = "SE7206-FPGA",
        .mask           = disable_se7206_irq,
        .unmask         = enable_se7206_irq,
        .mask_ack       = disable_se7206_irq,
index 3666eca..d21775c 100644 (file)
@@ -2,4 +2,4 @@
 # Makefile for the 7619 SolutionEngine specific parts of the kernel
 #
 
-obj-y   := setup.o io.o
+obj-y   := setup.o
diff --git a/arch/sh/boards/se/7619/io.c b/arch/sh/boards/se/7619/io.c
deleted file mode 100644 (file)
index 176f1f3..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- *
- * linux/arch/sh/boards/se/7619/io.c
- *
- * Copyright (C) 2006  Yoshinori Sato
- *
- * I/O routine for Hitachi 7619 SolutionEngine.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <asm/io.h>
-#include <asm/se7619.h>
-#include <asm/irq.h>
-
-/* FIXME: M3A-ZAB7 Compact Flash Slot support */
-
-static inline void delay(void)
-{
-       ctrl_inw(0xa0000000);   /* Uncached ROM area (P2) */
-}
-
-#define badio(name,port) \
-  printk("bad I/O operation (%s) for port 0x%lx at 0x%08x\n", \
-        #name, (port), (__u32) __builtin_return_address(0))
-
-unsigned char se7619___inb(unsigned long port)
-{
-       badio(inb, port);
-       return 0;
-}
-
-unsigned char se7619___inb_p(unsigned long port)
-{
-       badio(inb_p, port);
-       delay();
-       return 0;
-}
-
-unsigned short se7619___inw(unsigned long port)
-{
-       badio(inw, port);
-       return 0;
-}
-
-unsigned int se7619___inl(unsigned long port)
-{
-       badio(inl, port);
-       return 0;
-}
-
-void se7619___outb(unsigned char value, unsigned long port)
-{
-       badio(outb, port);
-}
-
-void se7619___outb_p(unsigned char value, unsigned long port)
-{
-       badio(outb_p, port);
-       delay();
-}
-
-void se7619___outw(unsigned short value, unsigned long port)
-{
-       badio(outw, port);
-}
-
-void se7619___outl(unsigned int value, unsigned long port)
-{
-       badio(outl, port);
-}
-
-void se7619___insb(unsigned long port, void *addr, unsigned long count)
-{
-       badio(inw, port);
-}
-
-void se7619___insw(unsigned long port, void *addr, unsigned long count)
-{
-       badio(inw, port);
-}
-
-void se7619___insl(unsigned long port, void *addr, unsigned long count)
-{
-       badio(insl, port);
-}
-
-void se7619___outsb(unsigned long port, const void *addr, unsigned long count)
-{
-       badio(insl, port);
-}
-
-void se7619___outsw(unsigned long port, const void *addr, unsigned long count)
-{
-       badio(insl, port);
-}
-
-void se7619___outsl(unsigned long port, const void *addr, unsigned long count)
-{
-       badio(outsw, port);
-}
index e627b26..52d2c4d 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <asm/io.h>
-#include <asm/se7619.h>
 #include <asm/machvec.h>
 
 /*
 struct sh_machine_vector mv_se __initmv = {
        .mv_name                = "SolutionEngine",
        .mv_nr_irqs             = 108,
-       .mv_inb                 = se7619___inb,
-       .mv_inw                 = se7619___inw,
-       .mv_inl                 = se7619___inl,
-       .mv_outb                = se7619___outb,
-       .mv_outw                = se7619___outw,
-       .mv_outl                = se7619___outl,
-
-       .mv_inb_p               = se7619___inb_p,
-       .mv_inw_p               = se7619___inw,
-       .mv_inl_p               = se7619___inl,
-       .mv_outb_p              = se7619___outb_p,
-       .mv_outw_p              = se7619___outw,
-       .mv_outl_p              = se7619___outl,
-
-       .mv_insb                = se7619___insb,
-       .mv_insw                = se7619___insw,
-       .mv_insl                = se7619___insl,
-       .mv_outsb               = se7619___outsb,
-       .mv_outsw               = se7619___outsw,
-       .mv_outsl               = se7619___outsl,
 };
 ALIAS_MV(se)
index 60797b3..11dc272 100644 (file)
@@ -8,13 +8,49 @@
 # Copyright (C) 1999 Stuart Menefy
 #
 
-targets := zImage
+MKIMAGE := $(srctree)/scripts/mkuboot.sh
+
+#
+# Assign safe dummy values if these variables are not defined,
+# in order to suppress error message.
+#
+CONFIG_PAGE_OFFSET     ?= 0x80000000
+CONFIG_MEMORY_START    ?= 0x0c000000
+CONFIG_BOOT_LINK_OFFSET        ?= 0x00800000
+CONFIG_ZERO_PAGE_OFFSET        ?= 0x00001000
+
+export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \
+       CONFIG_ZERO_PAGE_OFFSET
+
+targets := zImage vmlinux.srec uImage uImage.srec
 subdir- := compressed
 
 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
        $(call if_changed,objcopy)
-       @echo 'Kernel: $@ is ready'
+       @echo '  Kernel: $@ is ready'
 
 $(obj)/compressed/vmlinux: FORCE
        $(Q)$(MAKE) $(build)=$(obj)/compressed $@
 
+KERNEL_LOAD    := $(shell printf "0x%8x" $$[$(CONFIG_PAGE_OFFSET)  + \
+                                            $(CONFIG_MEMORY_START) + \
+                                            $(CONFIG_ZERO_PAGE_OFFSET)+0x1000])
+
+quiet_cmd_uimage = UIMAGE  $@
+      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sh -O linux -T kernel \
+                  -C gzip -a $(KERNEL_LOAD) -e $(KERNEL_LOAD) \
+                  -n 'Linux-$(KERNELRELEASE)' -d $< $@
+
+$(obj)/uImage: $(obj)/zImage FORCE
+       $(call if_changed,uimage)
+       @echo '  Image $@ is ready'
+
+OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec
+$(obj)/vmlinux.srec: $(obj)/compressed/vmlinux
+       $(call if_changed,objcopy)
+
+OBJCOPYFLAGS_uImage.srec := -I binary -O srec
+$(obj)/uImage.srec: $(obj)/uImage
+       $(call if_changed,objcopy)
+
+clean-files    += uImage uImage.srec vmlinux.srec
index e5f4437..d951241 100644 (file)
@@ -15,13 +15,7 @@ endif
 
 #
 # IMAGE_OFFSET is the load offset of the compression loader
-# Assign dummy values if these 2 variables are not defined,
-# in order to suppress error message.
 #
-CONFIG_PAGE_OFFSET     ?= 0x80000000
-CONFIG_MEMORY_START     ?= 0x0c000000
-CONFIG_BOOT_LINK_OFFSET ?= 0x00800000
-
 IMAGE_OFFSET   := $(shell printf "0x%08x" $$[$(CONFIG_PAGE_OFFSET)  + \
                                              $(CONFIG_MEMORY_START) + \
                                              $(CONFIG_BOOT_LINK_OFFSET)])
index 4c26a19..a8399b0 100644 (file)
@@ -8,6 +8,7 @@
 .text
 
 #include <linux/linkage.h>
+#include <asm/page.h>
 
        .global startup
 startup:
@@ -97,7 +98,7 @@ init_stack_addr:
 decompress_kernel_addr:
        .long   decompress_kernel
 kernel_start_addr:
-       .long   _text+0x1000
+       .long   _text+PAGE_SIZE
 
        .align  9
 fake_headers_as_bzImage:
index 35452d8..df65e30 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/addrspace.h>
+#include <asm/page.h>
 #ifdef CONFIG_SH_STANDARD_BIOS
 #include <asm/sh_bios.h>
 #endif
@@ -229,7 +230,7 @@ long* stack_start = &user_stack[STACK_SIZE];
 void decompress_kernel(void)
 {
        output_data = 0;
-       output_ptr = P2SEGADDR((unsigned long)&_text+0x1000);
+       output_ptr = P2SEGADDR((unsigned long)&_text+PAGE_SIZE);
        free_mem_ptr = (unsigned long)&_end;
        free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
 
index 238c0f1..e7f8ddb 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Tue Oct  3 11:14:13 2006
+# Linux kernel version: 2.6.19
+# Thu Dec  7 17:13:04 2006
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -10,6 +10,9 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -33,6 +36,7 @@ CONFIG_SYSVIPC=y
 # CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -114,6 +118,8 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_SH_LANDISK=y
 # CONFIG_SH_TITAN is not set
 # CONFIG_SH_SHMIN is not set
+# CONFIG_SH_7206_SOLUTION_ENGINE is not set
+# CONFIG_SH_7619_SOLUTION_ENGINE is not set
 # CONFIG_SH_UNKNOWN is not set
 
 #
@@ -125,6 +131,12 @@ CONFIG_CPU_SH4=y
 # SH-2 Processor Support
 #
 # CONFIG_CPU_SUBTYPE_SH7604 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+
+#
+# SH-2A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
 
 #
 # SH-3 Processor Support
@@ -160,6 +172,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
 #
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
 
 #
 # SH4AL-DSP Processor Support
@@ -175,6 +188,9 @@ CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
 CONFIG_VSYSCALL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -196,16 +212,21 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # Processor features
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_SH_FPU=y
 # CONFIG_SH_DSP is not set
 # CONFIG_SH_STORE_QUEUES is not set
 CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_IPR_IRQ=y
 CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
 
 #
 # Timer support
 #
 CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+# CONFIG_NO_IDLE_HZ is not set
 CONFIG_SH_PCLK_FREQ=33333333
 
 #
@@ -216,9 +237,7 @@ CONFIG_SH_PCLK_FREQ=33333333
 #
 # DMA support
 #
-CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
-# CONFIG_NR_DMA_CHANNELS_BOOL is not set
+# CONFIG_SH_DMA is not set
 
 #
 # Companion Chips
@@ -227,6 +246,11 @@ CONFIG_NR_ONCHIP_DMA_CHANNELS=4
 CONFIG_HEARTBEAT=y
 
 #
+# Additional SuperH Device Drivers
+#
+# CONFIG_PUSH_SWITCH is not set
+
+#
 # Kernel features
 #
 # CONFIG_HZ_100 is not set
@@ -340,11 +364,13 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 
 #
 # IP: Virtual Server Configuration
@@ -361,24 +387,12 @@ CONFIG_NETFILTER=y
 # Core Netfilter Configuration
 #
 # CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
 # CONFIG_NETFILTER_XTABLES is not set
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_CT_ACCT=y
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
-# CONFIG_IP_NF_CT_PROTO_SCTP is not set
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-# CONFIG_IP_NF_PPTP is not set
-# CONFIG_IP_NF_H323 is not set
-# CONFIG_IP_NF_SIP is not set
 CONFIG_IP_NF_QUEUE=m
 
 #
@@ -477,6 +491,12 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
@@ -519,6 +539,7 @@ CONFIG_BLK_DEV_AEC62XX=y
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
 # CONFIG_BLK_DEV_IT821X is not set
@@ -542,6 +563,7 @@ CONFIG_IDEDMA_AUTO=y
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
@@ -561,6 +583,7 @@ CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
 
 #
 # SCSI Transports
@@ -602,12 +625,12 @@ CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PSI240I is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_DC395x is not set
@@ -615,6 +638,7 @@ CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
 
 #
 # PCMCIA SCSI adapter support
@@ -757,6 +781,7 @@ CONFIG_8139CP=y
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
 
 #
 # Token Ring devices
@@ -871,10 +896,6 @@ CONFIG_HW_RANDOM=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_DRM is not set
 
 #
@@ -889,7 +910,6 @@ CONFIG_HW_RANDOM=y
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -905,6 +925,7 @@ CONFIG_HW_RANDOM=y
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -917,10 +938,6 @@ CONFIG_HWMON=y
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Misc devices
-#
-
-#
 # Multimedia devices
 #
 CONFIG_VIDEO_DEV=m
@@ -1037,6 +1054,7 @@ CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MULTITHREAD_PROBE is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -1106,7 +1124,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -1121,6 +1138,7 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_KAWETH is not set
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 CONFIG_USB_MON=y
 
@@ -1156,6 +1174,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=m
 # CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
 # CONFIG_USB_SERIAL_MOS7840 is not set
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
@@ -1167,6 +1186,7 @@ CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_XIRCOM is not set
 # CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
 
 #
 # USB Miscellaneous drivers
@@ -1188,6 +1208,7 @@ CONFIG_USB_EMI26=m
 CONFIG_USB_SISUSBVGA=m
 CONFIG_USB_SISUSBVGA_CON=y
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1254,6 +1275,7 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1264,6 +1286,7 @@ CONFIG_REISERFS_FS=y
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
@@ -1414,6 +1437,7 @@ CONFIG_NLS_CODEPAGE_932=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
@@ -1422,6 +1446,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_EARLY_PRINTK is not set
@@ -1445,6 +1470,4 @@ CONFIG_SH_STANDARD_BIOS=y
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
 CONFIG_PLIST=y
index 36cec0b..87ab908 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc4
-# Sun Nov  5 16:20:10 2006
+# Linux kernel version: 2.6.19
+# Wed Dec  6 14:40:15 2006
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -11,6 +11,8 @@ CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 # CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -34,24 +36,23 @@ CONFIG_LOCALVERSION=""
 # CONFIG_IKCONFIG is not set
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
-CONFIG_UID16=y
+# CONFIG_UID16 is not set
 # CONFIG_SYSCTL_SYSCALL is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_KALLSYMS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
+# CONFIG_ELF_CORE is not set
+# CONFIG_BASE_FULL is not set
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_VM_EVENT_COUNTERS is not set
 CONFIG_TINY_SHMEM=y
-CONFIG_BASE_SMALL=0
+CONFIG_BASE_SMALL=1
 # CONFIG_SLOB is not set
 
 #
@@ -160,6 +161,7 @@ CONFIG_CPU_SUBTYPE_SH7206=y
 #
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
 
 #
 # SH4AL-DSP Processor Support
@@ -172,7 +174,10 @@ CONFIG_CPU_SUBTYPE_SH7206=y
 #
 CONFIG_PAGE_OFFSET=0x00000000
 CONFIG_MEMORY_START=0x0c000000
-CONFIG_MEMORY_SIZE=0x02000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -194,6 +199,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # Processor features
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_SH_FPU is not set
 # CONFIG_SH_FPU_EMU is not set
 # CONFIG_SH_DSP is not set
@@ -203,6 +209,8 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 #
 CONFIG_SH_CMT=y
 # CONFIG_SH_MTU2 is not set
+CONFIG_SH_TIMER_IRQ=140
+# CONFIG_NO_IDLE_HZ is not set
 CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_SH_CLK_MD=6
 
@@ -222,6 +230,11 @@ CONFIG_SH_CLK_MD=6
 # CONFIG_HD6446X_SERIES is not set
 
 #
+# Additional SuperH Device Drivers
+#
+# CONFIG_PUSH_SWITCH is not set
+
+#
 # Kernel features
 #
 CONFIG_HZ_100=y
@@ -279,9 +292,6 @@ CONFIG_NET=y
 # CONFIG_NETDEBUG is not set
 # CONFIG_PACKET is not set
 # CONFIG_UNIX is not set
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -297,9 +307,9 @@ CONFIG_IP_FIB_HASH=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
@@ -371,7 +381,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
@@ -422,7 +432,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_START=0x20000000
-CONFIG_MTD_PHYSMAP_LEN=0x1000000
+CONFIG_MTD_PHYSMAP_LEN=0x01000000
 CONFIG_MTD_PHYSMAP_BANKWIDTH=4
 # CONFIG_MTD_SOLUTIONENGINE is not set
 # CONFIG_MTD_UCLINUX is not set
@@ -468,10 +478,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
@@ -519,7 +526,50 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # Network device support
 #
-# CONFIG_NETDEVICES is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_STNIC is not set
+CONFIG_SMC91X=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
 
@@ -536,7 +586,26 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # Input device support
 #
-# CONFIG_INPUT is not set
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
 
 #
 # Hardware I/O ports
@@ -564,8 +633,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_UNIX98_PTYS is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_LEGACY_PTYS is not set
 
 #
 # IPMI
@@ -576,7 +644,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -610,12 +678,8 @@ CONFIG_HW_RANDOM=y
 #
 # Hardware Monitoring support
 #
-CONFIG_HWMON=y
+# CONFIG_HWMON is not set
 # CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Multimedia devices
@@ -630,7 +694,7 @@ CONFIG_HWMON=y
 #
 # Graphics support
 #
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
 
 #
@@ -701,8 +765,7 @@ CONFIG_FIRMWARE_EDID=y
 #
 # File systems
 #
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
@@ -755,7 +818,7 @@ CONFIG_RAMFS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
-CONFIG_CRAMFS=y
+# CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
@@ -793,8 +856,9 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_ENABLE_MUST_CHECK is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
@@ -819,7 +883,7 @@ CONFIG_LOG_BUF_SHIFT=14
 #
 # Library routines
 #
-CONFIG_CRC_CCITT=y
+# CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/se7619_defconfig b/arch/sh/configs/se7619_defconfig
new file mode 100644 (file)
index 0000000..20ac7f4
--- /dev/null
@@ -0,0 +1,744 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.19
+# Wed Dec  6 16:35:36 2006
+#
+CONFIG_SUPERH=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+# CONFIG_UID16 is not set
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+CONFIG_SLAB=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=1
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
+# System type
+#
+# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_HP6XX is not set
+# CONFIG_SH_EC3104 is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_BIGSUR is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_R7780RP is not set
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_7206_SOLUTION_ENGINE is not set
+CONFIG_SH_7619_SOLUTION_ENGINE=y
+# CONFIG_SH_UNKNOWN is not set
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH2=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+CONFIG_CPU_SUBTYPE_SH7619=y
+
+#
+# SH-2A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+
+#
+# Memory management options
+#
+CONFIG_PAGE_OFFSET=0x00000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+CONFIG_SH_WRITETHROUGH=y
+# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_CPU_BIG_ENDIAN=y
+# CONFIG_SH_FPU is not set
+# CONFIG_SH_FPU_EMU is not set
+# CONFIG_SH_DSP is not set
+
+#
+# Timer support
+#
+CONFIG_SH_CMT=y
+CONFIG_SH_TIMER_IRQ=86
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_SH_PCLK_FREQ=31250000
+CONFIG_SH_CLK_MD=5
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0xa0000000
+CONFIG_MTD_PHYSMAP_LEN=0x01000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_SOLUTIONENGINE is not set
+# CONFIG_MTD_UCLINUX is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# Misc devices
+#
+# CONFIG_TIFM_CORE is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# ISDN subsystem
+#
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=3
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+# CONFIG_SYSFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_UNWIND_INFO is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
index f2b9157..b3d20c0 100644 (file)
@@ -14,7 +14,7 @@
 #include <asm/push-switch.h>
 
 #define DRV_NAME "push-switch"
-#define DRV_VERSION "0.1.0"
+#define DRV_VERSION "0.1.1"
 
 static ssize_t switch_show(struct device *dev,
                           struct device_attribute *attr,
@@ -32,10 +32,10 @@ static void switch_timer(unsigned long data)
        schedule_work(&psw->work);
 }
 
-static void switch_work_handler(void *data)
+static void switch_work_handler(struct work_struct *work)
 {
-       struct platform_device *pdev = data;
-       struct push_switch *psw = platform_get_drvdata(pdev);
+       struct push_switch *psw = container_of(work, struct push_switch, work);
+       struct platform_device *pdev = psw->pdev;
 
        psw->state = 0;
 
@@ -76,12 +76,15 @@ static int switch_drv_probe(struct platform_device *pdev)
                }
        }
 
-       INIT_WORK(&psw->work, switch_work_handler, pdev);
+       INIT_WORK(&psw->work, switch_work_handler);
        init_timer(&psw->debounce);
 
        psw->debounce.function = switch_timer;
        psw->debounce.data = (unsigned long)psw;
 
+       /* Workqueue API brain-damage */
+       psw->pdev = pdev;
+
        platform_set_drvdata(pdev, psw);
 
        return 0;
index 0582e67..d055a3e 100644 (file)
@@ -6,6 +6,7 @@ obj-$(CONFIG_CPU_SH2)           = sh2/
 obj-$(CONFIG_CPU_SH2A)         = sh2a/
 obj-$(CONFIG_CPU_SH3)          = sh3/
 obj-$(CONFIG_CPU_SH4)          = sh4/
+obj-$(CONFIG_CPU_SH4A)         += sh4a/
 
 obj-$(CONFIG_UBC_WAKEUP)       += ubc.o
 obj-$(CONFIG_SH_ADC)           += adc.o
index 34d51b3..d51fa5e 100644 (file)
@@ -177,15 +177,21 @@ interrupt_entry:
 7:     .long   do_IRQ
 8:     .long   do_exception_error
        
-trap_entry:    
-       add     #-0x10,r9
+trap_entry:
+       /* verbose BUG trapa entry check */
+       mov     #0x3e,r8
+       cmp/ge  r8,r9
+       bf/s    1f
+        add    #-0x10,r9
+       add     #0x10,r9
+1:     
        shll2   r9                      ! TRA
        mov     #OFF_TRA,r8
        add     r15,r8
        mov.l   r9,@r8
        mov     r9,r8
 #ifdef CONFIG_TRACE_IRQFLAGS
-       mov.l   5f, r9
+       mov.l   2f, r9
        jsr     @r9
         nop
 #endif
@@ -194,12 +200,8 @@ trap_entry:
         nop
        
        .align  2
-1:     .long   syscall_exit
-2:     .long   break_point_trap_software
-3:     .long   NR_syscalls
-4:     .long   sys_call_table
 #ifdef CONFIG_TRACE_IRQFLAGS
-5:     .long   trace_hardirqs_on
+2:     .long   trace_hardirqs_on
 #endif
 
 #if defined(CONFIG_SH_STANDARD_BIOS)
@@ -264,7 +266,7 @@ ENTRY(address_error_handler)
 restore_all:
        cli
 #ifdef CONFIG_TRACE_IRQFLAGS
-       mov.l   3f, r0
+       mov.l   1f, r0
        jsr     @r0
         nop
 #endif
@@ -309,20 +311,14 @@ restore_all:
        mov.l   @r15,r15
        rte
         nop
-2:
-       mov.l   1f,r8
-       mov.l   2f,r9
-       jmp     @r9
-        lds    r8,pr
 
-       .align  2
+#ifdef CONFIG_TRACE_IRQFLAGS
+1:     .long   trace_hardirqs_off
+#endif
 $current_thread_info:
        .long   __current_thread_info
 $cpu_mode:     
        .long   __cpu_mode
-#ifdef CONFIG_TRACE_IRQFLAGS
-3:     .long   trace_hardirqs_off
-#endif
                
 ! common exception handler
 #include "../../entry-common.S"
index 82c2d90..79283e6 100644 (file)
@@ -51,3 +51,44 @@ static int __init sh7619_devices_setup(void)
                                    ARRAY_SIZE(sh7619_devices));
 }
 __initcall(sh7619_devices_setup);
+
+#define INTC_IPRC      0xf8080000UL
+#define INTC_IPRD      0xf8080002UL
+
+#define CMI0_IRQ       86
+
+#define SCIF0_ERI_IRQ  88
+#define SCIF0_RXI_IRQ  89
+#define SCIF0_BRI_IRQ  90
+#define SCIF0_TXI_IRQ  91
+
+#define SCIF1_ERI_IRQ  92
+#define SCIF1_RXI_IRQ  93
+#define SCIF1_BRI_IRQ  94
+#define SCIF1_TXI_IRQ  95
+
+#define SCIF2_BRI_IRQ  96
+#define SCIF2_ERI_IRQ  97
+#define SCIF2_RXI_IRQ  98
+#define SCIF2_TXI_IRQ  99
+
+static struct ipr_data sh7619_ipr_map[] = {
+       { CMI0_IRQ,      INTC_IPRC, 1, 2 },
+       { SCIF0_ERI_IRQ, INTC_IPRD, 3, 3 },
+       { SCIF0_RXI_IRQ, INTC_IPRD, 3, 3 },
+       { SCIF0_BRI_IRQ, INTC_IPRD, 3, 3 },
+       { SCIF0_TXI_IRQ, INTC_IPRD, 3, 3 },
+       { SCIF1_ERI_IRQ, INTC_IPRD, 2, 3 },
+       { SCIF1_RXI_IRQ, INTC_IPRD, 2, 3 },
+       { SCIF1_BRI_IRQ, INTC_IPRD, 2, 3 },
+       { SCIF1_TXI_IRQ, INTC_IPRD, 2, 3 },
+       { SCIF2_ERI_IRQ, INTC_IPRD, 1, 3 },
+       { SCIF2_RXI_IRQ, INTC_IPRD, 1, 3 },
+       { SCIF2_BRI_IRQ, INTC_IPRD, 1, 3 },
+       { SCIF2_TXI_IRQ, INTC_IPRD, 1, 3 },
+};
+
+void __init init_IRQ_ipr(void)
+{
+       make_ipr_irq(sh7619_ipr_map, ARRAY_SIZE(sh7619_ipr_map));
+}
index cdfeef4..4b60fcc 100644 (file)
@@ -17,22 +17,22 @@ static struct plat_sci_port sci_platform_data[] = {
                .mapbase        = 0xfffe8000,
                .flags          = UPF_BOOT_AUTOCONF,
                .type           = PORT_SCIF,
-               .irqs           =  { 240, 241, 242, 243},
+               .irqs           =  { 241, 242, 243, 240},
        }, {
                .mapbase        = 0xfffe8800,
                .flags          = UPF_BOOT_AUTOCONF,
                .type           = PORT_SCIF,
-               .irqs           =  { 244, 245, 246, 247},
+               .irqs           =  { 247, 244, 245, 246},
        }, {
                .mapbase        = 0xfffe9000,
                .flags          = UPF_BOOT_AUTOCONF,
                .type           = PORT_SCIF,
-               .irqs           =  { 248, 249, 250, 251},
+               .irqs           =  { 249, 250, 251, 248},
        }, {
                .mapbase        = 0xfffe9800,
                .flags          = UPF_BOOT_AUTOCONF,
                .type           = PORT_SCIF,
-               .irqs           =  { 252, 253, 254, 255},
+               .irqs           =  { 253, 254, 255, 252},
        }, {
                .flags = 0,
        }
@@ -56,3 +56,57 @@ static int __init sh7206_devices_setup(void)
                                    ARRAY_SIZE(sh7206_devices));
 }
 __initcall(sh7206_devices_setup);
+
+#define INTC_IPR08     0xfffe0c04UL
+#define INTC_IPR09     0xfffe0c06UL
+#define INTC_IPR14     0xfffe0c10UL
+
+#define CMI0_IRQ       140
+
+#define MTU1_TGI1A     164
+
+#define SCIF0_BRI_IRQ  240
+#define SCIF0_ERI_IRQ  241
+#define SCIF0_RXI_IRQ  242
+#define SCIF0_TXI_IRQ  243
+
+#define SCIF1_BRI_IRQ  244
+#define SCIF1_ERI_IRQ  245
+#define SCIF1_RXI_IRQ  246
+#define SCIF1_TXI_IRQ  247
+
+#define SCIF2_BRI_IRQ  248
+#define SCIF2_ERI_IRQ  249
+#define SCIF2_RXI_IRQ  250
+#define SCIF2_TXI_IRQ  251
+
+#define SCIF3_BRI_IRQ  252
+#define SCIF3_ERI_IRQ  253
+#define SCIF3_RXI_IRQ  254
+#define SCIF3_TXI_IRQ  255
+
+static struct ipr_data sh7206_ipr_map[] = {
+       { CMI0_IRQ,      INTC_IPR08, 3, 2 },
+       { MTU2_TGI1A,    INTC_IPR09, 1, 2 },
+       { SCIF0_ERI_IRQ, INTC_IPR14, 3, 3 },
+       { SCIF0_RXI_IRQ, INTC_IPR14, 3, 3 },
+       { SCIF0_BRI_IRQ, INTC_IPR14, 3, 3 },
+       { SCIF0_TXI_IRQ, INTC_IPR14, 3, 3 },
+       { SCIF1_ERI_IRQ, INTC_IPR14, 2, 3 },
+       { SCIF1_RXI_IRQ, INTC_IPR14, 2, 3 },
+       { SCIF1_BRI_IRQ, INTC_IPR14, 2, 3 },
+       { SCIF1_TXI_IRQ, INTC_IPR14, 2, 3 },
+       { SCIF2_ERI_IRQ, INTC_IPR14, 1, 3 },
+       { SCIF2_RXI_IRQ, INTC_IPR14, 1, 3 },
+       { SCIF2_BRI_IRQ, INTC_IPR14, 1, 3 },
+       { SCIF2_TXI_IRQ, INTC_IPR14, 1, 3 },
+       { SCIF3_ERI_IRQ, INTC_IPR14, 0, 3 },
+       { SCIF3_RXI_IRQ, INTC_IPR14, 0, 3 },
+       { SCIF3_BRI_IRQ, INTC_IPR14, 0, 3 },
+       { SCIF3_TXI_IRQ, INTC_IPR14, 0, 3 },
+};
+
+void __init init_IRQ_ipr(void)
+{
+       make_ipr_irq(sh7206_ipr_map, ARRAY_SIZE(sh7206_ipr_map));
+}
index 6e415ba..19ca68c 100644 (file)
@@ -12,17 +12,12 @@ obj-$(CONFIG_SH_STORE_QUEUES)               += sq.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7750)       += setup-sh7750.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7751)       += setup-sh7750.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7760)       += setup-sh7760.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7770)       += setup-sh7770.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7780)       += setup-sh7780.o
-obj-$(CONFIG_CPU_SUBTYPE_SH73180)      += setup-sh73180.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7343)       += setup-sh7343.o
 obj-$(CONFIG_CPU_SUBTYPE_SH4_202)      += setup-sh4-202.o
 
 # Primary on-chip clocks (common)
+ifndef CONFIG_CPU_SH4A
 clock-$(CONFIG_CPU_SH4)                        := clock-sh4.o
-clock-$(CONFIG_CPU_SUBTYPE_SH73180)    := clock-sh73180.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7770)     := clock-sh7770.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7780)     := clock-sh7780.o
+endif
 
 # Additional clocks by subtype
 clock-$(CONFIG_CPU_SUBTYPE_SH4_202)    += clock-sh4-202.o
index afe0f1b..9031a22 100644 (file)
@@ -119,11 +119,20 @@ int __init detect_cpu_and_cache_system(void)
                break;
        case 0x3000:
        case 0x3003:
+       case 0x3009:
                cpu_data->type = CPU_SH7343;
                cpu_data->icache.ways = 4;
                cpu_data->dcache.ways = 4;
                cpu_data->flags |= CPU_HAS_LLSC;
                break;
+       case 0x3008:
+               if (prr == 0xa0) {
+                       cpu_data->type = CPU_SH7722;
+                       cpu_data->icache.ways = 4;
+                       cpu_data->dcache.ways = 4;
+                       cpu_data->flags |= CPU_HAS_LLSC;
+               }
+               break;
        case 0x8000:
                cpu_data->type = CPU_ST40RA;
                cpu_data->flags |= CPU_HAS_FPU;
index bbcb06f..cbac276 100644 (file)
 #include <linux/io.h>
 #include <asm/sci.h>
 
+static struct resource rtc_resources[] = {
+       [0] = {
+               .start  = 0xffc80000,
+               .end    = 0xffc80000 + 0x58 - 1,
+               .flags  = IORESOURCE_IO,
+       },
+       [1] = {
+               /* Period IRQ */
+               .start  = 21,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               /* Carry IRQ */
+               .start  = 22,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [3] = {
+               /* Alarm IRQ */
+               .start  = 20,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device rtc_device = {
+       .name           = "sh-rtc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(rtc_resources),
+       .resource       = rtc_resources,
+};
+
 static struct plat_sci_port sci_platform_data[] = {
        {
                .mapbase        = 0xffe00000,
@@ -39,6 +69,7 @@ static struct platform_device sci_device = {
 };
 
 static struct platform_device *sh7750_devices[] __initdata = {
+       &rtc_device,
        &sci_device,
 };
 
index 0c9ea38..d7fff75 100644 (file)
@@ -111,8 +111,9 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags)
 
        vma->phys_addr = map->addr;
 
-       if (remap_area_pages((unsigned long)vma->addr, vma->phys_addr,
-                            map->size, flags)) {
+       if (ioremap_page_range((unsigned long)vma->addr,
+                              (unsigned long)vma->addr + map->size,
+                              vma->phys_addr, __pgprot(flags))) {
                vunmap(vma->addr);
                return -EAGAIN;
        }
@@ -176,7 +177,7 @@ unsigned long sq_remap(unsigned long phys, unsigned int size,
 
        map->sq_addr = P4SEG_STORE_QUE + (page << PAGE_SHIFT);
 
-       ret = __sq_remap(map, flags);
+       ret = __sq_remap(map, pgprot_val(PAGE_KERNEL_NOCACHE) | flags);
        if (unlikely(ret != 0))
                goto out;
 
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
new file mode 100644 (file)
index 0000000..a8f493f
--- /dev/null
@@ -0,0 +1,19 @@
+#
+# Makefile for the Linux/SuperH SH-4 backends.
+#
+
+# CPU subtype setup
+obj-$(CONFIG_CPU_SUBTYPE_SH7770)       += setup-sh7770.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7780)       += setup-sh7780.o
+obj-$(CONFIG_CPU_SUBTYPE_SH73180)      += setup-sh73180.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7343)       += setup-sh7343.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7722)       += setup-sh7722.o
+
+# Primary on-chip clocks (common)
+clock-$(CONFIG_CPU_SUBTYPE_SH73180)    := clock-sh73180.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7770)     := clock-sh7770.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7780)     := clock-sh7780.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7343)     := clock-sh7343.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7722)     := clock-sh7343.o
+
+obj-y  += $(clock-y)
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
new file mode 100644 (file)
index 0000000..1707a21
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * arch/sh/kernel/cpu/sh4/clock-sh7343.c
+ *
+ * SH7343/SH7722 support for the clock framework
+ *
+ *  Copyright (C) 2006  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+
+/*
+ * SH7343/SH7722 uses a common set of multipliers and divisors, so this
+ * is quite simple..
+ */
+static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
+
+#define pll_calc() (((ctrl_inl(FRQCR) >> 24) & 0x1f) + 1)
+
+static void master_clk_init(struct clk *clk)
+{
+       clk->parent = clk_get(NULL, "cpu_clk");
+}
+
+static void master_clk_recalc(struct clk *clk)
+{
+       int idx = (ctrl_inl(FRQCR) & 0x000f);
+       clk->rate *= clk->parent->rate * multipliers[idx] / divisors[idx];
+}
+
+static struct clk_ops sh7343_master_clk_ops = {
+       .init           = master_clk_init,
+       .recalc         = master_clk_recalc,
+};
+
+static void module_clk_init(struct clk *clk)
+{
+       clk->parent = NULL;
+       clk->rate = CONFIG_SH_PCLK_FREQ;
+}
+
+static struct clk_ops sh7343_module_clk_ops = {
+       .init           = module_clk_init,
+};
+
+static void bus_clk_init(struct clk *clk)
+{
+       clk->parent = clk_get(NULL, "cpu_clk");
+}
+
+static void bus_clk_recalc(struct clk *clk)
+{
+       int idx = (ctrl_inl(FRQCR) >> 8) & 0x000f;
+       clk->rate = clk->parent->rate * multipliers[idx] / divisors[idx];
+}
+
+static struct clk_ops sh7343_bus_clk_ops = {
+       .init           = bus_clk_init,
+       .recalc         = bus_clk_recalc,
+};
+
+static void cpu_clk_init(struct clk *clk)
+{
+       clk->parent = clk_get(NULL, "module_clk");
+       clk->flags |= CLK_RATE_PROPAGATES;
+       clk_set_rate(clk, clk_get_rate(clk));
+}
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+       int idx = (ctrl_inl(FRQCR) >> 20) & 0x000f;
+       clk->rate = clk->parent->rate * pll_calc() *
+               multipliers[idx] / divisors[idx];
+}
+
+static struct clk_ops sh7343_cpu_clk_ops = {
+       .init           = cpu_clk_init,
+       .recalc         = cpu_clk_recalc,
+};
+
+static struct clk_ops *sh7343_clk_ops[] = {
+       &sh7343_master_clk_ops,
+       &sh7343_module_clk_ops,
+       &sh7343_bus_clk_ops,
+       &sh7343_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+       if (idx < ARRAY_SIZE(sh7343_clk_ops))
+               *ops = sh7343_clk_ops[idx];
+}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
new file mode 100644 (file)
index 0000000..1143fbf
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * SH7722 Setup
+ *
+ *  Copyright (C) 2006  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <asm/sci.h>
+
+static struct plat_sci_port sci_platform_data[] = {
+       {
+               .mapbase        = 0xffe00000,
+               .flags          = UPF_BOOT_AUTOCONF,
+               .type           = PORT_SCIF,
+               .irqs           = { 80, 81, 83, 82 },
+       }, {
+               .flags = 0,
+       }
+};
+
+static struct platform_device sci_device = {
+       .name           = "sh-sci",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = sci_platform_data,
+       },
+};
+
+static struct platform_device *sh7722_devices[] __initdata = {
+       &sci_device,
+};
+
+static int __init sh7722_devices_setup(void)
+{
+       return platform_add_devices(sh7722_devices,
+                                   ARRAY_SIZE(sh7722_devices));
+}
+__initcall(sh7722_devices_setup);
+
+static struct ipr_data sh7722_ipr_map[] = {
+       /* IRQ, IPR-idx, shift, prio */
+       { 16, 0, 12, 2 }, /* TMU0 */
+       { 17, 0,  8, 2 }, /* TMU1 */
+       { 80, 6, 12, 3 }, /* SCIF ERI */
+       { 81, 6, 12, 3 }, /* SCIF RXI */
+       { 82, 6, 12, 3 }, /* SCIF BRI */
+       { 83, 6, 12, 3 }, /* SCIF TXI */
+};
+
+static unsigned long ipr_offsets[] = {
+       0xa4080000, /*  0: IPRA */
+       0xa4080004, /*  1: IPRB */
+       0xa4080008, /*  2: IPRC */
+       0xa408000c, /*  3: IPRD */
+       0xa4080010, /*  4: IPRE */
+       0xa4080014, /*  5: IPRF */
+       0xa4080018, /*  6: IPRG */
+       0xa408001c, /*  7: IPRH */
+       0xa4080020, /*  8: IPRI */
+       0xa4080024, /*  9: IPRJ */
+       0xa4080028, /* 10: IPRK */
+       0xa408002c, /* 11: IPRL */
+};
+
+unsigned int map_ipridx_to_addr(int idx)
+{
+       if (unlikely(idx >= ARRAY_SIZE(ipr_offsets)))
+               return 0;
+       return ipr_offsets[idx];
+}
+
+void __init init_IRQ_ipr(void)
+{
+       make_ipr_irq(sh7722_ipr_map, ARRAY_SIZE(sh7722_ipr_map));
+}
index 6034082..560b91c 100644 (file)
@@ -144,16 +144,16 @@ static struct console *early_console =
        ;
 
 static int __initdata keep_early;
+static int early_console_initialized;
 
-int __init setup_early_printk(char *opt)
+int __init setup_early_printk(char *buf)
 {
-       char *space;
-       char buf[256];
+       if (!buf)
+               return 0;
 
-       strlcpy(buf, opt, sizeof(buf));
-       space = strchr(buf, ' ');
-       if (space)
-               *space = 0;
+       if (early_console_initialized)
+               return 0;
+       early_console_initialized = 1;
 
        if (strstr(buf, "keep"))
                keep_early = 1;
@@ -175,12 +175,14 @@ int __init setup_early_printk(char *opt)
        if (likely(early_console))
                register_console(early_console);
 
-       return 1;
+       return 0;
 }
-__setup("earlyprintk=", setup_early_printk);
+early_param("earlyprintk", setup_early_printk);
 
 void __init disable_early_printk(void)
 {
+       if (!early_console_initialized || !early_console)
+               return;
        if (!keep_early) {
                printk("disabling early console\n");
                unregister_console(early_console);
index 29136a3..fc279ae 100644 (file)
@@ -79,18 +79,29 @@ debug_kernel_sw:
        .align  2
 3:     .long   kgdb_handle_exception
 #endif /* CONFIG_SH_KGDB */
-
+#ifdef CONFIG_SH_STANDARD_BIOS
+       bra     debug_kernel_fw
+        nop
+#endif
 #endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
 
-
        .align  2
 debug_trap:    
 #if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
+       mov     r8, r0
+       shlr2   r0
+       cmp/eq  #0x3f, r0               ! sh_bios() trap
+       bf      1f
+#ifdef CONFIG_SH_KGDB
+       cmp/eq  #0xff, r0               ! XXX: KGDB trap, fix for SH-2.
+       bf      1f
+#endif
        mov     #OFF_SR, r0
        mov.l   @(r0,r15), r0           ! get status register
        shll    r0
        shll    r0                      ! kernel space?
        bt/s    debug_kernel
+1:
 #endif
         mov.l  @r15, r0                ! Restore R0 value
        mov.l   1f, r8
index 6aca4bc..71a3ad7 100644 (file)
@@ -33,7 +33,8 @@ ENTRY(empty_zero_page)
        .long   0x00360000      /* INITRD_START */
        .long   0x000a0000      /* INITRD_SIZE */
        .long   0
-       .balign PAGE_SIZE,0,PAGE_SIZE
+1:
+       .skip   PAGE_SIZE - empty_zero_page - 1b
 
        .text   
 /*
index f3e2631..486c06e 100644 (file)
@@ -470,9 +470,10 @@ unsigned long get_wchan(struct task_struct *p)
         */
        pc = thread_saved_pc(p);
        if (in_sched_functions(pc)) {
-               schedule_frame = ((unsigned long *)(long)p->thread.sp)[1];
-               return (unsigned long)((unsigned long *)schedule_frame)[1];
+               schedule_frame = (unsigned long)p->thread.sp;
+               return ((unsigned long *)schedule_frame)[21];
        }
+
        return pc;
 }
 
@@ -498,6 +499,16 @@ asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5,
 {
        struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
 
+       /* Rewind */
        regs->pc -= 2;
+
+#ifdef CONFIG_BUG
+       if (__kernel_text_address(instruction_pointer(regs))) {
+               u16 insn = *(u16 *)instruction_pointer(regs);
+               if (insn == TRAPA_BUG_OPCODE)
+                       handle_BUG(regs);
+       }
+#endif
+
        force_sig(SIGTRAP, current);
 }
index f8dd6b7..225f9ea 100644 (file)
@@ -84,8 +84,7 @@ unsigned long memory_start, memory_end;
 
 static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE],
                                  struct sh_machine_vector** mvp,
-                                 unsigned long *mv_io_base,
-                                 int *mv_mmio_enable)
+                                 unsigned long *mv_io_base)
 {
        char c = ' ', *to = command_line, *from = COMMAND_LINE;
        int len = 0;
@@ -112,23 +111,6 @@ static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE],
                        }
                }
 
-#ifdef CONFIG_EARLY_PRINTK
-               if (c == ' ' && !memcmp(from, "earlyprintk=", 12)) {
-                       char *ep_end;
-
-                       if (to != command_line)
-                               to--;
-
-                       from += 12;
-                       ep_end = strchr(from, ' ');
-
-                       setup_early_printk(from);
-                       printk("early console enabled\n");
-
-                       from = ep_end;
-               }
-#endif
-
                if (c == ' ' && !memcmp(from, "sh_mv=", 6)) {
                        char* mv_end;
                        char* mv_comma;
@@ -145,7 +127,6 @@ static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE],
                                int ints[3];
                                get_options(mv_comma+1, ARRAY_SIZE(ints), ints);
                                *mv_io_base = ints[1];
-                               *mv_mmio_enable = ints[2];
                                mv_len = mv_comma - from;
                        } else {
                                mv_len = mv_end - from;
@@ -158,6 +139,7 @@ static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE],
 
                        *mvp = get_mv_byname(mv_name);
                }
+
                c = *(from++);
                if (!c)
                        break;
@@ -177,9 +159,8 @@ static int __init sh_mv_setup(char **cmdline_p)
        struct sh_machine_vector *mv = NULL;
        char mv_name[MV_NAME_SIZE] = "";
        unsigned long mv_io_base = 0;
-       int mv_mmio_enable = 0;
 
-       parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable);
+       parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base);
 
 #ifdef CONFIG_SH_UNKNOWN
        if (mv == NULL) {
@@ -258,6 +239,7 @@ void __init setup_arch(char **cmdline_p)
 
        sh_mv_setup(cmdline_p);
 
+
        /*
         * Find the highest page frame number we have available
         */
@@ -305,6 +287,7 @@ void __init setup_arch(char **cmdline_p)
                                  PFN_PHYS(pages));
        }
 
+
        /*
         * Reserve the kernel text and
         * Reserve the bootmem bitmap. We do this in two steps (first step
@@ -325,14 +308,18 @@ void __init setup_arch(char **cmdline_p)
        ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
        if (&__rd_start != &__rd_end) {
                LOADER_TYPE = 1;
-               INITRD_START = PHYSADDR((unsigned long)&__rd_start) - __MEMORY_START;
-               INITRD_SIZE = (unsigned long)&__rd_end - (unsigned long)&__rd_start;
+               INITRD_START = PHYSADDR((unsigned long)&__rd_start) -
+                                       __MEMORY_START;
+               INITRD_SIZE = (unsigned long)&__rd_end -
+                             (unsigned long)&__rd_start;
        }
 
        if (LOADER_TYPE && INITRD_START) {
                if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
-                       reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE);
-                       initrd_start = INITRD_START + PAGE_OFFSET + __MEMORY_START;
+                       reserve_bootmem_node(NODE_DATA(0), INITRD_START +
+                                               __MEMORY_START, INITRD_SIZE);
+                       initrd_start = INITRD_START + PAGE_OFFSET +
+                                       __MEMORY_START;
                        initrd_end = initrd_start + INITRD_SIZE;
                } else {
                        printk("initrd extends beyond end of memory "
@@ -404,7 +391,7 @@ static const char *cpu_name[] = {
        [CPU_SH4_202]   = "SH4-202",    [CPU_SH4_501]   = "SH4-501",
        [CPU_SH7770]    = "SH7770",     [CPU_SH7780]    = "SH7780",
        [CPU_SH7781]    = "SH7781",     [CPU_SH7343]    = "SH7343",
-       [CPU_SH7785]    = "SH7785",
+       [CPU_SH7785]    = "SH7785",     [CPU_SH7722]    = "SH7722",
        [CPU_SH_NONE]   = "Unknown"
 };
 
index ceee791..e610623 100644 (file)
@@ -70,13 +70,26 @@ DECLARE_EXPORT(__sdivsi3);
 DECLARE_EXPORT(__ashrdi3);
 DECLARE_EXPORT(__ashldi3);
 DECLARE_EXPORT(__lshrdi3);
-DECLARE_EXPORT(__movstr);
 DECLARE_EXPORT(__movstrSI16);
+#if __GNUC__ == 4
+DECLARE_EXPORT(__movmem);
+#else
+DECLARE_EXPORT(__movstr);
+#endif
 
 #ifdef CONFIG_CPU_SH4
+#if __GNUC__ == 4
+DECLARE_EXPORT(__movmem_i4_even);
+DECLARE_EXPORT(__movmem_i4_odd);
+DECLARE_EXPORT(__movmemSI12_i4);
+DECLARE_EXPORT(__sdivsi3_i4i);
+DECLARE_EXPORT(__udiv_qrnnd_16);
+DECLARE_EXPORT(__udivsi3_i4i);
+#else /* GCC 3.x */
 DECLARE_EXPORT(__movstr_i4_even);
 DECLARE_EXPORT(__movstr_i4_odd);
 DECLARE_EXPORT(__movstrSI12_i4);
+#endif /* __GNUC__ == 4 */
 #endif
 
 #if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)
index bb1c480..379c88b 100644 (file)
@@ -101,7 +101,7 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
  */
 
 #define MOVW(n)         (0x9300|((n)-2))       /* Move mem word at PC+n to R3 */
-#if defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH2A)
+#if defined(CONFIG_CPU_SH2)
 #define TRAP_NOARG 0xc320              /* Syscall w/no args (NR in R3) */
 #else
 #define TRAP_NOARG 0xc310              /* Syscall w/no args (NR in R3) */
index 5083b6e..e18f183 100644 (file)
@@ -314,6 +314,12 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1,
 #endif
 }
 
+#if defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH2A)
+#define SYSCALL_ARG3   "trapa #0x23"
+#else
+#define SYSCALL_ARG3   "trapa #0x13"
+#endif
+
 /*
  * Do a system call from kernel instead of calling sys_execve so we
  * end up with proper pt_regs.
@@ -324,7 +330,7 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[])
        register long __sc4 __asm__ ("r4") = (long) filename;
        register long __sc5 __asm__ ("r5") = (long) argv;
        register long __sc6 __asm__ ("r6") = (long) envp;
-       __asm__ __volatile__ ("trapa    #0x13" : "=z" (__sc0)
+       __asm__ __volatile__ (SYSCALL_ARG3 : "=z" (__sc0)       
                        : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6)
                        : "memory");
        return __sc0;
index 3762d9d..ec11015 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kallsyms.h>
 #include <linux/io.h>
 #include <linux/debug_locks.h>
+#include <linux/limits.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
@@ -129,6 +130,40 @@ static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
        return -EFAULT;
 }
 
+#ifdef CONFIG_BUG
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+static inline void do_bug_verbose(struct pt_regs *regs)
+{
+       struct bug_frame f;
+       long len;
+
+       if (__copy_from_user(&f, (const void __user *)regs->pc,
+                            sizeof(struct bug_frame)))
+               return;
+
+       len = __strnlen_user(f.file, PATH_MAX) - 1;
+       if (unlikely(len < 0 || len >= PATH_MAX))
+               f.file = "<bad filename>";
+       len = __strnlen_user(f.func, PATH_MAX) - 1;
+       if (unlikely(len < 0 || len >= PATH_MAX))
+               f.func = "<bad function>";
+
+       printk(KERN_ALERT "kernel BUG in %s() at %s:%d!\n",
+              f.func, f.file, f.line);
+}
+#else
+static inline void do_bug_verbose(struct pt_regs *regs)
+{
+}
+#endif /* CONFIG_DEBUG_BUGVERBOSE */
+#endif /* CONFIG_BUG */
+
+void handle_BUG(struct pt_regs *regs)
+{
+       do_bug_verbose(regs);
+       die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
+}
+
 /*
  * handle an instruction that does an unaligned memory access by emulating the
  * desired behaviour
index 77b4026..f34bdcc 100644 (file)
@@ -51,7 +51,7 @@ SECTIONS
        }
 
   . = ALIGN(PAGE_SIZE);
-  .data.page_aligned : { *(.data.idt) }
+  .data.page_aligned : { *(.data.page_aligned) }
 
   . = ALIGN(32);
   __per_cpu_start = .;
index 4e0362f..29f4ee3 100644 (file)
@@ -35,6 +35,9 @@ config CPU_SUBTYPE_ST40
        select CPU_SH4
        select CPU_HAS_INTC2_IRQ
 
+config CPU_SHX2
+       bool
+
 #
 # Processor subtypes
 #
@@ -180,6 +183,7 @@ config CPU_SUBTYPE_SH7780
 config CPU_SUBTYPE_SH7785
        bool "Support SH7785 processor"
        select CPU_SH4A
+       select CPU_SHX2
        select CPU_HAS_INTC2_IRQ
 
 comment "SH4AL-DSP Processor Support"
@@ -192,6 +196,12 @@ config CPU_SUBTYPE_SH7343
        bool "Support SH7343 processor"
        select CPU_SH4AL_DSP
 
+config CPU_SUBTYPE_SH7722
+       bool "Support SH7722 processor"
+       select CPU_SH4AL_DSP
+       select CPU_SHX2
+       select CPU_HAS_IPR_IRQ
+
 endmenu
 
 menu "Memory management options"
@@ -250,7 +260,7 @@ config 32BIT
 
 config X2TLB
        bool "Enable extended TLB mode"
-       depends on CPU_SUBTYPE_SH7785 && MMU && EXPERIMENTAL
+       depends on CPU_SHX2 && MMU && EXPERIMENTAL
        help
          Selecting this option will enable the extended mode of the SH-X2
          TLB. For legacy SH-X behaviour and interoperability, say N. For
index ae531af..c695515 100644 (file)
@@ -107,7 +107,7 @@ void __init p3_cache_init(void)
 
        emit_cache_params();
 
-       if (remap_area_pages(P3SEG, 0, PAGE_SIZE * 4, _PAGE_CACHABLE))
+       if (ioremap_page_range(P3SEG, P3SEG + (PAGE_SIZE * 4), 0, PAGE_KERNEL))
                panic("%s failed.", __FUNCTION__);
 
        for (i = 0; i < cpu_data->dcache.n_aliases; i++)
index 59f4cc1..29bd37b 100644 (file)
@@ -77,6 +77,7 @@ void show_mem(void)
        printk("%d pages swap cached\n",cached);
 }
 
+#ifdef CONFIG_MMU
 static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
 {
        pgd_t *pgd;
@@ -139,6 +140,7 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
 
        set_pte_phys(address, phys, prot);
 }
+#endif /* CONFIG_MMU */
 
 /* References to section boundaries */
 
index 81f1562..3abcfa3 100644 (file)
@@ -27,10 +27,13 @@ config X86_POWERNOW_K8_ACPI
        default y
 
 config X86_SPEEDSTEP_CENTRINO
-       tristate "Intel Enhanced SpeedStep"
+       tristate "Intel Enhanced SpeedStep (deprecated)"
        select CPU_FREQ_TABLE
        depends on ACPI_PROCESSOR
        help
+         This is deprecated and this functionality is now merged into
+         acpi_cpufreq (X86_ACPI_CPUFREQ). Use that driver instead of
+         speedstep_centrino.
          This adds the CPUFreq driver for Enhanced SpeedStep enabled
          mobile CPUs.  This means Intel Pentium M (Centrino) CPUs
          or 64bit enabled Intel Xeons.
@@ -50,6 +53,7 @@ config X86_ACPI_CPUFREQ
        help
          This driver adds a CPUFreq driver which utilizes the ACPI
          Processor Performance States.
+         This driver also supports Intel Enhanced Speedstep.
 
          For details, take a look at <file:Documentation/cpu-freq/>.
 
index d8b5938..753ce1d 100644 (file)
@@ -5,8 +5,8 @@
 SRCDIR := ../../../i386/kernel/cpu/cpufreq
 
 obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
-obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
 obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
+obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
 obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o
 obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o
 
index bdb9c8b..9e584a7 100644 (file)
@@ -360,7 +360,7 @@ static int __init i2c_ioc_init(void)
        if (ret >= 0){
                ret = misc_register(&rtc_dev);
                if(ret < 0)
-                       i2c_bit_del_bus(&ioc_ops);
+                       i2c_del_adapter(&ioc_ops);
        }
 
        return ret;
index cb86967..38bd373 100644 (file)
@@ -203,9 +203,9 @@ static int __init at91wdt_probe(struct platform_device *pdev)
 {
        int res;
 
-       if (at91wdt_miscdev.dev)
+       if (at91wdt_miscdev.parent)
                return -EBUSY;
-       at91wdt_miscdev.dev = &pdev->dev;
+       at91wdt_miscdev.parent = &pdev->dev;
 
        res = misc_register(&at91wdt_miscdev);
        if (res)
@@ -221,7 +221,7 @@ static int __exit at91wdt_remove(struct platform_device *pdev)
 
        res = misc_deregister(&at91wdt_miscdev);
        if (!res)
-               at91wdt_miscdev.dev = NULL;
+               at91wdt_miscdev.parent = NULL;
 
        return res;
 }
index 3404a9c..e88947f 100644 (file)
@@ -347,7 +347,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
                goto err_free;
        }
 
-       mpcore_wdt_miscdev.dev = &dev->dev;
+       mpcore_wdt_miscdev.parent = &dev->dev;
        ret = misc_register(&mpcore_wdt_miscdev);
        if (ret) {
                dev_printk(KERN_ERR, _dev, "cannot register miscdev on minor=%d (err=%d)\n",
index 5dbd7dc..6c6f973 100644 (file)
@@ -290,7 +290,7 @@ static int __init omap_wdt_probe(struct platform_device *pdev)
        omap_wdt_disable();
        omap_wdt_adjust_timeout(timer_margin);
 
-       omap_wdt_miscdev.dev = &pdev->dev;
+       omap_wdt_miscdev.parent = &pdev->dev;
        ret = misc_register(&omap_wdt_miscdev);
        if (ret)
                goto fail;
index 6113872..2da5ac9 100644 (file)
@@ -42,6 +42,7 @@
 #include <asm/uaccess.h>
 #include <linux/usb.h>
 #include <linux/mutex.h>
+#include <linux/hid.h>         /* For HID_REQ_SET_REPORT & HID_DT_REPORT */
 
 
 #ifdef CONFIG_USB_DEBUG
@@ -109,10 +110,6 @@ MODULE_DEVICE_TABLE (usb, usb_pcwd_table);
 #define CMD_ENABLE_WATCHDOG            0x30    /* Enable / Disable Watchdog */
 #define CMD_DISABLE_WATCHDOG           CMD_ENABLE_WATCHDOG
 
-/* Some defines that I like to be somewhere else like include/linux/usb_hid.h */
-#define HID_REQ_SET_REPORT             0x09
-#define HID_DT_REPORT                  (USB_TYPE_CLASS | 0x02)
-
 /* We can only use 1 card due to the /dev/watchdog restriction */
 static int cards_found;
 
index ec39093..7576a13 100644 (file)
@@ -47,7 +47,7 @@
 
 
 /* Function prototypes */
-static irqreturn_t wdt_gpi_irqhdl(int, void *, struct pt_regs *);
+static irqreturn_t wdt_gpi_irqhdl(int, void *);
 static void wdt_gpi_start(void);
 static void wdt_gpi_stop(void);
 static void wdt_gpi_set_timeout(unsigned int);
@@ -94,8 +94,28 @@ module_param(nowayout, bool, 0444);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be disabled once started");
 
 
+/* Kernel interfaces */
+static struct file_operations fops = {
+       .owner          = THIS_MODULE,
+       .open           = wdt_gpi_open,
+       .release        = wdt_gpi_release,
+       .write          = wdt_gpi_write,
+       .unlocked_ioctl = wdt_gpi_ioctl,
+};
+
+static struct miscdevice miscdev = {
+       .minor          = WATCHDOG_MINOR,
+       .name           = wdt_gpi_name,
+       .fops           = &fops,
+};
+
+static struct notifier_block wdt_gpi_shutdown = {
+       .notifier_call  = wdt_gpi_notify,
+};
+
+
 /* Interrupt handler */
-static irqreturn_t wdt_gpi_irqhdl(int irq, void *ctxt, struct pt_regs *regs)
+static irqreturn_t wdt_gpi_irqhdl(int irq, void *ctxt)
 {
        if (!unlikely(__raw_readl(wd_regs + 0x0008) & 0x1))
                return IRQ_NONE;
@@ -312,26 +332,6 @@ wdt_gpi_notify(struct notifier_block *this, unsigned long code, void *unused)
 }
 
 
-/* Kernel interfaces */
-static struct file_operations fops = {
-       .owner          = THIS_MODULE,
-       .open           = wdt_gpi_open,
-       .release        = wdt_gpi_release,
-       .write          = wdt_gpi_write,
-       .unlocked_ioctl = wdt_gpi_ioctl,
-};
-
-static struct miscdevice miscdev = {
-       .minor          = WATCHDOG_MINOR,
-       .name           = wdt_gpi_name,
-       .fops           = &fops,
-};
-
-static struct notifier_block wdt_gpi_shutdown = {
-       .notifier_call  = wdt_gpi_notify,
-};
-
-
 /* Init & exit procedures */
 static const struct resource *
 wdt_gpi_get_resource(struct platform_device *pdv, const char *name,
index 47ab42d..9fb2edf 100644 (file)
@@ -29,7 +29,8 @@
 #include <linux/completion.h>
 #include <linux/mutex.h>
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "cpufreq-core", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, \
+                                               "cpufreq-core", msg)
 
 /**
  * The "cpufreq driver" - the arch- or hardware-dependent low
@@ -151,7 +152,8 @@ static void cpufreq_debug_disable_ratelimit(void)
        spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
 }
 
-void cpufreq_debug_printk(unsigned int type, const char *prefix, const char *fmt, ...)
+void cpufreq_debug_printk(unsigned int type, const char *prefix,
+                                                       const char *fmt, ...)
 {
        char s[256];
        va_list args;
@@ -161,7 +163,8 @@ void cpufreq_debug_printk(unsigned int type, const char *prefix, const char *fmt
        WARN_ON(!prefix);
        if (type & debug) {
                spin_lock_irqsave(&disable_ratelimit_lock, flags);
-               if (!disable_ratelimit && debug_ratelimit && !printk_ratelimit()) {
+               if (!disable_ratelimit && debug_ratelimit
+                                       && !printk_ratelimit()) {
                        spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
                        return;
                }
@@ -182,10 +185,12 @@ EXPORT_SYMBOL(cpufreq_debug_printk);
 
 
 module_param(debug, uint, 0644);
-MODULE_PARM_DESC(debug, "CPUfreq debugging: add 1 to debug core, 2 to debug drivers, and 4 to debug governors.");
+MODULE_PARM_DESC(debug, "CPUfreq debugging: add 1 to debug core,"
+                       " 2 to debug drivers, and 4 to debug governors.");
 
 module_param(debug_ratelimit, uint, 0644);
-MODULE_PARM_DESC(debug_ratelimit, "CPUfreq debugging: set to 0 to disable ratelimiting.");
+MODULE_PARM_DESC(debug_ratelimit, "CPUfreq debugging:"
+                                       " set to 0 to disable ratelimiting.");
 
 #else /* !CONFIG_CPU_FREQ_DEBUG */
 
@@ -219,17 +224,23 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
        if (!l_p_j_ref_freq) {
                l_p_j_ref = loops_per_jiffy;
                l_p_j_ref_freq = ci->old;
-               dprintk("saving %lu as reference value for loops_per_jiffy; freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
+               dprintk("saving %lu as reference value for loops_per_jiffy;"
+                       "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
        }
        if ((val == CPUFREQ_PRECHANGE  && ci->old < ci->new) ||
            (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) ||
            (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
-               loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new);
-               dprintk("scaling loops_per_jiffy to %lu for frequency %u kHz\n", loops_per_jiffy, ci->new);
+               loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
+                                                               ci->new);
+               dprintk("scaling loops_per_jiffy to %lu"
+                       "for frequency %u kHz\n", loops_per_jiffy, ci->new);
        }
 }
 #else
-static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) { return; }
+static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
+{
+       return;
+}
 #endif
 
 
@@ -316,7 +327,8 @@ static int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
                if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
                        *policy = CPUFREQ_POLICY_PERFORMANCE;
                        err = 0;
-               } else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) {
+               } else if (!strnicmp(str_governor, "powersave",
+                                               CPUFREQ_NAME_LEN)) {
                        *policy = CPUFREQ_POLICY_POWERSAVE;
                        err = 0;
                }
@@ -328,7 +340,8 @@ static int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
                t = __find_governor(str_governor);
 
                if (t == NULL) {
-                       char *name = kasprintf(GFP_KERNEL, "cpufreq_%s", str_governor);
+                       char *name = kasprintf(GFP_KERNEL, "cpufreq_%s",
+                                                               str_governor);
 
                        if (name) {
                                int ret;
@@ -361,7 +374,8 @@ extern struct sysdev_class cpu_sysdev_class;
 
 
 /**
- * cpufreq_per_cpu_attr_read() / show_##file_name() - print out cpufreq information
+ * cpufreq_per_cpu_attr_read() / show_##file_name() -
+ * print out cpufreq information
  *
  * Write out information from cpufreq_driver->policy[cpu]; object must be
  * "unsigned int".
@@ -380,7 +394,8 @@ show_one(scaling_min_freq, min);
 show_one(scaling_max_freq, max);
 show_one(scaling_cur_freq, cur);
 
-static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy);
+static int __cpufreq_set_policy(struct cpufreq_policy *data,
+                               struct cpufreq_policy *policy);
 
 /**
  * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
@@ -416,7 +431,8 @@ store_one(scaling_max_freq,max);
 /**
  * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
  */
-static ssize_t show_cpuinfo_cur_freq (struct cpufreq_policy * policy, char *buf)
+static ssize_t show_cpuinfo_cur_freq (struct cpufreq_policy * policy,
+                                                       char *buf)
 {
        unsigned int cur_freq = cpufreq_get(policy->cpu);
        if (!cur_freq)
@@ -428,7 +444,8 @@ static ssize_t show_cpuinfo_cur_freq (struct cpufreq_policy * policy, char *buf)
 /**
  * show_scaling_governor - show the current policy for the specified CPU
  */
-static ssize_t show_scaling_governor (struct cpufreq_policy * policy, char *buf)
+static ssize_t show_scaling_governor (struct cpufreq_policy * policy,
+                                                       char *buf)
 {
        if(policy->policy == CPUFREQ_POLICY_POWERSAVE)
                return sprintf(buf, "powersave\n");
@@ -458,7 +475,8 @@ static ssize_t store_scaling_governor (struct cpufreq_policy * policy,
        if (ret != 1)
                return -EINVAL;
 
-       if (cpufreq_parse_governor(str_governor, &new_policy.policy, &new_policy.governor))
+       if (cpufreq_parse_governor(str_governor, &new_policy.policy,
+                                               &new_policy.governor))
                return -EINVAL;
 
        lock_cpu_hotplug();
@@ -474,7 +492,10 @@ static ssize_t store_scaling_governor (struct cpufreq_policy * policy,
 
        unlock_cpu_hotplug();
 
-       return ret ? ret : count;
+       if (ret)
+               return ret;
+       else
+               return count;
 }
 
 /**
@@ -488,7 +509,7 @@ static ssize_t show_scaling_driver (struct cpufreq_policy * policy, char *buf)
 /**
  * show_scaling_available_governors - show the available CPUfreq governors
  */
-static ssize_t show_scaling_available_governors (struct cpufreq_policy * policy,
+static ssize_t show_scaling_available_governors (struct cpufreq_policy *policy,
                                char *buf)
 {
        ssize_t i = 0;
@@ -574,7 +595,11 @@ static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf)
        policy = cpufreq_cpu_get(policy->cpu);
        if (!policy)
                return -EINVAL;
-       ret = fattr->show ? fattr->show(policy,buf) : -EIO;
+       if (fattr->show)
+               ret = fattr->show(policy, buf);
+       else
+               ret = -EIO;
+
        cpufreq_cpu_put(policy);
        return ret;
 }
@@ -588,7 +613,11 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr,
        policy = cpufreq_cpu_get(policy->cpu);
        if (!policy)
                return -EINVAL;
-       ret = fattr->store ? fattr->store(policy,buf,count) : -EIO;
+       if (fattr->store)
+               ret = fattr->store(policy, buf, count);
+       else
+               ret = -EIO;
+
        cpufreq_cpu_put(policy);
        return ret;
 }
@@ -913,7 +942,8 @@ static void handle_update(struct work_struct *work)
  *     We adjust to current frequency first, and need to clean up later. So either call
  *     to cpufreq_update_policy() or schedule handle_update()).
  */
-static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, unsigned int new_freq)
+static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
+                               unsigned int new_freq)
 {
        struct cpufreq_freqs freqs;
 
@@ -938,16 +968,16 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, unsigne
 unsigned int cpufreq_quick_get(unsigned int cpu)
 {
        struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-       unsigned int ret = 0;
+       unsigned int ret_freq = 0;
 
        if (policy) {
                mutex_lock(&policy->lock);
-               ret = policy->cur;
+               ret_freq = policy->cur;
                mutex_unlock(&policy->lock);
                cpufreq_cpu_put(policy);
        }
 
-       return (ret);
+       return (ret_freq);
 }
 EXPORT_SYMBOL(cpufreq_quick_get);
 
@@ -961,7 +991,7 @@ EXPORT_SYMBOL(cpufreq_quick_get);
 unsigned int cpufreq_get(unsigned int cpu)
 {
        struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-       unsigned int ret = 0;
+       unsigned int ret_freq = 0;
 
        if (!policy)
                return 0;
@@ -971,12 +1001,14 @@ unsigned int cpufreq_get(unsigned int cpu)
 
        mutex_lock(&policy->lock);
 
-       ret = cpufreq_driver->get(cpu);
+       ret_freq = cpufreq_driver->get(cpu);
 
-       if (ret && policy->cur && !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
-               /* verify no discrepancy between actual and saved value exists */
-               if (unlikely(ret != policy->cur)) {
-                       cpufreq_out_of_sync(cpu, policy->cur, ret);
+       if (ret_freq && policy->cur &&
+               !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
+               /* verify no discrepancy between actual and
+                                       saved value exists */
+               if (unlikely(ret_freq != policy->cur)) {
+                       cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
                        schedule_work(&policy->update);
                }
        }
@@ -986,7 +1018,7 @@ unsigned int cpufreq_get(unsigned int cpu)
 out:
        cpufreq_cpu_put(policy);
 
-       return (ret);
+       return (ret_freq);
 }
 EXPORT_SYMBOL(cpufreq_get);
 
@@ -998,7 +1030,7 @@ EXPORT_SYMBOL(cpufreq_get);
 static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg)
 {
        int cpu = sysdev->id;
-       unsigned int ret = 0;
+       int ret = 0;
        unsigned int cur_freq = 0;
        struct cpufreq_policy *cpu_policy;
 
@@ -1080,7 +1112,7 @@ out:
 static int cpufreq_resume(struct sys_device * sysdev)
 {
        int cpu = sysdev->id;
-       unsigned int ret = 0;
+       int ret = 0;
        struct cpufreq_policy *cpu_policy;
 
        dprintk("resuming cpu %u\n", cpu);
@@ -1276,22 +1308,45 @@ int cpufreq_driver_target(struct cpufreq_policy *policy,
 }
 EXPORT_SYMBOL_GPL(cpufreq_driver_target);
 
+int cpufreq_driver_getavg(struct cpufreq_policy *policy)
+{
+       int ret = 0;
+
+       policy = cpufreq_cpu_get(policy->cpu);
+       if (!policy)
+               return -EINVAL;
+
+       mutex_lock(&policy->lock);
+
+       if (cpu_online(policy->cpu) && cpufreq_driver->getavg)
+               ret = cpufreq_driver->getavg(policy->cpu);
+
+       mutex_unlock(&policy->lock);
+
+       cpufreq_cpu_put(policy);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(cpufreq_driver_getavg);
+
 /*
  * Locking: Must be called with the lock_cpu_hotplug() lock held
  * when "event" is CPUFREQ_GOV_LIMITS
  */
 
-static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
+static int __cpufreq_governor(struct cpufreq_policy *policy,
+                                       unsigned int event)
 {
        int ret;
 
        if (!try_module_get(policy->governor->owner))
                return -EINVAL;
 
-       dprintk("__cpufreq_governor for CPU %u, event %u\n", policy->cpu, event);
+       dprintk("__cpufreq_governor for CPU %u, event %u\n",
+                                               policy->cpu, event);
        ret = policy->governor->governor(policy, event);
 
-       /* we keep one module reference alive for each CPU governed by this CPU */
+       /* we keep one module reference alive for
+                       each CPU governed by this CPU */
        if ((event != CPUFREQ_GOV_START) || ret)
                module_put(policy->governor->owner);
        if ((event == CPUFREQ_GOV_STOP) && !ret)
@@ -1367,9 +1422,12 @@ EXPORT_SYMBOL(cpufreq_get_policy);
 
 
 /*
+ * data   : current policy.
+ * policy : policy to be set.
  * Locking: Must be called with the lock_cpu_hotplug() lock held
  */
-static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy)
+static int __cpufreq_set_policy(struct cpufreq_policy *data,
+                               struct cpufreq_policy *policy)
 {
        int ret = 0;
 
@@ -1377,7 +1435,8 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
        dprintk("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
                policy->min, policy->max);
 
-       memcpy(&policy->cpuinfo, &data->cpuinfo, sizeof(struct cpufreq_cpuinfo));
+       memcpy(&policy->cpuinfo, &data->cpuinfo,
+                               sizeof(struct cpufreq_cpuinfo));
 
        if (policy->min > data->min && policy->min > policy->max) {
                ret = -EINVAL;
@@ -1410,7 +1469,8 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
        data->min = policy->min;
        data->max = policy->max;
 
-       dprintk("new min and max freqs are %u - %u kHz\n", data->min, data->max);
+       dprintk("new min and max freqs are %u - %u kHz\n",
+                                       data->min, data->max);
 
        if (cpufreq_driver->setpolicy) {
                data->policy = policy->policy;
@@ -1431,10 +1491,12 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
                        data->governor = policy->governor;
                        if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
                                /* new governor failed, so re-start old one */
-                               dprintk("starting governor %s failed\n", data->governor->name);
+                               dprintk("starting governor %s failed\n",
+                                                       data->governor->name);
                                if (old_gov) {
                                        data->governor = old_gov;
-                                       __cpufreq_governor(data, CPUFREQ_GOV_START);
+                                       __cpufreq_governor(data,
+                                                          CPUFREQ_GOV_START);
                                }
                                ret = -EINVAL;
                                goto error_out;
@@ -1524,7 +1586,8 @@ int cpufreq_update_policy(unsigned int cpu)
                        data->cur = policy.cur;
                } else {
                        if (data->cur != policy.cur)
-                               cpufreq_out_of_sync(cpu, data->cur, policy.cur);
+                               cpufreq_out_of_sync(cpu, data->cur,
+                                                               policy.cur);
                }
        }
 
@@ -1626,8 +1689,10 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
 
                /* if all ->init() calls failed, unregister */
                if (ret) {
-                       dprintk("no CPU initialized for driver %s\n", driver_data->name);
-                       sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
+                       dprintk("no CPU initialized for driver %s\n",
+                                                       driver_data->name);
+                       sysdev_driver_unregister(&cpu_sysdev_class,
+                                               &cpufreq_sysdev_driver);
 
                        spin_lock_irqsave(&cpufreq_driver_lock, flags);
                        cpufreq_driver = NULL;
index 5ef5ede..eef0270 100644 (file)
  * latency of the processor. The governor will work on any processor with 
  * transition latency <= 10mS, using appropriate sampling 
  * rate.
- * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL)
- * this governor will not work.
+ * For CPUs with transition latency > 10mS (mostly drivers
+ * with CPUFREQ_ETERNAL), this governor will not work.
  * All times here are in uS.
  */
 static unsigned int                            def_sampling_rate;
 #define MIN_SAMPLING_RATE_RATIO                        (2)
 /* for correct statistics, we need at least 10 ticks between each measure */
-#define MIN_STAT_SAMPLING_RATE                 (MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10))
-#define MIN_SAMPLING_RATE                      (def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
+#define MIN_STAT_SAMPLING_RATE                 \
+                       (MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10))
+#define MIN_SAMPLING_RATE                      \
+                       (def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
 #define MAX_SAMPLING_RATE                      (500 * def_sampling_rate)
 #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER   (1000)
 #define DEF_SAMPLING_DOWN_FACTOR               (1)
@@ -103,11 +105,16 @@ static struct dbs_tuners dbs_tuners_ins = {
 
 static inline unsigned int get_cpu_idle_time(unsigned int cpu)
 {
-       return  kstat_cpu(cpu).cpustat.idle +
+       unsigned int add_nice = 0, ret;
+
+       if (dbs_tuners_ins.ignore_nice)
+               add_nice = kstat_cpu(cpu).cpustat.nice;
+
+       ret =   kstat_cpu(cpu).cpustat.idle +
                kstat_cpu(cpu).cpustat.iowait +
-               ( dbs_tuners_ins.ignore_nice ?
-                 kstat_cpu(cpu).cpustat.nice :
-                 0);
+               add_nice;
+
+       return ret;
 }
 
 /************************** sysfs interface ************************/
@@ -452,6 +459,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
        unsigned int cpu = policy->cpu;
        struct cpu_dbs_info_s *this_dbs_info;
        unsigned int j;
+       int rc;
 
        this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
 
@@ -468,6 +476,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                        break;
                 
                mutex_lock(&dbs_mutex);
+
+               rc = sysfs_create_group(&policy->kobj, &dbs_attr_group);
+               if (rc) {
+                       mutex_unlock(&dbs_mutex);
+                       return rc;
+               }
+
                for_each_cpu_mask(j, policy->cpus) {
                        struct cpu_dbs_info_s *j_dbs_info;
                        j_dbs_info = &per_cpu(cpu_dbs_info, j);
@@ -480,7 +495,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                this_dbs_info->enable = 1;
                this_dbs_info->down_skip = 0;
                this_dbs_info->requested_freq = policy->cur;
-               sysfs_create_group(&policy->kobj, &dbs_attr_group);
+
                dbs_enable++;
                /*
                 * Start the timerschedule work, when this governor
index e1cc511..f697449 100644 (file)
 static unsigned int def_sampling_rate;
 #define MIN_SAMPLING_RATE_RATIO                        (2)
 /* for correct statistics, we need at least 10 ticks between each measure */
-#define MIN_STAT_SAMPLING_RATE                 (MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10))
-#define MIN_SAMPLING_RATE                      (def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
+#define MIN_STAT_SAMPLING_RATE                         \
+                       (MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10))
+#define MIN_SAMPLING_RATE                      \
+                       (def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
 #define MAX_SAMPLING_RATE                      (500 * def_sampling_rate)
 #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER   (1000)
 #define TRANSITION_LATENCY_LIMIT               (10 * 1000)
@@ -206,7 +208,8 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
        ret = sscanf(buf, "%u", &input);
 
        mutex_lock(&dbs_mutex);
-       if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) {
+       if (ret != 1 || input > MAX_SAMPLING_RATE
+                    || input < MIN_SAMPLING_RATE) {
                mutex_unlock(&dbs_mutex);
                return -EINVAL;
        }
@@ -397,8 +400,15 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
         * policy. To be safe, we focus 10 points under the threshold.
         */
        if (load < (dbs_tuners_ins.up_threshold - 10)) {
-               unsigned int freq_next = (policy->cur * load) /
+               unsigned int freq_next, freq_cur;
+
+               freq_cur = cpufreq_driver_getavg(policy);
+               if (!freq_cur)
+                       freq_cur = policy->cur;
+
+               freq_next = (freq_cur * load) /
                        (dbs_tuners_ins.up_threshold - 10);
+
                if (!dbs_tuners_ins.powersave_bias) {
                        __cpufreq_driver_target(policy, freq_next,
                                        CPUFREQ_RELATION_L);
@@ -472,6 +482,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
        unsigned int cpu = policy->cpu;
        struct cpu_dbs_info_s *this_dbs_info;
        unsigned int j;
+       int rc;
 
        this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
 
@@ -494,12 +505,23 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                if (dbs_enable == 1) {
                        kondemand_wq = create_workqueue("kondemand");
                        if (!kondemand_wq) {
-                               printk(KERN_ERR "Creation of kondemand failed\n");
+                               printk(KERN_ERR
+                                        "Creation of kondemand failed\n");
                                dbs_enable--;
                                mutex_unlock(&dbs_mutex);
                                return -ENOSPC;
                        }
                }
+
+               rc = sysfs_create_group(&policy->kobj, &dbs_attr_group);
+               if (rc) {
+                       if (dbs_enable == 1)
+                               destroy_workqueue(kondemand_wq);
+                       dbs_enable--;
+                       mutex_unlock(&dbs_mutex);
+                       return rc;
+               }
+
                for_each_cpu_mask(j, policy->cpus) {
                        struct cpu_dbs_info_s *j_dbs_info;
                        j_dbs_info = &per_cpu(cpu_dbs_info, j);
@@ -509,7 +531,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                        j_dbs_info->prev_cpu_wall = get_jiffies_64();
                }
                this_dbs_info->enable = 1;
-               sysfs_create_group(&policy->kobj, &dbs_attr_group);
                /*
                 * Start the timerschedule work, when this governor
                 * is used for first time
index de91e33..e8e1451 100644 (file)
@@ -15,7 +15,8 @@
 #include <linux/cpufreq.h>
 #include <linux/init.h>
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "performance", msg)
+#define dprintk(msg...) \
+       cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "performance", msg)
 
 
 static int cpufreq_governor_performance(struct cpufreq_policy *policy,
@@ -24,8 +25,10 @@ static int cpufreq_governor_performance(struct cpufreq_policy *policy,
        switch (event) {
        case CPUFREQ_GOV_START:
        case CPUFREQ_GOV_LIMITS:
-               dprintk("setting to %u kHz because of event %u\n", policy->max, event);
-               __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H);
+               dprintk("setting to %u kHz because of event %u\n",
+                                               policy->max, event);
+               __cpufreq_driver_target(policy, policy->max,
+                                               CPUFREQ_RELATION_H);
                break;
        default:
                break;
index 0a25960..13fe06b 100644 (file)
@@ -15,7 +15,8 @@
 #include <linux/cpufreq.h>
 #include <linux/init.h>
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "powersave", msg)
+#define dprintk(msg...) \
+       cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "powersave", msg)
 
 static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
                                        unsigned int event)
@@ -23,8 +24,10 @@ static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
        switch (event) {
        case CPUFREQ_GOV_START:
        case CPUFREQ_GOV_LIMITS:
-               dprintk("setting to %u kHz because of event %u\n", policy->min, event);
-               __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L);
+               dprintk("setting to %u kHz because of event %u\n",
+                                                       policy->min, event);
+               __cpufreq_driver_target(policy, policy->min,
+                                               CPUFREQ_RELATION_L);
                break;
        default:
                break;
index c2ecc59..6742b1a 100644 (file)
@@ -351,8 +351,8 @@ __init cpufreq_stats_init(void)
 
        register_hotcpu_notifier(&cpufreq_stat_cpu_notifier);
        for_each_online_cpu(cpu) {
-               cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_ONLINE,
-                       (void *)(long)cpu);
+               cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier,
+                               CPU_ONLINE, (void *)(long)cpu);
        }
        return 0;
 }
@@ -368,14 +368,15 @@ __exit cpufreq_stats_exit(void)
        unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier);
        lock_cpu_hotplug();
        for_each_online_cpu(cpu) {
-               cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_DEAD,
-                       (void *)(long)cpu);
+               cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier,
+                                               CPU_DEAD, (void *)(long)cpu);
        }
        unlock_cpu_hotplug();
 }
 
 MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>");
-MODULE_DESCRIPTION ("'cpufreq_stats' - A driver to export cpufreq stats through sysfs filesystem");
+MODULE_DESCRIPTION ("'cpufreq_stats' - A driver to export cpufreq stats"
+                               "through sysfs filesystem");
 MODULE_LICENSE ("GPL");
 
 module_init(cpufreq_stats_init);
index a06c204..2a4eb0b 100644 (file)
@@ -131,19 +131,26 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
                                   unsigned int event)
 {
        unsigned int cpu = policy->cpu;
+       int rc = 0;
+
        switch (event) {
        case CPUFREQ_GOV_START:
                if (!cpu_online(cpu))
                        return -EINVAL;
                BUG_ON(!policy->cur);
                mutex_lock(&userspace_mutex);
+               rc = sysfs_create_file (&policy->kobj,
+                                       &freq_attr_scaling_setspeed.attr);
+               if (rc)
+                       goto start_out;
+
                cpu_is_managed[cpu] = 1;
                cpu_min_freq[cpu] = policy->min;
                cpu_max_freq[cpu] = policy->max;
                cpu_cur_freq[cpu] = policy->cur;
                cpu_set_freq[cpu] = policy->cur;
-               sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
                dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]);
+start_out:
                mutex_unlock(&userspace_mutex);
                break;
        case CPUFREQ_GOV_STOP:
@@ -180,7 +187,7 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
                mutex_unlock(&userspace_mutex);
                break;
        }
-       return 0;
+       return rc;
 }
 
 
index 551f4cc..e749092 100644 (file)
@@ -9,7 +9,8 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "freq-table", msg)
+#define dprintk(msg...) \
+       cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "freq-table", msg)
 
 /*********************************************************************
  *                     FREQUENCY TABLE HELPERS                       *
@@ -29,7 +30,8 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
 
                        continue;
                }
-               dprintk("table entry %u: %u kHz, %u index\n", i, freq, table[i].index);
+               dprintk("table entry %u: %u kHz, %u index\n",
+                                       i, freq, table[i].index);
                if (freq < min_freq)
                        min_freq = freq;
                if (freq > max_freq)
@@ -54,13 +56,14 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
        unsigned int i;
        unsigned int count = 0;
 
-       dprintk("request for verification of policy (%u - %u kHz) for cpu %u\n", policy->min, policy->max, policy->cpu);
+       dprintk("request for verification of policy (%u - %u kHz) for cpu %u\n",
+                                       policy->min, policy->max, policy->cpu);
 
        if (!cpu_online(policy->cpu))
                return -EINVAL;
 
-       cpufreq_verify_within_limits(policy,
-                                    policy->cpuinfo.min_freq, policy->cpuinfo.max_freq);
+       cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+                                    policy->cpuinfo.max_freq);
 
        for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
                unsigned int freq = table[i].frequency;
@@ -75,10 +78,11 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
        if (!count)
                policy->max = next_larger;
 
-       cpufreq_verify_within_limits(policy,
-                                    policy->cpuinfo.min_freq, policy->cpuinfo.max_freq);
+       cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+                                    policy->cpuinfo.max_freq);
 
-       dprintk("verification lead to (%u - %u kHz) for cpu %u\n", policy->min, policy->max, policy->cpu);
+       dprintk("verification lead to (%u - %u kHz) for cpu %u\n",
+                               policy->min, policy->max, policy->cpu);
 
        return 0;
 }
@@ -101,7 +105,8 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
        };
        unsigned int i;
 
-       dprintk("request for target %u kHz (relation: %u) for cpu %u\n", target_freq, relation, policy->cpu);
+       dprintk("request for target %u kHz (relation: %u) for cpu %u\n",
+                                       target_freq, relation, policy->cpu);
 
        switch (relation) {
        case CPUFREQ_RELATION_H:
@@ -192,7 +197,10 @@ static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf)
 }
 
 struct freq_attr cpufreq_freq_attr_scaling_available_freqs = {
-       .attr = { .name = "scaling_available_frequencies", .mode = 0444, .owner=THIS_MODULE },
+       .attr = { .name = "scaling_available_frequencies",
+                 .mode = 0444,
+                 .owner=THIS_MODULE
+               },
        .show = show_available_freqs,
 };
 EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs);
index c034820..af02034 100644 (file)
@@ -38,17 +38,6 @@ config I2C_ALGOPCA
          This support is also available as a module.  If so, the module 
          will be called i2c-algo-pca.
 
-config I2C_ALGOITE
-       tristate "ITE I2C Algorithm"
-       depends on MIPS_ITE8172 && I2C
-       help
-         This supports the use of the ITE8172 I2C interface found on some MIPS
-         systems. Say Y if you have one of these. You should also say Y for
-         the ITE I2C peripheral driver support below.
-
-         This support is also available as a module.  If so, the module 
-         will be called i2c-algo-ite.
-
 config I2C_ALGO8XX
        tristate "MPC8xx CPM I2C interface"
        depends on 8xx && I2C
index 208be04..cac1051 100644 (file)
@@ -5,7 +5,6 @@
 obj-$(CONFIG_I2C_ALGOBIT)      += i2c-algo-bit.o
 obj-$(CONFIG_I2C_ALGOPCF)      += i2c-algo-pcf.o
 obj-$(CONFIG_I2C_ALGOPCA)      += i2c-algo-pca.o
-obj-$(CONFIG_I2C_ALGOITE)      += i2c-algo-ite.o
 obj-$(CONFIG_I2C_ALGO_SGI)     += i2c-algo-sgi.o
 
 ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
index 21c36bf..95aa539 100644 (file)
@@ -540,15 +540,7 @@ int i2c_bit_add_bus(struct i2c_adapter *adap)
 
        return i2c_add_adapter(adap);
 }
-
-
-int i2c_bit_del_bus(struct i2c_adapter *adap)
-{
-       return i2c_del_adapter(adap);
-}
-
 EXPORT_SYMBOL(i2c_bit_add_bus);
-EXPORT_SYMBOL(i2c_bit_del_bus);
 
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm");
diff --git a/drivers/i2c/algos/i2c-algo-ite.c b/drivers/i2c/algos/i2c-algo-ite.c
deleted file mode 100644 (file)
index 70d8eef..0000000
+++ /dev/null
@@ -1,806 +0,0 @@
-/*
-   -------------------------------------------------------------------------
-   i2c-algo-ite.c i2c driver algorithms for ITE adapters           
-   
-   Hai-Pao Fan, MontaVista Software, Inc.
-   hpfan@mvista.com or source@mvista.com
-
-   Copyright 2000 MontaVista Software Inc.
-
-   ---------------------------------------------------------------------------
-   This file was highly leveraged from i2c-algo-pcf.c, which was created
-   by Simon G. Vogl and Hans Berglund:
-
-
-     Copyright (C) 1995-1997 Simon G. Vogl
-                   1998-2000 Hans Berglund
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and 
-   Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
-   <mbailey@littlefeet-inc.com> */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-ite.h>
-#include "i2c-algo-ite.h"
-
-#define        PM_DSR          IT8172_PCI_IO_BASE + IT_PM_DSR
-#define        PM_IBSR         IT8172_PCI_IO_BASE + IT_PM_DSR + 0x04 
-#define GPIO_CCR       IT8172_PCI_IO_BASE + IT_GPCCR
-
-#define DEB2(x) if (i2c_debug>=2) x
-#define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/
-#define DEF_TIMEOUT 16
-
-
-/* module parameters:
- */
-static int i2c_debug;
-static int iic_test;   /* see if the line-setting functions work       */
-
-/* --- setting states on the bus with the right timing: ---------------        */
-
-#define get_clock(adap) adap->getclock(adap->data)
-#define iic_outw(adap, reg, val) adap->setiic(adap->data, reg, val)
-#define iic_inw(adap, reg) adap->getiic(adap->data, reg)
-
-
-/* --- other auxiliary functions --------------------------------------        */
-
-static void iic_start(struct i2c_algo_iic_data *adap)
-{
-       iic_outw(adap,ITE_I2CHCR,ITE_CMD);
-}
-
-static void iic_stop(struct i2c_algo_iic_data *adap)
-{
-       iic_outw(adap,ITE_I2CHCR,0);
-       iic_outw(adap,ITE_I2CHSR,ITE_I2CHSR_TDI);
-}
-
-static void iic_reset(struct i2c_algo_iic_data *adap)
-{
-       iic_outw(adap, PM_IBSR, iic_inw(adap, PM_IBSR) | 0x80);
-}
-
-
-static int wait_for_bb(struct i2c_algo_iic_data *adap)
-{
-       int timeout = DEF_TIMEOUT;
-       short status;
-
-       status = iic_inw(adap, ITE_I2CHSR);
-#ifndef STUB_I2C
-       while (timeout-- && (status & ITE_I2CHSR_HB)) {
-               udelay(1000); /* How much is this? */
-               status = iic_inw(adap, ITE_I2CHSR);
-       }
-#endif
-       if (timeout<=0) {
-               printk(KERN_ERR "Timeout, host is busy\n");
-               iic_reset(adap);
-       }
-       return(timeout<=0);
-}
-
-/* After we issue a transaction on the IIC bus, this function
- * is called.  It puts this process to sleep until we get an interrupt from
- * from the controller telling us that the transaction we requested in complete.
- */
-static int wait_for_pin(struct i2c_algo_iic_data *adap, short *status) {
-
-       int timeout = DEF_TIMEOUT;
-       
-       timeout = wait_for_bb(adap);
-       if (timeout) {
-               DEB2(printk("Timeout waiting for host not busy\n");)
-               return -EIO;
-       }                           
-       timeout = DEF_TIMEOUT;
-
-       *status = iic_inw(adap, ITE_I2CHSR);
-#ifndef STUB_I2C
-       while (timeout-- && !(*status & ITE_I2CHSR_TDI)) {
-          adap->waitforpin();
-          *status = iic_inw(adap, ITE_I2CHSR);
-       }
-#endif
-       if (timeout <= 0)
-               return(-1);
-       else
-               return(0);
-}
-
-static int wait_for_fe(struct i2c_algo_iic_data *adap, short *status)
-{
-       int timeout = DEF_TIMEOUT;
-
-       *status = iic_inw(adap, ITE_I2CFSR);
-#ifndef STUB_I2C 
-       while (timeout-- && (*status & ITE_I2CFSR_FE)) {
-               udelay(1000);
-               iic_inw(adap, ITE_I2CFSR);
-       }
-#endif
-       if (timeout <= 0) 
-               return(-1);
-       else
-               return(0);
-}
-
-static int iic_init (struct i2c_algo_iic_data *adap)
-{
-       short i;
-
-       /* Clear bit 7 to set I2C to normal operation mode */
-       i=iic_inw(adap, PM_DSR)& 0xff7f;
-       iic_outw(adap, PM_DSR, i);
-
-       /* set IT_GPCCR port C bit 2&3 as function 2 */
-       i = iic_inw(adap, GPIO_CCR) & 0xfc0f;
-       iic_outw(adap,GPIO_CCR,i);
-
-       /* Clear slave address/sub-address */
-       iic_outw(adap,ITE_I2CSAR, 0);
-       iic_outw(adap,ITE_I2CSSAR, 0);
-
-       /* Set clock counter register */
-       iic_outw(adap,ITE_I2CCKCNT, get_clock(adap));
-
-       /* Set START/reSTART/STOP time registers */
-       iic_outw(adap,ITE_I2CSHDR, 0x0a);
-       iic_outw(adap,ITE_I2CRSUR, 0x0a);
-       iic_outw(adap,ITE_I2CPSUR, 0x0a);
-
-       /* Enable interrupts on completing the current transaction */
-       iic_outw(adap,ITE_I2CHCR, ITE_I2CHCR_IE | ITE_I2CHCR_HCE);
-
-       /* Clear transfer count */
-       iic_outw(adap,ITE_I2CFBCR, 0x0);
-
-       DEB2(printk("iic_init: Initialized IIC on ITE 0x%x\n",
-               iic_inw(adap, ITE_I2CHSR)));
-       return 0;
-}
-
-
-/*
- * Sanity check for the adapter hardware - check the reaction of
- * the bus lines only if it seems to be idle.
- */
-static int test_bus(struct i2c_algo_iic_data *adap, char *name) {
-#if 0
-       int scl,sda;
-       sda=getsda(adap);
-       if (adap->getscl==NULL) {
-               printk("test_bus: Warning: Adapter can't read from clock line - skipping test.\n");
-               return 0;               
-       }
-       scl=getscl(adap);
-       printk("test_bus: Adapter: %s scl: %d  sda: %d -- testing...\n",
-       name,getscl(adap),getsda(adap));
-       if (!scl || !sda ) {
-               printk("test_bus: %s seems to be busy.\n",adap->name);
-               goto bailout;
-       }
-       sdalo(adap);
-       printk("test_bus:1 scl: %d  sda: %d\n", getscl(adap),
-              getsda(adap));
-       if ( 0 != getsda(adap) ) {
-               printk("test_bus: %s SDA stuck high!\n",name);
-               sdahi(adap);
-               goto bailout;
-       }
-       if ( 0 == getscl(adap) ) {
-               printk("test_bus: %s SCL unexpected low while pulling SDA low!\n",
-                       name);
-               goto bailout;
-       }               
-       sdahi(adap);
-       printk("test_bus:2 scl: %d  sda: %d\n", getscl(adap),
-              getsda(adap));
-       if ( 0 == getsda(adap) ) {
-               printk("test_bus: %s SDA stuck low!\n",name);
-               sdahi(adap);
-               goto bailout;
-       }
-       if ( 0 == getscl(adap) ) {
-               printk("test_bus: %s SCL unexpected low while SDA high!\n",
-                      adap->name);
-       goto bailout;
-       }
-       scllo(adap);
-       printk("test_bus:3 scl: %d  sda: %d\n", getscl(adap),
-              getsda(adap));
-       if ( 0 != getscl(adap) ) {
-
-               sclhi(adap);
-               goto bailout;
-       }
-       if ( 0 == getsda(adap) ) {
-               printk("test_bus: %s SDA unexpected low while pulling SCL low!\n",
-                       name);
-               goto bailout;
-       }
-       sclhi(adap);
-       printk("test_bus:4 scl: %d  sda: %d\n", getscl(adap),
-              getsda(adap));
-       if ( 0 == getscl(adap) ) {
-               printk("test_bus: %s SCL stuck low!\n",name);
-               sclhi(adap);
-               goto bailout;
-       }
-       if ( 0 == getsda(adap) ) {
-               printk("test_bus: %s SDA unexpected low while SCL high!\n",
-                       name);
-               goto bailout;
-       }
-       printk("test_bus: %s passed test.\n",name);
-       return 0;
-bailout:
-       sdahi(adap);
-       sclhi(adap);
-       return -ENODEV;
-#endif
-       return (0);
-}
-
-/* ----- Utility functions
- */
-
-
-/* Verify the device we want to talk to on the IIC bus really exists. */
-static inline int try_address(struct i2c_algo_iic_data *adap,
-                      unsigned int addr, int retries)
-{
-       int i, ret = -1;
-       short status;
-
-       for (i=0;i<retries;i++) {
-               iic_outw(adap, ITE_I2CSAR, addr);
-               iic_start(adap);
-               if (wait_for_pin(adap, &status) == 0) {
-                       if ((status & ITE_I2CHSR_DNE) == 0) { 
-                               iic_stop(adap);
-                               iic_outw(adap, ITE_I2CFCR, ITE_I2CFCR_FLUSH);
-                               ret=1;
-                               break;  /* success! */
-                       }
-               }
-               iic_stop(adap);
-               udelay(adap->udelay);
-       }
-       DEB2(if (i) printk("try_address: needed %d retries for 0x%x\n",i,
-                          addr));
-       return ret;
-}
-
-
-static int iic_sendbytes(struct i2c_adapter *i2c_adap,const char *buf,
-                         int count)
-{
-       struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-       int wrcount=0, timeout;
-       short status;
-       int loops, remainder, i, j;
-       union {
-               char byte[2];
-               unsigned short word;
-       } tmp;
-   
-       iic_outw(adap, ITE_I2CSSAR, (unsigned short)buf[wrcount++]);
-       count--;
-       if (count == 0)
-               return -EIO;
-
-       loops =  count / 32;            /* 32-byte FIFO */
-       remainder = count % 32;
-
-       if(loops) {
-               for(i=0; i<loops; i++) {
-
-                       iic_outw(adap, ITE_I2CFBCR, 32);
-                       for(j=0; j<32/2; j++) {
-                               tmp.byte[1] = buf[wrcount++];
-                               tmp.byte[0] = buf[wrcount++];
-                               iic_outw(adap, ITE_I2CFDR, tmp.word); 
-                       }
-
-                       /* status FIFO overrun */
-                       iic_inw(adap, ITE_I2CFSR);
-                       iic_inw(adap, ITE_I2CFBCR);
-
-                       iic_outw(adap, ITE_I2CHCR, ITE_WRITE);  /* Issue WRITE command */
-
-                       /* Wait for transmission to complete */
-                       timeout = wait_for_pin(adap, &status);
-                       if(timeout) {
-                               iic_stop(adap);
-                               printk("iic_sendbytes: %s write timeout.\n", i2c_adap->name);
-                               return -EREMOTEIO; /* got a better one ?? */
-       }
-                       if (status & ITE_I2CHSR_DB) {
-                               iic_stop(adap);
-                               printk("iic_sendbytes: %s write error - no ack.\n", i2c_adap->name);
-                               return -EREMOTEIO; /* got a better one ?? */
-                       }
-               }
-       }
-       if(remainder) {
-               iic_outw(adap, ITE_I2CFBCR, remainder);
-               for(i=0; i<remainder/2; i++) {
-                       tmp.byte[1] = buf[wrcount++];
-                       tmp.byte[0] = buf[wrcount++];
-                       iic_outw(adap, ITE_I2CFDR, tmp.word);
-               }
-
-               /* status FIFO overrun */
-               iic_inw(adap, ITE_I2CFSR);
-               iic_inw(adap, ITE_I2CFBCR);
-
-               iic_outw(adap, ITE_I2CHCR, ITE_WRITE);  /* Issue WRITE command */
-
-               timeout = wait_for_pin(adap, &status);
-               if(timeout) {
-                       iic_stop(adap);
-                       printk("iic_sendbytes: %s write timeout.\n", i2c_adap->name);
-                       return -EREMOTEIO; /* got a better one ?? */
-               }
-#ifndef STUB_I2C
-               if (status & ITE_I2CHSR_DB) { 
-                       iic_stop(adap);
-                       printk("iic_sendbytes: %s write error - no ack.\n", i2c_adap->name);
-                       return -EREMOTEIO; /* got a better one ?? */
-               }
-#endif
-       }
-       iic_stop(adap);
-       return wrcount;
-}
-
-
-static int iic_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count,
-       int sread)
-{
-       int rdcount=0, i, timeout;
-       short status;
-       struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-       int loops, remainder, j;
-       union {
-               char byte[2];
-               unsigned short word;
-       } tmp;
-               
-       loops = count / 32;                             /* 32-byte FIFO */
-       remainder = count % 32;
-
-       if(loops) {
-               for(i=0; i<loops; i++) {
-                       iic_outw(adap, ITE_I2CFBCR, 32);
-                       if (sread)
-                               iic_outw(adap, ITE_I2CHCR, ITE_SREAD);
-                       else
-                               iic_outw(adap, ITE_I2CHCR, ITE_READ);           /* Issue READ command */
-
-                       timeout = wait_for_pin(adap, &status);
-                       if(timeout) {
-                               iic_stop(adap);
-                               printk("iic_readbytes:  %s read timeout.\n", i2c_adap->name);
-                               return (-1);
-                       }
-#ifndef STUB_I2C
-                       if (status & ITE_I2CHSR_DB) {
-                               iic_stop(adap);
-                               printk("iic_readbytes: %s read error - no ack.\n", i2c_adap->name);
-                               return (-1);
-                       }
-#endif
-
-                       timeout = wait_for_fe(adap, &status);
-                       if(timeout) {
-                               iic_stop(adap);
-                               printk("iic_readbytes:  %s FIFO is empty\n", i2c_adap->name);
-                               return (-1); 
-                       }
-
-                       for(j=0; j<32/2; j++) {
-                               tmp.word = iic_inw(adap, ITE_I2CFDR);
-                               buf[rdcount++] = tmp.byte[1];
-                               buf[rdcount++] = tmp.byte[0];
-                       }
-
-                       /* status FIFO underrun */
-                       iic_inw(adap, ITE_I2CFSR);
-
-               }
-       }
-
-
-       if(remainder) {
-               remainder=(remainder+1)/2 * 2;
-               iic_outw(adap, ITE_I2CFBCR, remainder);
-               if (sread)
-                       iic_outw(adap, ITE_I2CHCR, ITE_SREAD);
-               else
-               iic_outw(adap, ITE_I2CHCR, ITE_READ);           /* Issue READ command */
-
-               timeout = wait_for_pin(adap, &status);
-               if(timeout) {
-                       iic_stop(adap);
-                       printk("iic_readbytes:  %s read timeout.\n", i2c_adap->name);
-                       return (-1);
-               }
-#ifndef STUB_I2C
-               if (status & ITE_I2CHSR_DB) {
-                       iic_stop(adap);
-                       printk("iic_readbytes: %s read error - no ack.\n", i2c_adap->name);
-                       return (-1);
-               }
-#endif
-               timeout = wait_for_fe(adap, &status);
-               if(timeout) {
-                       iic_stop(adap);
-                       printk("iic_readbytes:  %s FIFO is empty\n", i2c_adap->name);
-                       return (-1);
-               }         
-
-               for(i=0; i<(remainder+1)/2; i++) {
-                       tmp.word = iic_inw(adap, ITE_I2CFDR);
-                       buf[rdcount++] = tmp.byte[1];
-                       buf[rdcount++] = tmp.byte[0];
-               }
-
-               /* status FIFO underrun */
-               iic_inw(adap, ITE_I2CFSR);
-
-       }
-
-       iic_stop(adap);
-       return rdcount;
-}
-
-
-/* This function implements combined transactions.  Combined
- * transactions consist of combinations of reading and writing blocks of data.
- * Each transfer (i.e. a read or a write) is separated by a repeated start
- * condition.
- */
-#if 0
-static int iic_combined_transaction(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) 
-{
-   int i;
-   struct i2c_msg *pmsg;
-   int ret;
-
-   DEB2(printk("Beginning combined transaction\n"));
-
-   for(i=0; i<(num-1); i++) {
-      pmsg = &msgs[i];
-      if(pmsg->flags & I2C_M_RD) {
-         DEB2(printk("  This one is a read\n"));
-         ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_COMBINED_XFER);
-      }
-      else if(!(pmsg->flags & I2C_M_RD)) {
-         DEB2(printk("This one is a write\n"));
-         ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_COMBINED_XFER);
-      }
-   }
-   /* Last read or write segment needs to be terminated with a stop */
-   pmsg = &msgs[i];
-
-   if(pmsg->flags & I2C_M_RD) {
-      DEB2(printk("Doing the last read\n"));
-      ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_SINGLE_XFER);
-   }
-   else if(!(pmsg->flags & I2C_M_RD)) {
-      DEB2(printk("Doing the last write\n"));
-      ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_SINGLE_XFER);
-   }
-
-   return ret;
-}
-#endif
-
-
-/* Whenever we initiate a transaction, the first byte clocked
- * onto the bus after the start condition is the address (7 bit) of the
- * device we want to talk to.  This function manipulates the address specified
- * so that it makes sense to the hardware when written to the IIC peripheral.
- *
- * Note: 10 bit addresses are not supported in this driver, although they are
- * supported by the hardware.  This functionality needs to be implemented.
- */
-static inline int iic_doAddress(struct i2c_algo_iic_data *adap,
-                                struct i2c_msg *msg, int retries) 
-{
-       unsigned short flags = msg->flags;
-       unsigned int addr;
-       int ret;
-
-/* Ten bit addresses not supported right now */
-       if ( (flags & I2C_M_TEN)  ) { 
-#if 0
-               addr = 0xf0 | (( msg->addr >> 7) & 0x03);
-               DEB2(printk("addr0: %d\n",addr));
-               ret = try_address(adap, addr, retries);
-               if (ret!=1) {
-                       printk("iic_doAddress: died at extended address code.\n");
-                       return -EREMOTEIO;
-               }
-               iic_outw(adap,msg->addr & 0x7f);
-               if (ret != 1) {
-                       printk("iic_doAddress: died at 2nd address code.\n");
-                       return -EREMOTEIO;
-               }
-               if ( flags & I2C_M_RD ) {
-                       i2c_repstart(adap);
-                       addr |= 0x01;
-                       ret = try_address(adap, addr, retries);
-                       if (ret!=1) {
-                               printk("iic_doAddress: died at extended address code.\n");
-                               return -EREMOTEIO;
-                       }
-               }
-#endif
-       } else {
-
-               addr = ( msg->addr << 1 );
-
-#if 0
-               if (flags & I2C_M_RD )
-                       addr |= 1;
-               if (flags & I2C_M_REV_DIR_ADDR )
-                       addr ^= 1;
-#endif
-
-               if (iic_inw(adap, ITE_I2CSAR) != addr) {
-                       iic_outw(adap, ITE_I2CSAR, addr);
-                       ret = try_address(adap, addr, retries);
-                       if (ret!=1) {
-                               printk("iic_doAddress: died at address code.\n");
-                               return -EREMOTEIO;
-                       }
-               }
-
-  }
-
-       return 0;
-}
-
-
-/* Description: Prepares the controller for a transaction (clearing status
- * registers, data buffers, etc), and then calls either iic_readbytes or
- * iic_sendbytes to do the actual transaction.
- *
- * still to be done: Before we issue a transaction, we should
- * verify that the bus is not busy or in some unknown state.
- */
-static int iic_xfer(struct i2c_adapter *i2c_adap,
-                   struct i2c_msg *msgs, 
-                   int num)
-{
-       struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-       struct i2c_msg *pmsg;
-       int i = 0;
-       int ret, timeout;
-    
-       pmsg = &msgs[i];
-
-       if(!pmsg->len) {
-               DEB2(printk("iic_xfer: read/write length is 0\n");)
-               return -EIO;
-       }
-       if(!(pmsg->flags & I2C_M_RD) && (!(pmsg->len)%2) ) {
-               DEB2(printk("iic_xfer: write buffer length is not odd\n");)
-               return -EIO; 
-       }
-
-       /* Wait for any pending transfers to complete */
-       timeout = wait_for_bb(adap);
-       if (timeout) {
-               DEB2(printk("iic_xfer: Timeout waiting for host not busy\n");)
-               return -EIO;
-       }
-
-       /* Flush FIFO */
-       iic_outw(adap, ITE_I2CFCR, ITE_I2CFCR_FLUSH);
-
-       /* Load address */
-       ret = iic_doAddress(adap, pmsg, i2c_adap->retries);
-       if (ret)
-               return -EIO;
-
-#if 0
-       /* Combined transaction (read and write) */
-       if(num > 1) {
-           DEB2(printk("iic_xfer: Call combined transaction\n"));
-           ret = iic_combined_transaction(i2c_adap, msgs, num);
-  }
-#endif
-
-       DEB3(printk("iic_xfer: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
-               i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
-
-       if(pmsg->flags & I2C_M_RD)              /* Read */
-               ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, 0);
-       else {                                                                                                  /* Write */ 
-               udelay(1000);
-               ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len);
-       }
-
-       if (ret != pmsg->len)
-               DEB3(printk("iic_xfer: error or fail on read/write %d bytes.\n",ret)); 
-       else
-               DEB3(printk("iic_xfer: read/write %d bytes.\n",ret));
-
-       return ret;
-}
-
-
-/* Implements device specific ioctls.  Higher level ioctls can
- * be found in i2c-core.c and are typical of any i2c controller (specifying
- * slave address, timeouts, etc).  These ioctls take advantage of any hardware
- * features built into the controller for which this algorithm-adapter set
- * was written.  These ioctls allow you to take control of the data and clock
- * lines and set the either high or low,
- * similar to a GPIO pin.
- */
-static int algo_control(struct i2c_adapter *adapter, 
-       unsigned int cmd, unsigned long arg)
-{
-
-  struct i2c_algo_iic_data *adap = adapter->algo_data;
-  struct i2c_iic_msg s_msg;
-  char *buf;
-       int ret;
-
-  if (cmd == I2C_SREAD) {
-               if(copy_from_user(&s_msg, (struct i2c_iic_msg *)arg, 
-                               sizeof(struct i2c_iic_msg))) 
-                       return -EFAULT;
-               buf = kmalloc(s_msg.len, GFP_KERNEL);
-               if (buf== NULL)
-                       return -ENOMEM;
-
-               /* Flush FIFO */
-               iic_outw(adap, ITE_I2CFCR, ITE_I2CFCR_FLUSH);
-
-               /* Load address */
-               iic_outw(adap, ITE_I2CSAR,s_msg.addr<<1);
-               iic_outw(adap, ITE_I2CSSAR,s_msg.waddr & 0xff);
-
-               ret = iic_readbytes(adapter, buf, s_msg.len, 1);
-               if (ret>=0) {
-                       if(copy_to_user( s_msg.buf, buf, s_msg.len) ) 
-                               ret = -EFAULT;
-               }
-               kfree(buf);
-       }
-       return 0;
-}
-
-
-static u32 iic_func(struct i2c_adapter *adap)
-{
-       return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | 
-              I2C_FUNC_PROTOCOL_MANGLING; 
-}
-
-/* -----exported algorithm data: ------------------------------------- */
-
-static struct i2c_algorithm iic_algo = {
-       .master_xfer    = iic_xfer,
-       .algo_control   = algo_control, /* ioctl */
-       .functionality  = iic_func,
-};
-
-
-/* 
- * registering functions to load algorithms at runtime 
- */
-int i2c_iic_add_bus(struct i2c_adapter *adap)
-{
-       struct i2c_algo_iic_data *iic_adap = adap->algo_data;
-
-       if (iic_test) {
-               int ret = test_bus(iic_adap, adap->name);
-               if (ret<0)
-                       return -ENODEV;
-       }
-
-       DEB2(printk("i2c-algo-ite: hw routines for %s registered.\n",
-                   adap->name));
-
-       /* register new adapter to i2c module... */
-       adap->algo = &iic_algo;
-
-       adap->timeout = 100;    /* default values, should       */
-       adap->retries = 3;              /* be replaced by defines       */
-       adap->flags = 0;
-
-       iic_init(iic_adap);
-       return i2c_add_adapter(adap);
-}
-
-
-int i2c_iic_del_bus(struct i2c_adapter *adap)
-{
-       int res;
-       if ((res = i2c_del_adapter(adap)) < 0)
-               return res;
-       DEB2(printk("i2c-algo-ite: adapter unregistered: %s\n",adap->name));
-
-       return 0;
-}
-
-
-int __init i2c_algo_iic_init (void)
-{
-       printk(KERN_INFO "ITE iic (i2c) algorithm module\n");
-       return 0;
-}
-
-
-void i2c_algo_iic_exit(void)
-{
-       return;
-}
-
-
-EXPORT_SYMBOL(i2c_iic_add_bus);
-EXPORT_SYMBOL(i2c_iic_del_bus);
-
-/* The MODULE_* macros resolve to nothing if MODULES is not defined
- * when this file is compiled.
- */
-MODULE_AUTHOR("MontaVista Software <www.mvista.com>");
-MODULE_DESCRIPTION("ITE iic algorithm");
-MODULE_LICENSE("GPL");
-
-module_param(iic_test, bool, 0);
-module_param(i2c_debug, int, S_IRUGO | S_IWUSR);
-
-MODULE_PARM_DESC(iic_test, "Test if the I2C bus is available");
-MODULE_PARM_DESC(i2c_debug,
-        "debug level - 0 off; 1 normal; 2,3 more verbose; 9 iic-protocol");
-
-
-/* This function resolves to init_module (the function invoked when a module
- * is loaded via insmod) when this file is compiled with MODULES defined.
- * Otherwise (i.e. if you want this driver statically linked to the kernel),
- * a pointer to this function is stored in a table and called
- * during the initialization of the kernel (in do_basic_setup in /init/main.c) 
- *
- * All this functionality is complements of the macros defined in linux/init.h
- */
-module_init(i2c_algo_iic_init);
-
-
-/* If MODULES is defined when this file is compiled, then this function will
- * resolved to cleanup_module.
- */
-module_exit(i2c_algo_iic_exit);
diff --git a/drivers/i2c/algos/i2c-algo-ite.h b/drivers/i2c/algos/i2c-algo-ite.h
deleted file mode 100644 (file)
index a8ca3c9..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
-   --------------------------------------------------------------------
-   i2c-ite.h: Global defines for the I2C controller on board the    
-                 ITE MIPS processor.                                
-   --------------------------------------------------------------------
-   Hai-Pao Fan, MontaVista Software, Inc.
-   hpfan@mvista.com or source@mvista.com
-
-   Copyright 2001 MontaVista Software Inc.
-
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
-
- */
-
-#ifndef I2C_ITE_H
-#define I2C_ITE_H 1
-
-#include <asm/it8172/it8172.h>
-
-/* I2C Registers */
-#define ITE_I2CHCR     IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x30
-#define ITE_I2CHSR     IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x34
-#define ITE_I2CSAR     IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x38
-#define ITE_I2CSSAR    IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x3c
-#define ITE_I2CCKCNT   IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x48
-#define ITE_I2CSHDR    IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x4c
-#define ITE_I2CRSUR    IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x50
-#define ITE_I2CPSUR    IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x54
-
-#define ITE_I2CFDR     IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x70
-#define ITE_I2CFBCR    IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x74
-#define ITE_I2CFCR     IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x78
-#define ITE_I2CFSR     IT8172_PCI_IO_BASE + IT_I2C_BASE + 0x7c
-
-
-/* Host Control Register ITE_I2CHCR */
-#define        ITE_I2CHCR_HCE  0x01    /* Enable I2C Host Controller */
-#define        ITE_I2CHCR_IE   0x02    /* Enable the interrupt after completing
-                                  the current transaction */
-#define ITE_I2CHCR_CP_W        0x00    /* bit2-4 000 - Write */
-#define        ITE_I2CHCR_CP_R 0x08    /*        010 - Current address read */
-#define        ITE_I2CHCR_CP_S 0x10    /*        100 - Sequential read */
-#define ITE_I2CHCR_ST  0x20    /* Initiates the I2C host controller to execute
-                                  the command and send the data programmed in
-                                  all required registers to I2C bus */
-#define ITE_CMD                ITE_I2CHCR_HCE | ITE_I2CHCR_IE | ITE_I2CHCR_ST
-#define ITE_WRITE      ITE_CMD | ITE_I2CHCR_CP_W
-#define ITE_READ       ITE_CMD | ITE_I2CHCR_CP_R
-#define ITE_SREAD      ITE_CMD | ITE_I2CHCR_CP_S
-
-/* Host Status Register ITE_I2CHSR */
-#define        ITE_I2CHSR_DB   0x01    /* Device is busy, receives NACK response except
-                                  in the first and last bytes */
-#define        ITE_I2CHSR_DNE  0x02    /* Target address on I2C bus does not exist */
-#define        ITE_I2CHSR_TDI  0x04    /* R/W Transaction on I2C bus was completed */
-#define        ITE_I2CHSR_HB   0x08    /* Host controller is processing transactions */
-#define        ITE_I2CHSR_FER  0x10    /* Error occurs in the FIFO */
-
-/* Slave Address Register ITE_I2CSAR */
-#define        ITE_I2CSAR_SA_MASK      0xfe    /* Target I2C device address */
-#define        ITE_I2CSAR_ASO          0x0100  /* Output 1/0 to I2CAS port when the
-                                          next slave address is addressed */
-
-/* Slave Sub-address Register ITE_I2CSSAR */
-#define        ITE_I2CSSAR_SUBA_MASK   0xff    /* Target I2C device sub-address */
-
-/* Clock Counter Register ITE_I2CCKCNT */
-#define        ITE_I2CCKCNT_STOP       0x00    /* stop I2C clock */
-#define        ITE_I2CCKCNT_HPCC_MASK  0x7f    /* SCL high period counter */
-#define        ITE_I2CCKCNT_LPCC_MASK  0x7f00  /* SCL low period counter */
-
-/* START Hold Time Register ITE_I2CSHDR */
-/* value is counted based on 16 MHz internal clock */
-#define ITE_I2CSHDR_FM 0x0a    /* START condition at fast mode */
-#define        ITE_I2CSHDR_SM  0x47    /* START contition at standard mode */
-
-/* (Repeated) START Setup Time Register ITE_I2CRSUR */
-/* value is counted based on 16 MHz internal clock */
-#define        ITE_I2CRSUR_FM  0x0a    /* repeated START condition at fast mode */
-#define        ITE_I2CRSUR_SM  0x50    /* repeated START condition at standard mode */
-
-/* STOP setup Time Register ITE_I2CPSUR */
-
-/* FIFO Data Register ITE_I2CFDR */
-#define        ITE_I2CFDR_MASK         0xff
-
-/* FIFO Byte Count Register ITE_I2CFBCR */
-#define ITE_I2CFBCR_MASK       0x3f
-
-/* FIFO Control Register ITE_I2CFCR */
-#define        ITE_I2CFCR_FLUSH        0x01    /* Flush FIFO and reset the FIFO point
-                                          and I2CFSR */
-/* FIFO Status Register ITE_I2CFSR */
-#define        ITE_I2CFSR_FO   0x01    /* FIFO is overrun when write */
-#define        ITE_I2CFSR_FU   0x02    /* FIFO is underrun when read */
-#define        ITE_I2CFSR_FF   0x04    /* FIFO is full when write */
-#define        ITE_I2CFSR_FE   0x08    /* FIFO is empty when read */
-
-#endif  /* I2C_ITE_H */
index 9081c9f..36fdf97 100644 (file)
@@ -381,14 +381,7 @@ int i2c_pca_add_bus(struct i2c_adapter *adap)
 
        return rval;
 }
-
-int i2c_pca_del_bus(struct i2c_adapter *adap)
-{
-       return i2c_del_adapter(adap);
-}
-
 EXPORT_SYMBOL(i2c_pca_add_bus);
-EXPORT_SYMBOL(i2c_pca_del_bus);
 
 MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>");
 MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm");
index 3b20033..ecb2c2d 100644 (file)
@@ -486,15 +486,7 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap)
 
        return rval;
 }
-
-
-int i2c_pcf_del_bus(struct i2c_adapter *adap)
-{
-       return i2c_del_adapter(adap);
-}
-
 EXPORT_SYMBOL(i2c_pcf_add_bus);
-EXPORT_SYMBOL(i2c_pcf_del_bus);
 
 MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
 MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");
index 490d999..ac2d505 100644 (file)
@@ -171,15 +171,7 @@ int i2c_sgi_add_bus(struct i2c_adapter *adap)
 
        return i2c_add_adapter(adap);
 }
-
-
-int i2c_sgi_del_bus(struct i2c_adapter *adap)
-{
-       return i2c_del_adapter(adap);
-}
-
 EXPORT_SYMBOL(i2c_sgi_add_bus);
-EXPORT_SYMBOL(i2c_sgi_del_bus);
 
 MODULE_AUTHOR("Ladislav Michl <ladis@linux-mips.org>");
 MODULE_DESCRIPTION("I2C-Bus SGI algorithm");
index 90f91d0..e1989f3 100644 (file)
@@ -74,6 +74,13 @@ config I2C_AMD8111
          This driver can also be built as a module.  If so, the module
          will be called i2c-amd8111.
 
+config I2C_AT91
+       tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
+       depends on I2C && ARCH_AT91 && EXPERIMENTAL
+       help
+         This supports the use of the I2C interface on Atmel AT91
+         processors.
+
 config I2C_AU1550
        tristate "Au1550/Au1200 SMBus interface"
        depends on I2C && (SOC_AU1550 || SOC_AU1200)
@@ -209,18 +216,6 @@ config I2C_ISA
        tristate
        depends on I2C
 
-config I2C_ITE
-       tristate "ITE I2C Adapter"
-       depends on I2C && MIPS_ITE8172
-       select I2C_ALGOITE
-       help
-         This supports the ITE8172 I2C peripheral found on some MIPS
-         systems. Say Y if you have one of these. You should also say Y for
-         the ITE I2C driver algorithm support above.
-
-         This support is also available as a module.  If so, the module 
-         will be called i2c-ite.
-
 config I2C_IXP4XX
        tristate "IXP4xx GPIO-Based I2C Interface"
        depends on I2C && ARCH_IXP4XX
@@ -481,6 +476,17 @@ config I2C_STUB
 
          If you don't know what to do here, definitely say N.
 
+config I2C_VERSATILE
+       tristate "ARM Versatile/Realview I2C bus support"
+       depends on I2C && (ARCH_VERSATILE || ARCH_REALVIEW)
+       select I2C_ALGOBIT
+       help
+         Say yes if you want to support the I2C serial bus on ARMs Versatile
+         range of platforms.
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-versatile.
+
 config I2C_VIA
        tristate "VIA 82C586B"
        depends on I2C && PCI && EXPERIMENTAL
@@ -548,4 +554,23 @@ config I2C_MV64XXX
          This driver can also be built as a module.  If so, the module
          will be called i2c-mv64xxx.
 
+config I2C_PNX
+       tristate "I2C bus support for Philips PNX targets"
+       depends on ARCH_PNX4008 && I2C
+       help
+         This driver supports the Philips IP3204 I2C IP block master and/or
+         slave controller
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-pnx.
+
+config I2C_PNX_EARLY
+       bool "Early initialization for I2C on PNXxxxx"
+       depends on I2C_PNX=y
+       help
+         Under certain circumstances one may need to make sure I2C on PNXxxxx
+         is initialized earlier than some other driver that depends on it
+         (for instance, that might be USB in case of PNX4008). With this
+         option turned on you can guarantee that.
+
 endmenu
index 493c872..37196c1 100644 (file)
@@ -8,6 +8,7 @@ obj-$(CONFIG_I2C_ALI15X3)       += i2c-ali15x3.o
 obj-$(CONFIG_I2C_AMD756)       += i2c-amd756.o
 obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o
 obj-$(CONFIG_I2C_AMD8111)      += i2c-amd8111.o
+obj-$(CONFIG_I2C_AT91)         += i2c-at91.o
 obj-$(CONFIG_I2C_AU1550)       += i2c-au1550.o
 obj-$(CONFIG_I2C_ELEKTOR)      += i2c-elektor.o
 obj-$(CONFIG_I2C_HYDRA)                += i2c-hydra.o
@@ -16,7 +17,6 @@ obj-$(CONFIG_I2C_I810)                += i2c-i810.o
 obj-$(CONFIG_I2C_IBM_IIC)      += i2c-ibm_iic.o
 obj-$(CONFIG_I2C_IOP3XX)       += i2c-iop3xx.o
 obj-$(CONFIG_I2C_ISA)          += i2c-isa.o
-obj-$(CONFIG_I2C_ITE)          += i2c-ite.o
 obj-$(CONFIG_I2C_IXP2000)      += i2c-ixp2000.o
 obj-$(CONFIG_I2C_IXP4XX)       += i2c-ixp4xx.o
 obj-$(CONFIG_I2C_POWERMAC)     += i2c-powermac.o
@@ -29,6 +29,7 @@ obj-$(CONFIG_I2C_PARPORT)     += i2c-parport.o
 obj-$(CONFIG_I2C_PARPORT_LIGHT)        += i2c-parport-light.o
 obj-$(CONFIG_I2C_PCA_ISA)      += i2c-pca-isa.o
 obj-$(CONFIG_I2C_PIIX4)                += i2c-piix4.o
+obj-$(CONFIG_I2C_PNX)          += i2c-pnx.o
 obj-$(CONFIG_I2C_PROSAVAGE)    += i2c-prosavage.o
 obj-$(CONFIG_I2C_PXA)          += i2c-pxa.o
 obj-$(CONFIG_I2C_RPXLITE)      += i2c-rpx.o
@@ -39,6 +40,7 @@ obj-$(CONFIG_I2C_SIS5595)     += i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)       += i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)       += i2c-sis96x.o
 obj-$(CONFIG_I2C_STUB)         += i2c-stub.o
+obj-$(CONFIG_I2C_VERSATILE)    += i2c-versatile.o
 obj-$(CONFIG_I2C_VIA)          += i2c-via.o
 obj-$(CONFIG_I2C_VIAPRO)       += i2c-viapro.o
 obj-$(CONFIG_I2C_VOODOO3)      += i2c-voodoo3.o
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
new file mode 100644 (file)
index 0000000..67f91bd
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+    i2c Support for Atmel's AT91 Two-Wire Interface (TWI)
+
+    Copyright (C) 2004 Rick Bronson
+    Converted to 2.6 by Andrew Victor <andrew@sanpeople.com>
+
+    Borrowed heavily from original work by:
+    Copyright (C) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+*/
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+
+#include <asm/arch/at91_twi.h>
+#include <asm/arch/board.h>
+#include <asm/arch/cpu.h>
+
+#define TWI_CLOCK              100000          /* Hz. max 400 Kbits/sec */
+
+
+static struct clk *twi_clk;
+static void __iomem *twi_base;
+
+#define at91_twi_read(reg)             __raw_readl(twi_base + (reg))
+#define at91_twi_write(reg, val)       __raw_writel((val), twi_base + (reg))
+
+
+/*
+ * Initialize the TWI hardware registers.
+ */
+static void __devinit at91_twi_hwinit(void)
+{
+       unsigned long cdiv, ckdiv;
+
+       at91_twi_write(AT91_TWI_IDR, 0xffffffff);       /* Disable all interrupts */
+       at91_twi_write(AT91_TWI_CR, AT91_TWI_SWRST);    /* Reset peripheral */
+       at91_twi_write(AT91_TWI_CR, AT91_TWI_MSEN);     /* Set Master mode */
+
+       /* Calcuate clock dividers */
+       cdiv = (clk_get_rate(twi_clk) / (2 * TWI_CLOCK)) - 3;
+       cdiv = cdiv + 1;        /* round up */
+       ckdiv = 0;
+       while (cdiv > 255) {
+               ckdiv++;
+               cdiv = cdiv >> 1;
+       }
+
+       if (cpu_is_at91rm9200()) {                      /* AT91RM9200 Errata #22 */
+               if (ckdiv > 5) {
+                       printk(KERN_ERR "AT91 I2C: Invalid TWI_CLOCK value!\n");
+                       ckdiv = 5;
+               }
+       }
+
+       at91_twi_write(AT91_TWI_CWGR, (ckdiv << 16) | (cdiv << 8) | cdiv);
+}
+
+/*
+ * Poll the i2c status register until the specified bit is set.
+ * Returns 0 if timed out (100 msec).
+ */
+static short at91_poll_status(unsigned long bit)
+{
+       int loop_cntr = 10000;
+
+       do {
+               udelay(10);
+       } while (!(at91_twi_read(AT91_TWI_SR) & bit) && (--loop_cntr > 0));
+
+       return (loop_cntr > 0);
+}
+
+static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length)
+{
+       /* Send Start */
+       at91_twi_write(AT91_TWI_CR, AT91_TWI_START);
+
+       /* Read data */
+       while (length--) {
+               if (!length)    /* need to send Stop before reading last byte */
+                       at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP);
+               if (!at91_poll_status(AT91_TWI_RXRDY)) {
+                       dev_dbg(&adap->dev, "RXRDY timeout\n");
+                       return -ETIMEDOUT;
+               }
+               *buf++ = (at91_twi_read(AT91_TWI_RHR) & 0xff);
+       }
+
+       return 0;
+}
+
+static int xfer_write(struct i2c_adapter *adap, unsigned char *buf, int length)
+{
+       /* Load first byte into transmitter */
+       at91_twi_write(AT91_TWI_THR, *buf++);
+
+       /* Send Start */
+       at91_twi_write(AT91_TWI_CR, AT91_TWI_START);
+
+       do {
+               if (!at91_poll_status(AT91_TWI_TXRDY)) {
+                       dev_dbg(&adap->dev, "TXRDY timeout\n");
+                       return -ETIMEDOUT;
+               }
+
+               length--;       /* byte was transmitted */
+
+               if (length > 0)         /* more data to send? */
+                       at91_twi_write(AT91_TWI_THR, *buf++);
+       } while (length);
+
+       /* Send Stop */
+       at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP);
+
+       return 0;
+}
+
+/*
+ * Generic i2c master transfer entrypoint.
+ *
+ * Note: We do not use Atmel's feature of storing the "internal device address".
+ * Instead the "internal device address" has to be written using a seperate
+ * i2c message.
+ * http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html
+ */
+static int at91_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg, int num)
+{
+       int i, ret;
+
+       dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num);
+
+       for (i = 0; i < num; i++) {
+               dev_dbg(&adap->dev, " #%d: %sing %d byte%s %s 0x%02x\n", i,
+                       pmsg->flags & I2C_M_RD ? "read" : "writ",
+                       pmsg->len, pmsg->len > 1 ? "s" : "",
+                       pmsg->flags & I2C_M_RD ? "from" : "to", pmsg->addr);
+
+               at91_twi_write(AT91_TWI_MMR, (pmsg->addr << 16)
+                       | ((pmsg->flags & I2C_M_RD) ? AT91_TWI_MREAD : 0));
+
+               if (pmsg->len && pmsg->buf) {   /* sanity check */
+                       if (pmsg->flags & I2C_M_RD)
+                               ret = xfer_read(adap, pmsg->buf, pmsg->len);
+                       else
+                               ret = xfer_write(adap, pmsg->buf, pmsg->len);
+
+                       if (ret)
+                               return ret;
+
+                       /* Wait until transfer is finished */
+                       if (!at91_poll_status(AT91_TWI_TXCOMP)) {
+                               dev_dbg(&adap->dev, "TXCOMP timeout\n");
+                               return -ETIMEDOUT;
+                       }
+               }
+               dev_dbg(&adap->dev, "transfer complete\n");
+               pmsg++;         /* next message */
+       }
+       return i;
+}
+
+/*
+ * Return list of supported functionality.
+ */
+static u32 at91_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm at91_algorithm = {
+       .master_xfer    = at91_xfer,
+       .functionality  = at91_func,
+};
+
+/*
+ * Main initialization routine.
+ */
+static int __devinit at91_i2c_probe(struct platform_device *pdev)
+{
+       struct i2c_adapter *adapter;
+       struct resource *res;
+       int rc;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENXIO;
+
+       if (!request_mem_region(res->start, res->end - res->start + 1, "at91_i2c"))
+               return -EBUSY;
+
+       twi_base = ioremap(res->start, res->end - res->start + 1);
+       if (!twi_base) {
+               rc = -ENOMEM;
+               goto fail0;
+       }
+
+       twi_clk = clk_get(NULL, "twi_clk");
+       if (IS_ERR(twi_clk)) {
+               dev_err(&pdev->dev, "no clock defined\n");
+               rc = -ENODEV;
+               goto fail1;
+       }
+
+       adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
+       if (adapter == NULL) {
+               dev_err(&pdev->dev, "can't allocate inteface!\n");
+               rc = -ENOMEM;
+               goto fail2;
+       }
+       sprintf(adapter->name, "AT91");
+       adapter->algo = &at91_algorithm;
+       adapter->class = I2C_CLASS_HWMON;
+       adapter->dev.parent = &pdev->dev;
+
+       platform_set_drvdata(pdev, adapter);
+
+       clk_enable(twi_clk);            /* enable peripheral clock */
+       at91_twi_hwinit();              /* initialize TWI controller */
+
+       rc = i2c_add_adapter(adapter);
+       if (rc) {
+               dev_err(&pdev->dev, "Adapter %s registration failed\n",
+                               adapter->name);
+               goto fail3;
+       }
+
+       dev_info(&pdev->dev, "AT91 i2c bus driver.\n");
+       return 0;
+
+fail3:
+       platform_set_drvdata(pdev, NULL);
+       kfree(adapter);
+       clk_disable(twi_clk);
+fail2:
+       clk_put(twi_clk);
+fail1:
+       iounmap(twi_base);
+fail0:
+       release_mem_region(res->start, res->end - res->start + 1);
+
+       return rc;
+}
+
+static int __devexit at91_i2c_remove(struct platform_device *pdev)
+{
+       struct i2c_adapter *adapter = platform_get_drvdata(pdev);
+       struct resource *res;
+       int rc;
+
+       rc = i2c_del_adapter(adapter);
+       platform_set_drvdata(pdev, NULL);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       iounmap(twi_base);
+       release_mem_region(res->start, res->end - res->start + 1);
+
+       clk_disable(twi_clk);           /* disable peripheral clock */
+       clk_put(twi_clk);
+
+       return rc;
+}
+
+#ifdef CONFIG_PM
+
+/* NOTE: could save a few mA by keeping clock off outside of at91_xfer... */
+
+static int at91_i2c_suspend(struct platform_device *pdev, pm_message_t mesg)
+{
+       clk_disable(twi_clk);
+       return 0;
+}
+
+static int at91_i2c_resume(struct platform_device *pdev)
+{
+       return clk_enable(twi_clk);
+}
+
+#else
+#define at91_i2c_suspend       NULL
+#define at91_i2c_resume                NULL
+#endif
+
+static struct platform_driver at91_i2c_driver = {
+       .probe          = at91_i2c_probe,
+       .remove         = __devexit_p(at91_i2c_remove),
+       .suspend        = at91_i2c_suspend,
+       .resume         = at91_i2c_resume,
+       .driver         = {
+               .name   = "at91_i2c",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init at91_i2c_init(void)
+{
+       return platform_driver_register(&at91_i2c_driver);
+}
+
+static void __exit at91_i2c_exit(void)
+{
+       platform_driver_unregister(&at91_i2c_driver);
+}
+
+module_init(at91_i2c_init);
+module_exit(at91_i2c_exit);
+
+MODULE_AUTHOR("Rick Bronson");
+MODULE_DESCRIPTION("I2C (TWI) driver for Atmel AT91");
+MODULE_LICENSE("GPL");
index a591fe6..8349674 100644 (file)
@@ -293,7 +293,7 @@ static int __init i2c_pcfisa_init(void)
 
 static void i2c_pcfisa_exit(void)
 {
-       i2c_pcf_del_bus(&pcf_isa_ops);
+       i2c_del_adapter(&pcf_isa_ops);
 
        if (irq > 0) {
                disable_irq(irq);
index 457d48a..9832f77 100644 (file)
@@ -146,7 +146,7 @@ static int __devinit hydra_probe(struct pci_dev *dev,
 static void __devexit hydra_remove(struct pci_dev *dev)
 {
        pdregw(hydra_bit_data.data, 0);         /* clear SCLK_OE and SDAT_OE */
-       i2c_bit_del_bus(&hydra_adap);
+       i2c_del_adapter(&hydra_adap);
        iounmap(hydra_bit_data.data);
        release_mem_region(pci_resource_start(dev, 0)+
                           offsetof(struct Hydra, CachePD), 4);
index c7be2fd..ae625b8 100644 (file)
@@ -470,12 +470,20 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
        int err;
 
        I801_dev = dev;
-       if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
-           (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) ||
-           (dev->device == PCI_DEVICE_ID_INTEL_ESB_4))
+       switch (dev->device) {
+       case PCI_DEVICE_ID_INTEL_82801DB_3:
+       case PCI_DEVICE_ID_INTEL_82801EB_3:
+       case PCI_DEVICE_ID_INTEL_ESB_4:
+       case PCI_DEVICE_ID_INTEL_ICH6_16:
+       case PCI_DEVICE_ID_INTEL_ICH7_17:
+       case PCI_DEVICE_ID_INTEL_ESB2_17:
+       case PCI_DEVICE_ID_INTEL_ICH8_5:
+       case PCI_DEVICE_ID_INTEL_ICH9_6:
                isich4 = 1;
-       else
+               break;
+       default:
                isich4 = 0;
+       }
 
        err = pci_enable_device(dev);
        if (err) {
index b66fb6b..10c98bc 100644 (file)
@@ -219,14 +219,14 @@ static int __devinit i810_probe(struct pci_dev *dev, const struct pci_device_id
                return retval;
        retval = i2c_bit_add_bus(&i810_ddc_adapter);
        if (retval)
-               i2c_bit_del_bus(&i810_i2c_adapter);
+               i2c_del_adapter(&i810_i2c_adapter);
        return retval;
 }
 
 static void __devexit i810_remove(struct pci_dev *dev)
 {
-       i2c_bit_del_bus(&i810_ddc_adapter);
-       i2c_bit_del_bus(&i810_i2c_adapter);
+       i2c_del_adapter(&i810_ddc_adapter);
+       i2c_del_adapter(&i810_i2c_adapter);
        iounmap(ioaddr);
 }
 
index 781a99c..1898e99 100644 (file)
@@ -680,6 +680,12 @@ static int __devinit iic_probe(struct ocp_device *ocp){
        dev->idx = ocp->def->index;
        ocp_set_drvdata(ocp, dev);
        
+       if (!request_mem_region(ocp->def->paddr, sizeof(struct iic_regs),
+                               "ibm_iic")) {
+               ret = -EBUSY;
+               goto fail1;
+       }
+
        if (!(dev->vaddr = ioremap(ocp->def->paddr, sizeof(struct iic_regs)))){
                printk(KERN_CRIT "ibm-iic%d: failed to ioremap device registers\n",
                        dev->idx);
@@ -750,6 +756,8 @@ fail:
 
        iounmap(dev->vaddr);
 fail2: 
+       release_mem_region(ocp->def->paddr, sizeof(struct iic_regs));
+fail1:
        ocp_set_drvdata(ocp, NULL);
        kfree(dev);     
        return ret;
@@ -777,6 +785,7 @@ static void __devexit iic_remove(struct ocp_device *ocp)
                    free_irq(dev->irq, dev);
                }
                iounmap(dev->vaddr);
+               release_mem_region(ocp->def->paddr, sizeof(struct iic_regs));
                kfree(dev);
        }
 }
diff --git a/drivers/i2c/busses/i2c-ite.c b/drivers/i2c/busses/i2c-ite.c
deleted file mode 100644 (file)
index f7d7186..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
-   -------------------------------------------------------------------------
-   i2c-adap-ite.c i2c-hw access for the IIC peripheral on the ITE MIPS system
-   -------------------------------------------------------------------------
-   Hai-Pao Fan, MontaVista Software, Inc.
-   hpfan@mvista.com or source@mvista.com
-
-   Copyright 2001 MontaVista Software Inc.
-
-   ----------------------------------------------------------------------------
-   This file was highly leveraged from i2c-elektor.c, which was created
-   by Simon G. Vogl and Hans Berglund:
-
-     Copyright (C) 1995-97 Simon G. Vogl
-                   1998-99 Hans Berglund
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
-   Frodo Looijaard <frodol@dds.nl> */
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/wait.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-ite.h>
-#include <linux/i2c-adap-ite.h>
-#include "../i2c-ite.h"
-
-#define DEFAULT_BASE  0x14014030
-#define ITE_IIC_IO_SIZE        0x40
-#define DEFAULT_IRQ   0
-#define DEFAULT_CLOCK 0x1b0e   /* default 16MHz/(27+14) = 400KHz */
-#define DEFAULT_OWN   0x55
-
-static int base;
-static int irq;
-static int clock;
-static int own;
-
-static struct iic_ite gpi;
-static wait_queue_head_t iic_wait;
-static int iic_pending;
-static spinlock_t lock;
-
-/* ----- local functions ----------------------------------------------        */
-
-static void iic_ite_setiic(void *data, int ctl, short val)
-{
-        unsigned long j = jiffies + 10;
-
-       pr_debug(" Write 0x%02x to 0x%x\n",(unsigned short)val, ctl&0xff);
-#ifdef DEBUG
-       while (time_before(jiffies, j))
-               schedule();
-#endif
-       outw(val,ctl);
-}
-
-static short iic_ite_getiic(void *data, int ctl)
-{
-       short val;
-
-       val = inw(ctl);
-       pr_debug("Read 0x%02x from 0x%x\n",(unsigned short)val, ctl&0xff);
-       return (val);
-}
-
-/* Return our slave address.  This is the address
- * put on the I2C bus when another master on the bus wants to address us
- * as a slave
- */
-static int iic_ite_getown(void *data)
-{
-       return (gpi.iic_own);
-}
-
-
-static int iic_ite_getclock(void *data)
-{
-       return (gpi.iic_clock);
-}
-
-
-/* Put this process to sleep.  We will wake up when the
- * IIC controller interrupts.
- */
-static void iic_ite_waitforpin(void) {
-   DEFINE_WAIT(wait);
-   int timeout = 2;
-   unsigned long flags;
-
-   /* If interrupts are enabled (which they are), then put the process to
-    * sleep.  This process will be awakened by two events -- either the
-    * the IIC peripheral interrupts or the timeout expires. 
-    * If interrupts are not enabled then delay for a reasonable amount 
-    * of time and return.
-    */
-   if (gpi.iic_irq > 0) {
-       spin_lock_irqsave(&lock, flags);
-       if (iic_pending == 0) {
-               spin_unlock_irqrestore(&lock, flags);
-               prepare_to_wait(&iic_wait, &wait, TASK_INTERRUPTIBLE);
-               if (schedule_timeout(timeout*HZ)) {
-                       spin_lock_irqsave(&lock, flags);
-                       if (iic_pending == 1) {
-                               iic_pending = 0;
-                       }
-                       spin_unlock_irqrestore(&lock, flags);
-               }
-               finish_wait(&iic_wait, &wait);
-       } else {
-               iic_pending = 0;
-               spin_unlock_irqrestore(&lock, flags);
-       }
-   } else {
-      udelay(100);
-   }
-}
-
-
-static irqreturn_t iic_ite_handler(int this_irq, void *dev_id)
-{
-       spin_lock(&lock);
-       iic_pending = 1;
-       spin_unlock(&lock);
-
-       wake_up_interruptible(&iic_wait);
-
-       return IRQ_HANDLED;
-}
-
-
-/* Lock the region of memory where I/O registers exist.  Request our
- * interrupt line and register its associated handler.
- */
-static int iic_hw_resrc_init(void)
-{
-       if (!request_region(gpi.iic_base, ITE_IIC_IO_SIZE, "i2c"))
-               return -ENODEV;
-  
-       if (gpi.iic_irq <= 0)
-               return 0;
-
-       if (request_irq(gpi.iic_irq, iic_ite_handler, 0, "ITE IIC", 0) < 0)
-               gpi.iic_irq = 0;
-       else
-               enable_irq(gpi.iic_irq);
-
-       return 0;
-}
-
-
-static void iic_ite_release(void)
-{
-       if (gpi.iic_irq > 0) {
-               disable_irq(gpi.iic_irq);
-               free_irq(gpi.iic_irq, 0);
-       }
-       release_region(gpi.iic_base , 2);
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
-static struct i2c_algo_iic_data iic_ite_data = {
-       NULL,
-       iic_ite_setiic,
-       iic_ite_getiic,
-       iic_ite_getown,
-       iic_ite_getclock,
-       iic_ite_waitforpin,
-       80, 80, 100,            /*      waits, timeout */
-};
-
-static struct i2c_adapter iic_ite_ops = {
-       .owner          = THIS_MODULE,
-       .id             = I2C_HW_I_IIC,
-       .algo_data      = &iic_ite_data,
-       .name           = "ITE IIC adapter",
-};
-
-/* Called when the module is loaded.  This function starts the
- * cascade of calls up through the hierarchy of i2c modules (i.e. up to the
- *  algorithm layer and into to the core layer)
- */
-static int __init iic_ite_init(void) 
-{
-
-       struct iic_ite *piic = &gpi;
-
-       printk(KERN_INFO "Initialize ITE IIC adapter module\n");
-       if (base == 0)
-               piic->iic_base = DEFAULT_BASE;
-       else
-               piic->iic_base = base;
-
-       if (irq == 0)
-               piic->iic_irq = DEFAULT_IRQ;
-       else
-               piic->iic_irq = irq;
-
-       if (clock == 0)
-               piic->iic_clock = DEFAULT_CLOCK;
-       else
-               piic->iic_clock = clock;
-
-       if (own == 0)
-               piic->iic_own = DEFAULT_OWN;
-       else
-               piic->iic_own = own;
-
-       iic_ite_data.data = (void *)piic;
-       init_waitqueue_head(&iic_wait);
-       spin_lock_init(&lock);
-       if (iic_hw_resrc_init() == 0) {
-               if (i2c_iic_add_bus(&iic_ite_ops) < 0)
-                       return -ENODEV;
-       } else {
-               return -ENODEV;
-       }
-       printk(KERN_INFO " found device at %#x irq %d.\n", 
-               piic->iic_base, piic->iic_irq);
-       return 0;
-}
-
-
-static void iic_ite_exit(void)
-{
-       i2c_iic_del_bus(&iic_ite_ops);
-        iic_ite_release();
-}
-
-/* If modules is NOT defined when this file is compiled, then the MODULE_*
- * macros will resolve to nothing
- */
-MODULE_AUTHOR("MontaVista Software <www.mvista.com>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for ITE IIC bus adapter");
-MODULE_LICENSE("GPL");
-
-module_param(base, int, 0);
-module_param(irq, int, 0);
-module_param(clock, int, 0);
-module_param(own, int, 0);
-
-
-/* Called when module is loaded or when kernel is initialized.
- * If MODULES is defined when this file is compiled, then this function will
- * resolve to init_module (the function called when insmod is invoked for a
- * module).  Otherwise, this function is called early in the boot, when the
- * kernel is intialized.  Check out /include/init.h to see how this works.
- */
-module_init(iic_ite_init);
-
-/* Resolves to module_cleanup when MODULES is defined. */
-module_exit(iic_ite_exit); 
index dd3f4cd..efa3ecc 100644 (file)
@@ -90,7 +90,7 @@ static int ixp2000_i2c_remove(struct platform_device *plat_dev)
 
        platform_set_drvdata(plat_dev, NULL);
 
-       i2c_bit_del_bus(&drv_data->adapter);
+       i2c_del_adapter(&drv_data->adapter);
 
        kfree(drv_data);
 
index 68fe863..08e89b8 100644 (file)
@@ -91,7 +91,7 @@ static int ixp4xx_i2c_remove(struct platform_device *plat_dev)
 
        platform_set_drvdata(plat_dev, NULL);
 
-       i2c_bit_del_bus(&drv_data->adapter);
+       i2c_del_adapter(&drv_data->adapter);
 
        kfree(drv_data);
 
index e0292e4..ad37c10 100644 (file)
@@ -35,7 +35,7 @@
     nForce4 MCP55              0368
 
     This driver supports the 2 SMBuses that are included in the MCP of the
-    nForce2/3/4 chipsets.
+    nForce2/3/4/5xx chipsets.
 */
 
 /* Note: we assume there can only be one nForce2, with two SMBus interfaces */
@@ -52,8 +52,8 @@
 #include <asm/io.h>
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR ("Hans-Frieder Vogt <hfvogt@arcor.de>");
-MODULE_DESCRIPTION("nForce2 SMBus driver");
+MODULE_AUTHOR ("Hans-Frieder Vogt <hfvogt@gmx.net>");
+MODULE_DESCRIPTION("nForce2/3/4/5xx SMBus driver");
 
 
 struct nforce2_smbus {
@@ -80,9 +80,6 @@ struct nforce2_smbus {
 #define NVIDIA_SMB_ADDR                (smbus->base + 0x02)    /* address */
 #define NVIDIA_SMB_CMD         (smbus->base + 0x03)    /* command */
 #define NVIDIA_SMB_DATA                (smbus->base + 0x04)    /* 32 data registers */
-#define NVIDIA_SMB_BCNT                (smbus->base + 0x24)    /* number of data bytes */
-#define NVIDIA_SMB_ALRM_A      (smbus->base + 0x25)    /* alarm address */
-#define NVIDIA_SMB_ALRM_D      (smbus->base + 0x26)    /* 2 bytes alarm data */
 
 #define NVIDIA_SMB_STS_DONE    0x80
 #define NVIDIA_SMB_STS_ALRM    0x40
@@ -95,40 +92,17 @@ struct nforce2_smbus {
 #define NVIDIA_SMB_PRTCL_BYTE                  0x04
 #define NVIDIA_SMB_PRTCL_BYTE_DATA             0x06
 #define NVIDIA_SMB_PRTCL_WORD_DATA             0x08
-#define NVIDIA_SMB_PRTCL_BLOCK_DATA            0x0a
-#define NVIDIA_SMB_PRTCL_PROC_CALL             0x0c
-#define NVIDIA_SMB_PRTCL_BLOCK_PROC_CALL       0x0d
-#define NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA                0x4a
 #define NVIDIA_SMB_PRTCL_PEC                   0x80
 
 static struct pci_driver nforce2_driver;
 
-static s32 nforce2_access(struct i2c_adapter *adap, u16 addr,
-                      unsigned short flags, char read_write,
-                      u8 command, int size, union i2c_smbus_data *data);
-static u32 nforce2_func(struct i2c_adapter *adapter);
-
-
-static const struct i2c_algorithm smbus_algorithm = {
-       .smbus_xfer = nforce2_access,
-       .functionality = nforce2_func,
-};
-
-static struct i2c_adapter nforce2_adapter = {
-       .owner          = THIS_MODULE,
-       .class          = I2C_CLASS_HWMON,
-       .algo           = &smbus_algorithm,
-};
-
-/* Return -1 on error. See smbus.h for more information */
+/* Return -1 on error */
 static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
                unsigned short flags, char read_write,
                u8 command, int size, union i2c_smbus_data * data)
 {
        struct nforce2_smbus *smbus = adap->algo_data;
        unsigned char protocol, pec, temp;
-       unsigned char len = 0; /* to keep the compiler quiet */
-       int i;
 
        protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ :
                NVIDIA_SMB_PRTCL_WRITE;
@@ -163,35 +137,6 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
                        protocol |= NVIDIA_SMB_PRTCL_WORD_DATA | pec;
                        break;
 
-               case I2C_SMBUS_BLOCK_DATA:
-                       outb_p(command, NVIDIA_SMB_CMD);
-                       if (read_write == I2C_SMBUS_WRITE) {
-                               len = min_t(u8, data->block[0], 32);
-                               outb_p(len, NVIDIA_SMB_BCNT);
-                               for (i = 0; i < len; i++)
-                                       outb_p(data->block[i + 1], NVIDIA_SMB_DATA+i);
-                       }
-                       protocol |= NVIDIA_SMB_PRTCL_BLOCK_DATA | pec;
-                       break;
-
-               case I2C_SMBUS_I2C_BLOCK_DATA:
-                       len = min_t(u8, data->block[0], 32);
-                       outb_p(command, NVIDIA_SMB_CMD);
-                       outb_p(len, NVIDIA_SMB_BCNT);
-                       if (read_write == I2C_SMBUS_WRITE)
-                               for (i = 0; i < len; i++)
-                                       outb_p(data->block[i + 1], NVIDIA_SMB_DATA+i);
-                       protocol |= NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA;
-                       break;
-
-               case I2C_SMBUS_PROC_CALL:
-                       dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
-                       return -1;
-
-               case I2C_SMBUS_BLOCK_PROC_CALL:
-                       dev_err(&adap->dev, "I2C_SMBUS_BLOCK_PROC_CALL not supported!\n");
-                       return -1;
-
                default:
                        dev_err(&adap->dev, "Unsupported transaction %d\n", size);
                        return -1;
@@ -227,19 +172,8 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
                        break;
 
                case I2C_SMBUS_WORD_DATA:
-               /* case I2C_SMBUS_PROC_CALL: not supported */
                        data->word = inb_p(NVIDIA_SMB_DATA) | (inb_p(NVIDIA_SMB_DATA+1) << 8);
                        break;
-
-               case I2C_SMBUS_BLOCK_DATA:
-               /* case I2C_SMBUS_BLOCK_PROC_CALL: not supported */
-                       len = inb_p(NVIDIA_SMB_BCNT);
-                       len = min_t(u8, len, 32);
-               case I2C_SMBUS_I2C_BLOCK_DATA:
-                       for (i = 0; i < len; i++)
-                               data->block[i+1] = inb_p(NVIDIA_SMB_DATA + i);
-                       data->block[0] = len;
-                       break;
        }
 
        return 0;
@@ -250,10 +184,14 @@ static u32 nforce2_func(struct i2c_adapter *adapter)
 {
        /* other functionality might be possible, but is not tested */
        return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
-           I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA /* |
-           I2C_FUNC_SMBUS_BLOCK_DATA */;
+           I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA;
 }
 
+static struct i2c_algorithm smbus_algorithm = {
+       .smbus_xfer     = nforce2_access,
+       .functionality  = nforce2_func,
+};
+
 
 static struct pci_device_id nforce2_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) },
@@ -267,7 +205,6 @@ static struct pci_device_id nforce2_ids[] = {
        { 0 }
 };
 
-
 MODULE_DEVICE_TABLE (pci, nforce2_ids);
 
 
@@ -291,7 +228,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
                }
 
                smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK;
-               smbus->size = 8;
+               smbus->size = 64;
        }
        smbus->dev = dev;
 
@@ -300,7 +237,9 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
                        smbus->base, smbus->base+smbus->size-1, name);
                return -1;
        }
-       smbus->adapter = nforce2_adapter;
+       smbus->adapter.owner = THIS_MODULE;
+       smbus->adapter.class = I2C_CLASS_HWMON;
+       smbus->adapter.algo = &smbus_algorithm;
        smbus->adapter.algo_data = smbus;
        smbus->adapter.dev.parent = &dev->dev;
        snprintf(smbus->adapter.name, I2C_NAME_SIZE,
index dec04da..bcd8367 100644 (file)
@@ -231,8 +231,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
                 * 13           2               1
                 * 19.2         2               1
                 */
-               if (fclk_rate > 16000000)
-                       psc = (fclk_rate + 8000000) / 12000000;
+               if (fclk_rate > 12000000)
+                       psc = fclk_rate / 12000000;
        }
 
        /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
index 5eb2bd2..4bc4281 100644 (file)
@@ -163,7 +163,7 @@ static void __exit i2c_parport_exit(void)
        if (adapter_parm[type].init.val)
                line_set(0, &adapter_parm[type].init);
 
-       i2c_bit_del_bus(&parport_adapter);
+       i2c_del_adapter(&parport_adapter);
        release_region(base, 3);
 }
 
index 48a8294..66696a4 100644 (file)
@@ -218,7 +218,7 @@ static void i2c_parport_detach (struct parport *port)
                        if (adapter_parm[type].init.val)
                                line_set(port, 0, &adapter_parm[type].init);
                                
-                       i2c_bit_del_bus(&adapter->adapter);
+                       i2c_del_adapter(&adapter->adapter);
                        parport_unregister_device(adapter->pdev);
                        if (prev)
                                prev->next = adapter->next;
index 407840b..cc6536a 100644 (file)
@@ -156,7 +156,7 @@ static int __init pca_isa_init(void)
 
 static void pca_isa_exit(void)
 {
-       i2c_pca_del_bus(&pca_isa_ops);
+       i2c_del_adapter(&pca_isa_ops);
 
        if (irq > 0) {
                disable_irq(irq);
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
new file mode 100644 (file)
index 0000000..de0bca7
--- /dev/null
@@ -0,0 +1,708 @@
+/*
+ * Provides I2C support for Philips PNX010x/PNX4008 boards.
+ *
+ * Authors: Dennis Kovalev <dkovalev@ru.mvista.com>
+ *         Vitaly Wool <vwool@ru.mvista.com>
+ *
+ * 2004-2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/timer.h>
+#include <linux/completion.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-pnx.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#define I2C_PNX_TIMEOUT                10 /* msec */
+#define I2C_PNX_SPEED_KHZ      100
+#define I2C_PNX_REGION_SIZE    0x100
+#define PNX_DEFAULT_FREQ       13 /* MHz */
+
+static inline int wait_timeout(long timeout, struct i2c_pnx_algo_data *data)
+{
+       while (timeout > 0 &&
+                       (ioread32(I2C_REG_STS(data)) & mstatus_active)) {
+               mdelay(1);
+               timeout--;
+       }
+       return (timeout <= 0);
+}
+
+static inline int wait_reset(long timeout, struct i2c_pnx_algo_data *data)
+{
+       while (timeout > 0 &&
+                       (ioread32(I2C_REG_CTL(data)) & mcntrl_reset)) {
+               mdelay(1);
+               timeout--;
+       }
+       return (timeout <= 0);
+}
+
+static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap)
+{
+       struct i2c_pnx_algo_data *data = adap->algo_data;
+       struct timer_list *timer = &data->mif.timer;
+       int expires = I2C_PNX_TIMEOUT / (1000 / HZ);
+
+       del_timer_sync(timer);
+
+       dev_dbg(&adap->dev, "Timer armed at %lu plus %u jiffies.\n",
+               jiffies, expires);
+
+       timer->expires = jiffies + expires;
+       timer->data = (unsigned long)adap;
+
+       add_timer(timer);
+}
+
+/**
+ * i2c_pnx_start - start a device
+ * @slave_addr:                slave address
+ * @adap:              pointer to adapter structure
+ *
+ * Generate a START signal in the desired mode.
+ */
+static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap)
+{
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+
+       dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __FUNCTION__,
+               slave_addr, alg_data->mif.mode);
+
+       /* Check for 7 bit slave addresses only */
+       if (slave_addr & ~0x7f) {
+               dev_err(&adap->dev, "%s: Invalid slave address %x. "
+                      "Only 7-bit addresses are supported\n",
+                      adap->name, slave_addr);
+               return -EINVAL;
+       }
+
+       /* First, make sure bus is idle */
+       if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) {
+               /* Somebody else is monopolizing the bus */
+               dev_err(&adap->dev, "%s: Bus busy. Slave addr = %02x, "
+                      "cntrl = %x, stat = %x\n",
+                      adap->name, slave_addr,
+                      ioread32(I2C_REG_CTL(alg_data)),
+                      ioread32(I2C_REG_STS(alg_data)));
+               return -EBUSY;
+       } else if (ioread32(I2C_REG_STS(alg_data)) & mstatus_afi) {
+               /* Sorry, we lost the bus */
+               dev_err(&adap->dev, "%s: Arbitration failure. "
+                      "Slave addr = %02x\n", adap->name, slave_addr);
+               return -EIO;
+       }
+
+       /*
+        * OK, I2C is enabled and we have the bus.
+        * Clear the current TDI and AFI status flags.
+        */
+       iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi,
+                 I2C_REG_STS(alg_data));
+
+       dev_dbg(&adap->dev, "%s(): sending %#x\n", __FUNCTION__,
+               (slave_addr << 1) | start_bit | alg_data->mif.mode);
+
+       /* Write the slave address, START bit and R/W bit */
+       iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode,
+                 I2C_REG_TX(alg_data));
+
+       dev_dbg(&adap->dev, "%s(): exit\n", __FUNCTION__);
+
+       return 0;
+}
+
+/**
+ * i2c_pnx_stop - stop a device
+ * @adap:              pointer to I2C adapter structure
+ *
+ * Generate a STOP signal to terminate the master transaction.
+ */
+static void i2c_pnx_stop(struct i2c_adapter *adap)
+{
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+       /* Only 1 msec max timeout due to interrupt context */
+       long timeout = 1000;
+
+       dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
+               __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+
+       /* Write a STOP bit to TX FIFO */
+       iowrite32(0xff | stop_bit, I2C_REG_TX(alg_data));
+
+       /* Wait until the STOP is seen. */
+       while (timeout > 0 &&
+              (ioread32(I2C_REG_STS(alg_data)) & mstatus_active)) {
+               /* may be called from interrupt context */
+               udelay(1);
+               timeout--;
+       }
+
+       dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
+               __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+}
+
+/**
+ * i2c_pnx_master_xmit - transmit data to slave
+ * @adap:              pointer to I2C adapter structure
+ *
+ * Sends one byte of data to the slave
+ */
+static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
+{
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+       u32 val;
+
+       dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
+               __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+
+       if (alg_data->mif.len > 0) {
+               /* We still have something to talk about... */
+               val = *alg_data->mif.buf++;
+
+               if (alg_data->mif.len == 1) {
+                       val |= stop_bit;
+                       if (!alg_data->last)
+                               val |= start_bit;
+               }
+
+               alg_data->mif.len--;
+               iowrite32(val, I2C_REG_TX(alg_data));
+
+               dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __FUNCTION__,
+                       val, alg_data->mif.len + 1);
+
+               if (alg_data->mif.len == 0) {
+                       if (alg_data->last) {
+                               /* Wait until the STOP is seen. */
+                               if (wait_timeout(I2C_PNX_TIMEOUT, alg_data))
+                                       dev_err(&adap->dev, "The bus is still "
+                                               "active after timeout\n");
+                       }
+                       /* Disable master interrupts */
+                       iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
+                               ~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
+                                 I2C_REG_CTL(alg_data));
+
+                       del_timer_sync(&alg_data->mif.timer);
+
+                       dev_dbg(&adap->dev, "%s(): Waking up xfer routine.\n",
+                               __FUNCTION__);
+
+                       complete(&alg_data->mif.complete);
+               }
+       } else if (alg_data->mif.len == 0) {
+               /* zero-sized transfer */
+               i2c_pnx_stop(adap);
+
+               /* Disable master interrupts. */
+               iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
+                       ~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
+                         I2C_REG_CTL(alg_data));
+
+               /* Stop timer. */
+               del_timer_sync(&alg_data->mif.timer);
+               dev_dbg(&adap->dev, "%s(): Waking up xfer routine after "
+                       "zero-xfer.\n", __FUNCTION__);
+
+               complete(&alg_data->mif.complete);
+       }
+
+       dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
+               __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+
+       return 0;
+}
+
+/**
+ * i2c_pnx_master_rcv - receive data from slave
+ * @adap:              pointer to I2C adapter structure
+ *
+ * Reads one byte data from the slave
+ */
+static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
+{
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+       unsigned int val = 0;
+       u32 ctl = 0;
+
+       dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
+               __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+
+       /* Check, whether there is already data,
+        * or we didn't 'ask' for it yet.
+        */
+       if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) {
+               dev_dbg(&adap->dev, "%s(): Write dummy data to fill "
+                       "Rx-fifo...\n", __FUNCTION__);
+
+               if (alg_data->mif.len == 1) {
+                       /* Last byte, do not acknowledge next rcv. */
+                       val |= stop_bit;
+                       if (!alg_data->last)
+                               val |= start_bit;
+
+                       /*
+                        * Enable interrupt RFDAIE (data in Rx fifo),
+                        * and disable DRMIE (need data for Tx)
+                        */
+                       ctl = ioread32(I2C_REG_CTL(alg_data));
+                       ctl |= mcntrl_rffie | mcntrl_daie;
+                       ctl &= ~mcntrl_drmie;
+                       iowrite32(ctl, I2C_REG_CTL(alg_data));
+               }
+
+               /*
+                * Now we'll 'ask' for data:
+                * For each byte we want to receive, we must
+                * write a (dummy) byte to the Tx-FIFO.
+                */
+               iowrite32(val, I2C_REG_TX(alg_data));
+
+               return 0;
+       }
+
+       /* Handle data. */
+       if (alg_data->mif.len > 0) {
+               val = ioread32(I2C_REG_RX(alg_data));
+               *alg_data->mif.buf++ = (u8) (val & 0xff);
+               dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __FUNCTION__, val,
+                       alg_data->mif.len);
+
+               alg_data->mif.len--;
+               if (alg_data->mif.len == 0) {
+                       if (alg_data->last)
+                               /* Wait until the STOP is seen. */
+                               if (wait_timeout(I2C_PNX_TIMEOUT, alg_data))
+                                       dev_err(&adap->dev, "The bus is still "
+                                               "active after timeout\n");
+
+                       /* Disable master interrupts */
+                       ctl = ioread32(I2C_REG_CTL(alg_data));
+                       ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
+                                mcntrl_drmie | mcntrl_daie);
+                       iowrite32(ctl, I2C_REG_CTL(alg_data));
+
+                       /* Kill timer. */
+                       del_timer_sync(&alg_data->mif.timer);
+                       complete(&alg_data->mif.complete);
+               }
+       }
+
+       dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
+               __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+
+       return 0;
+}
+
+static irqreturn_t
+i2c_pnx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       u32 stat, ctl;
+       struct i2c_adapter *adap = dev_id;
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+
+       dev_dbg(&adap->dev, "%s(): mstat = %x mctrl = %x, mode = %d\n",
+               __FUNCTION__,
+               ioread32(I2C_REG_STS(alg_data)),
+               ioread32(I2C_REG_CTL(alg_data)),
+               alg_data->mif.mode);
+       stat = ioread32(I2C_REG_STS(alg_data));
+
+       /* let's see what kind of event this is */
+       if (stat & mstatus_afi) {
+               /* We lost arbitration in the midst of a transfer */
+               alg_data->mif.ret = -EIO;
+
+               /* Disable master interrupts. */
+               ctl = ioread32(I2C_REG_CTL(alg_data));
+               ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
+                        mcntrl_drmie);
+               iowrite32(ctl, I2C_REG_CTL(alg_data));
+
+               /* Stop timer, to prevent timeout. */
+               del_timer_sync(&alg_data->mif.timer);
+               complete(&alg_data->mif.complete);
+       } else if (stat & mstatus_nai) {
+               /* Slave did not acknowledge, generate a STOP */
+               dev_dbg(&adap->dev, "%s(): "
+                       "Slave did not acknowledge, generating a STOP.\n",
+                       __FUNCTION__);
+               i2c_pnx_stop(adap);
+
+               /* Disable master interrupts. */
+               ctl = ioread32(I2C_REG_CTL(alg_data));
+               ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
+                        mcntrl_drmie);
+               iowrite32(ctl, I2C_REG_CTL(alg_data));
+
+               /* Our return value. */
+               alg_data->mif.ret = -EIO;
+
+               /* Stop timer, to prevent timeout. */
+               del_timer_sync(&alg_data->mif.timer);
+               complete(&alg_data->mif.complete);
+       } else {
+               /*
+                * Two options:
+                * - Master Tx needs data.
+                * - There is data in the Rx-fifo
+                * The latter is only the case if we have requested for data,
+                * via a dummy write. (See 'i2c_pnx_master_rcv'.)
+                * We therefore check, as a sanity check, whether that interrupt
+                * has been enabled.
+                */
+               if ((stat & mstatus_drmi) || !(stat & mstatus_rfe)) {
+                       if (alg_data->mif.mode == I2C_SMBUS_WRITE) {
+                               i2c_pnx_master_xmit(adap);
+                       } else if (alg_data->mif.mode == I2C_SMBUS_READ) {
+                               i2c_pnx_master_rcv(adap);
+                       }
+               }
+       }
+
+       /* Clear TDI and AFI bits */
+       stat = ioread32(I2C_REG_STS(alg_data));
+       iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data));
+
+       dev_dbg(&adap->dev, "%s(): exiting, stat = %x ctrl = %x.\n",
+                __FUNCTION__, ioread32(I2C_REG_STS(alg_data)),
+                ioread32(I2C_REG_CTL(alg_data)));
+
+       return IRQ_HANDLED;
+}
+
+static void i2c_pnx_timeout(unsigned long data)
+{
+       struct i2c_adapter *adap = (struct i2c_adapter *)data;
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+       u32 ctl;
+
+       dev_err(&adap->dev, "Master timed out. stat = %04x, cntrl = %04x. "
+              "Resetting master...\n",
+              ioread32(I2C_REG_STS(alg_data)),
+              ioread32(I2C_REG_CTL(alg_data)));
+
+       /* Reset master and disable interrupts */
+       ctl = ioread32(I2C_REG_CTL(alg_data));
+       ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie | mcntrl_drmie);
+       iowrite32(ctl, I2C_REG_CTL(alg_data));
+
+       ctl |= mcntrl_reset;
+       iowrite32(ctl, I2C_REG_CTL(alg_data));
+       wait_reset(I2C_PNX_TIMEOUT, alg_data);
+       alg_data->mif.ret = -EIO;
+       complete(&alg_data->mif.complete);
+}
+
+static inline void bus_reset_if_active(struct i2c_adapter *adap)
+{
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+       u32 stat;
+
+       if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) {
+               dev_err(&adap->dev,
+                       "%s: Bus is still active after xfer. Reset it...\n",
+                      adap->name);
+               iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
+                         I2C_REG_CTL(alg_data));
+               wait_reset(I2C_PNX_TIMEOUT, alg_data);
+       } else if (!(stat & mstatus_rfe) || !(stat & mstatus_tfe)) {
+               /* If there is data in the fifo's after transfer,
+                * flush fifo's by reset.
+                */
+               iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
+                         I2C_REG_CTL(alg_data));
+               wait_reset(I2C_PNX_TIMEOUT, alg_data);
+       } else if (stat & mstatus_nai) {
+               iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
+                         I2C_REG_CTL(alg_data));
+               wait_reset(I2C_PNX_TIMEOUT, alg_data);
+       }
+}
+
+/**
+ * i2c_pnx_xfer - generic transfer entry point
+ * @adap:              pointer to I2C adapter structure
+ * @msgs:              array of messages
+ * @num:               number of messages
+ *
+ * Initiates the transfer
+ */
+static int
+i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+       struct i2c_msg *pmsg;
+       int rc = 0, completed = 0, i;
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+       u32 stat = ioread32(I2C_REG_STS(alg_data));
+
+       dev_dbg(&adap->dev, "%s(): entering: %d messages, stat = %04x.\n",
+               __FUNCTION__, num, ioread32(I2C_REG_STS(alg_data)));
+
+       bus_reset_if_active(adap);
+
+       /* Process transactions in a loop. */
+       for (i = 0; rc >= 0 && i < num; i++) {
+               u8 addr;
+
+               pmsg = &msgs[i];
+               addr = pmsg->addr;
+
+               if (pmsg->flags & I2C_M_TEN) {
+                       dev_err(&adap->dev,
+                               "%s: 10 bits addr not supported!\n",
+                               adap->name);
+                       rc = -EINVAL;
+                       break;
+               }
+
+               alg_data->mif.buf = pmsg->buf;
+               alg_data->mif.len = pmsg->len;
+               alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ?
+                       I2C_SMBUS_READ : I2C_SMBUS_WRITE;
+               alg_data->mif.ret = 0;
+               alg_data->last = (i == num - 1);
+
+               dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __FUNCTION__,
+                       alg_data->mif.mode,
+                       alg_data->mif.len);
+
+               i2c_pnx_arm_timer(adap);
+
+               /* initialize the completion var */
+               init_completion(&alg_data->mif.complete);
+
+               /* Enable master interrupt */
+               iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_afie |
+                               mcntrl_naie | mcntrl_drmie,
+                         I2C_REG_CTL(alg_data));
+
+               /* Put start-code and slave-address on the bus. */
+               rc = i2c_pnx_start(addr, adap);
+               if (rc < 0)
+                       break;
+
+               /* Wait for completion */
+               wait_for_completion(&alg_data->mif.complete);
+
+               if (!(rc = alg_data->mif.ret))
+                       completed++;
+               dev_dbg(&adap->dev, "%s(): Complete, return code = %d.\n",
+                       __FUNCTION__, rc);
+
+               /* Clear TDI and AFI bits in case they are set. */
+               if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) {
+                       dev_dbg(&adap->dev,
+                               "%s: TDI still set... clearing now.\n",
+                              adap->name);
+                       iowrite32(stat, I2C_REG_STS(alg_data));
+               }
+               if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) {
+                       dev_dbg(&adap->dev,
+                               "%s: AFI still set... clearing now.\n",
+                              adap->name);
+                       iowrite32(stat, I2C_REG_STS(alg_data));
+               }
+       }
+
+       bus_reset_if_active(adap);
+
+       /* Cleanup to be sure... */
+       alg_data->mif.buf = NULL;
+       alg_data->mif.len = 0;
+
+       dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n",
+               __FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+
+       if (completed != num)
+               return ((rc < 0) ? rc : -EREMOTEIO);
+
+       return num;
+}
+
+static u32 i2c_pnx_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm pnx_algorithm = {
+       .master_xfer = i2c_pnx_xfer,
+       .functionality = i2c_pnx_func,
+};
+
+static int i2c_pnx_controller_suspend(struct platform_device *pdev,
+                                     pm_message_t state)
+{
+       struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev);
+       return i2c_pnx->suspend(pdev, state);
+}
+
+static int i2c_pnx_controller_resume(struct platform_device *pdev)
+{
+       struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev);
+       return i2c_pnx->resume(pdev);
+}
+
+static int __devinit i2c_pnx_probe(struct platform_device *pdev)
+{
+       unsigned long tmp;
+       int ret = 0;
+       struct i2c_pnx_algo_data *alg_data;
+       int freq_mhz;
+       struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data;
+
+       if (!i2c_pnx || !i2c_pnx->adapter) {
+               dev_err(&pdev->dev, "%s: no platform data supplied\n",
+                      __FUNCTION__);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       platform_set_drvdata(pdev, i2c_pnx);
+
+       if (i2c_pnx->calculate_input_freq)
+               freq_mhz = i2c_pnx->calculate_input_freq(pdev);
+       else {
+               freq_mhz = PNX_DEFAULT_FREQ;
+               dev_info(&pdev->dev, "Setting bus frequency to default value: "
+                      "%d MHz", freq_mhz);
+       }
+
+       i2c_pnx->adapter->algo = &pnx_algorithm;
+
+       alg_data = i2c_pnx->adapter->algo_data;
+       init_timer(&alg_data->mif.timer);
+       alg_data->mif.timer.function = i2c_pnx_timeout;
+       alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter;
+
+       /* Register I/O resource */
+       if (!request_region(alg_data->base, I2C_PNX_REGION_SIZE, pdev->name)) {
+               dev_err(&pdev->dev,
+                      "I/O region 0x%08x for I2C already in use.\n",
+                      alg_data->base);
+               ret = -ENODEV;
+               goto out_drvdata;
+       }
+
+       if (!(alg_data->ioaddr =
+                       (u32)ioremap(alg_data->base, I2C_PNX_REGION_SIZE))) {
+               dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n");
+               ret = -ENOMEM;
+               goto out_release;
+       }
+
+       i2c_pnx->set_clock_run(pdev);
+
+       /*
+        * Clock Divisor High This value is the number of system clocks
+        * the serial clock (SCL) will be high.
+        * For example, if the system clock period is 50 ns and the maximum
+        * desired serial period is 10000 ns (100 kHz), then CLKHI would be
+        * set to 0.5*(f_sys/f_i2c)-2=0.5*(20e6/100e3)-2=98. The actual value
+        * programmed into CLKHI will vary from this slightly due to
+        * variations in the output pad's rise and fall times as well as
+        * the deglitching filter length.
+        */
+
+       tmp = ((freq_mhz * 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
+       iowrite32(tmp, I2C_REG_CKH(alg_data));
+       iowrite32(tmp, I2C_REG_CKL(alg_data));
+
+       iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data));
+       if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) {
+               ret = -ENODEV;
+               goto out_unmap;
+       }
+       init_completion(&alg_data->mif.complete);
+
+       ret = request_irq(alg_data->irq, i2c_pnx_interrupt,
+                       0, pdev->name, i2c_pnx->adapter);
+       if (ret)
+               goto out_clock;
+
+       /* Register this adapter with the I2C subsystem */
+       i2c_pnx->adapter->dev.parent = &pdev->dev;
+       ret = i2c_add_adapter(i2c_pnx->adapter);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "I2C: Failed to add bus\n");
+               goto out_irq;
+       }
+
+       dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
+              i2c_pnx->adapter->name, alg_data->base, alg_data->irq);
+
+       return 0;
+
+out_irq:
+       free_irq(alg_data->irq, alg_data);
+out_clock:
+       i2c_pnx->set_clock_stop(pdev);
+out_unmap:
+       iounmap((void *)alg_data->ioaddr);
+out_release:
+       release_region(alg_data->base, I2C_PNX_REGION_SIZE);
+out_drvdata:
+       platform_set_drvdata(pdev, NULL);
+out:
+       return ret;
+}
+
+static int __devexit i2c_pnx_remove(struct platform_device *pdev)
+{
+       struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev);
+       struct i2c_adapter *adap = i2c_pnx->adapter;
+       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+
+       free_irq(alg_data->irq, alg_data);
+       i2c_del_adapter(adap);
+       i2c_pnx->set_clock_stop(pdev);
+       iounmap((void *)alg_data->ioaddr);
+       release_region(alg_data->base, I2C_PNX_REGION_SIZE);
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+static struct platform_driver i2c_pnx_driver = {
+       .driver = {
+               .name = "pnx-i2c",
+               .owner = THIS_MODULE,
+       },
+       .probe = i2c_pnx_probe,
+       .remove = __devexit_p(i2c_pnx_remove),
+       .suspend = i2c_pnx_controller_suspend,
+       .resume = i2c_pnx_controller_resume,
+};
+
+static int __init i2c_adap_pnx_init(void)
+{
+       return platform_driver_register(&i2c_pnx_driver);
+}
+
+static void __exit i2c_adap_pnx_exit(void)
+{
+       platform_driver_unregister(&i2c_pnx_driver);
+}
+
+MODULE_AUTHOR("Vitaly Wool, Dennis Kovalev <source@mvista.com>");
+MODULE_DESCRIPTION("I2C driver for Philips IP3204-based I2C busses");
+MODULE_LICENSE("GPL");
+
+#ifdef CONFIG_I2C_PNX_EARLY
+/* We need to make sure I2C is initialized before USB */
+subsys_initcall(i2c_adap_pnx_init);
+#else
+mudule_init(i2c_adap_pnx_init);
+#endif
+module_exit(i2c_adap_pnx_exit);
index 7745e21..07c1f1e 100644 (file)
@@ -212,7 +212,7 @@ static void prosavage_remove(struct pci_dev *dev)
                if (chip->i2c_bus[i].adap_ok == 0)
                        continue;
 
-               ret = i2c_bit_del_bus(&chip->i2c_bus[i].adap);
+               ret = i2c_del_adapter(&chip->i2c_bus[i].adap);
                if (ret) {
                        dev_err(&dev->dev, "%s not removed\n",
                                chip->i2c_bus[i].adap.name);
index 209f47e..844b4ff 100644 (file)
@@ -173,7 +173,7 @@ static int __devinit savage4_probe(struct pci_dev *dev, const struct pci_device_
 
 static void __devexit savage4_remove(struct pci_dev *dev)
 {
-       i2c_bit_del_bus(&savage4_i2c_adapter);
+       i2c_del_adapter(&savage4_i2c_adapter);
        iounmap(ioaddr);
 }
 
diff --git a/drivers/i2c/busses/i2c-versatile.c b/drivers/i2c/busses/i2c-versatile.c
new file mode 100644 (file)
index 0000000..081d957
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ *  i2c-versatile.c
+ *
+ *  Copyright (C) 2006 ARM Ltd.
+ *  written by Russell King, Deep Blue Solutions Ltd.
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+
+#define I2C_CONTROL    0x00
+#define I2C_CONTROLS   0x00
+#define I2C_CONTROLC   0x04
+#define SCL            (1 << 0)
+#define SDA            (1 << 1)
+
+struct i2c_versatile {
+       struct i2c_adapter       adap;
+       struct i2c_algo_bit_data algo;
+       void __iomem             *base;
+};
+
+static void i2c_versatile_setsda(void *data, int state)
+{
+       struct i2c_versatile *i2c = data;
+
+       writel(SDA, i2c->base + (state ? I2C_CONTROLS : I2C_CONTROLC));
+}
+
+static void i2c_versatile_setscl(void *data, int state)
+{
+       struct i2c_versatile *i2c = data;
+
+       writel(SCL, i2c->base + (state ? I2C_CONTROLS : I2C_CONTROLC));
+}
+
+static int i2c_versatile_getsda(void *data)
+{
+       struct i2c_versatile *i2c = data;
+       return !!(readl(i2c->base + I2C_CONTROL) & SDA);
+}
+
+static int i2c_versatile_getscl(void *data)
+{
+       struct i2c_versatile *i2c = data;
+       return !!(readl(i2c->base + I2C_CONTROL) & SCL);
+}
+
+static struct i2c_algo_bit_data i2c_versatile_algo = {
+       .setsda = i2c_versatile_setsda,
+       .setscl = i2c_versatile_setscl,
+       .getsda = i2c_versatile_getsda,
+       .getscl = i2c_versatile_getscl,
+       .udelay = 30,
+       .timeout = HZ,
+};
+
+static int i2c_versatile_probe(struct platform_device *dev)
+{
+       struct i2c_versatile *i2c;
+       struct resource *r;
+       int ret;
+
+       r = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       if (!r) {
+               ret = -EINVAL;
+               goto err_out;
+       }
+
+       if (!request_mem_region(r->start, r->end - r->start + 1, "versatile-i2c")) {
+               ret = -EBUSY;
+               goto err_out;
+       }
+
+       i2c = kzalloc(sizeof(struct i2c_versatile), GFP_KERNEL);
+       if (!i2c) {
+               ret = -ENOMEM;
+               goto err_release;
+       }
+
+       i2c->base = ioremap(r->start, r->end - r->start + 1);
+       if (!i2c->base) {
+               ret = -ENOMEM;
+               goto err_free;
+       }
+
+       writel(SCL | SDA, i2c->base + I2C_CONTROLS);
+
+       i2c->adap.owner = THIS_MODULE;
+       strlcpy(i2c->adap.name, "Versatile I2C adapter", sizeof(i2c->adap.name));
+       i2c->adap.algo_data = &i2c->algo;
+       i2c->adap.dev.parent = &dev->dev;
+       i2c->algo = i2c_versatile_algo;
+       i2c->algo.data = i2c;
+
+       ret = i2c_bit_add_bus(&i2c->adap);
+       if (ret >= 0) {
+               platform_set_drvdata(dev, i2c);
+               return 0;
+       }
+
+       iounmap(i2c->base);
+ err_free:
+       kfree(i2c);
+ err_release:
+       release_mem_region(r->start, r->end - r->start + 1);
+ err_out:
+       return ret;
+}
+
+static int i2c_versatile_remove(struct platform_device *dev)
+{
+       struct i2c_versatile *i2c = platform_get_drvdata(dev);
+
+       platform_set_drvdata(dev, NULL);
+
+       i2c_del_adapter(&i2c->adap);
+       return 0;
+}
+
+static struct platform_driver i2c_versatile_driver = {
+       .probe          = i2c_versatile_probe,
+       .remove         = i2c_versatile_remove,
+       .driver         = {
+               .name   = "versatile-i2c",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init i2c_versatile_init(void)
+{
+       return platform_driver_register(&i2c_versatile_driver);
+}
+
+static void __exit i2c_versatile_exit(void)
+{
+       platform_driver_unregister(&i2c_versatile_driver);
+}
+
+module_init(i2c_versatile_init);
+module_exit(i2c_versatile_exit);
+
+MODULE_DESCRIPTION("ARM Versatile I2C bus driver");
+MODULE_LICENSE("GPL");
index 910e200..15d7e00 100644 (file)
@@ -151,7 +151,7 @@ static int __devinit vt586b_probe(struct pci_dev *dev, const struct pci_device_i
 
 static void __devexit vt586b_remove(struct pci_dev *dev)
 {
-       i2c_bit_del_bus(&vt586b_adapter);
+       i2c_del_adapter(&vt586b_adapter);
        release_region(I2C_DIR, IOSPACE);
        pm_io_base = 0;
 }
index 6c8d251..b0377b8 100644 (file)
@@ -211,14 +211,14 @@ static int __devinit voodoo3_probe(struct pci_dev *dev, const struct pci_device_
                return retval;
        retval = i2c_bit_add_bus(&voodoo3_ddc_adapter);
        if (retval)
-               i2c_bit_del_bus(&voodoo3_i2c_adapter);
+               i2c_del_adapter(&voodoo3_i2c_adapter);
        return retval;
 }
 
 static void __devexit voodoo3_remove(struct pci_dev *dev)
 {
-       i2c_bit_del_bus(&voodoo3_i2c_adapter);
-       i2c_bit_del_bus(&voodoo3_ddc_adapter);
+       i2c_del_adapter(&voodoo3_i2c_adapter);
+       i2c_del_adapter(&voodoo3_ddc_adapter);
        iounmap(ioaddr);
 }
 
index 8ddbae4..6cd96e4 100644 (file)
@@ -116,7 +116,7 @@ static int scx200_i2c_init(void)
 
 static void scx200_i2c_cleanup(void)
 {
-       i2c_bit_del_bus(&scx200_i2c_ops);
+       i2c_del_adapter(&scx200_i2c_ops);
 }
 
 module_init(scx200_i2c_init);
index 93d483b..ec17d6b 100644 (file)
@@ -347,13 +347,19 @@ static void ds1337_init_client(struct i2c_client *client)
 
        if ((status & 0x80) || (control & 0x80)) {
                /* RTC not running */
-               u8 buf[16];
+               u8 buf[1+16];   /* First byte is interpreted as address */
                struct i2c_msg msg[1];
 
                dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__);
 
                /* Initialize all, including STATUS and CONTROL to zero */
                memset(buf, 0, sizeof(buf));
+
+               /* Write valid values in the date/time registers */
+               buf[1+DS1337_REG_DAY] = 1;
+               buf[1+DS1337_REG_DATE] = 1;
+               buf[1+DS1337_REG_MONTH] = 1;
+
                msg[0].addr = client->addr;
                msg[0].flags = 0;
                msg[0].len = sizeof(buf);
index 7ca81f4..3e31f1d 100644 (file)
@@ -127,20 +127,17 @@ static ssize_t show_client_name(struct device *dev, struct device_attribute *att
        return sprintf(buf, "%s\n", client->name);
 }
 
-/* 
- * We can't use the DEVICE_ATTR() macro here as we want the same filename for a
- * different type of a device.  So beware if the DEVICE_ATTR() macro ever
- * changes, this definition will also have to change.
+/*
+ * We can't use the DEVICE_ATTR() macro here, as we used the same name for
+ * an i2c adapter attribute (above).
  */
-static struct device_attribute dev_attr_client_name = {
-       .attr   = {.name = "name", .mode = S_IRUGO, .owner = THIS_MODULE },
-       .show   = &show_client_name,
-};
+static struct device_attribute dev_attr_client_name =
+       __ATTR(name, S_IRUGO, &show_client_name, NULL);
 
 
 /* ---------------------------------------------------
- * registering functions 
- * --------------------------------------------------- 
+ * registering functions
+ * ---------------------------------------------------
  */
 
 /* -----
@@ -314,7 +311,7 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
        res = driver_register(&driver->driver);
        if (res)
                return res;
-       
+
        mutex_lock(&core_lists);
 
        list_add_tail(&driver->list,&drivers);
@@ -338,13 +335,13 @@ int i2c_del_driver(struct i2c_driver *driver)
        struct list_head   *item1, *item2, *_n;
        struct i2c_client  *client;
        struct i2c_adapter *adap;
-       
+
        int res = 0;
 
        mutex_lock(&core_lists);
 
        /* Have a look at each adapter, if clients of this driver are still
-        * attached. If so, detach them to be able to kill the driver 
+        * attached. If so, detach them to be able to kill the driver
         * afterwards.
         */
        list_for_each(item1,&adapters) {
@@ -419,14 +416,14 @@ int i2c_attach_client(struct i2c_client *client)
                goto out_unlock;
        }
        list_add_tail(&client->list,&adapter->clients);
-       
+
        client->usage_count = 0;
 
        client->dev.parent = &client->adapter->dev;
        client->dev.driver = &client->driver->driver;
        client->dev.bus = &i2c_bus_type;
        client->dev.release = &i2c_client_release;
-       
+
        snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id),
                "%d-%04x", i2c_adapter_id(adapter), client->addr);
        dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n",
@@ -467,7 +464,7 @@ int i2c_detach_client(struct i2c_client *client)
 {
        struct i2c_adapter *adapter = client->adapter;
        int res = 0;
-       
+
        if (client->usage_count > 0) {
                dev_warn(&client->dev, "Client [%s] still busy, "
                         "can't detach\n", client->name);
@@ -535,10 +532,10 @@ int i2c_release_client(struct i2c_client *client)
                         __FUNCTION__);
                return -EPERM;
        }
-       
+
        client->usage_count--;
        i2c_dec_use_client(client);
-       
+
        return 0;
 }
 
@@ -603,7 +600,7 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
                }
 #endif
 
-               mutex_lock(&adap->bus_lock);
+               mutex_lock_nested(&adap->bus_lock, adap->level);
                ret = adap->algo->master_xfer(adap,msgs,num);
                mutex_unlock(&adap->bus_lock);
 
@@ -624,7 +621,7 @@ int i2c_master_send(struct i2c_client *client,const char *buf ,int count)
        msg.flags = client->flags & I2C_M_TEN;
        msg.len = count;
        msg.buf = (char *)buf;
-       
+
        ret = i2c_transfer(adap, &msg, 1);
 
        /* If everything went ok (i.e. 1 msg transmitted), return #bytes
@@ -757,7 +754,7 @@ int i2c_probe(struct i2c_adapter *adapter,
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) {
                if (address_data->probe[0] == I2C_CLIENT_END
                 && address_data->normal_i2c[0] == I2C_CLIENT_END)
-                       return 0;
+                       return 0;
 
                dev_warn(&adapter->dev, "SMBus Quick command not supported, "
                         "can't probe for chips\n");
@@ -817,7 +814,7 @@ int i2c_probe(struct i2c_adapter *adapter,
 struct i2c_adapter* i2c_get_adapter(int id)
 {
        struct i2c_adapter *adapter;
-       
+
        mutex_lock(&core_lists);
        adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id);
        if (adapter && !try_module_get(adapter->owner))
@@ -834,14 +831,14 @@ void i2c_put_adapter(struct i2c_adapter *adap)
 
 /* The SMBus parts */
 
-#define POLY    (0x1070U << 3) 
+#define POLY    (0x1070U << 3)
 static u8
 crc8(u16 data)
 {
        int i;
-  
+
        for(i = 0; i < 8; i++) {
-               if (data & 0x8000) 
+               if (data & 0x8000)
                        data = data ^ POLY;
                data = data << 1;
        }
@@ -891,13 +888,13 @@ static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg)
                        rpec, cpec);
                return -1;
        }
-       return 0;       
+       return 0;
 }
 
 s32 i2c_smbus_write_quick(struct i2c_client *client, u8 value)
 {
        return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
-                             value,0,I2C_SMBUS_QUICK,NULL);
+                             value,0,I2C_SMBUS_QUICK,NULL);
 }
 
 s32 i2c_smbus_read_byte(struct i2c_client *client)
@@ -996,11 +993,11 @@ s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command,
                              I2C_SMBUS_I2C_BLOCK_DATA, &data);
 }
 
-/* Simulate a SMBus command using the i2c protocol 
+/* Simulate a SMBus command using the i2c protocol
    No checking of parameters is done!  */
-static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, 
+static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
                                    unsigned short flags,
-                                   char read_write, u8 command, int size, 
+                                   char read_write, u8 command, int size,
                                    union i2c_smbus_data * data)
 {
        /* So we need to generate a series of msgs. In the case of writing, we
@@ -1010,7 +1007,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
        unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];
        unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
        int num = read_write == I2C_SMBUS_READ?2:1;
-       struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 }, 
+       struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },
                                  { addr, flags | I2C_M_RD, 0, msgbuf1 }
                                };
        int i;
@@ -1103,14 +1100,14 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
        if (i) {
                /* Compute PEC if first message is a write */
                if (!(msg[0].flags & I2C_M_RD)) {
-                       if (num == 1) /* Write only */
+                       if (num == 1) /* Write only */
                                i2c_smbus_add_pec(&msg[0]);
                        else /* Write followed by read */
                                partial_pec = i2c_smbus_msg_pec(0, &msg[0]);
                }
                /* Ask for PEC if last message is a read */
                if (msg[num-1].flags & I2C_M_RD)
-                       msg[num-1].len++;
+                       msg[num-1].len++;
        }
 
        if (i2c_transfer(adapter, msg, num) < 0)
@@ -1130,7 +1127,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
                        case I2C_SMBUS_BYTE_DATA:
                                data->byte = msgbuf1[0];
                                break;
-                       case I2C_SMBUS_WORD_DATA: 
+                       case I2C_SMBUS_WORD_DATA:
                        case I2C_SMBUS_PROC_CALL:
                                data->word = msgbuf1[0] | (msgbuf1[1] << 8);
                                break;
@@ -1146,7 +1143,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
 
 
 s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags,
-                   char read_write, u8 command, int size, 
+                   char read_write, u8 command, int size,
                    union i2c_smbus_data * data)
 {
        s32 res;
index 2e22a2f..ac5bd2a 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    i2c-dev.c - i2c-bus driver, char device interface  
+    i2c-dev.c - i2c-bus driver, char device interface
 
     Copyright (C) 1995-97 Simon G. Vogl
     Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
@@ -90,6 +90,7 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev)
        spin_lock(&i2c_dev_list_lock);
        list_del(&i2c_dev->list);
        spin_unlock(&i2c_dev_list_lock);
+       kfree(i2c_dev);
 }
 
 static ssize_t show_adapter_name(struct device *dev,
@@ -172,7 +173,7 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
        switch ( cmd ) {
        case I2C_SLAVE:
        case I2C_SLAVE_FORCE:
-               if ((arg > 0x3ff) || 
+               if ((arg > 0x3ff) ||
                    (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))
                        return -EINVAL;
                if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg))
@@ -193,12 +194,11 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                return 0;
        case I2C_FUNCS:
                funcs = i2c_get_functionality(client->adapter);
-               return (copy_to_user((unsigned long __user *)arg, &funcs,
-                                    sizeof(unsigned long)))?-EFAULT:0;
+               return put_user(funcs, (unsigned long __user *)arg);
 
        case I2C_RDWR:
-               if (copy_from_user(&rdwr_arg, 
-                                  (struct i2c_rdwr_ioctl_data __user *)arg, 
+               if (copy_from_user(&rdwr_arg,
+                                  (struct i2c_rdwr_ioctl_data __user *)arg,
                                   sizeof(rdwr_arg)))
                        return -EFAULT;
 
@@ -206,9 +206,9 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                 * be sent at once */
                if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
                        return -EINVAL;
-               
+
                rdwr_pa = (struct i2c_msg *)
-                       kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), 
+                       kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
                        GFP_KERNEL);
 
                if (rdwr_pa == NULL) return -ENOMEM;
@@ -278,9 +278,9 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                                   (struct i2c_smbus_ioctl_data __user *) arg,
                                   sizeof(struct i2c_smbus_ioctl_data)))
                        return -EFAULT;
-               if ((data_arg.size != I2C_SMBUS_BYTE) && 
+               if ((data_arg.size != I2C_SMBUS_BYTE) &&
                    (data_arg.size != I2C_SMBUS_QUICK) &&
-                   (data_arg.size != I2C_SMBUS_BYTE_DATA) && 
+                   (data_arg.size != I2C_SMBUS_BYTE_DATA) &&
                    (data_arg.size != I2C_SMBUS_WORD_DATA) &&
                    (data_arg.size != I2C_SMBUS_PROC_CALL) &&
                    (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
@@ -291,11 +291,11 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                                data_arg.size);
                        return -EINVAL;
                }
-               /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1, 
+               /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
                   so the check is valid if size==I2C_SMBUS_QUICK too. */
-               if ((data_arg.read_write != I2C_SMBUS_READ) && 
+               if ((data_arg.read_write != I2C_SMBUS_READ) &&
                    (data_arg.read_write != I2C_SMBUS_WRITE)) {
-                       dev_dbg(&client->adapter->dev, 
+                       dev_dbg(&client->adapter->dev,
                                "read_write out of range (%x) in ioctl I2C_SMBUS.\n",
                                data_arg.read_write);
                        return -EINVAL;
@@ -304,7 +304,7 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                /* Note that command values are always valid! */
 
                if ((data_arg.size == I2C_SMBUS_QUICK) ||
-                   ((data_arg.size == I2C_SMBUS_BYTE) && 
+                   ((data_arg.size == I2C_SMBUS_BYTE) &&
                    (data_arg.read_write == I2C_SMBUS_WRITE)))
                        /* These are special: we do not use data */
                        return i2c_smbus_xfer(client->adapter, client->addr,
@@ -322,14 +322,14 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                if ((data_arg.size == I2C_SMBUS_BYTE_DATA) ||
                    (data_arg.size == I2C_SMBUS_BYTE))
                        datasize = sizeof(data_arg.data->byte);
-               else if ((data_arg.size == I2C_SMBUS_WORD_DATA) || 
+               else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||
                         (data_arg.size == I2C_SMBUS_PROC_CALL))
                        datasize = sizeof(data_arg.data->word);
                else /* size == smbus block, i2c block, or block proc. call */
                        datasize = sizeof(data_arg.data->block);
 
-               if ((data_arg.size == I2C_SMBUS_PROC_CALL) || 
-                   (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) || 
+               if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
+                   (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
                    (data_arg.read_write == I2C_SMBUS_WRITE)) {
                        if (copy_from_user(&temp, data_arg.data, datasize))
                                return -EFAULT;
@@ -337,8 +337,8 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                res = i2c_smbus_xfer(client->adapter,client->addr,client->flags,
                      data_arg.read_write,
                      data_arg.command,data_arg.size,&temp);
-               if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) || 
-                             (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) || 
+               if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
+                             (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
                              (data_arg.read_write == I2C_SMBUS_READ))) {
                        if (copy_to_user(data_arg.data, &temp, datasize))
                                return -EFAULT;
@@ -417,8 +417,8 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap)
        i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,
                                     MKDEV(I2C_MAJOR, adap->nr),
                                     "i2c-%d", adap->nr);
-       if (!i2c_dev->dev) {
-               res = -ENODEV;
+       if (IS_ERR(i2c_dev->dev)) {
+               res = PTR_ERR(i2c_dev->dev);
                goto error;
        }
        res = device_create_file(i2c_dev->dev, &dev_attr_name);
@@ -432,7 +432,6 @@ error_destroy:
        device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));
 error:
        return_i2c_dev(i2c_dev);
-       kfree(i2c_dev);
        return res;
 }
 
@@ -447,7 +446,6 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap)
        device_remove_file(i2c_dev->dev, &dev_attr_name);
        return_i2c_dev(i2c_dev);
        device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));
-       kfree(i2c_dev);
 
        pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name);
        return 0;
index 13a6179..fbb7f14 100644 (file)
@@ -1485,7 +1485,7 @@ static int __devinit add_card(struct pci_dev *dev,
 
                         }
 
-                        i2c_bit_del_bus(i2c_ad);
+                       i2c_del_adapter(i2c_ad);
                        kfree(i2c_ad);
                 }
         }
index 3d5f196..6b46c9b 100644 (file)
@@ -146,7 +146,7 @@ config TOUCHSCREEN_TOUCHWIN
 
 config TOUCHSCREEN_UCB1400
        tristate "Philips UCB1400 touchscreen"
-       depends on SND_AC97_BUS
+       select AC97_BUS
        help
          This enables support for the Philips UCB1400 touchscreen interface.
          The UCB1400 is an AC97 audio codec.  The touchscreen interface
index 8e4ce10..ffda71d 100644 (file)
@@ -650,7 +650,7 @@ static int __devinit pluto2_probe(struct pci_dev *pdev,
        /* dvb */
        ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE, &pdev->dev);
        if (ret < 0)
-               goto err_i2c_bit_del_bus;
+               goto err_i2c_del_adapter;
 
        dvb_adapter = &pluto->dvb_adapter;
 
@@ -712,8 +712,8 @@ err_dvb_dmx_release:
        dvb_dmx_release(dvbdemux);
 err_dvb_unregister_adapter:
        dvb_unregister_adapter(dvb_adapter);
-err_i2c_bit_del_bus:
-       i2c_bit_del_bus(&pluto->i2c_adap);
+err_i2c_del_adapter:
+       i2c_del_adapter(&pluto->i2c_adap);
 err_pluto_hw_exit:
        pluto_hw_exit(pluto);
 err_free_irq:
@@ -748,7 +748,7 @@ static void __devexit pluto2_remove(struct pci_dev *pdev)
        dvb_dmxdev_release(&pluto->dmxdev);
        dvb_dmx_release(dvbdemux);
        dvb_unregister_adapter(dvb_adapter);
-       i2c_bit_del_bus(&pluto->i2c_adap);
+       i2c_del_adapter(&pluto->i2c_adap);
        pluto_hw_exit(pluto);
        free_irq(pdev->irq, pluto);
        pci_iounmap(pdev, pluto->io_mem);
index 70de6c9..62b8730 100644 (file)
@@ -479,11 +479,7 @@ int __devexit fini_bttv_i2c(struct bttv *btv)
        if (0 != btv->i2c_rc)
                return 0;
 
-       if (btv->use_i2c_hw) {
-               return i2c_del_adapter(&btv->c.i2c_adap);
-       } else {
-               return i2c_bit_del_bus(&btv->c.i2c_adap);
-       }
+       return i2c_del_adapter(&btv->c.i2c_adap);
 }
 
 /*
index 4b655f2..453af5e 100644 (file)
@@ -1153,7 +1153,7 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
        mutex_lock(&devlist);
        cx88_ir_fini(core);
        if (0 == core->i2c_rc)
-               i2c_bit_del_bus(&core->i2c_adap);
+               i2c_del_adapter(&core->i2c_adap);
        list_del(&core->devlist);
        iounmap(core->lmmio);
        cx88_devcount--;
index 2b4f197..6068c9b 100644 (file)
@@ -168,7 +168,7 @@ void vp3054_i2c_remove(struct cx8802_dev *dev)
            dev->core->board != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
                return;
 
-       i2c_bit_del_bus(&vp3054_i2c->adap);
+       i2c_del_adapter(&vp3054_i2c->adap);
        kfree(vp3054_i2c);
 }
 
index 92bf9a1..0f3fba7 100644 (file)
@@ -50,6 +50,11 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
 #define PDEBUG(level, fmt, args...) \
                if (i2c_debug & (level)) info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ , ## args)
 
+static int usbvision_i2c_write(void *data, unsigned char addr, char *buf,
+                           short len);
+static int usbvision_i2c_read(void *data, unsigned char addr, char *buf,
+                          short len);
+
 static inline int try_write_address(struct i2c_adapter *i2c_adap,
                                    unsigned char addr, int retries)
 {
@@ -61,7 +66,7 @@ static inline int try_write_address(struct i2c_adapter *i2c_adap,
        data = i2c_get_adapdata(i2c_adap);
        buf[0] = 0x00;
        for (i = 0; i <= retries; i++) {
-               ret = (adap->outb(data, addr, buf, 1));
+               ret = (usbvision_i2c_write(data, addr, buf, 1));
                if (ret == 1)
                        break;  /* success! */
                udelay(5 /*adap->udelay */ );
@@ -86,7 +91,7 @@ static inline int try_read_address(struct i2c_adapter *i2c_adap,
 
        data = i2c_get_adapdata(i2c_adap);
        for (i = 0; i <= retries; i++) {
-               ret = (adap->inb(data, addr, buf, 1));
+               ret = (usbvision_i2c_read(data, addr, buf, 1));
                if (ret == 1)
                        break;  /* success! */
                udelay(5 /*adap->udelay */ );
@@ -153,7 +158,6 @@ static int
 usb_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
 {
        struct i2c_msg *pmsg;
-       struct i2c_algo_usb_data *adap = i2c_adap->algo_data;
        void *data;
        int i, ret;
        unsigned char addr;
@@ -170,13 +174,13 @@ usb_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
 
                if (pmsg->flags & I2C_M_RD) {
                        /* read bytes into buffer */
-                       ret = (adap->inb(data, addr, pmsg->buf, pmsg->len));
+                       ret = (usbvision_i2c_read(data, addr, pmsg->buf, pmsg->len));
                        if (ret < pmsg->len) {
                                return (ret < 0) ? ret : -EREMOTEIO;
                        }
                } else {
                        /* write bytes from buffer */
-                       ret = (adap->outb(data, addr, pmsg->buf, pmsg->len));
+                       ret = (usbvision_i2c_write(data, addr, pmsg->buf, pmsg->len));
                        if (ret < pmsg->len) {
                                return (ret < 0) ? ret : -EREMOTEIO;
                        }
index 6b6dff4..a373c14 100644 (file)
@@ -782,7 +782,7 @@ static int vino_i2c_add_bus(void)
 
 static int vino_i2c_del_bus(void)
 {
-       return i2c_sgi_del_bus(&vino_i2c_adapter);
+       return i2c_del_adapter(&vino_i2c_adapter);
 }
 
 static int i2c_camera_command(unsigned int cmd, void *arg)
index 653822c..4d1eb2f 100644 (file)
@@ -849,7 +849,7 @@ zoran_register_i2c (struct zoran *zr)
 static void
 zoran_unregister_i2c (struct zoran *zr)
 {
-       i2c_bit_del_bus((&zr->i2c_adapter));
+       i2c_del_adapter(&zr->i2c_adapter);
 }
 
 /* Check a zoran_params struct for correctness, insert default params */
index 931028f..35ad5cf 100644 (file)
@@ -2131,14 +2131,15 @@ static int rtl8139_poll(struct net_device *dev, int *budget)
        }
 
        if (done) {
+               unsigned long flags;
                /*
                 * Order is important since data can get interrupted
                 * again when we think we are done.
                 */
-               local_irq_disable();
+               local_irq_save(flags);
                RTL_W16_F(IntrMask, rtl8139_intr_mask);
                __netif_rx_complete(dev);
-               local_irq_enable();
+               local_irq_restore(flags);
        }
        spin_unlock(&tp->rx_lock);
 
index 143302a..72ba1a7 100644 (file)
@@ -2,6 +2,7 @@
  * SuperH On-Chip RTC Support
  *
  * Copyright (C) 2006  Paul Mundt
+ * Copyright (C) 2006  Jamie Lenehan
  *
  * Based on the old arch/sh/kernel/cpu/rtc.c by:
  *
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
+
+#define DRV_NAME       "sh-rtc"
+#define DRV_VERSION    "0.1.2"
 
 #ifdef CONFIG_CPU_SH3
 #define rtc_reg_size           sizeof(u16)
 
 #define RTC_REG(r)     ((r) * rtc_reg_size)
 
-#define R64CNT         RTC_REG(0)
-#define RSECCNT        RTC_REG(1)
-#define RMINCNT        RTC_REG(2)
-#define RHRCNT         RTC_REG(3)
-#define RWKCNT         RTC_REG(4)
-#define RDAYCNT        RTC_REG(5)
-#define RMONCNT        RTC_REG(6)
-#define RYRCNT         RTC_REG(7)
-#define RSECAR         RTC_REG(8)
-#define RMINAR         RTC_REG(9)
-#define RHRAR          RTC_REG(10)
-#define RWKAR          RTC_REG(11)
-#define RDAYAR         RTC_REG(12)
-#define RMONAR         RTC_REG(13)
-#define RCR1           RTC_REG(14)
-#define RCR2           RTC_REG(15)
+#define R64CNT         RTC_REG(0)
+
+#define RSECCNT                RTC_REG(1)      /* RTC sec */
+#define RMINCNT                RTC_REG(2)      /* RTC min */
+#define RHRCNT         RTC_REG(3)      /* RTC hour */
+#define RWKCNT         RTC_REG(4)      /* RTC week */
+#define RDAYCNT                RTC_REG(5)      /* RTC day */
+#define RMONCNT                RTC_REG(6)      /* RTC month */
+#define RYRCNT         RTC_REG(7)      /* RTC year */
+#define RSECAR         RTC_REG(8)      /* ALARM sec */
+#define RMINAR         RTC_REG(9)      /* ALARM min */
+#define RHRAR          RTC_REG(10)     /* ALARM hour */
+#define RWKAR          RTC_REG(11)     /* ALARM week */
+#define RDAYAR         RTC_REG(12)     /* ALARM day */
+#define RMONAR         RTC_REG(13)     /* ALARM month */
+#define RCR1           RTC_REG(14)     /* Control */
+#define RCR2           RTC_REG(15)     /* Control */
+
+/* ALARM Bits - or with BCD encoded value */
+#define AR_ENB         0x80    /* Enable for alarm cmp   */
 
 /* RCR1 Bits */
 #define RCR1_CF                0x80    /* Carry Flag             */
@@ -71,22 +79,28 @@ struct sh_rtc {
        unsigned int alarm_irq, periodic_irq, carry_irq;
        struct rtc_device *rtc_dev;
        spinlock_t lock;
+       int rearm_aie;
 };
 
-static irqreturn_t sh_rtc_interrupt(int irq, void *id)
+static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id)
 {
-       struct platform_device *pdev = id;
+       struct platform_device *pdev = to_platform_device(dev_id);
        struct sh_rtc *rtc = platform_get_drvdata(pdev);
        unsigned int tmp, events = 0;
 
        spin_lock(&rtc->lock);
 
        tmp = readb(rtc->regbase + RCR1);
+       tmp &= ~RCR1_CF;
 
-       if (tmp & RCR1_AF)
-               events |= RTC_AF | RTC_IRQF;
-
-       tmp &= ~(RCR1_CF | RCR1_AF);
+       if (rtc->rearm_aie) {
+               if (tmp & RCR1_AF)
+                       tmp &= ~RCR1_AF;        /* try to clear AF again */
+               else {
+                       tmp |= RCR1_AIE;        /* AF has cleared, rearm IRQ */
+                       rtc->rearm_aie = 0;
+               }
+       }
 
        writeb(tmp, rtc->regbase + RCR1);
 
@@ -97,9 +111,45 @@ static irqreturn_t sh_rtc_interrupt(int irq, void *id)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t sh_rtc_periodic(int irq, void *id)
+static irqreturn_t sh_rtc_alarm(int irq, void *dev_id)
+{
+       struct platform_device *pdev = to_platform_device(dev_id);
+       struct sh_rtc *rtc = platform_get_drvdata(pdev);
+       unsigned int tmp, events = 0;
+
+       spin_lock(&rtc->lock);
+
+       tmp = readb(rtc->regbase + RCR1);
+
+       /*
+        * If AF is set then the alarm has triggered. If we clear AF while
+        * the alarm time still matches the RTC time then AF will
+        * immediately be set again, and if AIE is enabled then the alarm
+        * interrupt will immediately be retrigger. So we clear AIE here
+        * and use rtc->rearm_aie so that the carry interrupt will keep
+        * trying to clear AF and once it stays cleared it'll re-enable
+        * AIE.
+        */
+       if (tmp & RCR1_AF) {
+               events |= RTC_AF | RTC_IRQF;
+
+               tmp &= ~(RCR1_AF|RCR1_AIE);
+
+               writeb(tmp, rtc->regbase + RCR1);
+
+               rtc->rearm_aie = 1;
+
+               rtc_update_irq(&rtc->rtc_dev->class_dev, 1, events);
+       }
+
+       spin_unlock(&rtc->lock);
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t sh_rtc_periodic(int irq, void *dev_id)
 {
-       struct sh_rtc *rtc = dev_get_drvdata(id);
+       struct platform_device *pdev = to_platform_device(dev_id);
+       struct sh_rtc *rtc = platform_get_drvdata(pdev);
 
        spin_lock(&rtc->lock);
 
@@ -139,10 +189,11 @@ static inline void sh_rtc_setaie(struct device *dev, unsigned int enable)
 
        tmp = readb(rtc->regbase + RCR1);
 
-       if (enable)
-               tmp |= RCR1_AIE;
-       else
+       if (!enable) {
                tmp &= ~RCR1_AIE;
+               rtc->rearm_aie = 0;
+       } else if (rtc->rearm_aie == 0)
+               tmp |= RCR1_AIE;
 
        writeb(tmp, rtc->regbase + RCR1);
 
@@ -177,7 +228,7 @@ static int sh_rtc_open(struct device *dev)
                goto err_bad_carry;
        }
 
-       ret = request_irq(rtc->alarm_irq, sh_rtc_interrupt, IRQF_DISABLED,
+       ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED,
                          "sh-rtc alarm", dev);
        if (unlikely(ret)) {
                dev_err(dev, "request alarm IRQ failed with %d, IRQ %d\n",
@@ -200,6 +251,7 @@ static void sh_rtc_release(struct device *dev)
        struct sh_rtc *rtc = dev_get_drvdata(dev);
 
        sh_rtc_setpie(dev, 0);
+       sh_rtc_setaie(dev, 0);
 
        free_irq(rtc->periodic_irq, dev);
        free_irq(rtc->carry_irq, dev);
@@ -267,7 +319,7 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
                tm->tm_hour     = BCD2BIN(readb(rtc->regbase + RHRCNT));
                tm->tm_wday     = BCD2BIN(readb(rtc->regbase + RWKCNT));
                tm->tm_mday     = BCD2BIN(readb(rtc->regbase + RDAYCNT));
-               tm->tm_mon      = BCD2BIN(readb(rtc->regbase + RMONCNT));
+               tm->tm_mon      = BCD2BIN(readb(rtc->regbase + RMONCNT)) - 1;
 
 #if defined(CONFIG_CPU_SH4)
                yr  = readw(rtc->regbase + RYRCNT);
@@ -295,7 +347,7 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
                "mday=%d, mon=%d, year=%d, wday=%d\n",
                __FUNCTION__,
                tm->tm_sec, tm->tm_min, tm->tm_hour,
-               tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
+               tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
 
        if (rtc_valid_tm(tm) < 0)
                dev_err(dev, "invalid date\n");
@@ -322,7 +374,7 @@ static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm)
        writeb(BIN2BCD(tm->tm_hour), rtc->regbase + RHRCNT);
        writeb(BIN2BCD(tm->tm_wday), rtc->regbase + RWKCNT);
        writeb(BIN2BCD(tm->tm_mday), rtc->regbase + RDAYCNT);
-       writeb(BIN2BCD(tm->tm_mon),  rtc->regbase + RMONCNT);
+       writeb(BIN2BCD(tm->tm_mon + 1), rtc->regbase + RMONCNT);
 
 #ifdef CONFIG_CPU_SH3
        year = tm->tm_year % 100;
@@ -344,12 +396,136 @@ static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm)
        return 0;
 }
 
+static inline int sh_rtc_read_alarm_value(struct sh_rtc *rtc, int reg_off)
+{
+       unsigned int byte;
+       int value = 0xff;       /* return 0xff for ignored values */
+
+       byte = readb(rtc->regbase + reg_off);
+       if (byte & AR_ENB) {
+               byte &= ~AR_ENB;        /* strip the enable bit */
+               value = BCD2BIN(byte);
+       }
+
+       return value;
+}
+
+static int sh_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct sh_rtc *rtc = platform_get_drvdata(pdev);
+       struct rtc_time* tm = &wkalrm->time;
+
+       spin_lock_irq(&rtc->lock);
+
+       tm->tm_sec      = sh_rtc_read_alarm_value(rtc, RSECAR);
+       tm->tm_min      = sh_rtc_read_alarm_value(rtc, RMINAR);
+       tm->tm_hour     = sh_rtc_read_alarm_value(rtc, RHRAR);
+       tm->tm_wday     = sh_rtc_read_alarm_value(rtc, RWKAR);
+       tm->tm_mday     = sh_rtc_read_alarm_value(rtc, RDAYAR);
+       tm->tm_mon      = sh_rtc_read_alarm_value(rtc, RMONAR);
+       if (tm->tm_mon > 0)
+               tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */
+       tm->tm_year     = 0xffff;
+
+       spin_unlock_irq(&rtc->lock);
+
+       return 0;
+}
+
+static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc,
+                                           int value, int reg_off)
+{
+       /* < 0 for a value that is ignored */
+       if (value < 0)
+               writeb(0, rtc->regbase + reg_off);
+       else
+               writeb(BIN2BCD(value) | AR_ENB,  rtc->regbase + reg_off);
+}
+
+static int sh_rtc_check_alarm(struct rtc_time* tm)
+{
+       /*
+        * The original rtc says anything > 0xc0 is "don't care" or "match
+        * all" - most users use 0xff but rtc-dev uses -1 for the same thing.
+        * The original rtc doesn't support years - some things use -1 and
+        * some 0xffff. We use -1 to make out tests easier.
+        */
+       if (tm->tm_year == 0xffff)
+               tm->tm_year = -1;
+       if (tm->tm_mon >= 0xff)
+               tm->tm_mon = -1;
+       if (tm->tm_mday >= 0xff)
+               tm->tm_mday = -1;
+       if (tm->tm_wday >= 0xff)
+               tm->tm_wday = -1;
+       if (tm->tm_hour >= 0xff)
+               tm->tm_hour = -1;
+       if (tm->tm_min >= 0xff)
+               tm->tm_min = -1;
+       if (tm->tm_sec >= 0xff)
+               tm->tm_sec = -1;
+
+       if (tm->tm_year > 9999 ||
+               tm->tm_mon >= 12 ||
+               tm->tm_mday == 0 || tm->tm_mday >= 32 ||
+               tm->tm_wday >= 7 ||
+               tm->tm_hour >= 24 ||
+               tm->tm_min >= 60 ||
+               tm->tm_sec >= 60)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct sh_rtc *rtc = platform_get_drvdata(pdev);
+       unsigned int rcr1;
+       struct rtc_time *tm = &wkalrm->time;
+       int mon, err;
+
+       err = sh_rtc_check_alarm(tm);
+       if (unlikely(err < 0))
+               return err;
+
+       spin_lock_irq(&rtc->lock);
+
+       /* disable alarm interrupt and clear flag */
+       rcr1 = readb(rtc->regbase + RCR1);
+       rcr1 &= ~RCR1_AF;
+       writeb(rcr1 & ~RCR1_AIE, rtc->regbase + RCR1);
+
+       rtc->rearm_aie = 0;
+
+       /* set alarm time */
+       sh_rtc_write_alarm_value(rtc, tm->tm_sec,  RSECAR);
+       sh_rtc_write_alarm_value(rtc, tm->tm_min,  RMINAR);
+       sh_rtc_write_alarm_value(rtc, tm->tm_hour, RHRAR);
+       sh_rtc_write_alarm_value(rtc, tm->tm_wday, RWKAR);
+       sh_rtc_write_alarm_value(rtc, tm->tm_mday, RDAYAR);
+       mon = tm->tm_mon;
+       if (mon >= 0)
+               mon += 1;
+       sh_rtc_write_alarm_value(rtc, mon, RMONAR);
+
+       /* Restore interrupt activation status */
+       writeb(rcr1, rtc->regbase + RCR1);
+
+       spin_unlock_irq(&rtc->lock);
+
+       return 0;
+}
+
 static struct rtc_class_ops sh_rtc_ops = {
        .open           = sh_rtc_open,
        .release        = sh_rtc_release,
        .ioctl          = sh_rtc_ioctl,
        .read_time      = sh_rtc_read_time,
        .set_time       = sh_rtc_set_time,
+       .read_alarm     = sh_rtc_read_alarm,
+       .set_alarm      = sh_rtc_set_alarm,
        .proc           = sh_rtc_proc,
 };
 
@@ -442,7 +618,7 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
 }
 static struct platform_driver sh_rtc_platform_driver = {
        .driver         = {
-               .name   = "sh-rtc",
+               .name   = DRV_NAME,
                .owner  = THIS_MODULE,
        },
        .probe          = sh_rtc_probe,
@@ -463,5 +639,6 @@ module_init(sh_rtc_init);
 module_exit(sh_rtc_exit);
 
 MODULE_DESCRIPTION("SuperH on-chip RTC driver");
-MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, Jamie Lenehan <lenehan@twibble.org>");
 MODULE_LICENSE("GPL");
index 9031b57..c53b696 100644 (file)
@@ -319,6 +319,28 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
 
        sci_out(port, SCFCR, fcr_val);
 }
+#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
+static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
+{
+       unsigned int fcr_val = 0;
+
+       if (cflag & CRTSCTS) {
+               fcr_val |= SCFCR_MCE;
+
+               ctrl_outw(0x0000, PORT_PSCR);
+       } else {
+               unsigned short data;
+
+               data = ctrl_inw(PORT_PSCR);
+               data &= 0x033f;
+               data |= 0x0400;
+               ctrl_outw(data, PORT_PSCR);
+
+               ctrl_outw(ctrl_inw(SCSPTR0) & 0x17, SCSPTR0);
+       }
+
+       sci_out(port, SCFCR, fcr_val);
+}
 #else
 /* For SH7750 */
 static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
index e4557cc..77f7d63 100644 (file)
 # define SCSPTR3 0xffe30010    /* 16 bit SCIF */
 # define SCSCR_INIT(port) 0x32 /* TIE=0,RIE=0,TE=1,RE=1,REIE=0,CKE=1 */
 # define SCIF_ONLY
+#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
+# define SCPDR0                        0xA405013E      /* 16 bit SCIF0 PSDR */
+# define SCSPTR0               SCPDR0
+# define SCIF_ORER             0x0001  /* overrun error bit */
+# define SCSCR_INIT(port)      0x0038  /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+# define SCIF_ONLY
+# define PORT_PSCR             0xA405011E
 #elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
 # define SCSPTR2 0xffe80020 /* 16 bit SCIF */
 # define SCIF_ORER 0x0001   /* overrun error bit */
@@ -495,6 +502,7 @@ static inline int sci_rxd_in(struct uart_port *port)
                return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
        if (port->mapbase == 0xfe620000)
                return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
+       return 1;
 }
 #elif defined(CONFIG_CPU_SUBTYPE_SH7300)
 static inline int sci_rxd_in(struct uart_port *port)
@@ -521,6 +529,13 @@ static inline int sci_rxd_in(struct uart_port *port)
                return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
        return 1;
 }
+#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
+static inline int sci_rxd_in(struct uart_port *port)
+{
+       if (port->mapbase == 0xffe00000)
+               return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */
+       return 1;
+}
 #elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
 static inline int sci_rxd_in(struct uart_port *port)
 {
@@ -550,6 +565,7 @@ static inline int sci_rxd_in(struct uart_port *port)
                return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
        if (port->mapbase == 0xff925000)
                return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
+       return 1;
 }
 #elif defined(CONFIG_CPU_SUBTYPE_SH7780)
 static inline int sci_rxd_in(struct uart_port *port)
@@ -558,6 +574,7 @@ static inline int sci_rxd_in(struct uart_port *port)
                return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
        if (port->mapbase == 0xffe10000)
                return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
+       return 1;
 }
 #elif defined(CONFIG_CPU_SUBTYPE_SH7206)
 static inline int sci_rxd_in(struct uart_port *port)
@@ -570,6 +587,7 @@ static inline int sci_rxd_in(struct uart_port *port)
                return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
        if (port->mapbase == 0xfffe9800)
                return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
+       return 1;
 }
 #elif defined(CONFIG_CPU_SUBTYPE_SH7619)
 static inline int sci_rxd_in(struct uart_port *port)
@@ -580,6 +598,7 @@ static inline int sci_rxd_in(struct uart_port *port)
                return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
        if (port->mapbase == 0xf8420000)
                return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
+       return 1;
 }
 #endif
 
index 869725a..e7c5b21 100644 (file)
@@ -120,19 +120,19 @@ void radeon_create_i2c_busses(struct radeonfb_info *rinfo)
 void radeon_delete_i2c_busses(struct radeonfb_info *rinfo)
 {
        if (rinfo->i2c[0].rinfo)
-               i2c_bit_del_bus(&rinfo->i2c[0].adapter);
+               i2c_del_adapter(&rinfo->i2c[0].adapter);
        rinfo->i2c[0].rinfo = NULL;
 
        if (rinfo->i2c[1].rinfo)
-               i2c_bit_del_bus(&rinfo->i2c[1].adapter);
+               i2c_del_adapter(&rinfo->i2c[1].adapter);
        rinfo->i2c[1].rinfo = NULL;
 
        if (rinfo->i2c[2].rinfo)
-               i2c_bit_del_bus(&rinfo->i2c[2].adapter);
+               i2c_del_adapter(&rinfo->i2c[2].adapter);
        rinfo->i2c[2].rinfo = NULL;
 
        if (rinfo->i2c[3].rinfo)
-               i2c_bit_del_bus(&rinfo->i2c[3].adapter);
+               i2c_del_adapter(&rinfo->i2c[3].adapter);
        rinfo->i2c[3].rinfo = NULL;
 }
 
index b952e45..961f4d4 100644 (file)
@@ -137,15 +137,15 @@ void i810_create_i2c_busses(struct i810fb_par *par)
 void i810_delete_i2c_busses(struct i810fb_par *par)
 {
         if (par->chan[0].par)
-                i2c_bit_del_bus(&par->chan[0].adapter);
+               i2c_del_adapter(&par->chan[0].adapter);
         par->chan[0].par = NULL;
 
        if (par->chan[1].par)
-               i2c_bit_del_bus(&par->chan[1].adapter);
+               i2c_del_adapter(&par->chan[1].adapter);
        par->chan[1].par = NULL;
 
        if (par->chan[2].par)
-               i2c_bit_del_bus(&par->chan[2].adapter);
+               i2c_del_adapter(&par->chan[2].adapter);
        par->chan[2].par = NULL;
 }
 
index 5686e21..33bc41f 100644 (file)
@@ -188,11 +188,11 @@ void intelfb_delete_i2c_busses(struct intelfb_info *dinfo)
 
        for (i = 0; i < MAX_OUTPUTS; i++) {
                if (dinfo->output[i].i2c_bus.dinfo) {
-                       i2c_bit_del_bus(&dinfo->output[i].i2c_bus.adapter);
+                       i2c_del_adapter(&dinfo->output[i].i2c_bus.adapter);
                        dinfo->output[i].i2c_bus.dinfo = NULL;
                }
                if (dinfo->output[i].ddc_bus.dinfo) {
-                       i2c_bit_del_bus(&dinfo->output[i].ddc_bus.adapter);
+                       i2c_del_adapter(&dinfo->output[i].ddc_bus.adapter);
                        dinfo->output[i].ddc_bus.dinfo = NULL;
                }
        }
index 795c1a9..797b423 100644 (file)
@@ -124,7 +124,7 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo,
 
 static void i2c_bit_bus_del(struct i2c_bit_adapter* b) {
        if (b->initialized) {
-               i2c_bit_del_bus(&b->adapter);
+               i2c_del_adapter(&b->adapter);
                b->initialized = 0;
        }
 }
index 442e853..8454adf 100644 (file)
@@ -147,15 +147,15 @@ void nvidia_create_i2c_busses(struct nvidia_par *par)
 void nvidia_delete_i2c_busses(struct nvidia_par *par)
 {
        if (par->chan[0].par)
-               i2c_bit_del_bus(&par->chan[0].adapter);
+               i2c_del_adapter(&par->chan[0].adapter);
        par->chan[0].par = NULL;
 
        if (par->chan[1].par)
-               i2c_bit_del_bus(&par->chan[1].adapter);
+               i2c_del_adapter(&par->chan[1].adapter);
        par->chan[1].par = NULL;
 
        if (par->chan[2].par)
-               i2c_bit_del_bus(&par->chan[2].adapter);
+               i2c_del_adapter(&par->chan[2].adapter);
        par->chan[2].par = NULL;
 
 }
index c15b259..01b85e3 100644 (file)
@@ -144,15 +144,15 @@ void riva_create_i2c_busses(struct riva_par *par)
 void riva_delete_i2c_busses(struct riva_par *par)
 {
        if (par->chan[0].par)
-               i2c_bit_del_bus(&par->chan[0].adapter);
+               i2c_del_adapter(&par->chan[0].adapter);
        par->chan[0].par = NULL;
 
        if (par->chan[1].par)
-               i2c_bit_del_bus(&par->chan[1].adapter);
+               i2c_del_adapter(&par->chan[1].adapter);
        par->chan[1].par = NULL;
 
        if (par->chan[2].par)
-               i2c_bit_del_bus(&par->chan[2].adapter);
+               i2c_del_adapter(&par->chan[2].adapter);
        par->chan[2].par = NULL;
 }
 
index cef5bf5..1411f3b 100644 (file)
@@ -208,7 +208,7 @@ void savagefb_delete_i2c_busses(struct fb_info *info)
        struct savagefb_par *par = info->par;
 
        if (par->chan.par)
-               i2c_bit_del_bus(&par->chan.adapter);
+               i2c_del_adapter(&par->chan.adapter);
 
        par->chan.par = NULL;
 }
index d11753c..357f1d5 100644 (file)
@@ -35,7 +35,7 @@
 /* for now we operate under the assertion that there can be only one
  * cluster active at a time.  Changing this will require trickling
  * cluster references throughout where nodes are looked up */
-static struct o2nm_cluster *o2nm_single_cluster = NULL;
+struct o2nm_cluster *o2nm_single_cluster = NULL;
 
 #define OCFS2_MAX_HB_CTL_PATH 256
 static char ocfs2_hb_ctl_path[OCFS2_MAX_HB_CTL_PATH] = "/sbin/ocfs2_hb_ctl";
@@ -97,17 +97,6 @@ const char *o2nm_get_hb_ctl_path(void)
 }
 EXPORT_SYMBOL_GPL(o2nm_get_hb_ctl_path);
 
-struct o2nm_cluster {
-       struct config_group     cl_group;
-       unsigned                cl_has_local:1;
-       u8                      cl_local_node;
-       rwlock_t                cl_nodes_lock;
-       struct o2nm_node        *cl_nodes[O2NM_MAX_NODES];
-       struct rb_root          cl_node_ip_tree;
-       /* this bitmap is part of a hack for disk bitmap.. will go eventually. - zab */
-       unsigned long   cl_nodes_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
-};
-
 struct o2nm_node *o2nm_get_node_by_num(u8 node_num)
 {
        struct o2nm_node *node = NULL;
@@ -543,6 +532,179 @@ static struct o2nm_node_group *to_o2nm_node_group(struct config_group *group)
 }
 #endif
 
+struct o2nm_cluster_attribute {
+       struct configfs_attribute attr;
+       ssize_t (*show)(struct o2nm_cluster *, char *);
+       ssize_t (*store)(struct o2nm_cluster *, const char *, size_t);
+};
+
+static ssize_t o2nm_cluster_attr_write(const char *page, ssize_t count,
+                                       unsigned int *val)
+{
+       unsigned long tmp;
+       char *p = (char *)page;
+
+       tmp = simple_strtoul(p, &p, 0);
+       if (!p || (*p && (*p != '\n')))
+               return -EINVAL;
+
+       if (tmp == 0)
+               return -EINVAL;
+       if (tmp >= (u32)-1)
+               return -ERANGE;
+
+       *val = tmp;
+
+       return count;
+}
+
+static ssize_t o2nm_cluster_attr_idle_timeout_ms_read(
+       struct o2nm_cluster *cluster, char *page)
+{
+       return sprintf(page, "%u\n", cluster->cl_idle_timeout_ms);
+}
+
+static ssize_t o2nm_cluster_attr_idle_timeout_ms_write(
+       struct o2nm_cluster *cluster, const char *page, size_t count)
+{
+       ssize_t ret;
+       unsigned int val;
+
+       ret =  o2nm_cluster_attr_write(page, count, &val);
+
+       if (ret > 0) {
+               if (cluster->cl_idle_timeout_ms != val
+                       && o2net_num_connected_peers()) {
+                       mlog(ML_NOTICE,
+                            "o2net: cannot change idle timeout after "
+                            "the first peer has agreed to it."
+                            "  %d connected peers\n",
+                            o2net_num_connected_peers());
+                       ret = -EINVAL;
+               } else if (val <= cluster->cl_keepalive_delay_ms) {
+                       mlog(ML_NOTICE, "o2net: idle timeout must be larger "
+                            "than keepalive delay\n");
+                       ret = -EINVAL;
+               } else {
+                       cluster->cl_idle_timeout_ms = val;
+               }
+       }
+
+       return ret;
+}
+
+static ssize_t o2nm_cluster_attr_keepalive_delay_ms_read(
+       struct o2nm_cluster *cluster, char *page)
+{
+       return sprintf(page, "%u\n", cluster->cl_keepalive_delay_ms);
+}
+
+static ssize_t o2nm_cluster_attr_keepalive_delay_ms_write(
+       struct o2nm_cluster *cluster, const char *page, size_t count)
+{
+       ssize_t ret;
+       unsigned int val;
+
+       ret =  o2nm_cluster_attr_write(page, count, &val);
+
+       if (ret > 0) {
+               if (cluster->cl_keepalive_delay_ms != val
+                   && o2net_num_connected_peers()) {
+                       mlog(ML_NOTICE,
+                            "o2net: cannot change keepalive delay after"
+                            " the first peer has agreed to it."
+                            "  %d connected peers\n",
+                            o2net_num_connected_peers());
+                       ret = -EINVAL;
+               } else if (val >= cluster->cl_idle_timeout_ms) {
+                       mlog(ML_NOTICE, "o2net: keepalive delay must be "
+                            "smaller than idle timeout\n");
+                       ret = -EINVAL;
+               } else {
+                       cluster->cl_keepalive_delay_ms = val;
+               }
+       }
+
+       return ret;
+}
+
+static ssize_t o2nm_cluster_attr_reconnect_delay_ms_read(
+       struct o2nm_cluster *cluster, char *page)
+{
+       return sprintf(page, "%u\n", cluster->cl_reconnect_delay_ms);
+}
+
+static ssize_t o2nm_cluster_attr_reconnect_delay_ms_write(
+       struct o2nm_cluster *cluster, const char *page, size_t count)
+{
+       return o2nm_cluster_attr_write(page, count,
+                                      &cluster->cl_reconnect_delay_ms);
+}
+static struct o2nm_cluster_attribute o2nm_cluster_attr_idle_timeout_ms = {
+       .attr   = { .ca_owner = THIS_MODULE,
+                   .ca_name = "idle_timeout_ms",
+                   .ca_mode = S_IRUGO | S_IWUSR },
+       .show   = o2nm_cluster_attr_idle_timeout_ms_read,
+       .store  = o2nm_cluster_attr_idle_timeout_ms_write,
+};
+
+static struct o2nm_cluster_attribute o2nm_cluster_attr_keepalive_delay_ms = {
+       .attr   = { .ca_owner = THIS_MODULE,
+                   .ca_name = "keepalive_delay_ms",
+                   .ca_mode = S_IRUGO | S_IWUSR },
+       .show   = o2nm_cluster_attr_keepalive_delay_ms_read,
+       .store  = o2nm_cluster_attr_keepalive_delay_ms_write,
+};
+
+static struct o2nm_cluster_attribute o2nm_cluster_attr_reconnect_delay_ms = {
+       .attr   = { .ca_owner = THIS_MODULE,
+                   .ca_name = "reconnect_delay_ms",
+                   .ca_mode = S_IRUGO | S_IWUSR },
+       .show   = o2nm_cluster_attr_reconnect_delay_ms_read,
+       .store  = o2nm_cluster_attr_reconnect_delay_ms_write,
+};
+
+static struct configfs_attribute *o2nm_cluster_attrs[] = {
+       &o2nm_cluster_attr_idle_timeout_ms.attr,
+       &o2nm_cluster_attr_keepalive_delay_ms.attr,
+       &o2nm_cluster_attr_reconnect_delay_ms.attr,
+       NULL,
+};
+static ssize_t o2nm_cluster_show(struct config_item *item,
+                                 struct configfs_attribute *attr,
+                                 char *page)
+{
+       struct o2nm_cluster *cluster = to_o2nm_cluster(item);
+       struct o2nm_cluster_attribute *o2nm_cluster_attr =
+               container_of(attr, struct o2nm_cluster_attribute, attr);
+       ssize_t ret = 0;
+
+       if (o2nm_cluster_attr->show)
+               ret = o2nm_cluster_attr->show(cluster, page);
+       return ret;
+}
+
+static ssize_t o2nm_cluster_store(struct config_item *item,
+                                  struct configfs_attribute *attr,
+                                  const char *page, size_t count)
+{
+       struct o2nm_cluster *cluster = to_o2nm_cluster(item);
+       struct o2nm_cluster_attribute *o2nm_cluster_attr =
+               container_of(attr, struct o2nm_cluster_attribute, attr);
+       ssize_t ret;
+
+       if (o2nm_cluster_attr->store == NULL) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       ret = o2nm_cluster_attr->store(cluster, page, count);
+       if (ret < count)
+               goto out;
+out:
+       return ret;
+}
+
 static struct config_item *o2nm_node_group_make_item(struct config_group *group,
                                                     const char *name)
 {
@@ -624,10 +786,13 @@ static void o2nm_cluster_release(struct config_item *item)
 
 static struct configfs_item_operations o2nm_cluster_item_ops = {
        .release        = o2nm_cluster_release,
+       .show_attribute         = o2nm_cluster_show,
+       .store_attribute        = o2nm_cluster_store,
 };
 
 static struct config_item_type o2nm_cluster_type = {
        .ct_item_ops    = &o2nm_cluster_item_ops,
+       .ct_attrs       = o2nm_cluster_attrs,
        .ct_owner       = THIS_MODULE,
 };
 
@@ -678,6 +843,9 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g
        cluster->cl_group.default_groups[2] = NULL;
        rwlock_init(&cluster->cl_nodes_lock);
        cluster->cl_node_ip_tree = RB_ROOT;
+       cluster->cl_reconnect_delay_ms = O2NET_RECONNECT_DELAY_MS_DEFAULT;
+       cluster->cl_idle_timeout_ms    = O2NET_IDLE_TIMEOUT_MS_DEFAULT;
+       cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT;
 
        ret = &cluster->cl_group;
        o2nm_single_cluster = cluster;
index fce8033..8fb23ca 100644 (file)
@@ -53,6 +53,23 @@ struct o2nm_node {
        unsigned long           nd_set_attributes;
 };
 
+struct o2nm_cluster {
+       struct config_group     cl_group;
+       unsigned                cl_has_local:1;
+       u8                      cl_local_node;
+       rwlock_t                cl_nodes_lock;
+       struct o2nm_node        *cl_nodes[O2NM_MAX_NODES];
+       struct rb_root          cl_node_ip_tree;
+       unsigned int            cl_idle_timeout_ms;
+       unsigned int            cl_keepalive_delay_ms;
+       unsigned int            cl_reconnect_delay_ms;
+
+       /* this bitmap is part of a hack for disk bitmap.. will go eventually. - zab */
+       unsigned long   cl_nodes_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
+};
+
+extern struct o2nm_cluster *o2nm_single_cluster;
+
 u8 o2nm_this_node(void);
 
 int o2nm_configured_node_map(unsigned long *map, unsigned bytes);
index 9b3209d..457753d 100644 (file)
@@ -147,6 +147,28 @@ static void o2net_listen_data_ready(struct sock *sk, int bytes);
 static void o2net_sc_send_keep_req(struct work_struct *work);
 static void o2net_idle_timer(unsigned long data);
 static void o2net_sc_postpone_idle(struct o2net_sock_container *sc);
+static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc);
+
+/*
+ * FIXME: These should use to_o2nm_cluster_from_node(), but we end up
+ * losing our parent link to the cluster during shutdown. This can be
+ * solved by adding a pre-removal callback to configfs, or passing
+ * around the cluster with the node. -jeffm
+ */
+static inline int o2net_reconnect_delay(struct o2nm_node *node)
+{
+       return o2nm_single_cluster->cl_reconnect_delay_ms;
+}
+
+static inline int o2net_keepalive_delay(struct o2nm_node *node)
+{
+       return o2nm_single_cluster->cl_keepalive_delay_ms;
+}
+
+static inline int o2net_idle_timeout(struct o2nm_node *node)
+{
+       return o2nm_single_cluster->cl_idle_timeout_ms;
+}
 
 static inline int o2net_sys_err_to_errno(enum o2net_system_error err)
 {
@@ -271,6 +293,8 @@ static void sc_kref_release(struct kref *kref)
 {
        struct o2net_sock_container *sc = container_of(kref,
                                        struct o2net_sock_container, sc_kref);
+       BUG_ON(timer_pending(&sc->sc_idle_timeout));
+
        sclog(sc, "releasing\n");
 
        if (sc->sc_sock) {
@@ -356,6 +380,13 @@ static void o2net_sc_cancel_delayed_work(struct o2net_sock_container *sc,
                sc_put(sc);
 }
 
+static atomic_t o2net_connected_peers = ATOMIC_INIT(0);
+
+int o2net_num_connected_peers(void)
+{
+       return atomic_read(&o2net_connected_peers);
+}
+
 static void o2net_set_nn_state(struct o2net_node *nn,
                               struct o2net_sock_container *sc,
                               unsigned valid, int err)
@@ -366,6 +397,11 @@ static void o2net_set_nn_state(struct o2net_node *nn,
 
        assert_spin_locked(&nn->nn_lock);
 
+       if (old_sc && !sc)
+               atomic_dec(&o2net_connected_peers);
+       else if (!old_sc && sc)
+               atomic_inc(&o2net_connected_peers);
+
        /* the node num comparison and single connect/accept path should stop
         * an non-null sc from being overwritten with another */
        BUG_ON(sc && nn->nn_sc && nn->nn_sc != sc);
@@ -424,9 +460,9 @@ static void o2net_set_nn_state(struct o2net_node *nn,
                /* delay if we're withing a RECONNECT_DELAY of the
                 * last attempt */
                delay = (nn->nn_last_connect_attempt +
-                        msecs_to_jiffies(O2NET_RECONNECT_DELAY_MS))
+                        msecs_to_jiffies(o2net_reconnect_delay(sc->sc_node)))
                        - jiffies;
-               if (delay > msecs_to_jiffies(O2NET_RECONNECT_DELAY_MS))
+               if (delay > msecs_to_jiffies(o2net_reconnect_delay(sc->sc_node)))
                        delay = 0;
                mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay);
                queue_delayed_work(o2net_wq, &nn->nn_connect_work, delay);
@@ -1099,13 +1135,51 @@ static int o2net_check_handshake(struct o2net_sock_container *sc)
                return -1;
        }
 
+       /*
+        * Ensure timeouts are consistent with other nodes, otherwise
+        * we can end up with one node thinking that the other must be down,
+        * but isn't. This can ultimately cause corruption.
+        */
+       if (be32_to_cpu(hand->o2net_idle_timeout_ms) !=
+                               o2net_idle_timeout(sc->sc_node)) {
+               mlog(ML_NOTICE, SC_NODEF_FMT " uses a network idle timeout of "
+                    "%u ms, but we use %u ms locally.  disconnecting\n",
+                    SC_NODEF_ARGS(sc),
+                    be32_to_cpu(hand->o2net_idle_timeout_ms),
+                    o2net_idle_timeout(sc->sc_node));
+               o2net_ensure_shutdown(nn, sc, -ENOTCONN);
+               return -1;
+       }
+
+       if (be32_to_cpu(hand->o2net_keepalive_delay_ms) !=
+                       o2net_keepalive_delay(sc->sc_node)) {
+               mlog(ML_NOTICE, SC_NODEF_FMT " uses a keepalive delay of "
+                    "%u ms, but we use %u ms locally.  disconnecting\n",
+                    SC_NODEF_ARGS(sc),
+                    be32_to_cpu(hand->o2net_keepalive_delay_ms),
+                    o2net_keepalive_delay(sc->sc_node));
+               o2net_ensure_shutdown(nn, sc, -ENOTCONN);
+               return -1;
+       }
+
+       if (be32_to_cpu(hand->o2hb_heartbeat_timeout_ms) !=
+                       O2HB_MAX_WRITE_TIMEOUT_MS) {
+               mlog(ML_NOTICE, SC_NODEF_FMT " uses a heartbeat timeout of "
+                    "%u ms, but we use %u ms locally.  disconnecting\n",
+                    SC_NODEF_ARGS(sc),
+                    be32_to_cpu(hand->o2hb_heartbeat_timeout_ms),
+                    O2HB_MAX_WRITE_TIMEOUT_MS);
+               o2net_ensure_shutdown(nn, sc, -ENOTCONN);
+               return -1;
+       }
+
        sc->sc_handshake_ok = 1;
 
        spin_lock(&nn->nn_lock);
        /* set valid and queue the idle timers only if it hasn't been
         * shut down already */
        if (nn->nn_sc == sc) {
-               o2net_sc_postpone_idle(sc);
+               o2net_sc_reset_idle_timer(sc);
                o2net_set_nn_state(nn, sc, 1, 0);
        }
        spin_unlock(&nn->nn_lock);
@@ -1131,6 +1205,23 @@ static int o2net_advance_rx(struct o2net_sock_container *sc)
        sclog(sc, "receiving\n");
        do_gettimeofday(&sc->sc_tv_advance_start);
 
+       if (unlikely(sc->sc_handshake_ok == 0)) {
+               if(sc->sc_page_off < sizeof(struct o2net_handshake)) {
+                       data = page_address(sc->sc_page) + sc->sc_page_off;
+                       datalen = sizeof(struct o2net_handshake) - sc->sc_page_off;
+                       ret = o2net_recv_tcp_msg(sc->sc_sock, data, datalen);
+                       if (ret > 0)
+                               sc->sc_page_off += ret;
+               }
+
+               if (sc->sc_page_off == sizeof(struct o2net_handshake)) {
+                       o2net_check_handshake(sc);
+                       if (unlikely(sc->sc_handshake_ok == 0))
+                               ret = -EPROTO;
+               }
+               goto out;
+       }
+
        /* do we need more header? */
        if (sc->sc_page_off < sizeof(struct o2net_msg)) {
                data = page_address(sc->sc_page) + sc->sc_page_off;
@@ -1138,15 +1229,6 @@ static int o2net_advance_rx(struct o2net_sock_container *sc)
                ret = o2net_recv_tcp_msg(sc->sc_sock, data, datalen);
                if (ret > 0) {
                        sc->sc_page_off += ret;
-
-                       /* this working relies on the handshake being
-                        * smaller than the normal message header */
-                       if (sc->sc_page_off >= sizeof(struct o2net_handshake)&&
-                           !sc->sc_handshake_ok && o2net_check_handshake(sc)) {
-                               ret = -EPROTO;
-                               goto out;
-                       }
-
                        /* only swab incoming here.. we can
                         * only get here once as we cross from
                         * being under to over */
@@ -1248,6 +1330,18 @@ static int o2net_set_nodelay(struct socket *sock)
        return ret;
 }
 
+static void o2net_initialize_handshake(void)
+{
+       o2net_hand->o2hb_heartbeat_timeout_ms = cpu_to_be32(
+               O2HB_MAX_WRITE_TIMEOUT_MS);
+       o2net_hand->o2net_idle_timeout_ms = cpu_to_be32(
+               o2net_idle_timeout(NULL));
+       o2net_hand->o2net_keepalive_delay_ms = cpu_to_be32(
+               o2net_keepalive_delay(NULL));
+       o2net_hand->o2net_reconnect_delay_ms = cpu_to_be32(
+               o2net_reconnect_delay(NULL));
+}
+
 /* ------------------------------------------------------------ */
 
 /* called when a connect completes and after a sock is accepted.  the
@@ -1262,6 +1356,7 @@ static void o2net_sc_connect_completed(struct work_struct *work)
               (unsigned long long)O2NET_PROTOCOL_VERSION,
              (unsigned long long)be64_to_cpu(o2net_hand->connector_id));
 
+       o2net_initialize_handshake();
        o2net_sendpage(sc, o2net_hand, sizeof(*o2net_hand));
        sc_put(sc);
 }
@@ -1287,8 +1382,10 @@ static void o2net_idle_timer(unsigned long data)
 
        do_gettimeofday(&now);
 
-       printk(KERN_INFO "o2net: connection to " SC_NODEF_FMT " has been idle for 10 "
-            "seconds, shutting it down.\n", SC_NODEF_ARGS(sc));
+       printk(KERN_INFO "o2net: connection to " SC_NODEF_FMT " has been idle for %u.%u "
+            "seconds, shutting it down.\n", SC_NODEF_ARGS(sc),
+                    o2net_idle_timeout(sc->sc_node) / 1000,
+                    o2net_idle_timeout(sc->sc_node) % 1000);
        mlog(ML_NOTICE, "here are some times that might help debug the "
             "situation: (tmr %ld.%ld now %ld.%ld dr %ld.%ld adv "
             "%ld.%ld:%ld.%ld func (%08x:%u) %ld.%ld:%ld.%ld)\n",
@@ -1306,14 +1403,21 @@ static void o2net_idle_timer(unsigned long data)
        o2net_sc_queue_work(sc, &sc->sc_shutdown_work);
 }
 
-static void o2net_sc_postpone_idle(struct o2net_sock_container *sc)
+static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc)
 {
        o2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work);
        o2net_sc_queue_delayed_work(sc, &sc->sc_keepalive_work,
-                                   O2NET_KEEPALIVE_DELAY_SECS * HZ);
+                     msecs_to_jiffies(o2net_keepalive_delay(sc->sc_node)));
        do_gettimeofday(&sc->sc_tv_timer);
        mod_timer(&sc->sc_idle_timeout,
-                 jiffies + (O2NET_IDLE_TIMEOUT_SECS * HZ));
+              jiffies + msecs_to_jiffies(o2net_idle_timeout(sc->sc_node)));
+}
+
+static void o2net_sc_postpone_idle(struct o2net_sock_container *sc)
+{
+       /* Only push out an existing timer */
+       if (timer_pending(&sc->sc_idle_timeout))
+               o2net_sc_reset_idle_timer(sc);
 }
 
 /* this work func is kicked whenever a path sets the nn state which doesn't
@@ -1435,9 +1539,12 @@ static void o2net_connect_expired(struct work_struct *work)
 
        spin_lock(&nn->nn_lock);
        if (!nn->nn_sc_valid) {
+               struct o2nm_node *node = nn->nn_sc->sc_node;
                mlog(ML_ERROR, "no connection established with node %u after "
-                    "%u seconds, giving up and returning errors.\n",
-                    o2net_num_from_nn(nn), O2NET_IDLE_TIMEOUT_SECS);
+                    "%u.%u seconds, giving up and returning errors.\n",
+                    o2net_num_from_nn(nn),
+                    o2net_idle_timeout(node) / 1000,
+                    o2net_idle_timeout(node) % 1000);
 
                o2net_set_nn_state(nn, NULL, 0, -ENOTCONN);
        }
@@ -1478,6 +1585,8 @@ static void o2net_hb_node_down_cb(struct o2nm_node *node, int node_num,
 
        if (node_num != o2nm_this_node())
                o2net_disconnect_node(node);
+
+       BUG_ON(atomic_read(&o2net_connected_peers) < 0);
 }
 
 static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num,
@@ -1489,14 +1598,14 @@ static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num,
 
        /* ensure an immediate connect attempt */
        nn->nn_last_connect_attempt = jiffies -
-               (msecs_to_jiffies(O2NET_RECONNECT_DELAY_MS) + 1);
+               (msecs_to_jiffies(o2net_reconnect_delay(node)) + 1);
 
        if (node_num != o2nm_this_node()) {
                /* heartbeat doesn't work unless a local node number is
                 * configured and doing so brings up the o2net_wq, so we can
                 * use it.. */
                queue_delayed_work(o2net_wq, &nn->nn_connect_expired,
-                                  O2NET_IDLE_TIMEOUT_SECS * HZ);
+                                  msecs_to_jiffies(o2net_idle_timeout(node)));
 
                /* believe it or not, accept and node hearbeating testing
                 * can succeed for this node before we got here.. so
@@ -1641,6 +1750,7 @@ static int o2net_accept_one(struct socket *sock)
        o2net_register_callbacks(sc->sc_sock->sk, sc);
        o2net_sc_queue_work(sc, &sc->sc_rx_work);
 
+       o2net_initialize_handshake();
        o2net_sendpage(sc, o2net_hand, sizeof(*o2net_hand));
 
 out:
index 616ff2b..21a4e43 100644 (file)
@@ -54,6 +54,13 @@ typedef int (o2net_msg_handler_func)(struct o2net_msg *msg, u32 len, void *data)
 
 #define O2NET_MAX_PAYLOAD_BYTES  (4096 - sizeof(struct o2net_msg))
 
+/* same as hb delay, we're waiting for another node to recognize our hb */
+#define O2NET_RECONNECT_DELAY_MS_DEFAULT       2000
+
+#define O2NET_KEEPALIVE_DELAY_MS_DEFAULT       5000
+#define O2NET_IDLE_TIMEOUT_MS_DEFAULT          10000
+
+
 /* TODO: figure this out.... */
 static inline int o2net_link_down(int err, struct socket *sock)
 {
@@ -101,6 +108,7 @@ void o2net_unregister_hb_callbacks(void);
 int o2net_start_listening(struct o2nm_node *node);
 void o2net_stop_listening(struct o2nm_node *node);
 void o2net_disconnect_node(struct o2nm_node *node);
+int o2net_num_connected_peers(void);
 
 int o2net_init(void);
 void o2net_exit(void);
index daebbd3..b700dc9 100644 (file)
 #define O2NET_MSG_KEEP_REQ_MAGIC  ((u16)0xfa57)
 #define O2NET_MSG_KEEP_RESP_MAGIC ((u16)0xfa58)
 
-/* same as hb delay, we're waiting for another node to recognize our hb */
-#define O2NET_RECONNECT_DELAY_MS       O2HB_REGION_TIMEOUT_MS
-
 /* we're delaying our quorum decision so that heartbeat will have timed
  * out truly dead nodes by the time we come around to making decisions
  * on their number */
 #define O2NET_QUORUM_DELAY_MS  ((o2hb_dead_threshold + 2) * O2HB_REGION_TIMEOUT_MS)
 
-#define O2NET_KEEPALIVE_DELAY_SECS     5
-#define O2NET_IDLE_TIMEOUT_SECS                10
-
 /* 
  * This version number represents quite a lot, unfortunately.  It not
  * only represents the raw network message protocol on the wire but also
  * locking semantics of the file system using the protocol.  It should 
  * be somewhere else, I'm sure, but right now it isn't.
  *
+ * New in version 5:
+ *     - Network timeout checking protocol
+ *
  * New in version 4:
  *     - Remove i_generation from lock names for better stat performance.
  *
  *     - full 64 bit i_size in the metadata lock lvbs
  *     - introduction of "rw" lock and pushing meta/data locking down
  */
-#define O2NET_PROTOCOL_VERSION 4ULL
+#define O2NET_PROTOCOL_VERSION 5ULL
 struct o2net_handshake {
        __be64  protocol_version;
        __be64  connector_id;
+       __be32  o2hb_heartbeat_timeout_ms;
+       __be32  o2net_idle_timeout_ms;
+       __be32  o2net_keepalive_delay_ms;
+       __be32  o2net_reconnect_delay_ms;
 };
 
 struct o2net_node {
index 69fba16..e622013 100644 (file)
@@ -770,7 +770,7 @@ static int ocfs2_lock_create(struct ocfs2_super *osb,
                             int dlm_flags)
 {
        int ret = 0;
-       enum dlm_status status;
+       enum dlm_status status = DLM_NORMAL;
        unsigned long flags;
 
        mlog_entry_void();
@@ -1138,6 +1138,7 @@ int ocfs2_rw_lock(struct inode *inode, int write)
 {
        int status, level;
        struct ocfs2_lock_res *lockres;
+       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
        BUG_ON(!inode);
 
@@ -1147,6 +1148,9 @@ int ocfs2_rw_lock(struct inode *inode, int write)
             (unsigned long long)OCFS2_I(inode)->ip_blkno,
             write ? "EXMODE" : "PRMODE");
 
+       if (ocfs2_mount_local(osb))
+               return 0;
+
        lockres = &OCFS2_I(inode)->ip_rw_lockres;
 
        level = write ? LKM_EXMODE : LKM_PRMODE;
@@ -1164,6 +1168,7 @@ void ocfs2_rw_unlock(struct inode *inode, int write)
 {
        int level = write ? LKM_EXMODE : LKM_PRMODE;
        struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_rw_lockres;
+       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
        mlog_entry_void();
 
@@ -1171,7 +1176,8 @@ void ocfs2_rw_unlock(struct inode *inode, int write)
             (unsigned long long)OCFS2_I(inode)->ip_blkno,
             write ? "EXMODE" : "PRMODE");
 
-       ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
+       if (!ocfs2_mount_local(osb))
+               ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
 
        mlog_exit_void();
 }
@@ -1182,6 +1188,7 @@ int ocfs2_data_lock_full(struct inode *inode,
 {
        int status = 0, level;
        struct ocfs2_lock_res *lockres;
+       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
        BUG_ON(!inode);
 
@@ -1201,6 +1208,9 @@ int ocfs2_data_lock_full(struct inode *inode,
                goto out;
        }
 
+       if (ocfs2_mount_local(osb))
+               goto out;
+
        lockres = &OCFS2_I(inode)->ip_data_lockres;
 
        level = write ? LKM_EXMODE : LKM_PRMODE;
@@ -1269,6 +1279,7 @@ void ocfs2_data_unlock(struct inode *inode,
 {
        int level = write ? LKM_EXMODE : LKM_PRMODE;
        struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_data_lockres;
+       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
        mlog_entry_void();
 
@@ -1276,7 +1287,8 @@ void ocfs2_data_unlock(struct inode *inode,
             (unsigned long long)OCFS2_I(inode)->ip_blkno,
             write ? "EXMODE" : "PRMODE");
 
-       if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)))
+       if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)) &&
+           !ocfs2_mount_local(osb))
                ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
 
        mlog_exit_void();
@@ -1467,8 +1479,9 @@ static int ocfs2_meta_lock_update(struct inode *inode,
 {
        int status = 0;
        struct ocfs2_inode_info *oi = OCFS2_I(inode);
-       struct ocfs2_lock_res *lockres;
+       struct ocfs2_lock_res *lockres = NULL;
        struct ocfs2_dinode *fe;
+       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
        mlog_entry_void();
 
@@ -1483,10 +1496,12 @@ static int ocfs2_meta_lock_update(struct inode *inode,
        }
        spin_unlock(&oi->ip_lock);
 
-       lockres = &oi->ip_meta_lockres;
+       if (!ocfs2_mount_local(osb)) {
+               lockres = &oi->ip_meta_lockres;
 
-       if (!ocfs2_should_refresh_lock_res(lockres))
-               goto bail;
+               if (!ocfs2_should_refresh_lock_res(lockres))
+                       goto bail;
+       }
 
        /* This will discard any caching information we might have had
         * for the inode metadata. */
@@ -1496,7 +1511,7 @@ static int ocfs2_meta_lock_update(struct inode *inode,
         * map (directories, bitmap files, etc) */
        ocfs2_extent_map_trunc(inode, 0);
 
-       if (ocfs2_meta_lvb_is_trustable(inode, lockres)) {
+       if (lockres && ocfs2_meta_lvb_is_trustable(inode, lockres)) {
                mlog(0, "Trusting LVB on inode %llu\n",
                     (unsigned long long)oi->ip_blkno);
                ocfs2_refresh_inode_from_lvb(inode);
@@ -1543,7 +1558,8 @@ static int ocfs2_meta_lock_update(struct inode *inode,
 
        status = 0;
 bail_refresh:
-       ocfs2_complete_lock_res_refresh(lockres, status);
+       if (lockres)
+               ocfs2_complete_lock_res_refresh(lockres, status);
 bail:
        mlog_exit(status);
        return status;
@@ -1585,7 +1601,7 @@ int ocfs2_meta_lock_full(struct inode *inode,
                         int arg_flags)
 {
        int status, level, dlm_flags, acquired;
-       struct ocfs2_lock_res *lockres;
+       struct ocfs2_lock_res *lockres = NULL;
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
        struct buffer_head *local_bh = NULL;
 
@@ -1607,6 +1623,9 @@ int ocfs2_meta_lock_full(struct inode *inode,
                goto bail;
        }
 
+       if (ocfs2_mount_local(osb))
+               goto local;
+
        if (!(arg_flags & OCFS2_META_LOCK_RECOVERY))
                wait_event(osb->recovery_event,
                           ocfs2_node_map_is_empty(osb, &osb->recovery_map));
@@ -1636,6 +1655,7 @@ int ocfs2_meta_lock_full(struct inode *inode,
                wait_event(osb->recovery_event,
                           ocfs2_node_map_is_empty(osb, &osb->recovery_map));
 
+local:
        /*
         * We only see this flag if we're being called from
         * ocfs2_read_locked_inode(). It means we're locking an inode
@@ -1644,7 +1664,8 @@ int ocfs2_meta_lock_full(struct inode *inode,
         */
        if (inode->i_state & I_NEW) {
                status = 0;
-               ocfs2_complete_lock_res_refresh(lockres, 0);
+               if (lockres)
+                       ocfs2_complete_lock_res_refresh(lockres, 0);
                goto bail;
        }
 
@@ -1767,6 +1788,7 @@ void ocfs2_meta_unlock(struct inode *inode,
 {
        int level = ex ? LKM_EXMODE : LKM_PRMODE;
        struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_meta_lockres;
+       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
        mlog_entry_void();
 
@@ -1774,7 +1796,8 @@ void ocfs2_meta_unlock(struct inode *inode,
             (unsigned long long)OCFS2_I(inode)->ip_blkno,
             ex ? "EXMODE" : "PRMODE");
 
-       if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)))
+       if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)) &&
+           !ocfs2_mount_local(osb))
                ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
 
        mlog_exit_void();
@@ -1783,7 +1806,7 @@ void ocfs2_meta_unlock(struct inode *inode,
 int ocfs2_super_lock(struct ocfs2_super *osb,
                     int ex)
 {
-       int status;
+       int status = 0;
        int level = ex ? LKM_EXMODE : LKM_PRMODE;
        struct ocfs2_lock_res *lockres = &osb->osb_super_lockres;
        struct buffer_head *bh;
@@ -1794,6 +1817,9 @@ int ocfs2_super_lock(struct ocfs2_super *osb,
        if (ocfs2_is_hard_readonly(osb))
                return -EROFS;
 
+       if (ocfs2_mount_local(osb))
+               goto bail;
+
        status = ocfs2_cluster_lock(osb, lockres, level, 0, 0);
        if (status < 0) {
                mlog_errno(status);
@@ -1832,7 +1858,8 @@ void ocfs2_super_unlock(struct ocfs2_super *osb,
        int level = ex ? LKM_EXMODE : LKM_PRMODE;
        struct ocfs2_lock_res *lockres = &osb->osb_super_lockres;
 
-       ocfs2_cluster_unlock(osb, lockres, level);
+       if (!ocfs2_mount_local(osb))
+               ocfs2_cluster_unlock(osb, lockres, level);
 }
 
 int ocfs2_rename_lock(struct ocfs2_super *osb)
@@ -1843,6 +1870,9 @@ int ocfs2_rename_lock(struct ocfs2_super *osb)
        if (ocfs2_is_hard_readonly(osb))
                return -EROFS;
 
+       if (ocfs2_mount_local(osb))
+               return 0;
+
        status = ocfs2_cluster_lock(osb, lockres, LKM_EXMODE, 0, 0);
        if (status < 0)
                mlog_errno(status);
@@ -1854,7 +1884,8 @@ void ocfs2_rename_unlock(struct ocfs2_super *osb)
 {
        struct ocfs2_lock_res *lockres = &osb->osb_rename_lockres;
 
-       ocfs2_cluster_unlock(osb, lockres, LKM_EXMODE);
+       if (!ocfs2_mount_local(osb))
+               ocfs2_cluster_unlock(osb, lockres, LKM_EXMODE);
 }
 
 int ocfs2_dentry_lock(struct dentry *dentry, int ex)
@@ -1869,6 +1900,9 @@ int ocfs2_dentry_lock(struct dentry *dentry, int ex)
        if (ocfs2_is_hard_readonly(osb))
                return -EROFS;
 
+       if (ocfs2_mount_local(osb))
+               return 0;
+
        ret = ocfs2_cluster_lock(osb, &dl->dl_lockres, level, 0, 0);
        if (ret < 0)
                mlog_errno(ret);
@@ -1882,7 +1916,8 @@ void ocfs2_dentry_unlock(struct dentry *dentry, int ex)
        struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
        struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
 
-       ocfs2_cluster_unlock(osb, &dl->dl_lockres, level);
+       if (!ocfs2_mount_local(osb))
+               ocfs2_cluster_unlock(osb, &dl->dl_lockres, level);
 }
 
 /* Reference counting of the dlm debug structure. We want this because
@@ -2145,12 +2180,15 @@ static void ocfs2_dlm_shutdown_debug(struct ocfs2_super *osb)
 
 int ocfs2_dlm_init(struct ocfs2_super *osb)
 {
-       int status;
+       int status = 0;
        u32 dlm_key;
-       struct dlm_ctxt *dlm;
+       struct dlm_ctxt *dlm = NULL;
 
        mlog_entry_void();
 
+       if (ocfs2_mount_local(osb))
+               goto local;
+
        status = ocfs2_dlm_init_debug(osb);
        if (status < 0) {
                mlog_errno(status);
@@ -2178,11 +2216,12 @@ int ocfs2_dlm_init(struct ocfs2_super *osb)
                goto bail;
        }
 
+       dlm_register_eviction_cb(dlm, &osb->osb_eviction_cb);
+
+local:
        ocfs2_super_lock_res_init(&osb->osb_super_lockres, osb);
        ocfs2_rename_lock_res_init(&osb->osb_rename_lockres, osb);
 
-       dlm_register_eviction_cb(dlm, &osb->osb_eviction_cb);
-
        osb->dlm = dlm;
 
        status = 0;
index cbfd45a..8fc52d6 100644 (file)
@@ -154,6 +154,9 @@ int ocfs2_register_hb_callbacks(struct ocfs2_super *osb)
 {
        int status;
 
+       if (ocfs2_mount_local(osb))
+               return 0;
+
        status = o2hb_register_callback(&osb->osb_hb_down);
        if (status < 0) {
                mlog_errno(status);
@@ -172,6 +175,9 @@ void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb)
 {
        int status;
 
+       if (ocfs2_mount_local(osb))
+               return;
+
        status = o2hb_unregister_callback(&osb->osb_hb_down);
        if (status < 0)
                mlog_errno(status);
@@ -186,6 +192,9 @@ void ocfs2_stop_heartbeat(struct ocfs2_super *osb)
        int ret;
        char *argv[5], *envp[3];
 
+       if (ocfs2_mount_local(osb))
+               return;
+
        if (!osb->uuid_str) {
                /* This can happen if we don't get far enough in mount... */
                mlog(0, "No UUID with which to stop heartbeat!\n\n");
index 42e361f..e4d9149 100644 (file)
@@ -423,7 +423,8 @@ static int ocfs2_read_locked_inode(struct inode *inode,
         * cluster lock before trusting anything anyway.
         */
        can_lock = !(args->fi_flags & OCFS2_FI_FLAG_SYSFILE)
-               && !(args->fi_flags & OCFS2_FI_FLAG_NOLOCK);
+               && !(args->fi_flags & OCFS2_FI_FLAG_NOLOCK)
+               && !ocfs2_mount_local(osb);
 
        /*
         * To maintain backwards compatibility with older versions of
index 1d7f4ab..825cb0a 100644 (file)
@@ -144,8 +144,10 @@ handle_t *ocfs2_start_trans(struct ocfs2_super *osb, int max_buffs)
                        ocfs2_abort(osb->sb, "Detected aborted journal");
                        handle = ERR_PTR(-EROFS);
                }
-       } else
-               atomic_inc(&(osb->journal->j_num_trans));
+       } else {
+               if (!ocfs2_mount_local(osb))
+                       atomic_inc(&(osb->journal->j_num_trans));
+       }
 
        return handle;
 }
@@ -507,9 +509,23 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb)
 
        BUG_ON(atomic_read(&(osb->journal->j_num_trans)) != 0);
 
-       status = ocfs2_journal_toggle_dirty(osb, 0);
-       if (status < 0)
-               mlog_errno(status);
+       if (ocfs2_mount_local(osb)) {
+               journal_lock_updates(journal->j_journal);
+               status = journal_flush(journal->j_journal);
+               journal_unlock_updates(journal->j_journal);
+               if (status < 0)
+                       mlog_errno(status);
+       }
+
+       if (status == 0) {
+               /*
+                * Do not toggle if flush was unsuccessful otherwise
+                * will leave dirty metadata in a "clean" journal
+                */
+               status = ocfs2_journal_toggle_dirty(osb, 0);
+               if (status < 0)
+                       mlog_errno(status);
+       }
 
        /* Shutdown the kernel journal system */
        journal_destroy(journal->j_journal);
@@ -549,7 +565,7 @@ static void ocfs2_clear_journal_error(struct super_block *sb,
        }
 }
 
-int ocfs2_journal_load(struct ocfs2_journal *journal)
+int ocfs2_journal_load(struct ocfs2_journal *journal, int local)
 {
        int status = 0;
        struct ocfs2_super *osb;
@@ -576,14 +592,18 @@ int ocfs2_journal_load(struct ocfs2_journal *journal)
        }
 
        /* Launch the commit thread */
-       osb->commit_task = kthread_run(ocfs2_commit_thread, osb, "ocfs2cmt");
-       if (IS_ERR(osb->commit_task)) {
-               status = PTR_ERR(osb->commit_task);
+       if (!local) {
+               osb->commit_task = kthread_run(ocfs2_commit_thread, osb,
+                                              "ocfs2cmt");
+               if (IS_ERR(osb->commit_task)) {
+                       status = PTR_ERR(osb->commit_task);
+                       osb->commit_task = NULL;
+                       mlog(ML_ERROR, "unable to launch ocfs2commit thread, "
+                            "error=%d", status);
+                       goto done;
+               }
+       } else
                osb->commit_task = NULL;
-               mlog(ML_ERROR, "unable to launch ocfs2commit thread, error=%d",
-                    status);
-               goto done;
-       }
 
 done:
        mlog_exit(status);
index 899112a..e121636 100644 (file)
@@ -157,7 +157,7 @@ int    ocfs2_journal_init(struct ocfs2_journal *journal,
 void   ocfs2_journal_shutdown(struct ocfs2_super *osb);
 int    ocfs2_journal_wipe(struct ocfs2_journal *journal,
                          int full);
-int    ocfs2_journal_load(struct ocfs2_journal *journal);
+int    ocfs2_journal_load(struct ocfs2_journal *journal, int local);
 int    ocfs2_check_journals_nolocks(struct ocfs2_super *osb);
 void   ocfs2_recovery_thread(struct ocfs2_super *osb,
                             int node_num);
@@ -174,6 +174,9 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode)
 {
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
+       if (ocfs2_mount_local(osb))
+               return;
+
        if (!ocfs2_inode_fully_checkpointed(inode)) {
                /* WARNING: This only kicks off a single
                 * checkpoint. If someone races you and adds more
index 69f85ae..51b0204 100644 (file)
@@ -83,10 +83,12 @@ static struct vm_operations_struct ocfs2_file_vm_ops = {
 int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
 {
        int ret = 0, lock_level = 0;
+       struct ocfs2_super *osb = OCFS2_SB(file->f_dentry->d_inode->i_sb);
 
        /* We don't want to support shared writable mappings yet. */
-       if (((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE))
-           && ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) {
+       if (!ocfs2_mount_local(osb) &&
+           ((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE)) &&
+           ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) {
                mlog(0, "disallow shared writable mmaps %lx\n", vma->vm_flags);
                /* This is -EINVAL because generic_file_readonly_mmap
                 * returns it in a similar situation. */
index 21db45d..9637039 100644 (file)
@@ -587,9 +587,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
        }
 
        ocfs2_inode_set_new(osb, inode);
-       status = ocfs2_create_new_inode_locks(inode);
-       if (status < 0)
-               mlog_errno(status);
+       if (!ocfs2_mount_local(osb)) {
+               status = ocfs2_create_new_inode_locks(inode);
+               if (status < 0)
+                       mlog_errno(status);
+       }
 
        status = 0; /* error in ocfs2_create_new_inode_locks is not
                     * critical */
index b767fd7..db8e77c 100644 (file)
@@ -349,6 +349,11 @@ static inline int ocfs2_is_soft_readonly(struct ocfs2_super *osb)
        return ret;
 }
 
+static inline int ocfs2_mount_local(struct ocfs2_super *osb)
+{
+       return (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT);
+}
+
 #define OCFS2_IS_VALID_DINODE(ptr)                                     \
        (!strcmp((ptr)->i_signature, OCFS2_INODE_SIGNATURE))
 
index 3330a5d..b5c6856 100644 (file)
@@ -86,7 +86,7 @@
        OCFS2_SB(sb)->s_feature_incompat &= ~(mask)
 
 #define OCFS2_FEATURE_COMPAT_SUPP      0
-#define OCFS2_FEATURE_INCOMPAT_SUPP    0
+#define OCFS2_FEATURE_INCOMPAT_SUPP    OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT
 #define OCFS2_FEATURE_RO_COMPAT_SUPP   0
 
 /*
  */
 #define OCFS2_FEATURE_INCOMPAT_HEARTBEAT_DEV   0x0002
 
+/*
+ * tunefs sets this incompat flag before starting the resize and clears it
+ * at the end. This flag protects users from inadvertently mounting the fs
+ * after an aborted run without fsck-ing.
+ */
+#define OCFS2_FEATURE_INCOMPAT_RESIZE_INPROG    0x0004
+
+/* Used to denote a non-clustered volume */
+#define OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT     0x0008
+
+/* Support for sparse allocation in b-trees */
+#define OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC    0x0010
 
 /*
  * Flags on ocfs2_dinode.i_flags
index 4bf3954..a6d2f8c 100644 (file)
@@ -508,6 +508,27 @@ bail:
        return status;
 }
 
+static int ocfs2_verify_heartbeat(struct ocfs2_super *osb)
+{
+       if (ocfs2_mount_local(osb)) {
+               if (osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) {
+                       mlog(ML_ERROR, "Cannot heartbeat on a locally "
+                            "mounted device.\n");
+                       return -EINVAL;
+               }
+       }
+
+       if (!(osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL)) {
+               if (!ocfs2_mount_local(osb) && !ocfs2_is_hard_readonly(osb)) {
+                       mlog(ML_ERROR, "Heartbeat has to be started to mount "
+                            "a read-write clustered device.\n");
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
 static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
 {
        struct dentry *root;
@@ -516,16 +537,24 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
        struct inode *inode = NULL;
        struct ocfs2_super *osb = NULL;
        struct buffer_head *bh = NULL;
+       char nodestr[8];
 
        mlog_entry("%p, %p, %i", sb, data, silent);
 
-       /* for now we only have one cluster/node, make sure we see it
-        * in the heartbeat universe */
-       if (!o2hb_check_local_node_heartbeating()) {
+       if (!ocfs2_parse_options(sb, data, &parsed_opt, 0)) {
                status = -EINVAL;
                goto read_super_error;
        }
 
+       /* for now we only have one cluster/node, make sure we see it
+        * in the heartbeat universe */
+       if (parsed_opt & OCFS2_MOUNT_HB_LOCAL) {
+               if (!o2hb_check_local_node_heartbeating()) {
+                       status = -EINVAL;
+                       goto read_super_error;
+               }
+       }
+
        /* probe for superblock */
        status = ocfs2_sb_probe(sb, &bh, &sector_size);
        if (status < 0) {
@@ -541,11 +570,6 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
        }
        brelse(bh);
        bh = NULL;
-
-       if (!ocfs2_parse_options(sb, data, &parsed_opt, 0)) {
-               status = -EINVAL;
-               goto read_super_error;
-       }
        osb->s_mount_opt = parsed_opt;
 
        sb->s_magic = OCFS2_SUPER_MAGIC;
@@ -588,21 +612,16 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
        }
 
        if (!ocfs2_is_hard_readonly(osb)) {
-               /* If this isn't a hard readonly mount, then we need
-                * to make sure that heartbeat is in a valid state,
-                * and that we mark ourselves soft readonly is -oro
-                * was specified. */
-               if (!(osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL)) {
-                       mlog(ML_ERROR, "No heartbeat for device (%s)\n",
-                            sb->s_id);
-                       status = -EINVAL;
-                       goto read_super_error;
-               }
-
                if (sb->s_flags & MS_RDONLY)
                        ocfs2_set_ro_flag(osb, 0);
        }
 
+       status = ocfs2_verify_heartbeat(osb);
+       if (status < 0) {
+               mlog_errno(status);
+               goto read_super_error;
+       }
+
        osb->osb_debug_root = debugfs_create_dir(osb->uuid_str,
                                                 ocfs2_debugfs_root);
        if (!osb->osb_debug_root) {
@@ -635,9 +654,14 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
 
        ocfs2_complete_mount_recovery(osb);
 
-       printk(KERN_INFO "ocfs2: Mounting device (%s) on (node %d, slot %d) "
+       if (ocfs2_mount_local(osb))
+               snprintf(nodestr, sizeof(nodestr), "local");
+       else
+               snprintf(nodestr, sizeof(nodestr), "%d", osb->node_num);
+
+       printk(KERN_INFO "ocfs2: Mounting device (%s) on (node %s, slot %d) "
               "with %s data mode.\n",
-              osb->dev_str, osb->node_num, osb->slot_num,
+              osb->dev_str, nodestr, osb->slot_num,
               osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK ? "writeback" :
               "ordered");
 
@@ -999,7 +1023,11 @@ static int ocfs2_fill_local_node_info(struct ocfs2_super *osb)
 
        /* XXX hold a ref on the node while mounte?  easy enough, if
         * desirable. */
-       osb->node_num = o2nm_this_node();
+       if (ocfs2_mount_local(osb))
+               osb->node_num = 0;
+       else
+               osb->node_num = o2nm_this_node();
+
        if (osb->node_num == O2NM_MAX_NODES) {
                mlog(ML_ERROR, "could not find this host's node number\n");
                status = -ENOENT;
@@ -1084,6 +1112,9 @@ static int ocfs2_mount_volume(struct super_block *sb)
                goto leave;
        }
 
+       if (ocfs2_mount_local(osb))
+               goto leave;
+
        /* This should be sent *after* we recovered our journal as it
         * will cause other nodes to unmark us as needing
         * recovery. However, we need to send it *before* dropping the
@@ -1114,6 +1145,7 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
 {
        int tmp;
        struct ocfs2_super *osb = NULL;
+       char nodestr[8];
 
        mlog_entry("(0x%p)\n", sb);
 
@@ -1177,8 +1209,13 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
 
        atomic_set(&osb->vol_state, VOLUME_DISMOUNTED);
 
-       printk(KERN_INFO "ocfs2: Unmounting device (%s) on (node %d)\n",
-              osb->dev_str, osb->node_num);
+       if (ocfs2_mount_local(osb))
+               snprintf(nodestr, sizeof(nodestr), "local");
+       else
+               snprintf(nodestr, sizeof(nodestr), "%d", osb->node_num);
+
+       printk(KERN_INFO "ocfs2: Unmounting device (%s) on (node %s)\n",
+              osb->dev_str, nodestr);
 
        ocfs2_delete_osb(osb);
        kfree(osb);
@@ -1536,6 +1573,7 @@ static int ocfs2_check_volume(struct ocfs2_super *osb)
 {
        int status = 0;
        int dirty;
+       int local;
        struct ocfs2_dinode *local_alloc = NULL; /* only used if we
                                                  * recover
                                                  * ourselves. */
@@ -1563,8 +1601,10 @@ static int ocfs2_check_volume(struct ocfs2_super *osb)
                     "recovering volume.\n");
        }
 
+       local = ocfs2_mount_local(osb);
+
        /* will play back anything left in the journal. */
-       ocfs2_journal_load(osb->journal);
+       ocfs2_journal_load(osb->journal, local);
 
        if (dirty) {
                /* recover my local alloc if we didn't unmount cleanly. */
index 5b4dca7..0315a8b 100644 (file)
@@ -1000,6 +1000,9 @@ int ocfs2_register_net_handlers(struct ocfs2_super *osb)
 {
        int status = 0;
 
+       if (ocfs2_mount_local(osb))
+               return 0;
+
        status = o2net_register_handler(OCFS2_MESSAGE_TYPE_RESPONSE,
                                        osb->net_key,
                                        sizeof(struct ocfs2_response_msg),
diff --git a/include/asm-arm/arch-pnx4008/i2c.h b/include/asm-arm/arch-pnx4008/i2c.h
new file mode 100644 (file)
index 0000000..92e8d65
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * PNX4008-specific tweaks for I2C IP3204 block
+ *
+ * Author: Vitaly Wool <vwool@ru.mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef __ASM_ARCH_I2C_H__
+#define __ASM_ARCH_I2C_H__
+
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+
+enum {
+       mstatus_tdi = 0x00000001,
+       mstatus_afi = 0x00000002,
+       mstatus_nai = 0x00000004,
+       mstatus_drmi = 0x00000008,
+       mstatus_active = 0x00000020,
+       mstatus_scl = 0x00000040,
+       mstatus_sda = 0x00000080,
+       mstatus_rff = 0x00000100,
+       mstatus_rfe = 0x00000200,
+       mstatus_tff = 0x00000400,
+       mstatus_tfe = 0x00000800,
+};
+
+enum {
+       mcntrl_tdie = 0x00000001,
+       mcntrl_afie = 0x00000002,
+       mcntrl_naie = 0x00000004,
+       mcntrl_drmie = 0x00000008,
+       mcntrl_daie = 0x00000020,
+       mcntrl_rffie = 0x00000040,
+       mcntrl_tffie = 0x00000080,
+       mcntrl_reset = 0x00000100,
+       mcntrl_cdbmode = 0x00000400,
+};
+
+enum {
+       rw_bit = 1 << 0,
+       start_bit = 1 << 8,
+       stop_bit = 1 << 9,
+};
+
+#define I2C_REG_RX(a)  ((a)->ioaddr)           /* Rx FIFO reg (RO) */
+#define I2C_REG_TX(a)  ((a)->ioaddr)           /* Tx FIFO reg (WO) */
+#define I2C_REG_STS(a) ((a)->ioaddr + 0x04)    /* Status reg (RO) */
+#define I2C_REG_CTL(a) ((a)->ioaddr + 0x08)    /* Ctl reg */
+#define I2C_REG_CKL(a) ((a)->ioaddr + 0x0c)    /* Clock divider low */
+#define I2C_REG_CKH(a) ((a)->ioaddr + 0x10)    /* Clock divider high */
+#define I2C_REG_ADR(a) ((a)->ioaddr + 0x14)    /* I2C address */
+#define I2C_REG_RFL(a) ((a)->ioaddr + 0x18)    /* Rx FIFO level (RO) */
+#define I2C_REG_TFL(a) ((a)->ioaddr + 0x1c)    /* Tx FIFO level (RO) */
+#define I2C_REG_RXB(a) ((a)->ioaddr + 0x20)    /* Num of bytes Rx-ed (RO) */
+#define I2C_REG_TXB(a) ((a)->ioaddr + 0x24)    /* Num of bytes Tx-ed (RO) */
+#define I2C_REG_TXS(a) ((a)->ioaddr + 0x28)    /* Tx slave FIFO (RO) */
+#define I2C_REG_STFL(a)        ((a)->ioaddr + 0x2c)    /* Tx slave FIFO level (RO) */
+
+#define HCLK_MHZ               13
+#define I2C_CHIP_NAME          "PNX4008-I2C"
+
+#endif                         /* __ASM_ARCH_I2C_H___ */
index 5679d49..609a389 100644 (file)
@@ -100,6 +100,8 @@ static inline void wrmsrl (unsigned long msr, unsigned long long val)
 
 #define MSR_P6_PERFCTR0                0xc1
 #define MSR_P6_PERFCTR1                0xc2
+#define MSR_FSB_FREQ           0xcd
+
 
 #define MSR_IA32_BBL_CR_CTL            0x119
 
@@ -130,6 +132,9 @@ static inline void wrmsrl (unsigned long msr, unsigned long long val)
 #define MSR_IA32_PERF_STATUS           0x198
 #define MSR_IA32_PERF_CTL              0x199
 
+#define MSR_IA32_MPERF                 0xE7
+#define MSR_IA32_APERF                 0xE8
+
 #define MSR_IA32_THERM_CONTROL         0x19a
 #define MSR_IA32_THERM_INTERRUPT       0x19b
 #define MSR_IA32_THERM_STATUS          0x19c
diff --git a/include/asm-sh/atomic-irq.h b/include/asm-sh/atomic-irq.h
new file mode 100644 (file)
index 0000000..74f7943
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef __ASM_SH_ATOMIC_IRQ_H
+#define __ASM_SH_ATOMIC_IRQ_H
+
+/*
+ * To get proper branch prediction for the main line, we must branch
+ * forward to code at the end of this object's .text section, then
+ * branch back to restart the operation.
+ */
+static inline void atomic_add(int i, atomic_t *v)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       *(long *)v += i;
+       local_irq_restore(flags);
+}
+
+static inline void atomic_sub(int i, atomic_t *v)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       *(long *)v -= i;
+       local_irq_restore(flags);
+}
+
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+       unsigned long temp, flags;
+
+       local_irq_save(flags);
+       temp = *(long *)v;
+       temp += i;
+       *(long *)v = temp;
+       local_irq_restore(flags);
+
+       return temp;
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+       unsigned long temp, flags;
+
+       local_irq_save(flags);
+       temp = *(long *)v;
+       temp -= i;
+       *(long *)v = temp;
+       local_irq_restore(flags);
+
+       return temp;
+}
+
+static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       *(long *)v &= ~mask;
+       local_irq_restore(flags);
+}
+
+static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       *(long *)v |= mask;
+       local_irq_restore(flags);
+}
+
+#endif /* __ASM_SH_ATOMIC_IRQ_H */
diff --git a/include/asm-sh/atomic-llsc.h b/include/asm-sh/atomic-llsc.h
new file mode 100644 (file)
index 0000000..4b00b78
--- /dev/null
@@ -0,0 +1,107 @@
+#ifndef __ASM_SH_ATOMIC_LLSC_H
+#define __ASM_SH_ATOMIC_LLSC_H
+
+/*
+ * To get proper branch prediction for the main line, we must branch
+ * forward to code at the end of this object's .text section, then
+ * branch back to restart the operation.
+ */
+static inline void atomic_add(int i, atomic_t *v)
+{
+       unsigned long tmp;
+
+       __asm__ __volatile__ (
+"1:    movli.l @%2, %0         ! atomic_add    \n"
+"      add     %1, %0                          \n"
+"      movco.l %0, @%2                         \n"
+"      bf      1b                              \n"
+       : "=&z" (tmp)
+       : "r" (i), "r" (&v->counter)
+       : "t");
+}
+
+static inline void atomic_sub(int i, atomic_t *v)
+{
+       unsigned long tmp;
+
+       __asm__ __volatile__ (
+"1:    movli.l @%2, %0         ! atomic_sub    \n"
+"      sub     %1, %0                          \n"
+"      movco.l %0, @%2                         \n"
+"      bf      1b                              \n"
+       : "=&z" (tmp)
+       : "r" (i), "r" (&v->counter)
+       : "t");
+}
+
+/*
+ * SH-4A note:
+ *
+ * We basically get atomic_xxx_return() for free compared with
+ * atomic_xxx(). movli.l/movco.l require r0 due to the instruction
+ * encoding, so the retval is automatically set without having to
+ * do any special work.
+ */
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+       unsigned long temp;
+
+       __asm__ __volatile__ (
+"1:    movli.l @%2, %0         ! atomic_add_return     \n"
+"      add     %1, %0                                  \n"
+"      movco.l %0, @%2                                 \n"
+"      bf      1b                                      \n"
+"      synco                                           \n"
+       : "=&z" (temp)
+       : "r" (i), "r" (&v->counter)
+       : "t");
+
+       return temp;
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+       unsigned long temp;
+
+       __asm__ __volatile__ (
+"1:    movli.l @%2, %0         ! atomic_sub_return     \n"
+"      sub     %1, %0                                  \n"
+"      movco.l %0, @%2                                 \n"
+"      bf      1b                                      \n"
+"      synco                                           \n"
+       : "=&z" (temp)
+       : "r" (i), "r" (&v->counter)
+       : "t");
+
+       return temp;
+}
+
+static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
+{
+       unsigned long tmp;
+
+       __asm__ __volatile__ (
+"1:    movli.l @%2, %0         ! atomic_clear_mask     \n"
+"      and     %1, %0                                  \n"
+"      movco.l %0, @%2                                 \n"
+"      bf      1b                                      \n"
+       : "=&z" (tmp)
+       : "r" (~mask), "r" (&v->counter)
+       : "t");
+}
+
+static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
+{
+       unsigned long tmp;
+
+       __asm__ __volatile__ (
+"1:    movli.l @%2, %0         ! atomic_set_mask       \n"
+"      or      %1, %0                                  \n"
+"      movco.l %0, @%2                                 \n"
+"      bf      1b                                      \n"
+       : "=&z" (tmp)
+       : "r" (mask), "r" (&v->counter)
+       : "t");
+}
+
+#endif /* __ASM_SH_ATOMIC_LLSC_H */
index 28305c3..e12570b 100644 (file)
@@ -17,119 +17,14 @@ typedef struct { volatile int counter; } atomic_t;
 #include <linux/compiler.h>
 #include <asm/system.h>
 
-/*
- * To get proper branch prediction for the main line, we must branch
- * forward to code at the end of this object's .text section, then
- * branch back to restart the operation.
- */
-static inline void atomic_add(int i, atomic_t *v)
-{
 #ifdef CONFIG_CPU_SH4A
-       unsigned long tmp;
-
-       __asm__ __volatile__ (
-"1:    movli.l @%2, %0         ! atomic_add    \n"
-"      add     %1, %0                          \n"
-"      movco.l %0, @%2                         \n"
-"      bf      1b                              \n"
-       : "=&z" (tmp)
-       : "r" (i), "r" (&v->counter)
-       : "t");
+#include <asm/atomic-llsc.h>
 #else
-       unsigned long flags;
-
-       local_irq_save(flags);
-       *(long *)v += i;
-       local_irq_restore(flags);
-#endif
-}
-
-static inline void atomic_sub(int i, atomic_t *v)
-{
-#ifdef CONFIG_CPU_SH4A
-       unsigned long tmp;
-
-       __asm__ __volatile__ (
-"1:    movli.l @%2, %0         ! atomic_sub    \n"
-"      sub     %1, %0                          \n"
-"      movco.l %0, @%2                         \n"
-"      bf      1b                              \n"
-       : "=&z" (tmp)
-       : "r" (i), "r" (&v->counter)
-       : "t");
-#else
-       unsigned long flags;
-
-       local_irq_save(flags);
-       *(long *)v -= i;
-       local_irq_restore(flags);
+#include <asm/atomic-irq.h>
 #endif
-}
-
-/*
- * SH-4A note:
- *
- * We basically get atomic_xxx_return() for free compared with
- * atomic_xxx(). movli.l/movco.l require r0 due to the instruction
- * encoding, so the retval is automatically set without having to
- * do any special work.
- */
-static inline int atomic_add_return(int i, atomic_t *v)
-{
-       unsigned long temp;
-
-#ifdef CONFIG_CPU_SH4A
-       __asm__ __volatile__ (
-"1:    movli.l @%2, %0         ! atomic_add_return     \n"
-"      add     %1, %0                                  \n"
-"      movco.l %0, @%2                                 \n"
-"      bf      1b                                      \n"
-"      synco                                           \n"
-       : "=&z" (temp)
-       : "r" (i), "r" (&v->counter)
-       : "t");
-#else
-       unsigned long flags;
-
-       local_irq_save(flags);
-       temp = *(long *)v;
-       temp += i;
-       *(long *)v = temp;
-       local_irq_restore(flags);
-#endif
-
-       return temp;
-}
 
 #define atomic_add_negative(a, v)      (atomic_add_return((a), (v)) < 0)
 
-static inline int atomic_sub_return(int i, atomic_t *v)
-{
-       unsigned long temp;
-
-#ifdef CONFIG_CPU_SH4A
-       __asm__ __volatile__ (
-"1:    movli.l @%2, %0         ! atomic_sub_return     \n"
-"      sub     %1, %0                                  \n"
-"      movco.l %0, @%2                                 \n"
-"      bf      1b                                      \n"
-"      synco                                           \n"
-       : "=&z" (temp)
-       : "r" (i), "r" (&v->counter)
-       : "t");
-#else
-       unsigned long flags;
-
-       local_irq_save(flags);
-       temp = *(long *)v;
-       temp -= i;
-       *(long *)v = temp;
-       local_irq_restore(flags);
-#endif
-
-       return temp;
-}
-
 #define atomic_dec_return(v) atomic_sub_return(1,(v))
 #define atomic_inc_return(v) atomic_add_return(1,(v))
 
@@ -180,50 +75,6 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
 }
 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 
-static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
-{
-#ifdef CONFIG_CPU_SH4A
-       unsigned long tmp;
-
-       __asm__ __volatile__ (
-"1:    movli.l @%2, %0         ! atomic_clear_mask     \n"
-"      and     %1, %0                                  \n"
-"      movco.l %0, @%2                                 \n"
-"      bf      1b                                      \n"
-       : "=&z" (tmp)
-       : "r" (~mask), "r" (&v->counter)
-       : "t");
-#else
-       unsigned long flags;
-
-       local_irq_save(flags);
-       *(long *)v &= ~mask;
-       local_irq_restore(flags);
-#endif
-}
-
-static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
-{
-#ifdef CONFIG_CPU_SH4A
-       unsigned long tmp;
-
-       __asm__ __volatile__ (
-"1:    movli.l @%2, %0         ! atomic_set_mask       \n"
-"      or      %1, %0                                  \n"
-"      movco.l %0, @%2                                 \n"
-"      bf      1b                                      \n"
-       : "=&z" (tmp)
-       : "r" (mask), "r" (&v->counter)
-       : "t");
-#else
-       unsigned long flags;
-
-       local_irq_save(flags);
-       *(long *)v |= mask;
-       local_irq_restore(flags);
-#endif
-}
-
 /* Atomic operations are already serializing on SH */
 #define smp_mb__before_atomic_dec()    barrier()
 #define smp_mb__after_atomic_dec()     barrier()
index 1b4fc52..2f89dd0 100644 (file)
@@ -1,19 +1,54 @@
 #ifndef __ASM_SH_BUG_H
 #define __ASM_SH_BUG_H
 
-
 #ifdef CONFIG_BUG
-/*
- * Tell the user there is some problem.
- */
-#define BUG() do { \
-       printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-       *(volatile int *)0 = 0; \
+
+struct bug_frame {
+       unsigned short  opcode;
+       unsigned short  line;
+       const char      *file;
+       const char      *func;
+};
+
+struct pt_regs;
+
+extern void handle_BUG(struct pt_regs *);
+
+#define TRAPA_BUG_OPCODE       0xc33e  /* trapa #0x3e */
+
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+
+#define BUG()                                          \
+do {                                                   \
+       __asm__ __volatile__ (                          \
+               ".align 2\n\t"                          \
+               ".short %O0\n\t"                        \
+               ".short %O1\n\t"                        \
+               ".long  %O2\n\t"                        \
+               ".long  %O3\n\t"                        \
+               :                                       \
+               : "n" (TRAPA_BUG_OPCODE),               \
+                 "i" (__LINE__), "X" (__FILE__),       \
+                 "X" (__FUNCTION__));                  \
+} while (0)
+
+#else
+
+#define BUG()                                  \
+do {                                           \
+       __asm__ __volatile__ (                  \
+               ".align 2\n\t"                  \
+               ".short %O0\n\t"                \
+               :                               \
+               : "n" (TRAPA_BUG_OPCODE));      \
 } while (0)
 
+#endif /* CONFIG_DEBUG_BUGVERBOSE */
+
 #define HAVE_ARCH_BUG
-#endif
+
+#endif /* CONFIG_BUG */
 
 #include <asm-generic/bug.h>
 
-#endif
+#endif /* __ASM_SH_BUG_H */
index 795047d..a294997 100644 (file)
@@ -16,9 +16,8 @@
 
 static void __init check_bugs(void)
 {
-       extern char *get_cpu_subtype(void);
        extern unsigned long loops_per_jiffy;
-       char *p= &init_utsname()->machine[2]; /* "sh" */
+       char *p = &init_utsname()->machine[2]; /* "sh" */
 
        cpu_data->loops_per_jiffy = loops_per_jiffy;
 
@@ -40,6 +39,15 @@ static void __init check_bugs(void)
                *p++ = '4';
                *p++ = 'a';
                break;
+       case CPU_SH73180 ... CPU_SH7722:
+               *p++ = '4';
+               *p++ = 'a';
+               *p++ = 'l';
+               *p++ = '-';
+               *p++ = 'd';
+               *p++ = 's';
+               *p++ = 'p';
+               break;
        default:
                *p++ = '?';
                *p++ = '!';
index d44344c..4bc8357 100644 (file)
@@ -34,25 +34,26 @@ asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum);
  */
 
 asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
-                                         int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
+                                           int len, __wsum sum,
+                                           int *src_err_ptr, int *dst_err_ptr);
 
 /*
  *     Note: when you get a NULL pointer exception here this means someone
- *     passed in an incorrect kernel address to one of these functions. 
- *     
- *     If you use these functions directly please don't forget the 
+ *     passed in an incorrect kernel address to one of these functions.
+ *
+ *     If you use these functions directly please don't forget the
  *     access_ok().
  */
-static __inline__
+static inline
 __wsum csum_partial_copy_nocheck(const void *src, void *dst,
-                                       int len, __wsum sum)
+                                int len, __wsum sum)
 {
-       return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
+       return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL);
 }
 
-static __inline__
+static inline
 __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
-                                               int len, __wsum sum, int *err_ptr)
+                                  int len, __wsum sum, int *err_ptr)
 {
        return csum_partial_copy_generic((__force const void *)src, dst,
                                        len, sum, err_ptr, NULL);
@@ -62,7 +63,7 @@ __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
  *     Fold a partial checksum
  */
 
-static __inline__ __sum16 csum_fold(__wsum sum)
+static inline __sum16 csum_fold(__wsum sum)
 {
        unsigned int __dummy;
        __asm__("swap.w %0, %1\n\t"
@@ -85,7 +86,7 @@ static __inline__ __sum16 csum_fold(__wsum sum)
  *      i386 version by Jorge Cwik <jorge@laser.satlink.net>, adapted
  *      for linux by * Arnt Gulbrandsen.
  */
-static __inline__ __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
 {
        unsigned int sum, __dummy0, __dummy1;
 
@@ -113,10 +114,10 @@ static __inline__ __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
        return  csum_fold(sum);
 }
 
-static __inline__ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
-                                                  unsigned short len,
-                                                  unsigned short proto,
-                                                  __wsum sum)
+static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
+                                       unsigned short len,
+                                       unsigned short proto,
+                                       __wsum sum)
 {
 #ifdef __LITTLE_ENDIAN__
        unsigned long len_proto = (proto + len) << 8;
@@ -132,6 +133,7 @@ static __inline__ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
                : "=r" (sum), "=r" (len_proto)
                : "r" (daddr), "r" (saddr), "1" (len_proto), "0" (sum)
                : "t");
+
        return sum;
 }
 
@@ -139,30 +141,28 @@ static __inline__ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
  * computes the checksum of the TCP/UDP pseudo-header
  * returns a 16-bit checksum, already complemented
  */
-static __inline__ __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
-                                                      unsigned short len,
-                                                      unsigned short proto,
-                                                      __wsum sum)
+static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+                                       unsigned short len,
+                                       unsigned short proto,
+                                       __wsum sum)
 {
-       return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+       return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
 }
 
 /*
  * this routine is used for miscellaneous IP-like checksums, mainly
  * in icmp.c
  */
-
-static __inline__ __sum16 ip_compute_csum(const void *buff, int len)
+static inline __sum16 ip_compute_csum(const void *buff, int len)
 {
-    return csum_fold (csum_partial(buff, len, 0));
+    return csum_fold(csum_partial(buff, len, 0));
 }
 
 #define _HAVE_ARCH_IPV6_CSUM
-#ifdef CONFIG_IPV6
-static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
-                                         const struct in6_addr *daddr,
-                                         __u32 len, unsigned short proto,
-                                         __wsum sum)
+static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+                                     const struct in6_addr *daddr,
+                                     __u32 len, unsigned short proto,
+                                     __wsum sum)
 {
        unsigned int __dummy;
        __asm__("clrt\n\t"
@@ -187,22 +187,21 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
                "movt   %1\n\t"
                "add    %1, %0\n"
                : "=r" (sum), "=&r" (__dummy)
-               : "r" (saddr), "r" (daddr), 
+               : "r" (saddr), "r" (daddr),
                  "r" (htonl(len)), "r" (htonl(proto)), "0" (sum)
                : "t");
 
        return csum_fold(sum);
 }
-#endif
 
-/* 
+/*
  *     Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static __inline__ __wsum csum_and_copy_to_user (const void *src,
-                                                     void __user *dst,
-                                                     int len, __wsum sum,
-                                                     int *err_ptr)
+static inline __wsum csum_and_copy_to_user(const void *src,
+                                          void __user *dst,
+                                          int len, __wsum sum,
+                                          int *err_ptr)
 {
        if (access_ok(VERIFY_WRITE, dst, len))
                return csum_partial_copy_generic((__force const void *)src,
index 6e9c7e6..f92b20a 100644 (file)
@@ -22,7 +22,7 @@
 #define CCR_CACHE_ICE  0x0100  /* Instruction Cache Enable */
 #define CCR_CACHE_ICI  0x0800  /* IC Invalidate */
 #define CCR_CACHE_IIX  0x8000  /* IC Index Enable */
-#ifndef CONFIG_CPU_SUBTYPE_SH7780
+#ifndef CONFIG_CPU_SH4A
 #define CCR_CACHE_EMODE        0x80000000      /* EMODE Enable */
 #endif
 
index ef2b9b1..602d061 100644 (file)
@@ -10,7 +10,7 @@
 #ifndef __ASM_CPU_SH4_FREQ_H
 #define __ASM_CPU_SH4_FREQ_H
 
-#if defined(CONFIG_CPU_SUBTYPE_SH73180)
+#if defined(CONFIG_CPU_SUBTYPE_SH73180) || defined(CONFIG_CPU_SUBTYPE_SH7722)
 #define FRQCR                  0xa4150000
 #elif defined(CONFIG_CPU_SUBTYPE_SH7780)
 #define        FRQCR                   0xffc80000
index 37ab0c1..8d0867b 100644 (file)
@@ -67,7 +67,7 @@ static inline dma_addr_t dma_map_single(struct device *dev,
        if (dev->bus == &pci_bus_type)
                return virt_to_bus(ptr);
 #endif
-       dma_cache_sync(ptr, size, dir);
+       dma_cache_sync(dev, ptr, size, dir);
 
        return virt_to_bus(ptr);
 }
@@ -81,7 +81,7 @@ static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
 
        for (i = 0; i < nents; i++) {
 #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-               dma_cache_sync(page_address(sg[i].page) + sg[i].offset,
+               dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
                               sg[i].length, dir);
 #endif
                sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset;
@@ -112,7 +112,7 @@ static inline void dma_sync_single(struct device *dev, dma_addr_t dma_handle,
        if (dev->bus == &pci_bus_type)
                return;
 #endif
-       dma_cache_sync(bus_to_virt(dma_handle), size, dir);
+       dma_cache_sync(dev, bus_to_virt(dma_handle), size, dir);
 }
 
 static inline void dma_sync_single_range(struct device *dev,
@@ -124,7 +124,7 @@ static inline void dma_sync_single_range(struct device *dev,
        if (dev->bus == &pci_bus_type)
                return;
 #endif
-       dma_cache_sync(bus_to_virt(dma_handle) + offset, size, dir);
+       dma_cache_sync(dev, bus_to_virt(dma_handle) + offset, size, dir);
 }
 
 static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg,
@@ -134,7 +134,7 @@ static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg,
 
        for (i = 0; i < nelems; i++) {
 #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-               dma_cache_sync(page_address(sg[i].page) + sg[i].offset,
+               dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
                               sg[i].length, dir);
 #endif
                sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset;
index fd57608..bff965e 100644 (file)
@@ -37,7 +37,8 @@
 # define ONCHIP_NR_IRQS 144
 #elif defined(CONFIG_CPU_SUBTYPE_SH7300) || \
       defined(CONFIG_CPU_SUBTYPE_SH73180) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7343)
+      defined(CONFIG_CPU_SUBTYPE_SH7343) || \
+      defined(CONFIG_CPU_SUBTYPE_SH7722)
 # define ONCHIP_NR_IRQS 109
 #elif defined(CONFIG_CPU_SUBTYPE_SH7780)
 # define ONCHIP_NR_IRQS 111
@@ -79,6 +80,8 @@
 # define OFFCHIP_NR_IRQS 16
 #elif defined(CONFIG_SH_7343_SOLUTION_ENGINE)
 # define OFFCHIP_NR_IRQS 12
+#elif defined(CONFIG_SH_7722_SOLUTION_ENGINE)
+# define OFFCHIP_NR_IRQS 14
 #elif defined(CONFIG_SH_UNKNOWN)
 # define OFFCHIP_NR_IRQS 16    /* Must also be last */
 #else
index c84901d..036ca28 100644 (file)
@@ -508,16 +508,50 @@ struct vm_area_struct;
 extern void update_mmu_cache(struct vm_area_struct * vma,
                             unsigned long address, pte_t pte);
 
-/* Encode and de-code a swap entry */
 /*
+ * Encode and de-code a swap entry
+ *
+ * Constraints:
+ *     _PAGE_FILE at bit 0
+ *     _PAGE_PRESENT at bit 8
+ *     _PAGE_PROTNONE at bit 9
+ *
+ * For the normal case, we encode the swap type into bits 0:7 and the
+ * swap offset into bits 10:30. For the 64-bit PTE case, we keep the
+ * preserved bits in the low 32-bits and use the upper 32 as the swap
+ * offset (along with a 5-bit type), following the same approach as x86
+ * PAE. This keeps the logic quite simple, and allows for a full 32
+ * PTE_FILE_MAX_BITS, as opposed to the 29-bits we're constrained with
+ * in the pte_low case.
+ *
+ * As is evident by the Alpha code, if we ever get a 64-bit unsigned
+ * long (swp_entry_t) to match up with the 64-bit PTEs, this all becomes
+ * much cleaner..
+ *
  * NOTE: We should set ZEROs at the position of _PAGE_PRESENT
  *       and _PAGE_PROTNONE bits
  */
-#define __swp_type(x)          ((x).val & 0xff)
-#define __swp_offset(x)                ((x).val >> 10)
-#define __swp_entry(type, offset) ((swp_entry_t) { (type) | ((offset) << 10) })
-#define __pte_to_swp_entry(pte)        ((swp_entry_t) { pte_val(pte) >> 1 })
-#define __swp_entry_to_pte(x)  ((pte_t) { (x).val << 1 })
+#ifdef CONFIG_X2TLB
+#define __swp_type(x)                  ((x).val & 0x1f)
+#define __swp_offset(x)                        ((x).val >> 5)
+#define __swp_entry(type, offset)      ((swp_entry_t){ (type) | (offset) << 5})
+#define __pte_to_swp_entry(pte)                ((swp_entry_t){ (pte).pte_high })
+#define __swp_entry_to_pte(x)          ((pte_t){ 0, (x).val })
+
+/*
+ * Encode and decode a nonlinear file mapping entry
+ */
+#define pte_to_pgoff(pte)              ((pte).pte_high)
+#define pgoff_to_pte(off)              ((pte_t) { _PAGE_FILE, (off) })
+
+#define PTE_FILE_MAX_BITS              32
+#else
+#define __swp_type(x)                  ((x).val & 0xff)
+#define __swp_offset(x)                        ((x).val >> 10)
+#define __swp_entry(type, offset)      ((swp_entry_t){(type) | (offset) <<10})
+
+#define __pte_to_swp_entry(pte)                ((swp_entry_t) { pte_val(pte) >> 1 })
+#define __swp_entry_to_pte(x)          ((pte_t) { (x).val << 1 })
 
 /*
  * Encode and decode a nonlinear file mapping entry
@@ -525,6 +559,7 @@ extern void update_mmu_cache(struct vm_area_struct * vma,
 #define PTE_FILE_MAX_BITS      29
 #define pte_to_pgoff(pte)      (pte_val(pte) >> 1)
 #define pgoff_to_pte(off)      ((pte_t) { ((off) << 1) | _PAGE_FILE })
+#endif
 
 typedef pte_t *pte_addr_t;
 
index 6f1dd7c..e29f2ab 100644 (file)
@@ -27,6 +27,8 @@
 #define CCN_CVR                0xff000040
 #define CCN_PRR                0xff000044
 
+const char *get_cpu_subtype(void);
+
 /*
  *  CPU type and hardware bug flags. Kept separately for each CPU.
  *
@@ -52,8 +54,10 @@ enum cpu_type {
        CPU_SH7760, CPU_ST40RA, CPU_ST40GX1, CPU_SH4_202, CPU_SH4_501,
 
        /* SH-4A types */
-       CPU_SH73180, CPU_SH7343, CPU_SH7770, CPU_SH7780, CPU_SH7781,
-       CPU_SH7785,
+       CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785,
+
+       /* SH4AL-DSP types */
+       CPU_SH73180, CPU_SH7343, CPU_SH7722,
 
        /* Unknown subtype */
        CPU_SH_NONE
index dfc6bad..4903f9e 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
+#include <linux/platform_device.h>
 
 struct push_switch {
        /* switch state */
@@ -12,6 +13,8 @@ struct push_switch {
        struct timer_list       debounce;
        /* workqueue */
        struct work_struct      work;
+       /* platform device, for workqueue handler */
+       struct platform_device  *pdev;
 };
 
 struct push_switch_platform_info {
index 952783d..3227bc9 100644 (file)
@@ -189,6 +189,7 @@ static inline unsigned int cpuid_edx(unsigned int op)
 
 #define MSR_IA32_PERFCTR0      0xc1
 #define MSR_IA32_PERFCTR1      0xc2
+#define MSR_FSB_FREQ           0xcd
 
 #define MSR_MTRRcap            0x0fe
 #define MSR_IA32_BBL_CR_CTL        0x119
@@ -311,6 +312,9 @@ static inline unsigned int cpuid_edx(unsigned int op)
 #define MSR_IA32_PERF_STATUS           0x198
 #define MSR_IA32_PERF_CTL              0x199
 
+#define MSR_IA32_MPERF                 0xE7
+#define MSR_IA32_APERF                 0xE8
+
 #define MSR_IA32_THERM_CONTROL         0x19a
 #define MSR_IA32_THERM_INTERRUPT       0x19b
 #define MSR_IA32_THERM_STATUS          0x19c
index 4ea39fe..7f008f6 100644 (file)
@@ -172,6 +172,8 @@ extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
                                   unsigned int relation);
 
 
+extern int cpufreq_driver_getavg(struct cpufreq_policy *policy);
+
 int cpufreq_register_governor(struct cpufreq_governor *governor);
 void cpufreq_unregister_governor(struct cpufreq_governor *governor);
 
@@ -204,6 +206,7 @@ struct cpufreq_driver {
        unsigned int    (*get)  (unsigned int cpu);
 
        /* optional */
+       unsigned int (*getavg)  (unsigned int cpu);
        int     (*exit)         (struct cpufreq_policy *policy);
        int     (*suspend)      (struct cpufreq_policy *policy, pm_message_t pmsg);
        int     (*resume)       (struct cpufreq_policy *policy);
index c8f8df2..937da70 100644 (file)
@@ -26,9 +26,9 @@
 
 /* --- Defines for bit-adapters ---------------------------------------        */
 /*
- * This struct contains the hw-dependent functions of bit-style adapters to 
+ * This struct contains the hw-dependent functions of bit-style adapters to
  * manipulate the line states, and to init any hw-specific features. This is
- * only used if you have more than one hw-type of adapter running. 
+ * only used if you have more than one hw-type of adapter running.
  */
 struct i2c_algo_bit_data {
        void *data;             /* private data for lowlevel routines */
@@ -44,6 +44,5 @@ struct i2c_algo_bit_data {
 };
 
 int i2c_bit_add_bus(struct i2c_adapter *);
-int i2c_bit_del_bus(struct i2c_adapter *);
 
 #endif /* _LINUX_I2C_ALGO_BIT_H */
diff --git a/include/linux/i2c-algo-ite.h b/include/linux/i2c-algo-ite.h
deleted file mode 100644 (file)
index 0073fe9..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-algo-ite.h i2c driver algorithms for ITE IIC adapters                 */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 1995-97 Simon G. Vogl
-                   1998-99 Hans Berglund
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
-   Frodo Looijaard <frodol@dds.nl> */
-
-/* Modifications by MontaVista Software, 2001
-   Changes made to support the ITE IIC peripheral */
-
-
-#ifndef I2C_ALGO_ITE_H
-#define I2C_ALGO_ITE_H 1
-
-#include <linux/types.h>
-
-/* Example of a sequential read request:
-       struct i2c_iic_msg s_msg; 
-
-       s_msg.addr=device_address;
-       s_msg.len=length;
-       s_msg.buf=buffer;
-       s_msg.waddr=word_address;
-       ioctl(file,I2C_SREAD, &s_msg);
- */
-#define I2C_SREAD      0x780   /* SREAD ioctl command */
-
-struct i2c_iic_msg {
-       __u16 addr;     /* device address */
-       __u16 waddr;    /* word address */
-       short len;      /* msg length */
-       char *buf;      /* pointer to msg data */
-};
-
-#ifdef __KERNEL__
-struct i2c_adapter;
-
-struct i2c_algo_iic_data {
-       void *data;             /* private data for lolevel routines    */
-       void (*setiic) (void *data, int ctl, int val);
-       int  (*getiic) (void *data, int ctl);
-       int  (*getown) (void *data);
-       int  (*getclock) (void *data);
-       void (*waitforpin) (void);     
-
-       /* local settings */
-       int udelay;
-       int mdelay;
-       int timeout;
-};
-
-int i2c_iic_add_bus(struct i2c_adapter *);
-int i2c_iic_del_bus(struct i2c_adapter *);
-#endif /* __KERNEL__ */
-#endif /* I2C_ALGO_ITE_H */
index 226693e..fce47c0 100644 (file)
@@ -10,6 +10,5 @@ struct i2c_algo_pca_data {
 };
 
 int i2c_pca_add_bus(struct i2c_adapter *);
-int i2c_pca_del_bus(struct i2c_adapter *);
 
 #endif /* _LINUX_I2C_ALGO_PCA_H */
index 9908f3f..994eb86 100644 (file)
@@ -31,7 +31,7 @@ struct i2c_algo_pcf_data {
        int  (*getpcf) (void *data, int ctl);
        int  (*getown) (void *data);
        int  (*getclock) (void *data);
-       void (*waitforpin) (void);     
+       void (*waitforpin) (void);
 
        /* local settings */
        int udelay;
@@ -39,6 +39,5 @@ struct i2c_algo_pcf_data {
 };
 
 int i2c_pcf_add_bus(struct i2c_adapter *);
-int i2c_pcf_del_bus(struct i2c_adapter *);
 
 #endif /* _LINUX_I2C_ALGO_PCF_H */
index 4a0113d..3b77150 100644 (file)
@@ -22,6 +22,5 @@ struct i2c_algo_sgi_data {
 };
 
 int i2c_sgi_add_bus(struct i2c_adapter *);
-int i2c_sgi_del_bus(struct i2c_adapter *);
 
 #endif /* I2C_ALGO_SGI_H */
index 0f4cf34..7ae3c33 100644 (file)
@@ -1,7 +1,7 @@
 /* ------------------------------------------------------------------------- */
-/*                                                                          */
+/*                                                                          */
 /* i2c-id.h - identifier values for i2c drivers and adapters                */
-/*                                                                          */
+/*                                                                          */
 /* ------------------------------------------------------------------------- */
 /*   Copyright (C) 1995-1999 Simon G. Vogl
 
 #define I2C_DRIVERID_SAA7120   11      /* video encoder                */
 #define I2C_DRIVERID_SAA7121   12      /* video encoder                */
 #define I2C_DRIVERID_SAA7185B  13      /* video encoder                */
-#define I2C_DRIVERID_CH7003    14      /* digital pc to tv encoder     */
+#define I2C_DRIVERID_CH7003    14      /* digital pc to tv encoder     */
 #define I2C_DRIVERID_PCF8574A  15      /* i2c expander - 8 bit in/out  */
 #define I2C_DRIVERID_PCF8582C  16      /* eeprom                       */
-#define I2C_DRIVERID_AT24Cxx   17      /* eeprom 1/2/4/8/16 K          */
+#define I2C_DRIVERID_AT24Cxx   17      /* eeprom 1/2/4/8/16 K          */
 #define I2C_DRIVERID_TEA6300   18      /* audio mixer                  */
 #define I2C_DRIVERID_BT829     19      /* pc to tv encoder             */
 #define I2C_DRIVERID_TDA9850   20      /* audio mixer                  */
@@ -82,9 +82,8 @@
 #define I2C_DRIVERID_STM41T00  52      /* real time clock              */
 #define I2C_DRIVERID_UDA1342   53      /* UDA1342 audio codec          */
 #define I2C_DRIVERID_ADV7170   54      /* video encoder                */
-#define I2C_DRIVERID_RADEON    55      /* I2C bus on Radeon boards     */
 #define I2C_DRIVERID_MAX1617   56      /* temp sensor                  */
-#define I2C_DRIVERID_SAA7191   57      /* video encoder                */
+#define I2C_DRIVERID_SAA7191   57      /* video decoder                */
 #define I2C_DRIVERID_INDYCAM   58      /* SGI IndyCam                  */
 #define I2C_DRIVERID_BT832     59      /* CMOS camera video processor  */
 #define I2C_DRIVERID_TDA9887   60      /* TDA988x IF-PLL demodulator   */
 #define I2C_DRIVERID_ADM1021 1008
 #define I2C_DRIVERID_ADM9240 1009
 #define I2C_DRIVERID_LTC1710 1010
-#define I2C_DRIVERID_ICSPLL 1012
 #define I2C_DRIVERID_BT869 1013
 #define I2C_DRIVERID_MAXILIFE 1014
 #define I2C_DRIVERID_MATORB 1015
  * ---- Adapter types ----------------------------------------------------
  */
 
-/* --- Bit algorithm adapters                                          */
+/* --- Bit algorithm adapters                                          */
 #define I2C_HW_B_LP            0x010000 /* Parallel port Philips style */
 #define I2C_HW_B_SER           0x010002 /* Serial line interface */
 #define I2C_HW_B_BT848         0x010005 /* BT848 video boards */
 /* --- MPC8xx PowerPC adapters                                         */
 #define I2C_HW_MPC8XX_EPON     0x110000 /* Eponymous MPC8xx I2C adapter */
 
-/* --- ITE based algorithms                                            */
-#define I2C_HW_I_IIC           0x080000 /* controller on the ITE */
-
 /* --- PowerPC on-chip adapters                                                */
 #define I2C_HW_OCP             0x120000 /* IBM on-chip I2C adapter */
 
diff --git a/include/linux/i2c-pnx.h b/include/linux/i2c-pnx.h
new file mode 100644 (file)
index 0000000..e6e9c81
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Header file for I2C support on PNX010x/4008.
+ *
+ * Author: Dennis Kovalev <dkovalev@ru.mvista.com>
+ *
+ * 2004-2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef __I2C_PNX_H__
+#define __I2C_PNX_H__
+
+#include <asm/arch/i2c.h>
+
+struct i2c_pnx_mif {
+       int                     ret;            /* Return value */
+       int                     mode;           /* Interface mode */
+       struct completion       complete;       /* I/O completion */
+       struct timer_list       timer;          /* Timeout */
+       char *                  buf;            /* Data buffer */
+       int                     len;            /* Length of data buffer */
+};
+
+struct i2c_pnx_algo_data {
+       u32                     base;
+       u32                     ioaddr;
+       int                     irq;
+       struct i2c_pnx_mif      mif;
+       int                     last;
+};
+
+struct i2c_pnx_data {
+       int (*suspend) (struct platform_device *pdev, pm_message_t state);
+       int (*resume) (struct platform_device *pdev);
+       u32 (*calculate_input_freq) (struct platform_device *pdev);
+       int (*set_clock_run) (struct platform_device *pdev);
+       int (*set_clock_stop) (struct platform_device *pdev);
+       struct i2c_adapter *adapter;
+};
+
+#endif /* __I2C_PNX_H__ */
index 9b5d047..71e50d3 100644 (file)
@@ -1,7 +1,7 @@
 /* ------------------------------------------------------------------------- */
-/*                                                                          */
+/*                                                                          */
 /* i2c.h - definitions for the i2c-bus interface                            */
-/*                                                                          */
+/*                                                                          */
 /* ------------------------------------------------------------------------- */
 /*   Copyright (C) 1995-2000 Simon G. Vogl
 
@@ -27,7 +27,7 @@
 #define _LINUX_I2C_H
 
 #include <linux/types.h>
-#ifdef __KERNEL__ 
+#ifdef __KERNEL__
 #include <linux/module.h>
 #include <linux/i2c-id.h>
 #include <linux/mod_devicetable.h>
@@ -53,8 +53,8 @@ union i2c_smbus_data;
 
 /*
  * The master routines are the ones normally used to transmit data to devices
- * on a bus (or read from them). Apart from two basic transfer functions to 
- * transmit one message at a time, a more complex version can be used to 
+ * on a bus (or read from them). Apart from two basic transfer functions to
+ * transmit one message at a time, a more complex version can be used to
  * transmit an arbitrary number of messages without interruption.
  */
 extern int i2c_master_send(struct i2c_client *,const char* ,int);
@@ -67,10 +67,10 @@ extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 
 /* This is the very generalized SMBus access routine. You probably do not
    want to use this, though; one of the functions below may be much easier,
-   and probably just as fast. 
+   and probably just as fast.
    Note that we use i2c_adapter here, because you do not need a specific
    smbus adapter to call this function. */
-extern s32 i2c_smbus_xfer (struct i2c_adapter * adapter, u16 addr, 
+extern s32 i2c_smbus_xfer (struct i2c_adapter * adapter, u16 addr,
                            unsigned short flags,
                            char read_write, u8 command, int size,
                            union i2c_smbus_data * data);
@@ -112,14 +112,14 @@ struct i2c_driver {
 
        /* Notifies the driver that a new bus has appeared. This routine
         * can be used by the driver to test if the bus meets its conditions
-        * & seek for the presence of the chip(s) it supports. If found, it 
+        * & seek for the presence of the chip(s) it supports. If found, it
         * registers the client(s) that are on the bus to the i2c admin. via
         * i2c_attach_client.
         */
        int (*attach_adapter)(struct i2c_adapter *);
        int (*detach_adapter)(struct i2c_adapter *);
 
-       /* tells the driver that a client is about to be deleted & gives it 
+       /* tells the driver that a client is about to be deleted & gives it
         * the chance to remove its private data. Also, if the client struct
         * has been dynamically allocated by the driver in the function above,
         * it must be freed here.
@@ -139,13 +139,13 @@ struct i2c_driver {
 #define I2C_NAME_SIZE  50
 
 /*
- * i2c_client identifies a single device (i.e. chip) that is connected to an 
+ * i2c_client identifies a single device (i.e. chip) that is connected to an
  * i2c bus. The behaviour is defined by the routines of the driver. This
  * function is mainly used for lookup & other admin. functions.
  */
 struct i2c_client {
        unsigned int flags;             /* div., see below              */
-       unsigned short addr;            /* chip address - NOTE: 7bit    */
+       unsigned short addr;            /* chip address - NOTE: 7bit    */
                                        /* addresses are stored in the  */
                                        /* _LOWER_ 7 bits               */
        struct i2c_adapter *adapter;    /* the adapter we sit on        */
@@ -182,14 +182,14 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data)
  */
 struct i2c_algorithm {
        /* If an adapter algorithm can't do I2C-level access, set master_xfer
-          to NULL. If an adapter algorithm can do SMBus access, set 
+          to NULL. If an adapter algorithm can do SMBus access, set
           smbus_xfer. If set to NULL, the SMBus protocol is simulated
           using common I2C messages */
        /* master_xfer should return the number of messages successfully
           processed, or a negative value on error */
-       int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs, 
+       int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs,
                           int num);
-       int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, 
+       int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
                           unsigned short flags, char read_write,
                           u8 command, int size, union i2c_smbus_data * data);
 
@@ -216,6 +216,7 @@ struct i2c_adapter {
        int (*client_unregister)(struct i2c_client *);
 
        /* data fields that are valid for all devices   */
+       u8 level;                       /* nesting level for lockdep */
        struct mutex bus_lock;
        struct mutex clist_lock;
 
@@ -316,7 +317,7 @@ extern int i2c_check_addr (struct i2c_adapter *adapter, int addr);
  * It will only call found_proc if some client is connected at the
  * specific address (unless a 'force' matched);
  */
-extern int i2c_probe(struct i2c_adapter *adapter, 
+extern int i2c_probe(struct i2c_adapter *adapter,
                struct i2c_client_address_data *address_data,
                int (*found_proc) (struct i2c_adapter *, int, int));
 
@@ -352,15 +353,15 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap)
  */
 struct i2c_msg {
        __u16 addr;     /* slave address                        */
-       __u16 flags;            
+       __u16 flags;
 #define I2C_M_TEN      0x10    /* we have a ten bit chip address       */
 #define I2C_M_RD       0x01
 #define I2C_M_NOSTART  0x4000
 #define I2C_M_REV_DIR_ADDR     0x2000
 #define I2C_M_IGNORE_NAK       0x1000
 #define I2C_M_NO_RD_ACK                0x0800
-       __u16 len;              /* msg length                           */
-       __u8 *buf;              /* pointer to msg data                  */
+       __u16 len;              /* msg length                           */
+       __u8 *buf;              /* pointer to msg data                  */
 };
 
 /* To determine what functionality is present */
@@ -370,16 +371,16 @@ struct i2c_msg {
 #define I2C_FUNC_PROTOCOL_MANGLING     0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
 #define I2C_FUNC_SMBUS_HWPEC_CALC      0x00000008 /* SMBus 2.0 */
 #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
-#define I2C_FUNC_SMBUS_QUICK           0x00010000 
-#define I2C_FUNC_SMBUS_READ_BYTE       0x00020000 
-#define I2C_FUNC_SMBUS_WRITE_BYTE      0x00040000 
-#define I2C_FUNC_SMBUS_READ_BYTE_DATA  0x00080000 
-#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 
-#define I2C_FUNC_SMBUS_READ_WORD_DATA  0x00200000 
-#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 
-#define I2C_FUNC_SMBUS_PROC_CALL       0x00800000 
-#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 
-#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 
+#define I2C_FUNC_SMBUS_QUICK           0x00010000
+#define I2C_FUNC_SMBUS_READ_BYTE       0x00020000
+#define I2C_FUNC_SMBUS_WRITE_BYTE      0x00040000
+#define I2C_FUNC_SMBUS_READ_BYTE_DATA  0x00080000
+#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
+#define I2C_FUNC_SMBUS_READ_WORD_DATA  0x00200000
+#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
+#define I2C_FUNC_SMBUS_PROC_CALL       0x00800000
+#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
+#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
 #define I2C_FUNC_SMBUS_READ_I2C_BLOCK  0x04000000 /* I2C-like block xfer  */
 #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
 #define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2         0x10000000 /* I2C-like block xfer  */
@@ -406,10 +407,10 @@ struct i2c_msg {
                              I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
                              I2C_FUNC_SMBUS_I2C_BLOCK)
 
-/* 
- * Data for SMBus Messages 
+/*
+ * Data for SMBus Messages
  */
-#define I2C_SMBUS_BLOCK_MAX    32      /* As specified in SMBus standard */    
+#define I2C_SMBUS_BLOCK_MAX    32      /* As specified in SMBus standard */
 union i2c_smbus_data {
        __u8 byte;
        __u16 word;
@@ -421,11 +422,11 @@ union i2c_smbus_data {
 #define I2C_SMBUS_READ 1
 #define I2C_SMBUS_WRITE        0
 
-/* SMBus transaction types (size parameter in the above functions) 
+/* SMBus transaction types (size parameter in the above functions)
    Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
 #define I2C_SMBUS_QUICK                    0
 #define I2C_SMBUS_BYTE             1
-#define I2C_SMBUS_BYTE_DATA        2 
+#define I2C_SMBUS_BYTE_DATA        2
 #define I2C_SMBUS_WORD_DATA        3
 #define I2C_SMBUS_PROC_CALL        4
 #define I2C_SMBUS_BLOCK_DATA       5
@@ -434,15 +435,15 @@ union i2c_smbus_data {
 
 
 /* ----- commands for the ioctl like i2c_command call:
- * note that additional calls are defined in the algorithm and hw 
- *     dependent layers - these can be listed here, or see the 
+ * note that additional calls are defined in the algorithm and hw
+ *     dependent layers - these can be listed here, or see the
  *     corresponding header files.
  */
                                /* -> bit-adapter specific ioctls       */
 #define I2C_RETRIES    0x0701  /* number of times a device address      */
                                /* should be polled when not            */
-                                /* acknowledging                       */
-#define I2C_TIMEOUT    0x0702  /* set timeout - call with int          */
+                                /* acknowledging                       */
+#define I2C_TIMEOUT    0x0702  /* set timeout - call with int          */
 
 
 /* this is for i2c-dev.c       */
index 4600093..6b0648c 100644 (file)
@@ -44,8 +44,11 @@ typedef struct {
 #define SEQLOCK_UNLOCKED \
                 __SEQLOCK_UNLOCKED(old_style_seqlock_init)
 
-#define seqlock_init(x) \
-               do { *(x) = (seqlock_t) __SEQLOCK_UNLOCKED(x); } while (0)
+#define seqlock_init(x)                                        \
+       do {                                            \
+               (x)->sequence = 0;                      \
+               spin_lock_init(&(x)->lock);             \
+       } while (0)
 
 #define DEFINE_SEQLOCK(x) \
                seqlock_t x = __SEQLOCK_UNLOCKED(x)
index a01abdd..823215d 100644 (file)
@@ -55,6 +55,7 @@ static void queue_process(struct work_struct *work)
        struct netpoll_info *npinfo =
                container_of(work, struct netpoll_info, tx_work.work);
        struct sk_buff *skb;
+       unsigned long flags;
 
        while ((skb = skb_dequeue(&npinfo->txq))) {
                struct net_device *dev = skb->dev;
@@ -64,15 +65,19 @@ static void queue_process(struct work_struct *work)
                        continue;
                }
 
-               netif_tx_lock_bh(dev);
+               local_irq_save(flags);
+               netif_tx_lock(dev);
                if (netif_queue_stopped(dev) ||
                    dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
                        skb_queue_head(&npinfo->txq, skb);
-                       netif_tx_unlock_bh(dev);
+                       netif_tx_unlock(dev);
+                       local_irq_restore(flags);
 
                        schedule_delayed_work(&npinfo->tx_work, HZ/10);
                        return;
                }
+               netif_tx_unlock(dev);
+               local_irq_restore(flags);
        }
 }
 
index 95949b6..9d77300 100644 (file)
@@ -93,4 +93,12 @@ endmenu
 
 endif
 
+config AC97_BUS
+       tristate
+       help
+         This is used to avoid config and link hard dependencies between the
+         sound subsystem and other function drivers completely unrelated to
+         sound although they're sharing the AC97 bus. Concerned drivers
+         should "select" this.
+
 endmenu
index 5f6bef5..9aee54c 100644 (file)
@@ -8,6 +8,9 @@ obj-$(CONFIG_DMASOUND) += oss/
 obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/
 obj-$(CONFIG_SND_AOA) += aoa/
 
+# This one must be compilable even if sound is configured out
+obj-$(CONFIG_AC97_BUS) += ac97_bus.o
+
 ifeq ($(CONFIG_SND),y)
   obj-y += last.o
 endif
similarity index 100%
rename from sound/pci/ac97/ac97_bus.c
rename to sound/ac97_bus.c
index 7971285..40ebd2f 100644 (file)
@@ -26,11 +26,7 @@ config SND_VX_LIB
 config SND_AC97_CODEC
        tristate
        select SND_PCM
-       select SND_AC97_BUS
-
-config SND_AC97_BUS
-       tristate
-
+       select AC97_BUS
 
 config SND_DUMMY
        tristate "Dummy (/dev/null) soundcard"
index 77b3482..3c32221 100644 (file)
@@ -10,11 +10,9 @@ snd-ac97-codec-objs += ac97_proc.o
 endif
 
 snd-ak4531-codec-objs := ak4531_codec.o
-snd-ac97-bus-objs := ac97_bus.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o
 obj-$(CONFIG_SND_ENS1370) += snd-ak4531-codec.o
-obj-$(CONFIG_SND_AC97_BUS) += snd-ac97-bus.o
 
 obj-m := $(sort $(obj-m))