aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/pcmcia/locking.txt118
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/mpc5121-psc.txt70
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/spi.txt7
-rw-r--r--Documentation/powerpc/ptrace.txt134
-rw-r--r--arch/powerpc/Kconfig29
-rw-r--r--arch/powerpc/boot/dts/arches.dts12
-rw-r--r--arch/powerpc/boot/dts/gef_ppc9a.dts16
-rw-r--r--arch/powerpc/boot/dts/gef_sbc310.dts19
-rw-r--r--arch/powerpc/boot/dts/gef_sbc610.dts66
-rw-r--r--arch/powerpc/boot/dts/glacier.dts76
-rw-r--r--arch/powerpc/boot/dts/katmai.dts71
-rw-r--r--arch/powerpc/boot/dts/mpc5121ads.dts55
-rw-r--r--arch/powerpc/boot/dts/mpc8568mds.dts65
-rw-r--r--arch/powerpc/configs/44x/katmai_defconfig94
-rw-r--r--arch/powerpc/configs/86xx/gef_ppc9a_defconfig47
-rw-r--r--arch/powerpc/configs/86xx/gef_sbc610_defconfig65
-rw-r--r--arch/powerpc/configs/mpc512x_defconfig1694
-rw-r--r--arch/powerpc/configs/ppc64_defconfig75
-rw-r--r--arch/powerpc/configs/pseries_defconfig63
-rw-r--r--arch/powerpc/include/asm/asm-compat.h5
-rw-r--r--arch/powerpc/include/asm/atomic.h48
-rw-r--r--arch/powerpc/include/asm/bitops.h56
-rw-r--r--arch/powerpc/include/asm/cputable.h4
-rw-r--r--arch/powerpc/include/asm/cputime.h7
-rw-r--r--arch/powerpc/include/asm/feature-fixups.h2
-rw-r--r--arch/powerpc/include/asm/futex.h6
-rw-r--r--arch/powerpc/include/asm/hardirq.h30
-rw-r--r--arch/powerpc/include/asm/local.h12
-rw-r--r--arch/powerpc/include/asm/mpc5121.h24
-rw-r--r--arch/powerpc/include/asm/mpc52xx_psc.h4
-rw-r--r--arch/powerpc/include/asm/mpic.h2
-rw-r--r--arch/powerpc/include/asm/mutex.h6
-rw-r--r--arch/powerpc/include/asm/param.h23
-rw-r--r--arch/powerpc/include/asm/pmac_feature.h2
-rw-r--r--arch/powerpc/include/asm/ppc-opcode.h18
-rw-r--r--arch/powerpc/include/asm/ppc-pci.h5
-rw-r--r--arch/powerpc/include/asm/processor.h36
-rw-r--r--arch/powerpc/include/asm/ptrace.h77
-rw-r--r--arch/powerpc/include/asm/reg_booke.h96
-rw-r--r--arch/powerpc/include/asm/spinlock.h32
-rw-r--r--arch/powerpc/include/asm/synch.h12
-rw-r--r--arch/powerpc/include/asm/system.h21
-rw-r--r--arch/powerpc/include/asm/topology.h48
-rw-r--r--arch/powerpc/kernel/entry_64.S3
-rw-r--r--arch/powerpc/kernel/firmware.c2
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S4
-rw-r--r--arch/powerpc/kernel/irq.c140
-rw-r--r--arch/powerpc/kernel/kgdb.c2
-rw-r--r--arch/powerpc/kernel/kprobes.c4
-rw-r--r--arch/powerpc/kernel/lparcfg.c10
-rw-r--r--arch/powerpc/kernel/nvram_64.c6
-rw-r--r--arch/powerpc/kernel/pci_of_scan.c2
-rw-r--r--arch/powerpc/kernel/pmc.c10
-rw-r--r--arch/powerpc/kernel/process.c116
-rw-r--r--arch/powerpc/kernel/prom_init.c81
-rw-r--r--arch/powerpc/kernel/ptrace.c516
-rw-r--r--arch/powerpc/kernel/signal.c6
-rw-r--r--arch/powerpc/kernel/signal_32.c16
-rw-r--r--arch/powerpc/kernel/time.c10
-rw-r--r--arch/powerpc/kernel/traps.c128
-rw-r--r--arch/powerpc/lib/copypage_64.S28
-rw-r--r--arch/powerpc/lib/copyuser_64.S80
-rw-r--r--arch/powerpc/lib/feature-fixups.c3
-rw-r--r--arch/powerpc/mm/40x_mmu.c4
-rw-r--r--arch/powerpc/mm/hash_native_64.c19
-rw-r--r--arch/powerpc/mm/mmu_context_hash64.c10
-rw-r--r--arch/powerpc/mm/mmu_context_nohash.c14
-rw-r--r--arch/powerpc/mm/tlb_low_64e.S2
-rw-r--r--arch/powerpc/mm/tlb_nohash.c6
-rw-r--r--arch/powerpc/platforms/512x/clock.c6
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads.c3
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads_cpld.c2
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_generic.c3
-rw-r--r--arch/powerpc/platforms/512x/mpc512x.h3
-rw-r--r--arch/powerpc/platforms/512x/mpc512x_shared.c43
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c3
-rw-r--r--arch/powerpc/platforms/85xx/socrates_fpga_pic.c2
-rw-r--r--arch/powerpc/platforms/85xx/stx_gp3.c2
-rw-r--r--arch/powerpc/platforms/cell/beat_htab.c24
-rw-r--r--arch/powerpc/platforms/cell/beat_interrupt.c20
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c4
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c2
-rw-r--r--arch/powerpc/platforms/iseries/irq.c2
-rw-r--r--arch/powerpc/platforms/iseries/proc.c2
-rw-r--r--arch/powerpc/platforms/iseries/setup.c2
-rw-r--r--arch/powerpc/platforms/powermac/bootx_init.c4
-rw-r--r--arch/powerpc/platforms/powermac/feature.c6
-rw-r--r--arch/powerpc/platforms/powermac/nvram.c14
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_base.c24
-rw-r--r--arch/powerpc/platforms/powermac/pic.c40
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c18
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c10
-rw-r--r--arch/powerpc/platforms/pseries/eeh_event.c2
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c22
-rw-r--r--arch/powerpc/platforms/pseries/hvCall_inst.c4
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c2
-rw-r--r--arch/powerpc/platforms/pseries/phyp_dump.c6
-rw-r--r--arch/powerpc/platforms/pseries/smp.c4
-rw-r--r--arch/powerpc/platforms/pseries/xics.c32
-rw-r--r--arch/powerpc/sysdev/cpm1.c2
-rw-r--r--arch/powerpc/sysdev/cpm2_pic.c2
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c2
-rw-r--r--arch/powerpc/sysdev/i8259.c24
-rw-r--r--arch/powerpc/sysdev/ipic.c22
-rw-r--r--arch/powerpc/sysdev/mpc8xx_pic.c2
-rw-r--r--arch/powerpc/sysdev/mpic.c40
-rw-r--r--arch/powerpc/sysdev/mpic_pasemi_msi.c2
-rw-r--r--arch/powerpc/sysdev/mv64x60_dev.c3
-rw-r--r--arch/powerpc/sysdev/ppc4xx_soc.c3
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.c4
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_io.c8
-rw-r--r--arch/powerpc/sysdev/uic.c2
-rw-r--r--arch/powerpc/xmon/xmon.c2
-rw-r--r--drivers/block/viodasd.c86
-rw-r--r--drivers/char/hvc_console.c6
-rw-r--r--drivers/char/hvc_console.h4
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c2
-rw-r--r--drivers/hwmon/ams/ams-core.c11
-rw-r--r--drivers/hwmon/ams/ams-i2c.c2
-rw-r--r--drivers/hwmon/ams/ams-pmu.c2
-rw-r--r--drivers/hwmon/ams/ams.h1
-rw-r--r--drivers/macintosh/therm_adt746x.c36
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c6
-rw-r--r--drivers/pcmcia/Kconfig9
-rw-r--r--drivers/pcmcia/Makefile4
-rw-r--r--drivers/pcmcia/at91_cf.c2
-rw-r--r--drivers/pcmcia/bfin_cf_pcmcia.c2
-rw-r--r--drivers/pcmcia/cardbus.c175
-rw-r--r--drivers/pcmcia/cistpl.c606
-rw-r--r--drivers/pcmcia/cs.c312
-rw-r--r--drivers/pcmcia/cs_internal.h89
-rw-r--r--drivers/pcmcia/ds.c333
-rw-r--r--drivers/pcmcia/electra_cf.c2
-rw-r--r--drivers/pcmcia/i82365.h4
-rw-r--r--drivers/pcmcia/m32r_cfc.c2
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c4
-rw-r--r--drivers/pcmcia/o2micro.h45
-rw-r--r--drivers/pcmcia/omap_cf.c2
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c42
-rw-r--r--drivers/pcmcia/pcmcia_resource.c169
-rw-r--r--drivers/pcmcia/rsrc_mgr.c48
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c285
-rw-r--r--drivers/pcmcia/socket_sysfs.c196
-rw-r--r--drivers/pcmcia/yenta_socket.c5
-rw-r--r--drivers/ps3/ps3av.c2
-rw-r--r--drivers/rtc/Kconfig10
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-mpc5121.c387
-rw-r--r--drivers/serial/mpc52xx_uart.c251
-rw-r--r--drivers/serial/serial_cs.c7
-rw-r--r--drivers/video/fsl-diu-fb.c5
-rw-r--r--include/linux/lmb.h1
-rw-r--r--include/pcmcia/ds.h2
-rw-r--r--include/pcmcia/ss.h40
-rw-r--r--lib/lmb.c13
-rwxr-xr-xscripts/kernel-doc16
156 files changed, 6160 insertions, 2070 deletions
diff --git a/Documentation/pcmcia/locking.txt b/Documentation/pcmcia/locking.txt
new file mode 100644
index 00000000000..68f622bc406
--- /dev/null
+++ b/Documentation/pcmcia/locking.txt
@@ -0,0 +1,118 @@
+This file explains the locking and exclusion scheme used in the PCCARD
+and PCMCIA subsystems.
+
+
+A) Overview, Locking Hierarchy:
+===============================
+
+pcmcia_socket_list_rwsem - protects only the list of sockets
+- skt_mutex - serializes card insert / ejection
+ - ops_mutex - serializes socket operation
+
+
+B) Exclusion
+============
+
+The following functions and callbacks to struct pcmcia_socket must
+be called with "skt_mutex" held:
+
+ socket_detect_change()
+ send_event()
+ socket_reset()
+ socket_shutdown()
+ socket_setup()
+ socket_remove()
+ socket_insert()
+ socket_early_resume()
+ socket_late_resume()
+ socket_resume()
+ socket_suspend()
+
+ struct pcmcia_callback *callback
+
+The following functions and callbacks to struct pcmcia_socket must
+be called with "ops_mutex" held:
+
+ socket_reset()
+ socket_setup()
+
+ struct pccard_operations *ops
+ struct pccard_resource_ops *resource_ops;
+
+Note that send_event() and struct pcmcia_callback *callback must not be
+called with "ops_mutex" held.
+
+
+C) Protection
+=============
+
+1. Global Data:
+---------------
+struct list_head pcmcia_socket_list;
+
+protected by pcmcia_socket_list_rwsem;
+
+
+2. Per-Socket Data:
+-------------------
+The resource_ops and their data are protected by ops_mutex.
+
+The "main" struct pcmcia_socket is protected as follows (read-only fields
+or single-use fields not mentioned):
+
+- by pcmcia_socket_list_rwsem:
+ struct list_head socket_list;
+
+- by thread_lock:
+ unsigned int thread_events;
+
+- by skt_mutex:
+ u_int suspended_state;
+ void (*tune_bridge);
+ struct pcmcia_callback *callback;
+ int resume_status;
+
+- by ops_mutex:
+ socket_state_t socket;
+ u_int state;
+ u_short lock_count;
+ pccard_mem_map cis_mem;
+ void __iomem *cis_virt;
+ struct { } irq;
+ io_window_t io[];
+ pccard_mem_map win[];
+ struct list_head cis_cache;
+ size_t fake_cis_len;
+ u8 *fake_cis;
+ u_int irq_mask;
+ void (*zoom_video);
+ int (*power_hook);
+ u8 resource...;
+ struct list_head devices_list;
+ u8 device_count;
+ struct pcmcia_state;
+
+
+3. Per PCMCIA-device Data:
+--------------------------
+
+The "main" struct pcmcia_devie is protected as follows (read-only fields
+or single-use fields not mentioned):
+
+
+- by pcmcia_socket->ops_mutex:
+ struct list_head socket_device_list;
+ struct config_t *function_config;
+ u16 _irq:1;
+ u16 _io:1;
+ u16 _win:4;
+ u16 _locked:1;
+ u16 allow_func_id_match:1;
+ u16 suspended:1;
+ u16 _removed:1;
+
+- by the PCMCIA driver:
+ io_req_t io;
+ irq_req_t irq;
+ config_req_t conf;
+ window_handle_t win;
diff --git a/Documentation/powerpc/dts-bindings/fsl/mpc5121-psc.txt b/Documentation/powerpc/dts-bindings/fsl/mpc5121-psc.txt
new file mode 100644
index 00000000000..8832e879891
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/fsl/mpc5121-psc.txt
@@ -0,0 +1,70 @@
+MPC5121 PSC Device Tree Bindings
+
+PSC in UART mode
+----------------
+
+For PSC in UART mode the needed PSC serial devices
+are specified by fsl,mpc5121-psc-uart nodes in the
+fsl,mpc5121-immr SoC node. Additionally the PSC FIFO
+Controller node fsl,mpc5121-psc-fifo is requered there:
+
+fsl,mpc5121-psc-uart nodes
+--------------------------
+
+Required properties :
+ - compatible : Should contain "fsl,mpc5121-psc-uart" and "fsl,mpc5121-psc"
+ - cell-index : Index of the PSC in hardware
+ - reg : Offset and length of the register set for the PSC device
+ - interrupts : <a b> where a is the interrupt number of the
+ PSC FIFO Controller and b is a field that represents an
+ encoding of the sense and level information for the interrupt.
+ - interrupt-parent : the phandle for the interrupt controller that
+ services interrupts for this device.
+
+Recommended properties :
+ - fsl,rx-fifo-size : the size of the RX fifo slice (a multiple of 4)
+ - fsl,tx-fifo-size : the size of the TX fifo slice (a multiple of 4)
+
+
+fsl,mpc5121-psc-fifo node
+-------------------------
+
+Required properties :
+ - compatible : Should be "fsl,mpc5121-psc-fifo"
+ - reg : Offset and length of the register set for the PSC
+ FIFO Controller
+ - interrupts : <a b> where a is the interrupt number of the
+ PSC FIFO Controller and b is a field that represents an
+ encoding of the sense and level information for the interrupt.
+ - interrupt-parent : the phandle for the interrupt controller that
+ services interrupts for this device.
+
+
+Example for a board using PSC0 and PSC1 devices in serial mode:
+
+serial@11000 {
+ compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc";
+ cell-index = <0>;
+ reg = <0x11000 0x100>;
+ interrupts = <40 0x8>;
+ interrupt-parent = < &ipic >;
+ fsl,rx-fifo-size = <16>;
+ fsl,tx-fifo-size = <16>;
+};
+
+serial@11100 {
+ compatible = "fsl,mpc5121-psc-uart", "fsl,mpc5121-psc";
+ cell-index = <1>;
+ reg = <0x11100 0x100>;
+ interrupts = <40 0x8>;
+ interrupt-parent = < &ipic >;
+ fsl,rx-fifo-size = <16>;
+ fsl,tx-fifo-size = <16>;
+};
+
+pscfifo@11f00 {
+ compatible = "fsl,mpc5121-psc-fifo";
+ reg = <0x11f00 0x100>;
+ interrupts = <40 0x8>;
+ interrupt-parent = < &ipic >;
+};
diff --git a/Documentation/powerpc/dts-bindings/fsl/spi.txt b/Documentation/powerpc/dts-bindings/fsl/spi.txt
index e7d9a344c4f..80510c018ee 100644
--- a/Documentation/powerpc/dts-bindings/fsl/spi.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/spi.txt
@@ -13,6 +13,11 @@ Required properties:
- interrupt-parent : the phandle for the interrupt controller that
services interrupts for this device.
+Optional properties:
+- gpios : specifies the gpio pins to be used for chipselects.
+ The gpios will be referred to as reg = <index> in the SPI child nodes.
+ If unspecified, a single SPI device without a chip select can be used.
+
Example:
spi@4c0 {
cell-index = <0>;
@@ -21,4 +26,6 @@ Example:
interrupts = <82 0>;
interrupt-parent = <700>;
mode = "cpu";
+ gpios = <&gpio 18 1 // device reg=<0>
+ &gpio 19 1>; // device reg=<1>
};
diff --git a/Documentation/powerpc/ptrace.txt b/Documentation/powerpc/ptrace.txt
new file mode 100644
index 00000000000..f4a5499b7bc
--- /dev/null
+++ b/Documentation/powerpc/ptrace.txt
@@ -0,0 +1,134 @@
+GDB intends to support the following hardware debug features of BookE
+processors:
+
+4 hardware breakpoints (IAC)
+2 hardware watchpoints (read, write and read-write) (DAC)
+2 value conditions for the hardware watchpoints (DVC)
+
+For that, we need to extend ptrace so that GDB can query and set these
+resources. Since we're extending, we're trying to create an interface
+that's extendable and that covers both BookE and server processors, so
+that GDB doesn't need to special-case each of them. We added the
+following 3 new ptrace requests.
+
+1. PTRACE_PPC_GETHWDEBUGINFO
+
+Query for GDB to discover the hardware debug features. The main info to
+be returned here is the minimum alignment for the hardware watchpoints.
+BookE processors don't have restrictions here, but server processors have
+an 8-byte alignment restriction for hardware watchpoints. We'd like to avoid
+adding special cases to GDB based on what it sees in AUXV.
+
+Since we're at it, we added other useful info that the kernel can return to
+GDB: this query will return the number of hardware breakpoints, hardware
+watchpoints and whether it supports a range of addresses and a condition.
+The query will fill the following structure provided by the requesting process:
+
+struct ppc_debug_info {
+ unit32_t version;
+ unit32_t num_instruction_bps;
+ unit32_t num_data_bps;
+ unit32_t num_condition_regs;
+ unit32_t data_bp_alignment;
+ unit32_t sizeof_condition; /* size of the DVC register */
+ uint64_t features; /* bitmask of the individual flags */
+};
+
+features will have bits indicating whether there is support for:
+
+#define PPC_DEBUG_FEATURE_INSN_BP_RANGE 0x1
+#define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x2
+#define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x4
+#define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x8
+
+2. PTRACE_SETHWDEBUG
+
+Sets a hardware breakpoint or watchpoint, according to the provided structure:
+
+struct ppc_hw_breakpoint {
+ uint32_t version;
+#define PPC_BREAKPOINT_TRIGGER_EXECUTE 0x1
+#define PPC_BREAKPOINT_TRIGGER_READ 0x2
+#define PPC_BREAKPOINT_TRIGGER_WRITE 0x4
+ uint32_t trigger_type; /* only some combinations allowed */
+#define PPC_BREAKPOINT_MODE_EXACT 0x0
+#define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE 0x1
+#define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE 0x2
+#define PPC_BREAKPOINT_MODE_MASK 0x3
+ uint32_t addr_mode; /* address match mode */
+
+#define PPC_BREAKPOINT_CONDITION_MODE 0x3
+#define PPC_BREAKPOINT_CONDITION_NONE 0x0
+#define PPC_BREAKPOINT_CONDITION_AND 0x1
+#define PPC_BREAKPOINT_CONDITION_EXACT 0x1 /* different name for the same thing as above */
+#define PPC_BREAKPOINT_CONDITION_OR 0x2
+#define PPC_BREAKPOINT_CONDITION_AND_OR 0x3
+#define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000 /* byte enable bits */
+#define PPC_BREAKPOINT_CONDITION_BE(n) (1<<((n)+16))
+ uint32_t condition_mode; /* break/watchpoint condition flags */
+
+ uint64_t addr;
+ uint64_t addr2;
+ uint64_t condition_value;
+};
+
+A request specifies one event, not necessarily just one register to be set.
+For instance, if the request is for a watchpoint with a condition, both the
+DAC and DVC registers will be set in the same request.
+
+With this GDB can ask for all kinds of hardware breakpoints and watchpoints
+that the BookE supports. COMEFROM breakpoints available in server processors
+are not contemplated, but that is out of the scope of this work.
+
+ptrace will return an integer (handle) uniquely identifying the breakpoint or
+watchpoint just created. This integer will be used in the PTRACE_DELHWDEBUG
+request to ask for its removal. Return -ENOSPC if the requested breakpoint
+can't be allocated on the registers.
+
+Some examples of using the structure to:
+
+- set a breakpoint in the first breakpoint register
+
+ p.version = PPC_DEBUG_CURRENT_VERSION;
+ p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
+ p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
+ p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
+ p.addr = (uint64_t) address;
+ p.addr2 = 0;
+ p.condition_value = 0;
+
+- set a watchpoint which triggers on reads in the second watchpoint register
+
+ p.version = PPC_DEBUG_CURRENT_VERSION;
+ p.trigger_type = PPC_BREAKPOINT_TRIGGER_READ;
+ p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
+ p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
+ p.addr = (uint64_t) address;
+ p.addr2 = 0;
+ p.condition_value = 0;
+
+- set a watchpoint which triggers only with a specific value
+
+ p.version = PPC_DEBUG_CURRENT_VERSION;
+ p.trigger_type = PPC_BREAKPOINT_TRIGGER_READ;
+ p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
+ p.condition_mode = PPC_BREAKPOINT_CONDITION_AND | PPC_BREAKPOINT_CONDITION_BE_ALL;
+ p.addr = (uint64_t) address;
+ p.addr2 = 0;
+ p.condition_value = (uint64_t) condition;
+
+- set a ranged hardware breakpoint
+
+ p.version = PPC_DEBUG_CURRENT_VERSION;
+ p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
+ p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
+ p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
+ p.addr = (uint64_t) begin_range;
+ p.addr2 = (uint64_t) end_range;
+ p.condition_value = 0;
+
+3. PTRACE_DELHWDEBUG
+
+Takes an integer which identifies an existing breakpoint or watchpoint
+(i.e., the value returned from PTRACE_SETHWDEBUG), and deletes the
+corresponding breakpoint or watchpoint..
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 50c9af43e01..155d571f5e2 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -58,7 +58,7 @@ config IRQ_PER_CPU
config NR_IRQS
int "Number of virtual interrupt numbers"
- range 32 512
+ range 32 32768
default "512"
help
This defines the number of virtual interrupt numbers the kernel
@@ -241,6 +241,33 @@ config PPC_OF_PLATFORM_PCI
config ARCH_SUPPORTS_DEBUG_PAGEALLOC
def_bool y
+config PPC_ADV_DEBUG_REGS
+ bool
+ depends on 40x || BOOKE
+ default y
+
+config PPC_ADV_DEBUG_IACS
+ int
+ depends on PPC_ADV_DEBUG_REGS
+ default 4 if 44x
+ default 2
+
+config PPC_ADV_DEBUG_DACS
+ int
+ depends on PPC_ADV_DEBUG_REGS
+ default 2
+
+config PPC_ADV_DEBUG_DVCS
+ int
+ depends on PPC_ADV_DEBUG_REGS
+ default 2 if 44x
+ default 0
+
+config PPC_ADV_DEBUG_DAC_RANGE
+ bool
+ depends on PPC_ADV_DEBUG_REGS && 44x
+ default y
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
diff --git a/arch/powerpc/boot/dts/arches.dts b/arch/powerpc/boot/dts/arches.dts
index 414ef8b7e57..30f41204acf 100644
--- a/arch/powerpc/boot/dts/arches.dts
+++ b/arch/powerpc/boot/dts/arches.dts
@@ -60,6 +60,7 @@
d-cache-size = <32768>;
dcr-controller;
dcr-access-method = "native";
+ next-level-cache = <&L2C0>;
};
};
@@ -146,6 +147,13 @@
dcr-reg = <0x010 0x002>;
};
+ CRYPTO: crypto@180000 {
+ compatible = "amcc,ppc460gt-crypto", "amcc,ppc4xx-crypto";
+ reg = <4 0x00180000 0x80400>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0x1d 0x4>;
+ };
+
MAL0: mcmal {
compatible = "ibm,mcmal-460gt", "ibm,mcmal2";
dcr-reg = <0x180 0x062>;
@@ -274,6 +282,7 @@
max-frame-size = <9000>;
rx-fifo-size = <4096>;
tx-fifo-size = <2048>;
+ rx-fifo-size-gige = <16384>;
phy-mode = "sgmii";
phy-map = <0xffffffff>;
gpcs-address = <0x0000000a>;
@@ -302,6 +311,7 @@
max-frame-size = <9000>;
rx-fifo-size = <4096>;
tx-fifo-size = <2048>;
+ rx-fifo-size-gige = <16384>;
phy-mode = "sgmii";
phy-map = <0x00000000>;
gpcs-address = <0x0000000b>;
@@ -331,6 +341,8 @@
max-frame-size = <9000>;
rx-fifo-size = <4096>;
tx-fifo-size = <2048>;
+ rx-fifo-size-gige = <16384>;
+ tx-fifo-size-gige = <16384>; /* emac2&3 only */
phy-mode = "sgmii";
phy-map = <0x00000001>;
gpcs-address = <0x0000000C>;
diff --git a/arch/powerpc/boot/dts/gef_ppc9a.dts b/arch/powerpc/boot/dts/gef_ppc9a.dts
index c86114e93f1..977f260d5e6 100644
--- a/arch/powerpc/boot/dts/gef_ppc9a.dts
+++ b/arch/powerpc/boot/dts/gef_ppc9a.dts
@@ -341,6 +341,22 @@
device_type = "open-pic";
};
+ msi@41600 {
+ compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
+ reg = <0x41600 0x80>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0
+ 0xe1 0
+ 0xe2 0
+ 0xe3 0
+ 0xe4 0
+ 0xe5 0
+ 0xe6 0
+ 0xe7 0>;
+ interrupt-parent = <&mpic>;
+ };
+
global-utilities@e0000 {
compatible = "fsl,mpc8641-guts";
reg = <0xe0000 0x1000>;
diff --git a/arch/powerpc/boot/dts/gef_sbc310.dts b/arch/powerpc/boot/dts/gef_sbc310.dts
index 820c2b355ab..8e4efff3bda 100644
--- a/arch/powerpc/boot/dts/gef_sbc310.dts
+++ b/arch/powerpc/boot/dts/gef_sbc310.dts
@@ -32,6 +32,7 @@
serial0 = &serial0;
serial1 = &serial1;
pci0 = &pci0;
+ pci1 = &pci1;
};
cpus {
@@ -338,6 +339,22 @@
device_type = "open-pic";
};
+ msi@41600 {
+ compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
+ reg = <0x41600 0x80>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0
+ 0xe1 0
+ 0xe2 0
+ 0xe3 0
+ 0xe4 0
+ 0xe5 0
+ 0xe6 0
+ 0xe7 0>;
+ interrupt-parent = <&mpic>;
+ };
+
global-utilities@e0000 {
compatible = "fsl,mpc8641-guts";
reg = <0xe0000 0x1000>;
@@ -358,7 +375,7 @@
clock-frequency = <33333333>;
interrupt-parent = <&mpic>;
interrupts = <0x18 0x2>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
interrupt-map = <
0x0000 0x0 0x0 0x1 &mpic 0x0 0x2
0x0000 0x0 0x0 0x2 &mpic 0x1 0x2
diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts
index 30911adefc8..bb7060078fb 100644
--- a/arch/powerpc/boot/dts/gef_sbc610.dts
+++ b/arch/powerpc/boot/dts/gef_sbc610.dts
@@ -75,14 +75,48 @@
interrupts = <19 2>;
interrupt-parent = <&mpic>;
- ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
- 1 0 0xe8000000 0x08000000 // Paged Flash 0
- 2 0 0xe0000000 0x08000000 // Paged Flash 1
- 3 0 0xfc100000 0x00020000 // NVRAM
- 4 0 0xfc000000 0x00008000 // FPGA
- 5 0 0xfc008000 0x00008000 // AFIX FPGA
- 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit)
- 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit)
+ ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
+ 1 0 0xe8000000 0x08000000 // Paged Flash 0
+ 2 0 0xe0000000 0x08000000 // Paged Flash 1
+ 3 0 0xfc100000 0x00020000 // NVRAM
+ 4 0 0xfc000000 0x00008000 // FPGA
+ 5 0 0xfc008000 0x00008000 // AFIX FPGA
+ 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit)
+ 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit)
+
+ /* flash@0,0 is a mirror of part of the memory in flash@1,0
+ flash@0,0 {
+ compatible = "gef,sbc610-firmware-mirror", "cfi-flash";
+ reg = <0x0 0x0 0x1000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "firmware";
+ reg = <0x0 0x1000000>;
+ read-only;
+ };
+ };
+ */
+
+ flash@1,0 {
+ compatible = "gef,sbc610-paged-flash", "cfi-flash";
+ reg = <0x1 0x0 0x8000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "user";
+ reg = <0x0 0x7800000>;
+ };
+ partition@7800000 {
+ label = "firmware";
+ reg = <0x7800000 0x800000>;
+ read-only;
+ };
+ };
nvram@3,0 {
device_type = "nvram";
@@ -305,6 +339,22 @@
device_type = "open-pic";
};
+ msi@41600 {
+ compatible = "fsl,mpc8641-msi", "fsl,mpic-msi";
+ reg = <0x41600 0x80>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0
+ 0xe1 0
+ 0xe2 0
+ 0xe3 0
+ 0xe4 0
+ 0xe5 0
+ 0xe6 0
+ 0xe7 0>;
+ interrupt-parent = <&mpic>;
+ };
+
global-utilities@e0000 {
compatible = "fsl,mpc8641-guts";
reg = <0xe0000 0x1000>;
diff --git a/arch/powerpc/boot/dts/glacier.dts b/arch/powerpc/boot/dts/glacier.dts
index f6f61893929..d62a4fb6f93 100644
--- a/arch/powerpc/boot/dts/glacier.dts
+++ b/arch/powerpc/boot/dts/glacier.dts
@@ -1,7 +1,7 @@
/*
* Device Tree Source for AMCC Glacier (460GT)
*
- * Copyright 2008 DENX Software Engineering, Stefan Roese <sr@denx.de>
+ * Copyright 2008-2010 DENX Software Engineering, Stefan Roese <sr@denx.de>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without
@@ -42,6 +42,7 @@
d-cache-size = <32768>;
dcr-controller;
dcr-access-method = "native";
+ next-level-cache = <&L2C0>;
};
};
@@ -106,6 +107,16 @@
dcr-reg = <0x00c 0x002>;
};
+ L2C0: l2c {
+ compatible = "ibm,l2-cache-460gt", "ibm,l2-cache";
+ dcr-reg = <0x020 0x008 /* Internal SRAM DCR's */
+ 0x030 0x008>; /* L2 cache DCR's */
+ cache-line-size = <32>; /* 32 bytes */
+ cache-size = <262144>; /* L2, 256K */
+ interrupt-parent = <&UIC1>;
+ interrupts = <11 1>;
+ };
+
plb {
compatible = "ibm,plb-460gt", "ibm,plb4";
#address-cells = <2>;
@@ -118,6 +129,13 @@
dcr-reg = <0x010 0x002>;
};
+ CRYPTO: crypto@180000 {
+ compatible = "amcc,ppc460gt-crypto", "amcc,ppc4xx-crypto";
+ reg = <4 0x00180000 0x80400>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0x1d 0x4>;
+ };
+
MAL0: mcmal {
compatible = "ibm,mcmal-460gt", "ibm,mcmal2";
dcr-reg = <0x180 0x062>;
@@ -186,6 +204,29 @@
reg = <0x03fa0000 0x00060000>;
};
};
+
+ ndfc@3,0 {
+ compatible = "ibm,ndfc";
+ reg = <0x00000003 0x00000000 0x00002000>;
+ ccr = <0x00001000>;
+ bank-settings = <0x80002222>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ nand {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ };
+ partition@100000 {
+ label = "user";
+ reg = <0x00000000 0x03f00000>;
+ };
+ };
+ };
};
UART0: serial@ef600300 {
@@ -237,6 +278,20 @@
reg = <0xef600700 0x00000014>;
interrupt-parent = <&UIC0>;
interrupts = <0x2 0x4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ rtc@68 {
+ compatible = "stm,m41t80";
+ reg = <0x68>;
+ interrupt-parent = <&UIC2>;
+ interrupts = <0x19 0x8>;
+ };
+ sttm@48 {
+ compatible = "ad,ad7414";
+ reg = <0x48>;
+ interrupt-parent = <&UIC1>;
+ interrupts = <0x14 0x8>;
+ };
};
IIC1: i2c@ef600800 {
@@ -275,7 +330,7 @@
EMAC0: ethernet@ef600e00 {
device_type = "network";
- compatible = "ibm,emac-460gt", "ibm,emac4";
+ compatible = "ibm,emac-460gt", "ibm,emac4sync";
interrupt-parent = <&EMAC0>;
interrupts = <0x0 0x1>;
#interrupt-cells = <1>;
@@ -283,7 +338,7 @@
#size-cells = <0>;
interrupt-map = </*Status*/ 0x0 &UIC2 0x10 0x4
/*Wake*/ 0x1 &UIC2 0x14 0x4>;
- reg = <0xef600e00 0x00000074>;
+ reg = <0xef600e00 0x000000c4>;
local-mac-address = [000000000000]; /* Filled in by U-Boot */
mal-device = <&MAL0>;
mal-tx-channel = <0>;
@@ -305,7 +360,7 @@
EMAC1: ethernet@ef600f00 {
device_type = "network";
- compatible = "ibm,emac-460gt", "ibm,emac4";
+ compatible = "ibm,emac-460gt", "ibm,emac4sync";
interrupt-parent = <&EMAC1>;
interrupts = <0x0 0x1>;
#interrupt-cells = <1>;
@@ -313,7 +368,7 @@
#size-cells = <0>;
interrupt-map = </*Status*/ 0x0 &UIC2 0x11 0x4
/*Wake*/ 0x1 &UIC2 0x15 0x4>;
- reg = <0xef600f00 0x00000074>;
+ reg = <0xef600f00 0x000000c4>;
local-mac-address = [000000000000]; /* Filled in by U-Boot */
mal-device = <&MAL0>;
mal-tx-channel = <1>;
@@ -336,7 +391,7 @@
EMAC2: ethernet@ef601100 {
device_type = "network";
- compatible = "ibm,emac-460gt", "ibm,emac4";
+ compatible = "ibm,emac-460gt", "ibm,emac4sync";
interrupt-parent = <&EMAC2>;
interrupts = <0x0 0x1>;
#interrupt-cells = <1>;
@@ -344,7 +399,7 @@
#size-cells = <0>;
interrupt-map = </*Status*/ 0x0 &UIC2 0x12 0x4
/*Wake*/ 0x1 &UIC2 0x16 0x4>;
- reg = <0xef601100 0x00000074>;
+ reg = <0xef601100 0x000000c4>;
local-mac-address = [000000000000]; /* Filled in by U-Boot */
mal-device = <&MAL0>;
mal-tx-channel = <2>;
@@ -366,7 +421,7 @@
EMAC3: ethernet@ef601200 {
device_type = "network";
- compatible = "ibm,emac-460gt", "ibm,emac4";
+ compatible = "ibm,emac-460gt", "ibm,emac4sync";
interrupt-parent = <&EMAC3>;
interrupts = <0x0 0x1>;
#interrupt-cells = <1>;
@@ -374,7 +429,7 @@
#size-cells = <0>;
interrupt-map = </*Status*/ 0x0 &UIC2 0x13 0x4
/*Wake*/ 0x1 &UIC2 0x17 0x4>;
- reg = <0xef601200 0x00000074>;
+ reg = <0xef601200 0x000000c4>;
local-mac-address = [000000000000]; /* Filled in by U-Boot */
mal-device = <&MAL0>;
mal-tx-channel = <3>;
@@ -414,6 +469,7 @@
* later cannot be changed
*/
ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000
+ 0x02000000 0x00000000 0x00000000 0x0000000c 0x0ee00000 0x00000000 0x00100000
0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>;
/* Inbound 2GB range starting at 0 */
@@ -444,6 +500,7 @@
* later cannot be changed
*/
ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000
+ 0x02000000 0x00000000 0x00000000 0x0000000f 0x00000000 0x00000000 0x00100000
0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>;
/* Inbound 2GB range starting at 0 */
@@ -485,6 +542,7 @@
* later cannot be changed
*/
ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000
+ 0x02000000 0x00000000 0x00000000 0x0000000f 0x00100000 0x00000000 0x00100000
0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>;
/* Inbound 2GB range starting at 0 */
diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts
index 8f345de960c..8cf2c0c88c0 100644
--- a/arch/powerpc/boot/dts/katmai.dts
+++ b/arch/powerpc/boot/dts/katmai.dts
@@ -156,7 +156,7 @@
compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb";
#address-cells = <1>;
#size-cells = <1>;
- ranges = <0x00000000 0x00000004 0xe0000000 0x20000000>;
+ ranges = <0xe0000000 0x00000004 0xe0000000 0x20000000>;
clock-frequency = <0>; /* Filled in by zImage */
EBC0: ebc {
@@ -165,14 +165,47 @@
#address-cells = <2>;
#size-cells = <1>;
clock-frequency = <0>; /* Filled in by zImage */
+ /* ranges property is supplied by U-Boot */
interrupts = <0x5 0x1>;
interrupt-parent = <&UIC1>;
+
+ nor_flash@0,0 {
+ compatible = "cfi-flash";
+ bank-width = <2>;
+ reg = <0x00000000 0x00000000 0x01000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "kernel";
+ reg = <0x00000000 0x001e0000>;
+ };
+ partition@1e0000 {
+ label = "dtb";
+ reg = <0x001e0000 0x00020000>;
+ };
+ partition@200000 {
+ label = "root";
+ reg = <0x00200000 0x00200000>;
+ };
+ partition@400000 {
+ label = "user";
+ reg = <0x00400000 0x00b60000>;
+ };
+ partition@f60000 {
+ label = "env";
+ reg = <0x00f60000 0x00040000>;
+ };
+ partition@fa0000 {
+ label = "u-boot";
+ reg = <0x00fa0000 0x00060000>;
+ };
+ };
};
- UART0: serial@10000200 {
+ UART0: serial@f0000200 {
device_type = "serial";
compatible = "ns16550";
- reg = <0x10000200 0x00000008>;
+ reg = <0xf0000200 0x00000008>;
virtual-reg = <0xa0000200>;
clock-frequency = <0>; /* Filled in by zImage */
current-speed = <115200>;
@@ -180,10 +213,10 @@
interrupts = <0x0 0x4>;
};
- UART1: serial@10000300 {
+ UART1: serial@f0000300 {
device_type = "serial";
compatible = "ns16550";
- reg = <0x10000300 0x00000008>;
+ reg = <0xf0000300 0x00000008>;
virtual-reg = <0xa0000300>;
clock-frequency = <0>;
current-speed = <0>;
@@ -192,10 +225,10 @@
};
- UART2: serial@10000600 {
+ UART2: serial@f0000600 {
device_type = "serial";
compatible = "ns16550";
- reg = <0x10000600 0x00000008>;
+ reg = <0xf0000600 0x00000008>;
virtual-reg = <0xa0000600>;
clock-frequency = <0>;
current-speed = <0>;
@@ -203,27 +236,27 @@
interrupts = <0x5 0x4>;
};
- IIC0: i2c@10000400 {
+ IIC0: i2c@f0000400 {
compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
- reg = <0x10000400 0x00000014>;
+ reg = <0xf0000400 0x00000014>;
interrupt-parent = <&UIC0>;
interrupts = <0x2 0x4>;
};
- IIC1: i2c@10000500 {
+ IIC1: i2c@f0000500 {
compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
- reg = <0x10000500 0x00000014>;
+ reg = <0xf0000500 0x00000014>;
interrupt-parent = <&UIC0>;
interrupts = <0x3 0x4>;
};
- EMAC0: ethernet@10000800 {
+ EMAC0: ethernet@f0000800 {
linux,network-index = <0x0>;
device_type = "network";
compatible = "ibm,emac-440spe", "ibm,emac4";
interrupt-parent = <&UIC1>;
interrupts = <0x1c 0x4 0x1d 0x4>;
- reg = <0x10000800 0x00000074>;
+ reg = <0xf0000800 0x00000074>;
local-mac-address = [000000000000];
mal-device = <&MAL0>;
mal-tx-channel = <0>;
@@ -248,11 +281,11 @@
primary;
large-inbound-windows;
enable-msi-hole;
- reg = <0x0000000c 0x0ec00000 0x00000008 /* Config space access */
- 0x00000000 0x00000000 0x00000000 /* no IACK cycles */
- 0x0000000c 0x0ed00000 0x00000004 /* Special cycles */
- 0x0000000c 0x0ec80000 0x00000100 /* Internal registers */
- 0x0000000c 0x0ec80100 0x000000fc>; /* Internal messaging registers */
+ reg = <0x0000000c 0x0ec00000 0x00000008 /* Config space access */
+ 0x00000000 0x00000000 0x00000000 /* no IACK cycles */
+ 0x0000000c 0x0ed00000 0x00000004 /* Special cycles */
+ 0x0000000c 0x0ec80000 0x00000100 /* Internal registers */
+ 0x0000000c 0x0ec80100 0x000000fc>; /* Internal messaging registers */
/* Outbound ranges, one memory and one IO,
* later cannot be changed
@@ -453,6 +486,6 @@
};
chosen {
- linux,stdout-path = "/plb/opb/serial@10000200";
+ linux,stdout-path = "/plb/opb/serial@f0000200";
};
};
diff --git a/arch/powerpc/boot/dts/mpc5121ads.dts b/arch/powerpc/boot/dts/mpc5121ads.dts
index c353dac3341..c9ef6bbe26c 100644
--- a/arch/powerpc/boot/dts/mpc5121ads.dts
+++ b/arch/powerpc/boot/dts/mpc5121ads.dts
@@ -62,17 +62,12 @@
interrupt-parent = < &ipic >;
#address-cells = <1>;
#size-cells = <1>;
- bank-width = <1>;
// ADS has two Hynix 512MB Nand flash chips in a single
- // stacked package .
+ // stacked package.
chips = <2>;
- nand0@0 {
- label = "nand0";
- reg = <0x00000000 0x02000000>; // first 32 MB of chip 0
- };
- nand1@20000000 {
- label = "nand1";
- reg = <0x20000000 0x02000000>; // first 32 MB of chip 1
+ nand@0 {
+ label = "nand";
+ reg = <0x00000000 0x40000000>; // 512MB + 512MB
};
};
@@ -166,6 +161,11 @@
interrupt-parent = < &ipic >;
};
+ reset@e00 { // Reset module
+ compatible = "fsl,mpc5121-reset";
+ reg = <0xe00 0x100>;
+ };
+
clock@f00 { // Clock control
compatible = "fsl,mpc5121-clock";
reg = <0xf00 0x100>;
@@ -185,17 +185,15 @@
interrupt-parent = < &ipic >;
};
- mscan@1300 {
+ can@1300 {
compatible = "fsl,mpc5121-mscan";
- cell-index = <0>;
interrupts = <12 0x8>;
interrupt-parent = < &ipic >;
reg = <0x1300 0x80>;
};
- mscan@1380 {
+ can@1380 {
compatible = "fsl,mpc5121-mscan";
- cell-index = <1>;
interrupts = <13 0x8>;
interrupt-parent = < &ipic >;
reg = <0x1380 0x80>;
@@ -205,17 +203,31 @@
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5121-i2c", "fsl-i2c";
- cell-index = <0>;
reg = <0x1700 0x20>;
interrupts = <9 0x8>;
interrupt-parent = < &ipic >;
+ fsl,preserve-clocking;
+
+ hwmon@4a {
+ compatible = "adi,ad7414";
+ reg = <0x4a>;
+ };
+
+ eeprom@50 {
+ compatible = "at,24c32";
+ reg = <0x50>;
+ };
+
+ rtc@68 {
+ compatible = "stm,m41t62";
+ reg = <0x68>;
+ };
};
i2c@1720 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5121-i2c", "fsl-i2c";
- cell-index = <1>;
reg = <0x1720 0x20>;
interrupts = <10 0x8>;
interrupt-parent = < &ipic >;
@@ -225,7 +237,6 @@
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5121-i2c", "fsl-i2c";
- cell-index = <2>;
reg = <0x1740 0x20>;
interrupts = <11 0x8>;
interrupt-parent = < &ipic >;
@@ -244,7 +255,7 @@
};
display@2100 {
- compatible = "fsl,mpc5121-diu", "fsl-diu";
+ compatible = "fsl,mpc5121-diu";
reg = <0x2100 0x100>;
interrupts = <64 0x8>;
interrupt-parent = < &ipic >;
@@ -277,7 +288,7 @@
// USB1 using external ULPI PHY
//usb@3000 {
- // compatible = "fsl,mpc5121-usb2-dr", "fsl-usb2-dr";
+ // compatible = "fsl,mpc5121-usb2-dr";
// reg = <0x3000 0x1000>;
// #address-cells = <1>;
// #size-cells = <0>;
@@ -285,12 +296,11 @@
// interrupts = <43 0x8>;
// dr_mode = "otg";
// phy_type = "ulpi";
- // port1;
//};
// USB0 using internal UTMI PHY
usb@4000 {
- compatible = "fsl,mpc5121-usb2-dr", "fsl-usb2-dr";
+ compatible = "fsl,mpc5121-usb2-dr";
reg = <0x4000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
@@ -298,7 +308,8 @@
interrupts = <44 0x8>;
dr_mode = "otg";
phy_type = "utmi_wide";
- port0;
+ fsl,invert-drvvbus;
+ fsl,invert-pwr-fault;
};
// IO control
@@ -365,7 +376,7 @@
};
dma@14000 {
- compatible = "fsl,mpc5121-dma2";
+ compatible = "fsl,mpc5121-dma";
reg = <0x14000 0x1800>;
interrupts = <65 0x8>;
interrupt-parent = < &ipic >;
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index 6d892ba74e5..92fb17876e7 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -54,9 +54,52 @@
reg = <0x0 0x10000000>;
};
- bcsr@f8000000 {
- compatible = "fsl,mpc8568mds-bcsr";
- reg = <0xf8000000 0x8000>;
+ localbus@e0005000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8568-localbus", "fsl,pq3-localbus",
+ "simple-bus";
+ reg = <0xe0005000 0x1000>;
+
+ ranges = <0x0 0x0 0xfe000000 0x02000000
+ 0x1 0x0 0xf8000000 0x00008000
+ 0x2 0x0 0xf0000000 0x04000000
+ 0x4 0x0 0xf8008000 0x00008000
+ 0x5 0x0 0xf8010000 0x00008000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x02000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ };
+
+ bcsr@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8568mds-bcsr";
+ reg = <1 0 0x8000>;
+ ranges = <0 1 0 0x8000>;
+
+ bcsr5: gpio-controller@11 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8568mds-bcsr-gpio";
+ reg = <0x5 0x1>;
+ gpio-controller;
+ };
+ };
+
+ pib@4,0 {
+ compatible = "fsl,mpc8568mds-pib";
+ reg = <4 0 0x8000>;
+ };
+
+ pib@5,0 {
+ compatible = "fsl,mpc8568mds-pib";
+ reg = <5 0 0x8000>;
+ };
};
soc8568@e0000000 {
@@ -610,4 +653,20 @@
sleep = <&pmc 0x00080000 /* controller */
&pmc 0x00040000>; /* message unit */
};
+
+ leds {
+ compatible = "gpio-leds";
+
+ green {
+ gpios = <&bcsr5 1 0>;
+ };
+
+ amber {
+ gpios = <&bcsr5 2 0>;
+ };
+
+ red {
+ gpios = <&bcsr5 3 0>;
+ };
+ };
};
diff --git a/arch/powerpc/configs/44x/katmai_defconfig b/arch/powerpc/configs/44x/katmai_defconfig
index dec901f9cc8..af244e1d255 100644
--- a/arch/powerpc/configs/44x/katmai_defconfig
+++ b/arch/powerpc/configs/44x/katmai_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc1
-# Mon Jan 4 14:55:34 2010
+# Linux kernel version: 2.6.33-rc5
+# Tue Jan 26 14:40:58 2010
#
# CONFIG_PPC64 is not set
@@ -106,6 +106,7 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -442,7 +443,90 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_SYS_HYPERVISOR is not set
CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
CONFIG_OF_DEVICE=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
@@ -500,7 +584,7 @@ CONFIG_HAVE_IDE=y
#
#
-# See the help texts for more information.
+# The newer stack is recommended.
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
@@ -763,7 +847,6 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
@@ -820,6 +903,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
diff --git a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
index a85f927bf22..622d84f48ab 100644
--- a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
+++ b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
@@ -1557,7 +1557,52 @@ CONFIG_RTC_DRV_RX8581=y
#
# TI VLYNQ
#
-# CONFIG_STAGING is not set
+CONFIG_STAGING=y
+# CONFIG_STAGING_EXCLUDE_BUILD is not set
+# CONFIG_ET131X is not set
+# CONFIG_ME4000 is not set
+# CONFIG_MEILHAUS is not set
+# CONFIG_USB_IP_COMMON is not set
+# CONFIG_ECHO is not set
+# CONFIG_COMEDI is not set
+# CONFIG_ASUS_OLED is not set
+# CONFIG_ALTERA_PCIE_CHDMA is not set
+# CONFIG_INPUT_MIMIO is not set
+# CONFIG_TRANZPORT is not set
+
+#
+# Android
+#
+# CONFIG_ANDROID is not set
+# CONFIG_DST is not set
+# CONFIG_POHMELFS is not set
+# CONFIG_B3DFG is not set
+# CONFIG_IDE_PHISON is not set
+# CONFIG_PLAN9AUTH is not set
+# CONFIG_HECI is not set
+# CONFIG_USB_CPC is not set
+
+#
+# Qualcomm MSM Camera And Video
+#
+
+#
+# Camera Sensor Selection
+#
+# CONFIG_HYPERV_STORAGE is not set
+# CONFIG_HYPERV_BLOCK is not set
+# CONFIG_HYPERV_NET is not set
+CONFIG_VME_BUS=y
+
+#
+# VME Bridge Drivers
+#
+CONFIG_VME_TSI148=y
+
+#
+# VME Device Drivers
+#
+# CONFIG_VME_USER is not set
#
# File systems
diff --git a/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
index 4554d9bb03e..62c2b81a4a8 100644
--- a/arch/powerpc/configs/86xx/gef_sbc610_defconfig
+++ b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
@@ -265,7 +265,7 @@ CONFIG_MMIO_NVRAM=y
#
# Kernel options
#
-# CONFIG_HIGHMEM is not set
+CONFIG_HIGHMEM=y
CONFIG_TICK_ONESHOT=y
# CONFIG_NO_HZ is not set
CONFIG_HIGH_RES_TIMERS=y
@@ -651,7 +651,7 @@ CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_OF_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
# CONFIG_MTD_AR7_PARTS is not set
#
@@ -671,13 +671,9 @@ CONFIG_MTD_BLOCK=y
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-# CONFIG_MTD_CFI_NOSWAP is not set
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_LE_BYTE_SWAP=y
-# CONFIG_MTD_CFI_GEOMETRY is not set
+# 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
@@ -688,7 +684,6 @@ 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_OTP is not set
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
# CONFIG_MTD_CFI_STAA is not set
@@ -1652,7 +1647,44 @@ CONFIG_RTC_DRV_RX8581=y
#
# TI VLYNQ
#
-# CONFIG_STAGING is not set
+CONFIG_STAGING=y
+# CONFIG_STAGING_EXCLUDE_BUILD is not set
+# CONFIG_ET131X is not set
+# CONFIG_ME4000 is not set
+# CONFIG_MEILHAUS is not set
+# CONFIG_USB_IP_COMMON is not set
+# CONFIG_ECHO is not set
+# CONFIG_COMEDI is not set
+# CONFIG_ASUS_OLED is not set
+# CONFIG_ALTERA_PCIE_CHDMA is not set
+# CONFIG_INPUT_MIMIO is not set
+# CONFIG_TRANZPORT is not set
+
+#
+# Android
+#
+# CONFIG_ANDROID is not set
+# CONFIG_DST is not set
+# CONFIG_POHMELFS is not set
+# CONFIG_B3DFG is not set
+# CONFIG_IDE_PHISON is not set
+# CONFIG_PLAN9AUTH is not set
+# CONFIG_HECI is not set
+# CONFIG_VT6655 is not set
+# CONFIG_USB_CPC is not set
+# CONFIG_RDC_17F3101X is not set
+CONFIG_VME_BUS=y
+
+#
+# VME Bridge Drivers
+#
+# CONFIG_VME_CA91CX42 is not set
+CONFIG_VME_TSI148=y
+
+#
+# VME Device Drivers
+#
+# CONFIG_VME_USER is not set
#
# File systems
@@ -1729,7 +1761,17 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1874,6 +1916,7 @@ CONFIG_DEBUG_PREEMPT=y
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_VM is not set
diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig
new file mode 100644
index 00000000000..a04727295d4
--- /dev/null
+++ b/arch/powerpc/configs/mpc512x_defconfig
@@ -0,0 +1,1694 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc6
+# Fri Feb 5 11:48:29 2010
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_PPC_BOOK3S_32=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
+CONFIG_6xx=y
+CONFIG_PPC_FPU=y
+# CONFIG_ALTIVEC is not set
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
+# CONFIG_SMP is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
+CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# Platform support
+#
+# CONFIG_PPC_CHRP is not set
+CONFIG_PPC_MPC512x=y
+CONFIG_PPC_MPC5121=y
+CONFIG_MPC5121_ADS=y
+# CONFIG_MPC5121_GENERIC is not set
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_PMAC is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
+# CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
+CONFIG_IPIC=y
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_QUICC_ENGINE is not set
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_MIGRATION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_FSL_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+CONFIG_CAN_VCAN=y
+CONFIG_CAN_DEV=y
+# CONFIG_CAN_CALC_BITTIMING is not set
+CONFIG_CAN_MSCAN=y
+# CONFIG_CAN_SJA1000 is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+CONFIG_CAN_DEBUG_DEVICES=y
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE 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=y
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_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
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_NAND_FSL_ELBC is not set
+CONFIG_MTD_NAND_MPC5121_NFC=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+CONFIG_OF_MDIO=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_XIP=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_FIXED_PHY=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_XILINX_EMACLITE is not set
+CONFIG_FS_ENET=y
+CONFIG_FS_ENET_MPC5121_FEC=y
+CONFIG_FS_ENET_HAS_FEC=y
+CONFIG_FS_ENET_MDIO_FEC=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_MPC52xx=y
+CONFIG_SERIAL_MPC52xx_CONSOLE=y
+CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+# CONFIG_VIDEO_ALLOW_V4L1 is not set
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+CONFIG_IR_CORE=y
+CONFIG_VIDEO_IR=y
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+CONFIG_VIDEO_ADV_DEBUG=y
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+CONFIG_VIDEO_IR_I2C=y
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TDA9875 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_M52790 is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+
+#
+# RDS decoders
+#
+# CONFIG_VIDEO_SAA6588 is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_ADV7180 is not set
+# CONFIG_VIDEO_BT819 is not set
+# CONFIG_VIDEO_BT856 is not set
+# CONFIG_VIDEO_BT866 is not set
+# CONFIG_VIDEO_KS0127 is not set
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_MT9V011 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA7110 is not set
+CONFIG_VIDEO_SAA711X=y
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_TVP514X is not set
+# CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_VPX3220 is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_SAA7185 is not set
+# CONFIG_VIDEO_ADV7170 is not set
+# CONFIG_VIDEO_ADV7175 is not set
+# CONFIG_VIDEO_THS7303 is not set
+# CONFIG_VIDEO_ADV7343 is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+CONFIG_USB_GSPCA=m
+# CONFIG_USB_M5602 is not set
+# CONFIG_USB_STV06XX is not set
+# CONFIG_USB_GL860 is not set
+# CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX is not set
+# CONFIG_USB_GSPCA_JEILINJ is not set
+# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_MR97310A is not set
+# CONFIG_USB_GSPCA_OV519 is not set
+# CONFIG_USB_GSPCA_OV534 is not set
+# CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7302 is not set
+# CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SN9C20X is not set
+# CONFIG_USB_GSPCA_SONIXB is not set
+# CONFIG_USB_GSPCA_SONIXJ is not set
+# CONFIG_USB_GSPCA_SPCA500 is not set
+# CONFIG_USB_GSPCA_SPCA501 is not set
+# CONFIG_USB_GSPCA_SPCA505 is not set
+# CONFIG_USB_GSPCA_SPCA506 is not set
+# CONFIG_USB_GSPCA_SPCA508 is not set
+# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_SQ905 is not set
+# CONFIG_USB_GSPCA_SQ905C is not set
+# CONFIG_USB_GSPCA_STK014 is not set
+# CONFIG_USB_GSPCA_STV0680 is not set
+# CONFIG_USB_GSPCA_SUNPLUS is not set
+# CONFIG_USB_GSPCA_T613 is not set
+# CONFIG_USB_GSPCA_TV8532 is not set
+# CONFIG_USB_GSPCA_VC032X is not set
+# CONFIG_USB_GSPCA_ZC3XX is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_HDPVR is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_CX231XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_ZC0301 is not set
+CONFIG_USB_PWC_INPUT_EVDEV=y
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_USB_S2255 is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_I2C_SI4713 is not set
+# CONFIG_RADIO_SI4713 is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_RADIO_SI470X is not set
+# CONFIG_USB_MR800 is not set
+# CONFIG_RADIO_TEA5764 is not set
+# CONFIG_RADIO_TEF6862 is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_OF is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_FSL_DIU=y
+# CONFIG_FB_IBM_GXT4500 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_LOGO is not set
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+# CONFIG_DRAGONRISE_FF is not set
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SMARTJOYPLUS=y
+# CONFIG_SMARTJOYPLUS_FF is not set
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+# CONFIG_THRUSTMASTER_FF is not set
+CONFIG_HID_ZEROPLUS=y
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_EHCI_BIG_ENDIAN_DESC=y
+# CONFIG_XPS_USB_HCD_XILINX is not set
+CONFIG_USB_EHCI_FSL=y
+CONFIG_USB_EHCI_HCD_PPC_OF=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+CONFIG_RTC_DRV_M41T80=y
+# CONFIG_RTC_DRV_M41T80_WDT is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_GENERIC is not set
+CONFIG_RTC_DRV_MPC5121=y
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+# CONFIG_FSL_DMA is not set
+CONFIG_MPC512X_DMA=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_XIP=y
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_IRQSTACKS is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_PPC_CLOCK=y
+CONFIG_PPC_LIB_RHEAP=y
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 7b3804a6e36..b5b25996079 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -137,8 +137,9 @@ CONFIG_TRACEPOINTS=y
CONFIG_MARKERS=y
CONFIG_OPROFILE=y
CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
+CONFIG_KPROBES=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_KRETPROBES=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
@@ -191,6 +192,7 @@ CONFIG_SCANLOG=m
CONFIG_LPARCFG=y
CONFIG_PPC_SMLPAR=y
CONFIG_CMM=y
+CONFIG_DTL=y
CONFIG_PPC_ISERIES=y
#
@@ -328,9 +330,10 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_KEXEC=y
# CONFIG_PHYP_DUMP is not set
CONFIG_IRQ_ALL_CPUS=y
-# CONFIG_NUMA is not set
+CONFIG_NUMA=y
+CONFIG_NODES_SHIFT=8
+CONFIG_MAX_ACTIVE_REGIONS=256
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -339,6 +342,7 @@ CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
+CONFIG_NEED_MULTIPLE_NODES=y
CONFIG_HAVE_MEMORY_PRESENT=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
@@ -354,11 +358,12 @@ CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_NODES_SPAN_OTHER_NODES=y
CONFIG_ARCH_MEMORY_PROBE=y
CONFIG_PPC_HAS_HASH_64K=y
# CONFIG_PPC_64K_PAGES is not set
CONFIG_FORCE_MAX_ZONEORDER=13
-# CONFIG_SCHED_SMT is not set
+CONFIG_SCHED_SMT=y
CONFIG_PROC_DEVICETREE=y
# CONFIG_CMDLINE_BOOL is not set
CONFIG_EXTRA_TARGETS=""
@@ -790,12 +795,12 @@ CONFIG_SCSI_IPR=y
CONFIG_SCSI_IPR_TRACE=y
CONFIG_SCSI_IPR_DUMP=y
# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLA_FC is not set
+CONFIG_SCSI_QLA_FC=m
# CONFIG_SCSI_QLA_ISCSI is not set
CONFIG_SCSI_LPFC=m
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
-CONFIG_SCSI_DEBUG=m
+# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
@@ -867,9 +872,8 @@ CONFIG_MD_AUTODETECT=y
CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
-CONFIG_MD_RAID10=y
-CONFIG_MD_RAID456=y
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
CONFIG_MD_MULTIPATH=m
CONFIG_MD_FAULTY=m
CONFIG_BLK_DEV_DM=y
@@ -984,7 +988,7 @@ CONFIG_ACENIC=m
CONFIG_ACENIC_OMIT_TIGON_I=y
# CONFIG_DL2K is not set
CONFIG_E1000=y
-# CONFIG_E1000E is not set
+CONFIG_E1000E=m
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
# CONFIG_NS83820 is not set
@@ -1006,19 +1010,19 @@ CONFIG_GELIC_WIRELESS=y
# CONFIG_ATL1E is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T1=m
+CONFIG_CHELSIO_T3=m
CONFIG_EHEA=m
# CONFIG_ENIC is not set
-# CONFIG_IXGBE is not set
+CONFIG_IXGBE=m
CONFIG_IXGB=m
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-# CONFIG_NETXEN_NIC is not set
+CONFIG_S2IO=m
+CONFIG_MYRI10GE=m
+CONFIG_NETXEN_NIC=m
# CONFIG_NIU is not set
CONFIG_PASEMI_MAC=y
-# CONFIG_MLX4_EN is not set
-# CONFIG_MLX4_CORE is not set
+CONFIG_MLX4_EN=m
+CONFIG_MLX4_CORE=m
# CONFIG_TEHUTI is not set
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
@@ -1169,7 +1173,7 @@ CONFIG_SERIAL_TXX9=y
CONFIG_HAS_TXX9_SERIAL=y
CONFIG_SERIAL_TXX9_NR_UARTS=6
CONFIG_SERIAL_TXX9_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_JSM=m
# CONFIG_SERIAL_OF_PLATFORM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
@@ -1586,7 +1590,7 @@ CONFIG_USB_DEVICEFS=y
CONFIG_USB_DEVICE_CLASS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
-# CONFIG_USB_MON is not set
+CONFIG_USB_MON=m
# CONFIG_USB_WUSB is not set
# CONFIG_USB_WUSB_CBAF is not set
@@ -1686,21 +1690,22 @@ CONFIG_USB_APPLEDISPLAY=m
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
CONFIG_INFINIBAND=m
-# CONFIG_INFINIBAND_USER_MAD is not set
-# CONFIG_INFINIBAND_USER_ACCESS is not set
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_USER_MEM=y
CONFIG_INFINIBAND_ADDR_TRANS=y
CONFIG_INFINIBAND_MTHCA=m
CONFIG_INFINIBAND_MTHCA_DEBUG=y
-# CONFIG_INFINIBAND_IPATH is not set
+CONFIG_INFINIBAND_IPATH=m
CONFIG_INFINIBAND_EHCA=m
# CONFIG_INFINIBAND_AMSO1100 is not set
-# CONFIG_MLX4_INFINIBAND is not set
+CONFIG_MLX4_INFINIBAND=m
# CONFIG_INFINIBAND_NES is not set
CONFIG_INFINIBAND_IPOIB=m
-# CONFIG_INFINIBAND_IPOIB_CM is not set
+CONFIG_INFINIBAND_IPOIB_CM=y
CONFIG_INFINIBAND_IPOIB_DEBUG=y
# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
-# CONFIG_INFINIBAND_SRP is not set
+CONFIG_INFINIBAND_SRP=m
CONFIG_INFINIBAND_ISER=m
CONFIG_EDAC=y
@@ -1798,7 +1803,7 @@ CONFIG_REISERFS_FS=y
CONFIG_REISERFS_FS_XATTR=y
CONFIG_REISERFS_FS_POSIX_ACL=y
CONFIG_REISERFS_FS_SECURITY=y
-CONFIG_JFS_FS=y
+CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y
CONFIG_JFS_SECURITY=y
# CONFIG_JFS_DEBUG is not set
@@ -1811,14 +1816,22 @@ CONFIG_XFS_POSIX_ACL=y
# CONFIG_XFS_RT is not set
# CONFIG_XFS_DEBUG is not set
# CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
+CONFIG_OCFS2_FS=m
+CONFIG_OCFS2_FS_O2CB=m
+CONFIG_OCFS2_FS_STATS=y
+CONFIG_OCFS2_DEBUG_MASKLOG=y
+# CONFIG_OCFS2_DEBUG_FS is not set
+# CONFIG_OCFS2_COMPAT_JBD is not set
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_NILFS2_FS=m
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=m
-# CONFIG_FUSE_FS is not set
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
@@ -1851,7 +1864,7 @@ CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
#
# Miscellaneous filesystems
@@ -2075,7 +2088,7 @@ CONFIG_XMON=y
CONFIG_XMON_DISASSEMBLY=y
CONFIG_DEBUGGER=y
CONFIG_IRQSTACKS=y
-# CONFIG_VIRQ_DEBUG is not set
+CONFIG_VIRQ_DEBUG=y
CONFIG_BOOTX_TEXT=y
# CONFIG_PPC_EARLY_DEBUG is not set
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index ca9ff9aad74..41de3ddc9f2 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -159,7 +159,7 @@ CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_KMOD=y
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_BLK_DEV_BSG=y
# CONFIG_BLK_DEV_INTEGRITY is not set
CONFIG_BLOCK_COMPAT=y
@@ -191,6 +191,7 @@ CONFIG_SCANLOG=m
CONFIG_LPARCFG=y
CONFIG_PPC_SMLPAR=y
CONFIG_CMM=y
+CONFIG_DTL=y
# CONFIG_PPC_ISERIES is not set
# CONFIG_PPC_PMAC is not set
# CONFIG_PPC_MAPLE is not set
@@ -255,7 +256,8 @@ CONFIG_KEXEC=y
# CONFIG_PHYP_DUMP is not set
CONFIG_IRQ_ALL_CPUS=y
CONFIG_NUMA=y
-CONFIG_NODES_SHIFT=4
+CONFIG_NODES_SHIFT=8
+CONFIG_MAX_ACTIVE_REGIONS=256
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
@@ -270,7 +272,9 @@ CONFIG_HAVE_MEMORY_PRESENT=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSEMEM_VMEMMAP=y
-# CONFIG_MEMORY_HOTPLUG is not set
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTPLUG_SPARSE=y
+CONFIG_MEMORY_HOTREMOVE=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_MIGRATION=y
@@ -705,7 +709,7 @@ CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
CONFIG_MD_RAID10=m
-# CONFIG_MD_RAID456 is not set
+CONFIG_MD_RAID456=m
CONFIG_MD_MULTIPATH=m
CONFIG_MD_FAULTY=m
CONFIG_BLK_DEV_DM=y
@@ -800,7 +804,7 @@ CONFIG_ACENIC=m
CONFIG_ACENIC_OMIT_TIGON_I=y
# CONFIG_DL2K is not set
CONFIG_E1000=y
-# CONFIG_E1000E is not set
+CONFIG_E1000E=m
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
# CONFIG_NS83820 is not set
@@ -818,18 +822,18 @@ CONFIG_TIGON3=y
# CONFIG_ATL1E is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T1=m
+CONFIG_CHELSIO_T3=m
CONFIG_EHEA=y
# CONFIG_ENIC is not set
-# CONFIG_IXGBE is not set
+CONFIG_IXGBE=m
CONFIG_IXGB=m
CONFIG_S2IO=m
-# CONFIG_MYRI10GE is not set
-# CONFIG_NETXEN_NIC is not set
+CONFIG_MYRI10GE=m
+CONFIG_NETXEN_NIC=m
# CONFIG_NIU is not set
-# CONFIG_MLX4_EN is not set
-# CONFIG_MLX4_CORE is not set
+CONFIG_MLX4_EN=m
+CONFIG_MLX4_CORE=m
# CONFIG_TEHUTI is not set
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
@@ -894,7 +898,7 @@ CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+CONFIG_INPUT_EVDEV=m
# CONFIG_INPUT_EVBUG is not set
#
@@ -1271,7 +1275,7 @@ CONFIG_USB_DEVICEFS=y
CONFIG_USB_DEVICE_CLASS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
-CONFIG_USB_MON=y
+CONFIG_USB_MON=m
# CONFIG_USB_WUSB is not set
# CONFIG_USB_WUSB_CBAF is not set
@@ -1311,7 +1315,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
#
# may also be needed; see USB_STORAGE Help for more information
#
-CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
@@ -1322,7 +1326,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_ALAUDA is not set
-CONFIG_USB_STORAGE_ONETOUCH=y
+# CONFIG_USB_STORAGE_ONETOUCH is not set
# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
# CONFIG_USB_LIBUSUAL is not set
@@ -1377,17 +1381,17 @@ CONFIG_INFINIBAND_USER_MEM=y
CONFIG_INFINIBAND_ADDR_TRANS=y
CONFIG_INFINIBAND_MTHCA=m
CONFIG_INFINIBAND_MTHCA_DEBUG=y
-# CONFIG_INFINIBAND_IPATH is not set
+CONFIG_INFINIBAND_IPATH=m
CONFIG_INFINIBAND_EHCA=m
# CONFIG_INFINIBAND_AMSO1100 is not set
-# CONFIG_MLX4_INFINIBAND is not set
+CONFIG_MLX4_INFINIBAND=m
# CONFIG_INFINIBAND_NES is not set
CONFIG_INFINIBAND_IPOIB=m
-# CONFIG_INFINIBAND_IPOIB_CM is not set
+CONFIG_INFINIBAND_IPOIB_CM=y
CONFIG_INFINIBAND_IPOIB_DEBUG=y
# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
CONFIG_INFINIBAND_SRP=m
-# CONFIG_INFINIBAND_ISER is not set
+CONFIG_INFINIBAND_ISER=m
# CONFIG_EDAC is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
@@ -1443,6 +1447,9 @@ CONFIG_OCFS2_FS_STATS=y
CONFIG_OCFS2_DEBUG_MASKLOG=y
# CONFIG_OCFS2_DEBUG_FS is not set
# CONFIG_OCFS2_COMPAT_JBD is not set
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_NILFS2_FS=m
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1455,8 +1462,8 @@ CONFIG_FUSE_FS=m
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
CONFIG_UDF_FS=m
CONFIG_UDF_NLS=y
@@ -1508,14 +1515,14 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
-CONFIG_NFSD=y
+CONFIG_NFSD=m
CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
+CONFIG_EXPORTFS=m
CONFIG_NFS_ACL_SUPPORT=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
@@ -1681,12 +1688,12 @@ CONFIG_DYNAMIC_PRINTK_DEBUG=y
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
CONFIG_DEBUG_STACKOVERFLOW=y
-# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_STACK_USAGE=y
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_HCALL_STATS is not set
-# CONFIG_CODE_PATCHING_SELFTEST is not set
-# CONFIG_FTR_FIXUP_SELFTEST is not set
-# CONFIG_MSI_BITMAP_SELFTEST is not set
+CONFIG_CODE_PATCHING_SELFTEST=y
+CONFIG_FTR_FIXUP_SELFTEST=y
+CONFIG_MSI_BITMAP_SELFTEST=y
CONFIG_XMON=y
CONFIG_XMON_DEFAULT=y
CONFIG_XMON_DISASSEMBLY=y
diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h
index 8f0fe797194..c1b475a941e 100644
--- a/arch/powerpc/include/asm/asm-compat.h
+++ b/arch/powerpc/include/asm/asm-compat.h
@@ -2,6 +2,7 @@
#define _ASM_POWERPC_ASM_COMPAT_H
#include <asm/types.h>
+#include <asm/ppc-opcode.h>
#ifdef __ASSEMBLY__
# define stringify_in_c(...) __VA_ARGS__
@@ -24,7 +25,7 @@
#define PPC_LONG stringify_in_c(.llong)
#define PPC_LONG_ALIGN stringify_in_c(.balign 8)
#define PPC_TLNEI stringify_in_c(tdnei)
-#define PPC_LLARX stringify_in_c(ldarx)
+#define PPC_LLARX(t, a, b, eh) PPC_LDARX(t, a, b, eh)
#define PPC_STLCX stringify_in_c(stdcx.)
#define PPC_CNTLZL stringify_in_c(cntlzd)
@@ -46,7 +47,7 @@
#define PPC_LONG stringify_in_c(.long)
#define PPC_LONG_ALIGN stringify_in_c(.balign 4)
#define PPC_TLNEI stringify_in_c(twnei)
-#define PPC_LLARX stringify_in_c(lwarx)
+#define PPC_LLARX(t, a, b, eh) PPC_LWARX(t, a, b, eh)
#define PPC_STLCX stringify_in_c(stwcx.)
#define PPC_CNTLZL stringify_in_c(cntlzw)
#define PPC_MTOCRF stringify_in_c(mtcrf)
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
index 4012483b189..b8f152ece02 100644
--- a/arch/powerpc/include/asm/atomic.h
+++ b/arch/powerpc/include/asm/atomic.h
@@ -49,13 +49,13 @@ static __inline__ int atomic_add_return(int a, atomic_t *v)
int t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%2 # atomic_add_return\n\
add %0,%1,%0\n"
PPC405_ERR77(0,%2)
" stwcx. %0,0,%2 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (a), "r" (&v->counter)
: "cc", "memory");
@@ -85,13 +85,13 @@ static __inline__ int atomic_sub_return(int a, atomic_t *v)
int t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%2 # atomic_sub_return\n\
subf %0,%1,%0\n"
PPC405_ERR77(0,%2)
" stwcx. %0,0,%2 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (a), "r" (&v->counter)
: "cc", "memory");
@@ -119,13 +119,13 @@ static __inline__ int atomic_inc_return(atomic_t *v)
int t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%1 # atomic_inc_return\n\
addic %0,%0,1\n"
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (&v->counter)
: "cc", "xer", "memory");
@@ -163,13 +163,13 @@ static __inline__ int atomic_dec_return(atomic_t *v)
int t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%1 # atomic_dec_return\n\
addic %0,%0,-1\n"
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (&v->counter)
: "cc", "xer", "memory");
@@ -194,7 +194,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
int t;
__asm__ __volatile__ (
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%1 # atomic_add_unless\n\
cmpw 0,%0,%3 \n\
beq- 2f \n\
@@ -202,7 +202,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
PPC405_ERR77(0,%2)
" stwcx. %0,0,%1 \n\
bne- 1b \n"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
" subf %0,%2,%0 \n\
2:"
: "=&r" (t)
@@ -227,7 +227,7 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v)
int t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%1 # atomic_dec_if_positive\n\
cmpwi %0,1\n\
addi %0,%0,-1\n\
@@ -235,7 +235,7 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v)
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
"\n\
2:" : "=&b" (t)
: "r" (&v->counter)
@@ -286,12 +286,12 @@ static __inline__ long atomic64_add_return(long a, atomic64_t *v)
long t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%2 # atomic64_add_return\n\
add %0,%1,%0\n\
stdcx. %0,0,%2 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (a), "r" (&v->counter)
: "cc", "memory");
@@ -320,12 +320,12 @@ static __inline__ long atomic64_sub_return(long a, atomic64_t *v)
long t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%2 # atomic64_sub_return\n\
subf %0,%1,%0\n\
stdcx. %0,0,%2 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (a), "r" (&v->counter)
: "cc", "memory");
@@ -352,12 +352,12 @@ static __inline__ long atomic64_inc_return(atomic64_t *v)
long t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%1 # atomic64_inc_return\n\
addic %0,%0,1\n\
stdcx. %0,0,%1 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (&v->counter)
: "cc", "xer", "memory");
@@ -394,12 +394,12 @@ static __inline__ long atomic64_dec_return(atomic64_t *v)
long t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%1 # atomic64_dec_return\n\
addic %0,%0,-1\n\
stdcx. %0,0,%1\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (&v->counter)
: "cc", "xer", "memory");
@@ -419,13 +419,13 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
long t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%1 # atomic64_dec_if_positive\n\
addic. %0,%0,-1\n\
blt- 2f\n\
stdcx. %0,0,%1\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
"\n\
2:" : "=&r" (t)
: "r" (&v->counter)
@@ -451,14 +451,14 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
long t;
__asm__ __volatile__ (
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%1 # atomic_add_unless\n\
cmpd 0,%0,%3 \n\
beq- 2f \n\
add %0,%2,%0 \n"
" stdcx. %0,0,%1 \n\
bne- 1b \n"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
" subf %0,%2,%0 \n\
2:"
: "=&r" (t)
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h
index 56f2f2ea563..30964ae2d09 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -65,7 +65,7 @@ static __inline__ void fn(unsigned long mask, \
unsigned long *p = (unsigned long *)_p; \
__asm__ __volatile__ ( \
prefix \
-"1:" PPC_LLARX "%0,0,%3\n" \
+"1:" PPC_LLARX(%0,0,%3,0) "\n" \
stringify_in_c(op) "%0,%0,%2\n" \
PPC405_ERR77(0,%3) \
PPC_STLCX "%0,0,%3\n" \
@@ -78,7 +78,7 @@ static __inline__ void fn(unsigned long mask, \
DEFINE_BITOP(set_bits, or, "", "")
DEFINE_BITOP(clear_bits, andc, "", "")
-DEFINE_BITOP(clear_bits_unlock, andc, LWSYNC_ON_SMP, "")
+DEFINE_BITOP(clear_bits_unlock, andc, PPC_RELEASE_BARRIER, "")
DEFINE_BITOP(change_bits, xor, "", "")
static __inline__ void set_bit(int nr, volatile unsigned long *addr)
@@ -103,31 +103,35 @@ static __inline__ void change_bit(int nr, volatile unsigned long *addr)
/* Like DEFINE_BITOP(), with changes to the arguments to 'op' and the output
* operands. */
-#define DEFINE_TESTOP(fn, op, prefix, postfix) \
-static __inline__ unsigned long fn( \
- unsigned long mask, \
- volatile unsigned long *_p) \
-{ \
- unsigned long old, t; \
- unsigned long *p = (unsigned long *)_p; \
- __asm__ __volatile__ ( \
- prefix \
-"1:" PPC_LLARX "%0,0,%3\n" \
- stringify_in_c(op) "%1,%0,%2\n" \
- PPC405_ERR77(0,%3) \
- PPC_STLCX "%1,0,%3\n" \
- "bne- 1b\n" \
- postfix \
- : "=&r" (old), "=&r" (t) \
- : "r" (mask), "r" (p) \
- : "cc", "memory"); \
- return (old & mask); \
+#define DEFINE_TESTOP(fn, op, prefix, postfix, eh) \
+static __inline__ unsigned long fn( \
+ unsigned long mask, \
+ volatile unsigned long *_p) \
+{ \
+ unsigned long old, t; \
+ unsigned long *p = (unsigned long *)_p; \
+ __asm__ __volatile__ ( \
+ prefix \
+"1:" PPC_LLARX(%0,0,%3,eh) "\n" \
+ stringify_in_c(op) "%1,%0,%2\n" \
+ PPC405_ERR77(0,%3) \
+ PPC_STLCX "%1,0,%3\n" \
+ "bne- 1b\n" \
+ postfix \
+ : "=&r" (old), "=&r" (t) \
+ : "r" (mask), "r" (p) \
+ : "cc", "memory"); \
+ return (old & mask); \
}
-DEFINE_TESTOP(test_and_set_bits, or, LWSYNC_ON_SMP, ISYNC_ON_SMP)
-DEFINE_TESTOP(test_and_set_bits_lock, or, "", ISYNC_ON_SMP)
-DEFINE_TESTOP(test_and_clear_bits, andc, LWSYNC_ON_SMP, ISYNC_ON_SMP)
-DEFINE_TESTOP(test_and_change_bits, xor, LWSYNC_ON_SMP, ISYNC_ON_SMP)
+DEFINE_TESTOP(test_and_set_bits, or, PPC_RELEASE_BARRIER,
+ PPC_ACQUIRE_BARRIER, 0)
+DEFINE_TESTOP(test_and_set_bits_lock, or, "",
+ PPC_ACQUIRE_BARRIER, 1)
+DEFINE_TESTOP(test_and_clear_bits, andc, PPC_RELEASE_BARRIER,
+ PPC_ACQUIRE_BARRIER, 0)
+DEFINE_TESTOP(test_and_change_bits, xor, PPC_RELEASE_BARRIER,
+ PPC_ACQUIRE_BARRIER, 0)
static __inline__ int test_and_set_bit(unsigned long nr,
volatile unsigned long *addr)
@@ -158,7 +162,7 @@ static __inline__ int test_and_change_bit(unsigned long nr,
static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr)
{
- __asm__ __volatile__(LWSYNC_ON_SMP "" ::: "memory");
+ __asm__ __volatile__(PPC_RELEASE_BARRIER "" ::: "memory");
__clear_bit(nr, addr);
}
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 80f315e8a42..abb833b0e58 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -381,9 +381,9 @@ extern const char *powerpc_base_platform;
#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
/* 64-bit CPUs */
-#define CPU_FTRS_POWER3 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
+#define CPU_FTRS_POWER3 (CPU_FTR_USE_TB | \
CPU_FTR_IABR | CPU_FTR_PPC_LE)
-#define CPU_FTRS_RS64 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
+#define CPU_FTRS_RS64 (CPU_FTR_USE_TB | \
CPU_FTR_IABR | \
CPU_FTR_MMCRA | CPU_FTR_CTRL)
#define CPU_FTRS_POWER4 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h
index fa19f3fe05f..8bdc6a9e577 100644
--- a/arch/powerpc/include/asm/cputime.h
+++ b/arch/powerpc/include/asm/cputime.h
@@ -73,10 +73,9 @@ static inline unsigned long cputime_to_jiffies(const cputime_t ct)
static inline cputime_t cputime_to_scaled(const cputime_t ct)
{
if (cpu_has_feature(CPU_FTR_SPURR) &&
- per_cpu(cputime_last_delta, smp_processor_id()))
- return ct *
- per_cpu(cputime_scaled_last_delta, smp_processor_id())/
- per_cpu(cputime_last_delta, smp_processor_id());
+ __get_cpu_var(cputime_last_delta))
+ return ct * __get_cpu_var(cputime_scaled_last_delta) /
+ __get_cpu_var(cputime_last_delta);
return ct;
}
diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h
index cbd4dfa4bce..96a7d067fbb 100644
--- a/arch/powerpc/include/asm/feature-fixups.h
+++ b/arch/powerpc/include/asm/feature-fixups.h
@@ -165,7 +165,7 @@ label##2: \
.pushsection sect,"a"; \
.align 2; \
label##3: \
- .long label##1b-label##3b; \
+ FTR_ENTRY_OFFSET label##1b-label##3b; \
.popsection;
#endif /* __ASM_POWERPC_FEATURE_FIXUPS_H */
diff --git a/arch/powerpc/include/asm/futex.h b/arch/powerpc/include/asm/futex.h
index 9696cc36d2d..7c589ef81fb 100644
--- a/arch/powerpc/include/asm/futex.h
+++ b/arch/powerpc/include/asm/futex.h
@@ -11,7 +11,7 @@
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
__asm__ __volatile ( \
- LWSYNC_ON_SMP \
+ PPC_RELEASE_BARRIER \
"1: lwarx %0,0,%2\n" \
insn \
PPC405_ERR77(0, %2) \
@@ -90,14 +90,14 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
return -EFAULT;
__asm__ __volatile__ (
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%2 # futex_atomic_cmpxchg_inatomic\n\
cmpw 0,%0,%3\n\
bne- 3f\n"
PPC405_ERR77(0,%2)
"2: stwcx. %4,0,%2\n\
bne- 1b\n"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
"3: .section .fixup,\"ax\"\n\
4: li %0,%5\n\
b 3b\n\
diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h
index fb3c05a0cbb..3147a297012 100644
--- a/arch/powerpc/include/asm/hardirq.h
+++ b/arch/powerpc/include/asm/hardirq.h
@@ -1 +1,29 @@
-#include <asm-generic/hardirq.h>
+#ifndef _ASM_POWERPC_HARDIRQ_H
+#define _ASM_POWERPC_HARDIRQ_H
+
+#include <linux/threads.h>
+#include <linux/irq.h>
+
+typedef struct {
+ unsigned int __softirq_pending;
+ unsigned int timer_irqs;
+ unsigned int pmu_irqs;
+ unsigned int mce_exceptions;
+ unsigned int spurious_irqs;
+} ____cacheline_aligned irq_cpustat_t;
+
+DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+
+#define __ARCH_IRQ_STAT
+
+#define local_softirq_pending() __get_cpu_var(irq_stat).__softirq_pending
+
+static inline void ack_bad_irq(unsigned int irq)
+{
+ printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
+}
+
+extern u64 arch_irq_stat_cpu(unsigned int cpu);
+#define arch_irq_stat_cpu arch_irq_stat_cpu
+
+#endif /* _ASM_POWERPC_HARDIRQ_H */
diff --git a/arch/powerpc/include/asm/local.h b/arch/powerpc/include/asm/local.h
index 84b457a3c1b..ce58c80e1bc 100644
--- a/arch/powerpc/include/asm/local.h
+++ b/arch/powerpc/include/asm/local.h
@@ -24,7 +24,7 @@ static __inline__ long local_add_return(long a, local_t *l)
long t;
__asm__ __volatile__(
-"1:" PPC_LLARX "%0,0,%2 # local_add_return\n\
+"1:" PPC_LLARX(%0,0,%2,0) " # local_add_return\n\
add %0,%1,%0\n"
PPC405_ERR77(0,%2)
PPC_STLCX "%0,0,%2 \n\
@@ -43,7 +43,7 @@ static __inline__ long local_sub_return(long a, local_t *l)
long t;
__asm__ __volatile__(
-"1:" PPC_LLARX "%0,0,%2 # local_sub_return\n\
+"1:" PPC_LLARX(%0,0,%2,0) " # local_sub_return\n\
subf %0,%1,%0\n"
PPC405_ERR77(0,%2)
PPC_STLCX "%0,0,%2 \n\
@@ -60,7 +60,7 @@ static __inline__ long local_inc_return(local_t *l)
long t;
__asm__ __volatile__(
-"1:" PPC_LLARX "%0,0,%1 # local_inc_return\n\
+"1:" PPC_LLARX(%0,0,%1,0) " # local_inc_return\n\
addic %0,%0,1\n"
PPC405_ERR77(0,%1)
PPC_STLCX "%0,0,%1 \n\
@@ -87,7 +87,7 @@ static __inline__ long local_dec_return(local_t *l)
long t;
__asm__ __volatile__(
-"1:" PPC_LLARX "%0,0,%1 # local_dec_return\n\
+"1:" PPC_LLARX(%0,0,%1,0) " # local_dec_return\n\
addic %0,%0,-1\n"
PPC405_ERR77(0,%1)
PPC_STLCX "%0,0,%1\n\
@@ -117,7 +117,7 @@ static __inline__ int local_add_unless(local_t *l, long a, long u)
long t;
__asm__ __volatile__ (
-"1:" PPC_LLARX "%0,0,%1 # local_add_unless\n\
+"1:" PPC_LLARX(%0,0,%1,0) " # local_add_unless\n\
cmpw 0,%0,%3 \n\
beq- 2f \n\
add %0,%2,%0 \n"
@@ -147,7 +147,7 @@ static __inline__ long local_dec_if_positive(local_t *l)
long t;
__asm__ __volatile__(
-"1:" PPC_LLARX "%0,0,%1 # local_dec_if_positive\n\
+"1:" PPC_LLARX(%0,0,%1,0) " # local_dec_if_positive\n\
cmpwi %0,1\n\
addi %0,%0,-1\n\
blt- 2f\n"
diff --git a/arch/powerpc/include/asm/mpc5121.h b/arch/powerpc/include/asm/mpc5121.h
new file mode 100644
index 00000000000..e6a30bb1d16
--- /dev/null
+++ b/arch/powerpc/include/asm/mpc5121.h
@@ -0,0 +1,24 @@
+/*
+ * MPC5121 Prototypes and definitions
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.
+ */
+
+#ifndef __ASM_POWERPC_MPC5121_H__
+#define __ASM_POWERPC_MPC5121_H__
+
+/* MPC512x Reset module registers */
+struct mpc512x_reset_module {
+ u32 rcwlr; /* Reset Configuration Word Low Register */
+ u32 rcwhr; /* Reset Configuration Word High Register */
+ u32 reserved1;
+ u32 reserved2;
+ u32 rsr; /* Reset Status Register */
+ u32 rmr; /* Reset Mode Register */
+ u32 rpr; /* Reset Protection Register */
+ u32 rcr; /* Reset Control Register */
+ u32 rcer; /* Reset Control Enable Register */
+};
+
+#endif /* __ASM_POWERPC_MPC5121_H__ */
diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h b/arch/powerpc/include/asm/mpc52xx_psc.h
index fb841205745..42561f4f032 100644
--- a/arch/powerpc/include/asm/mpc52xx_psc.h
+++ b/arch/powerpc/include/asm/mpc52xx_psc.h
@@ -25,7 +25,11 @@
#include <asm/types.h>
/* Max number of PSCs */
+#ifdef CONFIG_PPC_MPC512x
+#define MPC52xx_PSC_MAXNUM 12
+#else
#define MPC52xx_PSC_MAXNUM 6
+#endif
/* Programmable Serial Controller (PSC) status register bits */
#define MPC52xx_PSC_SR_UNEX_RX 0x0001
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index a002682f3a6..61913d9a21a 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -289,7 +289,7 @@ struct mpic
#ifdef CONFIG_MPIC_U3_HT_IRQS
/* The fixup table */
struct mpic_irq_fixup *fixups;
- spinlock_t fixup_lock;
+ raw_spinlock_t fixup_lock;
#endif
/* Register access method */
diff --git a/arch/powerpc/include/asm/mutex.h b/arch/powerpc/include/asm/mutex.h
index dabc01c727b..5399f7e1810 100644
--- a/arch/powerpc/include/asm/mutex.h
+++ b/arch/powerpc/include/asm/mutex.h
@@ -15,7 +15,7 @@ static inline int __mutex_cmpxchg_lock(atomic_t *v, int old, int new)
PPC405_ERR77(0,%1)
" stwcx. %3,0,%1\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
"\n\
2:"
: "=&r" (t)
@@ -35,7 +35,7 @@ static inline int __mutex_dec_return_lock(atomic_t *v)
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (t)
: "r" (&v->counter)
: "cc", "memory");
@@ -48,7 +48,7 @@ static inline int __mutex_inc_return_unlock(atomic_t *v)
int t;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%1 # mutex unlock\n\
addic %0,%0,1\n"
PPC405_ERR77(0,%1)
diff --git a/arch/powerpc/include/asm/param.h b/arch/powerpc/include/asm/param.h
index 094f63d4d5c..965d4542797 100644
--- a/arch/powerpc/include/asm/param.h
+++ b/arch/powerpc/include/asm/param.h
@@ -1,22 +1 @@
-#ifndef _ASM_POWERPC_PARAM_H
-#define _ASM_POWERPC_PARAM_H
-
-#ifdef __KERNEL__
-#define HZ CONFIG_HZ /* internal kernel timer frequency */
-#define USER_HZ 100 /* for user interfaces in "ticks" */
-#define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */
-#endif /* __KERNEL__ */
-
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE 4096
-
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
-
-#endif /* _ASM_POWERPC_PARAM_H */
+#include <asm-generic/param.h>
diff --git a/arch/powerpc/include/asm/pmac_feature.h b/arch/powerpc/include/asm/pmac_feature.h
index 877c35a4356..00eedc5a4e6 100644
--- a/arch/powerpc/include/asm/pmac_feature.h
+++ b/arch/powerpc/include/asm/pmac_feature.h
@@ -378,7 +378,7 @@ extern struct macio_chip* macio_find(struct device_node* child, int type);
* Those are exported by pmac feature for internal use by arch code
* only like the platform function callbacks, do not use directly in drivers
*/
-extern spinlock_t feature_lock;
+extern raw_spinlock_t feature_lock;
extern struct device_node *uninorth_node;
extern u32 __iomem *uninorth_base;
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index ef9aa84cac5..aea71479759 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -22,8 +22,10 @@
#define PPC_INST_DCBZL 0x7c2007ec
#define PPC_INST_ISEL 0x7c00001e
#define PPC_INST_ISEL_MASK 0xfc00003e
+#define PPC_INST_LDARX 0x7c0000a8
#define PPC_INST_LSWI 0x7c0004aa
#define PPC_INST_LSWX 0x7c00042a
+#define PPC_INST_LWARX 0x7c000029
#define PPC_INST_LWSYNC 0x7c2004ac
#define PPC_INST_LXVD2X 0x7c000698
#define PPC_INST_MCRXR 0x7c000400
@@ -55,15 +57,31 @@
#define __PPC_RA(a) (((a) & 0x1f) << 16)
#define __PPC_RB(b) (((b) & 0x1f) << 11)
#define __PPC_RS(s) (((s) & 0x1f) << 21)
+#define __PPC_RT(s) __PPC_RS(s)
#define __PPC_XS(s) ((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5))
#define __PPC_T_TLB(t) (((t) & 0x3) << 21)
#define __PPC_WC(w) (((w) & 0x3) << 21)
+/*
+ * Only use the larx hint bit on 64bit CPUs. Once we verify it doesn't have
+ * any side effects on all 32bit processors, we can do this all the time.
+ */
+#ifdef CONFIG_PPC64
+#define __PPC_EH(eh) (((eh) & 0x1) << 0)
+#else
+#define __PPC_EH(eh) 0
+#endif
/* Deal with instructions that older assemblers aren't aware of */
#define PPC_DCBAL(a, b) stringify_in_c(.long PPC_INST_DCBAL | \
__PPC_RA(a) | __PPC_RB(b))
#define PPC_DCBZL(a, b) stringify_in_c(.long PPC_INST_DCBZL | \
__PPC_RA(a) | __PPC_RB(b))
+#define PPC_LDARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LDARX | \
+ __PPC_RT(t) | __PPC_RA(a) | \
+ __PPC_RB(b) | __PPC_EH(eh))
+#define PPC_LWARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LWARX | \
+ __PPC_RT(t) | __PPC_RA(a) | \
+ __PPC_RB(b) | __PPC_EH(eh))
#define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \
__PPC_RB(b))
#define PPC_RFCI stringify_in_c(.long PPC_INST_RFCI)
diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h
index 2828f9d0f66..42fdff0e4b3 100644
--- a/arch/powerpc/include/asm/ppc-pci.h
+++ b/arch/powerpc/include/asm/ppc-pci.h
@@ -137,6 +137,11 @@ struct device_node * find_device_pe(struct device_node *dn);
void eeh_sysfs_add_device(struct pci_dev *pdev);
void eeh_sysfs_remove_device(struct pci_dev *pdev);
+static inline const char *eeh_pci_name(struct pci_dev *pdev)
+{
+ return pdev ? pci_name(pdev) : "<null>";
+}
+
#endif /* CONFIG_EEH */
#else /* CONFIG_PCI */
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 9eed29eee60..221ba624046 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -161,9 +161,41 @@ struct thread_struct {
#ifdef CONFIG_PPC32
void *pgdir; /* root of page-table tree */
#endif
-#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
- unsigned long dbcr0; /* debug control register values */
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+ /*
+ * The following help to manage the use of Debug Control Registers
+ * om the BookE platforms.
+ */
+ unsigned long dbcr0;
unsigned long dbcr1;
+#ifdef CONFIG_BOOKE
+ unsigned long dbcr2;
+#endif
+ /*
+ * The stored value of the DBSR register will be the value at the
+ * last debug interrupt. This register can only be read from the
+ * user (will never be written to) and has value while helping to
+ * describe the reason for the last debug trap. Torez
+ */
+ unsigned long dbsr;
+ /*
+ * The following will contain addresses used by debug applications
+ * to help trace and trap on particular address locations.
+ * The bits in the Debug Control Registers above help define which
+ * of the following registers will contain valid data and/or addresses.
+ */
+ unsigned long iac1;
+ unsigned long iac2;
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+ unsigned long iac3;
+ unsigned long iac4;
+#endif
+ unsigned long dac1;
+ unsigned long dac2;
+#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
+ unsigned long dvc1;
+ unsigned long dvc2;
+#endif
#endif
/* FP and VSX 0-31 register set */
double fpr[32][TS_FPRWIDTH];
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index cbd759e3cd7..b4510812656 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -24,6 +24,12 @@
* 2 of the License, or (at your option) any later version.
*/
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
#ifndef __ASSEMBLY__
struct pt_regs {
@@ -294,4 +300,75 @@ extern void user_disable_single_step(struct task_struct *);
#define PTRACE_SINGLEBLOCK 0x100 /* resume execution until next branch */
+#define PPC_PTRACE_GETHWDBGINFO 0x89
+#define PPC_PTRACE_SETHWDEBUG 0x88
+#define PPC_PTRACE_DELHWDEBUG 0x87
+
+#ifndef __ASSEMBLY__
+
+struct ppc_debug_info {
+ uint32_t version; /* Only version 1 exists to date */
+ uint32_t num_instruction_bps;
+ uint32_t num_data_bps;
+ uint32_t num_condition_regs;
+ uint32_t data_bp_alignment;
+ uint32_t sizeof_condition; /* size of the DVC register */
+ uint64_t features;
+};
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * features will have bits indication whether there is support for:
+ */
+#define PPC_DEBUG_FEATURE_INSN_BP_RANGE 0x0000000000000001
+#define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x0000000000000002
+#define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x0000000000000004
+#define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x0000000000000008
+
+#ifndef __ASSEMBLY__
+
+struct ppc_hw_breakpoint {
+ uint32_t version; /* currently, version must be 1 */
+ uint32_t trigger_type; /* only some combinations allowed */
+ uint32_t addr_mode; /* address match mode */
+ uint32_t condition_mode; /* break/watchpoint condition flags */
+ uint64_t addr; /* break/watchpoint address */
+ uint64_t addr2; /* range end or mask */
+ uint64_t condition_value; /* contents of the DVC register */
+};
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Trigger Type
+ */
+#define PPC_BREAKPOINT_TRIGGER_EXECUTE 0x00000001
+#define PPC_BREAKPOINT_TRIGGER_READ 0x00000002
+#define PPC_BREAKPOINT_TRIGGER_WRITE 0x00000004
+#define PPC_BREAKPOINT_TRIGGER_RW \
+ (PPC_BREAKPOINT_TRIGGER_READ | PPC_BREAKPOINT_TRIGGER_WRITE)
+
+/*
+ * Address Mode
+ */
+#define PPC_BREAKPOINT_MODE_EXACT 0x00000000
+#define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE 0x00000001
+#define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE 0x00000002
+#define PPC_BREAKPOINT_MODE_MASK 0x00000003
+
+/*
+ * Condition Mode
+ */
+#define PPC_BREAKPOINT_CONDITION_MODE 0x00000003
+#define PPC_BREAKPOINT_CONDITION_NONE 0x00000000
+#define PPC_BREAKPOINT_CONDITION_AND 0x00000001
+#define PPC_BREAKPOINT_CONDITION_EXACT PPC_BREAKPOINT_CONDITION_AND
+#define PPC_BREAKPOINT_CONDITION_OR 0x00000002
+#define PPC_BREAKPOINT_CONDITION_AND_OR 0x00000003
+#define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000
+#define PPC_BREAKPOINT_CONDITION_BE_SHIFT 16
+#define PPC_BREAKPOINT_CONDITION_BE(n) \
+ (1<<((n)+PPC_BREAKPOINT_CONDITION_BE_SHIFT))
+
#endif /* _ASM_POWERPC_PTRACE_H */
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 3bf78350552..8808d307fe7 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -248,6 +248,8 @@
#define DBSR_RET 0x00008000 /* Return Debug Event */
#define DBSR_CIRPT 0x00000040 /* Critical Interrupt Taken Event */
#define DBSR_CRET 0x00000020 /* Critical Return Debug Event */
+#define DBSR_IAC12ATS 0x00000002 /* Instr Address Compare 1/2 Toggle */
+#define DBSR_IAC34ATS 0x00000001 /* Instr Address Compare 3/4 Toggle */
#endif
#ifdef CONFIG_40x
#define DBSR_IC 0x80000000 /* Instruction Completion */
@@ -313,6 +315,38 @@
#define DBCR0_IA12T 0x00008000 /* Instr Addr 1-2 range Toggle */
#define DBCR0_IA34T 0x00004000 /* Instr Addr 3-4 range Toggle */
#define DBCR0_FT 0x00000001 /* Freeze Timers on debug event */
+
+#define dbcr_iac_range(task) ((task)->thread.dbcr0)
+#define DBCR_IAC12I DBCR0_IA12 /* Range Inclusive */
+#define DBCR_IAC12X (DBCR0_IA12 | DBCR0_IA12X) /* Range Exclusive */
+#define DBCR_IAC12MODE (DBCR0_IA12 | DBCR0_IA12X) /* IAC 1-2 Mode Bits */
+#define DBCR_IAC34I DBCR0_IA34 /* Range Inclusive */
+#define DBCR_IAC34X (DBCR0_IA34 | DBCR0_IA34X) /* Range Exclusive */
+#define DBCR_IAC34MODE (DBCR0_IA34 | DBCR0_IA34X) /* IAC 3-4 Mode Bits */
+
+/* Bit definitions related to the DBCR1. */
+#define DBCR1_DAC1R 0x80000000 /* DAC1 Read Debug Event */
+#define DBCR1_DAC2R 0x40000000 /* DAC2 Read Debug Event */
+#define DBCR1_DAC1W 0x20000000 /* DAC1 Write Debug Event */
+#define DBCR1_DAC2W 0x10000000 /* DAC2 Write Debug Event */
+
+#define dbcr_dac(task) ((task)->thread.dbcr1)
+#define DBCR_DAC1R DBCR1_DAC1R
+#define DBCR_DAC1W DBCR1_DAC1W
+#define DBCR_DAC2R DBCR1_DAC2R
+#define DBCR_DAC2W DBCR1_DAC2W
+
+/*
+ * Are there any active Debug Events represented in the
+ * Debug Control Registers?
+ */
+#define DBCR0_ACTIVE_EVENTS (DBCR0_ICMP | DBCR0_IAC1 | DBCR0_IAC2 | \
+ DBCR0_IAC3 | DBCR0_IAC4)
+#define DBCR1_ACTIVE_EVENTS (DBCR1_DAC1R | DBCR1_DAC2R | \
+ DBCR1_DAC1W | DBCR1_DAC2W)
+#define DBCR_ACTIVE_EVENTS(dbcr0, dbcr1) (((dbcr0) & DBCR0_ACTIVE_EVENTS) || \
+ ((dbcr1) & DBCR1_ACTIVE_EVENTS))
+
#elif defined(CONFIG_BOOKE)
#define DBCR0_EDM 0x80000000 /* External Debug Mode */
#define DBCR0_IDM 0x40000000 /* Internal Debug Mode */
@@ -342,19 +376,79 @@
#define DBCR0_CRET 0x00000020 /* Critical Return Debug Event */
#define DBCR0_FT 0x00000001 /* Freeze Timers on debug event */
+#define dbcr_dac(task) ((task)->thread.dbcr0)
+#define DBCR_DAC1R DBCR0_DAC1R
+#define DBCR_DAC1W DBCR0_DAC1W
+#define DBCR_DAC2R DBCR0_DAC2R
+#define DBCR_DAC2W DBCR0_DAC2W
+
/* Bit definitions related to the DBCR1. */
+#define DBCR1_IAC1US 0xC0000000 /* Instr Addr Cmp 1 Sup/User */
+#define DBCR1_IAC1ER 0x30000000 /* Instr Addr Cmp 1 Eff/Real */
+#define DBCR1_IAC1ER_01 0x10000000 /* reserved */
+#define DBCR1_IAC1ER_10 0x20000000 /* Instr Addr Cmp 1 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC1ER_11 0x30000000 /* Instr Addr Cmp 1 Eff/Real MSR[IS]=1 */
+#define DBCR1_IAC2US 0x0C000000 /* Instr Addr Cmp 2 Sup/User */
+#define DBCR1_IAC2ER 0x03000000 /* Instr Addr Cmp 2 Eff/Real */
+#define DBCR1_IAC2ER_01 0x01000000 /* reserved */
+#define DBCR1_IAC2ER_10 0x02000000 /* Instr Addr Cmp 2 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC2ER_11 0x03000000 /* Instr Addr Cmp 2 Eff/Real MSR[IS]=1 */
#define DBCR1_IAC12M 0x00800000 /* Instr Addr 1-2 range enable */
#define DBCR1_IAC12MX 0x00C00000 /* Instr Addr 1-2 range eXclusive */
#define DBCR1_IAC12AT 0x00010000 /* Instr Addr 1-2 range Toggle */
+#define DBCR1_IAC3US 0x0000C000 /* Instr Addr Cmp 3 Sup/User */
+#define DBCR1_IAC3ER 0x00003000 /* Instr Addr Cmp 3 Eff/Real */
+#define DBCR1_IAC3ER_01 0x00001000 /* reserved */
+#define DBCR1_IAC3ER_10 0x00002000 /* Instr Addr Cmp 3 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC3ER_11 0x00003000 /* Instr Addr Cmp 3 Eff/Real MSR[IS]=1 */
+#define DBCR1_IAC4US 0x00000C00 /* Instr Addr Cmp 4 Sup/User */
+#define DBCR1_IAC4ER 0x00000300 /* Instr Addr Cmp 4 Eff/Real */
+#define DBCR1_IAC4ER_01 0x00000100 /* Instr Addr Cmp 4 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC4ER_10 0x00000200 /* Instr Addr Cmp 4 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC4ER_11 0x00000300 /* Instr Addr Cmp 4 Eff/Real MSR[IS]=1 */
#define DBCR1_IAC34M 0x00000080 /* Instr Addr 3-4 range enable */
#define DBCR1_IAC34MX 0x000000C0 /* Instr Addr 3-4 range eXclusive */
#define DBCR1_IAC34AT 0x00000001 /* Instr Addr 3-4 range Toggle */
+#define dbcr_iac_range(task) ((task)->thread.dbcr1)
+#define DBCR_IAC12I DBCR1_IAC12M /* Range Inclusive */
+#define DBCR_IAC12X DBCR1_IAC12MX /* Range Exclusive */
+#define DBCR_IAC12MODE DBCR1_IAC12MX /* IAC 1-2 Mode Bits */
+#define DBCR_IAC34I DBCR1_IAC34M /* Range Inclusive */
+#define DBCR_IAC34X DBCR1_IAC34MX /* Range Exclusive */
+#define DBCR_IAC34MODE DBCR1_IAC34MX /* IAC 3-4 Mode Bits */
+
/* Bit definitions related to the DBCR2. */
+#define DBCR2_DAC1US 0xC0000000 /* Data Addr Cmp 1 Sup/User */
+#define DBCR2_DAC1ER 0x30000000 /* Data Addr Cmp 1 Eff/Real */
+#define DBCR2_DAC2US 0x00000000 /* Data Addr Cmp 2 Sup/User */
+#define DBCR2_DAC2ER 0x00000000 /* Data Addr Cmp 2 Eff/Real */
#define DBCR2_DAC12M 0x00800000 /* DAC 1-2 range enable */
+#define DBCR2_DAC12MM 0x00400000 /* DAC 1-2 Mask mode*/
#define DBCR2_DAC12MX 0x00C00000 /* DAC 1-2 range eXclusive */
+#define DBCR2_DAC12MODE 0x00C00000 /* DAC 1-2 Mode Bits */
#define DBCR2_DAC12A 0x00200000 /* DAC 1-2 Asynchronous */
-#endif
+#define DBCR2_DVC1M 0x000C0000 /* Data Value Comp 1 Mode */
+#define DBCR2_DVC1M_SHIFT 18 /* # of bits to shift DBCR2_DVC1M */
+#define DBCR2_DVC2M 0x00030000 /* Data Value Comp 2 Mode */
+#define DBCR2_DVC2M_SHIFT 16 /* # of bits to shift DBCR2_DVC2M */
+#define DBCR2_DVC1BE 0x00000F00 /* Data Value Comp 1 Byte */
+#define DBCR2_DVC1BE_SHIFT 8 /* # of bits to shift DBCR2_DVC1BE */
+#define DBCR2_DVC2BE 0x0000000F /* Data Value Comp 2 Byte */
+#define DBCR2_DVC2BE_SHIFT 0 /* # of bits to shift DBCR2_DVC2BE */
+
+/*
+ * Are there any active Debug Events represented in the
+ * Debug Control Registers?
+ */
+#define DBCR0_ACTIVE_EVENTS (DBCR0_ICMP | DBCR0_IAC1 | DBCR0_IAC2 | \
+ DBCR0_IAC3 | DBCR0_IAC4 | DBCR0_DAC1R | \
+ DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W)
+#define DBCR1_ACTIVE_EVENTS 0
+
+#define DBCR_ACTIVE_EVENTS(dbcr0, dbcr1) (((dbcr0) & DBCR0_ACTIVE_EVENTS) || \
+ ((dbcr1) & DBCR1_ACTIVE_EVENTS))
+#endif /* #elif defined(CONFIG_BOOKE) */
/* Bit definitions related to the TCR. */
#define TCR_WP(x) (((x)&0x3)<<30) /* WDT Period */
diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h
index 764094cff68..f9611bd69ed 100644
--- a/arch/powerpc/include/asm/spinlock.h
+++ b/arch/powerpc/include/asm/spinlock.h
@@ -27,6 +27,7 @@
#endif
#include <asm/asm-compat.h>
#include <asm/synch.h>
+#include <asm/ppc-opcode.h>
#define arch_spin_is_locked(x) ((x)->slock != 0)
@@ -60,13 +61,14 @@ static inline unsigned long __arch_spin_trylock(arch_spinlock_t *lock)
token = LOCK_TOKEN;
__asm__ __volatile__(
-"1: lwarx %0,0,%2\n\
+"1: " PPC_LWARX(%0,0,%2,1) "\n\
cmpwi 0,%0,0\n\
bne- 2f\n\
stwcx. %1,0,%2\n\
- bne- 1b\n\
- isync\n\
-2:" : "=&r" (tmp)
+ bne- 1b\n"
+ PPC_ACQUIRE_BARRIER
+"2:"
+ : "=&r" (tmp)
: "r" (token), "r" (&lock->slock)
: "cr0", "memory");
@@ -144,7 +146,7 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
{
SYNC_IO;
__asm__ __volatile__("# arch_spin_unlock\n\t"
- LWSYNC_ON_SMP: : :"memory");
+ PPC_RELEASE_BARRIER: : :"memory");
lock->slock = 0;
}
@@ -186,15 +188,15 @@ static inline long __arch_read_trylock(arch_rwlock_t *rw)
long tmp;
__asm__ __volatile__(
-"1: lwarx %0,0,%1\n"
+"1: " PPC_LWARX(%0,0,%1,1) "\n"
__DO_SIGN_EXTEND
" addic. %0,%0,1\n\
ble- 2f\n"
PPC405_ERR77(0,%1)
" stwcx. %0,0,%1\n\
- bne- 1b\n\
- isync\n\
-2:" : "=&r" (tmp)
+ bne- 1b\n"
+ PPC_ACQUIRE_BARRIER
+"2:" : "=&r" (tmp)
: "r" (&rw->lock)
: "cr0", "xer", "memory");
@@ -211,14 +213,14 @@ static inline long __arch_write_trylock(arch_rwlock_t *rw)
token = WRLOCK_TOKEN;
__asm__ __volatile__(
-"1: lwarx %0,0,%2\n\
+"1: " PPC_LWARX(%0,0,%2,1) "\n\
cmpwi 0,%0,0\n\
bne- 2f\n"
PPC405_ERR77(0,%1)
" stwcx. %1,0,%2\n\
- bne- 1b\n\
- isync\n\
-2:" : "=&r" (tmp)
+ bne- 1b\n"
+ PPC_ACQUIRE_BARRIER
+"2:" : "=&r" (tmp)
: "r" (token), "r" (&rw->lock)
: "cr0", "memory");
@@ -269,7 +271,7 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
__asm__ __volatile__(
"# read_unlock\n\t"
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%1\n\
addic %0,%0,-1\n"
PPC405_ERR77(0,%1)
@@ -283,7 +285,7 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
static inline void arch_write_unlock(arch_rwlock_t *rw)
{
__asm__ __volatile__("# write_unlock\n\t"
- LWSYNC_ON_SMP: : :"memory");
+ PPC_RELEASE_BARRIER: : :"memory");
rw->lock = 0;
}
diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h
index 28f6ddbff4c..d7cab44643c 100644
--- a/arch/powerpc/include/asm/synch.h
+++ b/arch/powerpc/include/asm/synch.h
@@ -37,11 +37,15 @@ static inline void isync(void)
#endif
#ifdef CONFIG_SMP
-#define ISYNC_ON_SMP "\n\tisync\n"
-#define LWSYNC_ON_SMP stringify_in_c(LWSYNC) "\n"
+#define __PPC_ACQUIRE_BARRIER \
+ START_LWSYNC_SECTION(97); \
+ isync; \
+ MAKE_LWSYNC_SECTION_ENTRY(97, __lwsync_fixup);
+#define PPC_ACQUIRE_BARRIER "\n" stringify_in_c(__PPC_ACQUIRE_BARRIER)
+#define PPC_RELEASE_BARRIER stringify_in_c(LWSYNC) "\n"
#else
-#define ISYNC_ON_SMP
-#define LWSYNC_ON_SMP
+#define PPC_ACQUIRE_BARRIER
+#define PPC_RELEASE_BARRIER
#endif
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/system.h b/arch/powerpc/include/asm/system.h
index bb8e006a47c..a6297c67c3d 100644
--- a/arch/powerpc/include/asm/system.h
+++ b/arch/powerpc/include/asm/system.h
@@ -112,8 +112,13 @@ static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
#endif
extern int set_dabr(unsigned long dabr);
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+extern void do_send_trap(struct pt_regs *regs, unsigned long address,
+ unsigned long error_code, int signal_code, int brkpt);
+#else
extern void do_dabr(struct pt_regs *regs, unsigned long address,
unsigned long error_code);
+#endif
extern void print_backtrace(unsigned long *);
extern void show_regs(struct pt_regs * regs);
extern void flush_instruction_cache(void);
@@ -232,12 +237,12 @@ __xchg_u32(volatile void *p, unsigned long val)
unsigned long prev;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%2 \n"
PPC405_ERR77(0,%2)
" stwcx. %3,0,%2 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (prev), "+m" (*(volatile unsigned int *)p)
: "r" (p), "r" (val)
: "cc", "memory");
@@ -275,12 +280,12 @@ __xchg_u64(volatile void *p, unsigned long val)
unsigned long prev;
__asm__ __volatile__(
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%2 \n"
PPC405_ERR77(0,%2)
" stdcx. %3,0,%2 \n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
: "=&r" (prev), "+m" (*(volatile unsigned long *)p)
: "r" (p), "r" (val)
: "cc", "memory");
@@ -366,14 +371,14 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
unsigned int prev;
__asm__ __volatile__ (
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: lwarx %0,0,%2 # __cmpxchg_u32\n\
cmpw 0,%0,%3\n\
bne- 2f\n"
PPC405_ERR77(0,%2)
" stwcx. %4,0,%2\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
"\n\
2:"
: "=&r" (prev), "+m" (*p)
@@ -412,13 +417,13 @@ __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
unsigned long prev;
__asm__ __volatile__ (
- LWSYNC_ON_SMP
+ PPC_RELEASE_BARRIER
"1: ldarx %0,0,%2 # __cmpxchg_u64\n\
cmpd 0,%0,%3\n\
bne- 2f\n\
stdcx. %4,0,%2\n\
bne- 1b"
- ISYNC_ON_SMP
+ PPC_ACQUIRE_BARRIER
"\n\
2:"
: "=&r" (prev), "+m" (*p)
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index bbf89701d7a..8eaec310a25 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -38,27 +38,33 @@ static inline int pcibus_to_node(struct pci_bus *bus)
cpumask_of_node(pcibus_to_node(bus)))
/* sched_domains SD_NODE_INIT for PPC64 machines */
-#define SD_NODE_INIT (struct sched_domain) { \
- .parent = NULL, \
- .child = NULL, \
- .groups = NULL, \
- .min_interval = 8, \
- .max_interval = 32, \
- .busy_factor = 32, \
- .imbalance_pct = 125, \
- .cache_nice_tries = 1, \
- .busy_idx = 3, \
- .idle_idx = 1, \
- .newidle_idx = 0, \
- .wake_idx = 0, \
- .flags = SD_LOAD_BALANCE \
- | SD_BALANCE_EXEC \
- | SD_BALANCE_FORK \
- | SD_BALANCE_NEWIDLE \
- | SD_SERIALIZE, \
- .last_balance = jiffies, \
- .balance_interval = 1, \
- .nr_balance_failed = 0, \
+#define SD_NODE_INIT (struct sched_domain) { \
+ .min_interval = 8, \
+ .max_interval = 32, \
+ .busy_factor = 32, \
+ .imbalance_pct = 125, \
+ .cache_nice_tries = 1, \
+ .busy_idx = 3, \
+ .idle_idx = 1, \
+ .newidle_idx = 0, \
+ .wake_idx = 0, \
+ .forkexec_idx = 0, \
+ \
+ .flags = 1*SD_LOAD_BALANCE \
+ | 1*SD_BALANCE_NEWIDLE \
+ | 1*SD_BALANCE_EXEC \
+ | 1*SD_BALANCE_FORK \
+ | 0*SD_BALANCE_WAKE \
+ | 0*SD_WAKE_AFFINE \
+ | 0*SD_PREFER_LOCAL \
+ | 0*SD_SHARE_CPUPOWER \
+ | 0*SD_POWERSAVINGS_BALANCE \
+ | 0*SD_SHARE_PKG_RESOURCES \
+ | 1*SD_SERIALIZE \
+ | 0*SD_PREFER_SIBLING \
+ , \
+ .last_balance = jiffies, \
+ .balance_interval = 1, \
}
extern void __init dump_numa_cpu_topology(void);
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index bdcb557d470..07109d84378 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -791,9 +791,8 @@ _GLOBAL(enter_rtas)
li r9,1
rldicr r9,r9,MSR_SF_LG,(63-MSR_SF_LG)
- ori r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP
+ ori r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP|MSR_RI
andc r6,r0,r9
- ori r6,r6,MSR_RI
sync /* disable interrupts so SRR0/1 */
mtmsrd r0 /* don't get trashed */
diff --git a/arch/powerpc/kernel/firmware.c b/arch/powerpc/kernel/firmware.c
index 1679a70bbca..6b1f4271eb5 100644
--- a/arch/powerpc/kernel/firmware.c
+++ b/arch/powerpc/kernel/firmware.c
@@ -17,5 +17,5 @@
#include <asm/firmware.h>
-unsigned long powerpc_firmware_features;
+unsigned long powerpc_firmware_features __read_mostly;
EXPORT_SYMBOL_GPL(powerpc_firmware_features);
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 7f4bd7f3b6a..25793bb0e78 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -214,11 +214,11 @@ skpinv: addi r6,r6,1 /* Increment */
bl 1f /* Find our address */
1: mflr r9
rlwimi r7,r9,0,20,31
- addi r7,r7,24
+ addi r7,r7,(2f - 1b)
mtspr SPRN_SRR0,r7
mtspr SPRN_SRR1,r6
rfi
-
+2:
/* 4. Clear out PIDs & Search info */
li r6,0
mtspr SPRN_MAS6,r6
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 9040330b053..64f6f2031c2 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -73,8 +73,10 @@
#define CREATE_TRACE_POINTS
#include <asm/trace.h>
+DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+EXPORT_PER_CPU_SYMBOL(irq_stat);
+
int __irq_offset_value;
-static int ppc_spurious_interrupts;
#ifdef CONFIG_PPC32
EXPORT_SYMBOL(__irq_offset_value);
@@ -180,30 +182,64 @@ notrace void raw_local_irq_restore(unsigned long en)
EXPORT_SYMBOL(raw_local_irq_restore);
#endif /* CONFIG_PPC64 */
+static int show_other_interrupts(struct seq_file *p, int prec)
+{
+ int j;
+
+#if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT)
+ if (tau_initialized) {
+ seq_printf(p, "%*s: ", prec, "TAU");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", tau_interrupts(j));
+ seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n");
+ }
+#endif /* CONFIG_PPC32 && CONFIG_TAU_INT */
+
+ seq_printf(p, "%*s: ", prec, "LOC");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", per_cpu(irq_stat, j).timer_irqs);
+ seq_printf(p, " Local timer interrupts\n");
+
+ seq_printf(p, "%*s: ", prec, "SPU");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", per_cpu(irq_stat, j).spurious_irqs);
+ seq_printf(p, " Spurious interrupts\n");
+
+ seq_printf(p, "%*s: ", prec, "CNT");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", per_cpu(irq_stat, j).pmu_irqs);
+ seq_printf(p, " Performance monitoring interrupts\n");
+
+ seq_printf(p, "%*s: ", prec, "MCE");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", per_cpu(irq_stat, j).mce_exceptions);
+ seq_printf(p, " Machine check exceptions\n");
+
+ return 0;
+}
+
int show_interrupts(struct seq_file *p, void *v)
{
- int i = *(loff_t *)v, j;
+ unsigned long flags, any_count = 0;
+ int i = *(loff_t *) v, j, prec;
struct irqaction *action;
struct irq_desc *desc;
- unsigned long flags;
+ if (i > nr_irqs)
+ return 0;
+
+ for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec)
+ j *= 10;
+
+ if (i == nr_irqs)
+ return show_other_interrupts(p, prec);
+
+ /* print header */
if (i == 0) {
- seq_puts(p, " ");
+ seq_printf(p, "%*s", prec + 8, "");
for_each_online_cpu(j)
- seq_printf(p, "CPU%d ", j);
+ seq_printf(p, "CPU%-8d", j);
seq_putc(p, '\n');
- } else if (i == nr_irqs) {
-#if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT)
- if (tau_initialized){
- seq_puts(p, "TAU: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", tau_interrupts(j));
- seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n");
- }
-#endif /* CONFIG_PPC32 && CONFIG_TAU_INT*/
- seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
-
- return 0;
}
desc = irq_to_desc(i);
@@ -211,37 +247,48 @@ int show_interrupts(struct seq_file *p, void *v)
return 0;
raw_spin_lock_irqsave(&desc->lock, flags);
-
+ for_each_online_cpu(j)
+ any_count |= kstat_irqs_cpu(i, j);
action = desc->action;
- if (!action || !action->handler)
- goto skip;
+ if (!action && !any_count)
+ goto out;
- seq_printf(p, "%3d: ", i);
-#ifdef CONFIG_SMP
+ seq_printf(p, "%*d: ", prec, i);
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
-#else
- seq_printf(p, "%10u ", kstat_irqs(i));
-#endif /* CONFIG_SMP */
if (desc->chip)
- seq_printf(p, " %s ", desc->chip->name);
+ seq_printf(p, " %-16s", desc->chip->name);
else
- seq_puts(p, " None ");
+ seq_printf(p, " %-16s", "None");
+ seq_printf(p, " %-8s", (desc->status & IRQ_LEVEL) ? "Level" : "Edge");
- seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge ");
- seq_printf(p, " %s", action->name);
+ if (action) {
+ seq_printf(p, " %s", action->name);
+ while ((action = action->next) != NULL)
+ seq_printf(p, ", %s", action->name);
+ }
- for (action = action->next; action; action = action->next)
- seq_printf(p, ", %s", action->name);
seq_putc(p, '\n');
-
-skip:
+out:
raw_spin_unlock_irqrestore(&desc->lock, flags);
-
return 0;
}
+/*
+ * /proc/stat helpers
+ */
+u64 arch_irq_stat_cpu(unsigned int cpu)
+{
+ u64 sum = per_cpu(irq_stat, cpu).timer_irqs;
+
+ sum += per_cpu(irq_stat, cpu).pmu_irqs;
+ sum += per_cpu(irq_stat, cpu).mce_exceptions;
+ sum += per_cpu(irq_stat, cpu).spurious_irqs;
+
+ return sum;
+}
+
#ifdef CONFIG_HOTPLUG_CPU
void fixup_irqs(cpumask_t map)
{
@@ -353,8 +400,7 @@ void do_IRQ(struct pt_regs *regs)
if (irq != NO_IRQ && irq != NO_IRQ_IGNORE)
handle_one_irq(irq);
else if (irq != NO_IRQ_IGNORE)
- /* That's not SMP safe ... but who cares ? */
- ppc_spurious_interrupts++;
+ __get_cpu_var(irq_stat).spurious_irqs++;
irq_exit();
set_irq_regs(old_regs);
@@ -474,7 +520,7 @@ void do_softirq(void)
*/
static LIST_HEAD(irq_hosts);
-static DEFINE_SPINLOCK(irq_big_lock);
+static DEFINE_RAW_SPINLOCK(irq_big_lock);
static unsigned int revmap_trees_allocated;
static DEFINE_MUTEX(revmap_trees_mutex);
struct irq_map_entry irq_map[NR_IRQS];
@@ -520,14 +566,14 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
if (host->ops->match == NULL)
host->ops->match = default_irq_host_match;
- spin_lock_irqsave(&irq_big_lock, flags);
+ raw_spin_lock_irqsave(&irq_big_lock, flags);
/* If it's a legacy controller, check for duplicates and
* mark it as allocated (we use irq 0 host pointer for that
*/
if (revmap_type == IRQ_HOST_MAP_LEGACY) {
if (irq_map[0].host != NULL) {
- spin_unlock_irqrestore(&irq_big_lock, flags);
+ raw_spin_unlock_irqrestore(&irq_big_lock, flags);
/* If we are early boot, we can't free the structure,
* too bad...
* this will be fixed once slab is made available early
@@ -541,7 +587,7 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
}
list_add(&host->link, &irq_hosts);
- spin_unlock_irqrestore(&irq_big_lock, flags);
+ raw_spin_unlock_irqrestore(&irq_big_lock, flags);
/* Additional setups per revmap type */
switch(revmap_type) {
@@ -592,13 +638,13 @@ struct irq_host *irq_find_host(struct device_node *node)
* the absence of a device node. This isn't a problem so far
* yet though...
*/
- spin_lock_irqsave(&irq_big_lock, flags);
+ raw_spin_lock_irqsave(&irq_big_lock, flags);
list_for_each_entry(h, &irq_hosts, link)
if (h->ops->match(h, node)) {
found = h;
break;
}
- spin_unlock_irqrestore(&irq_big_lock, flags);
+ raw_spin_unlock_irqrestore(&irq_big_lock, flags);
return found;
}
EXPORT_SYMBOL_GPL(irq_find_host);
@@ -967,7 +1013,7 @@ unsigned int irq_alloc_virt(struct irq_host *host,
if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS))
return NO_IRQ;
- spin_lock_irqsave(&irq_big_lock, flags);
+ raw_spin_lock_irqsave(&irq_big_lock, flags);
/* Use hint for 1 interrupt if any */
if (count == 1 && hint >= NUM_ISA_INTERRUPTS &&
@@ -991,7 +1037,7 @@ unsigned int irq_alloc_virt(struct irq_host *host,
}
}
if (found == NO_IRQ) {
- spin_unlock_irqrestore(&irq_big_lock, flags);
+ raw_spin_unlock_irqrestore(&irq_big_lock, flags);
return NO_IRQ;
}
hint_found:
@@ -1000,7 +1046,7 @@ unsigned int irq_alloc_virt(struct irq_host *host,
smp_wmb();
irq_map[i].host = host;
}
- spin_unlock_irqrestore(&irq_big_lock, flags);
+ raw_spin_unlock_irqrestore(&irq_big_lock, flags);
return found;
}
@@ -1012,7 +1058,7 @@ void irq_free_virt(unsigned int virq, unsigned int count)
WARN_ON (virq < NUM_ISA_INTERRUPTS);
WARN_ON (count == 0 || (virq + count) > irq_virq_count);
- spin_lock_irqsave(&irq_big_lock, flags);
+ raw_spin_lock_irqsave(&irq_big_lock, flags);
for (i = virq; i < (virq + count); i++) {
struct irq_host *host;
@@ -1025,7 +1071,7 @@ void irq_free_virt(unsigned int virq, unsigned int count)
smp_wmb();
irq_map[i].host = NULL;
}
- spin_unlock_irqrestore(&irq_big_lock, flags);
+ raw_spin_unlock_irqrestore(&irq_big_lock, flags);
}
int arch_early_irq_init(void)
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index b6bd1eaa1c2..41bada0298c 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -333,7 +333,7 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
atomic_set(&kgdb_cpu_doing_single_step, -1);
/* set the trace bit if we're stepping */
if (remcom_in_buffer[0] == 's') {
-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
mtspr(SPRN_DBCR0,
mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
linux_regs->msr |= MSR_DE;
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index c9329786073..3fd1af90211 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -36,7 +36,7 @@
#include <asm/uaccess.h>
#include <asm/system.h>
-#ifdef CONFIG_BOOKE
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
#define MSR_SINGLESTEP (MSR_DE)
#else
#define MSR_SINGLESTEP (MSR_SE)
@@ -110,7 +110,7 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
* like Decrementer or External Interrupt */
regs->msr &= ~MSR_EE;
regs->msr |= MSR_SINGLESTEP;
-#ifdef CONFIG_BOOKE
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
regs->msr &= ~MSR_CE;
mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
#endif
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 79a00bb9c64..d09d1c61515 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -359,7 +359,7 @@ static void parse_system_parameter_string(struct seq_file *m)
unsigned char *local_buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
if (!local_buffer) {
- printk(KERN_ERR "%s %s kmalloc failure at line %d \n",
+ printk(KERN_ERR "%s %s kmalloc failure at line %d\n",
__FILE__, __func__, __LINE__);
return;
}
@@ -383,13 +383,13 @@ static void parse_system_parameter_string(struct seq_file *m)
int idx, w_idx;
char *workbuffer = kzalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
if (!workbuffer) {
- printk(KERN_ERR "%s %s kmalloc failure at line %d \n",
+ printk(KERN_ERR "%s %s kmalloc failure at line %d\n",
__FILE__, __func__, __LINE__);
kfree(local_buffer);
return;
}
#ifdef LPARCFG_DEBUG
- printk(KERN_INFO "success calling get-system-parameter \n");
+ printk(KERN_INFO "success calling get-system-parameter\n");
#endif
splpar_strlen = local_buffer[0] * 256 + local_buffer[1];
local_buffer += 2; /* step over strlen value */
@@ -440,7 +440,7 @@ static int lparcfg_count_active_processors(void)
while ((cpus_dn = of_find_node_by_type(cpus_dn, "cpu"))) {
#ifdef LPARCFG_DEBUG
- printk(KERN_ERR "cpus_dn %p \n", cpus_dn);
+ printk(KERN_ERR "cpus_dn %p\n", cpus_dn);
#endif
count++;
}
@@ -725,7 +725,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
const unsigned int *lp_index_ptr;
unsigned int lp_index = 0;
- seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
+ seq_printf(m, "%s %s\n", MODULE_NAME, MODULE_VERS);
rootdn = of_find_node_by_path("/");
if (rootdn) {
diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index ad461e735ae..9cf197f01e9 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -338,8 +338,8 @@ static int __init nvram_create_os_partition(void)
rc = nvram_write_header(new_part);
if (rc <= 0) {
- printk(KERN_ERR "nvram_create_os_partition: nvram_write_header \
- failed (%d)\n", rc);
+ printk(KERN_ERR "nvram_create_os_partition: nvram_write_header "
+ "failed (%d)\n", rc);
return rc;
}
@@ -349,7 +349,7 @@ static int __init nvram_create_os_partition(void)
rc = ppc_md.nvram_write((char *)&seq_init, sizeof(seq_init), &tmp_index);
if (rc <= 0) {
printk(KERN_ERR "nvram_create_os_partition: nvram_write "
- "failed (%d)\n", rc);
+ "failed (%d)\n", rc);
return rc;
}
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 4aa17401657..cd11d5ca80d 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -304,7 +304,7 @@ static void __devinit __of_scan_bus(struct device_node *node,
int reglen, devfn;
struct pci_dev *dev;
- pr_debug("of_scan_bus(%s) bus no %d... \n",
+ pr_debug("of_scan_bus(%s) bus no %d...\n",
node->full_name, bus->number);
/* Scan direct children */
diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c
index 0516e2d3e02..461499b43cf 100644
--- a/arch/powerpc/kernel/pmc.c
+++ b/arch/powerpc/kernel/pmc.c
@@ -37,7 +37,7 @@ static void dummy_perf(struct pt_regs *regs)
}
-static DEFINE_SPINLOCK(pmc_owner_lock);
+static DEFINE_RAW_SPINLOCK(pmc_owner_lock);
static void *pmc_owner_caller; /* mostly for debugging */
perf_irq_t perf_irq = dummy_perf;
@@ -45,7 +45,7 @@ int reserve_pmc_hardware(perf_irq_t new_perf_irq)
{
int err = 0;
- spin_lock(&pmc_owner_lock);
+ raw_spin_lock(&pmc_owner_lock);
if (pmc_owner_caller) {
printk(KERN_WARNING "reserve_pmc_hardware: "
@@ -59,21 +59,21 @@ int reserve_pmc_hardware(perf_irq_t new_perf_irq)
perf_irq = new_perf_irq ? new_perf_irq : dummy_perf;
out:
- spin_unlock(&pmc_owner_lock);
+ raw_spin_unlock(&pmc_owner_lock);
return err;
}
EXPORT_SYMBOL_GPL(reserve_pmc_hardware);
void release_pmc_hardware(void)
{
- spin_lock(&pmc_owner_lock);
+ raw_spin_lock(&pmc_owner_lock);
WARN_ON(! pmc_owner_caller);
pmc_owner_caller = NULL;
perf_irq = dummy_perf;
- spin_unlock(&pmc_owner_lock);
+ raw_spin_unlock(&pmc_owner_lock);
}
EXPORT_SYMBOL_GPL(release_pmc_hardware);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 7b816daf3eb..e4d71ced97e 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -245,6 +245,24 @@ void discard_lazy_cpu_state(void)
}
#endif /* CONFIG_SMP */
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+void do_send_trap(struct pt_regs *regs, unsigned long address,
+ unsigned long error_code, int signal_code, int breakpt)
+{
+ siginfo_t info;
+
+ if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
+ 11, SIGSEGV) == NOTIFY_STOP)
+ return;
+
+ /* Deliver the signal to userspace */
+ info.si_signo = SIGTRAP;
+ info.si_errno = breakpt; /* breakpoint or watchpoint id */
+ info.si_code = signal_code;
+ info.si_addr = (void __user *)address;
+ force_sig_info(SIGTRAP, &info, current);
+}
+#else /* !CONFIG_PPC_ADV_DEBUG_REGS */
void do_dabr(struct pt_regs *regs, unsigned long address,
unsigned long error_code)
{
@@ -257,12 +275,6 @@ void do_dabr(struct pt_regs *regs, unsigned long address,
if (debugger_dabr_match(regs))
return;
- /* Clear the DAC and struct entries. One shot trigger */
-#if defined(CONFIG_BOOKE)
- mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~(DBSR_DAC1R | DBSR_DAC1W
- | DBCR0_IDM));
-#endif
-
/* Clear the DABR */
set_dabr(0);
@@ -273,9 +285,82 @@ void do_dabr(struct pt_regs *regs, unsigned long address,
info.si_addr = (void __user *)address;
force_sig_info(SIGTRAP, &info, current);
}
+#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
static DEFINE_PER_CPU(unsigned long, current_dabr);
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+/*
+ * Set the debug registers back to their default "safe" values.
+ */
+static void set_debug_reg_defaults(struct thread_struct *thread)
+{
+ thread->iac1 = thread->iac2 = 0;
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+ thread->iac3 = thread->iac4 = 0;
+#endif
+ thread->dac1 = thread->dac2 = 0;
+#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
+ thread->dvc1 = thread->dvc2 = 0;
+#endif
+ thread->dbcr0 = 0;
+#ifdef CONFIG_BOOKE
+ /*
+ * Force User/Supervisor bits to b11 (user-only MSR[PR]=1)
+ */
+ thread->dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US | \
+ DBCR1_IAC3US | DBCR1_IAC4US;
+ /*
+ * Force Data Address Compare User/Supervisor bits to be User-only
+ * (0b11 MSR[PR]=1) and set all other bits in DBCR2 register to be 0.
+ */
+ thread->dbcr2 = DBCR2_DAC1US | DBCR2_DAC2US;
+#else
+ thread->dbcr1 = 0;
+#endif
+}
+
+static void prime_debug_regs(struct thread_struct *thread)
+{
+ mtspr(SPRN_IAC1, thread->iac1);
+ mtspr(SPRN_IAC2, thread->iac2);
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+ mtspr(SPRN_IAC3, thread->iac3);
+ mtspr(SPRN_IAC4, thread->iac4);
+#endif
+ mtspr(SPRN_DAC1, thread->dac1);
+ mtspr(SPRN_DAC2, thread->dac2);
+#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
+ mtspr(SPRN_DVC1, thread->dvc1);
+ mtspr(SPRN_DVC2, thread->dvc2);
+#endif
+ mtspr(SPRN_DBCR0, thread->dbcr0);
+ mtspr(SPRN_DBCR1, thread->dbcr1);
+#ifdef CONFIG_BOOKE
+ mtspr(SPRN_DBCR2, thread->dbcr2);
+#endif
+}
+/*
+ * Unless neither the old or new thread are making use of the
+ * debug registers, set the debug registers from the values
+ * stored in the new thread.
+ */
+static void switch_booke_debug_regs(struct thread_struct *new_thread)
+{
+ if ((current->thread.dbcr0 & DBCR0_IDM)
+ || (new_thread->dbcr0 & DBCR0_IDM))
+ prime_debug_regs(new_thread);
+}
+#else /* !CONFIG_PPC_ADV_DEBUG_REGS */
+static void set_debug_reg_defaults(struct thread_struct *thread)
+{
+ if (thread->dabr) {
+ thread->dabr = 0;
+ set_dabr(0);
+ }
+}
+#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
+
int set_dabr(unsigned long dabr)
{
__get_cpu_var(current_dabr) = dabr;
@@ -284,7 +369,7 @@ int set_dabr(unsigned long dabr)
return ppc_md.set_dabr(dabr);
/* XXX should we have a CPU_FTR_HAS_DABR ? */
-#if defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
mtspr(SPRN_DAC1, dabr);
#elif defined(CONFIG_PPC_BOOK3S)
mtspr(SPRN_DABR, dabr);
@@ -371,10 +456,8 @@ struct task_struct *__switch_to(struct task_struct *prev,
#endif /* CONFIG_SMP */
-#if defined(CONFIG_BOOKE)
- /* If new thread DAC (HW breakpoint) is the same then leave it */
- if (new->thread.dabr)
- set_dabr(new->thread.dabr);
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+ switch_booke_debug_regs(&new->thread);
#else
if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
set_dabr(new->thread.dabr);
@@ -514,7 +597,7 @@ void show_regs(struct pt_regs * regs)
printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer);
trap = TRAP(regs);
if (trap == 0x300 || trap == 0x600)
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr);
#else
printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
@@ -556,14 +639,7 @@ void flush_thread(void)
{
discard_lazy_cpu_state();
- if (current->thread.dabr) {
- current->thread.dabr = 0;
- set_dabr(0);
-
-#if defined(CONFIG_BOOKE)
- current->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W);
-#endif
- }
+ set_debug_reg_defaults(&current->thread);
}
void
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index bafac2e41ae..5f306c4946e 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -654,6 +654,9 @@ static void __init early_cmdline_parse(void)
#define OV5_CMO 0x00
#endif
+/* Option Vector 6: IBM PAPR hints */
+#define OV6_LINUX 0x02 /* Linux is our OS */
+
/*
* The architecture vector has an array of PVR mask/value pairs,
* followed by # option vectors - 1, followed by the option vectors.
@@ -665,7 +668,7 @@ static unsigned char ibm_architecture_vec[] = {
W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */
W(0xffffffff), W(0x0f000002), /* all 2.05-compliant */
W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
- 5 - 1, /* 5 option vectors */
+ 6 - 1, /* 6 option vectors */
/* option vector 1: processor architectures supported */
3 - 2, /* length */
@@ -697,12 +700,29 @@ static unsigned char ibm_architecture_vec[] = {
0, /* don't halt */
/* option vector 5: PAPR/OF options */
- 5 - 2, /* length */
+ 13 - 2, /* length */
0, /* don't ignore, don't halt */
OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
OV5_DONATE_DEDICATE_CPU | OV5_MSI,
0,
OV5_CMO,
+ 0,
+ 0,
+ 0,
+ 0,
+ /* WARNING: The offset of the "number of cores" field below
+ * must match by the macro below. Update the definition if
+ * the structure layout changes.
+ */
+#define IBM_ARCH_VEC_NRCORES_OFFSET 100
+ W(NR_CPUS), /* number of cores supported */
+
+ /* option vector 6: IBM PAPR hints */
+ 4 - 2, /* length */
+ 0,
+ 0,
+ OV6_LINUX,
+
};
/* Old method - ELF header with PT_NOTE sections */
@@ -792,13 +812,70 @@ static struct fake_elf {
}
};
+static int __init prom_count_smt_threads(void)
+{
+ phandle node;
+ char type[64];
+ unsigned int plen;
+
+ /* Pick up th first CPU node we can find */
+ for (node = 0; prom_next_node(&node); ) {
+ type[0] = 0;
+ prom_getprop(node, "device_type", type, sizeof(type));
+
+ if (strcmp(type, RELOC("cpu")))
+ continue;
+ /*
+ * There is an entry for each smt thread, each entry being
+ * 4 bytes long. All cpus should have the same number of
+ * smt threads, so return after finding the first.
+ */
+ plen = prom_getproplen(node, "ibm,ppc-interrupt-server#s");
+ if (plen == PROM_ERROR)
+ break;
+ plen >>= 2;
+ prom_debug("Found 0x%x smt threads per core\n", (unsigned long)plen);
+
+ /* Sanity check */
+ if (plen < 1 || plen > 64) {
+ prom_printf("Threads per core 0x%x out of bounds, assuming 1\n",
+ (unsigned long)plen);
+ return 1;
+ }
+ return plen;
+ }
+ prom_debug("No threads found, assuming 1 per core\n");
+
+ return 1;
+
+}
+
+
static void __init prom_send_capabilities(void)
{
ihandle elfloader, root;
prom_arg_t ret;
+ u32 *cores;
root = call_prom("open", 1, 1, ADDR("/"));
if (root != 0) {
+ /* We need to tell the FW about the number of cores we support.
+ *
+ * To do that, we count the number of threads on the first core
+ * (we assume this is the same for all cores) and use it to
+ * divide NR_CPUS.
+ */
+ cores = (u32 *)PTRRELOC(&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]);
+ if (*cores != NR_CPUS) {
+ prom_printf("WARNING ! "
+ "ibm_architecture_vec structure inconsistent: 0x%x !\n",
+ *cores);
+ } else {
+ *cores = NR_CPUS / prom_count_smt_threads();
+ prom_printf("Max number of cores passed to firmware: 0x%x\n",
+ (unsigned long)*cores);
+ }
+
/* try calling the ibm,client-architecture-support method */
prom_printf("Calling ibm,client-architecture-support...");
if (call_prom_ret("call-method", 3, 2, &ret,
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index ef149880c14..d9b05866615 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -46,7 +46,7 @@
/*
* Set of msr bits that gdb can change on behalf of a process.
*/
-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
#define MSR_DEBUGCHANGE 0
#else
#define MSR_DEBUGCHANGE (MSR_SE | MSR_BE)
@@ -703,7 +703,7 @@ void user_enable_single_step(struct task_struct *task)
struct pt_regs *regs = task->thread.regs;
if (regs != NULL) {
-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
task->thread.dbcr0 &= ~DBCR0_BT;
task->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC;
regs->msr |= MSR_DE;
@@ -720,7 +720,7 @@ void user_enable_block_step(struct task_struct *task)
struct pt_regs *regs = task->thread.regs;
if (regs != NULL) {
-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
task->thread.dbcr0 &= ~DBCR0_IC;
task->thread.dbcr0 = DBCR0_IDM | DBCR0_BT;
regs->msr |= MSR_DE;
@@ -737,17 +737,25 @@ void user_disable_single_step(struct task_struct *task)
struct pt_regs *regs = task->thread.regs;
if (regs != NULL) {
-#if defined(CONFIG_BOOKE)
- /* If DAC don't clear DBCRO_IDM or MSR_DE */
- if (task->thread.dabr)
- task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT);
- else {
- task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM);
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+ /*
+ * The logic to disable single stepping should be as
+ * simple as turning off the Instruction Complete flag.
+ * And, after doing so, if all debug flags are off, turn
+ * off DBCR0(IDM) and MSR(DE) .... Torez
+ */
+ task->thread.dbcr0 &= ~DBCR0_IC;
+ /*
+ * Test to see if any of the DBCR_ACTIVE_EVENTS bits are set.
+ */
+ if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0,
+ task->thread.dbcr1)) {
+ /*
+ * All debug events were off.....
+ */
+ task->thread.dbcr0 &= ~DBCR0_IDM;
regs->msr &= ~MSR_DE;
}
-#elif defined(CONFIG_40x)
- task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM);
- regs->msr &= ~MSR_DE;
#else
regs->msr &= ~(MSR_SE | MSR_BE);
#endif
@@ -769,8 +777,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
if ((data & ~0x7UL) >= TASK_SIZE)
return -EIO;
-#ifndef CONFIG_BOOKE
-
+#ifndef CONFIG_PPC_ADV_DEBUG_REGS
/* For processors using DABR (i.e. 970), the bottom 3 bits are flags.
* It was assumed, on previous implementations, that 3 bits were
* passed together with the data address, fitting the design of the
@@ -789,21 +796,22 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
/* Move contents to the DABR register */
task->thread.dabr = data;
-
-#endif
-#if defined(CONFIG_BOOKE)
-
+#else /* CONFIG_PPC_ADV_DEBUG_REGS */
/* As described above, it was assumed 3 bits were passed with the data
* address, but we will assume only the mode bits will be passed
* as to not cause alignment restrictions for DAC-based processors.
*/
/* DAC's hold the whole address without any mode flags */
- task->thread.dabr = data & ~0x3UL;
-
- if (task->thread.dabr == 0) {
- task->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W | DBCR0_IDM);
- task->thread.regs->msr &= ~MSR_DE;
+ task->thread.dac1 = data & ~0x3UL;
+
+ if (task->thread.dac1 == 0) {
+ dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W);
+ if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0,
+ task->thread.dbcr1)) {
+ task->thread.regs->msr &= ~MSR_DE;
+ task->thread.dbcr0 &= ~DBCR0_IDM;
+ }
return 0;
}
@@ -814,17 +822,17 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
/* Set the Internal Debugging flag (IDM bit 1) for the DBCR0
register */
- task->thread.dbcr0 = DBCR0_IDM;
+ task->thread.dbcr0 |= DBCR0_IDM;
/* Check for write and read flags and set DBCR0
accordingly */
+ dbcr_dac(task) &= ~(DBCR_DAC1R|DBCR_DAC1W);
if (data & 0x1UL)
- task->thread.dbcr0 |= DBSR_DAC1R;
+ dbcr_dac(task) |= DBCR_DAC1R;
if (data & 0x2UL)
- task->thread.dbcr0 |= DBSR_DAC1W;
-
+ dbcr_dac(task) |= DBCR_DAC1W;
task->thread.regs->msr |= MSR_DE;
-#endif
+#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
return 0;
}
@@ -839,6 +847,394 @@ void ptrace_disable(struct task_struct *child)
user_disable_single_step(child);
}
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+static long set_intruction_bp(struct task_struct *child,
+ struct ppc_hw_breakpoint *bp_info)
+{
+ int slot;
+ int slot1_in_use = ((child->thread.dbcr0 & DBCR0_IAC1) != 0);
+ int slot2_in_use = ((child->thread.dbcr0 & DBCR0_IAC2) != 0);
+ int slot3_in_use = ((child->thread.dbcr0 & DBCR0_IAC3) != 0);
+ int slot4_in_use = ((child->thread.dbcr0 & DBCR0_IAC4) != 0);
+
+ if (dbcr_iac_range(child) & DBCR_IAC12MODE)
+ slot2_in_use = 1;
+ if (dbcr_iac_range(child) & DBCR_IAC34MODE)
+ slot4_in_use = 1;
+
+ if (bp_info->addr >= TASK_SIZE)
+ return -EIO;
+
+ if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) {
+
+ /* Make sure range is valid. */
+ if (bp_info->addr2 >= TASK_SIZE)
+ return -EIO;
+
+ /* We need a pair of IAC regsisters */
+ if ((!slot1_in_use) && (!slot2_in_use)) {
+ slot = 1;
+ child->thread.iac1 = bp_info->addr;
+ child->thread.iac2 = bp_info->addr2;
+ child->thread.dbcr0 |= DBCR0_IAC1;
+ if (bp_info->addr_mode ==
+ PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
+ dbcr_iac_range(child) |= DBCR_IAC12X;
+ else
+ dbcr_iac_range(child) |= DBCR_IAC12I;
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+ } else if ((!slot3_in_use) && (!slot4_in_use)) {
+ slot = 3;
+ child->thread.iac3 = bp_info->addr;
+ child->thread.iac4 = bp_info->addr2;
+ child->thread.dbcr0 |= DBCR0_IAC3;
+ if (bp_info->addr_mode ==
+ PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
+ dbcr_iac_range(child) |= DBCR_IAC34X;
+ else
+ dbcr_iac_range(child) |= DBCR_IAC34I;
+#endif
+ } else
+ return -ENOSPC;
+ } else {
+ /* We only need one. If possible leave a pair free in
+ * case a range is needed later
+ */
+ if (!slot1_in_use) {
+ /*
+ * Don't use iac1 if iac1-iac2 are free and either
+ * iac3 or iac4 (but not both) are free
+ */
+ if (slot2_in_use || (slot3_in_use == slot4_in_use)) {
+ slot = 1;
+ child->thread.iac1 = bp_info->addr;
+ child->thread.dbcr0 |= DBCR0_IAC1;
+ goto out;
+ }
+ }
+ if (!slot2_in_use) {
+ slot = 2;
+ child->thread.iac2 = bp_info->addr;
+ child->thread.dbcr0 |= DBCR0_IAC2;
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+ } else if (!slot3_in_use) {
+ slot = 3;
+ child->thread.iac3 = bp_info->addr;
+ child->thread.dbcr0 |= DBCR0_IAC3;
+ } else if (!slot4_in_use) {
+ slot = 4;
+ child->thread.iac4 = bp_info->addr;
+ child->thread.dbcr0 |= DBCR0_IAC4;
+#endif
+ } else
+ return -ENOSPC;
+ }
+out:
+ child->thread.dbcr0 |= DBCR0_IDM;
+ child->thread.regs->msr |= MSR_DE;
+
+ return slot;
+}
+
+static int del_instruction_bp(struct task_struct *child, int slot)
+{
+ switch (slot) {
+ case 1:
+ if (child->thread.iac1 == 0)
+ return -ENOENT;
+
+ if (dbcr_iac_range(child) & DBCR_IAC12MODE) {
+ /* address range - clear slots 1 & 2 */
+ child->thread.iac2 = 0;
+ dbcr_iac_range(child) &= ~DBCR_IAC12MODE;
+ }
+ child->thread.iac1 = 0;
+ child->thread.dbcr0 &= ~DBCR0_IAC1;
+ break;
+ case 2:
+ if (child->thread.iac2 == 0)
+ return -ENOENT;
+
+ if (dbcr_iac_range(child) & DBCR_IAC12MODE)
+ /* used in a range */
+ return -EINVAL;
+ child->thread.iac2 = 0;
+ child->thread.dbcr0 &= ~DBCR0_IAC2;
+ break;
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+ case 3:
+ if (child->thread.iac3 == 0)
+ return -ENOENT;
+
+ if (dbcr_iac_range(child) & DBCR_IAC34MODE) {
+ /* address range - clear slots 3 & 4 */
+ child->thread.iac4 = 0;
+ dbcr_iac_range(child) &= ~DBCR_IAC34MODE;
+ }
+ child->thread.iac3 = 0;
+ child->thread.dbcr0 &= ~DBCR0_IAC3;
+ break;
+ case 4:
+ if (child->thread.iac4 == 0)
+ return -ENOENT;
+
+ if (dbcr_iac_range(child) & DBCR_IAC34MODE)
+ /* Used in a range */
+ return -EINVAL;
+ child->thread.iac4 = 0;
+ child->thread.dbcr0 &= ~DBCR0_IAC4;
+ break;
+#endif
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
+{
+ int byte_enable =
+ (bp_info->condition_mode >> PPC_BREAKPOINT_CONDITION_BE_SHIFT)
+ & 0xf;
+ int condition_mode =
+ bp_info->condition_mode & PPC_BREAKPOINT_CONDITION_MODE;
+ int slot;
+
+ if (byte_enable && (condition_mode == 0))
+ return -EINVAL;
+
+ if (bp_info->addr >= TASK_SIZE)
+ return -EIO;
+
+ if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0) {
+ slot = 1;
+ if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
+ dbcr_dac(child) |= DBCR_DAC1R;
+ if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
+ dbcr_dac(child) |= DBCR_DAC1W;
+ child->thread.dac1 = (unsigned long)bp_info->addr;
+#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
+ if (byte_enable) {
+ child->thread.dvc1 =
+ (unsigned long)bp_info->condition_value;
+ child->thread.dbcr2 |=
+ ((byte_enable << DBCR2_DVC1BE_SHIFT) |
+ (condition_mode << DBCR2_DVC1M_SHIFT));
+ }
+#endif
+#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
+ } else if (child->thread.dbcr2 & DBCR2_DAC12MODE) {
+ /* Both dac1 and dac2 are part of a range */
+ return -ENOSPC;
+#endif
+ } else if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0) {
+ slot = 2;
+ if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
+ dbcr_dac(child) |= DBCR_DAC2R;
+ if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
+ dbcr_dac(child) |= DBCR_DAC2W;
+ child->thread.dac2 = (unsigned long)bp_info->addr;
+#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
+ if (byte_enable) {
+ child->thread.dvc2 =
+ (unsigned long)bp_info->condition_value;
+ child->thread.dbcr2 |=
+ ((byte_enable << DBCR2_DVC2BE_SHIFT) |
+ (condition_mode << DBCR2_DVC2M_SHIFT));
+ }
+#endif
+ } else
+ return -ENOSPC;
+ child->thread.dbcr0 |= DBCR0_IDM;
+ child->thread.regs->msr |= MSR_DE;
+
+ return slot + 4;
+}
+
+static int del_dac(struct task_struct *child, int slot)
+{
+ if (slot == 1) {
+ if (child->thread.dac1 == 0)
+ return -ENOENT;
+
+ child->thread.dac1 = 0;
+ dbcr_dac(child) &= ~(DBCR_DAC1R | DBCR_DAC1W);
+#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
+ if (child->thread.dbcr2 & DBCR2_DAC12MODE) {
+ child->thread.dac2 = 0;
+ child->thread.dbcr2 &= ~DBCR2_DAC12MODE;
+ }
+ child->thread.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE);
+#endif
+#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
+ child->thread.dvc1 = 0;
+#endif
+ } else if (slot == 2) {
+ if (child->thread.dac1 == 0)
+ return -ENOENT;
+
+#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
+ if (child->thread.dbcr2 & DBCR2_DAC12MODE)
+ /* Part of a range */
+ return -EINVAL;
+ child->thread.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE);
+#endif
+#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
+ child->thread.dvc2 = 0;
+#endif
+ child->thread.dac2 = 0;
+ dbcr_dac(child) &= ~(DBCR_DAC2R | DBCR_DAC2W);
+ } else
+ return -EINVAL;
+
+ return 0;
+}
+#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
+
+#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
+static int set_dac_range(struct task_struct *child,
+ struct ppc_hw_breakpoint *bp_info)
+{
+ int mode = bp_info->addr_mode & PPC_BREAKPOINT_MODE_MASK;
+
+ /* We don't allow range watchpoints to be used with DVC */
+ if (bp_info->condition_mode)
+ return -EINVAL;
+
+ /*
+ * Best effort to verify the address range. The user/supervisor bits
+ * prevent trapping in kernel space, but let's fail on an obvious bad
+ * range. The simple test on the mask is not fool-proof, and any
+ * exclusive range will spill over into kernel space.
+ */
+ if (bp_info->addr >= TASK_SIZE)
+ return -EIO;
+ if (mode == PPC_BREAKPOINT_MODE_MASK) {
+ /*
+ * dac2 is a bitmask. Don't allow a mask that makes a
+ * kernel space address from a valid dac1 value
+ */
+ if (~((unsigned long)bp_info->addr2) >= TASK_SIZE)
+ return -EIO;
+ } else {
+ /*
+ * For range breakpoints, addr2 must also be a valid address
+ */
+ if (bp_info->addr2 >= TASK_SIZE)
+ return -EIO;
+ }
+
+ if (child->thread.dbcr0 &
+ (DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W))
+ return -ENOSPC;
+
+ if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
+ child->thread.dbcr0 |= (DBCR0_DAC1R | DBCR0_IDM);
+ if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
+ child->thread.dbcr0 |= (DBCR0_DAC1W | DBCR0_IDM);
+ child->thread.dac1 = bp_info->addr;
+ child->thread.dac2 = bp_info->addr2;
+ if (mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE)
+ child->thread.dbcr2 |= DBCR2_DAC12M;
+ else if (mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
+ child->thread.dbcr2 |= DBCR2_DAC12MX;
+ else /* PPC_BREAKPOINT_MODE_MASK */
+ child->thread.dbcr2 |= DBCR2_DAC12MM;
+ child->thread.regs->msr |= MSR_DE;
+
+ return 5;
+}
+#endif /* CONFIG_PPC_ADV_DEBUG_DAC_RANGE */
+
+static long ppc_set_hwdebug(struct task_struct *child,
+ struct ppc_hw_breakpoint *bp_info)
+{
+ if (bp_info->version != 1)
+ return -ENOTSUPP;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+ /*
+ * Check for invalid flags and combinations
+ */
+ if ((bp_info->trigger_type == 0) ||
+ (bp_info->trigger_type & ~(PPC_BREAKPOINT_TRIGGER_EXECUTE |
+ PPC_BREAKPOINT_TRIGGER_RW)) ||
+ (bp_info->addr_mode & ~PPC_BREAKPOINT_MODE_MASK) ||
+ (bp_info->condition_mode &
+ ~(PPC_BREAKPOINT_CONDITION_MODE |
+ PPC_BREAKPOINT_CONDITION_BE_ALL)))
+ return -EINVAL;
+#if CONFIG_PPC_ADV_DEBUG_DVCS == 0
+ if (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
+ return -EINVAL;
+#endif
+
+ if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_EXECUTE) {
+ if ((bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_EXECUTE) ||
+ (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE))
+ return -EINVAL;
+ return set_intruction_bp(child, bp_info);
+ }
+ if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT)
+ return set_dac(child, bp_info);
+
+#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
+ return set_dac_range(child, bp_info);
+#else
+ return -EINVAL;
+#endif
+#else /* !CONFIG_PPC_ADV_DEBUG_DVCS */
+ /*
+ * We only support one data breakpoint
+ */
+ if (((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0) ||
+ ((bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0) ||
+ (bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_WRITE) ||
+ (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) ||
+ (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE))
+ return -EINVAL;
+
+ if (child->thread.dabr)
+ return -ENOSPC;
+
+ if ((unsigned long)bp_info->addr >= TASK_SIZE)
+ return -EIO;
+
+ child->thread.dabr = (unsigned long)bp_info->addr;
+
+ return 1;
+#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */
+}
+
+static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
+{
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+ int rc;
+
+ if (data <= 4)
+ rc = del_instruction_bp(child, (int)data);
+ else
+ rc = del_dac(child, (int)data - 4);
+
+ if (!rc) {
+ if (!DBCR_ACTIVE_EVENTS(child->thread.dbcr0,
+ child->thread.dbcr1)) {
+ child->thread.dbcr0 &= ~DBCR0_IDM;
+ child->thread.regs->msr &= ~MSR_DE;
+ }
+ }
+ return rc;
+#else
+ if (data != 1)
+ return -EINVAL;
+ if (child->thread.dabr == 0)
+ return -ENOENT;
+
+ child->thread.dabr = 0;
+
+ return 0;
+#endif
+}
+
/*
* Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
* we mark them as obsolete now, they will be removed in a future version
@@ -932,13 +1328,77 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
}
+ case PPC_PTRACE_GETHWDBGINFO: {
+ struct ppc_debug_info dbginfo;
+
+ dbginfo.version = 1;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+ dbginfo.num_instruction_bps = CONFIG_PPC_ADV_DEBUG_IACS;
+ dbginfo.num_data_bps = CONFIG_PPC_ADV_DEBUG_DACS;
+ dbginfo.num_condition_regs = CONFIG_PPC_ADV_DEBUG_DVCS;
+ dbginfo.data_bp_alignment = 4;
+ dbginfo.sizeof_condition = 4;
+ dbginfo.features = PPC_DEBUG_FEATURE_INSN_BP_RANGE |
+ PPC_DEBUG_FEATURE_INSN_BP_MASK;
+#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
+ dbginfo.features |=
+ PPC_DEBUG_FEATURE_DATA_BP_RANGE |
+ PPC_DEBUG_FEATURE_DATA_BP_MASK;
+#endif
+#else /* !CONFIG_PPC_ADV_DEBUG_REGS */
+ dbginfo.num_instruction_bps = 0;
+ dbginfo.num_data_bps = 1;
+ dbginfo.num_condition_regs = 0;
+#ifdef CONFIG_PPC64
+ dbginfo.data_bp_alignment = 8;
+#else
+ dbginfo.data_bp_alignment = 4;
+#endif
+ dbginfo.sizeof_condition = 0;
+ dbginfo.features = 0;
+#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
+
+ if (!access_ok(VERIFY_WRITE, data,
+ sizeof(struct ppc_debug_info)))
+ return -EFAULT;
+ ret = __copy_to_user((struct ppc_debug_info __user *)data,
+ &dbginfo, sizeof(struct ppc_debug_info)) ?
+ -EFAULT : 0;
+ break;
+ }
+
+ case PPC_PTRACE_SETHWDEBUG: {
+ struct ppc_hw_breakpoint bp_info;
+
+ if (!access_ok(VERIFY_READ, data,
+ sizeof(struct ppc_hw_breakpoint)))
+ return -EFAULT;
+ ret = __copy_from_user(&bp_info,
+ (struct ppc_hw_breakpoint __user *)data,
+ sizeof(struct ppc_hw_breakpoint)) ?
+ -EFAULT : 0;
+ if (!ret)
+ ret = ppc_set_hwdebug(child, &bp_info);
+ break;
+ }
+
+ case PPC_PTRACE_DELHWDEBUG: {
+ ret = ppc_del_hwdebug(child, addr, data);
+ break;
+ }
+
case PTRACE_GET_DEBUGREG: {
ret = -EINVAL;
/* We only support one DABR and no IABRS at the moment */
if (addr > 0)
break;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+ ret = put_user(child->thread.dac1,
+ (unsigned long __user *)data);
+#else
ret = put_user(child->thread.dabr,
(unsigned long __user *)data);
+#endif
break;
}
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 00b5078da9a..a0afb555a7c 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -140,17 +140,15 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
return 0; /* no signals delivered */
}
+#ifndef CONFIG_PPC_ADV_DEBUG_REGS
/*
* Reenable the DABR before delivering the signal to
* user space. The DABR will have been cleared if it
* triggered inside the kernel.
*/
- if (current->thread.dabr) {
+ if (current->thread.dabr)
set_dabr(current->thread.dabr);
-#if defined(CONFIG_BOOKE)
- mtspr(SPRN_DBCR0, current->thread.dbcr0);
#endif
- }
if (is32) {
if (ka.sa.sa_flags & SA_SIGINFO)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index d670429a160..266610119f6 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -1078,7 +1078,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
int i;
unsigned char tmp;
unsigned long new_msr = regs->msr;
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
unsigned long new_dbcr0 = current->thread.dbcr0;
#endif
@@ -1087,13 +1087,17 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
return -EFAULT;
switch (op.dbg_type) {
case SIG_DBG_SINGLE_STEPPING:
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
if (op.dbg_value) {
new_msr |= MSR_DE;
new_dbcr0 |= (DBCR0_IDM | DBCR0_IC);
} else {
- new_msr &= ~MSR_DE;
- new_dbcr0 &= ~(DBCR0_IDM | DBCR0_IC);
+ new_dbcr0 &= ~DBCR0_IC;
+ if (!DBCR_ACTIVE_EVENTS(new_dbcr0,
+ current->thread.dbcr1)) {
+ new_msr &= ~MSR_DE;
+ new_dbcr0 &= ~DBCR0_IDM;
+ }
}
#else
if (op.dbg_value)
@@ -1103,7 +1107,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
#endif
break;
case SIG_DBG_BRANCH_TRACING:
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
return -EINVAL;
#else
if (op.dbg_value)
@@ -1124,7 +1128,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
failure is a problem, anyway, and it's very unlikely unless
the user is really doing something wrong. */
regs->msr = new_msr;
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
current->thread.dbcr0 = new_dbcr0;
#endif
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 6c6093d67f3..1b16b9a3e49 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -265,8 +265,8 @@ void account_system_vtime(struct task_struct *tsk)
account_system_time(tsk, 0, delta, deltascaled);
else
account_idle_time(delta);
- per_cpu(cputime_last_delta, smp_processor_id()) = delta;
- per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled;
+ __get_cpu_var(cputime_last_delta) = delta;
+ __get_cpu_var(cputime_scaled_last_delta) = deltascaled;
local_irq_restore(flags);
}
EXPORT_SYMBOL_GPL(account_system_vtime);
@@ -575,6 +575,8 @@ void timer_interrupt(struct pt_regs * regs)
trace_timer_interrupt_entry(regs);
+ __get_cpu_var(irq_stat).timer_irqs++;
+
/* Ensure a positive value is written to the decrementer, or else
* some CPUs will continuue to take decrementer exceptions */
set_dec(DECREMENTER_MAX);
@@ -935,8 +937,8 @@ static void register_decrementer_clockevent(int cpu)
*dec = decrementer_clockevent;
dec->cpumask = cpumask_of(cpu);
- printk(KERN_DEBUG "clockevent: %s mult[%x] shift[%d] cpu[%d]\n",
- dec->name, dec->mult, dec->shift, cpu);
+ printk_once(KERN_DEBUG "clockevent: %s mult[%x] shift[%d] cpu[%d]\n",
+ dec->name, dec->mult, dec->shift, cpu);
clockevents_register_device(dec);
}
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index d069ff8a7e0..696626a2e83 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -60,13 +60,13 @@
#endif
#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
-int (*__debugger)(struct pt_regs *regs);
-int (*__debugger_ipi)(struct pt_regs *regs);
-int (*__debugger_bpt)(struct pt_regs *regs);
-int (*__debugger_sstep)(struct pt_regs *regs);
-int (*__debugger_iabr_match)(struct pt_regs *regs);
-int (*__debugger_dabr_match)(struct pt_regs *regs);
-int (*__debugger_fault_handler)(struct pt_regs *regs);
+int (*__debugger)(struct pt_regs *regs) __read_mostly;
+int (*__debugger_ipi)(struct pt_regs *regs) __read_mostly;
+int (*__debugger_bpt)(struct pt_regs *regs) __read_mostly;
+int (*__debugger_sstep)(struct pt_regs *regs) __read_mostly;
+int (*__debugger_iabr_match)(struct pt_regs *regs) __read_mostly;
+int (*__debugger_dabr_match)(struct pt_regs *regs) __read_mostly;
+int (*__debugger_fault_handler)(struct pt_regs *regs) __read_mostly;
EXPORT_SYMBOL(__debugger);
EXPORT_SYMBOL(__debugger_ipi);
@@ -102,11 +102,11 @@ static inline void pmac_backlight_unblank(void) { }
int die(const char *str, struct pt_regs *regs, long err)
{
static struct {
- spinlock_t lock;
+ raw_spinlock_t lock;
u32 lock_owner;
int lock_owner_depth;
} die = {
- .lock = __SPIN_LOCK_UNLOCKED(die.lock),
+ .lock = __RAW_SPIN_LOCK_UNLOCKED(die.lock),
.lock_owner = -1,
.lock_owner_depth = 0
};
@@ -120,7 +120,7 @@ int die(const char *str, struct pt_regs *regs, long err)
if (die.lock_owner != raw_smp_processor_id()) {
console_verbose();
- spin_lock_irqsave(&die.lock, flags);
+ raw_spin_lock_irqsave(&die.lock, flags);
die.lock_owner = smp_processor_id();
die.lock_owner_depth = 0;
bust_spinlocks(1);
@@ -146,6 +146,11 @@ int die(const char *str, struct pt_regs *regs, long err)
#endif
printk("%s\n", ppc_md.name ? ppc_md.name : "");
+ sysfs_printk_last_file();
+ if (notify_die(DIE_OOPS, str, regs, err, 255,
+ SIGSEGV) == NOTIFY_STOP)
+ return 1;
+
print_modules();
show_regs(regs);
} else {
@@ -155,7 +160,7 @@ int die(const char *str, struct pt_regs *regs, long err)
bust_spinlocks(0);
die.lock_owner = -1;
add_taint(TAINT_DIE);
- spin_unlock_irqrestore(&die.lock, flags);
+ raw_spin_unlock_irqrestore(&die.lock, flags);
if (kexec_should_crash(current) ||
kexec_sr_activated(smp_processor_id()))
@@ -294,7 +299,7 @@ static inline int check_io_access(struct pt_regs *regs)
return 0;
}
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
/* On 4xx, the reason for the machine check or program exception
is in the ESR. */
#define get_reason(regs) ((regs)->dsisr)
@@ -478,6 +483,8 @@ void machine_check_exception(struct pt_regs *regs)
{
int recover = 0;
+ __get_cpu_var(irq_stat).mce_exceptions++;
+
/* See if any machine dependent calls. In theory, we would want
* to call the CPU first, and call the ppc_md. one if the CPU
* one returns a positive number. However there is existing code
@@ -960,6 +967,8 @@ void vsx_unavailable_exception(struct pt_regs *regs)
void performance_monitor_exception(struct pt_regs *regs)
{
+ __get_cpu_var(irq_stat).pmu_irqs++;
+
perf_irq(regs);
}
@@ -1024,10 +1033,69 @@ void SoftwareEmulation(struct pt_regs *regs)
}
#endif /* CONFIG_8xx */
-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+static void handle_debug(struct pt_regs *regs, unsigned long debug_status)
+{
+ int changed = 0;
+ /*
+ * Determine the cause of the debug event, clear the
+ * event flags and send a trap to the handler. Torez
+ */
+ if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
+ dbcr_dac(current) &= ~(DBCR_DAC1R | DBCR_DAC1W);
+#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
+ current->thread.dbcr2 &= ~DBCR2_DAC12MODE;
+#endif
+ do_send_trap(regs, mfspr(SPRN_DAC1), debug_status, TRAP_HWBKPT,
+ 5);
+ changed |= 0x01;
+ } else if (debug_status & (DBSR_DAC2R | DBSR_DAC2W)) {
+ dbcr_dac(current) &= ~(DBCR_DAC2R | DBCR_DAC2W);
+ do_send_trap(regs, mfspr(SPRN_DAC2), debug_status, TRAP_HWBKPT,
+ 6);
+ changed |= 0x01;
+ } else if (debug_status & DBSR_IAC1) {
+ current->thread.dbcr0 &= ~DBCR0_IAC1;
+ dbcr_iac_range(current) &= ~DBCR_IAC12MODE;
+ do_send_trap(regs, mfspr(SPRN_IAC1), debug_status, TRAP_HWBKPT,
+ 1);
+ changed |= 0x01;
+ } else if (debug_status & DBSR_IAC2) {
+ current->thread.dbcr0 &= ~DBCR0_IAC2;
+ do_send_trap(regs, mfspr(SPRN_IAC2), debug_status, TRAP_HWBKPT,
+ 2);
+ changed |= 0x01;
+ } else if (debug_status & DBSR_IAC3) {
+ current->thread.dbcr0 &= ~DBCR0_IAC3;
+ dbcr_iac_range(current) &= ~DBCR_IAC34MODE;
+ do_send_trap(regs, mfspr(SPRN_IAC3), debug_status, TRAP_HWBKPT,
+ 3);
+ changed |= 0x01;
+ } else if (debug_status & DBSR_IAC4) {
+ current->thread.dbcr0 &= ~DBCR0_IAC4;
+ do_send_trap(regs, mfspr(SPRN_IAC4), debug_status, TRAP_HWBKPT,
+ 4);
+ changed |= 0x01;
+ }
+ /*
+ * At the point this routine was called, the MSR(DE) was turned off.
+ * Check all other debug flags and see if that bit needs to be turned
+ * back on or not.
+ */
+ if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0, current->thread.dbcr1))
+ regs->msr |= MSR_DE;
+ else
+ /* Make sure the IDM flag is off */
+ current->thread.dbcr0 &= ~DBCR0_IDM;
+
+ if (changed & 0x01)
+ mtspr(SPRN_DBCR0, current->thread.dbcr0);
+}
void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
{
+ current->thread.dbsr = debug_status;
+
/* Hack alert: On BookE, Branch Taken stops on the branch itself, while
* on server, it stops on the target of the branch. In order to simulate
* the server behaviour, we thus restart right away with a single step
@@ -1071,29 +1139,23 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
if (debugger_sstep(regs))
return;
- if (user_mode(regs))
- current->thread.dbcr0 &= ~(DBCR0_IC);
-
- _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
- } else if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
- regs->msr &= ~MSR_DE;
-
if (user_mode(regs)) {
- current->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W |
- DBCR0_IDM);
- } else {
- /* Disable DAC interupts */
- mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~(DBSR_DAC1R |
- DBSR_DAC1W | DBCR0_IDM));
-
- /* Clear the DAC event */
- mtspr(SPRN_DBSR, (DBSR_DAC1R | DBSR_DAC1W));
+ current->thread.dbcr0 &= ~DBCR0_IC;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+ if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0,
+ current->thread.dbcr1))
+ regs->msr |= MSR_DE;
+ else
+ /* Make sure the IDM bit is off */
+ current->thread.dbcr0 &= ~DBCR0_IDM;
+#endif
}
- /* Setup and send the trap to the handler */
- do_dabr(regs, mfspr(SPRN_DAC1), debug_status);
- }
+
+ _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
+ } else
+ handle_debug(regs, debug_status);
}
-#endif /* CONFIG_4xx || CONFIG_BOOKE */
+#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
#if !defined(CONFIG_TAU_INT)
void TAUException(struct pt_regs *regs)
diff --git a/arch/powerpc/lib/copypage_64.S b/arch/powerpc/lib/copypage_64.S
index e68beac0a17..4d4eeb90048 100644
--- a/arch/powerpc/lib/copypage_64.S
+++ b/arch/powerpc/lib/copypage_64.S
@@ -43,62 +43,62 @@ END_FTR_SECTION_IFSET(CPU_FTR_CP_USE_DCBTZ)
ld r7,16(r4)
ldu r8,24(r4)
1: std r5,8(r3)
- ld r9,8(r4)
std r6,16(r3)
+ ld r9,8(r4)
ld r10,16(r4)
std r7,24(r3)
- ld r11,24(r4)
std r8,32(r3)
+ ld r11,24(r4)
ld r12,32(r4)
std r9,40(r3)
- ld r5,40(r4)
std r10,48(r3)
+ ld r5,40(r4)
ld r6,48(r4)
std r11,56(r3)
- ld r7,56(r4)
std r12,64(r3)
+ ld r7,56(r4)
ld r8,64(r4)
std r5,72(r3)
- ld r9,72(r4)
std r6,80(r3)
+ ld r9,72(r4)
ld r10,80(r4)
std r7,88(r3)
- ld r11,88(r4)
std r8,96(r3)
+ ld r11,88(r4)
ld r12,96(r4)
std r9,104(r3)
- ld r5,104(r4)
std r10,112(r3)
+ ld r5,104(r4)
ld r6,112(r4)
std r11,120(r3)
- ld r7,120(r4)
stdu r12,128(r3)
+ ld r7,120(r4)
ldu r8,128(r4)
bdnz 1b
std r5,8(r3)
- ld r9,8(r4)
std r6,16(r3)
+ ld r9,8(r4)
ld r10,16(r4)
std r7,24(r3)
- ld r11,24(r4)
std r8,32(r3)
+ ld r11,24(r4)
ld r12,32(r4)
std r9,40(r3)
- ld r5,40(r4)
std r10,48(r3)
+ ld r5,40(r4)
ld r6,48(r4)
std r11,56(r3)
- ld r7,56(r4)
std r12,64(r3)
+ ld r7,56(r4)
ld r8,64(r4)
std r5,72(r3)
- ld r9,72(r4)
std r6,80(r3)
+ ld r9,72(r4)
ld r10,80(r4)
std r7,88(r3)
- ld r11,88(r4)
std r8,96(r3)
+ ld r11,88(r4)
ld r12,96(r4)
std r9,104(r3)
std r10,112(r3)
diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S
index 693b14a778f..578b625d6a3 100644
--- a/arch/powerpc/lib/copyuser_64.S
+++ b/arch/powerpc/lib/copyuser_64.S
@@ -44,37 +44,55 @@ BEGIN_FTR_SECTION
andi. r0,r4,7
bne .Lsrc_unaligned
END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
- srdi r7,r5,4
-20: ld r9,0(r4)
- addi r4,r4,-8
- mtctr r7
- andi. r5,r5,7
- bf cr7*4+0,22f
- addi r3,r3,8
- addi r4,r4,8
- mr r8,r9
- blt cr1,72f
-21: ld r9,8(r4)
-70: std r8,8(r3)
-22: ldu r8,16(r4)
-71: stdu r9,16(r3)
+ blt cr1,.Ldo_tail /* if < 16 bytes to copy */
+ srdi r0,r5,5
+ cmpdi cr1,r0,0
+20: ld r7,0(r4)
+220: ld r6,8(r4)
+ addi r4,r4,16
+ mtctr r0
+ andi. r0,r5,0x10
+ beq 22f
+ addi r3,r3,16
+ addi r4,r4,-16
+ mr r9,r7
+ mr r8,r6
+ beq cr1,72f
+21: ld r7,16(r4)
+221: ld r6,24(r4)
+ addi r4,r4,32
+70: std r9,0(r3)
+270: std r8,8(r3)
+22: ld r9,0(r4)
+222: ld r8,8(r4)
+71: std r7,16(r3)
+271: std r6,24(r3)
+ addi r3,r3,32
bdnz 21b
-72: std r8,8(r3)
+72: std r9,0(r3)
+272: std r8,8(r3)
+ andi. r5,r5,0xf
beq+ 3f
- addi r3,r3,16
+ addi r4,r4,16
.Ldo_tail:
- bf cr7*4+1,1f
-23: lwz r9,8(r4)
+ addi r3,r3,16
+ bf cr7*4+0,246f
+244: ld r9,0(r4)
+ addi r4,r4,8
+245: std r9,0(r3)
+ addi r3,r3,8
+246: bf cr7*4+1,1f
+23: lwz r9,0(r4)
addi r4,r4,4
73: stw r9,0(r3)
addi r3,r3,4
1: bf cr7*4+2,2f
-44: lhz r9,8(r4)
+44: lhz r9,0(r4)
addi r4,r4,2
74: sth r9,0(r3)
addi r3,r3,2
2: bf cr7*4+3,3f
-45: lbz r9,8(r4)
+45: lbz r9,0(r4)
75: stb r9,0(r3)
3: li r3,0
blr
@@ -220,7 +238,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
131:
addi r3,r3,8
120:
+320:
122:
+322:
124:
125:
126:
@@ -229,9 +249,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
129:
133:
addi r3,r3,8
-121:
132:
addi r3,r3,8
+121:
+321:
+344:
134:
135:
138:
@@ -303,18 +325,22 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
183:
add r3,r3,r7
b 1f
+371:
180:
addi r3,r3,8
171:
177:
addi r3,r3,8
-170:
-172:
+370:
+372:
176:
178:
addi r3,r3,4
185:
addi r3,r3,4
+170:
+172:
+345:
173:
174:
175:
@@ -341,11 +367,19 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
.section __ex_table,"a"
.align 3
.llong 20b,120b
+ .llong 220b,320b
.llong 21b,121b
+ .llong 221b,321b
.llong 70b,170b
+ .llong 270b,370b
.llong 22b,122b
+ .llong 222b,322b
.llong 71b,171b
+ .llong 271b,371b
.llong 72b,172b
+ .llong 272b,372b
+ .llong 244b,344b
+ .llong 245b,345b
.llong 23b,123b
.llong 73b,173b
.llong 44b,144b
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index 7e8865bcd68..e640175b65a 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -112,7 +112,8 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
{
- unsigned int *start, *end, *dest;
+ long *start, *end;
+ unsigned int *dest;
if (!(value & CPU_FTR_LWSYNC))
return ;
diff --git a/arch/powerpc/mm/40x_mmu.c b/arch/powerpc/mm/40x_mmu.c
index 08dfa8e6d86..65abfcfaaa9 100644
--- a/arch/powerpc/mm/40x_mmu.c
+++ b/arch/powerpc/mm/40x_mmu.c
@@ -84,8 +84,8 @@ void __init MMU_init_hw(void)
* vectors and the kernel live in real-mode.
*/
- mtspr(SPRN_DCCR, 0xF0000000); /* 512 MB of data space at 0x0. */
- mtspr(SPRN_ICCR, 0xF0000000); /* 512 MB of instr. space at 0x0. */
+ mtspr(SPRN_DCCR, 0xFFFF0000); /* 2GByte of data space at 0x0. */
+ mtspr(SPRN_ICCR, 0xFFFF0000); /* 2GByte of instr. space at 0x0. */
}
#define LARGE_PAGE_SIZE_16M (1<<24)
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index 056d23a1b10..784a400e078 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -37,7 +37,7 @@
#define HPTE_LOCK_BIT 3
-static DEFINE_SPINLOCK(native_tlbie_lock);
+static DEFINE_RAW_SPINLOCK(native_tlbie_lock);
static inline void __tlbie(unsigned long va, int psize, int ssize)
{
@@ -104,7 +104,7 @@ static inline void tlbie(unsigned long va, int psize, int ssize, int local)
if (use_local)
use_local = mmu_psize_defs[psize].tlbiel;
if (lock_tlbie && !use_local)
- spin_lock(&native_tlbie_lock);
+ raw_spin_lock(&native_tlbie_lock);
asm volatile("ptesync": : :"memory");
if (use_local) {
__tlbiel(va, psize, ssize);
@@ -114,7 +114,7 @@ static inline void tlbie(unsigned long va, int psize, int ssize, int local)
asm volatile("eieio; tlbsync; ptesync": : :"memory");
}
if (lock_tlbie && !use_local)
- spin_unlock(&native_tlbie_lock);
+ raw_spin_unlock(&native_tlbie_lock);
}
static inline void native_lock_hpte(struct hash_pte *hptep)
@@ -122,7 +122,7 @@ static inline void native_lock_hpte(struct hash_pte *hptep)
unsigned long *word = &hptep->v;
while (1) {
- if (!test_and_set_bit(HPTE_LOCK_BIT, word))
+ if (!test_and_set_bit_lock(HPTE_LOCK_BIT, word))
break;
while(test_bit(HPTE_LOCK_BIT, word))
cpu_relax();
@@ -133,8 +133,7 @@ static inline void native_unlock_hpte(struct hash_pte *hptep)
{
unsigned long *word = &hptep->v;
- asm volatile("lwsync":::"memory");
- clear_bit(HPTE_LOCK_BIT, word);
+ clear_bit_unlock(HPTE_LOCK_BIT, word);
}
static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
@@ -434,7 +433,7 @@ static void native_hpte_clear(void)
/* we take the tlbie lock and hold it. Some hardware will
* deadlock if we try to tlbie from two processors at once.
*/
- spin_lock(&native_tlbie_lock);
+ raw_spin_lock(&native_tlbie_lock);
slots = pteg_count * HPTES_PER_GROUP;
@@ -458,7 +457,7 @@ static void native_hpte_clear(void)
}
asm volatile("eieio; tlbsync; ptesync":::"memory");
- spin_unlock(&native_tlbie_lock);
+ raw_spin_unlock(&native_tlbie_lock);
local_irq_restore(flags);
}
@@ -521,7 +520,7 @@ static void native_flush_hash_range(unsigned long number, int local)
int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
if (lock_tlbie)
- spin_lock(&native_tlbie_lock);
+ raw_spin_lock(&native_tlbie_lock);
asm volatile("ptesync":::"memory");
for (i = 0; i < number; i++) {
@@ -536,7 +535,7 @@ static void native_flush_hash_range(unsigned long number, int local)
asm volatile("eieio; tlbsync; ptesync":::"memory");
if (lock_tlbie)
- spin_unlock(&native_tlbie_lock);
+ raw_spin_unlock(&native_tlbie_lock);
}
local_irq_restore(flags);
diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c
index b910d37aea1..51622daae09 100644
--- a/arch/powerpc/mm/mmu_context_hash64.c
+++ b/arch/powerpc/mm/mmu_context_hash64.c
@@ -23,7 +23,7 @@
#include <asm/mmu_context.h>
static DEFINE_SPINLOCK(mmu_context_lock);
-static DEFINE_IDR(mmu_context_idr);
+static DEFINE_IDA(mmu_context_ida);
/*
* The proto-VSID space has 2^35 - 1 segments available for user mappings.
@@ -39,11 +39,11 @@ int __init_new_context(void)
int err;
again:
- if (!idr_pre_get(&mmu_context_idr, GFP_KERNEL))
+ if (!ida_pre_get(&mmu_context_ida, GFP_KERNEL))
return -ENOMEM;
spin_lock(&mmu_context_lock);
- err = idr_get_new_above(&mmu_context_idr, NULL, 1, &index);
+ err = ida_get_new_above(&mmu_context_ida, 1, &index);
spin_unlock(&mmu_context_lock);
if (err == -EAGAIN)
@@ -53,7 +53,7 @@ again:
if (index > MAX_CONTEXT) {
spin_lock(&mmu_context_lock);
- idr_remove(&mmu_context_idr, index);
+ ida_remove(&mmu_context_ida, index);
spin_unlock(&mmu_context_lock);
return -ENOMEM;
}
@@ -85,7 +85,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
void __destroy_context(int context_id)
{
spin_lock(&mmu_context_lock);
- idr_remove(&mmu_context_idr, context_id);
+ ida_remove(&mmu_context_ida, context_id);
spin_unlock(&mmu_context_lock);
}
EXPORT_SYMBOL_GPL(__destroy_context);
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
index 1044a634b6d..dbc692145ec 100644
--- a/arch/powerpc/mm/mmu_context_nohash.c
+++ b/arch/powerpc/mm/mmu_context_nohash.c
@@ -56,7 +56,7 @@ static unsigned int next_context, nr_free_contexts;
static unsigned long *context_map;
static unsigned long *stale_map[NR_CPUS];
static struct mm_struct **context_mm;
-static DEFINE_SPINLOCK(context_lock);
+static DEFINE_RAW_SPINLOCK(context_lock);
#define CTX_MAP_SIZE \
(sizeof(unsigned long) * (last_context / BITS_PER_LONG + 1))
@@ -121,9 +121,9 @@ static unsigned int steal_context_smp(unsigned int id)
/* This will happen if you have more CPUs than available contexts,
* all we can do here is wait a bit and try again
*/
- spin_unlock(&context_lock);
+ raw_spin_unlock(&context_lock);
cpu_relax();
- spin_lock(&context_lock);
+ raw_spin_lock(&context_lock);
/* This will cause the caller to try again */
return MMU_NO_CONTEXT;
@@ -194,7 +194,7 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
unsigned long *map;
/* No lockless fast path .. yet */
- spin_lock(&context_lock);
+ raw_spin_lock(&context_lock);
pr_hard("[%d] activating context for mm @%p, active=%d, id=%d",
cpu, next, next->context.active, next->context.id);
@@ -278,7 +278,7 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
/* Flick the MMU and release lock */
pr_hardcont(" -> %d\n", id);
set_context(id, next->pgd);
- spin_unlock(&context_lock);
+ raw_spin_unlock(&context_lock);
}
/*
@@ -307,7 +307,7 @@ void destroy_context(struct mm_struct *mm)
WARN_ON(mm->context.active != 0);
- spin_lock_irqsave(&context_lock, flags);
+ raw_spin_lock_irqsave(&context_lock, flags);
id = mm->context.id;
if (id != MMU_NO_CONTEXT) {
__clear_bit(id, context_map);
@@ -318,7 +318,7 @@ void destroy_context(struct mm_struct *mm)
context_mm[id] = NULL;
nr_free_contexts++;
}
- spin_unlock_irqrestore(&context_lock, flags);
+ raw_spin_unlock_irqrestore(&context_lock, flags);
}
#ifdef CONFIG_SMP
diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S
index f288279e679..8b04c54e596 100644
--- a/arch/powerpc/mm/tlb_low_64e.S
+++ b/arch/powerpc/mm/tlb_low_64e.S
@@ -1,5 +1,5 @@
/*
- * Low leve TLB miss handlers for Book3E
+ * Low level TLB miss handlers for Book3E
*
* Copyright (C) 2008-2009
* Ben. Herrenschmidt (benh@kernel.crashing.org), IBM Corp.
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index 2fbc680c2c7..e81d5d67f83 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -150,7 +150,7 @@ EXPORT_SYMBOL(local_flush_tlb_page);
*/
#ifdef CONFIG_SMP
-static DEFINE_SPINLOCK(tlbivax_lock);
+static DEFINE_RAW_SPINLOCK(tlbivax_lock);
static int mm_is_core_local(struct mm_struct *mm)
{
@@ -232,10 +232,10 @@ void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
if (mmu_has_feature(MMU_FTR_USE_TLBIVAX_BCAST)) {
int lock = mmu_has_feature(MMU_FTR_LOCK_BCAST_INVAL);
if (lock)
- spin_lock(&tlbivax_lock);
+ raw_spin_lock(&tlbivax_lock);
_tlbivax_bcast(vmaddr, pid, tsize, ind);
if (lock)
- spin_unlock(&tlbivax_lock);
+ raw_spin_unlock(&tlbivax_lock);
goto bail;
} else {
struct tlb_flush_param p = {
diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c
index 84544d07204..4c42246b86a 100644
--- a/arch/powerpc/platforms/512x/clock.c
+++ b/arch/powerpc/platforms/512x/clock.c
@@ -698,8 +698,7 @@ static struct clk_interface mpc5121_clk_functions = {
.clk_get_parent = NULL,
};
-static int
-mpc5121_clk_init(void)
+int __init mpc5121_clk_init(void)
{
struct device_node *np;
@@ -724,6 +723,3 @@ mpc5121_clk_init(void)
clk_functions = mpc5121_clk_functions;
return 0;
}
-
-
-arch_initcall(mpc5121_clk_init);
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.c b/arch/powerpc/platforms/512x/mpc5121_ads.c
index 441abc48885..ee6ae129c25 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads.c
@@ -64,8 +64,9 @@ define_machine(mpc5121_ads) {
.name = "MPC5121 ADS",
.probe = mpc5121_ads_probe,
.setup_arch = mpc5121_ads_setup_arch,
- .init = mpc512x_declare_of_platform_devices,
+ .init = mpc512x_init,
.init_IRQ = mpc5121_ads_init_IRQ,
.get_irq = ipic_get_irq,
.calibrate_decr = generic_calibrate_decr,
+ .restart = mpc512x_restart,
};
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index da9b20a6376..4ecf4cf9a51 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -79,7 +79,7 @@ cpld_unmask_irq(unsigned int irq)
}
static struct irq_chip cpld_pic = {
- .name = " CPLD PIC ",
+ .name = "CPLD PIC",
.mask = cpld_mask_irq,
.ack = cpld_mask_irq,
.unmask = cpld_unmask_irq,
diff --git a/arch/powerpc/platforms/512x/mpc5121_generic.c b/arch/powerpc/platforms/512x/mpc5121_generic.c
index 2479de9e2d1..a6c0e3a2615 100644
--- a/arch/powerpc/platforms/512x/mpc5121_generic.c
+++ b/arch/powerpc/platforms/512x/mpc5121_generic.c
@@ -51,8 +51,9 @@ static int __init mpc5121_generic_probe(void)
define_machine(mpc5121_generic) {
.name = "MPC5121 generic",
.probe = mpc5121_generic_probe,
- .init = mpc512x_declare_of_platform_devices,
+ .init = mpc512x_init,
.init_IRQ = mpc512x_init_IRQ,
.get_irq = ipic_get_irq,
.calibrate_decr = generic_calibrate_decr,
+ .restart = mpc512x_restart,
};
diff --git a/arch/powerpc/platforms/512x/mpc512x.h b/arch/powerpc/platforms/512x/mpc512x.h
index 22a5352407e..b2daca0d148 100644
--- a/arch/powerpc/platforms/512x/mpc512x.h
+++ b/arch/powerpc/platforms/512x/mpc512x.h
@@ -12,5 +12,8 @@
#ifndef __MPC512X_H__
#define __MPC512X_H__
extern void __init mpc512x_init_IRQ(void);
+extern void __init mpc512x_init(void);
+extern int __init mpc5121_clk_init(void);
void __init mpc512x_declare_of_platform_devices(void);
+extern void mpc512x_restart(char *cmd);
#endif /* __MPC512X_H__ */
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
index 434d683df5a..b7f518a60f0 100644
--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -21,9 +21,38 @@
#include <asm/ipic.h>
#include <asm/prom.h>
#include <asm/time.h>
+#include <asm/mpc5121.h>
#include "mpc512x.h"
+static struct mpc512x_reset_module __iomem *reset_module_base;
+
+static void __init mpc512x_restart_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-reset");
+ if (!np)
+ return;
+
+ reset_module_base = of_iomap(np, 0);
+ of_node_put(np);
+}
+
+void mpc512x_restart(char *cmd)
+{
+ if (reset_module_base) {
+ /* Enable software reset "RSTE" */
+ out_be32(&reset_module_base->rpr, 0x52535445);
+ /* Set software hard reset */
+ out_be32(&reset_module_base->rcr, 0x2);
+ } else {
+ pr_err("Restart module not mapped.\n");
+ }
+ for (;;)
+ ;
+}
+
void __init mpc512x_init_IRQ(void)
{
struct device_node *np;
@@ -53,8 +82,22 @@ static struct of_device_id __initdata of_bus_ids[] = {
void __init mpc512x_declare_of_platform_devices(void)
{
+ struct device_node *np;
+
if (of_platform_bus_probe(NULL, of_bus_ids, NULL))
printk(KERN_ERR __FILE__ ": "
"Error while probing of_platform bus\n");
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-nfc");
+ if (np) {
+ of_platform_device_create(np, NULL, NULL);
+ of_node_put(np);
+ }
}
+void __init mpc512x_init(void)
+{
+ mpc512x_declare_of_platform_devices();
+ mpc5121_clk_init();
+ mpc512x_restart_init();
+}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index cc29c0f5300..04d105d689f 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -302,11 +302,14 @@ static struct of_device_id mpc85xx_ids[] = {
{ .compatible = "gianfar", },
{ .compatible = "fsl,rapidio-delta", },
{ .compatible = "fsl,mpc8548-guts", },
+ { .compatible = "gpio-leds", },
{},
};
static int __init mpc85xx_publish_devices(void)
{
+ if (machine_is(mpc8568_mds))
+ simple_gpiochip_init("fsl,mpc8568mds-bcsr-gpio");
if (machine_is(mpc8569_mds))
simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio");
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index e5da5f62b24..42e87f08aa0 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -232,7 +232,7 @@ static int socrates_fpga_pic_set_type(unsigned int virq,
}
static struct irq_chip socrates_fpga_pic_chip = {
- .name = " FPGA-PIC ",
+ .name = "FPGA-PIC",
.ack = socrates_fpga_pic_ack,
.mask = socrates_fpga_pic_mask,
.mask_ack = socrates_fpga_pic_mask_ack,
diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c
index f559918f3c6..bc33d1859ae 100644
--- a/arch/powerpc/platforms/85xx/stx_gp3.c
+++ b/arch/powerpc/platforms/85xx/stx_gp3.c
@@ -134,7 +134,7 @@ static void stx_gp3_show_cpuinfo(struct seq_file *m)
pvid = mfspr(SPRN_PVR);
svid = mfspr(SPRN_SVR);
- seq_printf(m, "Vendor\t\t: RPC Electronics STx \n");
+ seq_printf(m, "Vendor\t\t: RPC Electronics STx\n");
seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
seq_printf(m, "SVR\t\t: 0x%x\n", svid);
diff --git a/arch/powerpc/platforms/cell/beat_htab.c b/arch/powerpc/platforms/cell/beat_htab.c
index 35b1ec49271..2516c1cf846 100644
--- a/arch/powerpc/platforms/cell/beat_htab.c
+++ b/arch/powerpc/platforms/cell/beat_htab.c
@@ -40,7 +40,7 @@
#define DBG_LOW(fmt...) do { } while (0)
#endif
-static DEFINE_SPINLOCK(beat_htab_lock);
+static DEFINE_RAW_SPINLOCK(beat_htab_lock);
static inline unsigned int beat_read_mask(unsigned hpte_group)
{
@@ -114,18 +114,18 @@ static long beat_lpar_hpte_insert(unsigned long hpte_group,
if (rflags & _PAGE_NO_CACHE)
hpte_r &= ~_PAGE_COHERENT;
- spin_lock(&beat_htab_lock);
+ raw_spin_lock(&beat_htab_lock);
lpar_rc = beat_read_mask(hpte_group);
if (lpar_rc == 0) {
if (!(vflags & HPTE_V_BOLTED))
DBG_LOW(" full\n");
- spin_unlock(&beat_htab_lock);
+ raw_spin_unlock(&beat_htab_lock);
return -1;
}
lpar_rc = beat_insert_htab_entry(0, hpte_group, lpar_rc << 48,
hpte_v, hpte_r, &slot);
- spin_unlock(&beat_htab_lock);
+ raw_spin_unlock(&beat_htab_lock);
/*
* Since we try and ioremap PHBs we don't own, the pte insert
@@ -198,17 +198,17 @@ static long beat_lpar_hpte_updatepp(unsigned long slot,
"avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ",
want_v & HPTE_V_AVPN, slot, psize, newpp);
- spin_lock(&beat_htab_lock);
+ raw_spin_lock(&beat_htab_lock);
dummy0 = beat_lpar_hpte_getword0(slot);
if ((dummy0 & ~0x7FUL) != (want_v & ~0x7FUL)) {
DBG_LOW("not found !\n");
- spin_unlock(&beat_htab_lock);
+ raw_spin_unlock(&beat_htab_lock);
return -1;
}
lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7, &dummy0,
&dummy1);
- spin_unlock(&beat_htab_lock);
+ raw_spin_unlock(&beat_htab_lock);
if (lpar_rc != 0 || dummy0 == 0) {
DBG_LOW("not found !\n");
return -1;
@@ -262,13 +262,13 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp,
vsid = get_kernel_vsid(ea, MMU_SEGSIZE_256M);
va = (vsid << 28) | (ea & 0x0fffffff);
- spin_lock(&beat_htab_lock);
+ raw_spin_lock(&beat_htab_lock);
slot = beat_lpar_hpte_find(va, psize);
BUG_ON(slot == -1);
lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7,
&dummy0, &dummy1);
- spin_unlock(&beat_htab_lock);
+ raw_spin_unlock(&beat_htab_lock);
BUG_ON(lpar_rc != 0);
}
@@ -285,18 +285,18 @@ static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
slot, va, psize, local);
want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M);
- spin_lock_irqsave(&beat_htab_lock, flags);
+ raw_spin_lock_irqsave(&beat_htab_lock, flags);
dummy1 = beat_lpar_hpte_getword0(slot);
if ((dummy1 & ~0x7FUL) != (want_v & ~0x7FUL)) {
DBG_LOW("not found !\n");
- spin_unlock_irqrestore(&beat_htab_lock, flags);
+ raw_spin_unlock_irqrestore(&beat_htab_lock, flags);
return;
}
lpar_rc = beat_write_htab_entry(0, slot, 0, 0, HPTE_V_VALID, 0,
&dummy1, &dummy2);
- spin_unlock_irqrestore(&beat_htab_lock, flags);
+ raw_spin_unlock_irqrestore(&beat_htab_lock, flags);
BUG_ON(lpar_rc != 0);
}
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index 36052a9ebcd..682af97321a 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -30,7 +30,7 @@
#include "beat_wrapper.h"
#define MAX_IRQS NR_IRQS
-static DEFINE_SPINLOCK(beatic_irq_mask_lock);
+static DEFINE_RAW_SPINLOCK(beatic_irq_mask_lock);
static uint64_t beatic_irq_mask_enable[(MAX_IRQS+255)/64];
static uint64_t beatic_irq_mask_ack[(MAX_IRQS+255)/64];
@@ -65,30 +65,30 @@ static void beatic_mask_irq(unsigned int irq_plug)
{
unsigned long flags;
- spin_lock_irqsave(&beatic_irq_mask_lock, flags);
+ raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
beatic_irq_mask_enable[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64)));
beatic_update_irq_mask(irq_plug);
- spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
+ raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
}
static void beatic_unmask_irq(unsigned int irq_plug)
{
unsigned long flags;
- spin_lock_irqsave(&beatic_irq_mask_lock, flags);
+ raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
beatic_irq_mask_enable[irq_plug/64] |= 1UL << (63 - (irq_plug%64));
beatic_update_irq_mask(irq_plug);
- spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
+ raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
}
static void beatic_ack_irq(unsigned int irq_plug)
{
unsigned long flags;
- spin_lock_irqsave(&beatic_irq_mask_lock, flags);
+ raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
beatic_irq_mask_ack[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64)));
beatic_update_irq_mask(irq_plug);
- spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
+ raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
}
static void beatic_end_irq(unsigned int irq_plug)
@@ -103,14 +103,14 @@ static void beatic_end_irq(unsigned int irq_plug)
printk(KERN_ERR "IRQ over-downcounted, plug %d\n", irq_plug);
}
- spin_lock_irqsave(&beatic_irq_mask_lock, flags);
+ raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
beatic_irq_mask_ack[irq_plug/64] |= 1UL << (63 - (irq_plug%64));
beatic_update_irq_mask(irq_plug);
- spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
+ raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
}
static struct irq_chip beatic_pic = {
- .name = " CELL-BEAT ",
+ .name = "CELL-BEAT",
.unmask = beatic_unmask_irq,
.mask = beatic_mask_irq,
.eoi = beatic_end_irq,
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 6829cf7e2bd..10eb1a44362 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -88,7 +88,7 @@ static void iic_eoi(unsigned int irq)
}
static struct irq_chip iic_chip = {
- .name = " CELL-IIC ",
+ .name = "CELL-IIC",
.mask = iic_mask,
.unmask = iic_unmask,
.eoi = iic_eoi,
@@ -133,7 +133,7 @@ static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc)
static struct irq_chip iic_ioexc_chip = {
- .name = " CELL-IOEX",
+ .name = "CELL-IOEX",
.mask = iic_mask,
.unmask = iic_unmask,
.eoi = iic_ioexc_eoi,
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 01244f254a1..5876e888e41 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -168,7 +168,7 @@ static int spider_set_irq_type(unsigned int virq, unsigned int type)
}
static struct irq_chip spider_pic = {
- .name = " SPIDER ",
+ .name = "SPIDER",
.unmask = spider_unmask_irq,
.mask = spider_mask_irq,
.ack = spider_ack_irq,
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 86c4b29eea8..ba446bf355a 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -273,7 +273,7 @@ static void iseries_end_IRQ(unsigned int irq)
}
static struct irq_chip iseries_pic = {
- .name = "iSeries irq controller",
+ .name = "iSeries",
.startup = iseries_startup_IRQ,
.shutdown = iseries_shutdown_IRQ,
.unmask = iseries_enable_IRQ,
diff --git a/arch/powerpc/platforms/iseries/proc.c b/arch/powerpc/platforms/iseries/proc.c
index 91f4c6cd4b9..06763682db4 100644
--- a/arch/powerpc/platforms/iseries/proc.c
+++ b/arch/powerpc/platforms/iseries/proc.c
@@ -85,7 +85,7 @@ static int proc_titantod_show(struct seq_file *m, void *v)
seq_printf(m, " titan elapsed = %lu uSec\n", titan_usec);
seq_printf(m, " tb elapsed = %lu ticks\n", tb_ticks);
- seq_printf(m, " titan jiffies = %lu.%04lu \n", titan_jiffies,
+ seq_printf(m, " titan jiffies = %lu.%04lu\n", titan_jiffies,
titan_jiff_rem_usec);
seq_printf(m, " tb jiffies = %lu.%04lu\n", tb_jiffies,
tb_jiff_rem_usec);
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index a6cd3394fea..b0863410517 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -256,7 +256,7 @@ static unsigned long iSeries_process_mainstore_vpd(struct MemoryBlock *mb_array,
mem_blocks = iSeries_process_Condor_mainstore_vpd(mb_array,
max_entries);
- printk("Mainstore_VPD: numMemoryBlocks = %ld \n", mem_blocks);
+ printk("Mainstore_VPD: numMemoryBlocks = %ld\n", mem_blocks);
for (i = 0; i < mem_blocks; ++i) {
printk("Mainstore_VPD: block %3ld logical chunks %016lx - %016lx\n"
" abs chunks %016lx - %016lx\n",
diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
index 9dd789a7370..84d7fd9bcc6 100644
--- a/arch/powerpc/platforms/powermac/bootx_init.c
+++ b/arch/powerpc/platforms/powermac/bootx_init.c
@@ -539,7 +539,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
if (model
&& (strcmp(model, "iMac,1") == 0
|| strcmp(model, "PowerMac1,1") == 0)) {
- bootx_printf("iMac,1 detected, shutting down USB \n");
+ bootx_printf("iMac,1 detected, shutting down USB\n");
out_le32((unsigned __iomem *)0x80880008, 1); /* XXX */
}
}
@@ -554,7 +554,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
} else
space = bi->totalParamsSize;
- bootx_printf("Total space used by parameters & ramdisk: 0x%x \n", space);
+ bootx_printf("Total space used by parameters & ramdisk: 0x%x\n", space);
/* New BootX will have flushed all TLBs and enters kernel with
* MMU switched OFF, so this should not be useful anymore.
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index 33e815f4466..9e1b9fd7520 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -59,10 +59,10 @@ extern struct device_node *k2_skiplist[2];
* We use a single global lock to protect accesses. Each driver has
* to take care of its own locking
*/
-DEFINE_SPINLOCK(feature_lock);
+DEFINE_RAW_SPINLOCK(feature_lock);
-#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags);
-#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags);
+#define LOCK(flags) raw_spin_lock_irqsave(&feature_lock, flags);
+#define UNLOCK(flags) raw_spin_unlock_irqrestore(&feature_lock, flags);
/*
diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c
index c6f0f9e738e..80a5258d036 100644
--- a/arch/powerpc/platforms/powermac/nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -80,7 +80,7 @@ static int is_core_99;
static int core99_bank = 0;
static int nvram_partitions[3];
// XXX Turn that into a sem
-static DEFINE_SPINLOCK(nv_lock);
+static DEFINE_RAW_SPINLOCK(nv_lock);
static int (*core99_write_bank)(int bank, u8* datas);
static int (*core99_erase_bank)(int bank);
@@ -165,10 +165,10 @@ static unsigned char indirect_nvram_read_byte(int addr)
unsigned char val;
unsigned long flags;
- spin_lock_irqsave(&nv_lock, flags);
+ raw_spin_lock_irqsave(&nv_lock, flags);
out_8(nvram_addr, addr >> 5);
val = in_8(&nvram_data[(addr & 0x1f) << 4]);
- spin_unlock_irqrestore(&nv_lock, flags);
+ raw_spin_unlock_irqrestore(&nv_lock, flags);
return val;
}
@@ -177,10 +177,10 @@ static void indirect_nvram_write_byte(int addr, unsigned char val)
{
unsigned long flags;
- spin_lock_irqsave(&nv_lock, flags);
+ raw_spin_lock_irqsave(&nv_lock, flags);
out_8(nvram_addr, addr >> 5);
out_8(&nvram_data[(addr & 0x1f) << 4], val);
- spin_unlock_irqrestore(&nv_lock, flags);
+ raw_spin_unlock_irqrestore(&nv_lock, flags);
}
@@ -481,7 +481,7 @@ static void core99_nvram_sync(void)
if (!is_core_99 || !nvram_data || !nvram_image)
return;
- spin_lock_irqsave(&nv_lock, flags);
+ raw_spin_lock_irqsave(&nv_lock, flags);
if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
NVRAM_SIZE))
goto bail;
@@ -503,7 +503,7 @@ static void core99_nvram_sync(void)
if (core99_write_bank(core99_bank, nvram_image))
printk("nvram: Error writing bank %d\n", core99_bank);
bail:
- spin_unlock_irqrestore(&nv_lock, flags);
+ raw_spin_unlock_irqrestore(&nv_lock, flags);
#ifdef DEBUG
mdelay(2000);
diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c
index db20de512f3..f5e3cda6660 100644
--- a/arch/powerpc/platforms/powermac/pfunc_base.c
+++ b/arch/powerpc/platforms/powermac/pfunc_base.c
@@ -50,13 +50,13 @@ static int macio_do_gpio_write(PMF_STD_ARGS, u8 value, u8 mask)
value = ~value;
/* Toggle the GPIO */
- spin_lock_irqsave(&feature_lock, flags);
+ raw_spin_lock_irqsave(&feature_lock, flags);
tmp = readb(addr);
tmp = (tmp & ~mask) | (value & mask);
DBG("Do write 0x%02x to GPIO %s (%p)\n",
tmp, func->node->full_name, addr);
writeb(tmp, addr);
- spin_unlock_irqrestore(&feature_lock, flags);
+ raw_spin_unlock_irqrestore(&feature_lock, flags);
return 0;
}
@@ -145,9 +145,9 @@ static int macio_do_write_reg32(PMF_STD_ARGS, u32 offset, u32 value, u32 mask)
struct macio_chip *macio = func->driver_data;
unsigned long flags;
- spin_lock_irqsave(&feature_lock, flags);
+ raw_spin_lock_irqsave(&feature_lock, flags);
MACIO_OUT32(offset, (MACIO_IN32(offset) & ~mask) | (value & mask));
- spin_unlock_irqrestore(&feature_lock, flags);
+ raw_spin_unlock_irqrestore(&feature_lock, flags);
return 0;
}
@@ -168,9 +168,9 @@ static int macio_do_write_reg8(PMF_STD_ARGS, u32 offset, u8 value, u8 mask)
struct macio_chip *macio = func->driver_data;
unsigned long flags;
- spin_lock_irqsave(&feature_lock, flags);
+ raw_spin_lock_irqsave(&feature_lock, flags);
MACIO_OUT8(offset, (MACIO_IN8(offset) & ~mask) | (value & mask));
- spin_unlock_irqrestore(&feature_lock, flags);
+ raw_spin_unlock_irqrestore(&feature_lock, flags);
return 0;
}
@@ -223,12 +223,12 @@ static int macio_do_write_reg32_slm(PMF_STD_ARGS, u32 offset, u32 shift,
if (args == NULL || args->count == 0)
return -EINVAL;
- spin_lock_irqsave(&feature_lock, flags);
+ raw_spin_lock_irqsave(&feature_lock, flags);
tmp = MACIO_IN32(offset);
val = args->u[0].v << shift;
tmp = (tmp & ~mask) | (val & mask);
MACIO_OUT32(offset, tmp);
- spin_unlock_irqrestore(&feature_lock, flags);
+ raw_spin_unlock_irqrestore(&feature_lock, flags);
return 0;
}
@@ -243,12 +243,12 @@ static int macio_do_write_reg8_slm(PMF_STD_ARGS, u32 offset, u32 shift,
if (args == NULL || args->count == 0)
return -EINVAL;
- spin_lock_irqsave(&feature_lock, flags);
+ raw_spin_lock_irqsave(&feature_lock, flags);
tmp = MACIO_IN8(offset);
val = args->u[0].v << shift;
tmp = (tmp & ~mask) | (val & mask);
MACIO_OUT8(offset, tmp);
- spin_unlock_irqrestore(&feature_lock, flags);
+ raw_spin_unlock_irqrestore(&feature_lock, flags);
return 0;
}
@@ -278,12 +278,12 @@ static int unin_do_write_reg32(PMF_STD_ARGS, u32 offset, u32 value, u32 mask)
{
unsigned long flags;
- spin_lock_irqsave(&feature_lock, flags);
+ raw_spin_lock_irqsave(&feature_lock, flags);
/* This is fairly bogus in darwin, but it should work for our needs
* implemeted that way:
*/
UN_OUT(offset, (UN_IN(offset) & ~mask) | (value & mask));
- spin_unlock_irqrestore(&feature_lock, flags);
+ raw_spin_unlock_irqrestore(&feature_lock, flags);
return 0;
}
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 09e82729627..630a533d0e5 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -57,7 +57,7 @@ static int max_irqs;
static int max_real_irqs;
static u32 level_mask[4];
-static DEFINE_SPINLOCK(pmac_pic_lock);
+static DEFINE_RAW_SPINLOCK(pmac_pic_lock);
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
@@ -85,7 +85,7 @@ static void pmac_mask_and_ack_irq(unsigned int virq)
int i = src >> 5;
unsigned long flags;
- spin_lock_irqsave(&pmac_pic_lock, flags);
+ raw_spin_lock_irqsave(&pmac_pic_lock, flags);
__clear_bit(src, ppc_cached_irq_mask);
if (__test_and_clear_bit(src, ppc_lost_interrupts))
atomic_dec(&ppc_n_lost_interrupts);
@@ -97,7 +97,7 @@ static void pmac_mask_and_ack_irq(unsigned int virq)
mb();
} while((in_le32(&pmac_irq_hw[i]->enable) & bit)
!= (ppc_cached_irq_mask[i] & bit));
- spin_unlock_irqrestore(&pmac_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
}
static void pmac_ack_irq(unsigned int virq)
@@ -107,12 +107,12 @@ static void pmac_ack_irq(unsigned int virq)
int i = src >> 5;
unsigned long flags;
- spin_lock_irqsave(&pmac_pic_lock, flags);
+ raw_spin_lock_irqsave(&pmac_pic_lock, flags);
if (__test_and_clear_bit(src, ppc_lost_interrupts))
atomic_dec(&ppc_n_lost_interrupts);
out_le32(&pmac_irq_hw[i]->ack, bit);
(void)in_le32(&pmac_irq_hw[i]->ack);
- spin_unlock_irqrestore(&pmac_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
}
static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
@@ -152,12 +152,12 @@ static unsigned int pmac_startup_irq(unsigned int virq)
unsigned long bit = 1UL << (src & 0x1f);
int i = src >> 5;
- spin_lock_irqsave(&pmac_pic_lock, flags);
+ raw_spin_lock_irqsave(&pmac_pic_lock, flags);
if ((irq_to_desc(virq)->status & IRQ_LEVEL) == 0)
out_le32(&pmac_irq_hw[i]->ack, bit);
__set_bit(src, ppc_cached_irq_mask);
__pmac_set_irq_mask(src, 0);
- spin_unlock_irqrestore(&pmac_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
return 0;
}
@@ -167,10 +167,10 @@ static void pmac_mask_irq(unsigned int virq)
unsigned long flags;
unsigned int src = irq_map[virq].hwirq;
- spin_lock_irqsave(&pmac_pic_lock, flags);
+ raw_spin_lock_irqsave(&pmac_pic_lock, flags);
__clear_bit(src, ppc_cached_irq_mask);
__pmac_set_irq_mask(src, 1);
- spin_unlock_irqrestore(&pmac_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
}
static void pmac_unmask_irq(unsigned int virq)
@@ -178,24 +178,24 @@ static void pmac_unmask_irq(unsigned int virq)
unsigned long flags;
unsigned int src = irq_map[virq].hwirq;
- spin_lock_irqsave(&pmac_pic_lock, flags);
+ raw_spin_lock_irqsave(&pmac_pic_lock, flags);
__set_bit(src, ppc_cached_irq_mask);
__pmac_set_irq_mask(src, 0);
- spin_unlock_irqrestore(&pmac_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
}
static int pmac_retrigger(unsigned int virq)
{
unsigned long flags;
- spin_lock_irqsave(&pmac_pic_lock, flags);
+ raw_spin_lock_irqsave(&pmac_pic_lock, flags);
__pmac_retrigger(irq_map[virq].hwirq);
- spin_unlock_irqrestore(&pmac_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
return 1;
}
static struct irq_chip pmac_pic = {
- .name = " PMAC-PIC ",
+ .name = "PMAC-PIC",
.startup = pmac_startup_irq,
.mask = pmac_mask_irq,
.ack = pmac_ack_irq,
@@ -210,7 +210,7 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id)
int irq, bits;
int rc = IRQ_NONE;
- spin_lock_irqsave(&pmac_pic_lock, flags);
+ raw_spin_lock_irqsave(&pmac_pic_lock, flags);
for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) {
int i = irq >> 5;
bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
@@ -220,12 +220,12 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id)
if (bits == 0)
continue;
irq += __ilog2(bits);
- spin_unlock_irqrestore(&pmac_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
generic_handle_irq(irq);
- spin_lock_irqsave(&pmac_pic_lock, flags);
+ raw_spin_lock_irqsave(&pmac_pic_lock, flags);
rc = IRQ_HANDLED;
}
- spin_unlock_irqrestore(&pmac_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
return rc;
}
@@ -244,7 +244,7 @@ static unsigned int pmac_pic_get_irq(void)
return NO_IRQ_IGNORE; /* ignore, already handled */
}
#endif /* CONFIG_SMP */
- spin_lock_irqsave(&pmac_pic_lock, flags);
+ raw_spin_lock_irqsave(&pmac_pic_lock, flags);
for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
int i = irq >> 5;
bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
@@ -256,7 +256,7 @@ static unsigned int pmac_pic_get_irq(void)
irq += __ilog2(bits);
break;
}
- spin_unlock_irqrestore(&pmac_pic_lock, flags);
+ raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
if (unlikely(irq < 0))
return NO_IRQ;
return irq_linear_revmap(pmac_pic_host, irq);
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index ccd8dd03b8c..7df7fbb7cac 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -100,7 +100,7 @@ int eeh_subsystem_enabled;
EXPORT_SYMBOL(eeh_subsystem_enabled);
/* Lock to avoid races due to multiple reports of an error */
-static DEFINE_SPINLOCK(confirm_error_lock);
+static DEFINE_RAW_SPINLOCK(confirm_error_lock);
/* Buffer for reporting slot-error-detail rtas calls. Its here
* in BSS, and not dynamically alloced, so that it ends up in
@@ -436,7 +436,7 @@ static void __eeh_clear_slot(struct device_node *parent, int mode_flag)
void eeh_clear_slot (struct device_node *dn, int mode_flag)
{
unsigned long flags;
- spin_lock_irqsave(&confirm_error_lock, flags);
+ raw_spin_lock_irqsave(&confirm_error_lock, flags);
dn = find_device_pe (dn);
@@ -447,7 +447,7 @@ void eeh_clear_slot (struct device_node *dn, int mode_flag)
PCI_DN(dn)->eeh_mode &= ~mode_flag;
PCI_DN(dn)->eeh_check_count = 0;
__eeh_clear_slot(dn, mode_flag);
- spin_unlock_irqrestore(&confirm_error_lock, flags);
+ raw_spin_unlock_irqrestore(&confirm_error_lock, flags);
}
/**
@@ -491,7 +491,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
pdn->eeh_mode & EEH_MODE_NOCHECK) {
ignored_check++;
pr_debug("EEH: Ignored check (%x) for %s %s\n",
- pdn->eeh_mode, pci_name (dev), dn->full_name);
+ pdn->eeh_mode, eeh_pci_name(dev), dn->full_name);
return 0;
}
@@ -506,7 +506,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
* in one slot might report errors simultaneously, and we
* only want one error recovery routine running.
*/
- spin_lock_irqsave(&confirm_error_lock, flags);
+ raw_spin_lock_irqsave(&confirm_error_lock, flags);
rc = 1;
if (pdn->eeh_mode & EEH_MODE_ISOLATED) {
pdn->eeh_check_count ++;
@@ -515,7 +515,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
printk (KERN_ERR "EEH: %d reads ignored for recovering device at "
"location=%s driver=%s pci addr=%s\n",
pdn->eeh_check_count, location,
- dev->driver->name, pci_name(dev));
+ dev->driver->name, eeh_pci_name(dev));
printk (KERN_ERR "EEH: Might be infinite loop in %s driver\n",
dev->driver->name);
dump_stack();
@@ -575,7 +575,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
* with other functions on this device, and functions under
* bridges. */
eeh_mark_slot (dn, EEH_MODE_ISOLATED);
- spin_unlock_irqrestore(&confirm_error_lock, flags);
+ raw_spin_unlock_irqrestore(&confirm_error_lock, flags);
eeh_send_failure_event (dn, dev);
@@ -586,7 +586,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
return 1;
dn_unlock:
- spin_unlock_irqrestore(&confirm_error_lock, flags);
+ raw_spin_unlock_irqrestore(&confirm_error_lock, flags);
return rc;
}
@@ -1064,7 +1064,7 @@ void __init eeh_init(void)
struct device_node *phb, *np;
struct eeh_early_enable_info info;
- spin_lock_init(&confirm_error_lock);
+ raw_spin_lock_init(&confirm_error_lock);
spin_lock_init(&slot_errbuf_lock);
np = of_find_node_by_path("/rtas");
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index ef8e4544848..b8d70f5d9aa 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -337,7 +337,7 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
location = location ? location : "unknown";
printk(KERN_ERR "EEH: Error: Cannot find partition endpoint "
"for location=%s pci addr=%s\n",
- location, pci_name(event->dev));
+ location, eeh_pci_name(event->dev));
return NULL;
}
@@ -368,7 +368,7 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
pci_str = pci_name (frozen_pdn->pcidev);
drv_str = pcid_name (frozen_pdn->pcidev);
} else {
- pci_str = pci_name (event->dev);
+ pci_str = eeh_pci_name(event->dev);
drv_str = pcid_name (event->dev);
}
@@ -478,9 +478,9 @@ excess_failures:
* due to actual, failed cards.
*/
printk(KERN_ERR
- "EEH: PCI device at location=%s driver=%s pci addr=%s \n"
+ "EEH: PCI device at location=%s driver=%s pci addr=%s\n"
"has failed %d times in the last hour "
- "and has been permanently disabled. \n"
+ "and has been permanently disabled.\n"
"Please try reseating this device or replacing it.\n",
location, drv_str, pci_str, frozen_pdn->eeh_freeze_count);
goto perm_error;
@@ -488,7 +488,7 @@ excess_failures:
hard_fail:
printk(KERN_ERR
"EEH: Unable to recover from failure of PCI device "
- "at location=%s driver=%s pci addr=%s \n"
+ "at location=%s driver=%s pci addr=%s\n"
"Please try reseating this device or replacing it.\n",
location, drv_str, pci_str);
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c
index ddb80f5d850..ec5df8f519c 100644
--- a/arch/powerpc/platforms/pseries/eeh_event.c
+++ b/arch/powerpc/platforms/pseries/eeh_event.c
@@ -80,7 +80,7 @@ static int eeh_event_handler(void * dummy)
eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);
printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
- pci_name(event->dev));
+ eeh_pci_name(event->dev));
pdn = handle_eeh_events(event);
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 6ea4698d917..d1b124e44d7 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -387,24 +387,12 @@ static char cede_parameters[CEDE_LATENCY_PARAM_MAX_LENGTH];
static int parse_cede_parameters(void)
{
- int call_status;
-
memset(cede_parameters, 0, CEDE_LATENCY_PARAM_MAX_LENGTH);
- call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
- NULL,
- CEDE_LATENCY_TOKEN,
- __pa(cede_parameters),
- CEDE_LATENCY_PARAM_MAX_LENGTH);
-
- if (call_status != 0)
- printk(KERN_INFO "CEDE_LATENCY: \
- %s %s Error calling get-system-parameter(0x%x)\n",
- __FILE__, __func__, call_status);
- else
- printk(KERN_INFO "CEDE_LATENCY: \
- get-system-parameter successful.\n");
-
- return call_status;
+ return rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
+ NULL,
+ CEDE_LATENCY_TOKEN,
+ __pa(cede_parameters),
+ CEDE_LATENCY_PARAM_MAX_LENGTH);
}
static int __init pseries_cpu_hotplug_init(void)
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c
index 2f58c71b725..1fefae76e29 100644
--- a/arch/powerpc/platforms/pseries/hvCall_inst.c
+++ b/arch/powerpc/platforms/pseries/hvCall_inst.c
@@ -124,8 +124,8 @@ static void probe_hcall_exit(unsigned long opcode, unsigned long retval,
h = &__get_cpu_var(hcall_stats)[opcode / 4];
h->num_calls++;
- h->tb_total = mftb() - h->tb_start;
- h->purr_total = mfspr(SPRN_PURR) - h->purr_start;
+ h->tb_total += mftb() - h->tb_start;
+ h->purr_total += mfspr(SPRN_PURR) - h->purr_start;
put_cpu_var(hcall_stats);
}
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index b6fa3e4b51b..4b7a062dee1 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -165,7 +165,7 @@ int remove_phb_dynamic(struct pci_controller *phb)
struct resource *res;
int rc, i;
- pr_debug("PCI: Removing PHB %04x:%02x... \n",
+ pr_debug("PCI: Removing PHB %04x:%02x...\n",
pci_domain_nr(b), b->number);
/* We cannot to remove a root bus that has children */
diff --git a/arch/powerpc/platforms/pseries/phyp_dump.c b/arch/powerpc/platforms/pseries/phyp_dump.c
index 15eb6107bcd..225a50ab14b 100644
--- a/arch/powerpc/platforms/pseries/phyp_dump.c
+++ b/arch/powerpc/platforms/pseries/phyp_dump.c
@@ -150,7 +150,7 @@ static void print_dump_header(const struct phyp_dump_header *ph)
printk(KERN_INFO "Max auto time= %d\n", ph->maxtime_to_auto);
/*set cpu state and hpte states as well scratch pad area */
- printk(KERN_INFO " CPU AREA \n");
+ printk(KERN_INFO " CPU AREA\n");
printk(KERN_INFO "cpu dump_flags =%d\n", ph->cpu_data.dump_flags);
printk(KERN_INFO "cpu source_type =%d\n", ph->cpu_data.source_type);
printk(KERN_INFO "cpu error_flags =%d\n", ph->cpu_data.error_flags);
@@ -161,7 +161,7 @@ static void print_dump_header(const struct phyp_dump_header *ph)
printk(KERN_INFO "cpu length_copied =%llx\n",
ph->cpu_data.length_copied);
- printk(KERN_INFO " HPTE AREA \n");
+ printk(KERN_INFO " HPTE AREA\n");
printk(KERN_INFO "HPTE dump_flags =%d\n", ph->hpte_data.dump_flags);
printk(KERN_INFO "HPTE source_type =%d\n", ph->hpte_data.source_type);
printk(KERN_INFO "HPTE error_flags =%d\n", ph->hpte_data.error_flags);
@@ -172,7 +172,7 @@ static void print_dump_header(const struct phyp_dump_header *ph)
printk(KERN_INFO "HPTE length_copied =%llx\n",
ph->hpte_data.length_copied);
- printk(KERN_INFO " SRSD AREA \n");
+ printk(KERN_INFO " SRSD AREA\n");
printk(KERN_INFO "SRSD dump_flags =%d\n", ph->kernel_data.dump_flags);
printk(KERN_INFO "SRSD source_type =%d\n", ph->kernel_data.source_type);
printk(KERN_INFO "SRSD error_flags =%d\n", ph->kernel_data.error_flags);
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index b4886635972..4e7f89a8456 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -144,8 +144,8 @@ static void __devinit smp_pSeries_kick_cpu(int nr)
hcpuid = get_hard_smp_processor_id(nr);
rc = plpar_hcall_norets(H_PROD, hcpuid);
if (rc != H_SUCCESS)
- printk(KERN_ERR "Error: Prod to wake up processor %d\
- Ret= %ld\n", nr, rc);
+ printk(KERN_ERR "Error: Prod to wake up processor %d "
+ "Ret= %ld\n", nr, rc);
}
}
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index f5f79196721..4ca641042ec 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -127,7 +127,7 @@ static inline unsigned int lpar_xirr_info_get(void)
lpar_rc = plpar_xirr(&return_value);
if (lpar_rc != H_SUCCESS)
- panic(" bad return code xirr - rc = %lx \n", lpar_rc);
+ panic(" bad return code xirr - rc = %lx\n", lpar_rc);
return (unsigned int)return_value;
}
@@ -424,7 +424,7 @@ static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
}
static struct irq_chip xics_pic_direct = {
- .name = " XICS ",
+ .name = "XICS",
.startup = xics_startup,
.mask = xics_mask_irq,
.unmask = xics_unmask_irq,
@@ -433,7 +433,7 @@ static struct irq_chip xics_pic_direct = {
};
static struct irq_chip xics_pic_lpar = {
- .name = " XICS ",
+ .name = "XICS",
.startup = xics_startup,
.mask = xics_mask_irq,
.unmask = xics_unmask_irq,
@@ -510,15 +510,13 @@ static void __init xics_init_host(void)
/*
* XICS only has a single IPI, so encode the messages per CPU
*/
-struct xics_ipi_struct {
- unsigned long value;
- } ____cacheline_aligned;
-
-static struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
+static DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message);
static inline void smp_xics_do_message(int cpu, int msg)
{
- set_bit(msg, &xics_ipi_message[cpu].value);
+ unsigned long *tgt = &per_cpu(xics_ipi_message, cpu);
+
+ set_bit(msg, tgt);
mb();
if (firmware_has_feature(FW_FEATURE_LPAR))
lpar_qirr_info(cpu, IPI_PRIORITY);
@@ -544,25 +542,23 @@ void smp_xics_message_pass(int target, int msg)
static irqreturn_t xics_ipi_dispatch(int cpu)
{
+ unsigned long *tgt = &per_cpu(xics_ipi_message, cpu);
+
WARN_ON(cpu_is_offline(cpu));
mb(); /* order mmio clearing qirr */
- while (xics_ipi_message[cpu].value) {
- if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION,
- &xics_ipi_message[cpu].value)) {
+ while (*tgt) {
+ if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, tgt)) {
smp_message_recv(PPC_MSG_CALL_FUNCTION);
}
- if (test_and_clear_bit(PPC_MSG_RESCHEDULE,
- &xics_ipi_message[cpu].value)) {
+ if (test_and_clear_bit(PPC_MSG_RESCHEDULE, tgt)) {
smp_message_recv(PPC_MSG_RESCHEDULE);
}
- if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE,
- &xics_ipi_message[cpu].value)) {
+ if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, tgt)) {
smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE);
}
#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
- if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
- &xics_ipi_message[cpu].value)) {
+ if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, tgt)) {
smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
}
#endif
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index a4b41dbde12..ecad10d4e92 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -77,7 +77,7 @@ static void cpm_end_irq(unsigned int irq)
}
static struct irq_chip cpm_pic = {
- .name = " CPM PIC ",
+ .name = "CPM PIC",
.mask = cpm_mask_irq,
.unmask = cpm_unmask_irq,
.eoi = cpm_end_irq,
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index 1709ac5aac7..fcea4ff825d 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -198,7 +198,7 @@ err_sense:
}
static struct irq_chip cpm2_pic = {
- .name = " CPM2 SIU ",
+ .name = "CPM2 SIU",
.mask = cpm2_mask_irq,
.unmask = cpm2_unmask_irq,
.ack = cpm2_ack,
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index c6e11b07710..e094367d773 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -47,7 +47,7 @@ static struct irq_chip fsl_msi_chip = {
.mask = mask_msi_irq,
.unmask = unmask_msi_irq,
.ack = fsl_msi_end_irq,
- .name = " FSL-MSI ",
+ .name = "FSL-MSI",
};
static int fsl_msi_host_map(struct irq_host *h, unsigned int virq,
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index 0a55db8a5a2..6323e70e6bf 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -23,7 +23,7 @@ static unsigned char cached_8259[2] = { 0xff, 0xff };
#define cached_A1 (cached_8259[0])
#define cached_21 (cached_8259[1])
-static DEFINE_SPINLOCK(i8259_lock);
+static DEFINE_RAW_SPINLOCK(i8259_lock);
static struct irq_host *i8259_host;
@@ -42,7 +42,7 @@ unsigned int i8259_irq(void)
if (pci_intack)
irq = readb(pci_intack);
else {
- spin_lock(&i8259_lock);
+ raw_spin_lock(&i8259_lock);
lock = 1;
/* Perform an interrupt acknowledge cycle on controller 1. */
@@ -74,7 +74,7 @@ unsigned int i8259_irq(void)
irq = NO_IRQ;
if (lock)
- spin_unlock(&i8259_lock);
+ raw_spin_unlock(&i8259_lock);
return irq;
}
@@ -82,7 +82,7 @@ static void i8259_mask_and_ack_irq(unsigned int irq_nr)
{
unsigned long flags;
- spin_lock_irqsave(&i8259_lock, flags);
+ raw_spin_lock_irqsave(&i8259_lock, flags);
if (irq_nr > 7) {
cached_A1 |= 1 << (irq_nr-8);
inb(0xA1); /* DUMMY */
@@ -95,7 +95,7 @@ static void i8259_mask_and_ack_irq(unsigned int irq_nr)
outb(cached_21, 0x21);
outb(0x20, 0x20); /* Non-specific EOI */
}
- spin_unlock_irqrestore(&i8259_lock, flags);
+ raw_spin_unlock_irqrestore(&i8259_lock, flags);
}
static void i8259_set_irq_mask(int irq_nr)
@@ -110,13 +110,13 @@ static void i8259_mask_irq(unsigned int irq_nr)
pr_debug("i8259_mask_irq(%d)\n", irq_nr);
- spin_lock_irqsave(&i8259_lock, flags);
+ raw_spin_lock_irqsave(&i8259_lock, flags);
if (irq_nr < 8)
cached_21 |= 1 << irq_nr;
else
cached_A1 |= 1 << (irq_nr-8);
i8259_set_irq_mask(irq_nr);
- spin_unlock_irqrestore(&i8259_lock, flags);
+ raw_spin_unlock_irqrestore(&i8259_lock, flags);
}
static void i8259_unmask_irq(unsigned int irq_nr)
@@ -125,17 +125,17 @@ static void i8259_unmask_irq(unsigned int irq_nr)
pr_debug("i8259_unmask_irq(%d)\n", irq_nr);
- spin_lock_irqsave(&i8259_lock, flags);
+ raw_spin_lock_irqsave(&i8259_lock, flags);
if (irq_nr < 8)
cached_21 &= ~(1 << irq_nr);
else
cached_A1 &= ~(1 << (irq_nr-8));
i8259_set_irq_mask(irq_nr);
- spin_unlock_irqrestore(&i8259_lock, flags);
+ raw_spin_unlock_irqrestore(&i8259_lock, flags);
}
static struct irq_chip i8259_pic = {
- .name = " i8259 ",
+ .name = "i8259",
.mask = i8259_mask_irq,
.disable = i8259_mask_irq,
.unmask = i8259_unmask_irq,
@@ -241,7 +241,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
unsigned long flags;
/* initialize the controller */
- spin_lock_irqsave(&i8259_lock, flags);
+ raw_spin_lock_irqsave(&i8259_lock, flags);
/* Mask all first */
outb(0xff, 0xA1);
@@ -273,7 +273,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
outb(cached_A1, 0xA1);
outb(cached_21, 0x21);
- spin_unlock_irqrestore(&i8259_lock, flags);
+ raw_spin_unlock_irqrestore(&i8259_lock, flags);
/* create a legacy host */
i8259_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY,
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 28cdddd2f89..d7b9b9c6928 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -32,7 +32,7 @@
static struct ipic * primary_ipic;
static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip;
-static DEFINE_SPINLOCK(ipic_lock);
+static DEFINE_RAW_SPINLOCK(ipic_lock);
static struct ipic_info ipic_info[] = {
[1] = {
@@ -530,13 +530,13 @@ static void ipic_unmask_irq(unsigned int virq)
unsigned long flags;
u32 temp;
- spin_lock_irqsave(&ipic_lock, flags);
+ raw_spin_lock_irqsave(&ipic_lock, flags);
temp = ipic_read(ipic->regs, ipic_info[src].mask);
temp |= (1 << (31 - ipic_info[src].bit));
ipic_write(ipic->regs, ipic_info[src].mask, temp);
- spin_unlock_irqrestore(&ipic_lock, flags);
+ raw_spin_unlock_irqrestore(&ipic_lock, flags);
}
static void ipic_mask_irq(unsigned int virq)
@@ -546,7 +546,7 @@ static void ipic_mask_irq(unsigned int virq)
unsigned long flags;
u32 temp;
- spin_lock_irqsave(&ipic_lock, flags);
+ raw_spin_lock_irqsave(&ipic_lock, flags);
temp = ipic_read(ipic->regs, ipic_info[src].mask);
temp &= ~(1 << (31 - ipic_info[src].bit));
@@ -556,7 +556,7 @@ static void ipic_mask_irq(unsigned int virq)
* for nearly all cases. */
mb();
- spin_unlock_irqrestore(&ipic_lock, flags);
+ raw_spin_unlock_irqrestore(&ipic_lock, flags);
}
static void ipic_ack_irq(unsigned int virq)
@@ -566,7 +566,7 @@ static void ipic_ack_irq(unsigned int virq)
unsigned long flags;
u32 temp;
- spin_lock_irqsave(&ipic_lock, flags);
+ raw_spin_lock_irqsave(&ipic_lock, flags);
temp = 1 << (31 - ipic_info[src].bit);
ipic_write(ipic->regs, ipic_info[src].ack, temp);
@@ -575,7 +575,7 @@ static void ipic_ack_irq(unsigned int virq)
* for nearly all cases. */
mb();
- spin_unlock_irqrestore(&ipic_lock, flags);
+ raw_spin_unlock_irqrestore(&ipic_lock, flags);
}
static void ipic_mask_irq_and_ack(unsigned int virq)
@@ -585,7 +585,7 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
unsigned long flags;
u32 temp;
- spin_lock_irqsave(&ipic_lock, flags);
+ raw_spin_lock_irqsave(&ipic_lock, flags);
temp = ipic_read(ipic->regs, ipic_info[src].mask);
temp &= ~(1 << (31 - ipic_info[src].bit));
@@ -598,7 +598,7 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
* for nearly all cases. */
mb();
- spin_unlock_irqrestore(&ipic_lock, flags);
+ raw_spin_unlock_irqrestore(&ipic_lock, flags);
}
static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
@@ -660,7 +660,7 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
/* level interrupts and edge interrupts have different ack operations */
static struct irq_chip ipic_level_irq_chip = {
- .name = " IPIC ",
+ .name = "IPIC",
.unmask = ipic_unmask_irq,
.mask = ipic_mask_irq,
.mask_ack = ipic_mask_irq,
@@ -668,7 +668,7 @@ static struct irq_chip ipic_level_irq_chip = {
};
static struct irq_chip ipic_edge_irq_chip = {
- .name = " IPIC ",
+ .name = "IPIC",
.unmask = ipic_unmask_irq,
.mask = ipic_mask_irq,
.mask_ack = ipic_mask_irq_and_ack,
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 69bd6f4dff8..8c27d261aba 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -94,7 +94,7 @@ static int mpc8xx_set_irq_type(unsigned int virq, unsigned int flow_type)
}
static struct irq_chip mpc8xx_pic = {
- .name = " MPC8XX SIU ",
+ .name = "MPC8XX SIU",
.unmask = mpc8xx_unmask_irq,
.mask = mpc8xx_mask_irq,
.ack = mpc8xx_ack,
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 470dc6c11d5..339e8a3e26d 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -46,7 +46,7 @@
static struct mpic *mpics;
static struct mpic *mpic_primary;
-static DEFINE_SPINLOCK(mpic_lock);
+static DEFINE_RAW_SPINLOCK(mpic_lock);
#ifdef CONFIG_PPC32 /* XXX for now */
#ifdef CONFIG_IRQ_ALL_CPUS
@@ -347,10 +347,10 @@ static inline void mpic_ht_end_irq(struct mpic *mpic, unsigned int source)
unsigned int mask = 1U << (fixup->index & 0x1f);
writel(mask, fixup->applebase + soff);
} else {
- spin_lock(&mpic->fixup_lock);
+ raw_spin_lock(&mpic->fixup_lock);
writeb(0x11 + 2 * fixup->index, fixup->base + 2);
writel(fixup->data, fixup->base + 4);
- spin_unlock(&mpic->fixup_lock);
+ raw_spin_unlock(&mpic->fixup_lock);
}
}
@@ -366,7 +366,7 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
DBG("startup_ht_interrupt(0x%x, 0x%x) index: %d\n",
source, irqflags, fixup->index);
- spin_lock_irqsave(&mpic->fixup_lock, flags);
+ raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
/* Enable and configure */
writeb(0x10 + 2 * fixup->index, fixup->base + 2);
tmp = readl(fixup->base + 4);
@@ -374,7 +374,7 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
if (irqflags & IRQ_LEVEL)
tmp |= 0x22;
writel(tmp, fixup->base + 4);
- spin_unlock_irqrestore(&mpic->fixup_lock, flags);
+ raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags);
#ifdef CONFIG_PM
/* use the lowest bit inverted to the actual HW,
@@ -396,12 +396,12 @@ static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
DBG("shutdown_ht_interrupt(0x%x, 0x%x)\n", source, irqflags);
/* Disable */
- spin_lock_irqsave(&mpic->fixup_lock, flags);
+ raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
writeb(0x10 + 2 * fixup->index, fixup->base + 2);
tmp = readl(fixup->base + 4);
tmp |= 1;
writel(tmp, fixup->base + 4);
- spin_unlock_irqrestore(&mpic->fixup_lock, flags);
+ raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags);
#ifdef CONFIG_PM
/* use the lowest bit inverted to the actual HW,
@@ -515,7 +515,7 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
BUG_ON(mpic->fixups == NULL);
/* Init spinlock */
- spin_lock_init(&mpic->fixup_lock);
+ raw_spin_lock_init(&mpic->fixup_lock);
/* Map U3 config space. We assume all IO-APICs are on the primary bus
* so we only need to map 64kB.
@@ -573,12 +573,12 @@ static int irq_choose_cpu(const cpumask_t *mask)
if (cpumask_equal(mask, cpu_all_mask)) {
static int irq_rover;
- static DEFINE_SPINLOCK(irq_rover_lock);
+ static DEFINE_RAW_SPINLOCK(irq_rover_lock);
unsigned long flags;
/* Round-robin distribution... */
do_round_robin:
- spin_lock_irqsave(&irq_rover_lock, flags);
+ raw_spin_lock_irqsave(&irq_rover_lock, flags);
while (!cpu_online(irq_rover)) {
if (++irq_rover >= NR_CPUS)
@@ -590,7 +590,7 @@ static int irq_choose_cpu(const cpumask_t *mask)
irq_rover = 0;
} while (!cpu_online(irq_rover));
- spin_unlock_irqrestore(&irq_rover_lock, flags);
+ raw_spin_unlock_irqrestore(&irq_rover_lock, flags);
} else {
cpuid = cpumask_first_and(mask, cpu_online_mask);
if (cpuid >= nr_cpu_ids)
@@ -1368,14 +1368,14 @@ void __init mpic_set_serial_int(struct mpic *mpic, int enable)
unsigned long flags;
u32 v;
- spin_lock_irqsave(&mpic_lock, flags);
+ raw_spin_lock_irqsave(&mpic_lock, flags);
v = mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1);
if (enable)
v |= MPIC_GREG_GLOBAL_CONF_1_SIE;
else
v &= ~MPIC_GREG_GLOBAL_CONF_1_SIE;
mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1, v);
- spin_unlock_irqrestore(&mpic_lock, flags);
+ raw_spin_unlock_irqrestore(&mpic_lock, flags);
}
void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
@@ -1388,7 +1388,7 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
if (!mpic)
return;
- spin_lock_irqsave(&mpic_lock, flags);
+ raw_spin_lock_irqsave(&mpic_lock, flags);
if (mpic_is_ipi(mpic, irq)) {
reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) &
~MPIC_VECPRI_PRIORITY_MASK;
@@ -1400,7 +1400,7 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
}
- spin_unlock_irqrestore(&mpic_lock, flags);
+ raw_spin_unlock_irqrestore(&mpic_lock, flags);
}
void mpic_setup_this_cpu(void)
@@ -1415,7 +1415,7 @@ void mpic_setup_this_cpu(void)
DBG("%s: setup_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
- spin_lock_irqsave(&mpic_lock, flags);
+ raw_spin_lock_irqsave(&mpic_lock, flags);
/* let the mpic know we want intrs. default affinity is 0xffffffff
* until changed via /proc. That's how it's done on x86. If we want
@@ -1431,7 +1431,7 @@ void mpic_setup_this_cpu(void)
/* Set current processor priority to 0 */
mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
- spin_unlock_irqrestore(&mpic_lock, flags);
+ raw_spin_unlock_irqrestore(&mpic_lock, flags);
#endif /* CONFIG_SMP */
}
@@ -1460,7 +1460,7 @@ void mpic_teardown_this_cpu(int secondary)
BUG_ON(mpic == NULL);
DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
- spin_lock_irqsave(&mpic_lock, flags);
+ raw_spin_lock_irqsave(&mpic_lock, flags);
/* let the mpic know we don't want intrs. */
for (i = 0; i < mpic->num_sources ; i++)
@@ -1474,7 +1474,7 @@ void mpic_teardown_this_cpu(int secondary)
*/
mpic_eoi(mpic);
- spin_unlock_irqrestore(&mpic_lock, flags);
+ raw_spin_unlock_irqrestore(&mpic_lock, flags);
}
@@ -1575,7 +1575,7 @@ void mpic_request_ipis(void)
int i;
BUG_ON(mpic == NULL);
- printk(KERN_INFO "mpic: requesting IPIs ... \n");
+ printk(KERN_INFO "mpic: requesting IPIs...\n");
for (i = 0; i < 4; i++) {
unsigned int vipi = irq_create_mapping(mpic->irqhost,
diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c
index 0f6ab06f847..3b6a9a43718 100644
--- a/arch/powerpc/sysdev/mpic_pasemi_msi.c
+++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c
@@ -60,7 +60,7 @@ static struct irq_chip mpic_pasemi_msi_chip = {
.eoi = mpic_end_irq,
.set_type = mpic_set_irq_type,
.set_affinity = mpic_set_affinity,
- .name = "PASEMI-MSI ",
+ .name = "PASEMI-MSI",
};
static int pasemi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c
index b6bd775d2e2..31acd3b1718 100644
--- a/arch/powerpc/sysdev/mv64x60_dev.c
+++ b/arch/powerpc/sysdev/mv64x60_dev.c
@@ -16,6 +16,7 @@
#include <linux/mv643xx.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
+#include <linux/dma-mapping.h>
#include <asm/prom.h>
@@ -189,6 +190,7 @@ static int __init mv64x60_mpsc_device_setup(struct device_node *np, int id)
pdev = platform_device_alloc(MPSC_CTLR_NAME, port_number);
if (!pdev)
return -ENOMEM;
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
err = platform_device_add_resources(pdev, r, 5);
if (err)
@@ -302,6 +304,7 @@ static int __init mv64x60_eth_device_setup(struct device_node *np, int id,
if (!pdev)
return -ENOMEM;
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
err = platform_device_add_resources(pdev, r, 1);
if (err)
goto error;
diff --git a/arch/powerpc/sysdev/ppc4xx_soc.c b/arch/powerpc/sysdev/ppc4xx_soc.c
index 5b32adc9a9b..5c014350bf1 100644
--- a/arch/powerpc/sysdev/ppc4xx_soc.c
+++ b/arch/powerpc/sysdev/ppc4xx_soc.c
@@ -174,7 +174,8 @@ static int __init ppc4xx_l2c_probe(void)
| L2C_CFG_CPIM | L2C_CFG_TPIM | L2C_CFG_LIM | L2C_CFG_SMCM;
/* Check for 460EX/GT special handling */
- if (of_device_is_compatible(np, "ibm,l2-cache-460ex"))
+ if (of_device_is_compatible(np, "ibm,l2-cache-460ex") ||
+ of_device_is_compatible(np, "ibm,l2-cache-460gt"))
r |= L2C_CFG_RDBW;
mtdcr(dcrbase_l2c + DCRN_L2C0_CFG, r);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 2acc928d192..d927da893ec 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -237,7 +237,7 @@ static void qe_ic_mask_irq(unsigned int virq)
}
static struct irq_chip qe_ic_irq_chip = {
- .name = " QEIC ",
+ .name = "QEIC",
.unmask = qe_ic_unmask_irq,
.mask = qe_ic_mask_irq,
.mask_ack = qe_ic_mask_irq,
@@ -256,7 +256,7 @@ static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
struct irq_chip *chip;
if (qe_ic_info[hw].mask == 0) {
- printk(KERN_ERR "Can't map reserved IRQ \n");
+ printk(KERN_ERR "Can't map reserved IRQ\n");
return -EINVAL;
}
/* Default chip */
diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/arch/powerpc/sysdev/qe_lib/qe_io.c
index 7c87460179e..77e4934b88c 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_io.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_io.c
@@ -157,13 +157,13 @@ int par_io_of_config(struct device_node *np)
const unsigned int *pio_map;
if (par_io == NULL) {
- printk(KERN_ERR "par_io not initialized \n");
+ printk(KERN_ERR "par_io not initialized\n");
return -1;
}
ph = of_get_property(np, "pio-handle", NULL);
if (ph == NULL) {
- printk(KERN_ERR "pio-handle not available \n");
+ printk(KERN_ERR "pio-handle not available\n");
return -1;
}
@@ -171,12 +171,12 @@ int par_io_of_config(struct device_node *np)
pio_map = of_get_property(pio, "pio-map", &pio_map_len);
if (pio_map == NULL) {
- printk(KERN_ERR "pio-map is not set! \n");
+ printk(KERN_ERR "pio-map is not set!\n");
return -1;
}
pio_map_len /= sizeof(unsigned int);
if ((pio_map_len % 6) != 0) {
- printk(KERN_ERR "pio-map format wrong! \n");
+ printk(KERN_ERR "pio-map format wrong!\n");
return -1;
}
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 6f220a913e4..0038fb78f09 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -177,7 +177,7 @@ static int uic_set_irq_type(unsigned int virq, unsigned int flow_type)
}
static struct irq_chip uic_irq_chip = {
- .name = " UIC ",
+ .name = "UIC",
.unmask = uic_unmask_irq,
.mask = uic_mask_irq,
.mask_ack = uic_mask_ack_irq,
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 4e6152c1376..8bad7d5f32a 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -61,7 +61,7 @@ static int xmon_owner;
static int xmon_gate;
#endif /* CONFIG_SMP */
-static unsigned long in_xmon = 0;
+static unsigned long in_xmon __read_mostly = 0;
static unsigned long adrs;
static int size = 1;
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index a8c8b56b275..1b3def1e859 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -28,6 +28,9 @@
* All disk operations are performed by sending messages back and forth to
* the OS/400 partition.
*/
+
+#define pr_fmt(fmt) "viod: " fmt
+
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/module.h>
@@ -63,9 +66,6 @@ MODULE_LICENSE("GPL");
#define VIOD_VERS "1.64"
-#define VIOD_KERN_WARNING KERN_WARNING "viod: "
-#define VIOD_KERN_INFO KERN_INFO "viod: "
-
enum {
PARTITION_SHIFT = 3,
MAX_DISKNO = HVMAXARCHITECTEDVIRTUALDISKS,
@@ -156,7 +156,7 @@ static int viodasd_open(struct block_device *bdev, fmode_t mode)
((u64)DEVICE_NO(d) << 48) | ((u64)flags << 32),
0, 0, 0);
if (hvrc != 0) {
- printk(VIOD_KERN_WARNING "HV open failed %d\n", (int)hvrc);
+ pr_warning("HV open failed %d\n", (int)hvrc);
return -EIO;
}
@@ -167,9 +167,8 @@ static int viodasd_open(struct block_device *bdev, fmode_t mode)
const struct vio_error_entry *err =
vio_lookup_rc(viodasd_err_table, we.sub_result);
- printk(VIOD_KERN_WARNING
- "bad rc opening disk: %d:0x%04x (%s)\n",
- (int)we.rc, we.sub_result, err->msg);
+ pr_warning("bad rc opening disk: %d:0x%04x (%s)\n",
+ (int)we.rc, we.sub_result, err->msg);
return -EIO;
}
@@ -195,8 +194,7 @@ static int viodasd_release(struct gendisk *disk, fmode_t mode)
((u64)DEVICE_NO(d) << 48) /* | ((u64)flags << 32) */,
0, 0, 0);
if (hvrc != 0)
- printk(VIOD_KERN_WARNING "HV close call failed %d\n",
- (int)hvrc);
+ pr_warning("HV close call failed %d\n", (int)hvrc);
return 0;
}
@@ -288,8 +286,7 @@ static int send_request(struct request *req)
bevent = (struct vioblocklpevent *)
vio_get_event_buffer(viomajorsubtype_blockio);
if (bevent == NULL) {
- printk(VIOD_KERN_WARNING
- "error allocating disk event buffer\n");
+ pr_warning("error allocating disk event buffer\n");
goto error_ret;
}
@@ -333,9 +330,8 @@ static int send_request(struct request *req)
}
if (hvrc != HvLpEvent_Rc_Good) {
- printk(VIOD_KERN_WARNING
- "error sending disk event to OS/400 (rc %d)\n",
- (int)hvrc);
+ pr_warning("error sending disk event to OS/400 (rc %d)\n",
+ (int)hvrc);
goto error_ret;
}
spin_unlock_irqrestore(&viodasd_spinlock, flags);
@@ -402,7 +398,7 @@ retry:
((u64)dev_no << 48) | ((u64)flags<< 32),
0, 0, 0);
if (hvrc != 0) {
- printk(VIOD_KERN_WARNING "bad rc on HV open %d\n", (int)hvrc);
+ pr_warning("bad rc on HV open %d\n", (int)hvrc);
return 0;
}
@@ -416,9 +412,8 @@ retry:
goto retry;
}
if (we.max_disk > (MAX_DISKNO - 1)) {
- printk_once(VIOD_KERN_INFO
- "Only examining the first %d of %d disks connected\n",
- MAX_DISKNO, we.max_disk + 1);
+ printk_once(KERN_INFO pr_fmt("Only examining the first %d of %d disks connected\n"),
+ MAX_DISKNO, we.max_disk + 1);
}
/* Send the close event to OS/400. We DON'T expect a response */
@@ -432,17 +427,15 @@ retry:
((u64)dev_no << 48) | ((u64)flags << 32),
0, 0, 0);
if (hvrc != 0) {
- printk(VIOD_KERN_WARNING
- "bad rc sending event to OS/400 %d\n", (int)hvrc);
+ pr_warning("bad rc sending event to OS/400 %d\n", (int)hvrc);
return 0;
}
if (d->dev == NULL) {
/* this is when we reprobe for new disks */
if (vio_create_viodasd(dev_no) == NULL) {
- printk(VIOD_KERN_WARNING
- "cannot allocate virtual device for disk %d\n",
- dev_no);
+ pr_warning("cannot allocate virtual device for disk %d\n",
+ dev_no);
return 0;
}
/*
@@ -457,15 +450,13 @@ retry:
spin_lock_init(&d->q_lock);
q = blk_init_queue(do_viodasd_request, &d->q_lock);
if (q == NULL) {
- printk(VIOD_KERN_WARNING "cannot allocate queue for disk %d\n",
- dev_no);
+ pr_warning("cannot allocate queue for disk %d\n", dev_no);
return 0;
}
g = alloc_disk(1 << PARTITION_SHIFT);
if (g == NULL) {
- printk(VIOD_KERN_WARNING
- "cannot allocate disk structure for disk %d\n",
- dev_no);
+ pr_warning("cannot allocate disk structure for disk %d\n",
+ dev_no);
blk_cleanup_queue(q);
return 0;
}
@@ -489,13 +480,12 @@ retry:
g->driverfs_dev = d->dev;
set_capacity(g, d->size >> 9);
- printk(VIOD_KERN_INFO "disk %d: %lu sectors (%lu MB) "
- "CHS=%d/%d/%d sector size %d%s\n",
- dev_no, (unsigned long)(d->size >> 9),
- (unsigned long)(d->size >> 20),
- (int)d->cylinders, (int)d->tracks,
- (int)d->sectors, (int)d->bytes_per_sector,
- d->read_only ? " (RO)" : "");
+ pr_info("disk %d: %lu sectors (%lu MB) CHS=%d/%d/%d sector size %d%s\n",
+ dev_no, (unsigned long)(d->size >> 9),
+ (unsigned long)(d->size >> 20),
+ (int)d->cylinders, (int)d->tracks,
+ (int)d->sectors, (int)d->bytes_per_sector,
+ d->read_only ? " (RO)" : "");
/* register us in the global list */
add_disk(g);
@@ -580,8 +570,8 @@ static int viodasd_handle_read_write(struct vioblocklpevent *bevent)
if (error) {
const struct vio_error_entry *err;
err = vio_lookup_rc(viodasd_err_table, bevent->sub_result);
- printk(VIOD_KERN_WARNING "read/write error %d:0x%04x (%s)\n",
- event->xRc, bevent->sub_result, err->msg);
+ pr_warning("read/write error %d:0x%04x (%s)\n",
+ event->xRc, bevent->sub_result, err->msg);
num_sect = blk_rq_sectors(req);
}
qlock = req->q->queue_lock;
@@ -606,8 +596,7 @@ static void handle_block_event(struct HvLpEvent *event)
return;
/* First, we should NEVER get an int here...only acks */
if (hvlpevent_is_int(event)) {
- printk(VIOD_KERN_WARNING
- "Yikes! got an int in viodasd event handler!\n");
+ pr_warning("Yikes! got an int in viodasd event handler!\n");
if (hvlpevent_need_ack(event)) {
event->xRc = HvLpEvent_Rc_InvalidSubtype;
HvCallEvent_ackLpEvent(event);
@@ -650,7 +639,7 @@ static void handle_block_event(struct HvLpEvent *event)
break;
default:
- printk(VIOD_KERN_WARNING "invalid subtype!");
+ pr_warning("invalid subtype!");
if (hvlpevent_need_ack(event)) {
event->xRc = HvLpEvent_Rc_InvalidSubtype;
HvCallEvent_ackLpEvent(event);
@@ -739,29 +728,26 @@ static int __init viodasd_init(void)
vio_set_hostlp();
if (viopath_hostLp == HvLpIndexInvalid) {
- printk(VIOD_KERN_WARNING "invalid hosting partition\n");
+ pr_warning("invalid hosting partition\n");
rc = -EIO;
goto early_fail;
}
- printk(VIOD_KERN_INFO "vers " VIOD_VERS ", hosting partition %d\n",
- viopath_hostLp);
+ pr_info("vers " VIOD_VERS ", hosting partition %d\n", viopath_hostLp);
/* register the block device */
rc = register_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
if (rc) {
- printk(VIOD_KERN_WARNING
- "Unable to get major number %d for %s\n",
- VIODASD_MAJOR, VIOD_GENHD_NAME);
+ pr_warning("Unable to get major number %d for %s\n",
+ VIODASD_MAJOR, VIOD_GENHD_NAME);
goto early_fail;
}
/* Actually open the path to the hosting partition */
rc = viopath_open(viopath_hostLp, viomajorsubtype_blockio,
VIOMAXREQ + 2);
if (rc) {
- printk(VIOD_KERN_WARNING
- "error opening path to host partition %d\n",
- viopath_hostLp);
+ pr_warning("error opening path to host partition %d\n",
+ viopath_hostLp);
goto unregister_blk;
}
@@ -770,7 +756,7 @@ static int __init viodasd_init(void)
rc = vio_register_driver(&viodasd_driver);
if (rc) {
- printk(VIOD_KERN_WARNING "vio_register_driver failed\n");
+ pr_warning("vio_register_driver failed\n");
goto unset_handler;
}
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index d8dac5820f0..4c3b59be286 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -748,9 +748,9 @@ static const struct tty_operations hvc_ops = {
.chars_in_buffer = hvc_chars_in_buffer,
};
-struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data,
- const struct hv_ops *ops,
- int outbuf_size)
+struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
+ const struct hv_ops *ops,
+ int outbuf_size)
{
struct hvc_struct *hp;
int i;
diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h
index 52ddf4d3716..54381eba4e4 100644
--- a/drivers/char/hvc_console.h
+++ b/drivers/char/hvc_console.h
@@ -80,8 +80,8 @@ extern int hvc_instantiate(uint32_t vtermno, int index,
const struct hv_ops *ops);
/* register a vterm for hvc tty operation (module_init or hotplug add) */
-extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int data,
- const struct hv_ops *ops, int outbuf_size);
+extern struct hvc_struct * hvc_alloc(uint32_t vtermno, int data,
+ const struct hv_ops *ops, int outbuf_size);
/* remove a vterm from hvc tty operation (module_exit or hotplug remove) */
extern int hvc_remove(struct hvc_struct *hp);
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 2db4c0a29b0..c9bc896d68a 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1047,7 +1047,7 @@ release_io:
static ssize_t cmm_write(struct file *filp, const char __user *buf,
size_t count, loff_t *ppos)
{
- struct cm4000_dev *dev = (struct cm4000_dev *) filp->private_data;
+ struct cm4000_dev *dev = filp->private_data;
unsigned int iobase = dev->p_dev->io.BasePort1;
unsigned short s;
unsigned char tmp;
diff --git a/drivers/hwmon/ams/ams-core.c b/drivers/hwmon/ams/ams-core.c
index 6c9ace1b76f..2ad62c339cd 100644
--- a/drivers/hwmon/ams/ams-core.c
+++ b/drivers/hwmon/ams/ams-core.c
@@ -213,7 +213,7 @@ int __init ams_init(void)
return -ENODEV;
}
-void ams_exit(void)
+void ams_sensor_detach(void)
{
/* Remove input device */
ams_input_exit();
@@ -221,9 +221,6 @@ void ams_exit(void)
/* Remove attributes */
device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
- /* Shut down implementation */
- ams_info.exit();
-
/* Flush interrupt worker
*
* We do this after ams_info.exit(), because an interrupt might
@@ -239,6 +236,12 @@ void ams_exit(void)
pmf_unregister_irq_client(&ams_freefall_client);
}
+static void __exit ams_exit(void)
+{
+ /* Shut down implementation */
+ ams_info.exit();
+}
+
MODULE_AUTHOR("Stelian Pop, Michael Hanselmann");
MODULE_DESCRIPTION("Apple Motion Sensor driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/ams/ams-i2c.c b/drivers/hwmon/ams/ams-i2c.c
index 2cbf8a6506c..abeecd27b48 100644
--- a/drivers/hwmon/ams/ams-i2c.c
+++ b/drivers/hwmon/ams/ams-i2c.c
@@ -238,6 +238,8 @@ static int ams_i2c_probe(struct i2c_client *client,
static int ams_i2c_remove(struct i2c_client *client)
{
if (ams_info.has_device) {
+ ams_sensor_detach();
+
/* Disable interrupts */
ams_i2c_set_irq(AMS_IRQ_ALL, 0);
diff --git a/drivers/hwmon/ams/ams-pmu.c b/drivers/hwmon/ams/ams-pmu.c
index fb18b3d3162..4f61b3ee1b0 100644
--- a/drivers/hwmon/ams/ams-pmu.c
+++ b/drivers/hwmon/ams/ams-pmu.c
@@ -133,6 +133,8 @@ static void ams_pmu_get_xyz(s8 *x, s8 *y, s8 *z)
static void ams_pmu_exit(void)
{
+ ams_sensor_detach();
+
/* Disable interrupts */
ams_pmu_set_irq(AMS_IRQ_ALL, 0);
diff --git a/drivers/hwmon/ams/ams.h b/drivers/hwmon/ams/ams.h
index 5ed387b0bd9..b28d7e27a03 100644
--- a/drivers/hwmon/ams/ams.h
+++ b/drivers/hwmon/ams/ams.h
@@ -61,6 +61,7 @@ extern struct ams ams_info;
extern void ams_sensors(s8 *x, s8 *y, s8 *z);
extern int ams_sensor_attach(void);
+extern void ams_sensor_detach(void);
extern int ams_pmu_init(struct device_node *np);
extern int ams_i2c_init(struct device_node *np);
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 5ff47ba7f2d..c42eeb43042 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -90,6 +90,8 @@ static struct task_struct *thread_therm = NULL;
static void write_both_fan_speed(struct thermostat *th, int speed);
static void write_fan_speed(struct thermostat *th, int speed, int fan);
+static void thermostat_create_files(void);
+static void thermostat_remove_files(void);
static int
write_reg(struct thermostat* th, int reg, u8 data)
@@ -161,6 +163,8 @@ remove_thermostat(struct i2c_client *client)
struct thermostat *th = i2c_get_clientdata(client);
int i;
+ thermostat_remove_files();
+
if (thread_therm != NULL) {
kthread_stop(thread_therm);
}
@@ -312,7 +316,7 @@ static void update_fans_speed (struct thermostat *th)
if (verbose)
printk(KERN_DEBUG "adt746x: Setting fans speed to %d "
- "(limit exceeded by %d on %s) \n",
+ "(limit exceeded by %d on %s)\n",
new_speed, var,
sensor_location[fan_number+1]);
write_both_fan_speed(th, new_speed);
@@ -449,6 +453,8 @@ static int probe_thermostat(struct i2c_client *client,
return -ENOMEM;
}
+ thermostat_create_files();
+
return 0;
}
@@ -566,7 +572,6 @@ thermostat_init(void)
struct device_node* np;
const u32 *prop;
int i = 0, offset = 0;
- int err;
np = of_find_node_by_name(NULL, "fan");
if (!np)
@@ -633,6 +638,17 @@ thermostat_init(void)
return -ENODEV;
}
+#ifndef CONFIG_I2C_POWERMAC
+ request_module("i2c-powermac");
+#endif
+
+ return i2c_add_driver(&thermostat_driver);
+}
+
+static void thermostat_create_files(void)
+{
+ int err;
+
err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature);
err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature);
err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit);
@@ -647,16 +663,9 @@ thermostat_init(void)
if (err)
printk(KERN_WARNING
"Failed to create tempertaure attribute file(s).\n");
-
-#ifndef CONFIG_I2C_POWERMAC
- request_module("i2c-powermac");
-#endif
-
- return i2c_add_driver(&thermostat_driver);
}
-static void __exit
-thermostat_exit(void)
+static void thermostat_remove_files(void)
{
if (of_dev) {
device_remove_file(&of_dev->dev, &dev_attr_sensor1_temperature);
@@ -673,9 +682,14 @@ thermostat_exit(void)
device_remove_file(&of_dev->dev,
&dev_attr_sensor2_fan_speed);
- of_device_unregister(of_dev);
}
+}
+
+static void __exit
+thermostat_exit(void)
+{
i2c_del_driver(&thermostat_driver);
+ of_device_unregister(of_dev);
}
module_init(thermostat_init);
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 6dd486d2977..aa57cfd1e3f 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -453,8 +453,7 @@ static int mhz_mfc_config(struct pcmcia_device *link)
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
- link->irq.Attributes =
- IRQ_TYPE_DYNAMIC_SHARING;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->io.IOAddrLines = 16;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts2 = 8;
@@ -652,8 +651,7 @@ static int osi_config(struct pcmcia_device *link)
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
- link->irq.Attributes =
- IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
+ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
link->io.NumPorts1 = 64;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts2 = 8;
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 1e01578a0a7..0a6601c7680 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -84,7 +84,7 @@ config YENTA
tristate "CardBus yenta-compatible bridge support"
depends on PCI
select CARDBUS if !EMBEDDED
- select PCCARD_NONSTATIC
+ select PCCARD_NONSTATIC if PCMCIA != n
---help---
This option enables support for CardBus host bridges. Virtually
all modern PCMCIA bridges are CardBus compatible. A "bridge" is
@@ -161,9 +161,8 @@ config TCIC
config PCMCIA_M8XX
tristate "MPC8xx PCMCIA support"
- depends on PCMCIA && PPC && 8xx
- select PCCARD_IODYN
- select PCCARD_NONSTATIC
+ depends on PCCARD && PPC && 8xx
+ select PCCARD_IODYN if PCMCIA != n
help
Say Y here to include support for PowerPC 8xx series PCMCIA
controller.
@@ -259,14 +258,12 @@ config PCMCIA_PROBE
config M32R_PCC
bool "M32R PCMCIA I/F"
depends on M32R && CHIP_M32700 && PCMCIA
- select PCCARD_NONSTATIC
help
Say Y here to use the M32R PCMCIA controller.
config M32R_CFC
bool "M32R CF I/F Controller"
depends on M32R && (PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_MAPPI3 || PLAT_OPSPUT)
- select PCCARD_NONSTATIC
help
Say Y here to use the M32R CompactFlash controller.
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 21ee96448b1..381b031d9d7 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -2,11 +2,11 @@
# Makefile for the kernel pcmcia subsystem (c/o David Hinds)
#
-pcmcia_core-y += cs.o cistpl.o rsrc_mgr.o socket_sysfs.o
+pcmcia_core-y += cs.o rsrc_mgr.o socket_sysfs.o
pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
obj-$(CONFIG_PCCARD) += pcmcia_core.o
-pcmcia-y += ds.o pcmcia_resource.o
+pcmcia-y += ds.o pcmcia_resource.o cistpl.o
pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o
obj-$(CONFIG_PCMCIA) += pcmcia.o
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index e1dccedc596..5d228071ec6 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -52,8 +52,6 @@ struct at91_cf_socket {
unsigned long phys_baseaddr;
};
-#define SZ_2K (2 * SZ_1K)
-
static inline int at91_cf_present(struct at91_cf_socket *cf)
{
return !gpio_get_value(cf->board->det_pin);
diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c
index 300b368605c..2482ce7ac6d 100644
--- a/drivers/pcmcia/bfin_cf_pcmcia.c
+++ b/drivers/pcmcia/bfin_cf_pcmcia.c
@@ -205,7 +205,7 @@ static int __devinit bfin_cf_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "Blackfin CompactFlash/PCMCIA Socket Driver\n");
irq = platform_get_irq(pdev, 0);
- if (!irq)
+ if (irq <= 0)
return -EINVAL;
cd_pfx = platform_get_irq(pdev, 1); /*Card Detect GPIO PIN */
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index d99f846451a..ac0686efbf7 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -20,170 +20,12 @@
*/
-#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
+#include <linux/module.h>
#include <linux/pci.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <asm/irq.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
-#include "cs_internal.h"
-
-/*====================================================================*/
-
-/* Offsets in the Expansion ROM Image Header */
-#define ROM_SIGNATURE 0x0000 /* 2 bytes */
-#define ROM_DATA_PTR 0x0018 /* 2 bytes */
-
-/* Offsets in the CardBus PC Card Data Structure */
-#define PCDATA_SIGNATURE 0x0000 /* 4 bytes */
-#define PCDATA_VPD_PTR 0x0008 /* 2 bytes */
-#define PCDATA_LENGTH 0x000a /* 2 bytes */
-#define PCDATA_REVISION 0x000c
-#define PCDATA_IMAGE_SZ 0x0010 /* 2 bytes */
-#define PCDATA_ROM_LEVEL 0x0012 /* 2 bytes */
-#define PCDATA_CODE_TYPE 0x0014
-#define PCDATA_INDICATOR 0x0015
-
-/*=====================================================================
-
- Expansion ROM's have a special layout, and pointers specify an
- image number and an offset within that image. xlate_rom_addr()
- converts an image/offset address to an absolute offset from the
- ROM's base address.
-
-=====================================================================*/
-
-static u_int xlate_rom_addr(void __iomem *b, u_int addr)
-{
- u_int img = 0, ofs = 0, sz;
- u_short data;
- while ((readb(b) == 0x55) && (readb(b + 1) == 0xaa)) {
- if (img == (addr >> 28))
- return (addr & 0x0fffffff) + ofs;
- data = readb(b + ROM_DATA_PTR) + (readb(b + ROM_DATA_PTR + 1) << 8);
- sz = 512 * (readb(b + data + PCDATA_IMAGE_SZ) +
- (readb(b + data + PCDATA_IMAGE_SZ + 1) << 8));
- if ((sz == 0) || (readb(b + data + PCDATA_INDICATOR) & 0x80))
- break;
- b += sz;
- ofs += sz;
- img++;
- }
- return 0;
-}
-
-/*=====================================================================
-
- These are similar to setup_cis_mem and release_cis_mem for 16-bit
- cards. The "result" that is used externally is the cb_cis_virt
- pointer in the struct pcmcia_socket structure.
-
-=====================================================================*/
-
-static void cb_release_cis_mem(struct pcmcia_socket *s)
-{
- if (s->cb_cis_virt) {
- dev_dbg(&s->dev, "cb_release_cis_mem()\n");
- iounmap(s->cb_cis_virt);
- s->cb_cis_virt = NULL;
- s->cb_cis_res = NULL;
- }
-}
-
-static int cb_setup_cis_mem(struct pcmcia_socket *s, struct resource *res)
-{
- unsigned int start, size;
-
- if (res == s->cb_cis_res)
- return 0;
-
- if (s->cb_cis_res)
- cb_release_cis_mem(s);
-
- start = res->start;
- size = res->end - start + 1;
- s->cb_cis_virt = ioremap(start, size);
-
- if (!s->cb_cis_virt)
- return -1;
-
- s->cb_cis_res = res;
-
- return 0;
-}
-
-/*=====================================================================
-
- This is used by the CIS processing code to read CIS information
- from a CardBus device.
-
-=====================================================================*/
-
-int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len,
- void *ptr)
-{
- struct pci_dev *dev;
- struct resource *res;
-
- dev_dbg(&s->dev, "read_cb_mem(%d, %#x, %u)\n", space, addr, len);
- dev = pci_get_slot(s->cb_dev->subordinate, 0);
- if (!dev)
- goto fail;
-
- /* Config space? */
- if (space == 0) {
- if (addr + len > 0x100)
- goto failput;
- for (; len; addr++, ptr++, len--)
- pci_read_config_byte(dev, addr, ptr);
- return 0;
- }
-
- res = dev->resource + space - 1;
-
- pci_dev_put(dev);
-
- if (!res->flags)
- goto fail;
-
- if (cb_setup_cis_mem(s, res) != 0)
- goto fail;
-
- if (space == 7) {
- addr = xlate_rom_addr(s->cb_cis_virt, addr);
- if (addr == 0)
- goto fail;
- }
-
- if (addr + len > res->end - res->start)
- goto fail;
-
- memcpy_fromio(ptr, s->cb_cis_virt + addr, len);
- return 0;
-
-failput:
- pci_dev_put(dev);
-fail:
- memset(ptr, 0xff, len);
- return -1;
-}
-
-/*=====================================================================
-
- cb_alloc() and cb_free() allocate and free the kernel data
- structures for a Cardbus device, and handle the lowest level PCI
- device setup issues.
-
-=====================================================================*/
static void cardbus_config_irq_and_cls(struct pci_bus *bus, int irq)
{
@@ -215,6 +57,13 @@ static void cardbus_config_irq_and_cls(struct pci_bus *bus, int irq)
}
}
+/**
+ * cb_alloc() - add CardBus device
+ * @s: the pcmcia_socket where the CardBus device is located
+ *
+ * cb_alloc() allocates the kernel data structures for a Cardbus device
+ * and handles the lowest level PCI device setup issues.
+ */
int __ref cb_alloc(struct pcmcia_socket *s)
{
struct pci_bus *bus = s->cb_dev->subordinate;
@@ -249,12 +98,16 @@ int __ref cb_alloc(struct pcmcia_socket *s)
return 0;
}
+/**
+ * cb_free() - remove CardBus device
+ * @s: the pcmcia_socket where the CardBus device was located
+ *
+ * cb_free() handles the lowest level PCI device cleanup.
+ */
void cb_free(struct pcmcia_socket *s)
{
struct pci_dev *bridge = s->cb_dev;
- cb_release_cis_mem(s);
-
if (bridge)
pci_remove_behind_bridge(bridge);
}
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 25b1cd219e3..2f3622dd4b6 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -64,6 +64,7 @@ module_param(cis_width, int, 0444);
void release_cis_mem(struct pcmcia_socket *s)
{
+ mutex_lock(&s->ops_mutex);
if (s->cis_mem.flags & MAP_ACTIVE) {
s->cis_mem.flags &= ~MAP_ACTIVE;
s->ops->set_mem_map(s, &s->cis_mem);
@@ -75,13 +76,15 @@ void release_cis_mem(struct pcmcia_socket *s)
iounmap(s->cis_virt);
s->cis_virt = NULL;
}
+ mutex_unlock(&s->ops_mutex);
}
-EXPORT_SYMBOL(release_cis_mem);
/*
* Map the card memory at "card_offset" into virtual space.
* If flags & MAP_ATTRIB, map the attribute space, otherwise
* map the memory space.
+ *
+ * Must be called with ops_mutex held.
*/
static void __iomem *
set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags)
@@ -140,6 +143,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+ mutex_lock(&s->ops_mutex);
if (attr & IS_INDIRECT) {
/* Indirect accesses use a bunch of special registers at fixed
locations in common memory */
@@ -151,7 +155,9 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0));
if (!sys) {
+ dev_dbg(&s->dev, "could not map memory\n");
memset(ptr, 0xff, len);
+ mutex_unlock(&s->ops_mutex);
return -1;
}
@@ -165,6 +171,9 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
} else {
u_int inc = 1, card_offset, flags;
+ if (addr > CISTPL_MAX_CIS_SIZE)
+ dev_dbg(&s->dev, "attempt to read CIS mem at addr %#x", addr);
+
flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
if (attr) {
flags |= MAP_ATTRIB;
@@ -176,7 +185,9 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
while (len) {
sys = set_cis_map(s, card_offset, flags);
if (!sys) {
+ dev_dbg(&s->dev, "could not map memory\n");
memset(ptr, 0xff, len);
+ mutex_unlock(&s->ops_mutex);
return -1;
}
end = sys + s->map_size;
@@ -190,12 +201,12 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
addr = 0;
}
}
+ mutex_unlock(&s->ops_mutex);
dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
*(u_char *)(ptr+0), *(u_char *)(ptr+1),
*(u_char *)(ptr+2), *(u_char *)(ptr+3));
return 0;
}
-EXPORT_SYMBOL(pcmcia_read_cis_mem);
void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
@@ -206,6 +217,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+ mutex_lock(&s->ops_mutex);
if (attr & IS_INDIRECT) {
/* Indirect accesses use a bunch of special registers at fixed
locations in common memory */
@@ -216,8 +228,11 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
}
sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0));
- if (!sys)
+ if (!sys) {
+ dev_dbg(&s->dev, "could not map memory\n");
+ mutex_unlock(&s->ops_mutex);
return; /* FIXME: Error */
+ }
writeb(flags, sys+CISREG_ICTRL0);
writeb(addr & 0xff, sys+CISREG_IADDR0);
@@ -239,8 +254,11 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
card_offset = addr & ~(s->map_size-1);
while (len) {
sys = set_cis_map(s, card_offset, flags);
- if (!sys)
+ if (!sys) {
+ dev_dbg(&s->dev, "could not map memory\n");
+ mutex_unlock(&s->ops_mutex);
return; /* FIXME: error */
+ }
end = sys + s->map_size;
sys = sys + (addr & (s->map_size-1));
@@ -253,8 +271,8 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
addr = 0;
}
}
+ mutex_unlock(&s->ops_mutex);
}
-EXPORT_SYMBOL(pcmcia_write_cis_mem);
/*======================================================================
@@ -265,32 +283,36 @@ EXPORT_SYMBOL(pcmcia_write_cis_mem);
======================================================================*/
-static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
- size_t len, void *ptr)
+static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
+ size_t len, void *ptr)
{
- struct cis_cache_entry *cis;
- int ret;
+ struct cis_cache_entry *cis;
+ int ret = 0;
- if (s->fake_cis) {
- if (s->fake_cis_len >= addr+len)
- memcpy(ptr, s->fake_cis+addr, len);
- else
- memset(ptr, 0xff, len);
- return;
- }
+ if (s->state & SOCKET_CARDBUS)
+ return -EINVAL;
- list_for_each_entry(cis, &s->cis_cache, node) {
- if (cis->addr == addr && cis->len == len && cis->attr == attr) {
- memcpy(ptr, cis->cache, len);
- return;
+ mutex_lock(&s->ops_mutex);
+ if (s->fake_cis) {
+ if (s->fake_cis_len >= addr+len)
+ memcpy(ptr, s->fake_cis+addr, len);
+ else {
+ memset(ptr, 0xff, len);
+ ret = -EINVAL;
+ }
+ mutex_unlock(&s->ops_mutex);
+ return ret;
}
- }
-#ifdef CONFIG_CARDBUS
- if (s->state & SOCKET_CARDBUS)
- ret = read_cb_mem(s, attr, addr, len, ptr);
- else
-#endif
+ list_for_each_entry(cis, &s->cis_cache, node) {
+ if (cis->addr == addr && cis->len == len && cis->attr == attr) {
+ memcpy(ptr, cis->cache, len);
+ mutex_unlock(&s->ops_mutex);
+ return 0;
+ }
+ }
+ mutex_unlock(&s->ops_mutex);
+
ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);
if (ret == 0) {
@@ -301,9 +323,12 @@ static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
cis->len = len;
cis->attr = attr;
memcpy(cis->cache, ptr, len);
+ mutex_lock(&s->ops_mutex);
list_add(&cis->node, &s->cis_cache);
+ mutex_unlock(&s->ops_mutex);
}
}
+ return ret;
}
static void
@@ -311,32 +336,35 @@ remove_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, u_int len)
{
struct cis_cache_entry *cis;
+ mutex_lock(&s->ops_mutex);
list_for_each_entry(cis, &s->cis_cache, node)
if (cis->addr == addr && cis->len == len && cis->attr == attr) {
list_del(&cis->node);
kfree(cis);
break;
}
+ mutex_unlock(&s->ops_mutex);
}
+/**
+ * destroy_cis_cache() - destroy the CIS cache
+ * @s: pcmcia_socket for which CIS cache shall be destroyed
+ *
+ * This destroys the CIS cache but keeps any fake CIS alive. Must be
+ * called with ops_mutex held.
+ */
+
void destroy_cis_cache(struct pcmcia_socket *s)
{
struct list_head *l, *n;
+ struct cis_cache_entry *cis;
list_for_each_safe(l, n, &s->cis_cache) {
- struct cis_cache_entry *cis = list_entry(l, struct cis_cache_entry, node);
-
+ cis = list_entry(l, struct cis_cache_entry, node);
list_del(&cis->node);
kfree(cis);
}
-
- /*
- * If there was a fake CIS, destroy that as well.
- */
- kfree(s->fake_cis);
- s->fake_cis = NULL;
}
-EXPORT_SYMBOL(destroy_cis_cache);
/*======================================================================
@@ -349,6 +377,10 @@ int verify_cis_cache(struct pcmcia_socket *s)
{
struct cis_cache_entry *cis;
char *buf;
+ int ret;
+
+ if (s->state & SOCKET_CARDBUS)
+ return -EINVAL;
buf = kmalloc(256, GFP_KERNEL);
if (buf == NULL) {
@@ -361,14 +393,9 @@ int verify_cis_cache(struct pcmcia_socket *s)
if (len > 256)
len = 256;
-#ifdef CONFIG_CARDBUS
- if (s->state & SOCKET_CARDBUS)
- read_cb_mem(s, cis->attr, cis->addr, len, buf);
- else
-#endif
- pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
- if (memcmp(buf, cis->cache, len) != 0) {
+ ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
+ if (ret || memcmp(buf, cis->cache, len) != 0) {
kfree(buf);
return -1;
}
@@ -391,17 +418,20 @@ int pcmcia_replace_cis(struct pcmcia_socket *s,
dev_printk(KERN_WARNING, &s->dev, "replacement CIS too big\n");
return -EINVAL;
}
+ mutex_lock(&s->ops_mutex);
kfree(s->fake_cis);
s->fake_cis = kmalloc(len, GFP_KERNEL);
if (s->fake_cis == NULL) {
dev_printk(KERN_WARNING, &s->dev, "no memory to replace CIS\n");
+ mutex_unlock(&s->ops_mutex);
return -ENOMEM;
}
s->fake_cis_len = len;
memcpy(s->fake_cis, data, len);
+ dev_info(&s->dev, "Using replacement CIS\n");
+ mutex_unlock(&s->ops_mutex);
return 0;
}
-EXPORT_SYMBOL(pcmcia_replace_cis);
/*======================================================================
@@ -425,25 +455,16 @@ int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple
{
if (!s)
return -EINVAL;
- if (!(s->state & SOCKET_PRESENT))
+
+ if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
return -ENODEV;
tuple->TupleLink = tuple->Flags = 0;
-#ifdef CONFIG_CARDBUS
- if (s->state & SOCKET_CARDBUS) {
- struct pci_dev *dev = s->cb_dev;
- u_int ptr;
- pci_bus_read_config_dword(dev->subordinate, 0, PCI_CARDBUS_CIS, &ptr);
- tuple->CISOffset = ptr & ~7;
- SPACE(tuple->Flags) = (ptr & 7);
- } else
-#endif
- {
- /* Assume presence of a LONGLINK_C to address 0 */
- tuple->CISOffset = tuple->LinkOffset = 0;
- SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1;
- }
- if (!(s->state & SOCKET_CARDBUS) && (s->functions > 1) &&
- !(tuple->Attributes & TUPLE_RETURN_COMMON)) {
+
+ /* Assume presence of a LONGLINK_C to address 0 */
+ tuple->CISOffset = tuple->LinkOffset = 0;
+ SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1;
+
+ if ((s->functions > 1) && !(tuple->Attributes & TUPLE_RETURN_COMMON)) {
cisdata_t req = tuple->DesiredTuple;
tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
if (pccard_get_next_tuple(s, function, tuple) == 0) {
@@ -456,17 +477,19 @@ int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple
}
return pccard_get_next_tuple(s, function, tuple);
}
-EXPORT_SYMBOL(pccard_get_first_tuple);
static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
{
u_char link[5];
u_int ofs;
+ int ret;
if (MFC_FN(tuple->Flags)) {
/* Get indirect link from the MFC tuple */
- read_cis_cache(s, LINK_SPACE(tuple->Flags),
+ ret = read_cis_cache(s, LINK_SPACE(tuple->Flags),
tuple->LinkOffset, 5, link);
+ if (ret)
+ return -1;
ofs = get_unaligned_le32(link + 1);
SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
/* Move to the next indirect link */
@@ -479,10 +502,12 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
} else {
return -1;
}
- if (!(s->state & SOCKET_CARDBUS) && SPACE(tuple->Flags)) {
+ if (SPACE(tuple->Flags)) {
/* This is ugly, but a common CIS error is to code the long
link offset incorrectly, so we check the right spot... */
- read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
+ ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
+ if (ret)
+ return -1;
if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
(strncmp(link+2, "CIS", 3) == 0))
return ofs;
@@ -490,7 +515,9 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
/* Then, we try the wrong spot... */
ofs = ofs >> 1;
}
- read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
+ ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
+ if (ret)
+ return -1;
if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
(strncmp(link+2, "CIS", 3) == 0))
return ofs;
@@ -502,10 +529,11 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
{
u_char link[2], tmp;
int ofs, i, attr;
+ int ret;
if (!s)
return -EINVAL;
- if (!(s->state & SOCKET_PRESENT))
+ if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
return -ENODEV;
link[1] = tuple->TupleLink;
@@ -516,7 +544,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
if (link[1] == 0xff) {
link[0] = CISTPL_END;
} else {
- read_cis_cache(s, attr, ofs, 2, link);
+ ret = read_cis_cache(s, attr, ofs, 2, link);
+ if (ret)
+ return -1;
if (link[0] == CISTPL_NULL) {
ofs++; continue;
}
@@ -528,7 +558,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
if (ofs < 0)
return -ENOSPC;
attr = SPACE(tuple->Flags);
- read_cis_cache(s, attr, ofs, 2, link);
+ ret = read_cis_cache(s, attr, ofs, 2, link);
+ if (ret)
+ return -1;
}
/* Is this a link tuple? Make a note of it */
@@ -542,12 +574,16 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
case CISTPL_LONGLINK_A:
HAS_LINK(tuple->Flags) = 1;
LINK_SPACE(tuple->Flags) = attr | IS_ATTR;
- read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset);
+ ret = read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset);
+ if (ret)
+ return -1;
break;
case CISTPL_LONGLINK_C:
HAS_LINK(tuple->Flags) = 1;
LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR;
- read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset);
+ ret = read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset);
+ if (ret)
+ return -1;
break;
case CISTPL_INDIRECT:
HAS_LINK(tuple->Flags) = 1;
@@ -559,7 +595,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
LINK_SPACE(tuple->Flags) = attr;
if (function == BIND_FN_ALL) {
/* Follow all the MFC links */
- read_cis_cache(s, attr, ofs+2, 1, &tmp);
+ ret = read_cis_cache(s, attr, ofs+2, 1, &tmp);
+ if (ret)
+ return -1;
MFC_FN(tuple->Flags) = tmp;
} else {
/* Follow exactly one of the links */
@@ -592,7 +630,6 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
tuple->CISOffset = ofs + 2;
return 0;
}
-EXPORT_SYMBOL(pccard_get_next_tuple);
/*====================================================================*/
@@ -601,6 +638,7 @@ EXPORT_SYMBOL(pccard_get_next_tuple);
int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
{
u_int len;
+ int ret;
if (!s)
return -EINVAL;
@@ -611,12 +649,13 @@ int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
tuple->TupleDataLen = tuple->TupleLink;
if (len == 0)
return 0;
- read_cis_cache(s, SPACE(tuple->Flags),
+ ret = read_cis_cache(s, SPACE(tuple->Flags),
tuple->CISOffset + tuple->TupleOffset,
_MIN(len, tuple->TupleDataMax), tuple->TupleData);
+ if (ret)
+ return -1;
return 0;
}
-EXPORT_SYMBOL(pccard_get_tuple_data);
/*======================================================================
@@ -1190,119 +1229,6 @@ static int parse_cftable_entry(tuple_t *tuple,
/*====================================================================*/
-#ifdef CONFIG_CARDBUS
-
-static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar)
-{
- u_char *p;
- if (tuple->TupleDataLen < 6)
- return -EINVAL;
- p = (u_char *)tuple->TupleData;
- bar->attr = *p;
- p += 2;
- bar->size = get_unaligned_le32(p);
- return 0;
-}
-
-static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
-{
- u_char *p;
-
- p = (u_char *)tuple->TupleData;
- if ((*p != 3) || (tuple->TupleDataLen < 6))
- return -EINVAL;
- config->last_idx = *(++p);
- p++;
- config->base = get_unaligned_le32(p);
- config->subtuples = tuple->TupleDataLen - 6;
- return 0;
-}
-
-static int parse_cftable_entry_cb(tuple_t *tuple,
- cistpl_cftable_entry_cb_t *entry)
-{
- u_char *p, *q, features;
-
- p = tuple->TupleData;
- q = p + tuple->TupleDataLen;
- entry->index = *p & 0x3f;
- entry->flags = 0;
- if (*p & 0x40)
- entry->flags |= CISTPL_CFTABLE_DEFAULT;
-
- /* Process optional features */
- if (++p == q)
- return -EINVAL;
- features = *p; p++;
-
- /* Power options */
- if ((features & 3) > 0) {
- p = parse_power(p, q, &entry->vcc);
- if (p == NULL)
- return -EINVAL;
- } else
- entry->vcc.present = 0;
- if ((features & 3) > 1) {
- p = parse_power(p, q, &entry->vpp1);
- if (p == NULL)
- return -EINVAL;
- } else
- entry->vpp1.present = 0;
- if ((features & 3) > 2) {
- p = parse_power(p, q, &entry->vpp2);
- if (p == NULL)
- return -EINVAL;
- } else
- entry->vpp2.present = 0;
-
- /* I/O window options */
- if (features & 0x08) {
- if (p == q)
- return -EINVAL;
- entry->io = *p; p++;
- } else
- entry->io = 0;
-
- /* Interrupt options */
- if (features & 0x10) {
- p = parse_irq(p, q, &entry->irq);
- if (p == NULL)
- return -EINVAL;
- } else
- entry->irq.IRQInfo1 = 0;
-
- if (features & 0x20) {
- if (p == q)
- return -EINVAL;
- entry->mem = *p; p++;
- } else
- entry->mem = 0;
-
- /* Misc features */
- if (features & 0x80) {
- if (p == q)
- return -EINVAL;
- entry->flags |= (*p << 8);
- if (*p & 0x80) {
- if (++p == q)
- return -EINVAL;
- entry->flags |= (*p << 16);
- }
- while (*p & 0x80)
- if (++p == q)
- return -EINVAL;
- p++;
- }
-
- entry->subtuples = q-p;
-
- return 0;
-}
-
-#endif
-
-/*====================================================================*/
-
static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo)
{
u_char *p, *q;
@@ -1404,17 +1330,6 @@ int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
case CISTPL_DEVICE_A:
ret = parse_device(tuple, &parse->device);
break;
-#ifdef CONFIG_CARDBUS
- case CISTPL_BAR:
- ret = parse_bar(tuple, &parse->bar);
- break;
- case CISTPL_CONFIG_CB:
- ret = parse_config_cb(tuple, &parse->config);
- break;
- case CISTPL_CFTABLE_ENTRY_CB:
- ret = parse_cftable_entry_cb(tuple, &parse->cftable_entry_cb);
- break;
-#endif
case CISTPL_CHECKSUM:
ret = parse_checksum(tuple, &parse->checksum);
break;
@@ -1513,7 +1428,6 @@ done:
kfree(buf);
return ret;
}
-EXPORT_SYMBOL(pccard_read_tuple);
/**
@@ -1573,84 +1487,238 @@ next_entry:
kfree(buf);
return ret;
}
-EXPORT_SYMBOL(pccard_loop_tuple);
-/*======================================================================
-
- This tries to determine if a card has a sensible CIS. It returns
- the number of tuples in the CIS, or 0 if the CIS looks bad. The
- checks include making sure several critical tuples are present and
- valid; seeing if the total number of tuples is reasonable; and
- looking for tuples that use reserved codes.
-
-======================================================================*/
-
+/**
+ * pccard_validate_cis() - check whether card has a sensible CIS
+ * @s: the struct pcmcia_socket we are to check
+ * @info: returns the number of tuples in the (valid) CIS, or 0
+ *
+ * This tries to determine if a card has a sensible CIS. In @info, it
+ * returns the number of tuples in the CIS, or 0 if the CIS looks bad. The
+ * checks include making sure several critical tuples are present and
+ * valid; seeing if the total number of tuples is reasonable; and
+ * looking for tuples that use reserved codes.
+ *
+ * The function returns 0 on success.
+ */
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
{
- tuple_t *tuple;
- cisparse_t *p;
- unsigned int count = 0;
- int ret, reserved, dev_ok = 0, ident_ok = 0;
+ tuple_t *tuple;
+ cisparse_t *p;
+ unsigned int count = 0;
+ int ret, reserved, dev_ok = 0, ident_ok = 0;
- if (!s)
- return -EINVAL;
+ if (!s)
+ return -EINVAL;
- tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
- if (tuple == NULL) {
- dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
- return -ENOMEM;
- }
- p = kmalloc(sizeof(*p), GFP_KERNEL);
- if (p == NULL) {
- kfree(tuple);
- dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
- return -ENOMEM;
- }
+ /* We do not want to validate the CIS cache... */
+ mutex_lock(&s->ops_mutex);
+ destroy_cis_cache(s);
+ mutex_unlock(&s->ops_mutex);
- count = reserved = 0;
- tuple->DesiredTuple = RETURN_FIRST_TUPLE;
- tuple->Attributes = TUPLE_RETURN_COMMON;
- ret = pccard_get_first_tuple(s, BIND_FN_ALL, tuple);
- if (ret != 0)
- goto done;
-
- /* First tuple should be DEVICE; we should really have either that
- or a CFTABLE_ENTRY of some sort */
- if ((tuple->TupleCode == CISTPL_DEVICE) ||
- (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY, p) == 0) ||
- (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY_CB, p) == 0))
- dev_ok++;
-
- /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
- tuple, for card identification. Certain old D-Link and Linksys
- cards have only a broken VERS_2 tuple; hence the bogus test. */
- if ((pccard_read_tuple(s, BIND_FN_ALL, CISTPL_MANFID, p) == 0) ||
- (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_1, p) == 0) ||
- (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC))
- ident_ok++;
-
- if (!dev_ok && !ident_ok)
- goto done;
-
- for (count = 1; count < MAX_TUPLES; count++) {
- ret = pccard_get_next_tuple(s, BIND_FN_ALL, tuple);
+ tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
+ if (tuple == NULL) {
+ dev_warn(&s->dev, "no memory to validate CIS\n");
+ return -ENOMEM;
+ }
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (p == NULL) {
+ kfree(tuple);
+ dev_warn(&s->dev, "no memory to validate CIS\n");
+ return -ENOMEM;
+ }
+
+ count = reserved = 0;
+ tuple->DesiredTuple = RETURN_FIRST_TUPLE;
+ tuple->Attributes = TUPLE_RETURN_COMMON;
+ ret = pccard_get_first_tuple(s, BIND_FN_ALL, tuple);
if (ret != 0)
- break;
- if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
- ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
- ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
- reserved++;
- }
- if ((count == MAX_TUPLES) || (reserved > 5) ||
- ((!dev_ok || !ident_ok) && (count > 10)))
- count = 0;
+ goto done;
+
+ /* First tuple should be DEVICE; we should really have either that
+ or a CFTABLE_ENTRY of some sort */
+ if ((tuple->TupleCode == CISTPL_DEVICE) ||
+ (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY, p)) ||
+ (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY_CB, p)))
+ dev_ok++;
+
+ /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
+ tuple, for card identification. Certain old D-Link and Linksys
+ cards have only a broken VERS_2 tuple; hence the bogus test. */
+ if ((pccard_read_tuple(s, BIND_FN_ALL, CISTPL_MANFID, p) == 0) ||
+ (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_1, p) == 0) ||
+ (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC))
+ ident_ok++;
+
+ if (!dev_ok && !ident_ok)
+ goto done;
+
+ for (count = 1; count < MAX_TUPLES; count++) {
+ ret = pccard_get_next_tuple(s, BIND_FN_ALL, tuple);
+ if (ret != 0)
+ break;
+ if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
+ ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
+ ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
+ reserved++;
+ }
+ if ((count == MAX_TUPLES) || (reserved > 5) ||
+ ((!dev_ok || !ident_ok) && (count > 10)))
+ count = 0;
+
+ ret = 0;
done:
- if (info)
- *info = count;
- kfree(tuple);
- kfree(p);
- return 0;
+ /* invalidate CIS cache on failure */
+ if (!dev_ok || !ident_ok || !count) {
+ mutex_lock(&s->ops_mutex);
+ destroy_cis_cache(s);
+ mutex_unlock(&s->ops_mutex);
+ ret = -EIO;
+ }
+
+ if (info)
+ *info = count;
+ kfree(tuple);
+ kfree(p);
+ return ret;
}
-EXPORT_SYMBOL(pccard_validate_cis);
+
+
+#define to_socket(_dev) container_of(_dev, struct pcmcia_socket, dev)
+
+static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf,
+ loff_t off, size_t count)
+{
+ tuple_t tuple;
+ int status, i;
+ loff_t pointer = 0;
+ ssize_t ret = 0;
+ u_char *tuplebuffer;
+ u_char *tempbuffer;
+
+ tuplebuffer = kmalloc(sizeof(u_char) * 256, GFP_KERNEL);
+ if (!tuplebuffer)
+ return -ENOMEM;
+
+ tempbuffer = kmalloc(sizeof(u_char) * 258, GFP_KERNEL);
+ if (!tempbuffer) {
+ ret = -ENOMEM;
+ goto free_tuple;
+ }
+
+ memset(&tuple, 0, sizeof(tuple_t));
+
+ tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON;
+ tuple.DesiredTuple = RETURN_FIRST_TUPLE;
+ tuple.TupleOffset = 0;
+
+ status = pccard_get_first_tuple(s, BIND_FN_ALL, &tuple);
+ while (!status) {
+ tuple.TupleData = tuplebuffer;
+ tuple.TupleDataMax = 255;
+ memset(tuplebuffer, 0, sizeof(u_char) * 255);
+
+ status = pccard_get_tuple_data(s, &tuple);
+ if (status)
+ break;
+
+ if (off < (pointer + 2 + tuple.TupleDataLen)) {
+ tempbuffer[0] = tuple.TupleCode & 0xff;
+ tempbuffer[1] = tuple.TupleLink & 0xff;
+ for (i = 0; i < tuple.TupleDataLen; i++)
+ tempbuffer[i + 2] = tuplebuffer[i] & 0xff;
+
+ for (i = 0; i < (2 + tuple.TupleDataLen); i++) {
+ if (((i + pointer) >= off) &&
+ (i + pointer) < (off + count)) {
+ buf[ret] = tempbuffer[i];
+ ret++;
+ }
+ }
+ }
+
+ pointer += 2 + tuple.TupleDataLen;
+
+ if (pointer >= (off + count))
+ break;
+
+ if (tuple.TupleCode == CISTPL_END)
+ break;
+ status = pccard_get_next_tuple(s, BIND_FN_ALL, &tuple);
+ }
+
+ kfree(tempbuffer);
+ free_tuple:
+ kfree(tuplebuffer);
+
+ return ret;
+}
+
+
+static ssize_t pccard_show_cis(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ unsigned int size = 0x200;
+
+ if (off >= size)
+ count = 0;
+ else {
+ struct pcmcia_socket *s;
+ unsigned int chains;
+
+ if (off + count > size)
+ count = size - off;
+
+ s = to_socket(container_of(kobj, struct device, kobj));
+
+ if (!(s->state & SOCKET_PRESENT))
+ return -ENODEV;
+ if (pccard_validate_cis(s, &chains))
+ return -EIO;
+ if (!chains)
+ return -ENODATA;
+
+ count = pccard_extract_cis(s, buf, off, count);
+ }
+
+ return count;
+}
+
+
+static ssize_t pccard_store_cis(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct pcmcia_socket *s;
+ int error;
+
+ s = to_socket(container_of(kobj, struct device, kobj));
+
+ if (off)
+ return -EINVAL;
+
+ if (count >= CISTPL_MAX_CIS_SIZE)
+ return -EINVAL;
+
+ if (!(s->state & SOCKET_PRESENT))
+ return -ENODEV;
+
+ error = pcmcia_replace_cis(s, buf, count);
+ if (error)
+ return -EIO;
+
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);
+
+ return count;
+}
+
+
+struct bin_attribute pccard_cis_attr = {
+ .attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR },
+ .size = 0x200,
+ .read = pccard_show_cis,
+ .write = pccard_store_cis,
+};
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 6d6f82b38a6..e679e708db6 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -140,19 +140,13 @@ struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt)
struct device *dev = get_device(&skt->dev);
if (!dev)
return NULL;
- skt = dev_get_drvdata(dev);
- if (!try_module_get(skt->owner)) {
- put_device(&skt->dev);
- return NULL;
- }
- return skt;
+ return dev_get_drvdata(dev);
}
EXPORT_SYMBOL(pcmcia_get_socket);
void pcmcia_put_socket(struct pcmcia_socket *skt)
{
- module_put(skt->owner);
put_device(&skt->dev);
}
EXPORT_SYMBOL(pcmcia_put_socket);
@@ -181,8 +175,6 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
dev_dbg(&socket->dev, "pcmcia_register_socket(0x%p)\n", socket->ops);
- spin_lock_init(&socket->lock);
-
/* try to obtain a socket number [yes, it gets ugly if we
* register more than 2^sizeof(unsigned int) pcmcia
* sockets... but the socket number is deprecated
@@ -228,10 +220,13 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
init_completion(&socket->socket_released);
init_completion(&socket->thread_done);
mutex_init(&socket->skt_mutex);
+ mutex_init(&socket->ops_mutex);
spin_lock_init(&socket->thread_lock);
if (socket->resource_ops->init) {
+ mutex_lock(&socket->ops_mutex);
ret = socket->resource_ops->init(socket);
+ mutex_unlock(&socket->ops_mutex);
if (ret)
goto err;
}
@@ -283,15 +278,17 @@ void pcmcia_unregister_socket(struct pcmcia_socket *socket)
if (socket->thread)
kthread_stop(socket->thread);
- release_cis_mem(socket);
-
/* remove from our own list */
down_write(&pcmcia_socket_list_rwsem);
list_del(&socket->socket_list);
up_write(&pcmcia_socket_list_rwsem);
/* wait for sysfs to drop all references */
- release_resource_db(socket);
+ if (socket->resource_ops->exit) {
+ mutex_lock(&socket->ops_mutex);
+ socket->resource_ops->exit(socket);
+ mutex_unlock(&socket->ops_mutex);
+ }
wait_for_completion(&socket->socket_released);
} /* pcmcia_unregister_socket */
EXPORT_SYMBOL(pcmcia_unregister_socket);
@@ -328,7 +325,7 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority)
{
int ret;
- if (s->state & SOCKET_CARDBUS)
+ if ((s->state & SOCKET_CARDBUS) && (event != CS_EVENT_CARD_REMOVAL))
return 0;
dev_dbg(&s->dev, "send_event(event %d, pri %d, callback 0x%p)\n",
@@ -346,13 +343,6 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority)
return ret;
}
-static void socket_remove_drivers(struct pcmcia_socket *skt)
-{
- dev_dbg(&skt->dev, "remove_drivers\n");
-
- send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
-}
-
static int socket_reset(struct pcmcia_socket *skt)
{
int status, i;
@@ -395,7 +385,9 @@ static void socket_shutdown(struct pcmcia_socket *s)
dev_dbg(&s->dev, "shutdown\n");
- socket_remove_drivers(s);
+ send_event(s, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
+
+ mutex_lock(&s->ops_mutex);
s->state &= SOCKET_INUSE | SOCKET_PRESENT;
msleep(shutdown_delay * 10);
s->state &= SOCKET_INUSE;
@@ -406,11 +398,21 @@ static void socket_shutdown(struct pcmcia_socket *s)
s->ops->set_socket(s, &s->socket);
s->irq.AssignedIRQ = s->irq.Config = 0;
s->lock_count = 0;
- destroy_cis_cache(s);
+ kfree(s->fake_cis);
+ s->fake_cis = NULL;
+ s->functions = 0;
+
+ /* From here on we can be sure that only we (that is, the
+ * pccardd thread) accesses this socket, and all (16-bit)
+ * PCMCIA interactions are gone. Therefore, release
+ * ops_mutex so that we don't get a sysfs-related lockdep
+ * warning.
+ */
+ mutex_unlock(&s->ops_mutex);
+
#ifdef CONFIG_CARDBUS
cb_free(s);
#endif
- s->functions = 0;
/* give socket some time to power down */
msleep(100);
@@ -421,7 +423,7 @@ static void socket_shutdown(struct pcmcia_socket *s)
"*** DANGER *** unable to remove socket power\n");
}
- cs_socket_put(s);
+ s->state &= ~SOCKET_INUSE;
}
static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
@@ -460,7 +462,8 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
return -EINVAL;
}
skt->state |= SOCKET_CARDBUS;
- }
+ } else
+ skt->state &= ~SOCKET_CARDBUS;
/*
* Decode the card voltage requirements, and apply power to the card.
@@ -509,8 +512,12 @@ static int socket_insert(struct pcmcia_socket *skt)
dev_dbg(&skt->dev, "insert\n");
- if (!cs_socket_get(skt))
- return -ENODEV;
+ mutex_lock(&skt->ops_mutex);
+ if (skt->state & SOCKET_INUSE) {
+ mutex_unlock(&skt->ops_mutex);
+ return -EINVAL;
+ }
+ skt->state |= SOCKET_INUSE;
ret = socket_setup(skt, setup_delay);
if (ret == 0) {
@@ -528,9 +535,11 @@ static int socket_insert(struct pcmcia_socket *skt)
}
#endif
dev_dbg(&skt->dev, "insert done\n");
+ mutex_unlock(&skt->ops_mutex);
send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
} else {
+ mutex_unlock(&skt->ops_mutex);
socket_shutdown(skt);
}
@@ -542,58 +551,66 @@ static int socket_suspend(struct pcmcia_socket *skt)
if (skt->state & SOCKET_SUSPEND)
return -EBUSY;
+ mutex_lock(&skt->ops_mutex);
+ skt->suspended_state = skt->state;
+
send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
skt->socket = dead_socket;
skt->ops->set_socket(skt, &skt->socket);
if (skt->ops->suspend)
skt->ops->suspend(skt);
skt->state |= SOCKET_SUSPEND;
-
+ mutex_unlock(&skt->ops_mutex);
return 0;
}
static int socket_early_resume(struct pcmcia_socket *skt)
{
+ mutex_lock(&skt->ops_mutex);
skt->socket = dead_socket;
skt->ops->init(skt);
skt->ops->set_socket(skt, &skt->socket);
if (skt->state & SOCKET_PRESENT)
skt->resume_status = socket_setup(skt, resume_delay);
+ mutex_unlock(&skt->ops_mutex);
return 0;
}
static int socket_late_resume(struct pcmcia_socket *skt)
{
- if (!(skt->state & SOCKET_PRESENT)) {
- skt->state &= ~SOCKET_SUSPEND;
+ mutex_lock(&skt->ops_mutex);
+ skt->state &= ~SOCKET_SUSPEND;
+ mutex_unlock(&skt->ops_mutex);
+
+ if (!(skt->state & SOCKET_PRESENT))
return socket_insert(skt);
+
+ if (skt->resume_status) {
+ socket_shutdown(skt);
+ return 0;
}
- if (skt->resume_status == 0) {
- /*
- * FIXME: need a better check here for cardbus cards.
- */
- if (verify_cis_cache(skt) != 0) {
- dev_dbg(&skt->dev, "cis mismatch - different card\n");
- socket_remove_drivers(skt);
- destroy_cis_cache(skt);
- /*
- * Workaround: give DS time to schedule removal.
- * Remove me once the 100ms delay is eliminated
- * in ds.c
- */
- msleep(200);
- send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
- } else {
- dev_dbg(&skt->dev, "cis matches cache\n");
- send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
- }
- } else {
+ if (skt->suspended_state != skt->state) {
+ dev_dbg(&skt->dev,
+ "suspend state 0x%x != resume state 0x%x\n",
+ skt->suspended_state, skt->state);
+
socket_shutdown(skt);
+ return socket_insert(skt);
}
- skt->state &= ~SOCKET_SUSPEND;
+#ifdef CONFIG_CARDBUS
+ if (skt->state & SOCKET_CARDBUS) {
+ /* We can't be sure the CardBus card is the same
+ * as the one previously inserted. Therefore, remove
+ * and re-add... */
+ cb_free(skt);
+ cb_alloc(skt);
+ return 0;
+ }
+#endif
+ send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
return 0;
}
@@ -672,20 +689,26 @@ static int pccardd(void *__skt)
complete(&skt->thread_done);
+ /* wait for userspace to catch up */
+ msleep(250);
+
set_freezable();
for (;;) {
unsigned long flags;
unsigned int events;
+ unsigned int sysfs_events;
set_current_state(TASK_INTERRUPTIBLE);
spin_lock_irqsave(&skt->thread_lock, flags);
events = skt->thread_events;
skt->thread_events = 0;
+ sysfs_events = skt->sysfs_events;
+ skt->sysfs_events = 0;
spin_unlock_irqrestore(&skt->thread_lock, flags);
+ mutex_lock(&skt->skt_mutex);
if (events) {
- mutex_lock(&skt->skt_mutex);
if (events & SS_DETECT)
socket_detect_change(skt);
if (events & SS_BATDEAD)
@@ -694,10 +717,39 @@ static int pccardd(void *__skt)
send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW);
if (events & SS_READY)
send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW);
- mutex_unlock(&skt->skt_mutex);
- continue;
}
+ if (sysfs_events) {
+ if (sysfs_events & PCMCIA_UEVENT_EJECT)
+ socket_remove(skt);
+ if (sysfs_events & PCMCIA_UEVENT_INSERT)
+ socket_insert(skt);
+ if ((sysfs_events & PCMCIA_UEVENT_RESUME) &&
+ !(skt->state & SOCKET_CARDBUS)) {
+ ret = socket_resume(skt);
+ if (!ret && skt->callback)
+ skt->callback->resume(skt);
+ }
+ if ((sysfs_events & PCMCIA_UEVENT_SUSPEND) &&
+ !(skt->state & SOCKET_CARDBUS)) {
+ if (skt->callback)
+ ret = skt->callback->suspend(skt);
+ else
+ ret = 0;
+ if (!ret)
+ socket_suspend(skt);
+ }
+ if ((sysfs_events & PCMCIA_UEVENT_REQUERY) &&
+ !(skt->state & SOCKET_CARDBUS)) {
+ if (!ret && skt->callback)
+ skt->callback->requery(skt);
+ }
+ }
+ mutex_unlock(&skt->skt_mutex);
+
+ if (events || sysfs_events)
+ continue;
+
if (kthread_should_stop())
break;
@@ -707,6 +759,13 @@ static int pccardd(void *__skt)
/* make sure we are running before we exit */
set_current_state(TASK_RUNNING);
+ /* shut down socket, if a device is still present */
+ if (skt->state & SOCKET_PRESENT) {
+ mutex_lock(&skt->skt_mutex);
+ socket_remove(skt);
+ mutex_unlock(&skt->skt_mutex);
+ }
+
/* remove from the device core */
pccard_sysfs_remove_socket(&skt->dev);
device_unregister(&skt->dev);
@@ -732,6 +791,31 @@ void pcmcia_parse_events(struct pcmcia_socket *s, u_int events)
} /* pcmcia_parse_events */
EXPORT_SYMBOL(pcmcia_parse_events);
+/**
+ * pcmcia_parse_uevents() - tell pccardd to issue manual commands
+ * @s: the PCMCIA socket we wan't to command
+ * @events: events to pass to pccardd
+ *
+ * userspace-issued insert, eject, suspend and resume commands must be
+ * handled by pccardd to avoid any sysfs-related deadlocks. Valid events
+ * are PCMCIA_UEVENT_EJECT (for eject), PCMCIA_UEVENT__INSERT (for insert),
+ * PCMCIA_UEVENT_RESUME (for resume), PCMCIA_UEVENT_SUSPEND (for suspend)
+ * and PCMCIA_UEVENT_REQUERY (for re-querying the PCMCIA card).
+ */
+void pcmcia_parse_uevents(struct pcmcia_socket *s, u_int events)
+{
+ unsigned long flags;
+ dev_dbg(&s->dev, "parse_uevents: events %08x\n", events);
+ if (s->thread) {
+ spin_lock_irqsave(&s->thread_lock, flags);
+ s->sysfs_events |= events;
+ spin_unlock_irqrestore(&s->thread_lock, flags);
+
+ wake_up_process(s->thread);
+ }
+}
+EXPORT_SYMBOL(pcmcia_parse_uevents);
+
/* register pcmcia_callback */
int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
@@ -796,7 +880,10 @@ int pcmcia_reset_card(struct pcmcia_socket *skt)
send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
if (skt->callback)
skt->callback->suspend(skt);
- if (socket_reset(skt) == 0) {
+ mutex_lock(&skt->ops_mutex);
+ ret = socket_reset(skt);
+ mutex_unlock(&skt->ops_mutex);
+ if (ret == 0) {
send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
if (skt->callback)
skt->callback->resume(skt);
@@ -812,121 +899,6 @@ int pcmcia_reset_card(struct pcmcia_socket *skt)
EXPORT_SYMBOL(pcmcia_reset_card);
-/* These shut down or wake up a socket. They are sort of user
- * initiated versions of the APM suspend and resume actions.
- */
-int pcmcia_suspend_card(struct pcmcia_socket *skt)
-{
- int ret;
-
- dev_dbg(&skt->dev, "suspending socket\n");
-
- mutex_lock(&skt->skt_mutex);
- do {
- if (!(skt->state & SOCKET_PRESENT)) {
- ret = -ENODEV;
- break;
- }
- if (skt->state & SOCKET_CARDBUS) {
- ret = -EPERM;
- break;
- }
- if (skt->callback) {
- ret = skt->callback->suspend(skt);
- if (ret)
- break;
- }
- ret = socket_suspend(skt);
- } while (0);
- mutex_unlock(&skt->skt_mutex);
-
- return ret;
-} /* suspend_card */
-EXPORT_SYMBOL(pcmcia_suspend_card);
-
-
-int pcmcia_resume_card(struct pcmcia_socket *skt)
-{
- int ret;
-
- dev_dbg(&skt->dev, "waking up socket\n");
-
- mutex_lock(&skt->skt_mutex);
- do {
- if (!(skt->state & SOCKET_PRESENT)) {
- ret = -ENODEV;
- break;
- }
- if (skt->state & SOCKET_CARDBUS) {
- ret = -EPERM;
- break;
- }
- ret = socket_resume(skt);
- if (!ret && skt->callback)
- skt->callback->resume(skt);
- } while (0);
- mutex_unlock(&skt->skt_mutex);
-
- return ret;
-} /* resume_card */
-EXPORT_SYMBOL(pcmcia_resume_card);
-
-
-/* These handle user requests to eject or insert a card. */
-int pcmcia_eject_card(struct pcmcia_socket *skt)
-{
- int ret;
-
- dev_dbg(&skt->dev, "user eject request\n");
-
- mutex_lock(&skt->skt_mutex);
- do {
- if (!(skt->state & SOCKET_PRESENT)) {
- ret = -ENODEV;
- break;
- }
-
- ret = send_event(skt, CS_EVENT_EJECTION_REQUEST, CS_EVENT_PRI_LOW);
- if (ret != 0) {
- ret = -EINVAL;
- break;
- }
-
- socket_remove(skt);
- ret = 0;
- } while (0);
- mutex_unlock(&skt->skt_mutex);
-
- return ret;
-} /* eject_card */
-EXPORT_SYMBOL(pcmcia_eject_card);
-
-
-int pcmcia_insert_card(struct pcmcia_socket *skt)
-{
- int ret;
-
- dev_dbg(&skt->dev, "user insert request\n");
-
- mutex_lock(&skt->skt_mutex);
- do {
- if (skt->state & SOCKET_PRESENT) {
- ret = -EBUSY;
- break;
- }
- if (socket_insert(skt) == -ENODEV) {
- ret = -ENODEV;
- break;
- }
- ret = 0;
- } while (0);
- mutex_unlock(&skt->skt_mutex);
-
- return ret;
-} /* insert_card */
-EXPORT_SYMBOL(pcmcia_insert_card);
-
-
static int pcmcia_socket_uevent(struct device *dev,
struct kobj_uevent_env *env)
{
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 3bc02d53a3a..f95864c2191 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -87,37 +87,11 @@ struct pccard_resource_ops {
#define SOCKET_CARDBUS 0x8000
#define SOCKET_CARDBUS_CONFIG 0x10000
-static inline int cs_socket_get(struct pcmcia_socket *skt)
-{
- int ret;
-
- WARN_ON(skt->state & SOCKET_INUSE);
-
- ret = try_module_get(skt->owner);
- if (ret)
- skt->state |= SOCKET_INUSE;
- return ret;
-}
-
-static inline void cs_socket_put(struct pcmcia_socket *skt)
-{
- if (skt->state & SOCKET_INUSE) {
- skt->state &= ~SOCKET_INUSE;
- module_put(skt->owner);
- }
-}
-
/*
* Stuff internal to module "pcmcia_core":
*/
-/* cistpl.c */
-int verify_cis_cache(struct pcmcia_socket *s);
-
-/* rsrc_mgr.c */
-void release_resource_db(struct pcmcia_socket *s);
-
/* socket_sysfs.c */
extern int pccard_sysfs_add_socket(struct device *dev);
extern void pccard_sysfs_remove_socket(struct device *dev);
@@ -125,8 +99,6 @@ extern void pccard_sysfs_remove_socket(struct device *dev);
/* cardbus.c */
int cb_alloc(struct pcmcia_socket *s);
void cb_free(struct pcmcia_socket *s);
-int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len,
- void *ptr);
@@ -138,7 +110,8 @@ struct pcmcia_callback{
struct module *owner;
int (*event) (struct pcmcia_socket *s,
event_t event, int priority);
- void (*requery) (struct pcmcia_socket *s, int new_cis);
+ void (*requery) (struct pcmcia_socket *s);
+ int (*validate) (struct pcmcia_socket *s, unsigned int *i);
int (*suspend) (struct pcmcia_socket *s);
int (*resume) (struct pcmcia_socket *s);
};
@@ -151,16 +124,35 @@ extern struct class pcmcia_socket_class;
int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr);
-int pcmcia_suspend_card(struct pcmcia_socket *skt);
-int pcmcia_resume_card(struct pcmcia_socket *skt);
-
-int pcmcia_eject_card(struct pcmcia_socket *skt);
-int pcmcia_insert_card(struct pcmcia_socket *skt);
+void pcmcia_parse_uevents(struct pcmcia_socket *socket, unsigned int events);
+#define PCMCIA_UEVENT_EJECT 0x0001
+#define PCMCIA_UEVENT_INSERT 0x0002
+#define PCMCIA_UEVENT_SUSPEND 0x0004
+#define PCMCIA_UEVENT_RESUME 0x0008
+#define PCMCIA_UEVENT_REQUERY 0x0010
struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt);
void pcmcia_put_socket(struct pcmcia_socket *skt);
+/*
+ * Stuff internal to module "pcmcia".
+ */
+/* ds.c */
+extern struct bus_type pcmcia_bus_type;
+
+/* pcmcia_resource.c */
+extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
+extern int pcmcia_validate_mem(struct pcmcia_socket *s);
+extern struct resource *pcmcia_find_mem_region(u_long base,
+ u_long num,
+ u_long align,
+ int low,
+ struct pcmcia_socket *s);
+
+
/* cistpl.c */
+extern struct bin_attribute pccard_cis_attr;
+
int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,
u_int addr, u_int len, void *ptr);
void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
@@ -172,8 +164,8 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
int pcmcia_replace_cis(struct pcmcia_socket *s,
const u8 *data, const size_t len);
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *count);
+int verify_cis_cache(struct pcmcia_socket *s);
-/* loop over CIS entries */
int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
cisdata_t code, cisparse_t *parse, void *priv_data,
int (*loop_tuple) (tuple_t *tuple,
@@ -189,35 +181,8 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
-/* rsrc_mgr.c */
-int pcmcia_validate_mem(struct pcmcia_socket *s);
-struct resource *pcmcia_find_io_region(unsigned long base,
- int num,
- unsigned long align,
- struct pcmcia_socket *s);
-int pcmcia_adjust_io_region(struct resource *res,
- unsigned long r_start,
- unsigned long r_end,
- struct pcmcia_socket *s);
-struct resource *pcmcia_find_mem_region(u_long base,
- u_long num,
- u_long align,
- int low,
- struct pcmcia_socket *s);
-
-/*
- * Stuff internal to module "pcmcia".
- */
-/* ds.c */
-extern struct bus_type pcmcia_bus_type;
-
-/* pcmcia_resource.c */
-extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
-
#ifdef CONFIG_PCMCIA_IOCTL
/* ds.c */
-extern spinlock_t pcmcia_dev_list_lock;
-
extern struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev);
extern void pcmcia_put_dev(struct pcmcia_device *p_dev);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 1a4a3c49cc1..0f98be4450b 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -42,8 +42,6 @@ MODULE_DESCRIPTION("PCMCIA Driver Services");
MODULE_LICENSE("GPL");
-spinlock_t pcmcia_dev_list_lock;
-
/*====================================================================*/
static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
@@ -126,9 +124,9 @@ pcmcia_store_new_id(struct device_driver *driver, const char *buf, size_t count)
dynid->id.device_no = device_no;
memcpy(dynid->id.prod_id_hash, prod_id_hash, sizeof(__u32) * 4);
- spin_lock(&pdrv->dynids.lock);
+ mutex_lock(&pdrv->dynids.lock);
list_add_tail(&dynid->node, &pdrv->dynids.list);
- spin_unlock(&pdrv->dynids.lock);
+ mutex_unlock(&pdrv->dynids.lock);
if (get_driver(&pdrv->drv)) {
retval = driver_attach(&pdrv->drv);
@@ -146,12 +144,12 @@ pcmcia_free_dynids(struct pcmcia_driver *drv)
{
struct pcmcia_dynid *dynid, *n;
- spin_lock(&drv->dynids.lock);
+ mutex_lock(&drv->dynids.lock);
list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
list_del(&dynid->node);
kfree(dynid);
}
- spin_unlock(&drv->dynids.lock);
+ mutex_unlock(&drv->dynids.lock);
}
static int
@@ -182,7 +180,7 @@ int pcmcia_register_driver(struct pcmcia_driver *driver)
/* initialize common fields */
driver->drv.bus = &pcmcia_bus_type;
driver->drv.owner = driver->owner;
- spin_lock_init(&driver->dynids.lock);
+ mutex_init(&driver->dynids.lock);
INIT_LIST_HEAD(&driver->dynids.list);
pr_debug("registering driver %s\n", driver->drv.name);
@@ -239,30 +237,21 @@ static void pcmcia_release_function(struct kref *ref)
static void pcmcia_release_dev(struct device *dev)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+ int i;
dev_dbg(dev, "releasing device\n");
pcmcia_put_socket(p_dev->socket);
+ for (i = 0; i < 4; i++)
+ kfree(p_dev->prod_id[i]);
kfree(p_dev->devname);
kref_put(&p_dev->function_config->ref, pcmcia_release_function);
kfree(p_dev);
}
-static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc)
-{
- if (!s->pcmcia_state.device_add_pending) {
- dev_dbg(&s->dev, "scheduling to add %s secondary"
- " device to %d\n", mfc ? "mfc" : "pfc", s->sock);
- s->pcmcia_state.device_add_pending = 1;
- s->pcmcia_state.mfc_pfc = mfc;
- schedule_work(&s->device_add);
- }
- return;
-}
static int pcmcia_device_probe(struct device *dev)
{
struct pcmcia_device *p_dev;
struct pcmcia_driver *p_drv;
- struct pcmcia_device_id *did;
struct pcmcia_socket *s;
cistpl_config_t cis_config;
int ret = 0;
@@ -275,18 +264,6 @@ static int pcmcia_device_probe(struct device *dev)
p_drv = to_pcmcia_drv(dev->driver);
s = p_dev->socket;
- /* The PCMCIA code passes the match data in via dev_set_drvdata(dev)
- * which is an ugly hack. Once the driver probe is called it may
- * and often will overwrite the match data so we must save it first
- *
- * handle pseudo multifunction devices:
- * there are at most two pseudo multifunction devices.
- * if we're matching against the first, schedule a
- * call which will then check whether there are two
- * pseudo devices, and if not, add the second one.
- */
- did = dev_get_drvdata(&p_dev->dev);
-
dev_dbg(dev, "trying to bind to %s\n", p_drv->drv.name);
if ((!p_drv->probe) || (!p_dev->function_config) ||
@@ -315,9 +292,11 @@ static int pcmcia_device_probe(struct device *dev)
goto put_module;
}
- if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
+ mutex_lock(&s->ops_mutex);
+ if ((s->pcmcia_state.has_pfc) &&
(p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
- pcmcia_add_device_later(p_dev->socket, 0);
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);
+ mutex_unlock(&s->ops_mutex);
put_module:
if (ret)
@@ -336,26 +315,27 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
{
struct pcmcia_device *p_dev;
struct pcmcia_device *tmp;
- unsigned long flags;
dev_dbg(leftover ? &leftover->dev : &s->dev,
"pcmcia_card_remove(%d) %s\n", s->sock,
leftover ? leftover->devname : "");
+ mutex_lock(&s->ops_mutex);
if (!leftover)
s->device_count = 0;
else
s->device_count = 1;
+ mutex_unlock(&s->ops_mutex);
/* unregister all pcmcia_devices registered with this socket, except leftover */
list_for_each_entry_safe(p_dev, tmp, &s->devices_list, socket_device_list) {
if (p_dev == leftover)
continue;
- spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+ mutex_lock(&s->ops_mutex);
list_del(&p_dev->socket_device_list);
p_dev->_removed = 1;
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
dev_dbg(&p_dev->dev, "unregistering device\n");
device_unregister(&p_dev->dev);
@@ -368,7 +348,6 @@ static int pcmcia_device_remove(struct device *dev)
{
struct pcmcia_device *p_dev;
struct pcmcia_driver *p_drv;
- struct pcmcia_device_id *did;
int i;
p_dev = to_pcmcia_dev(dev);
@@ -380,9 +359,8 @@ static int pcmcia_device_remove(struct device *dev)
* pseudo multi-function card, we need to unbind
* all devices
*/
- did = dev_get_drvdata(&p_dev->dev);
- if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
- (p_dev->socket->device_count != 0) &&
+ if ((p_dev->socket->pcmcia_state.has_pfc) &&
+ (p_dev->socket->device_count > 0) &&
(p_dev->device_no == 0))
pcmcia_card_remove(p_dev->socket, p_dev);
@@ -431,16 +409,20 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL,
CISTPL_MANFID, &manf_id)) {
+ mutex_lock(&p_dev->socket->ops_mutex);
p_dev->manf_id = manf_id.manf;
p_dev->card_id = manf_id.card;
p_dev->has_manf_id = 1;
p_dev->has_card_id = 1;
+ mutex_unlock(&p_dev->socket->ops_mutex);
}
if (!pccard_read_tuple(p_dev->socket, p_dev->func,
CISTPL_FUNCID, &func_id)) {
+ mutex_lock(&p_dev->socket->ops_mutex);
p_dev->func_id = func_id.func;
p_dev->has_func_id = 1;
+ mutex_unlock(&p_dev->socket->ops_mutex);
} else {
/* rule of thumb: cards with no FUNCID, but with
* common memory device geometry information, are
@@ -457,17 +439,21 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
dev_dbg(&p_dev->dev,
"mem device geometry probably means "
"FUNCID_MEMORY\n");
+ mutex_lock(&p_dev->socket->ops_mutex);
p_dev->func_id = CISTPL_FUNCID_MEMORY;
p_dev->has_func_id = 1;
+ mutex_unlock(&p_dev->socket->ops_mutex);
}
kfree(devgeo);
}
if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL, CISTPL_VERS_1,
vers1)) {
+ mutex_lock(&p_dev->socket->ops_mutex);
for (i = 0; i < min_t(unsigned int, 4, vers1->ns); i++) {
char *tmp;
unsigned int length;
+ char *new;
tmp = vers1->str + vers1->ofs[i];
@@ -475,14 +461,17 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
if ((length < 2) || (length > 255))
continue;
- p_dev->prod_id[i] = kmalloc(sizeof(char) * length,
- GFP_KERNEL);
- if (!p_dev->prod_id[i])
+ new = kmalloc(sizeof(char) * length, GFP_KERNEL);
+ if (!new)
continue;
- p_dev->prod_id[i] = strncpy(p_dev->prod_id[i],
- tmp, length);
+ new = strncpy(new, tmp, length);
+
+ tmp = p_dev->prod_id[i];
+ p_dev->prod_id[i] = new;
+ kfree(tmp);
}
+ mutex_unlock(&p_dev->socket->ops_mutex);
}
kfree(vers1);
@@ -502,7 +491,7 @@ static DEFINE_MUTEX(device_add_lock);
struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function)
{
struct pcmcia_device *p_dev, *tmp_dev;
- unsigned long flags;
+ int i;
s = pcmcia_get_socket(s);
if (!s)
@@ -512,16 +501,19 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
pr_debug("adding device to %d, function %d\n", s->sock, function);
- /* max of 4 devices per card */
- if (s->device_count == 4)
- goto err_put;
-
p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
if (!p_dev)
goto err_put;
- p_dev->socket = s;
+ mutex_lock(&s->ops_mutex);
p_dev->device_no = (s->device_count++);
+ mutex_unlock(&s->ops_mutex);
+
+ /* max of 2 devices per card */
+ if (p_dev->device_no >= 2)
+ goto err_free;
+
+ p_dev->socket = s;
p_dev->func = function;
p_dev->dev.bus = &pcmcia_bus_type;
@@ -538,7 +530,7 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
goto err_free;
dev_dbg(&p_dev->dev, "devname is %s\n", p_dev->devname);
- spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+ mutex_lock(&s->ops_mutex);
/*
* p_dev->function_config must be the same for all card functions.
@@ -556,7 +548,7 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
/* Add to the list in pcmcia_bus_socket */
list_add(&p_dev->socket_device_list, &s->devices_list);
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
if (!p_dev->function_config) {
dev_dbg(&p_dev->dev, "creating config_t\n");
@@ -581,14 +573,19 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
return p_dev;
err_unreg:
- spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+ mutex_lock(&s->ops_mutex);
list_del(&p_dev->socket_device_list);
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
err_free:
+ mutex_lock(&s->ops_mutex);
+ s->device_count--;
+ mutex_unlock(&s->ops_mutex);
+
+ for (i = 0; i < 4; i++)
+ kfree(p_dev->prod_id[i]);
kfree(p_dev->devname);
kfree(p_dev);
- s->device_count--;
err_put:
mutex_unlock(&device_add_lock);
pcmcia_put_socket(s);
@@ -601,19 +598,23 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
{
cistpl_longlink_mfc_t mfc;
unsigned int no_funcs, i, no_chains;
- int ret = 0;
+ int ret = -EAGAIN;
+ mutex_lock(&s->ops_mutex);
if (!(s->resource_setup_done)) {
dev_dbg(&s->dev,
"no resources available, delaying card_add\n");
+ mutex_unlock(&s->ops_mutex);
return -EAGAIN; /* try again, but later... */
}
if (pcmcia_validate_mem(s)) {
dev_dbg(&s->dev, "validating mem resources failed, "
"delaying card_add\n");
+ mutex_unlock(&s->ops_mutex);
return -EAGAIN; /* try again, but later... */
}
+ mutex_unlock(&s->ops_mutex);
ret = pccard_validate_cis(s, &no_chains);
if (ret || !no_chains) {
@@ -634,17 +635,7 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
}
-static void pcmcia_delayed_add_device(struct work_struct *work)
-{
- struct pcmcia_socket *s =
- container_of(work, struct pcmcia_socket, device_add);
- dev_dbg(&s->dev, "adding additional device to %d\n", s->sock);
- pcmcia_device_add(s, s->pcmcia_state.mfc_pfc);
- s->pcmcia_state.device_add_pending = 0;
- s->pcmcia_state.mfc_pfc = 0;
-}
-
-static int pcmcia_requery(struct device *dev, void * _data)
+static int pcmcia_requery_callback(struct device *dev, void * _data)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
if (!p_dev->dev.driver) {
@@ -655,45 +646,67 @@ static int pcmcia_requery(struct device *dev, void * _data)
return 0;
}
-static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis)
-{
- int no_devices = 0;
- int ret = 0;
- unsigned long flags;
- /* must be called with skt_mutex held */
- dev_dbg(&skt->dev, "re-scanning socket %d\n", skt->sock);
+static void pcmcia_requery(struct pcmcia_socket *s)
+{
+ int present, has_pfc;
- spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
- if (list_empty(&skt->devices_list))
- no_devices = 1;
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_lock(&s->ops_mutex);
+ present = s->pcmcia_state.present;
+ mutex_unlock(&s->ops_mutex);
- /* If this is because of a CIS override, start over */
- if (new_cis && !no_devices)
- pcmcia_card_remove(skt, NULL);
+ if (!present)
+ return;
- /* if no devices were added for this socket yet because of
- * missing resource information or other trouble, we need to
- * do this now. */
- if (no_devices || new_cis) {
- ret = pcmcia_card_add(skt);
- if (ret)
- return;
+ if (s->functions == 0) {
+ pcmcia_card_add(s);
+ return;
}
/* some device information might have changed because of a CIS
* update or because we can finally read it correctly... so
* determine it again, overwriting old values if necessary. */
- bus_for_each_dev(&pcmcia_bus_type, NULL, NULL, pcmcia_requery);
+ bus_for_each_dev(&pcmcia_bus_type, NULL, NULL, pcmcia_requery_callback);
+
+ /* if the CIS changed, we need to check whether the number of
+ * functions changed. */
+ if (s->fake_cis) {
+ int old_funcs, new_funcs;
+ cistpl_longlink_mfc_t mfc;
+
+ /* does this cis override add or remove functions? */
+ old_funcs = s->functions;
+
+ if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC,
+ &mfc))
+ new_funcs = mfc.nfn;
+ else
+ new_funcs = 1;
+ if (old_funcs > new_funcs) {
+ pcmcia_card_remove(s, NULL);
+ pcmcia_card_add(s);
+ } else if (new_funcs > old_funcs) {
+ s->functions = new_funcs;
+ pcmcia_device_add(s, 1);
+ }
+ }
+
+ /* If the PCMCIA device consists of two pseudo devices,
+ * call pcmcia_device_add() -- which will fail if both
+ * devices are already registered. */
+ mutex_lock(&s->ops_mutex);
+ has_pfc = s->pcmcia_state.has_pfc;
+ mutex_unlock(&s->ops_mutex);
+ if (has_pfc)
+ pcmcia_device_add(s, 0);
/* we re-scan all devices, not just the ones connected to this
* socket. This does not matter, though. */
- ret = bus_rescan_devices(&pcmcia_bus_type);
- if (ret)
- printk(KERN_INFO "pcmcia: bus_rescan_devices failed\n");
+ if (bus_rescan_devices(&pcmcia_bus_type))
+ dev_warn(&s->dev, "rescanning the bus failed\n");
}
+
#ifdef CONFIG_PCMCIA_LOAD_CIS
/**
@@ -710,9 +723,6 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
struct pcmcia_socket *s = dev->socket;
const struct firmware *fw;
int ret = -ENOMEM;
- int no_funcs;
- int old_funcs;
- cistpl_longlink_mfc_t mfc;
if (!filename)
return -EINVAL;
@@ -739,19 +749,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
/* update information */
pcmcia_device_query(dev);
- /* does this cis override add or remove functions? */
- old_funcs = s->functions;
-
- if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, &mfc))
- no_funcs = mfc.nfn;
- else
- no_funcs = 1;
- s->functions = no_funcs;
-
- if (old_funcs > no_funcs)
- pcmcia_card_remove(s, dev);
- else if (no_funcs > old_funcs)
- pcmcia_add_device_later(s, 1);
+ /* requery (as number of functions might have changed) */
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);
}
release:
release_firmware(fw);
@@ -818,9 +817,14 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) {
if (dev->device_no != did->device_no)
return 0;
+ mutex_lock(&dev->socket->ops_mutex);
+ dev->socket->pcmcia_state.has_pfc = 1;
+ mutex_unlock(&dev->socket->ops_mutex);
}
if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) {
+ int ret;
+
if ((!dev->has_func_id) || (dev->func_id != did->func_id))
return 0;
@@ -835,10 +839,15 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
* after it has re-checked that there is no possible module
* with a prod_id/manf_id/card_id match.
*/
- dev_dbg(&dev->dev,
- "skipping FUNC_ID match until userspace interaction\n");
- if (!dev->allow_func_id_match)
+ mutex_lock(&dev->socket->ops_mutex);
+ ret = dev->allow_func_id_match;
+ mutex_unlock(&dev->socket->ops_mutex);
+
+ if (!ret) {
+ dev_dbg(&dev->dev,
+ "skipping FUNC_ID match until userspace ACK\n");
return 0;
+ }
}
if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
@@ -859,8 +868,6 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
return 0;
}
- dev_set_drvdata(&dev->dev, did);
-
return 1;
}
@@ -873,16 +880,16 @@ static int pcmcia_bus_match(struct device *dev, struct device_driver *drv)
struct pcmcia_dynid *dynid;
/* match dynamic devices first */
- spin_lock(&p_drv->dynids.lock);
+ mutex_lock(&p_drv->dynids.lock);
list_for_each_entry(dynid, &p_drv->dynids.list, node) {
dev_dbg(dev, "trying to match to %s\n", drv->name);
if (pcmcia_devmatch(p_dev, &dynid->id)) {
dev_dbg(dev, "matched to %s\n", drv->name);
- spin_unlock(&p_drv->dynids.lock);
+ mutex_unlock(&p_drv->dynids.lock);
return 1;
}
}
- spin_unlock(&p_drv->dynids.lock);
+ mutex_unlock(&p_drv->dynids.lock);
#ifdef CONFIG_PCMCIA_IOCTL
/* matching by cardmgr */
@@ -970,13 +977,14 @@ static int runtime_suspend(struct device *dev)
return rc;
}
-static void runtime_resume(struct device *dev)
+static int runtime_resume(struct device *dev)
{
int rc;
down(&dev->sem);
rc = pcmcia_dev_resume(dev);
up(&dev->sem);
+ return rc;
}
/************************ per-device sysfs output ***************************/
@@ -1027,7 +1035,7 @@ static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute
if ((!p_dev->suspended) && !strncmp(buf, "off", 3))
ret = runtime_suspend(dev);
else if (p_dev->suspended && !strncmp(buf, "on", 2))
- runtime_resume(dev);
+ ret = runtime_resume(dev);
return ret ? ret : count;
}
@@ -1059,19 +1067,14 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
- int ret;
if (!count)
return -EINVAL;
- mutex_lock(&p_dev->socket->skt_mutex);
+ mutex_lock(&p_dev->socket->ops_mutex);
p_dev->allow_func_id_match = 1;
- mutex_unlock(&p_dev->socket->skt_mutex);
-
- ret = bus_rescan_devices(&pcmcia_bus_type);
- if (ret)
- printk(KERN_INFO "pcmcia: bus_rescan_devices failed after "
- "allowing func_id matches\n");
+ mutex_unlock(&p_dev->socket->ops_mutex);
+ pcmcia_parse_uevents(p_dev->socket, PCMCIA_UEVENT_REQUERY);
return count;
}
@@ -1099,8 +1102,13 @@ static int pcmcia_dev_suspend(struct device *dev, pm_message_t state)
struct pcmcia_driver *p_drv = NULL;
int ret = 0;
- if (p_dev->suspended)
+ mutex_lock(&p_dev->socket->ops_mutex);
+ if (p_dev->suspended) {
+ mutex_unlock(&p_dev->socket->ops_mutex);
return 0;
+ }
+ p_dev->suspended = 1;
+ mutex_unlock(&p_dev->socket->ops_mutex);
dev_dbg(dev, "suspending\n");
@@ -1117,6 +1125,9 @@ static int pcmcia_dev_suspend(struct device *dev, pm_message_t state)
"pcmcia: device %s (driver %s) did "
"not want to go to sleep (%d)\n",
p_dev->devname, p_drv->drv.name, ret);
+ mutex_lock(&p_dev->socket->ops_mutex);
+ p_dev->suspended = 0;
+ mutex_unlock(&p_dev->socket->ops_mutex);
goto out;
}
}
@@ -1127,8 +1138,6 @@ static int pcmcia_dev_suspend(struct device *dev, pm_message_t state)
}
out:
- if (!ret)
- p_dev->suspended = 1;
return ret;
}
@@ -1139,8 +1148,13 @@ static int pcmcia_dev_resume(struct device *dev)
struct pcmcia_driver *p_drv = NULL;
int ret = 0;
- if (!p_dev->suspended)
+ mutex_lock(&p_dev->socket->ops_mutex);
+ if (!p_dev->suspended) {
+ mutex_unlock(&p_dev->socket->ops_mutex);
return 0;
+ }
+ p_dev->suspended = 0;
+ mutex_unlock(&p_dev->socket->ops_mutex);
dev_dbg(dev, "resuming\n");
@@ -1161,8 +1175,6 @@ static int pcmcia_dev_resume(struct device *dev)
ret = p_drv->resume(p_dev);
out:
- if (!ret)
- p_dev->suspended = 0;
return ret;
}
@@ -1237,13 +1249,22 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
switch (event) {
case CS_EVENT_CARD_REMOVAL:
+ mutex_lock(&s->ops_mutex);
s->pcmcia_state.present = 0;
+ mutex_unlock(&s->ops_mutex);
pcmcia_card_remove(skt, NULL);
handle_event(skt, event);
+ mutex_lock(&s->ops_mutex);
+ destroy_cis_cache(s);
+ mutex_unlock(&s->ops_mutex);
break;
case CS_EVENT_CARD_INSERTION:
+ mutex_lock(&s->ops_mutex);
+ s->pcmcia_state.has_pfc = 0;
s->pcmcia_state.present = 1;
+ destroy_cis_cache(s); /* to be on the safe side... */
+ mutex_unlock(&s->ops_mutex);
pcmcia_card_add(skt);
handle_event(skt, event);
break;
@@ -1251,8 +1272,24 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
case CS_EVENT_EJECTION_REQUEST:
break;
- case CS_EVENT_PM_SUSPEND:
case CS_EVENT_PM_RESUME:
+ if (verify_cis_cache(skt) != 0) {
+ dev_dbg(&skt->dev, "cis mismatch - different card\n");
+ /* first, remove the card */
+ ds_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
+ mutex_lock(&s->ops_mutex);
+ destroy_cis_cache(skt);
+ kfree(skt->fake_cis);
+ skt->fake_cis = NULL;
+ mutex_unlock(&s->ops_mutex);
+ /* now, add the new card */
+ ds_event(skt, CS_EVENT_CARD_INSERTION,
+ CS_EVENT_PRI_LOW);
+ }
+ handle_event(skt, event);
+ break;
+
+ case CS_EVENT_PM_SUSPEND:
case CS_EVENT_RESET_PHYSICAL:
case CS_EVENT_CARD_RESET:
default:
@@ -1275,9 +1312,13 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)
if (!p_dev)
return NULL;
+ mutex_lock(&p_dev->socket->ops_mutex);
if (!p_dev->socket->pcmcia_state.present)
goto out;
+ if (p_dev->socket->pcmcia_state.dead)
+ goto out;
+
if (p_dev->_removed)
goto out;
@@ -1286,6 +1327,7 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)
ret = p_dev;
out:
+ mutex_unlock(&p_dev->socket->ops_mutex);
pcmcia_put_dev(p_dev);
return ret;
}
@@ -1295,7 +1337,8 @@ EXPORT_SYMBOL(pcmcia_dev_present);
static struct pcmcia_callback pcmcia_bus_callback = {
.owner = THIS_MODULE,
.event = ds_event,
- .requery = pcmcia_bus_rescan,
+ .requery = pcmcia_requery,
+ .validate = pccard_validate_cis,
.suspend = pcmcia_bus_suspend,
.resume = pcmcia_bus_resume,
};
@@ -1313,17 +1356,17 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev,
return -ENODEV;
}
- /*
- * Ugly. But we want to wait for the socket threads to have started up.
- * We really should let the drivers themselves drive some of this..
- */
- msleep(250);
+ ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr);
+ if (ret) {
+ dev_printk(KERN_ERR, dev, "PCMCIA registration failed\n");
+ pcmcia_put_socket(socket);
+ return ret;
+ }
#ifdef CONFIG_PCMCIA_IOCTL
init_waitqueue_head(&socket->queue);
#endif
INIT_LIST_HEAD(&socket->devices_list);
- INIT_WORK(&socket->device_add, pcmcia_delayed_add_device);
memset(&socket->pcmcia_state, 0, sizeof(u8));
socket->device_count = 0;
@@ -1345,14 +1388,20 @@ static void pcmcia_bus_remove_socket(struct device *dev,
if (!socket)
return;
+ mutex_lock(&socket->ops_mutex);
socket->pcmcia_state.dead = 1;
+ mutex_unlock(&socket->ops_mutex);
+
pccard_register_pcmcia(socket, NULL);
/* unregister any unbound devices */
mutex_lock(&socket->skt_mutex);
pcmcia_card_remove(socket, NULL);
+ release_cis_mem(socket);
mutex_unlock(&socket->skt_mutex);
+ sysfs_remove_bin_file(&dev->kobj, &pccard_cis_attr);
+
pcmcia_put_socket(socket);
return;
@@ -1383,8 +1432,6 @@ static int __init init_pcmcia_bus(void)
{
int ret;
- spin_lock_init(&pcmcia_dev_list_lock);
-
ret = bus_register(&pcmcia_bus_type);
if (ret < 0) {
printk(KERN_WARNING "pcmcia: bus_register error: %d\n", ret);
diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c
index d187ba4c5e0..89cfddca089 100644
--- a/drivers/pcmcia/electra_cf.c
+++ b/drivers/pcmcia/electra_cf.c
@@ -347,7 +347,7 @@ static int __devexit electra_cf_remove(struct of_device *ofdev)
return 0;
}
-static struct of_device_id electra_cf_match[] = {
+static const struct of_device_id electra_cf_match[] = {
{
.compatible = "electra-cf",
},
diff --git a/drivers/pcmcia/i82365.h b/drivers/pcmcia/i82365.h
index 622860c689d..849ef1b5d68 100644
--- a/drivers/pcmcia/i82365.h
+++ b/drivers/pcmcia/i82365.h
@@ -77,8 +77,8 @@
#define I365_VPP2_5V 0x04 /* Vpp2 = 5.0v */
#define I365_VPP2_12V 0x08 /* Vpp2 = 12.0v */
#define I365_VPP1_MASK 0x03 /* Mask for turning off Vpp1 */
-#define I365_VPP1_5V 0x01 /* Vpp2 = 5.0v */
-#define I365_VPP1_12V 0x02 /* Vpp2 = 12.0v */
+#define I365_VPP1_5V 0x01 /* Vpp1 = 5.0v */
+#define I365_VPP1_12V 0x02 /* Vpp1 = 12.0v */
/* Flags for I365_INTCTL */
#define I365_RING_ENA 0x80
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 26a621c9e2f..0ece2cd4a85 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -764,7 +764,7 @@ static int __init init_m32r_pcc(void)
for (i = 0 ; i < pcc_sockets ; i++) {
socket[i].socket.dev.parent = &pcc_device.dev;
socket[i].socket.ops = &pcc_operations;
- socket[i].socket.resource_ops = &pccard_nonstatic_ops;
+ socket[i].socket.resource_ops = &pccard_static_ops;
socket[i].socket.owner = THIS_MODULE;
socket[i].number = i;
ret = pcmcia_register_socket(&socket[i].socket);
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index 7f79c4e169a..61c21591812 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -1233,7 +1233,7 @@ static int __init m8xx_probe(struct of_device *ofdev,
socket[i].socket.io_offset = 0;
socket[i].socket.pci_irq = pcmcia_schlvl;
socket[i].socket.ops = &m8xx_services;
- socket[i].socket.resource_ops = &pccard_nonstatic_ops;
+ socket[i].socket.resource_ops = &pccard_iodyn_ops;
socket[i].socket.cb_dev = NULL;
socket[i].socket.dev.parent = &ofdev->dev;
socket[i].pcmcia = pcmcia;
@@ -1303,7 +1303,7 @@ static int m8xx_resume(struct platform_device *pdev)
#define m8xx_resume NULL
#endif
-static struct of_device_id m8xx_pcmcia_match[] = {
+static const struct of_device_id m8xx_pcmcia_match[] = {
{
.type = "pcmcia",
.compatible = "fsl,pq-pcmcia",
diff --git a/drivers/pcmcia/o2micro.h b/drivers/pcmcia/o2micro.h
index 624442fc0d3..e74bebac269 100644
--- a/drivers/pcmcia/o2micro.h
+++ b/drivers/pcmcia/o2micro.h
@@ -116,13 +116,12 @@ static int o2micro_override(struct yenta_socket *socket)
* from Eric Still, 02Micro.
*/
u8 a, b;
+ bool use_speedup;
if (PCI_FUNC(socket->dev->devfn) == 0) {
a = config_readb(socket, O2_RESERVED1);
b = config_readb(socket, O2_RESERVED2);
-
- dev_printk(KERN_INFO, &socket->dev->dev,
- "O2: res at 0x94/0xD4: %02x/%02x\n", a, b);
+ dev_dbg(&socket->dev->dev, "O2: 0x94/0xD4: %02x/%02x\n", a, b);
switch (socket->dev->device) {
/*
@@ -135,23 +134,37 @@ static int o2micro_override(struct yenta_socket *socket)
case PCI_DEVICE_ID_O2_6812:
case PCI_DEVICE_ID_O2_6832:
case PCI_DEVICE_ID_O2_6836:
- case PCI_DEVICE_ID_O2_6933:
- dev_printk(KERN_INFO, &socket->dev->dev,
- "Yenta O2: old bridge, disabling read "
- "prefetch/write burst\n");
- config_writeb(socket, O2_RESERVED1,
- a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
- config_writeb(socket, O2_RESERVED2,
- b & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
+ case PCI_DEVICE_ID_O2_6933:
+ use_speedup = false;
break;
-
default:
- dev_printk(KERN_INFO , &socket->dev->dev,
- "O2: enabling read prefetch/write burst\n");
+ use_speedup = true;
+ break;
+ }
+
+ /* the user may override our decision */
+ if (strcasecmp(o2_speedup, "on") == 0)
+ use_speedup = true;
+ else if (strcasecmp(o2_speedup, "off") == 0)
+ use_speedup = false;
+ else if (strcasecmp(o2_speedup, "default") != 0)
+ dev_warn(&socket->dev->dev,
+ "O2: Unknown parameter, using 'default'");
+
+ if (use_speedup) {
+ dev_info(&socket->dev->dev,
+ "O2: enabling read prefetch/write burst\n");
+ config_writeb(socket, O2_RESERVED1,
+ a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
+ config_writeb(socket, O2_RESERVED2,
+ b | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
+ } else {
+ dev_info(&socket->dev->dev,
+ "O2: disabling read prefetch/write burst\n");
config_writeb(socket, O2_RESERVED1,
- a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
+ a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
config_writeb(socket, O2_RESERVED2,
- b | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
+ b & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
}
}
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 663781d2012..3ef99155239 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -71,8 +71,6 @@ struct omap_cf_socket {
#define POLL_INTERVAL (2 * HZ)
-#define SZ_2K (2 * SZ_1K)
-
/*--------------------------------------------------------------------------*/
static int omap_cf_ss_init(struct pcmcia_socket *s)
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index f73fd5beaa3..13a7132cf68 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -62,16 +62,15 @@ static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
unsigned int function)
{
struct pcmcia_device *p_dev = NULL;
- unsigned long flags;
- spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+ mutex_lock(&s->ops_mutex);
list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
if (p_dev->func == function) {
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
return pcmcia_get_dev(p_dev);
}
}
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
return NULL;
}
@@ -169,7 +168,6 @@ static int pcmcia_adjust_resource_info(adjust_t *adj)
{
struct pcmcia_socket *s;
int ret = -ENOSYS;
- unsigned long flags;
down_read(&pcmcia_socket_list_rwsem);
list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
@@ -182,14 +180,13 @@ static int pcmcia_adjust_resource_info(adjust_t *adj)
/* you can't use the old interface if the new
* one was used before */
- spin_lock_irqsave(&s->lock, flags);
+ mutex_lock(&s->ops_mutex);
if ((s->resource_setup_new) &&
!(s->resource_setup_old)) {
- spin_unlock_irqrestore(&s->lock, flags);
+ mutex_unlock(&s->ops_mutex);
continue;
} else if (!(s->resource_setup_old))
s->resource_setup_old = 1;
- spin_unlock_irqrestore(&s->lock, flags);
switch (adj->Resource) {
case RES_MEMORY_RANGE:
@@ -208,10 +205,9 @@ static int pcmcia_adjust_resource_info(adjust_t *adj)
* last call to adjust_resource_info, we
* always need to assume this is the latest
* one... */
- spin_lock_irqsave(&s->lock, flags);
s->resource_setup_done = 1;
- spin_unlock_irqrestore(&s->lock, flags);
}
+ mutex_unlock(&s->ops_mutex);
}
}
up_read(&pcmcia_socket_list_rwsem);
@@ -470,7 +466,6 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
struct pcmcia_driver *p_drv;
struct pcmcia_device *p_dev;
int ret = 0;
- unsigned long flags;
s = pcmcia_get_socket(s);
if (!s)
@@ -490,7 +485,7 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
goto err_put_driver;
}
- spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+ mutex_lock(&s->ops_mutex);
list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
if (p_dev->func == bind_info->function) {
if ((p_dev->dev.driver == &p_drv->drv)) {
@@ -499,7 +494,7 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
* registered, and it was registered
* by userspace before, we need to
* return the "instance". */
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
bind_info->instance = p_dev;
ret = -EBUSY;
goto err_put_module;
@@ -507,7 +502,7 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
/* the correct driver managed to bind
* itself magically to the correct
* device. */
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
p_dev->cardmgr = p_drv;
ret = 0;
goto err_put_module;
@@ -516,12 +511,12 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
/* there's already a device available where
* no device has been bound to yet. So we don't
* need to register a device! */
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
goto rescan;
}
}
}
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
p_dev = pcmcia_device_add(s, bind_info->function);
if (!p_dev) {
@@ -578,7 +573,6 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int
dev_node_t *node;
struct pcmcia_device *p_dev;
struct pcmcia_driver *p_drv;
- unsigned long flags;
int ret = 0;
#ifdef CONFIG_CARDBUS
@@ -617,7 +611,7 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int
}
#endif
- spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+ mutex_lock(&s->ops_mutex);
list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
if (p_dev->func == bind_info->function) {
p_dev = pcmcia_get_dev(p_dev);
@@ -626,11 +620,11 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int
goto found;
}
}
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
return -ENODEV;
found:
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
p_drv = to_pcmcia_drv(p_dev->dev.driver);
if (p_drv && !p_dev->_locked) {
@@ -931,16 +925,16 @@ static int ds_ioctl(struct inode *inode, struct file *file,
ret = pccard_validate_cis(s, &buf->cisinfo.Chains);
break;
case DS_SUSPEND_CARD:
- ret = pcmcia_suspend_card(s);
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_SUSPEND);
break;
case DS_RESUME_CARD:
- ret = pcmcia_resume_card(s);
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_RESUME);
break;
case DS_EJECT_CARD:
- err = pcmcia_eject_card(s);
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_EJECT);
break;
case DS_INSERT_CARD:
- err = pcmcia_insert_card(s);
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_INSERT);
break;
case DS_ACCESS_CONFIGURATION_REGISTER:
if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index d5db95644b6..b2df04199a2 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -43,6 +43,39 @@ module_param(io_speed, int, 0444);
static u8 pcmcia_used_irq[NR_IRQS];
#endif
+static int pcmcia_adjust_io_region(struct resource *res, unsigned long start,
+ unsigned long end, struct pcmcia_socket *s)
+{
+ if (s->resource_ops->adjust_io_region)
+ return s->resource_ops->adjust_io_region(res, start, end, s);
+ return -ENOMEM;
+}
+
+static struct resource *pcmcia_find_io_region(unsigned long base, int num,
+ unsigned long align,
+ struct pcmcia_socket *s)
+{
+ if (s->resource_ops->find_io)
+ return s->resource_ops->find_io(base, num, align, s);
+ return NULL;
+}
+
+int pcmcia_validate_mem(struct pcmcia_socket *s)
+{
+ if (s->resource_ops->validate_mem)
+ return s->resource_ops->validate_mem(s);
+ /* if there is no callback, we can assume that everything is OK */
+ return 0;
+}
+
+struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
+ int low, struct pcmcia_socket *s)
+{
+ if (s->resource_ops->find_mem)
+ return s->resource_ops->find_mem(base, num, align, low, s);
+ return NULL;
+}
+
/** alloc_io_space
*
@@ -158,14 +191,18 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
return -EINVAL;
s = p_dev->socket;
+
+ mutex_lock(&s->ops_mutex);
c = p_dev->function_config;
if (!(c->state & CONFIG_LOCKED)) {
dev_dbg(&s->dev, "Configuration isnt't locked\n");
+ mutex_unlock(&s->ops_mutex);
return -EACCES;
}
addr = (c->ConfigBase + reg->Offset) >> 1;
+ mutex_unlock(&s->ops_mutex);
switch (reg->Action) {
case CS_READ:
@@ -190,6 +227,7 @@ int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh,
memreq_t *req)
{
struct pcmcia_socket *s = p_dev->socket;
+ int ret;
wh--;
if (wh >= MAX_WIN)
@@ -198,12 +236,13 @@ int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh,
dev_dbg(&s->dev, "failure: requested page is zero\n");
return -EINVAL;
}
+ mutex_lock(&s->ops_mutex);
s->win[wh].card_start = req->CardOffset;
- if (s->ops->set_mem_map(s, &s->win[wh]) != 0) {
- dev_dbg(&s->dev, "failed to set_mem_map\n");
- return -EIO;
- }
- return 0;
+ ret = s->ops->set_mem_map(s, &s->win[wh]);
+ if (ret)
+ dev_warn(&s->dev, "failed to set_mem_map\n");
+ mutex_unlock(&s->ops_mutex);
+ return ret;
} /* pcmcia_map_mem_page */
EXPORT_SYMBOL(pcmcia_map_mem_page);
@@ -219,14 +258,18 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
config_t *c;
s = p_dev->socket;
+
+ mutex_lock(&s->ops_mutex);
c = p_dev->function_config;
if (!(s->state & SOCKET_PRESENT)) {
dev_dbg(&s->dev, "No card present\n");
+ mutex_unlock(&s->ops_mutex);
return -ENODEV;
}
if (!(c->state & CONFIG_LOCKED)) {
dev_dbg(&s->dev, "Configuration isnt't locked\n");
+ mutex_unlock(&s->ops_mutex);
return -EACCES;
}
@@ -251,10 +294,12 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
if (mod->Vpp1 != mod->Vpp2) {
dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n");
+ mutex_unlock(&s->ops_mutex);
return -EINVAL;
}
s->socket.Vpp = mod->Vpp1;
if (s->ops->set_socket(s, &s->socket)) {
+ mutex_unlock(&s->ops_mutex);
dev_printk(KERN_WARNING, &s->dev,
"Unable to set VPP\n");
return -EIO;
@@ -262,6 +307,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
+ mutex_unlock(&s->ops_mutex);
return -EINVAL;
}
@@ -286,6 +332,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
s->ops->set_io_map(s, &io_on);
}
}
+ mutex_unlock(&s->ops_mutex);
return 0;
} /* modify_configuration */
@@ -296,9 +343,11 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
{
pccard_io_map io = { 0, 0, 0, 0, 1 };
struct pcmcia_socket *s = p_dev->socket;
- config_t *c = p_dev->function_config;
+ config_t *c;
int i;
+ mutex_lock(&s->ops_mutex);
+ c = p_dev->function_config;
if (p_dev->_locked) {
p_dev->_locked = 0;
if (--(s->lock_count) == 0) {
@@ -321,6 +370,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
s->ops->set_io_map(s, &io);
}
}
+ mutex_unlock(&s->ops_mutex);
return 0;
} /* pcmcia_release_configuration */
@@ -337,10 +387,14 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
{
struct pcmcia_socket *s = p_dev->socket;
- config_t *c = p_dev->function_config;
+ int ret = -EINVAL;
+ config_t *c;
+
+ mutex_lock(&s->ops_mutex);
+ c = p_dev->function_config;
if (!p_dev->_io)
- return -EINVAL;
+ goto out;
p_dev->_io = 0;
@@ -348,7 +402,7 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
(c->io.NumPorts1 != req->NumPorts1) ||
(c->io.BasePort2 != req->BasePort2) ||
(c->io.NumPorts2 != req->NumPorts2))
- return -EINVAL;
+ goto out;
c->state &= ~CONFIG_IO_REQ;
@@ -356,28 +410,38 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
if (req->NumPorts2)
release_io_space(s, req->BasePort2, req->NumPorts2);
- return 0;
+out:
+ mutex_unlock(&s->ops_mutex);
+
+ return ret;
} /* pcmcia_release_io */
static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
{
struct pcmcia_socket *s = p_dev->socket;
- config_t *c = p_dev->function_config;
+ config_t *c;
+ int ret = -EINVAL;
+
+ mutex_lock(&s->ops_mutex);
+
+ c = p_dev->function_config;
if (!p_dev->_irq)
- return -EINVAL;
+ goto out;
+
p_dev->_irq = 0;
if (c->state & CONFIG_LOCKED)
- return -EACCES;
+ goto out;
+
if (c->irq.Attributes != req->Attributes) {
dev_dbg(&s->dev, "IRQ attributes must match assigned ones\n");
- return -EINVAL;
+ goto out;
}
if (s->irq.AssignedIRQ != req->AssignedIRQ) {
dev_dbg(&s->dev, "IRQ must match assigned one\n");
- return -EINVAL;
+ goto out;
}
if (--s->irq.Config == 0) {
c->state &= ~CONFIG_IRQ_REQ;
@@ -390,8 +454,12 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
#ifdef CONFIG_PCMCIA_PROBE
pcmcia_used_irq[req->AssignedIRQ]--;
#endif
+ ret = 0;
- return 0;
+out:
+ mutex_unlock(&s->ops_mutex);
+
+ return ret;
} /* pcmcia_release_irq */
@@ -404,10 +472,12 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh)
if (wh >= MAX_WIN)
return -EINVAL;
+ mutex_lock(&s->ops_mutex);
win = &s->win[wh];
if (!(p_dev->_win & CLIENT_WIN_REQ(wh))) {
dev_dbg(&s->dev, "not releasing unknown window\n");
+ mutex_unlock(&s->ops_mutex);
return -EINVAL;
}
@@ -423,6 +493,7 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh)
win->res = NULL;
}
p_dev->_win &= ~CLIENT_WIN_REQ(wh);
+ mutex_unlock(&s->ops_mutex);
return 0;
} /* pcmcia_release_window */
@@ -445,8 +516,11 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
dev_dbg(&s->dev, "IntType may not be INT_CARDBUS\n");
return -EINVAL;
}
+
+ mutex_lock(&s->ops_mutex);
c = p_dev->function_config;
if (c->state & CONFIG_LOCKED) {
+ mutex_unlock(&s->ops_mutex);
dev_dbg(&s->dev, "Configuration is locked\n");
return -EACCES;
}
@@ -454,6 +528,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
/* Do power control. We don't allow changes in Vcc. */
s->socket.Vpp = req->Vpp;
if (s->ops->set_socket(s, &s->socket)) {
+ mutex_unlock(&s->ops_mutex);
dev_printk(KERN_WARNING, &s->dev,
"Unable to set socket state\n");
return -EINVAL;
@@ -476,6 +551,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
s->socket.io_irq = 0;
s->ops->set_socket(s, &s->socket);
s->lock_count++;
+ mutex_unlock(&s->ops_mutex);
/* Set up CIS configuration registers */
base = c->ConfigBase = req->ConfigBase;
@@ -524,6 +600,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
/* Configure I/O windows */
if (c->state & CONFIG_IO_REQ) {
+ mutex_lock(&s->ops_mutex);
iomap.speed = io_speed;
for (i = 0; i < MAX_IO_WIN; i++)
if (s->io[i].res) {
@@ -542,6 +619,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
s->ops->set_io_map(s, &iomap);
s->io[i].Config++;
}
+ mutex_unlock(&s->ops_mutex);
}
c->state |= CONFIG_LOCKED;
@@ -560,54 +638,65 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
{
struct pcmcia_socket *s = p_dev->socket;
config_t *c;
+ int ret = -EINVAL;
+
+ mutex_lock(&s->ops_mutex);
if (!(s->state & SOCKET_PRESENT)) {
dev_dbg(&s->dev, "No card present\n");
- return -ENODEV;
+ goto out;
}
if (!req)
- return -EINVAL;
+ goto out;
+
c = p_dev->function_config;
if (c->state & CONFIG_LOCKED) {
dev_dbg(&s->dev, "Configuration is locked\n");
- return -EACCES;
+ goto out;
}
if (c->state & CONFIG_IO_REQ) {
dev_dbg(&s->dev, "IO already configured\n");
- return -EBUSY;
+ goto out;
}
if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) {
dev_dbg(&s->dev, "bad attribute setting for IO region 1\n");
- return -EINVAL;
+ goto out;
}
if ((req->NumPorts2 > 0) &&
(req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) {
dev_dbg(&s->dev, "bad attribute setting for IO region 2\n");
- return -EINVAL;
+ goto out;
}
dev_dbg(&s->dev, "trying to allocate resource 1\n");
- if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
- req->NumPorts1, req->IOAddrLines)) {
+ ret = alloc_io_space(s, req->Attributes1, &req->BasePort1,
+ req->NumPorts1, req->IOAddrLines);
+ if (ret) {
dev_dbg(&s->dev, "allocation of resource 1 failed\n");
- return -EBUSY;
+ goto out;
}
if (req->NumPorts2) {
dev_dbg(&s->dev, "trying to allocate resource 2\n");
- if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
- req->NumPorts2, req->IOAddrLines)) {
+ ret = alloc_io_space(s, req->Attributes2, &req->BasePort2,
+ req->NumPorts2, req->IOAddrLines);
+ if (ret) {
dev_dbg(&s->dev, "allocation of resource 2 failed\n");
release_io_space(s, req->BasePort1, req->NumPorts1);
- return -EBUSY;
+ goto out;
}
}
c->io = *req;
c->state |= CONFIG_IO_REQ;
p_dev->_io = 1;
- return 0;
+ dev_dbg(&s->dev, "allocating resources succeeded: %d\n", ret);
+
+out:
+ mutex_unlock(&s->ops_mutex);
+
+ return ret;
} /* pcmcia_request_io */
EXPORT_SYMBOL(pcmcia_request_io);
@@ -636,18 +725,20 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
int ret = -EINVAL, irq = 0;
int type;
+ mutex_lock(&s->ops_mutex);
+
if (!(s->state & SOCKET_PRESENT)) {
dev_dbg(&s->dev, "No card present\n");
- return -ENODEV;
+ goto out;
}
c = p_dev->function_config;
if (c->state & CONFIG_LOCKED) {
dev_dbg(&s->dev, "Configuration is locked\n");
- return -EACCES;
+ goto out;
}
if (c->state & CONFIG_IRQ_REQ) {
dev_dbg(&s->dev, "IRQ already configured\n");
- return -EBUSY;
+ goto out;
}
/* Decide what type of interrupt we are registering */
@@ -708,7 +799,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
if (ret && !s->irq.AssignedIRQ) {
if (!s->pci_irq) {
dev_printk(KERN_INFO, &s->dev, "no IRQ found\n");
- return ret;
+ goto out;
}
type = IRQF_SHARED;
irq = s->pci_irq;
@@ -720,7 +811,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
if (ret) {
dev_printk(KERN_INFO, &s->dev,
"request_irq() failed\n");
- return ret;
+ goto out;
}
}
@@ -743,7 +834,10 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
pcmcia_used_irq[irq]++;
#endif
- return 0;
+ ret = 0;
+out:
+ mutex_unlock(&s->ops_mutex);
+ return ret;
} /* pcmcia_request_irq */
EXPORT_SYMBOL(pcmcia_request_irq);
@@ -796,6 +890,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
return -EINVAL;
}
+ mutex_lock(&s->ops_mutex);
win = &s->win[w];
if (!(s->features & SS_CAP_STATIC_MAP)) {
@@ -803,6 +898,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
(req->Attributes & WIN_MAP_BELOW_1MB), s);
if (!win->res) {
dev_dbg(&s->dev, "allocating mem region failed\n");
+ mutex_unlock(&s->ops_mutex);
return -EINVAL;
}
}
@@ -821,8 +917,10 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
if (req->Attributes & WIN_USE_WAIT)
win->flags |= MAP_USE_WAIT;
win->card_start = 0;
+
if (s->ops->set_mem_map(s, win) != 0) {
dev_dbg(&s->dev, "failed to set memory mapping\n");
+ mutex_unlock(&s->ops_mutex);
return -EIO;
}
s->state |= SOCKET_WIN_REQ(w);
@@ -833,6 +931,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
else
req->Base = win->res->start;
+ mutex_unlock(&s->ops_mutex);
*wh = w + 1;
return 0;
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index f8401a0ef89..e6f7d410aed 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -21,60 +21,12 @@
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
-
-int pcmcia_validate_mem(struct pcmcia_socket *s)
-{
- if (s->resource_ops->validate_mem)
- return s->resource_ops->validate_mem(s);
- /* if there is no callback, we can assume that everything is OK */
- return 0;
-}
-EXPORT_SYMBOL(pcmcia_validate_mem);
-
-int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,
- unsigned long r_end, struct pcmcia_socket *s)
-{
- if (s->resource_ops->adjust_io_region)
- return s->resource_ops->adjust_io_region(res, r_start, r_end, s);
- return -ENOMEM;
-}
-EXPORT_SYMBOL(pcmcia_adjust_io_region);
-
-struct resource *pcmcia_find_io_region(unsigned long base, int num,
- unsigned long align, struct pcmcia_socket *s)
-{
- if (s->resource_ops->find_io)
- return s->resource_ops->find_io(base, num, align, s);
- return NULL;
-}
-EXPORT_SYMBOL(pcmcia_find_io_region);
-
-struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
- int low, struct pcmcia_socket *s)
-{
- if (s->resource_ops->find_mem)
- return s->resource_ops->find_mem(base, num, align, low, s);
- return NULL;
-}
-EXPORT_SYMBOL(pcmcia_find_mem_region);
-
-void release_resource_db(struct pcmcia_socket *s)
-{
- if (s->resource_ops->exit)
- s->resource_ops->exit(s);
-}
-
-
static int static_init(struct pcmcia_socket *s)
{
- unsigned long flags;
-
/* the good thing about SS_CAP_STATIC_MAP sockets is
* that they don't need a resource database */
- spin_lock_irqsave(&s->lock, flags);
s->resource_setup_done = 1;
- spin_unlock_irqrestore(&s->lock, flags);
return 0;
}
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index c67638fe691..4663b3fa9f9 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -55,11 +55,10 @@ struct resource_map {
struct socket_data {
struct resource_map mem_db;
+ struct resource_map mem_db_valid;
struct resource_map io_db;
- unsigned int rsrc_mem_probe;
};
-static DEFINE_MUTEX(rsrc_mutex);
#define MEM_PROBE_LOW (1 << 0)
#define MEM_PROBE_HIGH (1 << 1)
@@ -125,8 +124,10 @@ static int add_interval(struct resource_map *map, u_long base, u_long num)
struct resource_map *p, *q;
for (p = map; ; p = p->next) {
- if ((p != map) && (p->base+p->num-1 >= base))
- return -1;
+ if ((p != map) && (p->base+p->num >= base)) {
+ p->num = max(num + base - p->base, p->num);
+ return 0;
+ }
if ((p->next == map) || (p->next->base > base+num-1))
break;
}
@@ -264,36 +265,44 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
}
#endif
-/*======================================================================
-
- This is tricky... when we set up CIS memory, we try to validate
- the memory window space allocations.
-
-======================================================================*/
+/*======================================================================*/
-/* Validation function for cards with a valid CIS */
+/**
+ * readable() - iomem validation function for cards with a valid CIS
+ */
static int readable(struct pcmcia_socket *s, struct resource *res,
unsigned int *count)
{
- int ret = -1;
+ int ret = -EINVAL;
+
+ if (s->fake_cis) {
+ dev_dbg(&s->dev, "fake CIS is being used: can't validate mem\n");
+ return 0;
+ }
s->cis_mem.res = res;
s->cis_virt = ioremap(res->start, s->map_size);
if (s->cis_virt) {
- ret = pccard_validate_cis(s, count);
- /* invalidate mapping and CIS cache */
+ mutex_unlock(&s->ops_mutex);
+ /* as we're only called from pcmcia.c, we're safe */
+ if (s->callback->validate)
+ ret = s->callback->validate(s, count);
+ /* invalidate mapping */
+ mutex_lock(&s->ops_mutex);
iounmap(s->cis_virt);
s->cis_virt = NULL;
- destroy_cis_cache(s);
}
s->cis_mem.res = NULL;
- if ((ret != 0) || (*count == 0))
- return 0;
- return 1;
+ if ((ret) || (*count == 0))
+ return -EINVAL;
+ return 0;
}
-/* Validation function for simple memory cards */
-static int checksum(struct pcmcia_socket *s, struct resource *res)
+/**
+ * checksum() - iomem validation function for simple memory cards
+ */
+static int checksum(struct pcmcia_socket *s, struct resource *res,
+ unsigned int *value)
{
pccard_mem_map map;
int i, a = 0, b = -1, d;
@@ -321,61 +330,90 @@ static int checksum(struct pcmcia_socket *s, struct resource *res)
iounmap(virt);
}
- return (b == -1) ? -1 : (a>>1);
+ if (b == -1)
+ return -EINVAL;
+
+ *value = a;
+
+ return 0;
}
-static int
-cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size)
+/**
+ * do_validate_mem() - low level validate a memory region for PCMCIA use
+ * @s: PCMCIA socket to validate
+ * @base: start address of resource to check
+ * @size: size of resource to check
+ * @validate: validation function to use
+ *
+ * do_validate_mem() splits up the memory region which is to be checked
+ * into two parts. Both are passed to the @validate() function. If
+ * @validate() returns non-zero, or the value parameter to @validate()
+ * is zero, or the value parameter is different between both calls,
+ * the check fails, and -EINVAL is returned. Else, 0 is returned.
+ */
+static int do_validate_mem(struct pcmcia_socket *s,
+ unsigned long base, unsigned long size,
+ int validate (struct pcmcia_socket *s,
+ struct resource *res,
+ unsigned int *value))
{
+ struct socket_data *s_data = s->resource_data;
struct resource *res1, *res2;
- unsigned int info1, info2;
- int ret = 0;
+ unsigned int info1 = 1, info2 = 1;
+ int ret = -EINVAL;
res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
"PCMCIA memprobe");
if (res1 && res2) {
- ret = readable(s, res1, &info1);
- ret += readable(s, res2, &info2);
+ ret = 0;
+ if (validate) {
+ ret = validate(s, res1, &info1);
+ ret += validate(s, res2, &info2);
+ }
}
free_region(res2);
free_region(res1);
- return (ret == 2) && (info1 == info2);
-}
+ dev_dbg(&s->dev, "cs: memory probe 0x%06lx-0x%06lx: %p %p %u %u %u",
+ base, base+size-1, res1, res2, ret, info1, info2);
-static int
-checksum_match(struct pcmcia_socket *s, unsigned long base, unsigned long size)
-{
- struct resource *res1, *res2;
- int a = -1, b = -1;
-
- res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
- res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
- "PCMCIA memprobe");
+ if ((ret) || (info1 != info2) || (info1 == 0))
+ return -EINVAL;
- if (res1 && res2) {
- a = checksum(s, res1);
- b = checksum(s, res2);
+ if (validate && !s->fake_cis) {
+ /* move it to the validated data set */
+ add_interval(&s_data->mem_db_valid, base, size);
+ sub_interval(&s_data->mem_db, base, size);
}
- free_region(res2);
- free_region(res1);
-
- return (a == b) && (a >= 0);
+ return 0;
}
-/*======================================================================
-
- The memory probe. If the memory list includes a 64K-aligned block
- below 1MB, we probe in 64K chunks, and as soon as we accumulate at
- least mem_limit free space, we quit.
-
-======================================================================*/
-static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
+/**
+ * do_mem_probe() - validate a memory region for PCMCIA use
+ * @s: PCMCIA socket to validate
+ * @base: start address of resource to check
+ * @num: size of resource to check
+ * @validate: validation function to use
+ * @fallback: validation function to use if validate fails
+ *
+ * do_mem_probe() checks a memory region for use by the PCMCIA subsystem.
+ * To do so, the area is split up into sensible parts, and then passed
+ * into the @validate() function. Only if @validate() and @fallback() fail,
+ * the area is marked as unavaibale for use by the PCMCIA subsystem. The
+ * function returns the size of the usable memory area.
+ */
+static int do_mem_probe(struct pcmcia_socket *s, u_long base, u_long num,
+ int validate (struct pcmcia_socket *s,
+ struct resource *res,
+ unsigned int *value),
+ int fallback (struct pcmcia_socket *s,
+ struct resource *res,
+ unsigned int *value))
{
struct socket_data *s_data = s->resource_data;
u_long i, j, bad, fail, step;
@@ -393,15 +431,14 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
for (i = j = base; i < base+num; i = j + step) {
if (!fail) {
for (j = i; j < base+num; j += step) {
- if (cis_readable(s, j, step))
+ if (!do_validate_mem(s, j, step, validate))
break;
}
fail = ((i == base) && (j == base+num));
}
- if (fail) {
- for (j = i; j < base+num; j += 2*step)
- if (checksum_match(s, j, step) &&
- checksum_match(s, j + step, step))
+ if ((fail) && (fallback)) {
+ for (j = i; j < base+num; j += step)
+ if (!do_validate_mem(s, j, step, fallback))
break;
}
if (i != j) {
@@ -416,8 +453,14 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
return num - bad;
}
+
#ifdef CONFIG_PCMCIA_PROBE
+/**
+ * inv_probe() - top-to-bottom search for one usuable high memory area
+ * @s: PCMCIA socket to validate
+ * @m: resource_map to check
+ */
static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
{
struct socket_data *s_data = s->resource_data;
@@ -432,9 +475,18 @@ static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
}
if (m->base < 0x100000)
return 0;
- return do_mem_probe(m->base, m->num, s);
+ return do_mem_probe(s, m->base, m->num, readable, checksum);
}
+/**
+ * validate_mem() - memory probe function
+ * @s: PCMCIA socket to validate
+ * @probe_mask: MEM_PROBE_LOW | MEM_PROBE_HIGH
+ *
+ * The memory probe. If the memory list includes a 64K-aligned block
+ * below 1MB, we probe in 64K chunks, and as soon as we accumulate at
+ * least mem_limit free space, we quit. Returns 0 on usuable ports.
+ */
static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
{
struct resource_map *m, mm;
@@ -446,6 +498,8 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
if (probe_mask & MEM_PROBE_HIGH) {
if (inv_probe(s_data->mem_db.next, s) > 0)
return 0;
+ if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
+ return 0;
dev_printk(KERN_NOTICE, &s->dev,
"cs: warning: no high memory space available!\n");
return -ENODEV;
@@ -457,7 +511,8 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
if (mm.base >= 0x100000)
continue;
if ((mm.base | mm.num) & 0xffff) {
- ok += do_mem_probe(mm.base, mm.num, s);
+ ok += do_mem_probe(s, mm.base, mm.num, readable,
+ checksum);
continue;
}
/* Special probe for 64K-aligned block */
@@ -467,7 +522,8 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
if (ok >= mem_limit)
sub_interval(&s_data->mem_db, b, 0x10000);
else
- ok += do_mem_probe(b, 0x10000, s);
+ ok += do_mem_probe(s, b, 0x10000,
+ readable, checksum);
}
}
}
@@ -480,6 +536,13 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
#else /* CONFIG_PCMCIA_PROBE */
+/**
+ * validate_mem() - memory probe function
+ * @s: PCMCIA socket to validate
+ * @probe_mask: ignored
+ *
+ * Returns 0 on usuable ports.
+ */
static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
{
struct resource_map *m, mm;
@@ -488,7 +551,7 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
mm = *m;
- ok += do_mem_probe(mm.base, mm.num, s);
+ ok += do_mem_probe(s, mm.base, mm.num, readable, checksum);
}
if (ok > 0)
return 0;
@@ -498,31 +561,31 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
#endif /* CONFIG_PCMCIA_PROBE */
-/*
+/**
+ * pcmcia_nonstatic_validate_mem() - try to validate iomem for PCMCIA use
+ * @s: PCMCIA socket to validate
+ *
+ * This is tricky... when we set up CIS memory, we try to validate
+ * the memory window space allocations.
+ *
* Locking note: Must be called with skt_mutex held!
*/
static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
{
struct socket_data *s_data = s->resource_data;
unsigned int probe_mask = MEM_PROBE_LOW;
- int ret = 0;
+ int ret;
- if (!probe_mem)
+ if (!probe_mem || !(s->state & SOCKET_PRESENT))
return 0;
- mutex_lock(&rsrc_mutex);
-
if (s->features & SS_CAP_PAGE_REGS)
probe_mask = MEM_PROBE_HIGH;
- if (probe_mask & ~s_data->rsrc_mem_probe) {
- if (s->state & SOCKET_PRESENT)
- ret = validate_mem(s, probe_mask);
- if (!ret)
- s_data->rsrc_mem_probe |= probe_mask;
- }
+ ret = validate_mem(s, probe_mask);
- mutex_unlock(&rsrc_mutex);
+ if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
+ return 0;
return ret;
}
@@ -602,7 +665,6 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
struct socket_data *s_data = s->resource_data;
int ret = -ENOMEM;
- mutex_lock(&rsrc_mutex);
for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
unsigned long start = m->base;
unsigned long end = m->base + m->num - 1;
@@ -613,7 +675,6 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
ret = adjust_resource(res, r_start, r_end - r_start + 1);
break;
}
- mutex_unlock(&rsrc_mutex);
return ret;
}
@@ -647,7 +708,6 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
data.offset = base & data.mask;
data.map = &s_data->io_db;
- mutex_lock(&rsrc_mutex);
#ifdef CONFIG_PCI
if (s->cb_dev) {
ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
@@ -656,7 +716,6 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
#endif
ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
1, pcmcia_align, &data);
- mutex_unlock(&rsrc_mutex);
if (ret != 0) {
kfree(res);
@@ -672,15 +731,15 @@ static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
struct socket_data *s_data = s->resource_data;
struct pcmcia_align_data data;
unsigned long min, max;
- int ret, i;
+ int ret, i, j;
low = low || !(s->features & SS_CAP_PAGE_REGS);
data.mask = align - 1;
data.offset = base & data.mask;
- data.map = &s_data->mem_db;
for (i = 0; i < 2; i++) {
+ data.map = &s_data->mem_db_valid;
if (low) {
max = 0x100000UL;
min = base < max ? base : 0;
@@ -689,17 +748,23 @@ static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
min = 0x100000UL + base;
}
- mutex_lock(&rsrc_mutex);
+ for (j = 0; j < 2; j++) {
#ifdef CONFIG_PCI
- if (s->cb_dev) {
- ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
- 1, min, 0,
- pcmcia_align, &data);
- } else
+ if (s->cb_dev) {
+ ret = pci_bus_alloc_resource(s->cb_dev->bus,
+ res, num, 1, min, 0,
+ pcmcia_align, &data);
+ } else
#endif
- ret = allocate_resource(&iomem_resource, res, num, min,
- max, 1, pcmcia_align, &data);
- mutex_unlock(&rsrc_mutex);
+ {
+ ret = allocate_resource(&iomem_resource,
+ res, num, min, max, 1,
+ pcmcia_align, &data);
+ }
+ if (ret == 0)
+ break;
+ data.map = &s_data->mem_db;
+ }
if (ret == 0 || low)
break;
low = 1;
@@ -722,25 +787,18 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
if (end < start)
return -EINVAL;
- mutex_lock(&rsrc_mutex);
switch (action) {
case ADD_MANAGED_RESOURCE:
ret = add_interval(&data->mem_db, start, size);
+ if (!ret)
+ do_mem_probe(s, start, size, NULL, NULL);
break;
case REMOVE_MANAGED_RESOURCE:
ret = sub_interval(&data->mem_db, start, size);
- if (!ret) {
- struct pcmcia_socket *socket;
- down_read(&pcmcia_socket_list_rwsem);
- list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
- release_cis_mem(socket);
- up_read(&pcmcia_socket_list_rwsem);
- }
break;
default:
ret = -EINVAL;
}
- mutex_unlock(&rsrc_mutex);
return ret;
}
@@ -758,7 +816,6 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
if (end > IO_SPACE_LIMIT)
return -EINVAL;
- mutex_lock(&rsrc_mutex);
switch (action) {
case ADD_MANAGED_RESOURCE:
if (add_interval(&data->io_db, start, size) != 0) {
@@ -777,7 +834,6 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
ret = -EINVAL;
break;
}
- mutex_unlock(&rsrc_mutex);
return ret;
}
@@ -860,6 +916,7 @@ static int nonstatic_init(struct pcmcia_socket *s)
return -ENOMEM;
data->mem_db.next = &data->mem_db;
+ data->mem_db_valid.next = &data->mem_db_valid;
data->io_db.next = &data->io_db;
s->resource_data = (void *) data;
@@ -874,7 +931,10 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
struct socket_data *data = s->resource_data;
struct resource_map *p, *q;
- mutex_lock(&rsrc_mutex);
+ for (p = data->mem_db_valid.next; p != &data->mem_db_valid; p = q) {
+ q = p->next;
+ kfree(p);
+ }
for (p = data->mem_db.next; p != &data->mem_db; p = q) {
q = p->next;
kfree(p);
@@ -883,7 +943,6 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
q = p->next;
kfree(p);
}
- mutex_unlock(&rsrc_mutex);
}
@@ -910,7 +969,7 @@ static ssize_t show_io_db(struct device *dev,
struct resource_map *p;
ssize_t ret = 0;
- mutex_lock(&rsrc_mutex);
+ mutex_lock(&s->ops_mutex);
data = s->resource_data;
for (p = data->io_db.next; p != &data->io_db; p = p->next) {
@@ -922,7 +981,7 @@ static ssize_t show_io_db(struct device *dev,
((unsigned long) p->base + p->num - 1));
}
- mutex_unlock(&rsrc_mutex);
+ mutex_unlock(&s->ops_mutex);
return ret;
}
@@ -950,9 +1009,11 @@ static ssize_t store_io_db(struct device *dev,
if (end_addr < start_addr)
return -EINVAL;
+ mutex_lock(&s->ops_mutex);
ret = adjust_io(s, add, start_addr, end_addr);
if (!ret)
s->resource_setup_new = 1;
+ mutex_unlock(&s->ops_mutex);
return ret ? ret : count;
}
@@ -966,9 +1027,19 @@ static ssize_t show_mem_db(struct device *dev,
struct resource_map *p;
ssize_t ret = 0;
- mutex_lock(&rsrc_mutex);
+ mutex_lock(&s->ops_mutex);
data = s->resource_data;
+ for (p = data->mem_db_valid.next; p != &data->mem_db_valid;
+ p = p->next) {
+ if (ret > (PAGE_SIZE - 10))
+ continue;
+ ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
+ "0x%08lx - 0x%08lx\n",
+ ((unsigned long) p->base),
+ ((unsigned long) p->base + p->num - 1));
+ }
+
for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
if (ret > (PAGE_SIZE - 10))
continue;
@@ -978,7 +1049,7 @@ static ssize_t show_mem_db(struct device *dev,
((unsigned long) p->base + p->num - 1));
}
- mutex_unlock(&rsrc_mutex);
+ mutex_unlock(&s->ops_mutex);
return ret;
}
@@ -1006,9 +1077,11 @@ static ssize_t store_mem_db(struct device *dev,
if (end_addr < start_addr)
return -EINVAL;
+ mutex_lock(&s->ops_mutex);
ret = adjust_memory(s, add, start_addr, end_addr);
if (!ret)
s->resource_setup_new = 1;
+ mutex_unlock(&s->ops_mutex);
return ret ? ret : count;
}
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index 7a456000332..08278016e58 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -88,15 +88,14 @@ static DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL);
static ssize_t pccard_store_insert(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- ssize_t ret;
struct pcmcia_socket *s = to_socket(dev);
if (!count)
return -EINVAL;
- ret = pcmcia_insert_card(s);
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_INSERT);
- return ret ? ret : count;
+ return count;
}
static DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert);
@@ -113,18 +112,22 @@ static ssize_t pccard_store_card_pm_state(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- ssize_t ret = -EINVAL;
struct pcmcia_socket *s = to_socket(dev);
+ ssize_t ret = count;
if (!count)
return -EINVAL;
- if (!(s->state & SOCKET_SUSPEND) && !strncmp(buf, "off", 3))
- ret = pcmcia_suspend_card(s);
- else if ((s->state & SOCKET_SUSPEND) && !strncmp(buf, "on", 2))
- ret = pcmcia_resume_card(s);
+ if (!strncmp(buf, "off", 3))
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_SUSPEND);
+ else {
+ if (!strncmp(buf, "on", 2))
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_RESUME);
+ else
+ ret = -EINVAL;
+ }
- return ret ? -ENODEV : count;
+ return ret;
}
static DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state);
@@ -132,15 +135,14 @@ static ssize_t pccard_store_eject(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- ssize_t ret;
struct pcmcia_socket *s = to_socket(dev);
if (!count)
return -EINVAL;
- ret = pcmcia_eject_card(s);
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_EJECT);
- return ret ? ret : count;
+ return count;
}
static DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject);
@@ -167,7 +169,9 @@ static ssize_t pccard_store_irq_mask(struct device *dev,
ret = sscanf(buf, "0x%x\n", &mask);
if (ret == 1) {
+ mutex_lock(&s->ops_mutex);
s->irq_mask &= mask;
+ mutex_unlock(&s->ops_mutex);
ret = 0;
}
@@ -187,163 +191,21 @@ static ssize_t pccard_store_resource(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- unsigned long flags;
struct pcmcia_socket *s = to_socket(dev);
if (!count)
return -EINVAL;
- spin_lock_irqsave(&s->lock, flags);
+ mutex_lock(&s->ops_mutex);
if (!s->resource_setup_done)
s->resource_setup_done = 1;
- spin_unlock_irqrestore(&s->lock, flags);
-
- mutex_lock(&s->skt_mutex);
- if ((s->callback) &&
- (s->state & SOCKET_PRESENT) &&
- !(s->state & SOCKET_CARDBUS)) {
- if (try_module_get(s->callback->owner)) {
- s->callback->requery(s, 0);
- module_put(s->callback->owner);
- }
- }
- mutex_unlock(&s->skt_mutex);
-
- return count;
-}
-static DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource);
+ mutex_unlock(&s->ops_mutex);
-
-static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf, loff_t off, size_t count)
-{
- tuple_t tuple;
- int status, i;
- loff_t pointer = 0;
- ssize_t ret = 0;
- u_char *tuplebuffer;
- u_char *tempbuffer;
-
- tuplebuffer = kmalloc(sizeof(u_char) * 256, GFP_KERNEL);
- if (!tuplebuffer)
- return -ENOMEM;
-
- tempbuffer = kmalloc(sizeof(u_char) * 258, GFP_KERNEL);
- if (!tempbuffer) {
- ret = -ENOMEM;
- goto free_tuple;
- }
-
- memset(&tuple, 0, sizeof(tuple_t));
-
- tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON;
- tuple.DesiredTuple = RETURN_FIRST_TUPLE;
- tuple.TupleOffset = 0;
-
- status = pccard_get_first_tuple(s, BIND_FN_ALL, &tuple);
- while (!status) {
- tuple.TupleData = tuplebuffer;
- tuple.TupleDataMax = 255;
- memset(tuplebuffer, 0, sizeof(u_char) * 255);
-
- status = pccard_get_tuple_data(s, &tuple);
- if (status)
- break;
-
- if (off < (pointer + 2 + tuple.TupleDataLen)) {
- tempbuffer[0] = tuple.TupleCode & 0xff;
- tempbuffer[1] = tuple.TupleLink & 0xff;
- for (i = 0; i < tuple.TupleDataLen; i++)
- tempbuffer[i + 2] = tuplebuffer[i] & 0xff;
-
- for (i = 0; i < (2 + tuple.TupleDataLen); i++) {
- if (((i + pointer) >= off) &&
- (i + pointer) < (off + count)) {
- buf[ret] = tempbuffer[i];
- ret++;
- }
- }
- }
-
- pointer += 2 + tuple.TupleDataLen;
-
- if (pointer >= (off + count))
- break;
-
- if (tuple.TupleCode == CISTPL_END)
- break;
- status = pccard_get_next_tuple(s, BIND_FN_ALL, &tuple);
- }
-
- kfree(tempbuffer);
- free_tuple:
- kfree(tuplebuffer);
-
- return ret;
-}
-
-static ssize_t pccard_show_cis(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
-{
- unsigned int size = 0x200;
-
- if (off >= size)
- count = 0;
- else {
- struct pcmcia_socket *s;
- unsigned int chains;
-
- if (off + count > size)
- count = size - off;
-
- s = to_socket(container_of(kobj, struct device, kobj));
-
- if (!(s->state & SOCKET_PRESENT))
- return -ENODEV;
- if (pccard_validate_cis(s, &chains))
- return -EIO;
- if (!chains)
- return -ENODATA;
-
- count = pccard_extract_cis(s, buf, off, count);
- }
-
- return count;
-}
-
-static ssize_t pccard_store_cis(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
-{
- struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj));
- int error;
-
- if (off)
- return -EINVAL;
-
- if (count >= CISTPL_MAX_CIS_SIZE)
- return -EINVAL;
-
- if (!(s->state & SOCKET_PRESENT))
- return -ENODEV;
-
- error = pcmcia_replace_cis(s, buf, count);
- if (error)
- return -EIO;
-
- mutex_lock(&s->skt_mutex);
- if ((s->callback) && (s->state & SOCKET_PRESENT) &&
- !(s->state & SOCKET_CARDBUS)) {
- if (try_module_get(s->callback->owner)) {
- s->callback->requery(s, 1);
- module_put(s->callback->owner);
- }
- }
- mutex_unlock(&s->skt_mutex);
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);
return count;
}
-
+static DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource);
static struct attribute *pccard_socket_attributes[] = {
&dev_attr_card_type.attr,
@@ -362,28 +224,12 @@ static const struct attribute_group socket_attrs = {
.attrs = pccard_socket_attributes,
};
-static struct bin_attribute pccard_cis_attr = {
- .attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR },
- .size = 0x200,
- .read = pccard_show_cis,
- .write = pccard_store_cis,
-};
-
int pccard_sysfs_add_socket(struct device *dev)
{
- int ret = 0;
-
- ret = sysfs_create_group(&dev->kobj, &socket_attrs);
- if (!ret) {
- ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr);
- if (ret)
- sysfs_remove_group(&dev->kobj, &socket_attrs);
- }
- return ret;
+ return sysfs_create_group(&dev->kobj, &socket_attrs);
}
void pccard_sysfs_remove_socket(struct device *dev)
{
- sysfs_remove_bin_file(&dev->kobj, &pccard_cis_attr);
sysfs_remove_group(&dev->kobj, &socket_attrs);
}
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 1f2039d5e96..b85375f8762 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -37,6 +37,11 @@ static int pwr_irqs_off;
module_param(pwr_irqs_off, bool, 0644);
MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!");
+static char o2_speedup[] = "default";
+module_param_string(o2_speedup, o2_speedup, sizeof(o2_speedup), 0444);
+MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' "
+ "or 'default' (uses recommended behaviour for the detected bridge)");
+
#define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args)
/* Don't ask.. */
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index e82d8c9c6cd..95a689befc8 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -532,7 +532,7 @@ static void ps3av_set_videomode_packet(u32 id)
res = ps3av_cmd_avb_param(&avb_param, len);
if (res == PS3AV_STATUS_NO_SYNC_HEAD)
printk(KERN_WARNING
- "%s: Command failed. Please try your request again. \n",
+ "%s: Command failed. Please try your request again.\n",
__func__);
else if (res)
dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n");
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 8167e9e6827..2bb8a8b7ffa 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -868,4 +868,14 @@ config RTC_DRV_MC13783
help
This enables support for the Freescale MC13783 PMIC RTC
+config RTC_DRV_MPC5121
+ tristate "Freescale MPC5121 built-in RTC"
+ depends on PPC_MPC512x && RTC_CLASS
+ help
+ If you say yes here you will get support for the
+ built-in RTC MPC5121.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-mpc5121.
+
endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index e5160fddc44..b7148afb8f5 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
obj-$(CONFIG_RTC_DRV_MC13783) += rtc-mc13783.o
obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o
+obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o
obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o
obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o
obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c
new file mode 100644
index 00000000000..4313ca03a96
--- /dev/null
+++ b/drivers/rtc/rtc-mpc5121.c
@@ -0,0 +1,387 @@
+/*
+ * Real-time clock driver for MPC5121
+ *
+ * Copyright 2007, Domen Puncer <domen.puncer@telargo.com>
+ * Copyright 2008, Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/rtc.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+
+struct mpc5121_rtc_regs {
+ u8 set_time; /* RTC + 0x00 */
+ u8 hour_set; /* RTC + 0x01 */
+ u8 minute_set; /* RTC + 0x02 */
+ u8 second_set; /* RTC + 0x03 */
+
+ u8 set_date; /* RTC + 0x04 */
+ u8 month_set; /* RTC + 0x05 */
+ u8 weekday_set; /* RTC + 0x06 */
+ u8 date_set; /* RTC + 0x07 */
+
+ u8 write_sw; /* RTC + 0x08 */
+ u8 sw_set; /* RTC + 0x09 */
+ u16 year_set; /* RTC + 0x0a */
+
+ u8 alm_enable; /* RTC + 0x0c */
+ u8 alm_hour_set; /* RTC + 0x0d */
+ u8 alm_min_set; /* RTC + 0x0e */
+ u8 int_enable; /* RTC + 0x0f */
+
+ u8 reserved1;
+ u8 hour; /* RTC + 0x11 */
+ u8 minute; /* RTC + 0x12 */
+ u8 second; /* RTC + 0x13 */
+
+ u8 month; /* RTC + 0x14 */
+ u8 wday_mday; /* RTC + 0x15 */
+ u16 year; /* RTC + 0x16 */
+
+ u8 int_alm; /* RTC + 0x18 */
+ u8 int_sw; /* RTC + 0x19 */
+ u8 alm_status; /* RTC + 0x1a */
+ u8 sw_minute; /* RTC + 0x1b */
+
+ u8 bus_error_1; /* RTC + 0x1c */
+ u8 int_day; /* RTC + 0x1d */
+ u8 int_min; /* RTC + 0x1e */
+ u8 int_sec; /* RTC + 0x1f */
+
+ /*
+ * target_time:
+ * intended to be used for hibernation but hibernation
+ * does not work on silicon rev 1.5 so use it for non-volatile
+ * storage of offset between the actual_time register and linux
+ * time
+ */
+ u32 target_time; /* RTC + 0x20 */
+ /*
+ * actual_time:
+ * readonly time since VBAT_RTC was last connected
+ */
+ u32 actual_time; /* RTC + 0x24 */
+ u32 keep_alive; /* RTC + 0x28 */
+};
+
+struct mpc5121_rtc_data {
+ unsigned irq;
+ unsigned irq_periodic;
+ struct mpc5121_rtc_regs __iomem *regs;
+ struct rtc_device *rtc;
+ struct rtc_wkalrm wkalarm;
+};
+
+/*
+ * Update second/minute/hour registers.
+ *
+ * This is just so alarm will work.
+ */
+static void mpc5121_rtc_update_smh(struct mpc5121_rtc_regs __iomem *regs,
+ struct rtc_time *tm)
+{
+ out_8(&regs->second_set, tm->tm_sec);
+ out_8(&regs->minute_set, tm->tm_min);
+ out_8(&regs->hour_set, tm->tm_hour);
+
+ /* set time sequence */
+ out_8(&regs->set_time, 0x1);
+ out_8(&regs->set_time, 0x3);
+ out_8(&regs->set_time, 0x1);
+ out_8(&regs->set_time, 0x0);
+}
+
+static int mpc5121_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
+ struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+ unsigned long now;
+
+ /*
+ * linux time is actual_time plus the offset saved in target_time
+ */
+ now = in_be32(&regs->actual_time) + in_be32(&regs->target_time);
+
+ rtc_time_to_tm(now, tm);
+
+ /*
+ * update second minute hour registers
+ * so alarms will work
+ */
+ mpc5121_rtc_update_smh(regs, tm);
+
+ return rtc_valid_tm(tm);
+}
+
+static int mpc5121_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
+ struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+ int ret;
+ unsigned long now;
+
+ /*
+ * The actual_time register is read only so we write the offset
+ * between it and linux time to the target_time register.
+ */
+ ret = rtc_tm_to_time(tm, &now);
+ if (ret == 0)
+ out_be32(&regs->target_time, now - in_be32(&regs->actual_time));
+
+ /*
+ * update second minute hour registers
+ * so alarms will work
+ */
+ mpc5121_rtc_update_smh(regs, tm);
+
+ return 0;
+}
+
+static int mpc5121_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+ struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
+ struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+
+ *alarm = rtc->wkalarm;
+
+ alarm->pending = in_8(&regs->alm_status);
+
+ return 0;
+}
+
+static int mpc5121_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+ struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
+ struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+
+ /*
+ * the alarm has no seconds so deal with it
+ */
+ if (alarm->time.tm_sec) {
+ alarm->time.tm_sec = 0;
+ alarm->time.tm_min++;
+ if (alarm->time.tm_min >= 60) {
+ alarm->time.tm_min = 0;
+ alarm->time.tm_hour++;
+ if (alarm->time.tm_hour >= 24)
+ alarm->time.tm_hour = 0;
+ }
+ }
+
+ alarm->time.tm_mday = -1;
+ alarm->time.tm_mon = -1;
+ alarm->time.tm_year = -1;
+
+ out_8(&regs->alm_min_set, alarm->time.tm_min);
+ out_8(&regs->alm_hour_set, alarm->time.tm_hour);
+
+ out_8(&regs->alm_enable, alarm->enabled);
+
+ rtc->wkalarm = *alarm;
+ return 0;
+}
+
+static irqreturn_t mpc5121_rtc_handler(int irq, void *dev)
+{
+ struct mpc5121_rtc_data *rtc = dev_get_drvdata((struct device *)dev);
+ struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+
+ if (in_8(&regs->int_alm)) {
+ /* acknowledge and clear status */
+ out_8(&regs->int_alm, 1);
+ out_8(&regs->alm_status, 1);
+
+ rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static irqreturn_t mpc5121_rtc_handler_upd(int irq, void *dev)
+{
+ struct mpc5121_rtc_data *rtc = dev_get_drvdata((struct device *)dev);
+ struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+
+ if (in_8(&regs->int_sec) && (in_8(&regs->int_enable) & 0x1)) {
+ /* acknowledge */
+ out_8(&regs->int_sec, 1);
+
+ rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_UF);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static int mpc5121_rtc_alarm_irq_enable(struct device *dev,
+ unsigned int enabled)
+{
+ struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
+ struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+ int val;
+
+ if (enabled)
+ val = 1;
+ else
+ val = 0;
+
+ out_8(&regs->alm_enable, val);
+ rtc->wkalarm.enabled = val;
+
+ return 0;
+}
+
+static int mpc5121_rtc_update_irq_enable(struct device *dev,
+ unsigned int enabled)
+{
+ struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
+ struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+ int val;
+
+ val = in_8(&regs->int_enable);
+
+ if (enabled)
+ val = (val & ~0x8) | 0x1;
+ else
+ val &= ~0x1;
+
+ out_8(&regs->int_enable, val);
+
+ return 0;
+}
+
+static const struct rtc_class_ops mpc5121_rtc_ops = {
+ .read_time = mpc5121_rtc_read_time,
+ .set_time = mpc5121_rtc_set_time,
+ .read_alarm = mpc5121_rtc_read_alarm,
+ .set_alarm = mpc5121_rtc_set_alarm,
+ .alarm_irq_enable = mpc5121_rtc_alarm_irq_enable,
+ .update_irq_enable = mpc5121_rtc_update_irq_enable,
+};
+
+static int __devinit mpc5121_rtc_probe(struct of_device *op,
+ const struct of_device_id *match)
+{
+ struct mpc5121_rtc_data *rtc;
+ int err = 0;
+ u32 ka;
+
+ rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
+ if (!rtc)
+ return -ENOMEM;
+
+ rtc->regs = of_iomap(op->node, 0);
+ if (!rtc->regs) {
+ dev_err(&op->dev, "%s: couldn't map io space\n", __func__);
+ err = -ENOSYS;
+ goto out_free;
+ }
+
+ device_init_wakeup(&op->dev, 1);
+
+ dev_set_drvdata(&op->dev, rtc);
+
+ rtc->irq = irq_of_parse_and_map(op->node, 1);
+ err = request_irq(rtc->irq, mpc5121_rtc_handler, IRQF_DISABLED,
+ "mpc5121-rtc", &op->dev);
+ if (err) {
+ dev_err(&op->dev, "%s: could not request irq: %i\n",
+ __func__, rtc->irq);
+ goto out_dispose;
+ }
+
+ rtc->irq_periodic = irq_of_parse_and_map(op->node, 0);
+ err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd,
+ IRQF_DISABLED, "mpc5121-rtc_upd", &op->dev);
+ if (err) {
+ dev_err(&op->dev, "%s: could not request irq: %i\n",
+ __func__, rtc->irq_periodic);
+ goto out_dispose2;
+ }
+
+ ka = in_be32(&rtc->regs->keep_alive);
+ if (ka & 0x02) {
+ dev_warn(&op->dev,
+ "mpc5121-rtc: Battery or oscillator failure!\n");
+ out_be32(&rtc->regs->keep_alive, ka);
+ }
+
+ rtc->rtc = rtc_device_register("mpc5121-rtc", &op->dev,
+ &mpc5121_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc->rtc)) {
+ err = PTR_ERR(rtc->rtc);
+ goto out_free_irq;
+ }
+
+ return 0;
+
+out_free_irq:
+ free_irq(rtc->irq_periodic, &op->dev);
+out_dispose2:
+ irq_dispose_mapping(rtc->irq_periodic);
+ free_irq(rtc->irq, &op->dev);
+out_dispose:
+ irq_dispose_mapping(rtc->irq);
+ iounmap(rtc->regs);
+out_free:
+ kfree(rtc);
+
+ return err;
+}
+
+static int __devexit mpc5121_rtc_remove(struct of_device *op)
+{
+ struct mpc5121_rtc_data *rtc = dev_get_drvdata(&op->dev);
+ struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
+
+ /* disable interrupt, so there are no nasty surprises */
+ out_8(&regs->alm_enable, 0);
+ out_8(&regs->int_enable, in_8(&regs->int_enable) & ~0x1);
+
+ rtc_device_unregister(rtc->rtc);
+ iounmap(rtc->regs);
+ free_irq(rtc->irq, &op->dev);
+ free_irq(rtc->irq_periodic, &op->dev);
+ irq_dispose_mapping(rtc->irq);
+ irq_dispose_mapping(rtc->irq_periodic);
+ dev_set_drvdata(&op->dev, NULL);
+ kfree(rtc);
+
+ return 0;
+}
+
+static struct of_device_id mpc5121_rtc_match[] __devinitdata = {
+ { .compatible = "fsl,mpc5121-rtc", },
+ {},
+};
+
+static struct of_platform_driver mpc5121_rtc_driver = {
+ .owner = THIS_MODULE,
+ .name = "mpc5121-rtc",
+ .match_table = mpc5121_rtc_match,
+ .probe = mpc5121_rtc_probe,
+ .remove = __devexit_p(mpc5121_rtc_remove),
+};
+
+static int __init mpc5121_rtc_init(void)
+{
+ return of_register_platform_driver(&mpc5121_rtc_driver);
+}
+module_init(mpc5121_rtc_init);
+
+static void __exit mpc5121_rtc_exit(void)
+{
+ of_unregister_platform_driver(&mpc5121_rtc_driver);
+}
+module_exit(mpc5121_rtc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Rigby <jcrigby@gmail.com>");
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 7ce9e9f567a..3119fddaedb 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -74,6 +74,7 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/clk.h>
#include <asm/mpc52xx.h>
#include <asm/mpc52xx_psc.h>
@@ -113,6 +114,7 @@ static void mpc52xx_uart_of_enumerate(void);
/* Forward declaration of the interruption handling routine */
static irqreturn_t mpc52xx_uart_int(int irq, void *dev_id);
+static irqreturn_t mpc5xxx_uart_process_int(struct uart_port *port);
/* Simple macro to test if a port is console or not. This one is taken
@@ -145,6 +147,11 @@ struct psc_ops {
void (*cw_disable_ints)(struct uart_port *port);
void (*cw_restore_ints)(struct uart_port *port);
unsigned long (*getuartclk)(void *p);
+ int (*clock)(struct uart_port *port, int enable);
+ int (*fifoc_init)(void);
+ void (*fifoc_uninit)(void);
+ void (*get_irq)(struct uart_port *, struct device_node *);
+ irqreturn_t (*handle_irq)(struct uart_port *port);
};
#ifdef CONFIG_PPC_MPC52xx
@@ -256,6 +263,18 @@ static unsigned long mpc52xx_getuartclk(void *p)
return mpc5xxx_get_bus_frequency(p) / 2;
}
+static void mpc52xx_psc_get_irq(struct uart_port *port, struct device_node *np)
+{
+ port->irqflags = IRQF_DISABLED;
+ port->irq = irq_of_parse_and_map(np, 0);
+}
+
+/* 52xx specific interrupt handler. The caller holds the port lock */
+static irqreturn_t mpc52xx_psc_handle_irq(struct uart_port *port)
+{
+ return mpc5xxx_uart_process_int(port);
+}
+
static struct psc_ops mpc52xx_psc_ops = {
.fifo_init = mpc52xx_psc_fifo_init,
.raw_rx_rdy = mpc52xx_psc_raw_rx_rdy,
@@ -273,14 +292,32 @@ static struct psc_ops mpc52xx_psc_ops = {
.cw_disable_ints = mpc52xx_psc_cw_disable_ints,
.cw_restore_ints = mpc52xx_psc_cw_restore_ints,
.getuartclk = mpc52xx_getuartclk,
+ .get_irq = mpc52xx_psc_get_irq,
+ .handle_irq = mpc52xx_psc_handle_irq,
};
#endif /* CONFIG_MPC52xx */
#ifdef CONFIG_PPC_MPC512x
#define FIFO_512x(port) ((struct mpc512x_psc_fifo __iomem *)(PSC(port)+1))
+
+/* PSC FIFO Controller for mpc512x */
+struct psc_fifoc {
+ u32 fifoc_cmd;
+ u32 fifoc_int;
+ u32 fifoc_dma;
+ u32 fifoc_axe;
+ u32 fifoc_debug;
+};
+
+static struct psc_fifoc __iomem *psc_fifoc;
+static unsigned int psc_fifoc_irq;
+
static void mpc512x_psc_fifo_init(struct uart_port *port)
{
+ /* /32 prescaler */
+ out_be16(&PSC(port)->mpc52xx_psc_clock_select, 0xdd00);
+
out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_RESET_SLICE);
out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_ENABLE_SLICE);
out_be32(&FIFO_512x(port)->txalarm, 1);
@@ -393,6 +430,160 @@ static unsigned long mpc512x_getuartclk(void *p)
return mpc5xxx_get_bus_frequency(p);
}
+#define DEFAULT_FIFO_SIZE 16
+
+static unsigned int __init get_fifo_size(struct device_node *np,
+ char *fifo_name)
+{
+ const unsigned int *fp;
+
+ fp = of_get_property(np, fifo_name, NULL);
+ if (fp)
+ return *fp;
+
+ pr_warning("no %s property in %s node, defaulting to %d\n",
+ fifo_name, np->full_name, DEFAULT_FIFO_SIZE);
+
+ return DEFAULT_FIFO_SIZE;
+}
+
+#define FIFOC(_base) ((struct mpc512x_psc_fifo __iomem *) \
+ ((u32)(_base) + sizeof(struct mpc52xx_psc)))
+
+/* Init PSC FIFO Controller */
+static int __init mpc512x_psc_fifoc_init(void)
+{
+ struct device_node *np;
+ void __iomem *psc;
+ unsigned int tx_fifo_size;
+ unsigned int rx_fifo_size;
+ int fifobase = 0; /* current fifo address in 32 bit words */
+
+ np = of_find_compatible_node(NULL, NULL,
+ "fsl,mpc5121-psc-fifo");
+ if (!np) {
+ pr_err("%s: Can't find FIFOC node\n", __func__);
+ return -ENODEV;
+ }
+
+ psc_fifoc = of_iomap(np, 0);
+ if (!psc_fifoc) {
+ pr_err("%s: Can't map FIFOC\n", __func__);
+ return -ENODEV;
+ }
+
+ psc_fifoc_irq = irq_of_parse_and_map(np, 0);
+ of_node_put(np);
+ if (psc_fifoc_irq == NO_IRQ) {
+ pr_err("%s: Can't get FIFOC irq\n", __func__);
+ iounmap(psc_fifoc);
+ return -ENODEV;
+ }
+
+ for_each_compatible_node(np, NULL, "fsl,mpc5121-psc-uart") {
+ tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size");
+ rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size");
+
+ /* size in register is in 4 byte units */
+ tx_fifo_size /= 4;
+ rx_fifo_size /= 4;
+ if (!tx_fifo_size)
+ tx_fifo_size = 1;
+ if (!rx_fifo_size)
+ rx_fifo_size = 1;
+
+ psc = of_iomap(np, 0);
+ if (!psc) {
+ pr_err("%s: Can't map %s device\n",
+ __func__, np->full_name);
+ continue;
+ }
+
+ /* FIFO space is 4KiB, check if requested size is available */
+ if ((fifobase + tx_fifo_size + rx_fifo_size) > 0x1000) {
+ pr_err("%s: no fifo space available for %s\n",
+ __func__, np->full_name);
+ iounmap(psc);
+ /*
+ * chances are that another device requests less
+ * fifo space, so we continue.
+ */
+ continue;
+ }
+ /* set tx and rx fifo size registers */
+ out_be32(&FIFOC(psc)->txsz, (fifobase << 16) | tx_fifo_size);
+ fifobase += tx_fifo_size;
+ out_be32(&FIFOC(psc)->rxsz, (fifobase << 16) | rx_fifo_size);
+ fifobase += rx_fifo_size;
+
+ /* reset and enable the slices */
+ out_be32(&FIFOC(psc)->txcmd, 0x80);
+ out_be32(&FIFOC(psc)->txcmd, 0x01);
+ out_be32(&FIFOC(psc)->rxcmd, 0x80);
+ out_be32(&FIFOC(psc)->rxcmd, 0x01);
+
+ iounmap(psc);
+ }
+
+ return 0;
+}
+
+static void __exit mpc512x_psc_fifoc_uninit(void)
+{
+ iounmap(psc_fifoc);
+}
+
+/* 512x specific interrupt handler. The caller holds the port lock */
+static irqreturn_t mpc512x_psc_handle_irq(struct uart_port *port)
+{
+ unsigned long fifoc_int;
+ int psc_num;
+
+ /* Read pending PSC FIFOC interrupts */
+ fifoc_int = in_be32(&psc_fifoc->fifoc_int);
+
+ /* Check if it is an interrupt for this port */
+ psc_num = (port->mapbase & 0xf00) >> 8;
+ if (test_bit(psc_num, &fifoc_int) ||
+ test_bit(psc_num + 16, &fifoc_int))
+ return mpc5xxx_uart_process_int(port);
+
+ return IRQ_NONE;
+}
+
+static int mpc512x_psc_clock(struct uart_port *port, int enable)
+{
+ struct clk *psc_clk;
+ int psc_num;
+ char clk_name[10];
+
+ if (uart_console(port))
+ return 0;
+
+ psc_num = (port->mapbase & 0xf00) >> 8;
+ snprintf(clk_name, sizeof(clk_name), "psc%d_clk", psc_num);
+ psc_clk = clk_get(port->dev, clk_name);
+ if (IS_ERR(psc_clk)) {
+ dev_err(port->dev, "Failed to get PSC clock entry!\n");
+ return -ENODEV;
+ }
+
+ dev_dbg(port->dev, "%s %sable\n", clk_name, enable ? "en" : "dis");
+
+ if (enable)
+ clk_enable(psc_clk);
+ else
+ clk_disable(psc_clk);
+
+ return 0;
+}
+
+static void mpc512x_psc_get_irq(struct uart_port *port, struct device_node *np)
+{
+ port->irqflags = IRQF_SHARED;
+ port->irq = psc_fifoc_irq;
+}
+
static struct psc_ops mpc512x_psc_ops = {
.fifo_init = mpc512x_psc_fifo_init,
.raw_rx_rdy = mpc512x_psc_raw_rx_rdy,
@@ -410,6 +601,11 @@ static struct psc_ops mpc512x_psc_ops = {
.cw_disable_ints = mpc512x_psc_cw_disable_ints,
.cw_restore_ints = mpc512x_psc_cw_restore_ints,
.getuartclk = mpc512x_getuartclk,
+ .clock = mpc512x_psc_clock,
+ .fifoc_init = mpc512x_psc_fifoc_init,
+ .fifoc_uninit = mpc512x_psc_fifoc_uninit,
+ .get_irq = mpc512x_psc_get_irq,
+ .handle_irq = mpc512x_psc_handle_irq,
};
#endif
@@ -519,10 +715,15 @@ mpc52xx_uart_startup(struct uart_port *port)
struct mpc52xx_psc __iomem *psc = PSC(port);
int ret;
+ if (psc_ops->clock) {
+ ret = psc_ops->clock(port, 1);
+ if (ret)
+ return ret;
+ }
+
/* Request IRQ */
ret = request_irq(port->irq, mpc52xx_uart_int,
- IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
- "mpc52xx_psc_uart", port);
+ port->irqflags, "mpc52xx_psc_uart", port);
if (ret)
return ret;
@@ -553,6 +754,9 @@ mpc52xx_uart_shutdown(struct uart_port *port)
port->read_status_mask = 0;
out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
+ if (psc_ops->clock)
+ psc_ops->clock(port, 0);
+
/* Release interrupt */
free_irq(port->irq, port);
}
@@ -851,15 +1055,12 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
}
static irqreturn_t
-mpc52xx_uart_int(int irq, void *dev_id)
+mpc5xxx_uart_process_int(struct uart_port *port)
{
- struct uart_port *port = dev_id;
unsigned long pass = ISR_PASS_LIMIT;
unsigned int keepgoing;
u8 status;
- spin_lock(&port->lock);
-
/* While we have stuff to do, we continue */
do {
/* If we don't find anything to do, we stop */
@@ -886,11 +1087,23 @@ mpc52xx_uart_int(int irq, void *dev_id)
} while (keepgoing);
- spin_unlock(&port->lock);
-
return IRQ_HANDLED;
}
+static irqreturn_t
+mpc52xx_uart_int(int irq, void *dev_id)
+{
+ struct uart_port *port = dev_id;
+ irqreturn_t ret;
+
+ spin_lock(&port->lock);
+
+ ret = psc_ops->handle_irq(port);
+
+ spin_unlock(&port->lock);
+
+ return ret;
+}
/* ======================================================================== */
/* Console ( if applicable ) */
@@ -1152,7 +1365,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
return -EINVAL;
}
- port->irq = irq_of_parse_and_map(op->node, 0);
+ psc_ops->get_irq(port, op->node);
if (port->irq == NO_IRQ) {
dev_dbg(&op->dev, "Could not get irq\n");
return -EINVAL;
@@ -1163,10 +1376,8 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
/* Add the port to the uart sub-system */
ret = uart_add_one_port(&mpc52xx_uart_driver, port);
- if (ret) {
- irq_dispose_mapping(port->irq);
+ if (ret)
return ret;
- }
dev_set_drvdata(&op->dev, (void *)port);
return 0;
@@ -1178,10 +1389,8 @@ mpc52xx_uart_of_remove(struct of_device *op)
struct uart_port *port = dev_get_drvdata(&op->dev);
dev_set_drvdata(&op->dev, NULL);
- if (port) {
+ if (port)
uart_remove_one_port(&mpc52xx_uart_driver, port);
- irq_dispose_mapping(port->irq);
- }
return 0;
}
@@ -1288,6 +1497,15 @@ mpc52xx_uart_init(void)
mpc52xx_uart_of_enumerate();
+ /*
+ * Map the PSC FIFO Controller and init if on MPC512x.
+ */
+ if (psc_ops->fifoc_init) {
+ ret = psc_ops->fifoc_init();
+ if (ret)
+ return ret;
+ }
+
ret = of_register_platform_driver(&mpc52xx_uart_of_driver);
if (ret) {
printk(KERN_ERR "%s: of_register_platform_driver failed (%i)\n",
@@ -1302,6 +1520,9 @@ mpc52xx_uart_init(void)
static void __exit
mpc52xx_uart_exit(void)
{
+ if (psc_ops->fifoc_uninit)
+ psc_ops->fifoc_uninit();
+
of_unregister_platform_driver(&mpc52xx_uart_of_driver);
uart_unregister_driver(&mpc52xx_uart_driver);
}
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 95421fa3b30..e91db4b3801 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -696,11 +696,11 @@ static int serial_config(struct pcmcia_device * link)
info->multi = info->quirk->multi;
if (info->multi > 1)
- multi_config(link);
+ i = multi_config(link);
else
- simple_config(link);
+ i = simple_config(link);
- if (info->ndev == 0)
+ if (i || info->ndev == 0)
goto failed;
/*
@@ -715,6 +715,7 @@ static int serial_config(struct pcmcia_device * link)
return 0;
failed:
+ dev_warn(&link->dev, "serial_cs: failed to initialize\n");
serial_remove(link);
return -ENODEV;
}
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 72d68b3dc47..4637bcbe03a 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -1633,6 +1633,11 @@ static int __init fsl_diu_setup(char *options)
#endif
static struct of_device_id fsl_diu_match[] = {
+#ifdef CONFIG_PPC_MPC512x
+ {
+ .compatible = "fsl,mpc5121-diu",
+ },
+#endif
{
.compatible = "fsl,diu",
},
diff --git a/include/linux/lmb.h b/include/linux/lmb.h
index ef82b8fcbdd..f3d14333ebe 100644
--- a/include/linux/lmb.h
+++ b/include/linux/lmb.h
@@ -42,6 +42,7 @@ extern void __init lmb_init(void);
extern void __init lmb_analyze(void);
extern long lmb_add(u64 base, u64 size);
extern long lmb_remove(u64 base, u64 size);
+extern long __init lmb_free(u64 base, u64 size);
extern long __init lmb_reserve(u64 base, u64 size);
extern u64 __init lmb_alloc_nid(u64 size, u64 align, int nid,
u64 (*nid_range)(u64, u64, int *));
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index ee148573c11..d57847f2f6c 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -40,7 +40,7 @@ struct net_device;
* Documentation/pcmcia/driver.txt for details.
*/
struct pcmcia_dynids {
- spinlock_t lock;
+ struct mutex lock;
struct list_head list;
};
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index cbfba885eb8..32896a77391 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -134,9 +134,9 @@ struct pccard_operations {
struct pcmcia_socket {
struct module *owner;
- spinlock_t lock;
socket_state_t socket;
u_int state;
+ u_int suspended_state; /* state before suspend */
u_short functions;
u_short lock_count;
pccard_mem_map cis_mem;
@@ -200,9 +200,14 @@ struct pcmcia_socket {
struct task_struct *thread;
struct completion thread_done;
unsigned int thread_events;
- /* protects socket h/w state */
+ unsigned int sysfs_events;
+
+ /* For the non-trivial interaction between these locks,
+ * see Documentation/pcmcia/locking.txt */
struct mutex skt_mutex;
- /* protects thread_events */
+ struct mutex ops_mutex;
+
+ /* protects thread_events and sysfs_events */
spinlock_t thread_lock;
/* pcmcia (16-bit) */
@@ -225,30 +230,19 @@ struct pcmcia_socket {
u8 busy:1;
/* pcmcia module is being unloaded */
u8 dead:1;
- /* a multifunction-device add event is pending */
- u8 device_add_pending:1;
- /* the pending event adds a mfc (1) or pfc (0) */
- u8 mfc_pfc:1;
+ /* the PCMCIA card consists of two pseudo devices */
+ u8 has_pfc:1;
- u8 reserved:3;
+ u8 reserved:4;
} pcmcia_state;
- /* for adding further pseudo-multifunction devices */
- struct work_struct device_add;
-
#ifdef CONFIG_PCMCIA_IOCTL
struct user_info_t *user;
wait_queue_head_t queue;
#endif /* CONFIG_PCMCIA_IOCTL */
#endif /* CONFIG_PCMCIA */
- /* cardbus (32-bit) */
-#ifdef CONFIG_CARDBUS
- struct resource *cb_cis_res;
- void __iomem *cb_cis_virt;
-#endif /* CONFIG_CARDBUS */
-
/* socket device */
struct device dev;
/* data internal to the socket driver */
@@ -263,13 +257,25 @@ struct pcmcia_socket {
* - pccard_static_ops iomem and ioport areas are assigned statically
* - pccard_iodyn_ops iomem areas is assigned statically, ioport
* areas dynamically
+ * If this option is selected, use
+ * "select PCCARD_IODYN" in Kconfig.
* - pccard_nonstatic_ops iomem and ioport areas are assigned dynamically.
* If this option is selected, use
* "select PCCARD_NONSTATIC" in Kconfig.
+ *
*/
extern struct pccard_resource_ops pccard_static_ops;
+#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
extern struct pccard_resource_ops pccard_iodyn_ops;
extern struct pccard_resource_ops pccard_nonstatic_ops;
+#else
+/* If PCMCIA is not used, but only CARDBUS, these functions are not used
+ * at all. Therefore, do not use the large (240K!) rsrc_nonstatic module
+ */
+#define pccard_iodyn_ops pccard_static_ops
+#define pccard_nonstatic_ops pccard_static_ops
+#endif
+
/* socket drivers are expected to use these callbacks in their .drv struct */
extern int pcmcia_socket_dev_suspend(struct device *dev);
diff --git a/lib/lmb.c b/lib/lmb.c
index 9cee17142b2..b1fc5260652 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -205,9 +205,8 @@ long lmb_add(u64 base, u64 size)
}
-long lmb_remove(u64 base, u64 size)
+static long __lmb_remove(struct lmb_region *rgn, u64 base, u64 size)
{
- struct lmb_region *rgn = &(lmb.memory);
u64 rgnbegin, rgnend;
u64 end = base + size;
int i;
@@ -254,6 +253,16 @@ long lmb_remove(u64 base, u64 size)
return lmb_add_region(rgn, end, rgnend - end);
}
+long lmb_remove(u64 base, u64 size)
+{
+ return __lmb_remove(&lmb.memory, base, size);
+}
+
+long __init lmb_free(u64 base, u64 size)
+{
+ return __lmb_remove(&lmb.reserved, base, size);
+}
+
long __init lmb_reserve(u64 base, u64 size)
{
struct lmb_region *_rgn = &lmb.reserved;
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 241310e59cd..208ad3b0ca5 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -13,8 +13,6 @@ use strict;
## This software falls under the GNU General Public License. ##
## Please read the COPYING file for more information ##
-# w.o. 03-11-2000: added the '-filelist' option.
-
# 18/01/2001 - Cleanups
# Functions prototyped as foo(void) same as foo()
# Stop eval'ing where we don't need to.
@@ -245,7 +243,7 @@ my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
# could cause "use of undefined value" or other bugs.
my ($function, %function_table, %parametertypes, $declaration_purpose);
my ($type, $declaration_name, $return_type);
-my ($newsection, $newcontents, $prototype, $filelist, $brcount, %source_map);
+my ($newsection, $newcontents, $prototype, $brcount, %source_map);
if (defined($ENV{'KBUILD_VERBOSE'})) {
$verbose = "$ENV{'KBUILD_VERBOSE'}";
@@ -338,8 +336,6 @@ while ($ARGV[0] =~ m/^-(.*)/) {
$verbose = 1;
} elsif (($cmd eq "-h") || ($cmd eq "--help")) {
usage();
- } elsif ($cmd eq '-filelist') {
- $filelist = shift @ARGV;
} elsif ($cmd eq '-no-doc-sections') {
$no_doc_sections = 1;
}
@@ -1811,14 +1807,6 @@ if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
close(SOURCE_MAP);
}
-if ($filelist) {
- open(FLIST,"<$filelist") or die "Can't open file list $filelist";
- while(<FLIST>) {
- chop;
- process_file($_);
- }
-}
-
foreach (@ARGV) {
chomp;
process_file($_);
@@ -2023,6 +2011,8 @@ sub process_file($) {
return;
}
+ $. = 1;
+
$section_counter = 0;
while (<IN>) {
if ($state == 0) {