提交 c548f08a 编写于 作者: L Linus Torvalds

Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc

* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (24 commits)
  [POWERPC] Fix vmemmap warning in init_64.c
  [POWERPC] Fix 64 bits vDSO DWARF info for CR register
  [POWERPC] Add 1TB workaround for PA6T
  [POWERPC] Enable NO_HZ and high res timers for pseries and ppc64 configs
  [POWERPC] Quieten cache information at boot
  [POWERPC] Quieten clockevent printk
  [POWERPC] Enable SLUB in *_defconfig
  [POWERPC] Fix 1TB segment detection
  [POWERPC] Fix iSeries_hpte_insert prototype
  [POWERPC] Fix copyright symbol
  [POWERPC] ibmebus: Move to of_device and of_platform_driver, match eHCA and eHEA drivers
  [POWERPC] ibmebus: Add device creation and bus probing based on of_device
  [POWERPC] ibmebus: Remove bus match/probe/remove functions
  [POWERPC] Move of_device allocation into of_device.[ch]
  [POWERPC] mpc52xx: device tree changes for FEC and MDIO
  [POWERPC] bestcomm: GenBD task support
  [POWERPC] bestcomm: FEC task support
  [POWERPC] bestcomm: ATA task support
  [POWERPC] bestcomm: core bestcomm support for Freescale MPC5200
  [POWERPC] mpc52xx: Update mpc52xx_psc structure with B revision changes
  ...
