diff options
Diffstat (limited to 'arch')
24 files changed, 245 insertions, 192 deletions
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index 500c9610ab3..e0f19ab9116 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c @@ -75,7 +75,7 @@ no_pgd: void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd) { pmd_t *pmd; - struct page *pte; + pgtable_t pte; if (!pgd) return; @@ -90,10 +90,8 @@ void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd) goto free; } - pte = pmd_page(*pmd); + pte = pmd_pgtable(*pmd); pmd_clear(pmd); - dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE); - pte_lock_deinit(pte); pte_free(mm, pte); pmd_free(mm, pmd); free: diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 6dfa3b3c0e2..18a9c5f4b00 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -742,7 +742,9 @@ sys_call_table: .long sys_epoll_pwait /* 315 */ .long sys_utimensat .long sys_signalfd - .long sys_ni_syscall + .long sys_timerfd_create .long sys_eventfd .long sys_fallocate /* 320 */ + .long sys_timerfd_settime + .long sys_timerfd_gettime diff --git a/arch/m68knommu/defconfig b/arch/m68knommu/defconfig index 648113075f9..670b0a99cfa 100644 --- a/arch/m68knommu/defconfig +++ b/arch/m68knommu/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.23 -# Thu Oct 18 13:17:38 2007 +# Linux kernel version: 2.6.25-rc3 +# Mon Feb 25 15:03:00 2008 # CONFIG_M68K=y # CONFIG_MMU is not set @@ -15,8 +15,10 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME=y CONFIG_TIME_LOW_RES=y CONFIG_NO_IOPORT=y +CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -31,12 +33,14 @@ CONFIG_LOCALVERSION_AUTO=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_GROUP_SCHED is not set # CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -48,15 +52,22 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set # CONFIG_SIGNALFD is not set +# CONFIG_TIMERFD is not set # CONFIG_EVENTFD is not set # CONFIG_VM_EVENT_COUNTERS is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +# CONFIG_HAVE_OPROFILE is not set +# CONFIG_HAVE_KPROBES is not set +CONFIG_SLABINFO=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y @@ -83,6 +94,8 @@ CONFIG_IOSCHED_NOOP=y # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # # Processor type and features @@ -121,6 +134,7 @@ CONFIG_M5272C3=y # CONFIG_MOD5272 is not set CONFIG_FREESCALE=y CONFIG_4KSTACKS=y +CONFIG_HZ=100 # # RAM configuration @@ -147,6 +161,7 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 @@ -159,10 +174,6 @@ CONFIG_VIRT_TO_BUS=y # CONFIG_ARCH_SUPPORTS_MSI is not set # -# PCCARD (PCMCIA/CardBus) support -# - -# # Executable file formats # CONFIG_BINFMT_FLAT=y @@ -205,6 +216,7 @@ CONFIG_IP_FIB_HASH=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y @@ -229,10 +241,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set # @@ -240,6 +248,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -283,6 +292,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -339,10 +349,11 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -360,9 +371,15 @@ CONFIG_NETDEVICES=y # CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_VETH is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y # CONFIG_MII is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set CONFIG_FEC=y # CONFIG_FEC2 is not set # CONFIG_NETDEV_1000 is not set @@ -377,7 +394,7 @@ CONFIG_FEC=y CONFIG_PPP=y # CONFIG_PPP_MULTILINK is not set # CONFIG_PPP_FILTER is not set -# CONFIG_PPP_ASYNC is not set +CONFIG_PPP_ASYNC=y # CONFIG_PPP_SYNC_TTY is not set # CONFIG_PPP_DEFLATE is not set # CONFIG_PPP_BSDCOMP is not set @@ -386,7 +403,6 @@ CONFIG_PPP=y # CONFIG_PPPOL2TP is not set # CONFIG_SLIP is not set CONFIG_SLHC=y -# CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -418,12 +434,16 @@ CONFIG_SLHC=y # # Non-8250 serial port support # -CONFIG_SERIAL_COLDFIRE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_COLDFIRE is not set +CONFIG_SERIAL_MCF=y +CONFIG_SERIAL_MCF_BAUDRATE=19200 +CONFIG_SERIAL_MCF_CONSOLE=y # CONFIG_UNIX98_PTYS is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_IPMI_HANDLER is not set -# CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set # CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set @@ -439,6 +459,14 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set # # Multifunction device drivers @@ -450,20 +478,20 @@ CONFIG_LEGACY_PTY_COUNT=256 # # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -CONFIG_DAB=y +# CONFIG_DAB is not set # # Graphics support # +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Display device support # # CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y -# CONFIG_FB is not set # # Sound @@ -471,23 +499,11 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y # CONFIG_SOUND is not set # CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_RTC_CLASS is not set # -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# # Userspace I/O # # CONFIG_UIO is not set @@ -505,11 +521,9 @@ CONFIG_EXT2_FS=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -CONFIG_ROMFS_FS=y +# CONFIG_DNOTIFY is not set # CONFIG_INOTIFY is not set # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -535,7 +549,6 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -551,42 +564,27 @@ CONFIG_RAMFS=y # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set +CONFIG_ROMFS_FS=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# # CONFIG_NLS is not set - -# -# Distributed Lock Manager -# # CONFIG_DLM is not set # # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y # CONFIG_ENABLE_MUST_CHECK is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -594,6 +592,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_SAMPLES is not set # CONFIG_FULLDEBUG is not set # CONFIG_HIGHPROFILE is not set # CONFIG_BOOTPARAM is not set @@ -605,6 +604,7 @@ CONFIG_MSDOS_PARTITION=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set # CONFIG_CRYPTO is not set # diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S index 1b02b882006..fca2e49917a 100644 --- a/arch/m68knommu/kernel/syscalltable.S +++ b/arch/m68knommu/kernel/syscalltable.S @@ -336,9 +336,11 @@ ENTRY(sys_call_table) .long sys_epoll_pwait /* 315 */ .long sys_utimensat .long sys_signalfd - .long sys_ni_syscall + .long sys_timerfd_create .long sys_eventfd .long sys_fallocate /* 320 */ + .long sys_timerfd_settime + .long sys_timerfd_gettime .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall diff --git a/arch/m68knommu/platform/68328/timers.c b/arch/m68knommu/platform/68328/timers.c index 9159fd05c9a..6bafefa546e 100644 --- a/arch/m68knommu/platform/68328/timers.c +++ b/arch/m68knommu/platform/68328/timers.c @@ -67,16 +67,6 @@ static irqreturn_t hw_tick(int irq, void *dummy) /***************************************************************************/ -static irqreturn_t hw_tick(int irq, void *dummy) -{ - /* Reset Timer1 */ - TSTAT &= 0; - - return arch_timer_interrupt(irq, dummy); -} - -/***************************************************************************/ - static struct irqaction m68328_timer_irq = { .name = "timer", .flags = IRQF_DISABLED | IRQF_TIMER, diff --git a/arch/powerpc/boot/cuboot-bamboo.c b/arch/powerpc/boot/cuboot-bamboo.c index 900c7ff2b7e..b5c30f766c4 100644 --- a/arch/powerpc/boot/cuboot-bamboo.c +++ b/arch/powerpc/boot/cuboot-bamboo.c @@ -17,6 +17,7 @@ #include "44x.h" #include "cuboot.h" +#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/arch/powerpc/boot/cuboot-ebony.c b/arch/powerpc/boot/cuboot-ebony.c index c5f37ce172e..56564ba37f6 100644 --- a/arch/powerpc/boot/cuboot-ebony.c +++ b/arch/powerpc/boot/cuboot-ebony.c @@ -17,6 +17,7 @@ #include "44x.h" #include "cuboot.h" +#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/arch/powerpc/boot/cuboot-katmai.c b/arch/powerpc/boot/cuboot-katmai.c index c021167f938..5434d70b566 100644 --- a/arch/powerpc/boot/cuboot-katmai.c +++ b/arch/powerpc/boot/cuboot-katmai.c @@ -22,6 +22,7 @@ #include "44x.h" #include "cuboot.h" +#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/arch/powerpc/boot/cuboot-taishan.c b/arch/powerpc/boot/cuboot-taishan.c index f66455a45ab..b55b80467ee 100644 --- a/arch/powerpc/boot/cuboot-taishan.c +++ b/arch/powerpc/boot/cuboot-taishan.c @@ -21,7 +21,9 @@ #include "dcr.h" #include "4xx.h" +#define TARGET_4xx #define TARGET_44x +#define TARGET_440GX #include "ppcboot.h" static bd_t bd; diff --git a/arch/powerpc/boot/cuboot-warp.c b/arch/powerpc/boot/cuboot-warp.c index bdedebe1bc1..3db93e85e9e 100644 --- a/arch/powerpc/boot/cuboot-warp.c +++ b/arch/powerpc/boot/cuboot-warp.c @@ -11,6 +11,7 @@ #include "4xx.h" #include "cuboot.h" +#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/arch/powerpc/boot/dts/haleakala.dts b/arch/powerpc/boot/dts/haleakala.dts index 5dd3d15f0fe..ae68fefc01b 100644 --- a/arch/powerpc/boot/dts/haleakala.dts +++ b/arch/powerpc/boot/dts/haleakala.dts @@ -235,7 +235,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - compatible = "ibm,plb-pciex-405exr", "ibm,plb-pciex"; + compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex"; primary; port = <0>; /* port number */ reg = <a0000000 20000000 /* Config space access */ diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts index bc32ac7250e..fc86e5a3afc 100644 --- a/arch/powerpc/boot/dts/katmai.dts +++ b/arch/powerpc/boot/dts/katmai.dts @@ -38,8 +38,8 @@ timebase-frequency = <0>; /* Filled in by zImage */ i-cache-line-size = <20>; d-cache-line-size = <20>; - i-cache-size = <20000>; - d-cache-size = <20000>; + i-cache-size = <8000>; + d-cache-size = <8000>; dcr-controller; dcr-access-method = "native"; }; @@ -136,11 +136,11 @@ }; POB0: opb { - compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb"; + compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = <00000000 4 e0000000 20000000>; - clock-frequency = <0>; /* Filled in by zImage */ + ranges = <00000000 4 e0000000 20000000>; + clock-frequency = <0>; /* Filled in by zImage */ EBC0: ebc { compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc"; @@ -153,38 +153,38 @@ }; UART0: serial@10000200 { - device_type = "serial"; - compatible = "ns16550"; - reg = <10000200 8>; + device_type = "serial"; + compatible = "ns16550"; + reg = <10000200 8>; virtual-reg = <a0000200>; - clock-frequency = <0>; /* Filled in by zImage */ - current-speed = <1c200>; - interrupt-parent = <&UIC0>; - interrupts = <0 4>; - }; + clock-frequency = <0>; /* Filled in by zImage */ + current-speed = <1c200>; + interrupt-parent = <&UIC0>; + interrupts = <0 4>; + }; UART1: serial@10000300 { - device_type = "serial"; - compatible = "ns16550"; - reg = <10000300 8>; + device_type = "serial"; + compatible = "ns16550"; + reg = <10000300 8>; virtual-reg = <a0000300>; - clock-frequency = <0>; - current-speed = <0>; - interrupt-parent = <&UIC0>; - interrupts = <1 4>; - }; + clock-frequency = <0>; + current-speed = <0>; + interrupt-parent = <&UIC0>; + interrupts = <1 4>; + }; UART2: serial@10000600 { - device_type = "serial"; - compatible = "ns16550"; - reg = <10000600 8>; + device_type = "serial"; + compatible = "ns16550"; + reg = <10000600 8>; virtual-reg = <a0000600>; - clock-frequency = <0>; - current-speed = <0>; - interrupt-parent = <&UIC1>; - interrupts = <5 4>; - }; + clock-frequency = <0>; + current-speed = <0>; + interrupt-parent = <&UIC1>; + interrupts = <5 4>; + }; IIC0: i2c@10000400 { compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c index 13929771bee..9eed1f68fca 100644 --- a/arch/powerpc/oprofile/op_model_cell.c +++ b/arch/powerpc/oprofile/op_model_cell.c @@ -1151,7 +1151,7 @@ static void cell_handle_interrupt(struct pt_regs *regs, for (i = 0; i < num_counters; ++i) { if ((interrupt_mask & CBE_PM_CTR_OVERFLOW_INTR(i)) && ctr[i].enabled) { - oprofile_add_pc(pc, is_kernel, i); + oprofile_add_ext_sample(pc, regs, i, is_kernel); cbe_write_ctr(cpu, i, reset_value[i]); } } diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c index 9aa4425d80b..4d5fd1dbd40 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c @@ -199,6 +199,7 @@ int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv) return 0; } +EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv); /** * mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index edab631a8dc..20ea0e118f2 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -113,7 +113,7 @@ /* IOMMU sizing */ #define IO_SEGMENT_SHIFT 28 -#define IO_PAGENO_BITS (IO_SEGMENT_SHIFT - IOMMU_PAGE_SHIFT) +#define IO_PAGENO_BITS(shift) (IO_SEGMENT_SHIFT - (shift)) /* The high bit needs to be set on every DMA address */ #define SPIDER_DMA_OFFSET 0x80000000ul @@ -123,7 +123,6 @@ struct iommu_window { struct cbe_iommu *iommu; unsigned long offset; unsigned long size; - unsigned long pte_offset; unsigned int ioid; struct iommu_table table; }; @@ -200,7 +199,7 @@ static void tce_build_cell(struct iommu_table *tbl, long index, long npages, (window->ioid & IOPTE_IOID_Mask); #endif - io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset); + io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE) io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask); @@ -232,7 +231,7 @@ static void tce_free_cell(struct iommu_table *tbl, long index, long npages) | (window->ioid & IOPTE_IOID_Mask); #endif - io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset); + io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); for (i = 0; i < npages; i++) io_pte[i] = pte; @@ -307,76 +306,84 @@ static int cell_iommu_find_ioc(int nid, unsigned long *base) return -ENODEV; } -static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu, +static void cell_iommu_setup_stab(struct cbe_iommu *iommu, unsigned long dbase, unsigned long dsize, unsigned long fbase, unsigned long fsize) { struct page *page; - int i; - unsigned long reg, segments, pages_per_segment, ptab_size, stab_size, - n_pte_pages, base; - - base = dbase; - if (fsize != 0) - base = min(fbase, dbase); + unsigned long segments, stab_size; segments = max(dbase + dsize, fbase + fsize) >> IO_SEGMENT_SHIFT; - pages_per_segment = 1ull << IO_PAGENO_BITS; - pr_debug("%s: iommu[%d]: segments: %lu, pages per segment: %lu\n", - __FUNCTION__, iommu->nid, segments, pages_per_segment); + pr_debug("%s: iommu[%d]: segments: %lu\n", + __FUNCTION__, iommu->nid, segments); /* set up the segment table */ stab_size = segments * sizeof(unsigned long); page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size)); BUG_ON(!page); iommu->stab = page_address(page); - clear_page(iommu->stab); + memset(iommu->stab, 0, stab_size); +} + +static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu, + unsigned long base, unsigned long size, unsigned long gap_base, + unsigned long gap_size, unsigned long page_shift) +{ + struct page *page; + int i; + unsigned long reg, segments, pages_per_segment, ptab_size, + n_pte_pages, start_seg, *ptab; + + start_seg = base >> IO_SEGMENT_SHIFT; + segments = size >> IO_SEGMENT_SHIFT; + pages_per_segment = 1ull << IO_PAGENO_BITS(page_shift); + /* PTEs for each segment must start on a 4K bounday */ + pages_per_segment = max(pages_per_segment, + (1 << 12) / sizeof(unsigned long)); - /* ... and the page tables. Since these are contiguous, we can treat - * the page tables as one array of ptes, like pSeries does. - */ ptab_size = segments * pages_per_segment * sizeof(unsigned long); pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __FUNCTION__, iommu->nid, ptab_size, get_order(ptab_size)); page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size)); BUG_ON(!page); - iommu->ptab = page_address(page); - memset(iommu->ptab, 0, ptab_size); + ptab = page_address(page); + memset(ptab, 0, ptab_size); - /* allocate a bogus page for the end of each mapping */ - page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); - BUG_ON(!page); - iommu->pad_page = page_address(page); - clear_page(iommu->pad_page); - - /* number of pages needed for a page table */ - n_pte_pages = (pages_per_segment * - sizeof(unsigned long)) >> IOMMU_PAGE_SHIFT; + /* number of 4K pages needed for a page table */ + n_pte_pages = (pages_per_segment * sizeof(unsigned long)) >> 12; pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n", - __FUNCTION__, iommu->nid, iommu->stab, iommu->ptab, + __FUNCTION__, iommu->nid, iommu->stab, ptab, n_pte_pages); /* initialise the STEs */ reg = IOSTE_V | ((n_pte_pages - 1) << 5); - if (IOMMU_PAGE_SIZE == 0x1000) - reg |= IOSTE_PS_4K; - else if (IOMMU_PAGE_SIZE == 0x10000) - reg |= IOSTE_PS_64K; - else { - extern void __unknown_page_size_error(void); - __unknown_page_size_error(); + switch (page_shift) { + case 12: reg |= IOSTE_PS_4K; break; + case 16: reg |= IOSTE_PS_64K; break; + case 20: reg |= IOSTE_PS_1M; break; + case 24: reg |= IOSTE_PS_16M; break; + default: BUG(); } + gap_base = gap_base >> IO_SEGMENT_SHIFT; + gap_size = gap_size >> IO_SEGMENT_SHIFT; + pr_debug("Setting up IOMMU stab:\n"); - for (i = base >> IO_SEGMENT_SHIFT; i < segments; i++) { - iommu->stab[i] = reg | - (__pa(iommu->ptab) + n_pte_pages * IOMMU_PAGE_SIZE * i); + for (i = start_seg; i < (start_seg + segments); i++) { + if (i >= gap_base && i < (gap_base + gap_size)) { + pr_debug("\toverlap at %d, skipping\n", i); + continue; + } + iommu->stab[i] = reg | (__pa(ptab) + (n_pte_pages << 12) * + (i - start_seg)); pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]); } + + return ptab; } static void cell_iommu_enable_hardware(struct cbe_iommu *iommu) @@ -423,7 +430,9 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu) static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long base, unsigned long size) { - cell_iommu_setup_page_tables(iommu, base, size, 0, 0); + cell_iommu_setup_stab(iommu, base, size, 0, 0); + iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size, 0, 0, + IOMMU_PAGE_SHIFT); cell_iommu_enable_hardware(iommu); } @@ -464,6 +473,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, unsigned long pte_offset) { struct iommu_window *window; + struct page *page; u32 ioid; ioid = cell_iommu_get_ioid(np); @@ -475,13 +485,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, window->size = size; window->ioid = ioid; window->iommu = iommu; - window->pte_offset = pte_offset; window->table.it_blocksize = 16; window->table.it_base = (unsigned long)iommu->ptab; window->table.it_index = iommu->nid; - window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + - window->pte_offset; + window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + pte_offset; window->table.it_size = size >> IOMMU_PAGE_SHIFT; iommu_init_table(&window->table, iommu->nid); @@ -504,6 +512,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, * This code also assumes that we have a window that starts at 0, * which is the case on all spider based blades. */ + page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); + BUG_ON(!page); + iommu->pad_page = page_address(page); + clear_page(iommu->pad_page); + __set_bit(0, window->table.it_map); tce_build_cell(&window->table, window->table.it_offset, 1, (unsigned long)iommu->pad_page, DMA_TO_DEVICE); @@ -549,7 +562,7 @@ static void cell_dma_dev_setup_iommu(struct device *dev) archdata->dma_data = &window->table; } -static void cell_dma_dev_setup_static(struct device *dev); +static void cell_dma_dev_setup_fixed(struct device *dev); static void cell_dma_dev_setup(struct device *dev) { @@ -557,7 +570,7 @@ static void cell_dma_dev_setup(struct device *dev) /* Order is important here, these are not mutually exclusive */ if (get_dma_ops(dev) == &dma_iommu_fixed_ops) - cell_dma_dev_setup_static(dev); + cell_dma_dev_setup_fixed(dev); else if (get_pci_dma_ops() == &dma_iommu_ops) cell_dma_dev_setup_iommu(dev); else if (get_pci_dma_ops() == &dma_direct_ops) @@ -858,7 +871,7 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask) return 0; } -static void cell_dma_dev_setup_static(struct device *dev) +static void cell_dma_dev_setup_fixed(struct device *dev) { struct dev_archdata *archdata = &dev->archdata; u64 addr; @@ -869,35 +882,45 @@ static void cell_dma_dev_setup_static(struct device *dev) dev_dbg(dev, "iommu: fixed addr = %lx\n", addr); } +static void insert_16M_pte(unsigned long addr, unsigned long *ptab, + unsigned long base_pte) +{ + unsigned long segment, offset; + + segment = addr >> IO_SEGMENT_SHIFT; + offset = (addr >> 24) - (segment << IO_PAGENO_BITS(24)); + ptab = ptab + (segment * (1 << 12) / sizeof(unsigned long)); + + pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n", + addr, ptab, segment, offset); + + ptab[offset] = base_pte | (__pa(addr) & IOPTE_RPN_Mask); +} + static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu, struct device_node *np, unsigned long dbase, unsigned long dsize, unsigned long fbase, unsigned long fsize) { - unsigned long base_pte, uaddr, *io_pte; - int i; + unsigned long base_pte, uaddr, ioaddr, *ptab; - dma_iommu_fixed_base = fbase; + ptab = cell_iommu_alloc_ptab(iommu, fba |