......@@ -698,3 +698,7 @@ source "crypto/Kconfig"
config PPC_CLOCK
bool
default n
config PPC_LIB_RHEAP
bool
......@@ -277,10 +277,26 @@
ethernet@3000 {
device_type = "network";
compatible = "mpc5200b-fec","mpc5200-fec";
reg = <3000 800>;
reg = <3000 400>;
mac-address = [ 02 03 04 05 06 07 ]; // Bad!
interrupts = <2 5 0>;
interrupt-parent = <&mpc5200_pic>;
phy-handle = <&phy0>;
};
mdio@3000 {
#address-cells = <1>;
#size-cells = <0>;
device_type = "mdio";
compatible = "mpc5200b-fec-phy";
reg = <3000 400>; // fec range, since we need to setup fec interrupts
interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
interrupt-parent = <&mpc5200_pic>;
phy0:ethernet-phy@0 {
device_type = "ethernet-phy";
reg = <0>;
};
};
ata@3a00 {
......
......@@ -91,8 +91,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -695,7 +696,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -92,8 +92,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -1218,7 +1219,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -92,8 +92,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -1373,7 +1374,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -90,8 +90,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -773,7 +774,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -92,8 +92,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -1580,7 +1581,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -88,8 +88,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -909,7 +910,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -93,8 +93,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -1056,7 +1057,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -91,8 +91,9 @@ CONFIG_SIGNALFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -700,7 +701,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -89,8 +89,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -1459,7 +1460,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -816,7 +817,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -90,8 +90,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -1095,8 +1096,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
CONFIG_DEBUG_SLAB=y
# CONFIG_DEBUG_SLAB_LEAK is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......
......@@ -85,8 +85,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -867,7 +868,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -1272,7 +1273,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......
......@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......
......@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......
......@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......
......@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......
......@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......
......@@ -90,8 +90,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -704,7 +705,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -93,8 +93,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -1427,7 +1428,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -94,8 +94,9 @@ CONFIG_SIGNALFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -791,7 +792,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -88,8 +88,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -949,7 +950,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -93,8 +93,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -1427,7 +1428,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -90,8 +90,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -832,7 +833,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -88,8 +88,9 @@ CONFIG_SIGNALFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -993,7 +994,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -94,8 +94,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -1432,7 +1433,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -83,8 +83,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......
......@@ -90,8 +90,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -1588,7 +1589,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -91,8 +91,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -1829,7 +1830,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -96,8 +96,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -216,6 +217,10 @@ CONFIG_AXON_RAM=m
#
# Kernel options
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
......@@ -1750,7 +1755,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -86,8 +86,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -930,7 +931,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -89,8 +89,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......
......@@ -91,8 +91,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -1059,7 +1060,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
CONFIG_DEBUG_SPINLOCK=y
......
......@@ -96,8 +96,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -176,6 +177,10 @@ CONFIG_IBMEBUS=y
#
# Kernel options
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
......@@ -1504,7 +1509,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -91,8 +91,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -781,7 +782,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
......@@ -706,7 +707,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
......
......@@ -408,6 +408,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_1T_SEGMENT)
std r7,SLBSHADOW_STACKVSID(r9) /* Save VSID */
std r0,SLBSHADOW_STACKESID(r9) /* Save ESID */
/* No need to check for CPU_FTR_NO_SLBIE_B here, since when
* we have 1TB segments, the only CPUs known to have the errata
* only support less than 1TB of system memory and we'll never
* actually hit this code path.
*/
slbie r6
slbie r6 /* Workaround POWER5 < DD2.1 issue */
slbmte r7,r0
......
......@@ -41,6 +41,7 @@
#include <linux/kobject.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/of_platform.h>
#include <asm/ibmebus.h>
#include <asm/abs_addr.h>
......@@ -50,6 +51,13 @@ static struct device ibmebus_bus_device = { /* fake "parent" device */
struct bus_type ibmebus_bus_type;
/* These devices will automatically be added to the bus during init */
static struct of_device_id builtin_matches[] = {
{ .compatible = "IBM,lhca" },
{ .compatible = "IBM,lhea" },
{},
};
static void *ibmebus_alloc_coherent(struct device *dev,
size_t size,
dma_addr_t *dma_handle,
......@@ -124,190 +132,87 @@ static struct dma_mapping_ops ibmebus_dma_ops = {
.dma_supported = ibmebus_dma_supported,
};
static int ibmebus_bus_probe(struct device *dev)
static int ibmebus_match_path(struct device *dev, void *data)
{
struct ibmebus_dev *ibmebusdev = to_ibmebus_dev(dev);
struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver);
const struct of_device_id *id;
int error = -ENODEV;
if (!ibmebusdrv->probe)
return error;
id = of_match_device(ibmebusdrv->id_table, &ibmebusdev->ofdev);
if (id) {
error = ibmebusdrv->probe(ibmebusdev, id);
}
return error;
struct device_node *dn = to_of_device(dev)->node;
return (dn->full_name &&
(strcasecmp((char *)data, dn->full_name) == 0));
}
static int ibmebus_bus_remove(struct device *dev)
static int ibmebus_match_node(struct device *dev, void *data)
{
struct ibmebus_dev *ibmebusdev = to_ibmebus_dev(dev);
struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver);
if (ibmebusdrv->remove) {
return ibmebusdrv->remove(ibmebusdev);
}
return 0;
return to_of_device(dev)->node == data;
}
static void __devinit ibmebus_dev_release(struct device *dev)
static int ibmebus_create_device(struct device_node *dn)
{
of_node_put(to_ibmebus_dev(dev)->ofdev.node);
kfree(to_ibmebus_dev(dev));
}
static int __devinit ibmebus_register_device_common(
struct ibmebus_dev *dev, const char *name)
{
int err = 0;
dev->ofdev.dev.parent = &ibmebus_bus_device;
dev->ofdev.dev.bus = &ibmebus_bus_type;
dev->ofdev.dev.release = ibmebus_dev_release;
struct of_device *dev;
int ret;
dev->ofdev.dev.archdata.of_node = dev->ofdev.node;
dev->ofdev.dev.archdata.dma_ops = &ibmebus_dma_ops;
dev->ofdev.dev.archdata.numa_node = of_node_to_nid(dev->ofdev.node);
/* An ibmebusdev is based on a of_device. We have to change the
* bus type to use our own DMA mapping operations.
*/
if ((err = of_device_register(&dev->ofdev)) != 0) {
printk(KERN_ERR "%s: failed to register device (%d).\n",
__FUNCTION__, err);
return -ENODEV;
}
return 0;
}
static struct ibmebus_dev* __devinit ibmebus_register_device_node(
struct device_node *dn)
{
struct ibmebus_dev *dev;
int i, len, bus_len;
dev = kzalloc(sizeof(struct ibmebus_dev), GFP_KERNEL);
dev = of_device_alloc(dn, NULL, &ibmebus_bus_device);
if (!dev)
return ERR_PTR(-ENOMEM);
dev->ofdev.node = of_node_get(dn);
len = strlen(dn->full_name + 1);
bus_len = min(len, BUS_ID_SIZE - 1);
memcpy(dev->ofdev.dev.bus_id, dn->full_name + 1
+ (len - bus_len), bus_len);
for (i = 0; i < bus_len; i++)
if (dev->ofdev.dev.bus_id[i] == '/')
dev->ofdev.dev.bus_id[i] = '_';
/* Register with generic device framework. */
if (ibmebus_register_device_common(dev, dn->name) != 0) {
kfree(dev);
return ERR_PTR(-ENODEV);
}
return dev;
}
static void ibmebus_probe_of_nodes(char* name)
{
struct device_node *dn = NULL;
while ((dn = of_find_node_by_name(dn, name))) {
if (IS_ERR(ibmebus_register_device_node(dn))) {
of_node_put(dn);
return;
}
}
of_node_put(dn);
return -ENOMEM;
return;
}
dev->dev.bus = &ibmebus_bus_type;
dev->dev.archdata.dma_ops = &ibmebus_dma_ops;
static void ibmebus_add_devices_by_id(struct of_device_id *idt)
{
while (strlen(idt->name) > 0) {
ibmebus_probe_of_nodes(idt->name);
idt++;
ret = of_device_register(dev);
if (ret) {
of_device_free(dev);
return ret;
}
return;
}
static int ibmebus_match_name(struct device *dev, void *data)
{
const struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev);
const char *name;
name = of_get_property(ebus_dev->ofdev.node, "name", NULL);
if (name && (strcmp(data, name) == 0))
return 1;
return 0;
}
static int ibmebus_unregister_device(struct device *dev)
static int ibmebus_create_devices(const struct of_device_id *matches)
{
of_device_unregister(to_of_device(dev));
struct device_node *root, *child;
int ret = 0;
return 0;
}
root = of_find_node_by_path("/");
static void ibmebus_remove_devices_by_id(struct of_device_id *idt)
{
struct device *dev;
for (child = NULL; (child = of_get_next_child(root, child)); ) {
if (!of_match_node(matches, child))
continue;
while (strlen(idt->name) > 0) {
while ((dev = bus_find_device(&ibmebus_bus_type, NULL,
(void*)idt->name,
ibmebus_match_name))) {
ibmebus_unregister_device(dev);
if (bus_find_device(&ibmebus_bus_type, NULL, child,
ibmebus_match_node))
continue;
ret = ibmebus_create_device(child);
if (ret) {
printk(KERN_ERR "%s: failed to create device (%i)",
__FUNCTION__, ret);
of_node_put(child);
break;
}
idt++;
}
return;
of_node_put(root);
return ret;
}
int ibmebus_register_driver(struct ibmebus_driver *drv)
int ibmebus_register_driver(struct of_platform_driver *drv)
{
int err = 0;
/* If the driver uses devices that ibmebus doesn't know, add them */
ibmebus_create_devices(drv->match_table);
drv->driver.name = drv->name;
drv->driver.bus = &ibmebus_bus_type;
drv->driver.probe = ibmebus_bus_probe;
drv->driver.remove = ibmebus_bus_remove;
if ((err = driver_register(&drv->driver) != 0))
return err;
/* remove all supported devices first, in case someone
* probed them manually before registering the driver */
ibmebus_remove_devices_by_id(drv->id_table);
ibmebus_add_devices_by_id(drv->id_table);
return 0;
return driver_register(&drv->driver);
}
EXPORT_SYMBOL(ibmebus_register_driver);
void ibmebus_unregister_driver(struct ibmebus_driver *drv)
void ibmebus_unregister_driver(struct of_platform_driver *drv)
{
driver_unregister(&drv->driver);
ibmebus_remove_devices_by_id(drv->id_table);
}
EXPORT_SYMBOL(ibmebus_unregister_driver);
int ibmebus_request_irq(struct ibmebus_dev *dev,
u32 ist,
irq_handler_t handler,
unsigned long irq_flags, const char * devname,
int ibmebus_request_irq(u32 ist, irq_handler_t handler,
unsigned long irq_flags, const char *devname,
void *dev_id)
{
unsigned int irq = irq_create_mapping(NULL, ist);
......@@ -315,12 +220,11 @@ int ibmebus_request_irq(struct ibmebus_dev *dev,
if (irq == NO_IRQ)
return -EINVAL;
return request_irq(irq, handler,
irq_flags, devname, dev_id);
return request_irq(irq, handler, irq_flags, devname, dev_id);
}
EXPORT_SYMBOL(ibmebus_request_irq);
void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id)
void ibmebus_free_irq(u32 ist, void *dev_id)
{
unsigned int irq = irq_find_mapping(NULL, ist);
......@@ -328,29 +232,10 @@ void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id)
}
EXPORT_SYMBOL(ibmebus_free_irq);
static int ibmebus_bus_match(struct device *dev, struct device_driver *drv)
{
const struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev);
struct ibmebus_driver *ebus_drv = to_ibmebus_driver(drv);
const struct of_device_id *ids = ebus_drv->id_table;
const struct of_device_id *found_id;
if (!ids)
return 0;
found_id = of_match_device(ids, &ebus_dev->ofdev);
if (found_id)
return 1;
return 0;
}
static ssize_t name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev);
const char *name = of_get_property(ebus_dev->ofdev.node, "name", NULL);
return sprintf(buf, "%s\n", name);
return sprintf(buf, "%s\n", to_of_device(dev)->node->name);
}
static struct device_attribute ibmebus_dev_attrs[] = {
......@@ -358,18 +243,6 @@ static struct device_attribute ibmebus_dev_attrs[] = {
__ATTR_NULL
};
static int ibmebus_match_path(struct device *dev, void *data)
{
int rc;
struct device_node *dn =
of_node_get(to_ibmebus_dev(dev)->ofdev.node);
rc = (dn->full_name && (strcasecmp((char*)data, dn->full_name) == 0));
of_node_put(dn);
return rc;
}
static char *ibmebus_chomp(const char *in, size_t count)
{
char *out = kmalloc(count + 1, GFP_KERNEL);
......@@ -389,9 +262,8 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
const char *buf, size_t count)
{
struct device_node *dn = NULL;
struct ibmebus_dev *dev;
char *path;
ssize_t rc;
ssize_t rc = 0;
path = ibmebus_chomp(buf, count);
if (!path)
......@@ -406,9 +278,8 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
}
if ((dn = of_find_node_by_path(path))) {
dev = ibmebus_register_device_node(dn);
rc = ibmebus_create_device(dn);
of_node_put(dn);
rc = IS_ERR(dev) ? PTR_ERR(dev) : count;
} else {
printk(KERN_WARNING "%s: no such device node: %s\n",
__FUNCTION__, path);
......@@ -417,7 +288,9 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
out:
kfree(path);
return rc;
if (rc)
return rc;
return count;
}
static ssize_t ibmebus_store_remove(struct bus_type *bus,
......@@ -432,7 +305,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus,
if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path,
ibmebus_match_path))) {
ibmebus_unregister_device(dev);
of_device_unregister(to_of_device(dev));
kfree(path);
return count;
......@@ -452,8 +325,7 @@ static struct bus_attribute ibmebus_bus_attrs[] = {
};
struct bus_type ibmebus_bus_type = {
.name = "ibmebus",
.match = ibmebus_bus_match,
.uevent = of_device_uevent,
.dev_attrs = ibmebus_dev_attrs,
.bus_attrs = ibmebus_bus_attrs
};
......@@ -465,9 +337,9 @@ static int __init ibmebus_bus_init(void)
printk(KERN_INFO "IBM eBus Device Driver\n");
err = bus_register(&ibmebus_bus_type);
err = of_bus_type_init(&ibmebus_bus_type, "ibmebus");
if (err) {
printk(KERN_ERR ":%s: failed to register IBM eBus.\n",
printk(KERN_ERR "%s: failed to register IBM eBus.\n",
__FUNCTION__);
return err;
}
......@@ -481,6 +353,13 @@ static int __init ibmebus_bus_init(void)
return err;
}
err = ibmebus_create_devices(builtin_matches);
if (err) {
device_unregister(&ibmebus_bus_device);
bus_unregister(&ibmebus_bus_type);
return err;
}
return 0;
}
__initcall(ibmebus_bus_init);
postcore_initcall(ibmebus_bus_init);
......@@ -7,8 +7,88 @@
#include <linux/slab.h>
#include <asm/errno.h>
#include <asm/dcr.h>
#include <asm/of_device.h>
static void of_device_make_bus_id(struct of_device *dev)
{
static atomic_t bus_no_reg_magic;
struct device_node *node = dev->node;
char *name = dev->dev.bus_id;
const u32 *reg;
u64 addr;
int magic;
/*
* If it's a DCR based device, use 'd' for native DCRs
* and 'D' for MMIO DCRs.
*/
#ifdef CONFIG_PPC_DCR
reg = of_get_property(node, "dcr-reg", NULL);
if (reg) {
#ifdef CONFIG_PPC_DCR_NATIVE
snprintf(name, BUS_ID_SIZE, "d%x.%s",
*reg, node->name);
#else /* CONFIG_PPC_DCR_NATIVE */
addr = of_translate_dcr_address(node, *reg, NULL);
if (addr != OF_BAD_ADDR) {
snprintf(name, BUS_ID_SIZE,
"D%llx.%s", (unsigned long long)addr,
node->name);
return;
}
#endif /* !CONFIG_PPC_DCR_NATIVE */
}
#endif /* CONFIG_PPC_DCR */
/*
* For MMIO, get the physical address
*/
reg = of_get_property(node, "reg", NULL);
if (reg) {
addr = of_translate_address(node, reg);
if (addr != OF_BAD_ADDR) {
snprintf(name, BUS_ID_SIZE,
"%llx.%s", (unsigned long long)addr,
node->name);
return;
}
}
/*
* No BusID, use the node name and add a globally incremented
* counter (and pray...)
*/
magic = atomic_add_return(1, &bus_no_reg_magic);
snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1);
}
struct of_device *of_device_alloc(struct device_node *np,
const char *bus_id,
struct device *parent)
{
struct of_device *dev;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return NULL;
dev->node = of_node_get(np);
dev->dev.dma_mask = &dev->dma_mask;
dev->dev.parent = parent;
dev->dev.release = of_release_dev;
dev->dev.archdata.of_node = np;
dev->dev.archdata.numa_node = of_node_to_nid(np);
if (bus_id)
strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
else
of_device_make_bus_id(dev);
return dev;
}
EXPORT_SYMBOL(of_device_alloc);
ssize_t of_device_get_modalias(struct of_device *ofdev,
char *str, ssize_t len)
{
......
......@@ -23,7 +23,6 @@
#include <linux/of_platform.h>
#include <asm/errno.h>
#include <asm/dcr.h>
#include <asm/topology.h>
#include <asm/pci-bridge.h>
#include <asm/ppc-pci.h>
......@@ -53,8 +52,6 @@ static struct of_device_id of_default_bus_ids[] = {
{},
};
static atomic_t bus_no_reg_magic;
struct bus_type of_platform_bus_type = {
.uevent = of_device_uevent,
};
......@@ -87,89 +84,26 @@ void of_unregister_platform_driver(struct of_platform_driver *drv)
}
EXPORT_SYMBOL(of_unregister_platform_driver);
static void of_platform_make_bus_id(struct of_device *dev)
{
struct device_node *node = dev->node;
char *name = dev->dev.bus_id;
const u32 *reg;
u64 addr;
int magic;
/*
* If it's a DCR based device, use 'd' for native DCRs
* and 'D' for MMIO DCRs.
*/
#ifdef CONFIG_PPC_DCR
reg = of_get_property(node, "dcr-reg", NULL);
if (reg) {
#ifdef CONFIG_PPC_DCR_NATIVE
snprintf(name, BUS_ID_SIZE, "d%x.%s",
*reg, node->name);
#else /* CONFIG_PPC_DCR_NATIVE */
addr = of_translate_dcr_address(node, *reg, NULL);
if (addr != OF_BAD_ADDR) {
snprintf(name, BUS_ID_SIZE,
"D%llx.%s", (unsigned long long)addr,
node->name);
return;
}
#endif /* !CONFIG_PPC_DCR_NATIVE */
}
#endif /* CONFIG_PPC_DCR */
/*
* For MMIO, get the physical address
*/
reg = of_get_property(node, "reg", NULL);
if (reg) {
addr = of_translate_address(node, reg);
if (addr != OF_BAD_ADDR) {
snprintf(name, BUS_ID_SIZE,
"%llx.%s", (unsigned long long)addr,
node->name);
return;
}
}
/*
* No BusID, use the node name and add a globally incremented
* counter (and pray...)
*/
magic = atomic_add_return(1, &bus_no_reg_magic);
snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1);
}
struct of_device* of_platform_device_create(struct device_node *np,
const char *bus_id,
struct device *parent)
{
struct of_device *dev;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
dev = of_device_alloc(np, bus_id, parent);
if (!dev)
return NULL;
dev->node = of_node_get(np);
dev->dma_mask = 0xffffffffUL;
dev->dev.dma_mask = &dev->dma_mask;
dev->dev.parent = parent;
dev->dev.bus = &of_platform_bus_type;
dev->dev.release = of_release_dev;
dev->dev.archdata.of_node = np;
dev->dev.archdata.numa_node = of_node_to_nid(np);
/* We do not fill the DMA ops for platform devices by default.
* This is currently the responsibility of the platform code
* to do such, possibly using a device notifier
*/
if (bus_id)
strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
else
of_platform_make_bus_id(dev);
if (of_device_register(dev) != 0) {
kfree(dev);
of_device_free(dev);
return NULL;
}
......
......@@ -426,11 +426,14 @@ void __init setup_system(void)
printk("-----------------------------------------------------\n");
printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size);
printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size());
printk("ppc64_caches.dcache_line_size = 0x%x\n",
ppc64_caches.dline_size);
printk("ppc64_caches.icache_line_size = 0x%x\n",
ppc64_caches.iline_size);
printk("htab_address = 0x%p\n", htab_address);
if (ppc64_caches.dline_size != 0x80)
printk("ppc64_caches.dcache_line_size = 0x%x\n",
ppc64_caches.dline_size);
if (ppc64_caches.iline_size != 0x80)
printk("ppc64_caches.icache_line_size = 0x%x\n",
ppc64_caches.iline_size);
if (htab_address)
printk("htab_address = 0x%p\n", htab_address);
printk("htab_hash_mask = 0x%lx\n", htab_hash_mask);
#if PHYSICAL_START > 0
printk("physical_start = 0x%x\n", PHYSICAL_START);
......
......@@ -829,7 +829,7 @@ static void register_decrementer_clockevent(int cpu)
*dec = decrementer_clockevent;
dec->cpumask = cpumask_of_cpu(cpu);
printk(KERN_ERR "clockevent: %s mult[%lx] shift[%d] cpu[%d]\n",
printk(KERN_INFO "clockevent: %s mult[%lx] shift[%d] cpu[%d]\n",
dec->name, dec->mult, dec->shift, cpu);
clockevents_register_device(dec);
......
......@@ -134,13 +134,16 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
9:
/* This is where the pt_regs pointer can be found on the stack. */
#define PTREGS 128+168+56
#define PTREGS 128+168+56
/* Size of regs. */
#define RSIZE 8
#define RSIZE 8
/* Size of CR reg in DWARF unwind info. */
#define CRSIZE 4
/* This is the offset of the VMX reg pointer. */
#define VREGS 48*RSIZE+33*8
#define VREGS 48*RSIZE+33*8
/* Describe where general purpose regs are saved. */
#define EH_FRAME_GEN \
......@@ -178,7 +181,7 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
rsave (31, 31*RSIZE); \
rsave (67, 32*RSIZE); /* ap, used as temp for nip */ \
rsave (65, 36*RSIZE); /* lr */ \
rsave (70, 38*RSIZE) /* cr */
rsave (70, 38*RSIZE + (RSIZE - CRSIZE)) /* cr */
/* Describe where the FP regs are saved. */
#define EH_FRAME_FP \
......
......@@ -14,7 +14,6 @@ endif
obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \
memcpy_64.o usercopy_64.o mem_64.o string.o
obj-$(CONFIG_QUICC_ENGINE) += rheap.o
obj-$(CONFIG_XMON) += sstep.o
obj-$(CONFIG_KPROBES) += sstep.o
obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
......@@ -23,6 +22,4 @@ ifeq ($(CONFIG_PPC64),y)
obj-$(CONFIG_SMP) += locks.o
endif
# Temporary hack until we have migrated to asm-powerpc
obj-$(CONFIG_8xx) += rheap.o
obj-$(CONFIG_CPM2) += rheap.o
obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o
......@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/err.h>
#include <linux/slab.h>
......@@ -275,6 +276,7 @@ rh_info_t *rh_create(unsigned int alignment)
return info;
}
EXPORT_SYMBOL_GPL(rh_create);
/*
* Destroy a dynamically created remote heap. Deallocate only if the areas
......@@ -288,6 +290,7 @@ void rh_destroy(rh_info_t * info)
if ((info->flags & RHIF_STATIC_INFO) == 0)
kfree(info);
}
EXPORT_SYMBOL_GPL(rh_destroy);
/*
* Initialize in place a remote heap info block. This is needed to support
......@@ -320,6 +323,7 @@ void rh_init(rh_info_t * info, unsigned int alignment, int max_blocks,
for (i = 0, blk = block; i < max_blocks; i++, blk++)
list_add(&blk->list, &info->empty_list);
}
EXPORT_SYMBOL_GPL(rh_init);
/* Attach a free memory region, coalesces regions if adjuscent */
int rh_attach_region(rh_info_t * info, unsigned long start, int size)
......@@ -360,6 +364,7 @@ int rh_attach_region(rh_info_t * info, unsigned long start, int size)
return 0;
}
EXPORT_SYMBOL_GPL(rh_attach_region);
/* Detatch given address range, splits free block if needed. */
unsigned long rh_detach_region(rh_info_t * info, unsigned long start, int size)
......@@ -428,6 +433,7 @@ unsigned long rh_detach_region(rh_info_t * info, unsigned long start, int size)
return s;
}
EXPORT_SYMBOL_GPL(rh_detach_region);
/* Allocate a block of memory at the specified alignment. The value returned
* is an offset into the buffer initialized by rh_init(), or a negative number
......@@ -502,6 +508,7 @@ unsigned long rh_alloc_align(rh_info_t * info, int size, int alignment, const ch
return start;
}
EXPORT_SYMBOL_GPL(rh_alloc_align);
/* Allocate a block of memory at the default alignment. The value returned is
* an offset into the buffer initialized by rh_init(), or a negative number if
......@@ -511,6 +518,7 @@ unsigned long rh_alloc(rh_info_t * info, int size, const char *owner)
{
return rh_alloc_align(info, size, info->alignment, owner);
}
EXPORT_SYMBOL_GPL(rh_alloc);
/* Allocate a block of memory at the given offset, rounded up to the default
* alignment. The value returned is an offset into the buffer initialized by
......@@ -594,6 +602,7 @@ unsigned long rh_alloc_fixed(rh_info_t * info, unsigned long start, int size, co
return start;
}
EXPORT_SYMBOL_GPL(rh_alloc_fixed);
/* Deallocate the memory previously allocated by one of the rh_alloc functions.
* The return value is the size of the deallocated block, or a negative number
......@@ -626,6 +635,7 @@ int rh_free(rh_info_t * info, unsigned long start)
return size;
}
EXPORT_SYMBOL_GPL(rh_free);
int rh_get_stats(rh_info_t * info, int what, int max_stats, rh_stats_t * stats)
{
......@@ -663,6 +673,7 @@ int rh_get_stats(rh_info_t * info, int what, int max_stats, rh_stats_t * stats)
return nr;
}
EXPORT_SYMBOL_GPL(rh_get_stats);
int rh_set_owner(rh_info_t * info, unsigned long start, const char *owner)
{
......@@ -687,6 +698,7 @@ int rh_set_owner(rh_info_t * info, unsigned long start, const char *owner)
return size;
}
EXPORT_SYMBOL_GPL(rh_set_owner);
void rh_dump(rh_info_t * info)
{
......@@ -722,6 +734,7 @@ void rh_dump(rh_info_t * info)
st[i].size, st[i].owner != NULL ? st[i].owner : "");
printk(KERN_INFO "\n");
}
EXPORT_SYMBOL_GPL(rh_dump);
void rh_dump_blk(rh_info_t * info, rh_block_t * blk)
{
......@@ -729,3 +742,5 @@ void rh_dump_blk(rh_info_t * info, rh_block_t * blk)
"blk @0x%p: 0x%lx-0x%lx (%u)\n",
blk, blk->start, blk->start + blk->size, blk->size);
}
EXPORT_SYMBOL_GPL(rh_dump_blk);
......@@ -407,11 +407,16 @@ do_mathemu(struct pt_regs *regs)
case XE:
idx = (insn >> 16) & 0x1f;
if (!idx)
goto illegal;
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
op1 = (void *)(regs->gpr[idx] + regs->gpr[(insn >> 11) & 0x1f]);
if (!idx) {
if (((insn >> 1) & 0x3ff) == STFIWX)
op1 = (void *)(regs->gpr[(insn >> 11) & 0x1f]);
else
goto illegal;
} else {
op1 = (void *)(regs->gpr[idx] + regs->gpr[(insn >> 11) & 0x1f]);
}
break;
case XEU:
......
......@@ -209,9 +209,10 @@ static int __init htab_dt_scan_seg_sizes(unsigned long node,
if (prop[0] == 40) {
DBG("1T segment support detected\n");
cur_cpu_spec->cpu_features |= CPU_FTR_1T_SEGMENT;
return 1;
}
return 1;
}
cur_cpu_spec->cpu_features &= ~CPU_FTR_NO_SLBIE_B;
return 0;
}
......
......@@ -240,7 +240,7 @@ int __meminit vmemmap_populate(struct page *start_page,
return -ENOMEM;
printk(KERN_WARNING "vmemmap %08lx allocated at %p, "
"physical %p.\n", start, p, __pa(p));
"physical %08lx.\n", start, p, __pa(p));
mapped = htab_bolt_mapping(start, start + page_size,
__pa(p), mode_rw, mmu_linear_psize,
......
......@@ -157,7 +157,8 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
unsigned long stack = KSTK_ESP(tsk);
unsigned long unmapped_base;
if (offset <= SLB_CACHE_ENTRIES) {
if (!cpu_has_feature(CPU_FTR_NO_SLBIE_B) &&
offset <= SLB_CACHE_ENTRIES) {
int i;
asm volatile("isync" : : : "memory");
for (i = 0; i < offset; i++) {
......
......@@ -264,6 +264,7 @@ config TAU_AVERAGE
config QUICC_ENGINE
bool
select PPC_LIB_RHEAP
help
The QUICC Engine (QE) is a new generation of communications
coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
......@@ -274,6 +275,7 @@ config CPM2
bool
default n
select CPM
select PPC_LIB_RHEAP
help
The CPM2 (Communications Processor Module) is a coprocessor on
embedded CPUs made by Freescale. Selecting this option means that
......@@ -313,4 +315,6 @@ config FSL_ULI1575
config CPM
bool
source "arch/powerpc/sysdev/bestcomm/Kconfig"
endmenu
......@@ -37,6 +37,7 @@ config PPC_8xx
select FSL_SOC
select 8xx
select WANT_DEVICE_TREE
select PPC_LIB_RHEAP
config 40x
bool "AMCC 40x"
......
......@@ -39,9 +39,9 @@ static inline void iSeries_hunlock(unsigned long slot)
spin_unlock(&iSeries_hlocks[(slot >> 4) & 0x3f]);
}
long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
unsigned long pa, unsigned long rflags,
unsigned long vflags, int psize)
unsigned long vflags, int psize, int ssize)
{
long slot;
struct hash_pte lhpte;
......
......@@ -2,7 +2,7 @@
* Legacy iSeries specific vio initialisation
* that needs to be built in (not a module).
*
* © Copyright 2007 IBM Corporation
* © Copyright 2007 IBM Corporation
* Author: Stephen Rothwell
* Some parts collected from various other files
*
......
......@@ -14,6 +14,7 @@ obj-$(CONFIG_FSL_SOC) += fsl_soc.o
obj-$(CONFIG_FSL_PCI) += fsl_pci.o
obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/
mv64x60-$(CONFIG_PCI) += mv64x60_pci.o
obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o \
mv64x60_udbg.o
......
#
# Kconfig options for Bestcomm
#
config PPC_BESTCOMM
tristate "Bestcomm DMA engine support"
depends on PPC_MPC52xx
default n
select PPC_LIB_RHEAP
help
BestComm is the name of the communication coprocessor found
on the Freescale MPC5200 family of processor. It's usage is
optionnal for some drivers (like ATA), but required for
others (like FEC).
If you want to use drivers that require DMA operations,
answer Y or M. Otherwise say N.
config PPC_BESTCOMM_ATA
tristate "Bestcomm ATA task support"
depends on PPC_BESTCOMM
default n
help
This option enables the support for the ATA task.
config PPC_BESTCOMM_FEC
tristate "Bestcomm FEC tasks support"
depends on PPC_BESTCOMM
default n
help
This option enables the support for the FEC tasks.
config PPC_BESTCOMM_GEN_BD
tristate "Bestcomm GenBD tasks support"
depends on PPC_BESTCOMM
default n
help
This option enables the support for the GenBD tasks.
#
# Makefile for BestComm & co
#
bestcomm-core-objs := bestcomm.o sram.o
bestcomm-ata-objs := ata.o bcom_ata_task.o
bestcomm-fec-objs := fec.o bcom_fec_rx_task.o bcom_fec_tx_task.o
bestcomm-gen-bd-objs := gen_bd.o bcom_gen_bd_rx_task.o bcom_gen_bd_tx_task.o
obj-$(CONFIG_PPC_BESTCOMM) += bestcomm-core.o
obj-$(CONFIG_PPC_BESTCOMM_ATA) += bestcomm-ata.o
obj-$(CONFIG_PPC_BESTCOMM_FEC) += bestcomm-fec.o
obj-$(CONFIG_PPC_BESTCOMM_GEN_BD) += bestcomm-gen-bd.o
/*
* Bestcomm ATA task driver
*
*
* Patterned after bestcomm/fec.c by Dale Farnsworth <dfarnsworth@mvista.com>
* 2003-2004 (c) MontaVista, Software, Inc.
*
* Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2006 Freescale - John Rigby
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <asm/io.h>
#include "bestcomm.h"
#include "bestcomm_priv.h"
#include "ata.h"
/* ======================================================================== */
/* Task image/var/inc */
/* ======================================================================== */
/* ata task image */
extern u32 bcom_ata_task[];
/* ata task vars that need to be set before enabling the task */
struct bcom_ata_var {
u32 enable; /* (u16*) address of task's control register */
u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
u32 bd_start; /* (struct bcom_bd*) current bd */
u32 buffer_size; /* size of receive buffer */
};
/* ata task incs that need to be set before enabling the task */
struct bcom_ata_inc {
u16 pad0;
s16 incr_bytes;
u16 pad1;
s16 incr_dst;
u16 pad2;
s16 incr_src;
};
/* ======================================================================== */
/* Task support code */
/* ======================================================================== */
struct bcom_task *
bcom_ata_init(int queue_len, int maxbufsize)
{
struct bcom_task *tsk;
struct bcom_ata_var *var;
struct bcom_ata_inc *inc;
tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_ata_bd), 0);
if (!tsk)
return NULL;
tsk->flags = BCOM_FLAGS_NONE;
bcom_ata_reset_bd(tsk);
var = (struct bcom_ata_var *) bcom_task_var(tsk->tasknum);
inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum);
if (bcom_load_image(tsk->tasknum, bcom_ata_task)) {
bcom_task_free(tsk);
return NULL;
}
var->enable = bcom_eng->regs_base +
offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
var->bd_base = tsk->bd_pa;
var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
var->bd_start = tsk->bd_pa;
var->buffer_size = maxbufsize;
/* Configure some stuff */
bcom_set_task_pragma(tsk->tasknum, BCOM_ATA_PRAGMA);
bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ATA_RX], BCOM_IPR_ATA_RX);
out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ATA_TX], BCOM_IPR_ATA_TX);
out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
return tsk;
}
EXPORT_SYMBOL_GPL(bcom_ata_init);
void bcom_ata_rx_prepare(struct bcom_task *tsk)
{
struct bcom_ata_inc *inc;
inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum);
inc->incr_bytes = -(s16)sizeof(u32);
inc->incr_src = 0;
inc->incr_dst = sizeof(u32);
bcom_set_initiator(tsk->tasknum, BCOM_INITIATOR_ATA_RX);
}
EXPORT_SYMBOL_GPL(bcom_ata_rx_prepare);
void bcom_ata_tx_prepare(struct bcom_task *tsk)
{
struct bcom_ata_inc *inc;
inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum);
inc->incr_bytes = -(s16)sizeof(u32);
inc->incr_src = sizeof(u32);
inc->incr_dst = 0;
bcom_set_initiator(tsk->tasknum, BCOM_INITIATOR_ATA_TX);
}
EXPORT_SYMBOL_GPL(bcom_ata_tx_prepare);
void bcom_ata_reset_bd(struct bcom_task *tsk)
{
struct bcom_ata_var *var;
/* Reset all BD */
memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
tsk->index = 0;
tsk->outdex = 0;
var = (struct bcom_ata_var *) bcom_task_var(tsk->tasknum);
var->bd_start = var->bd_base;
}
EXPORT_SYMBOL_GPL(bcom_ata_reset_bd);
void bcom_ata_release(struct bcom_task *tsk)
{
/* Nothing special for the ATA tasks */
bcom_task_free(tsk);
}
EXPORT_SYMBOL_GPL(bcom_ata_release);
MODULE_DESCRIPTION("BestComm ATA task driver");
MODULE_AUTHOR("John Rigby");
MODULE_LICENSE("GPL v2");
/*
* Header for Bestcomm ATA task driver
*
*
* Copyright (C) 2006 Freescale - John Rigby
* Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#ifndef __BESTCOMM_ATA_H__
#define __BESTCOMM_ATA_H__
struct bcom_ata_bd {
u32 status;
u32 dst_pa;
u32 src_pa;
};
extern struct bcom_task *
bcom_ata_init(int queue_len, int maxbufsize);
extern void
bcom_ata_rx_prepare(struct bcom_task *tsk);
extern void
bcom_ata_tx_prepare(struct bcom_task *tsk);
extern void
bcom_ata_reset_bd(struct bcom_task *tsk);
#endif /* __BESTCOMM_ATA_H__ */
/*
* Bestcomm ATA task microcode
*
* Copyright (c) 2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Created based on bestcom/code_dma/image_rtos1/dma_image.hex
*/
#include <asm/types.h>
/*
* The header consists of the following fields:
* u32 magic;
* u8 desc_size;
* u8 var_size;
* u8 inc_size;
* u8 first_var;
* u8 reserved[8];
*
* The size fields contain the number of 32-bit words.
*/
u32 bcom_ata_task[] = {
/* header */
0x4243544b,
0x0e060709,
0x00000000,
0x00000000,
/* Task descriptors */
0x8198009b, /* LCD: idx0 = var3; idx0 <= var2; idx0 += inc3 */
0x13e00c08, /* DRD1A: var3 = var1; FN=0 MORE init=31 WS=0 RS=0 */
0xb8000264, /* LCD: idx1 = *idx0, idx2 = var0; idx1 < var9; idx1 += inc4, idx2 += inc4 */
0x10000f00, /* DRD1A: var3 = idx0; FN=0 MORE init=0 WS=0 RS=0 */
0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
0x0c8cfc8a, /* DRD2B1: *idx2 = EU3(); EU3(*idx2,var10) */
0xd8988240, /* LCDEXT: idx1 = idx1; idx1 > var9; idx1 += inc0 */
0xf845e011, /* LCDEXT: idx2 = *(idx0 + var00000015); ; idx2 += inc2 */
0xb845e00a, /* LCD: idx3 = *(idx0 + var00000019); ; idx3 += inc1 */
0x0bfecf90, /* DRD1A: *idx3 = *idx2; FN=0 TFD init=31 WS=3 RS=3 */
0x9898802d, /* LCD: idx1 = idx1; idx1 once var0; idx1 += inc5 */
0x64000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 INT EXT init=0 WS=0 RS=0 */
0x0c0cf849, /* DRD2B1: *idx0 = EU3(); EU3(idx1,var9) */
0x000001f8, /* NOP */
/* VAR[9]-VAR[14] */
0x40000000,
0x7fff7fff,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
/* INC[0]-INC[6] */
0x40000000,
0xe0000000,
0xe0000000,
0xa000000c,
0x20000000,
0x00000000,
0x00000000,
};
/*
* Bestcomm FEC RX task microcode
*
* Copyright (c) 2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Automatically created based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
* on Tue Mar 22 11:19:38 2005 GMT
*/
#include <asm/types.h>
/*
* The header consists of the following fields:
* u32 magic;
* u8 desc_size;
* u8 var_size;
* u8 inc_size;
* u8 first_var;
* u8 reserved[8];
*
* The size fields contain the number of 32-bit words.
*/
u32 bcom_fec_rx_task[] = {
/* header */
0x4243544b,
0x18060709,
0x00000000,
0x00000000,
/* Task descriptors */
0x808220e3, /* LCD: idx0 = var1, idx1 = var4; idx1 <= var3; idx0 += inc4, idx1 += inc3 */
0x10601010, /* DRD1A: var4 = var2; FN=0 MORE init=3 WS=0 RS=0 */
0xb8800264, /* LCD: idx2 = *idx1, idx3 = var0; idx2 < var9; idx2 += inc4, idx3 += inc4 */
0x10001308, /* DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
0x0cccfcca, /* DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */
0x80004000, /* LCDEXT: idx2 = 0x00000000; ; */
0xb8c58029, /* LCD: idx3 = *(idx1 + var00000015); idx3 once var0; idx3 += inc5 */
0x60000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=0 RS=0 */
0x088cf8cc, /* DRD2B1: idx2 = EU3(); EU3(idx3,var12) */
0x991982f2, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var11; idx2 += inc6, idx3 += inc2 */
0x006acf80, /* DRD1A: *idx3 = *idx0; FN=0 init=3 WS=1 RS=1 */
0x80004000, /* LCDEXT: idx2 = 0x00000000; ; */
0x9999802d, /* LCD: idx3 = idx3; idx3 once var0; idx3 += inc5 */
0x70000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
0x034cfc4e, /* DRD2B1: var13 = EU3(); EU3(*idx1,var14) */
0x00008868, /* DRD1A: idx2 = var13; FN=0 init=0 WS=0 RS=0 */
0x99198341, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var13; idx2 += inc0, idx3 += inc1 */
0x007ecf80, /* DRD1A: *idx3 = *idx0; FN=0 init=3 WS=3 RS=3 */
0x99198272, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var9; idx2 += inc6, idx3 += inc2 */
0x046acf80, /* DRD1A: *idx3 = *idx0; FN=0 INT init=3 WS=1 RS=1 */
0x9819002d, /* LCD: idx2 = idx0; idx2 once var0; idx2 += inc5 */
0x0060c790, /* DRD1A: *idx1 = *idx2; FN=0 init=3 WS=0 RS=0 */
0x000001f8, /* NOP */
/* VAR[9]-VAR[14] */
0x40000000,
0x7fff7fff,
0x00000000,
0x00000003,
0x40000008,
0x43ffffff,
/* INC[0]-INC[6] */
0x40000000,
0xe0000000,
0xe0000000,
0xa0000008,
0x20000000,
0x00000000,
0x4000ffff,
};
/*
* Bestcomm FEC TX task microcode
*
* Copyright (c) 2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Automatically created based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
* on Tue Mar 22 11:19:29 2005 GMT
*/
#include <asm/types.h>
/*
* The header consists of the following fields:
* u32 magic;
* u8 desc_size;
* u8 var_size;
* u8 inc_size;
* u8 first_var;
* u8 reserved[8];
*
* The size fields contain the number of 32-bit words.
*/
u32 bcom_fec_tx_task[] = {
/* header */
0x4243544b,
0x2407070d,
0x00000000,
0x00000000,
/* Task descriptors */
0x8018001b, /* LCD: idx0 = var0; idx0 <= var0; idx0 += inc3 */
0x60000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
0x01ccfc0d, /* DRD2B1: var7 = EU3(); EU3(*idx0,var13) */
0x8082a123, /* LCD: idx0 = var1, idx1 = var5; idx1 <= var4; idx0 += inc4, idx1 += inc3 */
0x10801418, /* DRD1A: var5 = var3; FN=0 MORE init=4 WS=0 RS=0 */
0xf88103a4, /* LCDEXT: idx2 = *idx1, idx3 = var2; idx2 < var14; idx2 += inc4, idx3 += inc4 */
0x801a6024, /* LCD: idx4 = var0; ; idx4 += inc4 */
0x10001708, /* DRD1A: var5 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
0x0cccfccf, /* DRD2B1: *idx3 = EU3(); EU3(*idx3,var15) */
0x991a002c, /* LCD: idx2 = idx2, idx3 = idx4; idx2 once var0; idx2 += inc5, idx3 += inc4 */
0x70000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
0x024cfc4d, /* DRD2B1: var9 = EU3(); EU3(*idx1,var13) */
0x60000003, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */
0x0cccf247, /* DRD2B1: *idx3 = EU3(); EU3(var9,var7) */
0x80004000, /* LCDEXT: idx2 = 0x00000000; ; */
0xb8c80029, /* LCD: idx3 = *(idx1 + var0000001a); idx3 once var0; idx3 += inc5 */
0x70000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
0x088cf8d1, /* DRD2B1: idx2 = EU3(); EU3(idx3,var17) */
0x00002f10, /* DRD1A: var11 = idx2; FN=0 init=0 WS=0 RS=0 */
0x99198432, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var16; idx2 += inc6, idx3 += inc2 */
0x008ac398, /* DRD1A: *idx0 = *idx3; FN=0 init=4 WS=1 RS=1 */
0x80004000, /* LCDEXT: idx2 = 0x00000000; ; */
0x9999802d, /* LCD: idx3 = idx3; idx3 once var0; idx3 += inc5 */
0x70000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
0x048cfc53, /* DRD2B1: var18 = EU3(); EU3(*idx1,var19) */
0x60000008, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=8 EXT init=0 WS=0 RS=0 */
0x088cf48b, /* DRD2B1: idx2 = EU3(); EU3(var18,var11) */
0x99198481, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var18; idx2 += inc0, idx3 += inc1 */
0x009ec398, /* DRD1A: *idx0 = *idx3; FN=0 init=4 WS=3 RS=3 */
0x991983b2, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var14; idx2 += inc6, idx3 += inc2 */
0x088ac398, /* DRD1A: *idx0 = *idx3; FN=0 TFD init=4 WS=1 RS=1 */
0x9919002d, /* LCD: idx2 = idx2; idx2 once var0; idx2 += inc5 */
0x60000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
0x0c4cf88e, /* DRD2B1: *idx1 = EU3(); EU3(idx2,var14) */
0x000001f8, /* NOP */
/* VAR[13]-VAR[19] */
0x0c000000,
0x40000000,
0x7fff7fff,
0x00000000,
0x00000003,
0x40000004,
0x43ffffff,
/* INC[0]-INC[6] */
0x40000000,
0xe0000000,
0xe0000000,
0xa0000008,
0x20000000,
0x00000000,
0x4000ffff,
};
/*
* Bestcomm GenBD RX task microcode
*
* Copyright (C) 2006 AppSpec Computer Technologies Corp.
* Jeff Gibbons <jeff.gibbons@appspec.com>
* Copyright (c) 2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
* on Tue Mar 4 10:14:12 2006 GMT
*
*/
#include <asm/types.h>
/*
* The header consists of the following fields:
* u32 magic;
* u8 desc_size;
* u8 var_size;
* u8 inc_size;
* u8 first_var;
* u8 reserved[8];
*
* The size fields contain the number of 32-bit words.
*/
u32 bcom_gen_bd_rx_task[] = {
/* header */
0x4243544b,
0x0d020409,
0x00000000,
0x00000000,
/* Task descriptors */
0x808220da, /* LCD: idx0 = var1, idx1 = var4; idx1 <= var3; idx0 += inc3, idx1 += inc2 */
0x13e01010, /* DRD1A: var4 = var2; FN=0 MORE init=31 WS=0 RS=0 */
0xb880025b, /* LCD: idx2 = *idx1, idx3 = var0; idx2 < var9; idx2 += inc3, idx3 += inc3 */
0x10001308, /* DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
0x0cccfcca, /* DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */
0xd9190240, /* LCDEXT: idx2 = idx2; idx2 > var9; idx2 += inc0 */
0xb8c5e009, /* LCD: idx3 = *(idx1 + var00000015); ; idx3 += inc1 */
0x07fecf80, /* DRD1A: *idx3 = *idx0; FN=0 INT init=31 WS=3 RS=3 */
0x99190024, /* LCD: idx2 = idx2; idx2 once var0; idx2 += inc4 */
0x60000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
0x0c4cf889, /* DRD2B1: *idx1 = EU3(); EU3(idx2,var9) */
0x000001f8, /* NOP */
/* VAR[9]-VAR[10] */
0x40000000,
0x7fff7fff,
/* INC[0]-INC[3] */
0x40000000,
0xe0000000,
0xa0000008,
0x20000000,
};
/*
* Bestcomm GenBD TX task microcode
*
* Copyright (C) 2006 AppSpec Computer Technologies Corp.
* Jeff Gibbons <jeff.gibbons@appspec.com>
* Copyright (c) 2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
* on Tue Mar 4 10:14:12 2006 GMT
*
*/
#include <asm/types.h>
/*
* The header consists of the following fields:
* u32 magic;
* u8 desc_size;
* u8 var_size;
* u8 inc_size;
* u8 first_var;
* u8 reserved[8];
*
* The size fields contain the number of 32-bit words.
*/
u32 bcom_gen_bd_tx_task[] = {
/* header */
0x4243544b,
0x0f040609,
0x00000000,
0x00000000,
/* Task descriptors */
0x800220e3, /* LCD: idx0 = var0, idx1 = var4; idx1 <= var3; idx0 += inc4, idx1 += inc3 */
0x13e01010, /* DRD1A: var4 = var2; FN=0 MORE init=31 WS=0 RS=0 */
0xb8808264, /* LCD: idx2 = *idx1, idx3 = var1; idx2 < var9; idx2 += inc4, idx3 += inc4 */
0x10001308, /* DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
0x0cccfcca, /* DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */
0xd9190300, /* LCDEXT: idx2 = idx2; idx2 > var12; idx2 += inc0 */
0xb8c5e009, /* LCD: idx3 = *(idx1 + var00000015); ; idx3 += inc1 */
0x03fec398, /* DRD1A: *idx0 = *idx3; FN=0 init=31 WS=3 RS=3 */
0x9919826a, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var9; idx2 += inc5, idx3 += inc2 */
0x0feac398, /* DRD1A: *idx0 = *idx3; FN=0 TFD INT init=31 WS=1 RS=1 */
0x99190036, /* LCD: idx2 = idx2; idx2 once var0; idx2 += inc6 */
0x60000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
0x0c4cf889, /* DRD2B1: *idx1 = EU3(); EU3(idx2,var9) */
0x000001f8, /* NOP */
/* VAR[9]-VAR[12] */
0x40000000,
0x7fff7fff,
0x00000000,
0x40000004,
/* INC[0]-INC[5] */
0x40000000,
0xe0000000,
0xe0000000,
0xa0000008,
0x20000000,
0x4000ffff,
};
/*
* Driver for MPC52xx processor BestComm peripheral controller
*
*
* Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2005 Varma Electronics Oy,
* ( by Andrey Volkov <avolkov@varma-el.com> )
* Copyright (C) 2003-2004 MontaVista, Software, Inc.
* ( by Dale Farnsworth <dfarnsworth@mvista.com> )
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mpc52xx.h>
#include "sram.h"
#include "bestcomm_priv.h"
#include "bestcomm.h"
#define DRIVER_NAME "bestcomm-core"
struct bcom_engine *bcom_eng = NULL;
EXPORT_SYMBOL_GPL(bcom_eng); /* needed for inline functions */
/* ======================================================================== */
/* Public and private API */
/* ======================================================================== */
/* Private API */
struct bcom_task *
bcom_task_alloc(int bd_count, int bd_size, int priv_size)
{
int i, tasknum = -1;
struct bcom_task *tsk;
/* Get and reserve a task num */
spin_lock(&bcom_eng->lock);
for (i=0; i<BCOM_MAX_TASKS; i++)
if (!bcom_eng->tdt[i].stop) { /* we use stop as a marker */
bcom_eng->tdt[i].stop = 0xfffffffful; /* dummy addr */
tasknum = i;
break;
}
spin_unlock(&bcom_eng->lock);
if (tasknum < 0)
return NULL;
/* Allocate our structure */
tsk = kzalloc(sizeof(struct bcom_task) + priv_size, GFP_KERNEL);
if (!tsk)
goto error;
tsk->tasknum = tasknum;
if (priv_size)
tsk->priv = (void*)tsk + sizeof(struct bcom_task);
/* Get IRQ of that task */
tsk->irq = irq_of_parse_and_map(bcom_eng->ofnode, tsk->tasknum);
if (tsk->irq == NO_IRQ)
goto error;
/* Init the BDs, if needed */
if (bd_count) {
tsk->cookie = kmalloc(sizeof(void*) * bd_count, GFP_KERNEL);
if (!tsk->cookie)
goto error;
tsk->bd = bcom_sram_alloc(bd_count * bd_size, 4, &tsk->bd_pa);
if (!tsk->bd)
goto error;
memset(tsk->bd, 0x00, bd_count * bd_size);
tsk->num_bd = bd_count;
tsk->bd_size = bd_size;
}
return tsk;
error:
if (tsk) {
if (tsk->irq != NO_IRQ)
irq_dispose_mapping(tsk->irq);
bcom_sram_free(tsk->bd);
kfree(tsk->cookie);
kfree(tsk);
}
bcom_eng->tdt[tasknum].stop = 0;
return NULL;
}
EXPORT_SYMBOL_GPL(bcom_task_alloc);
void
bcom_task_free(struct bcom_task *tsk)
{
/* Stop the task */
bcom_disable_task(tsk->tasknum);
/* Clear TDT */
bcom_eng->tdt[tsk->tasknum].start = 0;
bcom_eng->tdt[tsk->tasknum].stop = 0;
/* Free everything */
irq_dispose_mapping(tsk->irq);
bcom_sram_free(tsk->bd);
kfree(tsk->cookie);
kfree(tsk);
}
EXPORT_SYMBOL_GPL(bcom_task_free);
int
bcom_load_image(int task, u32 *task_image)
{
struct bcom_task_header *hdr = (struct bcom_task_header *)task_image;
struct bcom_tdt *tdt;
u32 *desc, *var, *inc;
u32 *desc_src, *var_src, *inc_src;
/* Safety checks */
if (hdr->magic != BCOM_TASK_MAGIC) {
printk(KERN_ERR DRIVER_NAME
": Trying to load invalid microcode\n");
return -EINVAL;
}
if ((task < 0) || (task >= BCOM_MAX_TASKS)) {
printk(KERN_ERR DRIVER_NAME
": Trying to load invalid task %d\n", task);
return -EINVAL;
}
/* Initial load or reload */
tdt = &bcom_eng->tdt[task];
if (tdt->start) {
desc = bcom_task_desc(task);
if (hdr->desc_size != bcom_task_num_descs(task)) {
printk(KERN_ERR DRIVER_NAME
": Trying to reload wrong task image "
"(%d size %d/%d)!\n",
task,
hdr->desc_size,
bcom_task_num_descs(task));
return -EINVAL;
}
} else {
phys_addr_t start_pa;
desc = bcom_sram_alloc(hdr->desc_size * sizeof(u32), 4, &start_pa);
if (!desc)
return -ENOMEM;
tdt->start = start_pa;
tdt->stop = start_pa + ((hdr->desc_size-1) * sizeof(u32));
}
var = bcom_task_var(task);
inc = bcom_task_inc(task);
/* Clear & copy */
memset(var, 0x00, BCOM_VAR_SIZE);
memset(inc, 0x00, BCOM_INC_SIZE);
desc_src = (u32 *)(hdr + 1);
var_src = desc_src + hdr->desc_size;
inc_src = var_src + hdr->var_size;
memcpy(desc, desc_src, hdr->desc_size * sizeof(u32));
memcpy(var + hdr->first_var, var_src, hdr->var_size * sizeof(u32));
memcpy(inc, inc_src, hdr->inc_size * sizeof(u32));
return 0;
}
EXPORT_SYMBOL_GPL(bcom_load_image);
void
bcom_set_initiator(int task, int initiator)
{
int i;
int num_descs;
u32 *desc;
int next_drd_has_initiator;
bcom_set_tcr_initiator(task, initiator);
/* Just setting tcr is apparently not enough due to some problem */
/* with it. So we just go thru all the microcode and replace in */
/* the DRD directly */
desc = bcom_task_desc(task);
next_drd_has_initiator = 1;
num_descs = bcom_task_num_descs(task);
for (i=0; i<num_descs; i++, desc++) {
if (!bcom_desc_is_drd(*desc))
continue;
if (next_drd_has_initiator)
if (bcom_desc_initiator(*desc) != BCOM_INITIATOR_ALWAYS)
bcom_set_desc_initiator(desc, initiator);
next_drd_has_initiator = !bcom_drd_is_extended(*desc);
}
}
EXPORT_SYMBOL_GPL(bcom_set_initiator);
/* Public API */
void
bcom_enable(struct bcom_task *tsk)
{
bcom_enable_task(tsk->tasknum);
}
EXPORT_SYMBOL_GPL(bcom_enable);
void
bcom_disable(struct bcom_task *tsk)
{
bcom_disable_task(tsk->tasknum);
}
EXPORT_SYMBOL_GPL(bcom_disable);
/* ======================================================================== */
/* Engine init/cleanup */
/* ======================================================================== */
/* Function Descriptor table */
/* this will need to be updated if Freescale changes their task code FDT */
static u32 fdt_ops[] = {
0xa0045670, /* FDT[48] - load_acc() */
0x80045670, /* FDT[49] - unload_acc() */
0x21800000, /* FDT[50] - and() */
0x21e00000, /* FDT[51] - or() */
0x21500000, /* FDT[52] - xor() */
0x21400000, /* FDT[53] - andn() */
0x21500000, /* FDT[54] - not() */
0x20400000, /* FDT[55] - add() */
0x20500000, /* FDT[56] - sub() */
0x20800000, /* FDT[57] - lsh() */
0x20a00000, /* FDT[58] - rsh() */
0xc0170000, /* FDT[59] - crc8() */
0xc0145670, /* FDT[60] - crc16() */
0xc0345670, /* FDT[61] - crc32() */
0xa0076540, /* FDT[62] - endian32() */
0xa0000760, /* FDT[63] - endian16() */
};
static int __devinit
bcom_engine_init(void)
{
int task;
phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa;
unsigned int tdt_size, ctx_size, var_size, fdt_size;
/* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */
tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt);
ctx_size = BCOM_MAX_TASKS * BCOM_CTX_SIZE;
var_size = BCOM_MAX_TASKS * (BCOM_VAR_SIZE + BCOM_INC_SIZE);
fdt_size = BCOM_FDT_SIZE;
bcom_eng->tdt = bcom_sram_alloc(tdt_size, sizeof(u32), &tdt_pa);
bcom_eng->ctx = bcom_sram_alloc(ctx_size, BCOM_CTX_ALIGN, &ctx_pa);
bcom_eng->var = bcom_sram_alloc(var_size, BCOM_VAR_ALIGN, &var_pa);
bcom_eng->fdt = bcom_sram_alloc(fdt_size, BCOM_FDT_ALIGN, &fdt_pa);
if (!bcom_eng->tdt || !bcom_eng->ctx || !bcom_eng->var || !bcom_eng->fdt) {
printk(KERN_ERR "DMA: SRAM alloc failed in engine init !\n");
bcom_sram_free(bcom_eng->tdt);
bcom_sram_free(bcom_eng->ctx);
bcom_sram_free(bcom_eng->var);
bcom_sram_free(bcom_eng->fdt);
return -ENOMEM;
}
memset(bcom_eng->tdt, 0x00, tdt_size);
memset(bcom_eng->ctx, 0x00, ctx_size);
memset(bcom_eng->var, 0x00, var_size);
memset(bcom_eng->fdt, 0x00, fdt_size);
/* Copy the FDT for the EU#3 */
memcpy(&bcom_eng->fdt[48], fdt_ops, sizeof(fdt_ops));
/* Initialize Task base structure */
for (task=0; task<BCOM_MAX_TASKS; task++)
{
out_be16(&bcom_eng->regs->tcr[task], 0);
out_8(&bcom_eng->regs->ipr[task], 0);
bcom_eng->tdt[task].context = ctx_pa;
bcom_eng->tdt[task].var = var_pa;
bcom_eng->tdt[task].fdt = fdt_pa;
var_pa += BCOM_VAR_SIZE + BCOM_INC_SIZE;
ctx_pa += BCOM_CTX_SIZE;
}
out_be32(&bcom_eng->regs->taskBar, tdt_pa);
/* Init 'always' initiator */
out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS);
/* Disable COMM Bus Prefetch, apparently it's not reliable yet */
/* FIXME: This should be done on 5200 and not 5200B ... */
out_be16(&bcom_eng->regs->PtdCntrl, in_be16(&bcom_eng->regs->PtdCntrl) | 1);
/* Init lock */
spin_lock_init(&bcom_eng->lock);
return 0;
}
static void
bcom_engine_cleanup(void)
{
int task;
/* Stop all tasks */
for (task=0; task<BCOM_MAX_TASKS; task++)
{
out_be16(&bcom_eng->regs->tcr[task], 0);
out_8(&bcom_eng->regs->ipr[task], 0);
}
out_be32(&bcom_eng->regs->taskBar, 0ul);
/* Release the SRAM zones */
bcom_sram_free(bcom_eng->tdt);
bcom_sram_free(bcom_eng->ctx);
bcom_sram_free(bcom_eng->var);
bcom_sram_free(bcom_eng->fdt);
}
/* ======================================================================== */
/* OF platform driver */
/* ======================================================================== */
static int __devinit
mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match)
{
struct device_node *ofn_sram;
struct resource res_bcom;
int rv;
/* Inform user we're ok so far */
printk(KERN_INFO "DMA: MPC52xx BestComm driver\n");
/* Get the bestcomm node */
of_node_get(op->node);
/* Prepare SRAM */
ofn_sram = of_find_compatible_node(NULL, "sram", "mpc5200-sram");
if (!ofn_sram) {
printk(KERN_ERR DRIVER_NAME ": "
"No SRAM found in device tree\n");
rv = -ENODEV;
goto error_ofput;
}
rv = bcom_sram_init(ofn_sram, DRIVER_NAME);
of_node_put(ofn_sram);
if (rv) {
printk(KERN_ERR DRIVER_NAME ": "
"Error in SRAM init\n");
goto error_ofput;
}
/* Get a clean struct */
bcom_eng = kzalloc(sizeof(struct bcom_engine), GFP_KERNEL);
if (!bcom_eng) {
printk(KERN_ERR DRIVER_NAME ": "
"Can't allocate state structure\n");
rv = -ENOMEM;
goto error_sramclean;
}
/* Save the node */
bcom_eng->ofnode = op->node;
/* Get, reserve & map io */
if (of_address_to_resource(op->node, 0, &res_bcom)) {
printk(KERN_ERR DRIVER_NAME ": "
"Can't get resource\n");
rv = -EINVAL;
goto error_sramclean;
}
if (!request_mem_region(res_bcom.start, sizeof(struct mpc52xx_sdma),
DRIVER_NAME)) {
printk(KERN_ERR DRIVER_NAME ": "
"Can't request registers region\n");
rv = -EBUSY;
goto error_sramclean;
}
bcom_eng->regs_base = res_bcom.start;
bcom_eng->regs = ioremap(res_bcom.start, sizeof(struct mpc52xx_sdma));
if (!bcom_eng->regs) {
printk(KERN_ERR DRIVER_NAME ": "
"Can't map registers\n");
rv = -ENOMEM;
goto error_release;
}
/* Now, do the real init */
rv = bcom_engine_init();
if (rv)
goto error_unmap;
/* Done ! */
printk(KERN_INFO "DMA: MPC52xx BestComm engine @%08lx ok !\n",
bcom_eng->regs_base);
return 0;
/* Error path */
error_unmap:
iounmap(bcom_eng->regs);
error_release:
release_mem_region(res_bcom.start, sizeof(struct mpc52xx_sdma));
error_sramclean:
kfree(bcom_eng);
bcom_sram_cleanup();
error_ofput:
of_node_put(op->node);
printk(KERN_ERR "DMA: MPC52xx BestComm init failed !\n");
return rv;
}
static int
mpc52xx_bcom_remove(struct of_device *op)
{
/* Clean up the engine */
bcom_engine_cleanup();
/* Cleanup SRAM */
bcom_sram_cleanup();
/* Release regs */
iounmap(bcom_eng->regs);
release_mem_region(bcom_eng->regs_base, sizeof(struct mpc52xx_sdma));
/* Release the node */
of_node_put(bcom_eng->ofnode);
/* Release memory */
kfree(bcom_eng);
bcom_eng = NULL;
return 0;
}
static struct of_device_id mpc52xx_bcom_of_match[] = {
{
.type = "dma-controller",
.compatible = "mpc5200-bestcomm",
},
{},
};
MODULE_DEVICE_TABLE(of, mpc52xx_bcom_of_match);
static struct of_platform_driver mpc52xx_bcom_of_platform_driver = {
.owner = THIS_MODULE,
.name = DRIVER_NAME,
.match_table = mpc52xx_bcom_of_match,
.probe = mpc52xx_bcom_probe,
.remove = mpc52xx_bcom_remove,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
};
/* ======================================================================== */
/* Module */
/* ======================================================================== */
static int __init
mpc52xx_bcom_init(void)
{
return of_register_platform_driver(&mpc52xx_bcom_of_platform_driver);
}
static void __exit
mpc52xx_bcom_exit(void)
{
of_unregister_platform_driver(&mpc52xx_bcom_of_platform_driver);
}
/* If we're not a module, we must make sure everything is setup before */
/* anyone tries to use us ... that's why we use subsys_initcall instead */
/* of module_init. */
subsys_initcall(mpc52xx_bcom_init);
module_exit(mpc52xx_bcom_exit);
MODULE_DESCRIPTION("Freescale MPC52xx BestComm DMA");
MODULE_AUTHOR("Sylvain Munaut <tnt@246tNt.com>");
MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>");
MODULE_AUTHOR("Dale Farnsworth <dfarnsworth@mvista.com>");
MODULE_LICENSE("GPL v2");
/*
* Public header for the MPC52xx processor BestComm driver
*
*
* Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2005 Varma Electronics Oy,
* ( by Andrey Volkov <avolkov@varma-el.com> )
* Copyright (C) 2003-2004 MontaVista, Software, Inc.
* ( by Dale Farnsworth <dfarnsworth@mvista.com> )
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#ifndef __BESTCOMM_H__
#define __BESTCOMM_H__
struct bcom_bd; /* defined later on ... */
/* ======================================================================== */
/* Generic task managment */
/* ======================================================================== */
/**
* struct bcom_task - Structure describing a loaded BestComm task
*
* This structure is never built by the driver it self. It's built and
* filled the intermediate layer of the BestComm API, the task dependent
* support code.
*
* Most likely you don't need to poke around inside this structure. The
* fields are exposed in the header just for the sake of inline functions
*/
struct bcom_task {
unsigned int tasknum;
unsigned int flags;
int irq;
struct bcom_bd *bd;
phys_addr_t bd_pa;
void **cookie;
unsigned short index;
unsigned short outdex;
unsigned int num_bd;
unsigned int bd_size;
void* priv;
};
#define BCOM_FLAGS_NONE 0x00000000ul
#define BCOM_FLAGS_ENABLE_TASK (1ul << 0)
/**
* bcom_enable - Enable a BestComm task
* @tsk: The BestComm task structure
*
* This function makes sure the given task is enabled and can be run
* by the BestComm engine as needed
*/
extern void bcom_enable(struct bcom_task *tsk);
/**
* bcom_disable - Disable a BestComm task
* @tsk: The BestComm task structure
*
* This function disable a given task, making sure it's not executed
* by the BestComm engine.
*/
extern void bcom_disable(struct bcom_task *tsk);
/**
* bcom_get_task_irq - Returns the irq number of a BestComm task
* @tsk: The BestComm task structure
*/
static inline int
bcom_get_task_irq(struct bcom_task *tsk) {
return tsk->irq;
}
/* ======================================================================== */
/* BD based tasks helpers */
/* ======================================================================== */
/**
* struct bcom_bd - Structure describing a generic BestComm buffer descriptor
* @status: The current status of this buffer. Exact meaning depends on the
* task type
* @data: An array of u32 whose meaning depends on the task type.
*/
struct bcom_bd {
u32 status;
u32 data[1]; /* variable, but at least 1 */
};
#define BCOM_BD_READY 0x40000000ul
/** _bcom_next_index - Get next input index.
* @tsk: pointer to task structure
*
* Support function; Device drivers should not call this
*/
static inline int
_bcom_next_index(struct bcom_task *tsk)
{
return ((tsk->index + 1) == tsk->num_bd) ? 0 : tsk->index + 1;
}
/** _bcom_next_outdex - Get next output index.
* @tsk: pointer to task structure
*
* Support function; Device drivers should not call this
*/
static inline int
_bcom_next_outdex(struct bcom_task *tsk)
{
return ((tsk->outdex + 1) == tsk->num_bd) ? 0 : tsk->outdex + 1;
}
/**
* bcom_queue_empty - Checks if a BestComm task BD queue is empty
* @tsk: The BestComm task structure
*/
static inline int
bcom_queue_empty(struct bcom_task *tsk)
{
return tsk->index == tsk->outdex;
}
/**
* bcom_queue_full - Checks if a BestComm task BD queue is full
* @tsk: The BestComm task structure
*/
static inline int
bcom_queue_full(struct bcom_task *tsk)
{
return tsk->outdex == _bcom_next_index(tsk);
}
/**
* bcom_buffer_done - Checks if a BestComm
* @tsk: The BestComm task structure
*/
static inline int
bcom_buffer_done(struct bcom_task *tsk)
{
if (bcom_queue_empty(tsk))
return 0;
return !(tsk->bd[tsk->outdex].status & BCOM_BD_READY);
}
/**
* bcom_prepare_next_buffer - clear status of next available buffer.
* @tsk: The BestComm task structure
*
* Returns pointer to next buffer descriptor
*/
static inline struct bcom_bd *
bcom_prepare_next_buffer(struct bcom_task *tsk)
{
tsk->bd[tsk->index].status = 0; /* cleanup last status */
return &tsk->bd[tsk->index];
}
static inline void
bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie)
{
tsk->cookie[tsk->index] = cookie;
mb(); /* ensure the bd is really up-to-date */
tsk->bd[tsk->index].status |= BCOM_BD_READY;
tsk->index = _bcom_next_index(tsk);
if (tsk->flags & BCOM_FLAGS_ENABLE_TASK)
bcom_enable(tsk);
}
static inline void *
bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd)
{
void *cookie = tsk->cookie[tsk->outdex];
if (p_status)
*p_status = tsk->bd[tsk->outdex].status;
if (p_bd)
*p_bd = &tsk->bd[tsk->outdex];
tsk->outdex = _bcom_next_outdex(tsk);
return cookie;
}
#endif /* __BESTCOMM_H__ */
/*
* Private header for the MPC52xx processor BestComm driver
*
* By private, we mean that driver should not use it directly. It's meant
* to be used by the BestComm engine driver itself and by the intermediate
* layer between the core and the drivers.
*
* Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2005 Varma Electronics Oy,
* ( by Andrey Volkov <avolkov@varma-el.com> )
* Copyright (C) 2003-2004 MontaVista, Software, Inc.
* ( by Dale Farnsworth <dfarnsworth@mvista.com> )
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#ifndef __BESTCOMM_PRIV_H__
#define __BESTCOMM_PRIV_H__
#include <linux/spinlock.h>
#include <linux/of.h>
#include <asm/io.h>
#include <asm/mpc52xx.h>
#include "sram.h"
/* ======================================================================== */
/* Engine related stuff */
/* ======================================================================== */
/* Zones sizes and needed alignments */
#define BCOM_MAX_TASKS 16
#define BCOM_MAX_VAR 24
#define BCOM_MAX_INC 8
#define BCOM_MAX_FDT 64
#define BCOM_MAX_CTX 20
#define BCOM_CTX_SIZE (BCOM_MAX_CTX * sizeof(u32))
#define BCOM_CTX_ALIGN 0x100
#define BCOM_VAR_SIZE (BCOM_MAX_VAR * sizeof(u32))
#define BCOM_INC_SIZE (BCOM_MAX_INC * sizeof(u32))
#define BCOM_VAR_ALIGN 0x80
#define BCOM_FDT_SIZE (BCOM_MAX_FDT * sizeof(u32))
#define BCOM_FDT_ALIGN 0x100
/**
* struct bcom_tdt - Task Descriptor Table Entry
*
*/
struct bcom_tdt {
u32 start;
u32 stop;
u32 var;
u32 fdt;
u32 exec_status; /* used internally by BestComm engine */
u32 mvtp; /* used internally by BestComm engine */
u32 context;
u32 litbase;
};
/**
* struct bcom_engine
*
* This holds all info needed globaly to handle the engine
*/
struct bcom_engine {
struct device_node *ofnode;
struct mpc52xx_sdma __iomem *regs;
phys_addr_t regs_base;
struct bcom_tdt *tdt;
u32 *ctx;
u32 *var;
u32 *fdt;
spinlock_t lock;
};
extern struct bcom_engine *bcom_eng;
/* ======================================================================== */
/* Tasks related stuff */
/* ======================================================================== */
/* Tasks image header */
#define BCOM_TASK_MAGIC 0x4243544B /* 'BCTK' */
struct bcom_task_header {
u32 magic;
u8 desc_size; /* the size fields */
u8 var_size; /* are given in number */
u8 inc_size; /* of 32-bits words */
u8 first_var;
u8 reserved[8];
};
/* Descriptors stucture & co */
#define BCOM_DESC_NOP 0x000001f8
#define BCOM_LCD_MASK 0x80000000
#define BCOM_DRD_EXTENDED 0x40000000
#define BCOM_DRD_INITIATOR_SHIFT 21
/* Tasks pragma */
#define BCOM_PRAGMA_BIT_RSV 7 /* reserved pragma bit */
#define BCOM_PRAGMA_BIT_PRECISE_INC 6 /* increment 0=when possible, */
/* 1=iter end */
#define BCOM_PRAGMA_BIT_RST_ERROR_NO 5 /* don't reset errors on */
/* task enable */
#define BCOM_PRAGMA_BIT_PACK 4 /* pack data enable */
#define BCOM_PRAGMA_BIT_INTEGER 3 /* data alignment */
/* 0=frac(msb), 1=int(lsb) */
#define BCOM_PRAGMA_BIT_SPECREAD 2 /* XLB speculative read */
#define BCOM_PRAGMA_BIT_CW 1 /* write line buffer enable */
#define BCOM_PRAGMA_BIT_RL 0 /* read line buffer enable */
/* Looks like XLB speculative read generates XLB errors when a buffer
* is at the end of the physical memory. i.e. when accessing the
* lasts words, the engine tries to prefetch the next but there is no
* next ...
*/
#define BCOM_STD_PRAGMA ((0 << BCOM_PRAGMA_BIT_RSV) | \
(0 << BCOM_PRAGMA_BIT_PRECISE_INC) | \
(0 << BCOM_PRAGMA_BIT_RST_ERROR_NO) | \
(0 << BCOM_PRAGMA_BIT_PACK) | \
(0 << BCOM_PRAGMA_BIT_INTEGER) | \
(0 << BCOM_PRAGMA_BIT_SPECREAD) | \
(1 << BCOM_PRAGMA_BIT_CW) | \
(1 << BCOM_PRAGMA_BIT_RL))
#define BCOM_PCI_PRAGMA ((0 << BCOM_PRAGMA_BIT_RSV) | \
(0 << BCOM_PRAGMA_BIT_PRECISE_INC) | \
(0 << BCOM_PRAGMA_BIT_RST_ERROR_NO) | \
(0 << BCOM_PRAGMA_BIT_PACK) | \
(1 << BCOM_PRAGMA_BIT_INTEGER) | \
(0 << BCOM_PRAGMA_BIT_SPECREAD) | \
(1 << BCOM_PRAGMA_BIT_CW) | \
(1 << BCOM_PRAGMA_BIT_RL))
#define BCOM_ATA_PRAGMA BCOM_STD_PRAGMA
#define BCOM_CRC16_DP_0_PRAGMA BCOM_STD_PRAGMA
#define BCOM_CRC16_DP_1_PRAGMA BCOM_STD_PRAGMA
#define BCOM_FEC_RX_BD_PRAGMA BCOM_STD_PRAGMA
#define BCOM_FEC_TX_BD_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_DP_0_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_DP_1_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_DP_2_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_DP_3_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_DP_BD_0_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_DP_BD_1_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_RX_BD_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_TX_BD_PRAGMA BCOM_STD_PRAGMA
#define BCOM_GEN_LPC_PRAGMA BCOM_STD_PRAGMA
#define BCOM_PCI_RX_PRAGMA BCOM_PCI_PRAGMA
#define BCOM_PCI_TX_PRAGMA BCOM_PCI_PRAGMA
/* Initiators number */
#define BCOM_INITIATOR_ALWAYS 0
#define BCOM_INITIATOR_SCTMR_0 1
#define BCOM_INITIATOR_SCTMR_1 2
#define BCOM_INITIATOR_FEC_RX 3
#define BCOM_INITIATOR_FEC_TX 4
#define BCOM_INITIATOR_ATA_RX 5
#define BCOM_INITIATOR_ATA_TX 6
#define BCOM_INITIATOR_SCPCI_RX 7
#define BCOM_INITIATOR_SCPCI_TX 8
#define BCOM_INITIATOR_PSC3_RX 9
#define BCOM_INITIATOR_PSC3_TX 10
#define BCOM_INITIATOR_PSC2_RX 11
#define BCOM_INITIATOR_PSC2_TX 12
#define BCOM_INITIATOR_PSC1_RX 13
#define BCOM_INITIATOR_PSC1_TX 14
#define BCOM_INITIATOR_SCTMR_2 15
#define BCOM_INITIATOR_SCLPC 16
#define BCOM_INITIATOR_PSC5_RX 17
#define BCOM_INITIATOR_PSC5_TX 18
#define BCOM_INITIATOR_PSC4_RX 19
#define BCOM_INITIATOR_PSC4_TX 20
#define BCOM_INITIATOR_I2C2_RX 21
#define BCOM_INITIATOR_I2C2_TX 22
#define BCOM_INITIATOR_I2C1_RX 23
#define BCOM_INITIATOR_I2C1_TX 24
#define BCOM_INITIATOR_PSC6_RX 25
#define BCOM_INITIATOR_PSC6_TX 26
#define BCOM_INITIATOR_IRDA_RX 25
#define BCOM_INITIATOR_IRDA_TX 26
#define BCOM_INITIATOR_SCTMR_3 27
#define BCOM_INITIATOR_SCTMR_4 28
#define BCOM_INITIATOR_SCTMR_5 29
#define BCOM_INITIATOR_SCTMR_6 30
#define BCOM_INITIATOR_SCTMR_7 31
/* Initiators priorities */
#define BCOM_IPR_ALWAYS 7
#define BCOM_IPR_SCTMR_0 2
#define BCOM_IPR_SCTMR_1 2
#define BCOM_IPR_FEC_RX 6
#define BCOM_IPR_FEC_TX 5
#define BCOM_IPR_ATA_RX 4
#define BCOM_IPR_ATA_TX 3
#define BCOM_IPR_SCPCI_RX 2
#define BCOM_IPR_SCPCI_TX 2
#define BCOM_IPR_PSC3_RX 2
#define BCOM_IPR_PSC3_TX 2
#define BCOM_IPR_PSC2_RX 2
#define BCOM_IPR_PSC2_TX 2
#define BCOM_IPR_PSC1_RX 2
#define BCOM_IPR_PSC1_TX 2
#define BCOM_IPR_SCTMR_2 2
#define BCOM_IPR_SCLPC 2
#define BCOM_IPR_PSC5_RX 2
#define BCOM_IPR_PSC5_TX 2
#define BCOM_IPR_PSC4_RX 2
#define BCOM_IPR_PSC4_TX 2
#define BCOM_IPR_I2C2_RX 2
#define BCOM_IPR_I2C2_TX 2
#define BCOM_IPR_I2C1_RX 2
#define BCOM_IPR_I2C1_TX 2
#define BCOM_IPR_PSC6_RX 2
#define BCOM_IPR_PSC6_TX 2
#define BCOM_IPR_IRDA_RX 2
#define BCOM_IPR_IRDA_TX 2
#define BCOM_IPR_SCTMR_3 2
#define BCOM_IPR_SCTMR_4 2
#define BCOM_IPR_SCTMR_5 2
#define BCOM_IPR_SCTMR_6 2
#define BCOM_IPR_SCTMR_7 2
/* ======================================================================== */
/* API */
/* ======================================================================== */
extern struct bcom_task *bcom_task_alloc(int bd_count, int bd_size, int priv_size);
extern void bcom_task_free(struct bcom_task *tsk);
extern int bcom_load_image(int task, u32 *task_image);
extern void bcom_set_initiator(int task, int initiator);
#define TASK_ENABLE 0x8000
static inline void
bcom_enable_task(int task)
{
u16 reg;
reg = in_be16(&bcom_eng->regs->tcr[task]);
out_be16(&bcom_eng->regs->tcr[task], reg | TASK_ENABLE);
}
static inline void
bcom_disable_task(int task)
{
u16 reg = in_be16(&bcom_eng->regs->tcr[task]);
out_be16(&bcom_eng->regs->tcr[task], reg & ~TASK_ENABLE);
}
static inline u32 *
bcom_task_desc(int task)
{
return bcom_sram_pa2va(bcom_eng->tdt[task].start);
}
static inline int
bcom_task_num_descs(int task)
{
return (bcom_eng->tdt[task].stop - bcom_eng->tdt[task].start)/sizeof(u32) + 1;
}
static inline u32 *
bcom_task_var(int task)
{
return bcom_sram_pa2va(bcom_eng->tdt[task].var);
}
static inline u32 *
bcom_task_inc(int task)
{
return &bcom_task_var(task)[BCOM_MAX_VAR];
}
static inline int
bcom_drd_is_extended(u32 desc)
{
return (desc) & BCOM_DRD_EXTENDED;
}
static inline int
bcom_desc_is_drd(u32 desc)
{
return !(desc & BCOM_LCD_MASK) && desc != BCOM_DESC_NOP;
}
static inline int
bcom_desc_initiator(u32 desc)
{
return (desc >> BCOM_DRD_INITIATOR_SHIFT) & 0x1f;
}
static inline void
bcom_set_desc_initiator(u32 *desc, int initiator)
{
*desc = (*desc & ~(0x1f << BCOM_DRD_INITIATOR_SHIFT)) |
((initiator & 0x1f) << BCOM_DRD_INITIATOR_SHIFT);
}
static inline void
bcom_set_task_pragma(int task, int pragma)
{
u32 *fdt = &bcom_eng->tdt[task].fdt;
*fdt = (*fdt & ~0xff) | pragma;
}
static inline void
bcom_set_task_auto_start(int task, int next_task)
{
u16 __iomem *tcr = &bcom_eng->regs->tcr[task];
out_be16(tcr, (in_be16(tcr) & ~0xff) | 0x00c0 | next_task);
}
static inline void
bcom_set_tcr_initiator(int task, int initiator)
{
u16 __iomem *tcr = &bcom_eng->regs->tcr[task];
out_be16(tcr, (in_be16(tcr) & ~0x1f00) | ((initiator & 0x1f) << 8));
}
#endif /* __BESTCOMM_PRIV_H__ */
/*
* Bestcomm FEC tasks driver
*
*
* Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2003-2004 MontaVista, Software, Inc.
* ( by Dale Farnsworth <dfarnsworth@mvista.com> )
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <asm/io.h>
#include "bestcomm.h"
#include "bestcomm_priv.h"
#include "fec.h"
/* ======================================================================== */
/* Task image/var/inc */
/* ======================================================================== */
/* fec tasks images */
extern u32 bcom_fec_rx_task[];
extern u32 bcom_fec_tx_task[];
/* rx task vars that need to be set before enabling the task */
struct bcom_fec_rx_var {
u32 enable; /* (u16*) address of task's control register */
u32 fifo; /* (u32*) address of fec's fifo */
u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
u32 bd_start; /* (struct bcom_bd*) current bd */
u32 buffer_size; /* size of receive buffer */
};
/* rx task incs that need to be set before enabling the task */
struct bcom_fec_rx_inc {
u16 pad0;
s16 incr_bytes;
u16 pad1;
s16 incr_dst;
u16 pad2;
s16 incr_dst_ma;
};
/* tx task vars that need to be set before enabling the task */
struct bcom_fec_tx_var {
u32 DRD; /* (u32*) address of self-modified DRD */
u32 fifo; /* (u32*) address of fec's fifo */
u32 enable; /* (u16*) address of task's control register */
u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
u32 bd_start; /* (struct bcom_bd*) current bd */
u32 buffer_size; /* set by uCode for each packet */
};
/* tx task incs that need to be set before enabling the task */
struct bcom_fec_tx_inc {
u16 pad0;
s16 incr_bytes;
u16 pad1;
s16 incr_src;
u16 pad2;
s16 incr_src_ma;
};
/* private structure in the task */
struct bcom_fec_priv {
phys_addr_t fifo;
int maxbufsize;
};
/* ======================================================================== */
/* Task support code */
/* ======================================================================== */
struct bcom_task *
bcom_fec_rx_init(int queue_len, phys_addr_t fifo, int maxbufsize)
{
struct bcom_task *tsk;
struct bcom_fec_priv *priv;
tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_fec_bd),
sizeof(struct bcom_fec_priv));
if (!tsk)
return NULL;
tsk->flags = BCOM_FLAGS_NONE;
priv = tsk->priv;
priv->fifo = fifo;
priv->maxbufsize = maxbufsize;
if (bcom_fec_rx_reset(tsk)) {
bcom_task_free(tsk);
return NULL;
}
return tsk;
}
EXPORT_SYMBOL_GPL(bcom_fec_rx_init);
int
bcom_fec_rx_reset(struct bcom_task *tsk)
{
struct bcom_fec_priv *priv = tsk->priv;
struct bcom_fec_rx_var *var;
struct bcom_fec_rx_inc *inc;
/* Shutdown the task */
bcom_disable_task(tsk->tasknum);
/* Reset the microcode */
var = (struct bcom_fec_rx_var *) bcom_task_var(tsk->tasknum);
inc = (struct bcom_fec_rx_inc *) bcom_task_inc(tsk->tasknum);
if (bcom_load_image(tsk->tasknum, bcom_fec_rx_task))
return -1;
var->enable = bcom_eng->regs_base +
offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
var->fifo = (u32) priv->fifo;
var->bd_base = tsk->bd_pa;
var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
var->bd_start = tsk->bd_pa;
var->buffer_size = priv->maxbufsize;
inc->incr_bytes = -(s16)sizeof(u32); /* These should be in the */
inc->incr_dst = sizeof(u32); /* task image, but we stick */
inc->incr_dst_ma= sizeof(u8); /* to the official ones */
/* Reset the BDs */
tsk->index = 0;
tsk->outdex = 0;
memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
/* Configure some stuff */
bcom_set_task_pragma(tsk->tasknum, BCOM_FEC_RX_BD_PRAGMA);
bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_FEC_RX], BCOM_IPR_FEC_RX);
out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
return 0;
}
EXPORT_SYMBOL_GPL(bcom_fec_rx_reset);
void
bcom_fec_rx_release(struct bcom_task *tsk)
{
/* Nothing special for the FEC tasks */
bcom_task_free(tsk);
}
EXPORT_SYMBOL_GPL(bcom_fec_rx_release);
/* Return 2nd to last DRD */
/* This is an ugly hack, but at least it's only done
once at initialization */
static u32 *self_modified_drd(int tasknum)
{
u32 *desc;
int num_descs;
int drd_count;
int i;
num_descs = bcom_task_num_descs(tasknum);
desc = bcom_task_desc(tasknum) + num_descs - 1;
drd_count = 0;
for (i=0; i<num_descs; i++, desc--)
if (bcom_desc_is_drd(*desc) && ++drd_count == 3)
break;
return desc;
}
struct bcom_task *
bcom_fec_tx_init(int queue_len, phys_addr_t fifo)
{
struct bcom_task *tsk;
struct bcom_fec_priv *priv;
tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_fec_bd),
sizeof(struct bcom_fec_priv));
if (!tsk)
return NULL;
tsk->flags = BCOM_FLAGS_ENABLE_TASK;
priv = tsk->priv;
priv->fifo = fifo;
if (bcom_fec_tx_reset(tsk)) {
bcom_task_free(tsk);
return NULL;
}
return tsk;
}
EXPORT_SYMBOL_GPL(bcom_fec_tx_init);
int
bcom_fec_tx_reset(struct bcom_task *tsk)
{
struct bcom_fec_priv *priv = tsk->priv;
struct bcom_fec_tx_var *var;
struct bcom_fec_tx_inc *inc;
/* Shutdown the task */
bcom_disable_task(tsk->tasknum);
/* Reset the microcode */
var = (struct bcom_fec_tx_var *) bcom_task_var(tsk->tasknum);
inc = (struct bcom_fec_tx_inc *) bcom_task_inc(tsk->tasknum);
if (bcom_load_image(tsk->tasknum, bcom_fec_tx_task))
return -1;
var->enable = bcom_eng->regs_base +
offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
var->fifo = (u32) priv->fifo;
var->DRD = bcom_sram_va2pa(self_modified_drd(tsk->tasknum));
var->bd_base = tsk->bd_pa;
var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
var->bd_start = tsk->bd_pa;
inc->incr_bytes = -(s16)sizeof(u32); /* These should be in the */
inc->incr_src = sizeof(u32); /* task image, but we stick */
inc->incr_src_ma= sizeof(u8); /* to the official ones */
/* Reset the BDs */
tsk->index = 0;
tsk->outdex = 0;
memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
/* Configure some stuff */
bcom_set_task_pragma(tsk->tasknum, BCOM_FEC_TX_BD_PRAGMA);
bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_FEC_TX], BCOM_IPR_FEC_TX);
out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
return 0;
}
EXPORT_SYMBOL_GPL(bcom_fec_tx_reset);
void
bcom_fec_tx_release(struct bcom_task *tsk)
{
/* Nothing special for the FEC tasks */
bcom_task_free(tsk);
}
EXPORT_SYMBOL_GPL(bcom_fec_tx_release);
MODULE_DESCRIPTION("BestComm FEC tasks driver");
MODULE_AUTHOR("Dale Farnsworth <dfarnsworth@mvista.com>");
MODULE_LICENSE("GPL v2");
/*
* Header for Bestcomm FEC tasks driver
*
*
* Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2003-2004 MontaVista, Software, Inc.
* ( by Dale Farnsworth <dfarnsworth@mvista.com> )
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#ifndef __BESTCOMM_FEC_H__
#define __BESTCOMM_FEC_H__
struct bcom_fec_bd {
u32 status;
u32 skb_pa;
};
#define BCOM_FEC_TX_BD_TFD 0x08000000ul /* transmit frame done */
#define BCOM_FEC_TX_BD_TC 0x04000000ul /* transmit CRC */
#define BCOM_FEC_TX_BD_ABC 0x02000000ul /* append bad CRC */
#define BCOM_FEC_RX_BD_L 0x08000000ul /* buffer is last in frame */
#define BCOM_FEC_RX_BD_BC 0x00800000ul /* DA is broadcast */
#define BCOM_FEC_RX_BD_MC 0x00400000ul /* DA is multicast and not broadcast */
#define BCOM_FEC_RX_BD_LG 0x00200000ul /* Rx frame length violation */
#define BCOM_FEC_RX_BD_NO 0x00100000ul /* Rx non-octet aligned frame */
#define BCOM_FEC_RX_BD_CR 0x00040000ul /* Rx CRC error */
#define BCOM_FEC_RX_BD_OV 0x00020000ul /* overrun */
#define BCOM_FEC_RX_BD_TR 0x00010000ul /* Rx frame truncated */
#define BCOM_FEC_RX_BD_LEN_MASK 0x000007fful /* mask for length of received frame */
#define BCOM_FEC_RX_BD_ERRORS (BCOM_FEC_RX_BD_LG | BCOM_FEC_RX_BD_NO | \
BCOM_FEC_RX_BD_CR | BCOM_FEC_RX_BD_OV | BCOM_FEC_RX_BD_TR)
extern struct bcom_task *
bcom_fec_rx_init(int queue_len, phys_addr_t fifo, int maxbufsize);
extern int
bcom_fec_rx_reset(struct bcom_task *tsk);
extern void
bcom_fec_rx_release(struct bcom_task *tsk);
extern struct bcom_task *
bcom_fec_tx_init(int queue_len, phys_addr_t fifo);
extern int
bcom_fec_tx_reset(struct bcom_task *tsk);
extern void
bcom_fec_tx_release(struct bcom_task *tsk);
#endif /* __BESTCOMM_FEC_H__ */
/*
* Driver for MPC52xx processor BestComm General Buffer Descriptor
*
* Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2006 AppSpec Computer Technologies Corp.
* Jeff Gibbons <jeff.gibbons@appspec.com>
*
* 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/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/types.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/mpc52xx.h>
#include "bestcomm.h"
#include "bestcomm_priv.h"
#include "gen_bd.h"
/* ======================================================================== */
/* Task image/var/inc */
/* ======================================================================== */
/* gen_bd tasks images */
extern u32 bcom_gen_bd_rx_task[];
extern u32 bcom_gen_bd_tx_task[];
/* rx task vars that need to be set before enabling the task */
struct bcom_gen_bd_rx_var {
u32 enable; /* (u16*) address of task's control register */
u32 fifo; /* (u32*) address of gen_bd's fifo */
u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
u32 bd_start; /* (struct bcom_bd*) current bd */
u32 buffer_size; /* size of receive buffer */
};
/* rx task incs that need to be set before enabling the task */
struct bcom_gen_bd_rx_inc {
u16 pad0;
s16 incr_bytes;
u16 pad1;
s16 incr_dst;
};
/* tx task vars that need to be set before enabling the task */
struct bcom_gen_bd_tx_var {
u32 fifo; /* (u32*) address of gen_bd's fifo */
u32 enable; /* (u16*) address of task's control register */
u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
u32 bd_start; /* (struct bcom_bd*) current bd */
u32 buffer_size; /* set by uCode for each packet */
};
/* tx task incs that need to be set before enabling the task */
struct bcom_gen_bd_tx_inc {
u16 pad0;
s16 incr_bytes;
u16 pad1;
s16 incr_src;
u16 pad2;
s16 incr_src_ma;
};
/* private structure */
struct bcom_gen_bd_priv {
phys_addr_t fifo;
int initiator;
int ipr;
int maxbufsize;
};
/* ======================================================================== */
/* Task support code */
/* ======================================================================== */
struct bcom_task *
bcom_gen_bd_rx_init(int queue_len, phys_addr_t fifo,
int initiator, int ipr, int maxbufsize)
{
struct bcom_task *tsk;
struct bcom_gen_bd_priv *priv;
tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_gen_bd),
sizeof(struct bcom_gen_bd_priv));
if (!tsk)
return NULL;
tsk->flags = BCOM_FLAGS_NONE;
priv = tsk->priv;
priv->fifo = fifo;
priv->initiator = initiator;
priv->ipr = ipr;
priv->maxbufsize = maxbufsize;
if (bcom_gen_bd_rx_reset(tsk)) {
bcom_task_free(tsk);
return NULL;
}
return tsk;
}
EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_init);
int
bcom_gen_bd_rx_reset(struct bcom_task *tsk)
{
struct bcom_gen_bd_priv *priv = tsk->priv;
struct bcom_gen_bd_rx_var *var;
struct bcom_gen_bd_rx_inc *inc;
/* Shutdown the task */
bcom_disable_task(tsk->tasknum);
/* Reset the microcode */
var = (struct bcom_gen_bd_rx_var *) bcom_task_var(tsk->tasknum);
inc = (struct bcom_gen_bd_rx_inc *) bcom_task_inc(tsk->tasknum);
if (bcom_load_image(tsk->tasknum, bcom_gen_bd_rx_task))
return -1;
var->enable = bcom_eng->regs_base +
offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
var->fifo = (u32) priv->fifo;
var->bd_base = tsk->bd_pa;
var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
var->bd_start = tsk->bd_pa;
var->buffer_size = priv->maxbufsize;
inc->incr_bytes = -(s16)sizeof(u32);
inc->incr_dst = sizeof(u32);
/* Reset the BDs */
tsk->index = 0;
tsk->outdex = 0;
memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
/* Configure some stuff */
bcom_set_task_pragma(tsk->tasknum, BCOM_GEN_RX_BD_PRAGMA);
bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
out_8(&bcom_eng->regs->ipr[priv->initiator], priv->ipr);
bcom_set_initiator(tsk->tasknum, priv->initiator);
out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
return 0;
}
EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_reset);
void
bcom_gen_bd_rx_release(struct bcom_task *tsk)
{
/* Nothing special for the GenBD tasks */
bcom_task_free(tsk);
}
EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_release);
extern struct bcom_task *
bcom_gen_bd_tx_init(int queue_len, phys_addr_t fifo,
int initiator, int ipr)
{
struct bcom_task *tsk;
struct bcom_gen_bd_priv *priv;
tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_gen_bd),
sizeof(struct bcom_gen_bd_priv));
if (!tsk)
return NULL;
tsk->flags = BCOM_FLAGS_NONE;
priv = tsk->priv;
priv->fifo = fifo;
priv->initiator = initiator;
priv->ipr = ipr;
if (bcom_gen_bd_tx_reset(tsk)) {
bcom_task_free(tsk);
return NULL;
}
return tsk;
}
EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_init);
int
bcom_gen_bd_tx_reset(struct bcom_task *tsk)
{
struct bcom_gen_bd_priv *priv = tsk->priv;
struct bcom_gen_bd_tx_var *var;
struct bcom_gen_bd_tx_inc *inc;
/* Shutdown the task */
bcom_disable_task(tsk->tasknum);
/* Reset the microcode */
var = (struct bcom_gen_bd_tx_var *) bcom_task_var(tsk->tasknum);
inc = (struct bcom_gen_bd_tx_inc *) bcom_task_inc(tsk->tasknum);
if (bcom_load_image(tsk->tasknum, bcom_gen_bd_tx_task))
return -1;
var->enable = bcom_eng->regs_base +
offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
var->fifo = (u32) priv->fifo;
var->bd_base = tsk->bd_pa;
var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
var->bd_start = tsk->bd_pa;
inc->incr_bytes = -(s16)sizeof(u32);
inc->incr_src = sizeof(u32);
inc->incr_src_ma = sizeof(u8);
/* Reset the BDs */
tsk->index = 0;
tsk->outdex = 0;
memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
/* Configure some stuff */
bcom_set_task_pragma(tsk->tasknum, BCOM_GEN_TX_BD_PRAGMA);
bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
out_8(&bcom_eng->regs->ipr[priv->initiator], priv->ipr);
bcom_set_initiator(tsk->tasknum, priv->initiator);
out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
return 0;
}
EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_reset);
void
bcom_gen_bd_tx_release(struct bcom_task *tsk)
{
/* Nothing special for the GenBD tasks */
bcom_task_free(tsk);
}
EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_release);
MODULE_DESCRIPTION("BestComm General Buffer Descriptor tasks driver");
MODULE_AUTHOR("Jeff Gibbons <jeff.gibbons@appspec.com>");
MODULE_LICENSE("GPL v2");
/*
* Header for Bestcomm General Buffer Descriptor tasks driver
*
*
* Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2006 AppSpec Computer Technologies Corp.
* Jeff Gibbons <jeff.gibbons@appspec.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
*
*/
#ifndef __BESTCOMM_GEN_BD_H__
#define __BESTCOMM_GEN_BD_H__
struct bcom_gen_bd {
u32 status;
u32 buf_pa;
};
extern struct bcom_task *
bcom_gen_bd_rx_init(int queue_len, phys_addr_t fifo,
int initiator, int ipr, int maxbufsize);
extern int
bcom_gen_bd_rx_reset(struct bcom_task *tsk);
extern void
bcom_gen_bd_rx_release(struct bcom_task *tsk);
extern struct bcom_task *
bcom_gen_bd_tx_init(int queue_len, phys_addr_t fifo,
int initiator, int ipr);
extern int
bcom_gen_bd_tx_reset(struct bcom_task *tsk);
extern void
bcom_gen_bd_tx_release(struct bcom_task *tsk);
#endif /* __BESTCOMM_GEN_BD_H__ */
/*
* Simple memory allocator for on-board SRAM
*
*
* Maintainer : Sylvain Munaut <tnt@246tNt.com>
*
* Copyright (C) 2005 Sylvain Munaut <tnt@246tNt.com>
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/of.h>
#include <asm/io.h>
#include <asm/mmu.h>
#include "sram.h"
/* Struct keeping our 'state' */
struct bcom_sram *bcom_sram = NULL;
EXPORT_SYMBOL_GPL(bcom_sram); /* needed for inline functions */
/* ======================================================================== */
/* Public API */
/* ======================================================================== */
/* DO NOT USE in interrupts, if needed in irq handler, we should use the
_irqsave version of the spin_locks */
int bcom_sram_init(struct device_node *sram_node, char *owner)
{
int rv;
const u32 *regaddr_p;
u64 regaddr64, size64;
unsigned int psize;
/* Create our state struct */
if (bcom_sram) {
printk(KERN_ERR "%s: bcom_sram_init: "
"Already initialized !\n", owner);
return -EBUSY;
}
bcom_sram = kmalloc(sizeof(struct bcom_sram), GFP_KERNEL);
if (!bcom_sram) {
printk(KERN_ERR "%s: bcom_sram_init: "
"Couldn't allocate internal state !\n", owner);
return -ENOMEM;
}
/* Get address and size of the sram */
regaddr_p = of_get_address(sram_node, 0, &size64, NULL);
if (!regaddr_p) {
printk(KERN_ERR "%s: bcom_sram_init: "
"Invalid device node !\n", owner);
rv = -EINVAL;
goto error_free;
}
regaddr64 = of_translate_address(sram_node, regaddr_p);
bcom_sram->base_phys = (phys_addr_t) regaddr64;
bcom_sram->size = (unsigned int) size64;
/* Request region */
if (!request_mem_region(bcom_sram->base_phys, bcom_sram->size, owner)) {
printk(KERN_ERR "%s: bcom_sram_init: "
"Couldn't request region !\n", owner);
rv = -EBUSY;
goto error_free;
}
/* Map SRAM */
/* sram is not really __iomem */
bcom_sram->base_virt = (void*) ioremap(bcom_sram->base_phys, bcom_sram->size);
if (!bcom_sram->base_virt) {
printk(KERN_ERR "%s: bcom_sram_init: "
"Map error SRAM zone 0x%08lx (0x%0x)!\n",
owner, bcom_sram->base_phys, bcom_sram->size );
rv = -ENOMEM;
goto error_release;
}
/* Create an rheap (defaults to 32 bits word alignment) */
bcom_sram->rh = rh_create(4);
/* Attach the free zones */
#if 0
/* Currently disabled ... for future use only */
reg_addr_p = of_get_property(sram_node, "available", &psize);
#else
regaddr_p = NULL;
psize = 0;
#endif
if (!regaddr_p || !psize) {
/* Attach the whole zone */
rh_attach_region(bcom_sram->rh, 0, bcom_sram->size);
} else {
/* Attach each zone independently */
while (psize >= 2 * sizeof(u32)) {
phys_addr_t zbase = of_translate_address(sram_node, regaddr_p);
rh_attach_region(bcom_sram->rh, zbase - bcom_sram->base_phys, regaddr_p[1]);
regaddr_p += 2;
psize -= 2 * sizeof(u32);
}
}
/* Init our spinlock */
spin_lock_init(&bcom_sram->lock);
return 0;
error_release:
release_mem_region(bcom_sram->base_phys, bcom_sram->size);
error_free:
kfree(bcom_sram);
bcom_sram = NULL;
return rv;
}
EXPORT_SYMBOL_GPL(bcom_sram_init);
void bcom_sram_cleanup(void)
{
/* Free resources */
if (bcom_sram) {
rh_destroy(bcom_sram->rh);
iounmap((void __iomem *)bcom_sram->base_virt);
release_mem_region(bcom_sram->base_phys, bcom_sram->size);
kfree(bcom_sram);
bcom_sram = NULL;
}
}
EXPORT_SYMBOL_GPL(bcom_sram_cleanup);
void* bcom_sram_alloc(int size, int align, phys_addr_t *phys)
{
unsigned long offset;
spin_lock(&bcom_sram->lock);
offset = rh_alloc_align(bcom_sram->rh, size, align, NULL);
spin_unlock(&bcom_sram->lock);
if (IS_ERR_VALUE(offset))
return NULL;
*phys = bcom_sram->base_phys + offset;
return bcom_sram->base_virt + offset;
}
EXPORT_SYMBOL_GPL(bcom_sram_alloc);
void bcom_sram_free(void *ptr)
{
unsigned long offset;
if (!ptr)
return;
offset = ptr - bcom_sram->base_virt;
spin_lock(&bcom_sram->lock);
rh_free(bcom_sram->rh, offset);
spin_unlock(&bcom_sram->lock);
}
EXPORT_SYMBOL_GPL(bcom_sram_free);
/*
* Handling of a sram zone for bestcomm
*
*
* Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#ifndef __BESTCOMM_SRAM_H__
#define __BESTCOMM_SRAM_H__
#include <asm/rheap.h>
#include <asm/mmu.h>
#include <linux/spinlock.h>
/* Structure used internally */
/* The internals are here for the inline functions
* sake, certainly not for the user to mess with !
*/
struct bcom_sram {
phys_addr_t base_phys;
void *base_virt;
unsigned int size;
rh_info_t *rh;
spinlock_t lock;
};
extern struct bcom_sram *bcom_sram;
/* Public API */
extern int bcom_sram_init(struct device_node *sram_node, char *owner);
extern void bcom_sram_cleanup(void);
extern void* bcom_sram_alloc(int size, int align, phys_addr_t *phys);
extern void bcom_sram_free(void *ptr);
static inline phys_addr_t bcom_sram_va2pa(void *va) {
return bcom_sram->base_phys +
(unsigned long)(va - bcom_sram->base_virt);
}
static inline void *bcom_sram_pa2va(phys_addr_t pa) {
return bcom_sram->base_virt +
(unsigned long)(pa - bcom_sram->base_phys);
}
#endif /* __BESTCOMM_SRAM_H__ */
......@@ -255,7 +255,7 @@ DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_transpare
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_transparent)
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_transparent);
......
......@@ -102,6 +102,7 @@ config 44x
config 8xx
bool "8xx"
select PPC_LIB_RHEAP
config E200
bool "e200"
......@@ -798,6 +799,7 @@ config CPM1
config CPM2
bool
depends on 8260 || MPC8560 || MPC8555
select PPC_LIB_RHEAP
default y
help
The CPM2 (Communications Processor Module) is a coprocessor on
......@@ -1277,6 +1279,10 @@ config BOOT_LOAD
config PIN_TLB
bool "Pinned Kernel TLBs (860 ONLY)"
depends on ADVANCED_OPTIONS && 8xx
config PPC_LIB_RHEAP
bool
endmenu
source "net/Kconfig"
......
......@@ -107,7 +107,7 @@ struct ehca_sport {
struct ehca_shca {
struct ib_device ib_device;
struct ibmebus_dev *ibmebus_dev;
struct of_device *ofdev;
u8 num_ports;
int hw_level;
struct list_head shca_list;
......
......@@ -123,7 +123,7 @@ int ehca_create_eq(struct ehca_shca *shca,
/* register interrupt handlers and initialize work queues */
if (type == EHCA_EQ) {
ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt_eq,
ret = ibmebus_request_irq(eq->ist, ehca_interrupt_eq,
IRQF_DISABLED, "ehca_eq",
(void *)shca);
if (ret < 0)
......@@ -131,7 +131,7 @@ int ehca_create_eq(struct ehca_shca *shca,
tasklet_init(&eq->interrupt_task, ehca_tasklet_eq, (long)shca);
} else if (type == EHCA_NEQ) {
ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt_neq,
ret = ibmebus_request_irq(eq->ist, ehca_interrupt_neq,
IRQF_DISABLED, "ehca_neq",
(void *)shca);
if (ret < 0)
......@@ -171,7 +171,7 @@ int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq)
u64 h_ret;
spin_lock_irqsave(&eq->spinlock, flags);
ibmebus_free_irq(NULL, eq->ist, (void *)shca);
ibmebus_free_irq(eq->ist, (void *)shca);
h_ret = hipz_h_destroy_eq(shca->ipz_hca_handle, eq);
......
......@@ -404,7 +404,7 @@ int ehca_init_device(struct ehca_shca *shca)
shca->ib_device.node_type = RDMA_NODE_IB_CA;
shca->ib_device.phys_port_cnt = shca->num_ports;
shca->ib_device.num_comp_vectors = 1;
shca->ib_device.dma_device = &shca->ibmebus_dev->ofdev.dev;
shca->ib_device.dma_device = &shca->ofdev->dev;
shca->ib_device.query_device = ehca_query_device;
shca->ib_device.query_port = ehca_query_port;
shca->ib_device.query_gid = ehca_query_gid;
......@@ -658,7 +658,7 @@ static struct attribute_group ehca_dev_attr_grp = {
.attrs = ehca_dev_attrs
};
static int __devinit ehca_probe(struct ibmebus_dev *dev,
static int __devinit ehca_probe(struct of_device *dev,
const struct of_device_id *id)
{
struct ehca_shca *shca;
......@@ -666,16 +666,16 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
struct ib_pd *ibpd;
int ret;
handle = of_get_property(dev->ofdev.node, "ibm,hca-handle", NULL);
handle = of_get_property(dev->node, "ibm,hca-handle", NULL);
if (!handle) {
ehca_gen_err("Cannot get eHCA handle for adapter: %s.",
dev->ofdev.node->full_name);
dev->node->full_name);
return -ENODEV;
}
if (!(*handle)) {
ehca_gen_err("Wrong eHCA handle for adapter: %s.",
dev->ofdev.node->full_name);
dev->node->full_name);
return -ENODEV;
}
......@@ -686,9 +686,9 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
}
mutex_init(&shca->modify_mutex);
shca->ibmebus_dev = dev;
shca->ofdev = dev;
shca->ipz_hca_handle.handle = *handle;
dev->ofdev.dev.driver_data = shca;
dev->dev.driver_data = shca;
ret = ehca_sense_attributes(shca);
if (ret < 0) {
......@@ -764,7 +764,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
}
}
ret = sysfs_create_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp);
ret = sysfs_create_group(&dev->dev.kobj, &ehca_dev_attr_grp);
if (ret) /* only complain; we can live without attributes */
ehca_err(&shca->ib_device,
"Cannot create device attributes ret=%d", ret);
......@@ -814,12 +814,12 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
return -EINVAL;
}
static int __devexit ehca_remove(struct ibmebus_dev *dev)
static int __devexit ehca_remove(struct of_device *dev)
{
struct ehca_shca *shca = dev->ofdev.dev.driver_data;
struct ehca_shca *shca = dev->dev.driver_data;
int ret;
sysfs_remove_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp);
sysfs_remove_group(&dev->dev.kobj, &ehca_dev_attr_grp);
if (ehca_open_aqp1 == 1) {
int i;
......@@ -870,11 +870,11 @@ static struct of_device_id ehca_device_table[] =
{},
};
static struct ibmebus_driver ehca_driver = {
.name = "ehca",
.id_table = ehca_device_table,
.probe = ehca_probe,
.remove = ehca_remove,
static struct of_platform_driver ehca_driver = {
.name = "ehca",
.match_table = ehca_device_table,
.probe = ehca_probe,
.remove = ehca_remove,
};
void ehca_poll_eqs(unsigned long data)
......
......@@ -388,7 +388,7 @@ struct ehea_port_res {
#define EHEA_MAX_PORTS 16
struct ehea_adapter {
u64 handle;
struct ibmebus_dev *ebus_dev;
struct of_device *ofdev;
struct ehea_port *port[EHEA_MAX_PORTS];
struct ehea_eq *neq; /* notification event queue */
struct tasklet_struct neq_tasklet;
......
......@@ -98,10 +98,10 @@ struct work_struct ehea_rereg_mr_task;
struct semaphore dlpar_mem_lock;
static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
static int __devinit ehea_probe_adapter(struct of_device *dev,
const struct of_device_id *id);
static int __devexit ehea_remove(struct ibmebus_dev *dev);
static int __devexit ehea_remove(struct of_device *dev);
static struct of_device_id ehea_device_table[] = {
{
......@@ -111,9 +111,9 @@ static struct of_device_id ehea_device_table[] = {
{},
};
static struct ibmebus_driver ehea_driver = {
static struct of_platform_driver ehea_driver = {
.name = "ehea",
.id_table = ehea_device_table,
.match_table = ehea_device_table,
.probe = ehea_probe_adapter,
.remove = ehea_remove,
};
......@@ -1044,7 +1044,7 @@ static int ehea_reg_interrupts(struct net_device *dev)
snprintf(port->int_aff_name, EHEA_IRQ_NAME_SIZE - 1, "%s-aff",
dev->name);
ret = ibmebus_request_irq(NULL, port->qp_eq->attr.ist1,
ret = ibmebus_request_irq(port->qp_eq->attr.ist1,
ehea_qp_aff_irq_handler,
IRQF_DISABLED, port->int_aff_name, port);
if (ret) {
......@@ -1062,7 +1062,7 @@ static int ehea_reg_interrupts(struct net_device *dev)
pr = &port->port_res[i];
snprintf(pr->int_send_name, EHEA_IRQ_NAME_SIZE - 1,
"%s-queue%d", dev->name, i);
ret = ibmebus_request_irq(NULL, pr->eq->attr.ist1,
ret = ibmebus_request_irq(pr->eq->attr.ist1,
ehea_recv_irq_handler,
IRQF_DISABLED, pr->int_send_name,
pr);
......@@ -1083,11 +1083,11 @@ static int ehea_reg_interrupts(struct net_device *dev)
out_free_req:
while (--i >= 0) {
u32 ist = port->port_res[i].eq->attr.ist1;
ibmebus_free_irq(NULL, ist, &port->port_res[i]);
ibmebus_free_irq(ist, &port->port_res[i]);
}
out_free_qpeq:
ibmebus_free_irq(NULL, port->qp_eq->attr.ist1, port);
ibmebus_free_irq(port->qp_eq->attr.ist1, port);
i = port->num_def_qps;
goto out;
......@@ -1104,14 +1104,14 @@ static void ehea_free_interrupts(struct net_device *dev)
for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
pr = &port->port_res[i];
ibmebus_free_irq(NULL, pr->eq->attr.ist1, pr);
ibmebus_free_irq(pr->eq->attr.ist1, pr);
if (netif_msg_intr(port))
ehea_info("free send irq for res %d with handle 0x%X",
i, pr->eq->attr.ist1);
}
/* associated events */
ibmebus_free_irq(NULL, port->qp_eq->attr.ist1, port);
ibmebus_free_irq(port->qp_eq->attr.ist1, port);
if (netif_msg_intr(port))
ehea_info("associated event interrupt for handle 0x%X freed",
port->qp_eq->attr.ist1);
......@@ -2832,7 +2832,7 @@ static struct device *ehea_register_port(struct ehea_port *port,
int ret;
port->ofdev.node = of_node_get(dn);
port->ofdev.dev.parent = &port->adapter->ebus_dev->ofdev.dev;
port->ofdev.dev.parent = &port->adapter->ofdev->dev;
port->ofdev.dev.bus = &ibmebus_bus_type;
sprintf(port->ofdev.dev.bus_id, "port%d", port_name_cnt++);
......@@ -3011,7 +3011,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
const u32 *dn_log_port_id;
int i = 0;
lhea_dn = adapter->ebus_dev->ofdev.node;
lhea_dn = adapter->ofdev->node;
while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
......@@ -3051,7 +3051,7 @@ static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter,
struct device_node *eth_dn = NULL;
const u32 *dn_log_port_id;
lhea_dn = adapter->ebus_dev->ofdev.node;
lhea_dn = adapter->ofdev->node;
while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
......@@ -3157,31 +3157,31 @@ static ssize_t ehea_remove_port(struct device *dev,
static DEVICE_ATTR(probe_port, S_IWUSR, NULL, ehea_probe_port);
static DEVICE_ATTR(remove_port, S_IWUSR, NULL, ehea_remove_port);
int ehea_create_device_sysfs(struct ibmebus_dev *dev)
int ehea_create_device_sysfs(struct of_device *dev)
{
int ret = device_create_file(&dev->ofdev.dev, &dev_attr_probe_port);
int ret = device_create_file(&dev->dev, &dev_attr_probe_port);
if (ret)
goto out;
ret = device_create_file(&dev->ofdev.dev, &dev_attr_remove_port);
ret = device_create_file(&dev->dev, &dev_attr_remove_port);
out:
return ret;
}
void ehea_remove_device_sysfs(struct ibmebus_dev *dev)
void ehea_remove_device_sysfs(struct of_device *dev)
{
device_remove_file(&dev->ofdev.dev, &dev_attr_probe_port);
device_remove_file(&dev->ofdev.dev, &dev_attr_remove_port);
device_remove_file(&dev->dev, &dev_attr_probe_port);
device_remove_file(&dev->dev, &dev_attr_remove_port);
}
static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
static int __devinit ehea_probe_adapter(struct of_device *dev,
const struct of_device_id *id)
{
struct ehea_adapter *adapter;
const u64 *adapter_handle;
int ret;
if (!dev || !dev->ofdev.node) {
if (!dev || !dev->node) {
ehea_error("Invalid ibmebus device probed");
return -EINVAL;
}
......@@ -3189,36 +3189,36 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
if (!adapter) {
ret = -ENOMEM;
dev_err(&dev->ofdev.dev, "no mem for ehea_adapter\n");
dev_err(&dev->dev, "no mem for ehea_adapter\n");
goto out;
}
list_add(&adapter->list, &adapter_list);
adapter->ebus_dev = dev;
adapter->ofdev = dev;
adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle",
adapter_handle = of_get_property(dev->node, "ibm,hea-handle",
NULL);
if (adapter_handle)
adapter->handle = *adapter_handle;
if (!adapter->handle) {
dev_err(&dev->ofdev.dev, "failed getting handle for adapter"
" '%s'\n", dev->ofdev.node->full_name);
dev_err(&dev->dev, "failed getting handle for adapter"
" '%s'\n", dev->node->full_name);
ret = -ENODEV;
goto out_free_ad;
}
adapter->pd = EHEA_PD_ID;
dev->ofdev.dev.driver_data = adapter;
dev->dev.driver_data = adapter;
/* initialize adapter and ports */
/* get adapter properties */
ret = ehea_sense_adapter_attr(adapter);
if (ret) {
dev_err(&dev->ofdev.dev, "sense_adapter_attr failed: %d", ret);
dev_err(&dev->dev, "sense_adapter_attr failed: %d", ret);
goto out_free_ad;
}
......@@ -3226,18 +3226,18 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1);
if (!adapter->neq) {
ret = -EIO;
dev_err(&dev->ofdev.dev, "NEQ creation failed");
dev_err(&dev->dev, "NEQ creation failed");
goto out_free_ad;
}
tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet,
(unsigned long)adapter);
ret = ibmebus_request_irq(NULL, adapter->neq->attr.ist1,
ret = ibmebus_request_irq(adapter->neq->attr.ist1,
ehea_interrupt_neq, IRQF_DISABLED,
"ehea_neq", adapter);
if (ret) {
dev_err(&dev->ofdev.dev, "requesting NEQ IRQ failed");
dev_err(&dev->dev, "requesting NEQ IRQ failed");
goto out_kill_eq;
}
......@@ -3247,7 +3247,7 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
ret = ehea_setup_ports(adapter);
if (ret) {
dev_err(&dev->ofdev.dev, "setup_ports failed");
dev_err(&dev->dev, "setup_ports failed");
goto out_rem_dev_sysfs;
}
......@@ -3258,7 +3258,7 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
ehea_remove_device_sysfs(dev);
out_free_irq:
ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter);
ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
out_kill_eq:
ehea_destroy_eq(adapter->neq);
......@@ -3269,9 +3269,9 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
return ret;
}
static int __devexit ehea_remove(struct ibmebus_dev *dev)
static int __devexit ehea_remove(struct of_device *dev)
{
struct ehea_adapter *adapter = dev->ofdev.dev.driver_data;
struct ehea_adapter *adapter = dev->dev.driver_data;
int i;
for (i = 0; i < EHEA_MAX_PORTS; i++)
......@@ -3284,7 +3284,7 @@ static int __devexit ehea_remove(struct ibmebus_dev *dev)
flush_scheduled_work();
ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter);
ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
tasklet_kill(&adapter->neq_tasklet);
ehea_destroy_eq(adapter->neq);
......
......@@ -165,6 +165,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
#define CPU_FTR_SPURR LONG_ASM_CONST(0x0001000000000000)
#define CPU_FTR_DSCR LONG_ASM_CONST(0x0002000000000000)
#define CPU_FTR_1T_SEGMENT LONG_ASM_CONST(0x0004000000000000)
#define CPU_FTR_NO_SLBIE_B LONG_ASM_CONST(0x0008000000000000)
#ifndef __ASSEMBLY__
......@@ -367,7 +368,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
#define CPU_FTRS_PA6T (CPU_FTR_USE_TB | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
CPU_FTR_PURR | CPU_FTR_REAL_LE)
CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_NO_SLBIE_B)
#define CPU_FTRS_COMPATIBLE (CPU_FTR_USE_TB | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2)
......
......@@ -43,42 +43,18 @@
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/mod_devicetable.h>
#include <asm/of_device.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
extern struct bus_type ibmebus_bus_type;
struct ibmebus_dev {
struct of_device ofdev;
};
int ibmebus_register_driver(struct of_platform_driver *drv);
void ibmebus_unregister_driver(struct of_platform_driver *drv);
struct ibmebus_driver {
char *name;
struct of_device_id *id_table;
int (*probe) (struct ibmebus_dev *dev, const struct of_device_id *id);
int (*remove) (struct ibmebus_dev *dev);
struct device_driver driver;
};
int ibmebus_register_driver(struct ibmebus_driver *drv);
void ibmebus_unregister_driver(struct ibmebus_driver *drv);
int ibmebus_request_irq(struct ibmebus_dev *dev,
u32 ist,
irq_handler_t handler,
unsigned long irq_flags, const char * devname,
int ibmebus_request_irq(u32 ist, irq_handler_t handler,
unsigned long irq_flags, const char *devname,
void *dev_id);
void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id);
static inline struct ibmebus_driver *to_ibmebus_driver(struct device_driver *drv)
{
return container_of(drv, struct ibmebus_driver, driver);
}
static inline struct ibmebus_dev *to_ibmebus_dev(struct device *dev)
{
return container_of(dev, struct ibmebus_dev, ofdev.dev);
}
void ibmebus_free_irq(u32 ist, void *dev_id);
#endif /* __KERNEL__ */
#endif /* _ASM_IBMEBUS_H */
......@@ -17,6 +17,10 @@ struct of_device
struct device dev; /* Generic device interface */
};
extern struct of_device *of_device_alloc(struct device_node *np,
const char *bus_id,
struct device *parent);
extern ssize_t of_device_get_modalias(struct of_device *ofdev,
char *str, ssize_t len);
extern int of_device_uevent(struct device *dev,
......
......@@ -28,6 +28,10 @@
#define MPC52xx_PSC_MAXNUM 6
/* Programmable Serial Controller (PSC) status register bits */
#define MPC52xx_PSC_SR_UNEX_RX 0x0001
#define MPC52xx_PSC_SR_DATA_VAL 0x0002
#define MPC52xx_PSC_SR_DATA_OVR 0x0004
#define MPC52xx_PSC_SR_CMDSEND 0x0008
#define MPC52xx_PSC_SR_CDE 0x0080
#define MPC52xx_PSC_SR_RXRDY 0x0100
#define MPC52xx_PSC_SR_RXFULL 0x0200
......@@ -132,8 +136,10 @@ struct mpc52xx_psc {
u8 reserved5[3];
u8 ctlr; /* PSC + 0x1c */
u8 reserved6[3];
u16 ccr; /* PSC + 0x20 */
u8 reserved7[14];
u32 ccr; /* PSC + 0x20 */
u32 ac97_slots; /* PSC + 0x24 */
u32 ac97_cmd; /* PSC + 0x28 */
u32 ac97_data; /* PSC + 0x2c */
u8 ivr; /* PSC + 0x30 */
u8 reserved8[3];
u8 ip; /* PSC + 0x34 */
......
......@@ -22,5 +22,10 @@ extern int of_device_register(struct of_device *ofdev);
extern void of_device_unregister(struct of_device *ofdev);
extern void of_release_dev(struct device *dev);
static inline void of_device_free(struct of_device *dev)
{
of_release_dev(&dev->dev);
}
#endif /* __KERNEL__ */
#endif /* _LINUX_OF_DEVICE_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册